/** * @file MBS - FPLE MV * @author Masked * @version 1.1.0 2016-02-27 */ /*: * @plugindesc This plugin makes your game a first person labyrinth explorer. * * @author Masked * * @param View Distance * @desc The amount of tiles ahead the player can see by default. * @default 3 * * @param Light Color * @desc The hex code for the color used on the light. * @default #ffffff * * @param Wall Terrain * @desc The ID for wall tiles terrain tag on FPLE tilesets. * @default 1 * * @param Ceiling Region * @desc The Region ID for ceiled tiles. * @default 0 * * @param 3D Anaglyph * @desc Whether to use 3D cyan and red anaglyph to give your game depth. 1 = YES, 0 = NO. * @default 0 * * @param Texture Filter * @desc The texture's filter type. (nearest/linear) * @default linear * * @param Texture Format * @desc The texture file format used. (png/jpg/dds/gif/...) * @default png * * @param Texture Anisotropy * @desc The amount of samples taken from textures. (usually a power of 2) * @default 1 * * @param Antialiasing * @desc Whether to use antialiasing or not (expensive). 1 = YES, 0 = NO. * @default 0 * * @param Optimization Level * @desc The level of optimization applied (degrading). (none/low/medium/high) * @default none * * @help * # * First Person Labyrinth Explorer * by Masked * * This plugin makes your game a kind of 3D so it looks like a first person * labyrinth explorer. * * * How to use * * 1. Setup * * I really recommend you using the Demo as a base for creating your FPLE * projects, so you can skip this part. * If you create the project from scratch, however, you'll need to download * babylon.js by yourself from http://cdn.babylonjs.com/2-3/babylon.js and * save it at your project's "js/libs" folder. This plugin was made using * babylon.js 2.3, so you should use this version too to avoid possible * bugs, but feel free to try later versions. * Then, edit your index.html and add this after line 14: * * Now, you're half a step nearer to be ready to go. * * 2. Textures * * Textures can be set creating a file named "{tileset}_{row}-{col}", * replacing '{tileset}' by the FPLE tileset number on the database and * '{row}' and '{col}' with, respectively, the row and column the tile you are * texturing is on the tileset's A5 layer, and placing it at your game's * img/textures folder. * There's no maximum/minimum size for the textures, but keep in mind that * bigger textures are more expensive and can cause some serious performance * decrease, specially on older computers. * * 3. Tilesets * * Setting tilesets up for FPLE is quite simple: first, create the tileset * and set just the A5 layer (which is, currently, the only one supported by * FPLE). Then, you can set passability flags as you want, and mark wall * tiles with the terrain tag you choose on your plugin settings. * Note that the first tile at the first row is always invisible, so it's * recommended you use a black tile or something like that. * * 4. Mapping * * Mapping is quite intuitive, just put wall tiles wherer you want to be walls * and floor tiles where you don't, you can use the first tile at the first * wall to create holes since it's invisible. Also, you may want your map to * have a ceiling, if so, you just have to set the tiles you want with the * ceil region you choose on the plugin settings. * * 5. Plugin commands * * FPLE setResolution : Sets the FPLE canvas resolution (higher * is better) * FPLE setViewDistance : Sets the FPLE view distance in tile * * Examples: * FPLE setResolution 0.5 : Sets the resolution at half * FPLE setResolution v[42] : Sets the resolution to the value of * variable 42 * * FPLE setViewDistance 3 : Sets the view radius to 3 tiles * FPLE setViewDistance v[42] : Sets the view radius to the value of * variable 42 * * * Credits * * - Masked, for creating; * - babylon.js team (https://github.com/BabylonJS/Babylon.js/graphs/contributors), * for their aweasomer library. */ /*:pt * @plugindesc Esse plugin transforma seu jogo em um explorador de labirinto em primeira pessoa. * * @author Masked * * @param View Distance * @desc Número de tiles à frente que o jogador vê por padrão. * @default 3 * * @param Light Color * @desc Código hexadecimal da cor da luz do jogador. * @default #ffffff * * @param Wall Terrain * @desc ID do terreno usado para identificar paredes nos tilesets. * @default 1 * * @param Ceiling Region * @desc ID da região usada em tiles com teto no mapa. * @default 0 * * @param 3D Anaglyph * @desc Quando usar ou não um efeito de vermelho e ciano para dar profundidade ao jogo. 1 = SIM, 0 = NÃO. * @default 0 * * @param Texture Filter * @desc Filtro usado nas texturas. (nearest/linear) * @default linear * * @param Texture Format * @desc Formato dos arquivos de textura. (png/jpg/dds/gif/...) * @default png * * @param Texture Anisotropy * @desc Número de amostras tiradas das texturas. (geralmente uma potência de 2) * @default 1 * * @param Antialiasing * @desc Quando usar antialiasing ou não (alto custo de performance). 1 = SIM, 0 = NÃO. * @default 0 * * @param Optimization Level * @desc Nível de otimização da cena aplicado (degradante). (none/low/medium/high) * @default none * * @help * # * First Person Labyrinth Explorer * por Masked * * Esse plugin constrói um cenário 3D para o seu jogo a partir de mapas simples, * tornando-o um explorador de labirinto em primeira pessoa. * * * Como Usar * * 1. Instalação * * Eu recomendo fortemente que use a DEMO do FPLE como base para seu projeto, * se estiver usando-a, pule esta parte. * Caso você queira criar seu projeto do zero, no entanto, é necessário baixar * o babylon.js de http://cdn.babylonjs.com/2-3/babylon.js e salvá-lo na pasta * "js/libs" do seu jogo. Esse plugin foi feito e testado usando a versão r74, * por isso é recomendado usar esta versão para evitar problemas. * Depois, edite o index.html do seu jogo e adicione isso após a linha 14: * * Pronto, plugin instalado, agora estamos meio passo mais próximos do final :D * * 2. Texturas * * Texturas são definidas criando arquivos com nomes seguindo o padrão * "{tileset}_{linha}-{coluna}", substituindo '{tileset}' pelo ID do tileset do * FPLE no database e '{linha}' e '{coluna}' com, respectivamente, o número da * linha e coluna do tile correspondente à textura no tileset. Note que apenas * tiles A5 podem ser usados no momento. * Arquivos de textura devem estar na pasta "img/textures" do seu projeto. * Não há valor mínimo ou máximo para o tamanho das texturas, mas recomenda-se * usar texturas quadradas e com tamanhos que sejam potências de 2. É importante * perceber que usar texturas maiores pode causar lag, especialmente em * computadores antigos. * * 3. Tilesets * * Configurar tilesets no FPLE é bem simples: primeiro, crie um tileset com * apenas a camada A5. Então, configure a passabilidade normalmente e marque tiles * de paede com o terreno que você escolheu nas configurações do plugin. * Note que o primeiro tile da primeira coluna é sempre invisível, então é * recomendado deixar isso sinalizado no próprio tileset. * * 4. Mapeamento * * O mapeamento não muda muito, na verdade, a única alteração é que tiles sem * textura, vazios ou o primeiro tile da primeira linha do tileset são * transparentes e ficam parecendo buracos no jogo, e você pode configurar como * o teto aparece mudando a região dos tiles. Se a região de teto for 0, então * todos os tiles sem região terão um teto. * * 5. Comandos de pugin * * FPLE setResolution : Define a resolução do canvas do FPLE * (quanto maior, melhor) * FPLE setViewDistance : Define o raio de visão do jogador * * Exemplos: * FPLE setResolution 0.5 : Define a resolução como metade do normal * FPLE setResolution v[42] : Define a resolução como o valor da * variável número 42 * * FPLE setViewDistance 3 : Define o raio de visão como 3 tiles * FPLE setViewDistance v[42] : Define o raio de visão como o valor da * variável número 42 * * * Créditos * * - Masked, por criar; * - Equipe do babylon.js (https://github.com/BabylonJS/Babylon.js/graphs/contributors), * pela biblioteca mais lindona. */ "use strict"; // This plugin uses babylon.js (http://babylonjs.com/) if (!BABYLON) throw new error('FPLE: Unable to find babylon.js, please follow the plugin' + ' instructions and try again.'); if (!BABYLON.Engine.isSupported()) throw new error('FPLE: Browser not supported by babylon.js.'); // Import for compatibility check var Imported = Imported || {}; Imported['MBS - FPLE'] = 1.10; // MBS module var MBS = MBS || {}; MBS.FPLE = {}; // Global babylonJS engine object var $babylon; // Global fple scene object var $fple; //----------------------------------------------------------------------------- // MBS.FPLE // // FPLE settings module (function ($) { // Parameter loading $.Filename = document.currentScript.src; $.Params = PluginManager.parameters(decodeURI(/([^\/]+)\.js$/.exec($.Filename)[1])); // Settings $.viewRadius = Number($.Params['View Distance']); $.lightColor = $.Params['Light Color']; $.wallTerrain = Number($.Params['Wall Terrain']); // $.ceilRegion = Number($.Params['Ceiling Region']); $.ceilRegion = String($.Params['Ceiling Region']); $.ceilRegion = $.ceilRegion.split(' '); if ($.ceilRegion === '') $.ceilRegion = []; for (var temp = 0; temp < $.ceilRegion.length; ++temp) { $.ceilRegion[temp] = parseInt($.ceilRegion[temp]); }; $.anaglyph3d = !!Number($.Params['3D Anaglyph']); $.textureFilter = $.Params['Texture Filter']; $.textureFormat = $.Params['Texture Format']; $.anisotropy = Number($.Params['Texture Anisotropy']); $.antialias = !!Number($.Params['Antialiasing']); $.optimization = $.Params['Optimization Level']; // Heights $.floorHeight = 0; $.wallHeight = 1; $.ceilHeight = 2; $.cameraHeight = 1; // Image files format string $.textureFileFormat = "img/textures/%1_%2-%3.%4"; $.bumpTextureFileFormat = "img/bump/%1_%2-%3.%4"; $.parallaxFileFormat = "img/parallaxes/%1.%2"; // Resizes the FPLE canvas to change the game resolution $.setPixelRate = function(n) { if (!Graphics._fple_renderer) return; Graphics._fple_renderer.setSize(Graphics.width * n, Graphics.height * n); Graphics._updateFPLE(); }; })(MBS.FPLE); //----------------------------------------------------------------------------- // MBS.FPLE.Map // // FPLE Map, this converts $dataMap into a 3D cubic map MBS.FPLE.Map = function() { this.initialize.apply(this, arguments); }; (function() { /** * Map initialization. */ MBS.FPLE.Map.prototype.initialize = function() { this.clearCache(); this.refresh(); }; /** * Clears the map cache. * Used just for creating '_cache' and/or reloading textures. */ MBS.FPLE.Map.prototype.clearCache = function() { this._cache = { textures: {}, materials: {} }; }; /** * Extracts $dataMap data. */ MBS.FPLE.Map.prototype.refresh = function() { // Clears all loaded data this._data = []; // Loads mapa data var width = $dataMap.width; var height = $dataMap.height; var data = $dataMap.data; for (var x = 0; x < width; x++) { this._data[x] = []; for (var y = 0; y < height; y++) { // Store tile ID this._data[x][y] = data[y * width + x]; } } }; /** * Gets a cached texture or loads it if it's hasn't been used yet. * * @param {String} filename The file from where to load the texture. */ MBS.FPLE.Map.prototype.getTexture = function(filename, scene) { // Load texture from cache or from file var cache = this._cache.textures[filename]; if (cache) return cache; var texture = new BABYLON.Texture( filename, scene, false ); texture.anisotropicFilteringLevel = MBS.FPLE.anisotropy; // Apply desired filter if (MBS.FPLE.textureFilter.match(/^nearest$/i)) texture.updateSamplingMode(BABYLON.Texture.NEAREST_SAMPLINGMODE); else texture.updateSamplingMode(BABYLON.Texture.NEAREST_BILINEARMODE); // Store it on cache this._cache.textures[filename] = texture; return texture; }; /** * Gets a cached material or loads it if it's hasn't been used yet. * * @param {String} filename The file from where to load the material texture. */ MBS.FPLE.Map.prototype.getMaterial = function(tile_id, row, col, scene) { var filename = MBS.FPLE.textureFileFormat.format( $dataMap.tilesetId, row, col, MBS.FPLE.textureFormat); var material; // Don't lose your time if it has already been loaded if (this._cache.materials[filename]) { material = this._cache.materials[filename]; // Load it otherwise } else { material = new BABYLON.MultiMaterial(filename, scene); var texture = this.getTexture(filename, scene); var f = new BABYLON.StandardMaterial(filename + "_front",scene); f.diffuseTexture = texture.clone(); f.specularColor = new BABYLON.Color3(0, 0, 0); f.diffuseTexture.uScale = -1; f.diffuseTexture.vScale = -1; var ba = new BABYLON.StandardMaterial(filename + "_back",scene); ba.diffuseTexture = texture.clone(); ba.specularColor = new BABYLON.Color3(0, 0, 0); ba.diffuseTexture.uScale = 1; ba.diffuseTexture.vScale = 1; var l = new BABYLON.StandardMaterial(filename + "_left",scene); l.diffuseTexture = texture.clone(); l.specularColor = new BABYLON.Color3(0, 0, 0); l.diffuseTexture.wAng = 0.5 * Math.PI; var r = new BABYLON.StandardMaterial(filename + "_right",scene); r.diffuseTexture = texture.clone(); r.specularColor = new BABYLON.Color3(0, 0, 0); r.diffuseTexture.wAng = 0.5 * Math.PI; var t = new BABYLON.StandardMaterial(filename + "_top",scene); t.diffuseTexture = texture.clone(); t.specularColor = new BABYLON.Color3(0, 0, 0); t.diffuseTexture.wAng = -0.5 * Math.PI; var bo = new BABYLON.StandardMaterial(filename + "_bottom",scene); bo.diffuseTexture = texture.clone(); bo.specularColor = new BABYLON.Color3(0, 0, 0); bo.diffuseTexture.wAng = 0.5 * Math.PI; bo.diffuseTexture.uScale = 1; material.subMaterials.push(f); material.subMaterials.push(ba); material.subMaterials.push(l); material.subMaterials.push(r); material.subMaterials.push(t); material.subMaterials.push(bo); // Store it on cache this._cache.materials[filename] = material; } return material; }; /** * Adds this map's data to a babylonJS scene * * @param {BABYLON.Scene} scene The scene to add the objects into. * @returns The scene where the objects were added. */ MBS.FPLE.Map.prototype.toScene = function(scene) { this._applyTiles(scene); this._applyEvents(scene); }; /** * Creates a cube to add into a FPLE scene. */ MBS.FPLE.Map.prototype._createCube = function(name, scene) { var cube; if (!this._cubeMesh) { cube = BABYLON.Mesh.CreateBox(name, 1.0, scene); this._cubeMesh = cube; } cube = this._cubeMesh.clone(name); return cube; }; MBS.FPLE.Map.prototype._buildMesh = function(cubes, material) { var mesh = BABYLON.Mesh.MergeMeshes(cubes, true); mesh.subMeshes=[]; var verticesCount=mesh.getTotalVertices(); var i = 0, n; if (cubes[0]) { n = 0; mesh.subMeshes.push(new BABYLON.SubMesh(0, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(1, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(2, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(3, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(4, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(5, n++, verticesCount, i++ * 6, 6, mesh)); } if (cubes[1]) { n = 6; mesh.subMeshes.push(new BABYLON.SubMesh(0, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(1, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(2, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(3, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(4, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(5, n++, verticesCount, i++ * 6, 6, mesh)); } if (cubes[2]) { n = 12; mesh.subMeshes.push(new BABYLON.SubMesh(0, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(1, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(2, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(3, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(4, n++, verticesCount, i++ * 6, 6, mesh)); mesh.subMeshes.push(new BABYLON.SubMesh(5, n++, verticesCount, i++ * 6, 6, mesh)); } mesh.material = material; return mesh; }; /** * Adds this map's tiles to a babylonJS scene * * @param {BABYLON.Scene} scene The scene to add the cubes into. If not * defined, a new scene is used. */ MBS.FPLE.Map.prototype._applyTiles = function(scene) { // Forward declarations var tile, row, col, filename, material, cube; for (var x = 0; x < this._data.length; x++) { for (var y = 0; y < this._data[x].length; y++) { tile = this._data[x][y]; col = (Math.floor(tile / 128) % 2 * 8 + tile % 8); // srsly? row = (Math.floor(tile % 256 / 8) % 16); // wow, such formula // Do not draw the first tile at the first row if (col === 0 && row === 0) continue; material = this.getMaterial($dataMap.tilesetId, row, col, scene); var cubes = []; // Floor cube = this._createCube('floor' + x + '-' + y, scene); cube.position = new BABYLON.Vector3(-x, MBS.FPLE.floorHeight, y); cubes.push(cube); // Wall if ($gameMap.terrainTag(x, y) === MBS.FPLE.wallTerrain) { cube = this._createCube('wall' + x + '-' + y, scene); cube.position = new BABYLON.Vector3(-x, MBS.FPLE.wallHeight, y); cubes.push(cube); } // Ceiling /*if ($gameMap.regionId(x, y) === MBS.FPLE.ceilRegion) { cube = this._createCube('ceil' + x + '-' + y, scene); cube.position = new BABYLON.Vector3(-x, MBS.FPLE.ceilHeight, y); cubes.push(cube); }*/ for(var Lian=0;Lian