una tablas tabla para laberinto juegos juego hechos games game figuras engine dinamicas datos crear con codigos code agregar javascript jquery function html5-canvas game-engine

tablas - juegos hechos en javascript



Creando plataformas 2d usando JavaScript (3)

Genial, he encontrado una solución.

Primero, eliminé toda la función "Gráficos" y la reemplacé por la función "código complejo", luego configuré las mismas tres imágenes para cada matriz de argumentos, como esta:

var dirt = Graphic(["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 40, 40);

pero esta no es una buena solución ya que necesitaré reutilizar las mismas imágenes nueve veces para llenar las 9 matrices, luego he agregado esto a la función Gráficos:

if (typeof topCenter === "undefined") { topCenter = topRight = middleLeft = middleCenter = middleRight = bottomLeft = bottomCenter = bottomRight = topLeft; }

permitiéndome declarar una única matriz y propagar su valor a la otra 9.

Y, para reducir la repetición del código, como se recomienda @Alnitak, creé una función para devolver un nuevo objeto Bitmap con una imagen aleatoria. Gracias.

Aquí está el código final:

function randomImage(arr) { return new createjs.Bitmap(arr[Math.floor(Math.random() * arr.length)]); } var Graphic = function (blockWidth, blockHeight, topLeft, topCenter, topRight, middleLeft, middleCenter, middleRight, bottomLeft, bottomCenter, bottomRight) { if (typeof topCenter === "undefined") { topCenter = topRight = middleLeft = middleCenter = middleRight = bottomLeft = bottomCenter = bottomRight = topLeft; } return { createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) { for (var blockY = 0; blockY < blockGroupHeight / blockHeight; blockY++) { for (var blockX = 0; blockX < blockGroupWidth / blockWidth; blockX++) { if (blockY == 0 && blockX == 0) { var obj = randomImage(topLeft); } if (blockY == 0 && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) { var obj = randomImage(topCenter); } if (blockY == 0 && blockX == (blockGroupWidth / blockWidth - 1)) { var obj = randomImage(topRight); } if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == 0) { var obj = randomImage(middleLeft); } if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) { var obj = randomImage(middleCenter); } if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) { var obj = randomImage(middleRight); } if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == 0) { var obj = randomImage(bottomLeft); } if (blockY == (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) { var obj = randomImage(bottomCenter); } if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) { var obj = randomImage(bottomRight); } obj.width = blockWidth; obj.height = blockHeight; if (typeof alpha !== ''undefined'') { obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block. } obj.x = Math.round(x + (blockWidth * blockX)); obj.y = Math.round(y + (blockHeight * blockY)); stage.addChild(obj); } } } } } var dirt = Graphic(40, 40, ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"]); var bigDirt = Graphic(40, 40, ["http://i.imgur.com/DLwZMwJ.png"], ["http://i.imgur.com/UJn3Mtb.png"], ["http://i.imgur.com/AC2GFM2.png"], ["http://i.imgur.com/iH6wFj0.png"], ["http://i.imgur.com/wDSNzyc.png", "http://i.imgur.com/NUPhXaa.png"], ["http://i.imgur.com/b9vCjrO.png"], ["http://i.imgur.com/hNumqPG.png"], ["http://i.imgur.com/zXvJECc.png"], ["http://i.imgur.com/Whp7EuL.png"]); dirt.createBlockAt(40, 40, 40 * 3, 40 * 3); bigDirt.createBlockAt(40 * 4, 40, 40 * 3, 40 * 3);

JSFiddle

Si bien no puedo aceptar esto como la respuesta correcta (porque soy el OP y tengo que esperar dos días para hacerlo), son totalmente bienvenidas las nuevas formas de mejorar mi código. Gracias.

EDIT: la respuesta de @ Alnitak fue mejor que la mía, entonces no marcaré esto como el correcto.

Estoy desarrollando un juego HTML5 Canvas utilizando EaselJS y he escrito una función que me permite crear "bloques" simplemente configurando una o más imágenes, tamaño y posición.

y por "bloques", lo que quiero decir es:

Estoy haciendo esto usando dos métodos:

Primer método:

Con este método, los bloques se crean en el espacio disponible dentro de la ubicación que he establecido, utilizando las imágenes al azar.

Segundo método:

Los bloques se crean dentro de la ubicación que he configurado usando imágenes específicas para la esquina superior izquierda, parte superior, esquina superior derecha, lado izquierdo, centro, lado derecho, esquina inferior izquierda, parte inferior e esquina inferior derecha, y puede haber más de una imagen individual para cada una de esas partes (por lo que el sistema usa una aleatoria para evitar repetir la misma imagen varias veces).

Ok, pero ¿cuál es el problema?

Esta función usa un trillón de 77 líneas (¡131 líneas que cuentan con la parte relacionada con la detección de colisiones) ! Sé que hay una mejor manera de hacerlo, que tomará aproximadamente la mitad o menos líneas de lo que está tomando ahora, pero no sé cómo hacerlo y cuando alguien me muestre, usaré el "camino correcto" para el resto de mi vida. ¿Me puedes ayudar?

Lo que quiero:

Una posible forma de utilizar menos líneas es usar un único "método" que me permita crear bloques compuestos por bloques que están compuestos por las 9 o más imágenes (simplemente no sé cómo hacerlo, y Sé que es difícil de entender. Intenta imaginar la tercera imagen que se usa 9 veces). // ¡Esta parte de la pregunta lo hace sobre el tema!

Tenga en cuenta que esta pregunta no es subjetiva, ya que el objetivo aquí es usar menos líneas, y no estoy usando la etiqueta EaselJS porque la pregunta no es específica de EaselJS, cualquiera con conocimiento de JavaScript puede responderme.

Aquí está mi función de JavaScript increíblemente grande:

var Graphic = function (src, blockWidth, blockHeight) { return { createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) { for (var blockY = 0; blockY < blockGroupHeight / blockHeight; blockY++) { for (var blockX = 0; blockX < blockGroupWidth / blockWidth; blockX++) { var obj = new createjs.Bitmap(src[Math.floor(Math.random() * src.length)]); obj.width = blockWidth; obj.height = blockHeight; if (typeof alpha !== ''undefined'') { obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block. } obj.x = Math.round(x + (blockWidth * blockX)); obj.y = Math.round(y + (blockHeight * blockY)); stage.addChild(obj); } } } } } var complexBlock = function (topLeft, topCenter, topRight, middleLeft, middleCenter, middleRight, bottomLeft, bottomCenter, bottomRight, blockWidth, blockHeight) { return { createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) { for (var blockY = 0; blockY < blockGroupHeight / blockHeight; blockY++) { for (var blockX = 0; blockX < blockGroupWidth / blockWidth; blockX++) { if (blockY == 0 && blockX == 0) { var obj = new createjs.Bitmap(topLeft[Math.floor(Math.random() * topLeft.length)]); } if (blockY == 0 && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) { var obj = new createjs.Bitmap(topCenter[Math.floor(Math.random() * topCenter.length)]); } if (blockY == 0 && blockX == (blockGroupWidth / blockWidth - 1)) { var obj = new createjs.Bitmap(topRight[Math.floor(Math.random() * topRight.length)]); } if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == 0) { var obj = new createjs.Bitmap(middleLeft[Math.floor(Math.random() * middleLeft.length)]); } if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) { var obj = new createjs.Bitmap(middleCenter[Math.floor(Math.random() * middleCenter.length)]); } if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) { var obj = new createjs.Bitmap(middleRight[Math.floor(Math.random() * middleRight.length)]); } if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == 0) { var obj = new createjs.Bitmap(bottomLeft[Math.floor(Math.random() * bottomLeft.length)]); } if (blockY == (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) { var obj = new createjs.Bitmap(bottomCenter[Math.floor(Math.random() * bottomCenter.length)]); } if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) { var obj = new createjs.Bitmap(bottomRight[Math.floor(Math.random() * bottomRight.length)]); } obj.width = blockWidth; obj.height = blockHeight; if (typeof alpha !== ''undefined'') { obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block. } obj.x = Math.round(x + (blockWidth * blockX)); obj.y = Math.round(y + (blockHeight * blockY)); stage.addChild(obj); } } } } } var bigDirt = complexBlock(["http://i.imgur.com/DLwZMwJ.png"], ["http://i.imgur.com/UJn3Mtb.png"], ["http://i.imgur.com/AC2GFM2.png"], ["http://i.imgur.com/iH6wFj0.png"], ["http://i.imgur.com/wDSNzyc.png", "http://i.imgur.com/NUPhXaa.png"], ["http://i.imgur.com/b9vCjrO.png"], ["http://i.imgur.com/hNumqPG.png"], ["http://i.imgur.com/zXvJECc.png"], ["http://i.imgur.com/Whp7EuL.png"], 40, 40); bigDirt.createBlockAt(0, 0, 40*3, 40*3);

