UNPKG

fury-js

Version:

WebGL Game Engine

123 lines (105 loc) 4.17 kB
const Maths = require('./maths'); const Prefab = require('./prefab'); const Renderer = require('./renderer'); const Shaders = require('./shaders'); const Primitives = require('./primitives'); module.exports = (function(){ let exports = {}; let getAtlasIndex = (atlas, name) => { let map = atlas.map; for (let i = 0, l = map.length; i < l; i++) { if (map[i] == name) { return i; } } return 0; }; let getPrefabName = (atlas, atlasIndex, color, alpha, centered) => { let name = atlas.id + "_" + atlasIndex; if (alpha !== undefined && alpha != atlas.materialConfig.properties.alpha) { name += "_" + (alpha ? "a1" : "a0"); } if (color !== undefined && (color[0] != 1 || color[1] != 1 || color[2] != 1 || color[3] != 1)) { name += "_" + color[0] + "_" + color[1] + "_" + color[2] + "_" + color[3]; } if (centered) { name += "_c"; } return name; } let setOffset = (out, atlasIndex, width, height) => { out[0] = (atlasIndex % width) / width; out[1] = 1 - (Math.floor(atlasIndex / width) + 1) / height; }; let setMaterialConfigOffset = (config, atlasIndex, width, height) => { config.properties.offset = [0,0]; // Create new offset array per prefab setOffset(config.properties.offset, atlasIndex, width, height); }; exports.setMaterialOffset = (material, atlas, tile) => { let atlasIndex = getAtlasIndex(atlas, tile); if (!material.offset) { material.offset = [0,0]; } setOffset(material.offset, atlasIndex, atlas.width, atlas.height); }; exports.setMaterialFrame = (material, atlas, frameIndex) => { if (!material.offset) { material.offset = [0,0]; } setOffset(material.offset, frameIndex, atlas.width, atlas.height); }; exports.createTilePrefab = (config) => { let { atlas, tile, color, alpha, centered } = config; let { width, height } = atlas; let atlasIndex = getAtlasIndex(atlas, tile); let prefabName = getPrefabName(atlas, atlasIndex, color, alpha, centered); if (Prefab.prefabs[prefabName] === undefined) { let meshConfig = centered ? atlas.centerdMeshConfig : atlas.meshConfig; let materialConfig = Object.create(atlas.materialConfig); // Each prefab needs it's own properties object so that properties can be manipulated indepedently materialConfig.properties = Object.assign({}, atlas.materialConfig.properties); // Each prefab needs it's own offset for the same reason (however we leave scale as we don't expect that to vary) materialConfig.properties.offset = [ 0, 0 ]; if (alpha !== undefined) { materialConfig.properties.alpha = alpha; } if (color !== undefined) { materialConfig.properties.color = color; } else { // This shouldn't be necessary, however it is materialConfig.properties.color = [ 1,1,1,1 ]; } setOffset(materialConfig.properties.offset, atlasIndex, width, height); Prefab.create({ name: prefabName, meshConfig: meshConfig, materialConfig: materialConfig }); } return prefabName; }; exports.create = (config, image) => { if (!config.id || !config.map || !config.width || !config.height || !config.tileWidth || !config.tileHeight) { console.error("Invalid atlas definition provided, must contain properties: id, map, width, height, tileWidth and tileHeight"); } let atlas = Object.create(config); atlas.alpha = atlas.alpha === undefined ? true : !!atlas.alpha; atlas.texture = Renderer.createTexture(image, false, true); atlas.materialConfig = { shader: Shaders.Sprite, texture: atlas.texture, properties: { alpha: atlas.alpha, offset: [ 0, 0 ], scale: [ 1 / atlas.width, 1 / atlas.height ] } }; atlas.meshConfig = Primitives.createQuadMeshConfig(atlas.tileWidth, atlas.tileHeight); atlas.centerdMeshConfig = Primitives.createCenteredQuadMeshConfig(atlas.tileWidth, atlas.tileHeight); return atlas; }; exports.load = (config, callback) => { let image = new Image(); image.onload = () => { callback(exports.create(config, image)); }; image.src = config.path; }; return exports; })();