De acuerdo ... Mucho código aquí, ¿cómo lo pruebo?

Aquí vamos: JSFiddle


No veo una manera fácil de reducir el número de líneas dadas las nueve ramas posibles, pero puedes reducir sustancialmente la repetición en tu código:

function randomImage(arr) { return new createjs.Bitmap(arr[Math.floor(Math.random() * arr.length)]); } if (blockY == 0 && blockX == 0) { var obj = randomImage(topLeft); } // etc

Re: las nueve ramas posibles, debe tener en cuenta que son mutuamente exclusivas, por lo que debe utilizar else if lugar de simplemente if , y que también están naturalmente agrupadas en grupos de tres, lo que sugiere que deben estar anidados.

EDITAR, de hecho, hay una forma de reducir mucho el tamaño de la función. Tenga en cuenta que para X e Y tiene tres opciones cada una (nueve en total). Es posible codificar qué matriz de imágenes desea en función de una tabla de búsqueda bidimensional:

var blocksHigh = blockGroupHeight / blockHeight; var blocksWide = blockGroupWidth / blockWidth; var blockSelector = [ [topLeft, topCenter, topRight], [middleLeft, middleCenter, middleRight], [bottomLeft, bottomCenter, bottomRight] ]; for (var blockY = 0; blockY < blocksHigh; blockY++) { var blockSY = (blockY == 0) ? 0 : blockY < (blocksHigh - 1) ? 1 : 2; for (var blockX = 0; blockX < blocksWide; blockX++) { var blockSX = (blockY == 0) ? 0 : blockY < (blocksWide - 1) ? 1 : 2; var array = blockSelector[blockSY][blockSX]; var obj = randomImage(array); ... } }

Tenga en cuenta las definiciones de blocksHigh y blocksWide exterior del bucle para reducir costosas operaciones de división repetidas.

Ver http://jsfiddle.net/alnitak/Kpj3E/


Bien, es casi un año después y decidí volver aquí para mejorar las respuestas existentes. La sugerencia de Alnitak de crear una "tabla de búsqueda bidimensional" fue genial, pero hay una forma aún mejor de hacer lo que estaba pidiendo.

Hojas de Sprite

El núcleo problemático es la necesidad de elegir muchas imágenes separadas y fusionarlas para crear un mosaico más grande. Para resolver esto, he fusionado todas las imágenes en una hoja de sprites. Luego, con EaselJS, he separado cada parte de la plataforma (topLeft, topCenter, etc.) en múltiples animaciones, y las imágenes alternativas de la misma parte de la plataforma que se usarían al azar se insertan dentro de la animación de la pieza predeterminada, como una matriz ( entonces topLeft puede ser cinco imágenes que se usan al azar).

Esto se logró haciendo una clase que crea un objeto contenedor EaselJS, coloca la hoja de sprites dentro de este contenedor, mueve la hoja de sprites a la posición correcta, almacena el marco en caché y actualiza la memoria caché del contenedor utilizando la operación compuesta composite overlay, que pone la memoria caché actual sobre la última; luego vuelve a hacer esto hasta que la plataforma finalice.

Mi sistema de detección de colisiones luego se aplica al contenedor.

Aquí está el código JavaScript resultante:

createMosaic = function (oArgs) { // Required arguments: source: String, width: Int, height: Int, frameLabels: Object oArgs.repeatX = oArgs.repeatX || 1; oArgs.repeatY = oArgs.repeatY || 1; this.self = new createjs.Container(); this.self.set({ x: oArgs.x || 0, y: oArgs.y || 0, width: ((oArgs.columnWidth || oArgs.width) * oArgs.repeatX) + oArgs.margin[1] + oArgs.margin[2], height: ((oArgs.lineHeight || oArgs.height) * oArgs.repeatY) + oArgs.margin[0] + oArgs.margin[3], weight: (oArgs.weight || 20) * (oArgs.repeatX * oArgs.repeatY) }).set(oArgs.customProperties || {}); this.self.cache( 0, 0, this.self.width, this.self.height ); var _bmp = new createjs.Bitmap(oArgs.source); _bmp.filters = oArgs.filters || []; _bmp.cache(0, 0, _bmp.image.width, _bmp.image.height); var spriteSheet = new createjs.SpriteSheet({ images: [_bmp.cacheCanvas], frames: {width: oArgs.width, height: oArgs.height}, animations: oArgs.frameLabels }); var sprite = new createjs.Sprite(spriteSheet); this.self.addChild(sprite); for (var hl = 0; hl < oArgs.repeatY; hl++) { for (var vl = 0; vl < oArgs.repeatX; vl++) { var _yid = (hl < 1) ? "top" : (hl < oArgs.repeatY - 1) ? "middle" : "bottom"; var _xid = (vl < 1) ? "Left" : (vl < oArgs.repeatX - 1) ? "Center" : "Right"; if(typeof oArgs.frameLabels[_yid + _xid] === "undefined"){ oArgs.frameLabels[_yid + _xid] = oArgs.frameLabels["topLeft"]; } // Case the expected frameLabel animation is missing, it will default to "topLeft" sprite.gotoAndStop(_yid + _xid); if (utils.getRandomArbitrary(0, 1) <= (oArgs.alternativeTileProbability || 0) && oArgs.frameLabels[_yid + _xid].length > 1) { // If there are multiple frames in the current frameLabels animation, this code choses a random one based on probability var _randomPieceFrame = oArgs.frameLabels[_yid + _xid][utils.getRandomInt(1, oArgs.frameLabels[_yid + _xid].length - 1)]; sprite.gotoAndStop(_randomPieceFrame); } sprite.set({x: vl * (oArgs.columnWidth || oArgs.width), y: hl * (oArgs.lineHeight || oArgs.height)}); this.self.updateCache("source-overlay"); } } this.self.removeChild(sprite); awake.container.addChild(this.self); };

Uso:

createMosaic({ source: "path/to/spritesheet.png", width: 20, height: 20, frameLabels: { topLeft: 0, topCenter: 1, topRight: 3, middleLeft: 4, middleCenter: [5, 6, 9, 10], middleRight: 7, bottomLeft: 12, bottomCenter: 13, bottomRight: 15 }, x: 100, y: 100, repeatX: 30, repeatY: 15, alternativeTileProbability: 75 / 100 });

Recomiendo usar el "createMosaic" como una función devuelta por un constructor que le transmite los argumentos requeridos, por lo que no tendrá que escribir la ruta de la imagen fuente, el ancho, el alto y el frameLabels cada vez que quiera crear una plataforma de tierra , por ejemplo.

Además, esta respuesta puede tener más LoC que las otras anteriores, pero está hecha de esta manera para tener más estructura.