No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Refactor del mapa de juego

7/24
Recursos

Aportes 29

Preguntas 4

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Hola!

Lo que hice diferente fue crear un objeto literal del mapa, para poder luego solo usar sus funciones o cambiar las propiedades, que en este caso ser铆a el nivel.
Con este objeto literal creado, ya cuando se ejecuta el juego, solo especifico el nivel y luego le digo que lo renderice.
El otro punto diferente al del profe, es que para limpiar y transformar al mapa como lo necesito, use un match y expresiones regulares, para encontrar directamente cada fila.
Por lo dem谩s est谩 todo igual.

const canvas = document.getElementById('game');
const game = canvas.getContext("2d");
let canvasSize;
let canvasElement;

//creo un objeto literal del mapa, y agrego una propiedad que es el nivel y otra que es una funcion render
const map={
    lvl:0,
    render:function () {
        if(this.lvl>=maps.length){
            return console.log ("Ese mapa no existe")
        }
        // Encontramos el mapa y lo preparamos como queremos
        const Map = maps[this.lvl].match(/[IXO\-]+/g)
            .map(a => a.split(""))
        //  le configuramos las propeidades de los elementos que vamos a dibujar
        game.font = canvasElement + "px Verdana"
        game.textAlign = "end"
        // recorremos el mapa para poder obtener las coordenadas de cada una de las posiciones que necesitamos
        Map.forEach((x, xi) => {
        x.forEach((y, yi) => {
            const posX = canvasElement * (xi + 1)
            const posY = canvasElement * (yi + 1)
            game.fillText(emojis[y], posY, posX)
        })
    })
    }
}

window.addEventListener('load', setCanvasSize);
window.addEventListener('resize', setCanvasSize)


function setCanvasSize() {
    window.innerHeight > window.innerWidth
        ? canvasSize = window.innerWidth * 0.9
        : canvasSize = window.innerHeight * 0.7;


    canvas.setAttribute("height", canvasSize)
    canvas.setAttribute("width", canvasSize)
    canvasElement = canvasSize / 10;
    startGame()
}


function startGame() {
    map.lvl=1
    map.render()

}

mi soluci贸n b谩sica (bas谩ndome en el principio KISS xD (https://people.apache.org/~fhanik/kiss.html))

Para evitar complicarnos con el 铆ndice +1 al momento de renderizar los elementos, podemos utilizar los m茅todos del canvas: game.textBaseLine define la posici贸n vertical del texto en el canvas, recibe varios atributos que puedes revisar en la documentaci贸n. El valor 'top' hace que nuestro tome como superior la ubicaci贸n que le damos, de esta forma, si la coordenada y tiene el valor de 0, el texto no se pondr谩 por encima sino por debajo del 0, as铆 es como quedan alineados de tal forma que se vean completamente en el canvas.

Resumen de la clase

  • Explicaci贸n del c贸digo





  • Test


Para simplificar el reto.
Solo con el mapRows se puede realizar el recorrimiento.
Ya que se puede recorrer un string colocando el indice de la letra en la variable.
ejemplo mapRows[0][0] me daria la primar letra del primer array.
Ya no se necesitar铆a usar mapRowCols.

const mapRows = map.trim().split('\n');
  mapRows.forEach((row, rowIndex) => {
    for (let col = 0; col < row.length; col++) {
      const emoji = emojis[row[col]];
      const posX = elementsSize * (col + 1) + 5;
      const posY = elementsSize * (rowIndex + 1) - 10;
      game.fillText(emoji, posX, posY);
    }
  });

Este es una duda que me surgio en mis inicios en el Desarrollo, 驴porque un forEach y no un For normal o un map o cualquier metodo para recorer arrays?, y bien se hacen sobre todo por cuestiones de legibilidad del codigo, un for normal tiene mejor rendimiento en cuestion de CPU, sin embargo los metodos implicitos que poseen ya los lenguajes 1: nos ahorran tiempo para no estar declarnado los ciclos a manito el famoso no volver a inventar la rueda, y 2: los hace mucho mas entendible al momento de leer el codigo. (claramente ya en cuando avances mas te daras cuenta que hay mas factores que se tienen que tomar en cuenta como la mutabilidad pero principalmente estos dos primeros son los mas importantes cuando empiezas y te hacen bolas los ciclos) o ami me sirvio por lo menos

Lo mismo pero m谩s barato :v

No me gustaba que todo quedara algo descuadrado, as铆 que aplique una t茅cnica hecha por un compa帽ero en otra clase y cree las variables seg煤n mi criterio para entenderlas mejor:

const canvas = document.querySelector('#game');
const game = canvas.getContext('2d');
let canvas_size;
let elements_size;
let map;
let emoji;
let x;
let y;

window.addEventListener('load', calculate_canvas_size);
window.addEventListener('resize', calculate_canvas_size);

function calculate_canvas_size(){
    window.innerHeight > window.innerWidth
    ? canvas_size = window.innerWidth * 0.8
    : canvas_size = window.innerHeight * 0.8

    canvas.setAttribute('width', canvas_size);
    canvas.setAttribute('height', canvas_size);

    calculate_elements_size();
}

function calculate_elements_size(){
    elements_size = (canvas_size * 0.1) - 1;
    game.font = `${elements_size}px Verdana`;

    map = (maps[0].trim().split('\n')).map(x => x.trim().split(''));
    console.log({map});

    map.forEach((row, ri) => { // element, index
        row.forEach((col, ci) => {
            emoji = emojis[col];
            x = elements_size * ci;
            y = elements_size * (ri+1);

            game.fillText(emoji, x, y);
        });
    });
}

// registro de la consola: console log

XD soy el unico que toma los cursos de JS sin saber crear una civilizacion super avanzada con dicho lenguaje?

Yo en el paso anterior ya hab铆a definido una funci贸n para obtener los elementos del mapa

function getMaps(level) {
    const mapRows = maps[level].trim().split('\n');
    const mapCol = mapRows.map(row => row.trim().split(''));
    return mapCol
}

Pero lo del ciclo anidado de for no lo pude desenmara帽ar sola 馃き馃き

Antes de ver la clase lo hice con un ciclo FOR y .MAP, porque no conocia bien el metodo FOREACH. Asi me habia quedado:

const canvas = document.querySelector("#game");
const context = canvas.getContext("2d");

window.addEventListener("load", setCanvasSize);
window.addEventListener("resize", setCanvasSize);

let canvasSize;
let elementsSize;

function startGame() {
	context.textAlign = "end";
	context.font = elementsSize + "px Verdana";

	const map = maps[2];
	const cleanMap = map.trim().split("\n");
	const matrixMap = cleanMap.map((row) => row.trim().split(""));
	console.log(matrixMap);

	for (let i = 0; i < 10; i++) {
		matrixMap.map((row, indice) =>
			context.fillText(
				emojis[row[i]],
				elementsSize * (i + 1),
				elementsSize * (indice + 1)
			)
		);
	}
}

// context.fillRect(100, 100, 1, 1);
// context.clearRect(50, 0, 100, 50);
// context.font = "30px Cabin";
// context.fillStyle = "green";
// context.textAlign = "center";
// context.fillText("Fabio", 100, 100);

function setCanvasSize() {
	canvasSize;
	if (window.innerWidth >= window.innerHeight) {
		canvasSize = innerHeight * 0.8;
	} else {
		canvasSize = innerWidth * 0.8;
	}

	canvas.setAttribute("width", canvasSize);
	canvas.setAttribute("height", canvasSize);
	elementsSize = canvasSize * 0.1;

	startGame();
}

const mapaPrueba = maps[2].split(鈥欌)
let fila = 1;
let columna = 0;

mapaPrueba.forEach(a =>{
if (a == 鈥-鈥 || a == 鈥極鈥 || a == 鈥榅鈥 || a == 鈥業鈥){
if(columna < 10){ columna = columna +1} else{columna = 1}
game.fillText(emojis[a],elementosTamanio * (columna - 1), elementosTamanio * fila)
if(columna ==10){ fila = fila +1}
}
})

Para los que tienen a煤n problemas en que los emojis se salen de su pantalla (a煤n no he averiguado exactamente el por qu茅 suceder谩 esto) pero la soluci贸n que descubr铆 fue modificar los valores que se suman con los 铆ndices de 鈥渃ol鈥 y 鈥渞ow鈥, por ejemplo, en el c贸digo de JuanDc es:

const posX = elementsSize * (colI + 1);
const posY = elementsSize * (rowI + 1);

Pero yo le mov铆 y mov铆 los valores hasta que encajaron completamente todos los emojis dentro de los bordes del canvas, quedando el ciclo as铆:

mapRowCols.forEach((row, rowI) => {
    row.forEach((col, colI) => {
      const emoji = emojis[col];
      const posX = elementsSize * (colI + 1.2);
      const posY = elementsSize * (rowI + 0.85);
      game.fillText(emoji, posX, posY);
    });
  });

Dediquen un rato a buscar los valores que sean acordes a su c贸digo, yo prob茅 todo el responsive y funcion贸 perfecto incluso cambiando literalmente de monitor, as铆 que me funciona y lo dejar茅 quieto as铆 馃槄.

Algo que me alegra de ir avanzando en Js es que empiezas a tener mas iniciativa por modificar el codigo que ense帽an segun creas conveniente.
En mi caso, mi codigo quedo asi:

function initialPaint(blocksSize) {
  game.font = blocksSize * 0.9 + "px impact";

  const map = maps[2].trim();
  const mapRows = map.split("\n").map((row) => row.trim());

  for (let row = 0.85; row <= mapRows.length; row++) {
    for (let column = 0.05; column < 10; column++) {
      const emoji = emojis[mapRows[Math.floor(row)][Math.floor(column)]];

      game.fillText(emoji, blocksSize * column, blocksSize * row);
    }
  }
}

Las principales diferencias son:

  • El tama帽o de mi emoji es del 90% del tama帽o de la celda( la celda es el 10% del tama帽o del canvas) .
  • Puedo usar la variable de los for para ajustar la posicion de los emojis y que no les quede una parte oculta como se le ve al profe y a otros compa帽eros que han compartido. Basicamente esta es la razon por la que no use el el codigo refactorizado, si queria poder ajustar la posicion habria tenido que adicionar mas codigo. Supongo q es una cuestion de toma de desiciones y un poco de preferencias.

La desventaja es que debido a que la variable del for no es un entero debo usar Math.floor para convertirlo y usarlo para ubicar el emoji en el array.

Yo lo intent茅 con dos ciclos for of y fall茅. tengo el mismo c贸digo del profe solo cambi茅 una parte del c贸digo para centras las im谩genes dentro del canva.

function startGame () {

    console.log({canvasSize, elementsSize})

    game.font = elementsSize + 'px Verdana';
    game.textAlign = 'center';

    const map = maps[0];
    const mapRows = map.trim().split('\n');
    const columnsOfmapRows = mapRows.map(row => row.trim().split(''));

columnsOfmapRows.forEach((row, rowIndex) => {
    row.forEach((column, columnIndex) => {
        const emoji = emojis[column];
        const positionX = (elementsSize * 0.93)  * (columnIndex + 1) ;
        const positionY =  (elementsSize * 0.97) * (rowIndex + 1); 
        game.fillText(emoji, positionX, positionY)
        console.log(rowIndex)
    });
});

Hola, Yo pude hacerlo usando map y me resulto mucho mas facil

mapRowsCols.map((row, rowIndex) => {
  return row.map((col, colIndex) => {
    game.fillText(emojis[col], elementsSize * colIndex, elementsSize * (rowIndex + 1));
  });
});
function startGame(){
  game.font = elemtSize + 'px Verdana';
  game.textAlign = 'end';
  // for (let i = 1; i <= 10; i++) {
  //   game.fillText(emojis['X'], elemtSize*i+4, elemtSize-10);
  // }

  const map = maps[0];
  const mapRow = map.trim().split('\n');
  const mapRowCol = mapRow.map(row => row.trim().split(''));
  // console.log({mapRowCol})
  
  // for (let x = 1; x <= 10; x++) {
  //   for (let y = 1; y <= 10; y++) {
  //     game.fillText(emojis[mapRowCol[y-1][x-1]],elemtSize*x,elemtSize*y-10);
  //   }
  // }

  mapRowCol.forEach((row, x)=>{
    row.forEach((column, y)=>{
      const emoji=emojis[column]
      game.fillText(emoji,elemtSize*(y+1),elemtSize*(x+1)-10);
    })
  })

}

Les comparto mi soluci贸n para esta clase. 馃槃
He utilizado un ciclo forque cuenta hasta 100 para poder renderizar los caracteres y una serie de contadores que me ayudan a saber en la posici贸n en la que se tienen que dibujar cada car谩cter.
Les comparto los archivos .jscon los que estoy trabajando, el resultado que obtuve y el link del repositorio en GitHub.

maps.js

export const EMOJIS = {
    '-'              : ' ',
    'O'              : '馃捇',
    'X'              : '馃懢',
    'I'              : '鉁',
    'PLAYER'         : '馃懆鈥嶐煉',
    'BOMB_COLLISION' : '馃挜',
    'GAME_OVER'      : '馃憥',
    'WIN'            : '馃弳',
    'LIFE'           : '鉂わ笍'
};

const MAPS = [];

MAPS.push(`
    IXXXXXXXXX
    -XXXXXXXXX
    -XXXXXXXXX
    -XXXXXXXXX
    -XXXXXXXXX
    -XXXXXXXXX
    -XXXXXXXXX
    -XXXXXXXXX
    -XXXXXXXXX
    OXXXXXXXXX
  `);
MAPS.push(`
    O--XXXXXXX
    X--XXXXXXX
    XX----XXXX
    X--XX-XXXX
    X-XXX--XXX
    X-XXXX-XXX
    XX--XX--XX
    XX--XXX-XX
    XXXX---IXX
    XXXXXXXXXX
    `);
MAPS.push(`
    I-----XXXX
    XXXXX-XXXX
    XX----XXXX
    XX-XXXXXXX
    XX-----XXX
    XXXXXX-XXX
    XX-----XXX
    XX-XXXXXXX
    XX-----OXX
    XXXXXXXXXX
  `);
MAPS.push(`
    XXXXX----I
    XXXXX-XXXX
    XX----XXXX
    XX-XXXXXXX
    ------XXXX
    -XXXXX-XXX
    -------XXX
    X-XXXXXXXX
    X-----OXXX
    XXXXXXXXXX
  `);

export const MAPS_USE = MAPS.map(map => map.trim().replaceAll(' ', ''));

game.js

import { EMOJIS, MAPS_USE as MAP } from './maps.js';

const startGame = (fontSize, elementSize) => {
    GAME.font = `${fontSize}px sans-serif`;
    GAME.textAlign = 'left';

    let yDraw = elementSize;
    let xPositionEmoji = 0;
    let yPositionEmoji = 0;
    const MAP_EMOJIS = MAP[1]
        .split('\n')
        .map(row => row.split(''));

    for (let i = 0; i < 100; i++) {
        if (i % 10 === 0 && i !== 0) {
            yPositionEmoji++;
            xPositionEmoji = 0;
            yDraw = elementSize * (yPositionEmoji + 1) * 0.98;
        }

        const X_DRAW = elementSize * xPositionEmoji * 1.015;
        const EMOJI_DRAW = MAP_EMOJIS[yPositionEmoji][xPositionEmoji];

        GAME.fillText(EMOJIS[EMOJI_DRAW], X_DRAW, yDraw);
        xPositionEmoji++;
    }
};

const setCanvasSize = () => {
    const WIDTH_WINDOWS = window.innerWidth;
    const HEIGHT_WINDOWS = window.innerHeight;
    const IS_WIDTH_SMALLER = WIDTH_WINDOWS < HEIGHT_WINDOWS && WIDTH_WINDOWS < 550;
    const WIDTH_BASE = window.innerWidth * 0.9;
    const HEIGHT_BASE = window.innerHeight * 0.6;
    const SIDE_CANVAS = (IS_WIDTH_SMALLER)
        ? (WIDTH_BASE).toString()
        : (HEIGHT_BASE).toString();

    CANVAS.setAttribute('width', SIDE_CANVAS);
    CANVAS.setAttribute('height', SIDE_CANVAS);

    const ELEMENT_SIZE = Number(SIDE_CANVAS) / 10.25;
    const FONT_SIZE = ELEMENT_SIZE * 0.82;

    startGame(FONT_SIZE, ELEMENT_SIZE);
};

const CANVAS = document.querySelector('#main__game-container-id');
const GAME = CANVAS.getContext('2d');

window.addEventListener('load', setCanvasSize);
window.addEventListener('resize', setCanvasSize);

Resultado

Asi lo realize:

// * Inicio del juego 
const startGame = () => {

  game.font = elementsSize + 'px Verdana';
  game.textAlign = 'start';
  game.textBaseline = 'top';

  let map = maps[0];
  map = map.trim().split('\n');
  map = map.map(element => element.trim().split(''));

  map.forEach((row, rowIndex) => {
    row.forEach((col, colIndex) => {
      const emoji = emojis[col];
      game.fillText(emoji, elementsSize * colIndex, elementsSize * rowIndex)
    })
  });
};

Yo lo deje as铆, me parecio m谩s simple de leer:

const canvas = document.querySelector("#game");
const game = canvas.getContext("2d");

window.addEventListener("load",setCanvasSize);
window.addEventListener("resize",setCanvasSize);


let canvassize;

function setCanvasSize(){
    
    if( window.innerWidth > window.innerHeight ){
        canvassize = window.innerHeight*0.70;
    }else{
        canvassize = window.innerWidth*0.60;
        
    }  
    
    canvas.setAttribute("width", canvassize);
    canvas.setAttribute("height", canvassize);
    startGame()
}
function startGame(){
    // Espera que se cargue la p谩gina
    // game.fillRect(0,50,100,100);
    // game.clearRect(50,50,100,100);
    // game.fillStyle ="Purple"; 
    // game.font = "25px Verdana";
    // game.textAlign ="center"; //start, end, left, center, right
    // game.fillText("Platzi",50,50,200);
    // const valueheight = window.innerHeight; // height value of windows
    // const valuewidth = window.innerWidth; // width value of windows 

    /* other form to fill the map 
    const valuemaps = Object.keys(emojis);
    console.log(valuemaps);
    let count1 = 1;
    let count2 = 1;
    for (let i = 0; i <maps[0].length; i++) {
        for (let j = 0; j < valuemaps.length; j++) {
           if(maps[0][i] == valuemaps[j]){
            game.fillText(emojis[valuemaps[j]] ,elementSize * count1 , elementSize * count2);
            if(count1 == 10){
                count1 = 1;
                count2++;
            }else{
                count1++;
               
            }          
           }
        }
        if(count2 > 10){
            count2 = 1 ;
        }  
    }
    console.log({count1,count2})
    
    */
    
    const elementSize = canvassize/10;
    console.log({elementSize,game});  
    game.textAlign = "end";
    game.textBaseline = "bottom"; // align text en forma vertical 'top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom'
    game.font = String (elementSize -10) + "px Arial" ;
    
    const mapPerLevel = renderMap(1);
    for (let i = 0; i < 10; i++) {
        for (let j = 0; j < 10; j++) {

            game.fillText(emojis[mapPerLevel[j][i]] ,elementSize * (i+1) , elementSize * (j+1));             
        }
        
    }
    
}
function renderMap(level){

    const  filterMap = maps[level].trim().split("\n");
    const maprender = filterMap.map(function(key){ return key.trim().split("")});
    return maprender;
}
//console.log(renderMap(0));

no ser谩 lo mas eficiente pero me gusto como quedo

const canvas = document.querySelector('#game');
const juego  = canvas.getContext('2d');

window.addEventListener('load', redimencionar);
window.addEventListener('resize', redimencionar);

function redimencionar(){
    const canvas_t = (window.innerWidth < window.innerHeight ? window.innerWidth : window.innerHeight) *.75 ;
    canvas.setAttribute('width', canvas_t  );
    canvas.setAttribute('height', canvas_t );
    juego.textAlign='end';
    inicia(canvas_t / 10);}

function inicia(size_t = 0){
    juego.font = size_t - size_t / 10 +'px arial';
    const arreglo = map[2].match(/[IOX-]/g);

    arreglo.forEach((char, idx) => {
        const y = (~~(idx/10) + 1) * size_t - size_t / 5;
        const x = (idx - (~~(idx/10) * 10) + 1) * size_t + size_t / 10;
        
        juego.fillText(emojis[char], x, y );});}

Asi me quedo mi codigo, lo hize guiandome del ejemplo del Compa帽ero Tommy Toala Cox, me gusto su manera de usar el objeto, asi mismo en vez de usar width, use el vmin para darle el ancho y alto al canvas, asi me quedo:

const canvas = document.querySelector('#game');
const game = canvas.getContext('2d');
let canvasSize;
let elementSize;

const gameStart = {
  level: 1,
  render: function () {
    if (this.level >= maps.length) {
      return console.log("Ese mapa no existe")
    }
    const map = maps[this.level].match(/[IXO\-]+/g)
      .map(a => a.split(""))
    game.font = `${elementSize}px Verdana`;
    game.textAlign = 'center';
    game.textBaseline = 'middle';

    map.forEach((row, rowIndex) => {
      row.forEach((col,colIndex)=>{
        const emoji = emojis[col];
        const posX = elementSize * ((colIndex - 0.42) + 1);
        const posY = elementSize * ((rowIndex - 0.32) + 1);
        game.fillText(emoji, posX, posY);
      });
    });
  }
}


window.addEventListener('load', setCanvasSize);
window.addEventListener('resize', setCanvasSize);

function setCanvasSize() {
 canvasSize = Math.min(window.innerWidth, window.innerHeight) * 0.7;

  canvas.setAttribute('width', canvasSize);
  canvas.setAttribute('height', canvasSize);

  elementSize = canvasSize / 10.20;

  startGame();
}


function startGame() {
  gameStart.render()
}

Amo los metodos de Array con las Arrow functions , siempre van a dar una solucion mas clara !!

Usar maps puede ser la mejor opci贸n para si m谩s adelante los mapas tienen otro tama帽o, no tener que estar cambiando el tama帽o del bucle for manualmente, aunque claro tambien se podr铆a calcular el tama帽o previamente.
Como previamente hab铆a conseguido el mapa de otra forma, tuve que a帽adir un array.from()

const map = maps[1].trim().split("\n  ");
map.forEach((row, rowIdx) => {
  Array.from(row).forEach((col, colIdx) => {
    ctx.fillText(
      emojis[col],
      rowIdx * element_size + 2,
      (colIdx + 1) * element_size - 8
    );
  });
});

qued贸 un poco parecido al de la clase, solo ahorrando algunas variables:

// inicializar juego
function startGame() {
  // tama帽o elementos
  game.font = (elementsSize - 6) + 'px Verdana';
  game.textAlign = "end";

  // mapa del juego
  const map = maps[1];

// obtener arreglo de caracteres individuales
  const mapRowCols = map.trim().split('\n').map(row => row.trim().split(''));

  // index: obtener posiciones
  mapRowCols.forEach((row, rowIndex) => {
    row.forEach((col, colIndex) => {
      game.fillText(emojis[col], elementsSize * (colIndex + 1), elementsSize * (rowIndex + 1));
    });
  });
}

game.js

const canvas = document.querySelector("#game");
const game = canvas.getContext("2d");

window.addEventListener("DOMContentLoaded", startGame);
window.addEventListener("resize", setCanvasSize);

let elementsSize;
let map;

function startGame() {
  parseMap();
  setCanvasSize();
}

function setCanvasSize() {
  const canvasSize = Math.min(window.innerHeight, window.innerWidth) * 0.75;

  canvas.width = canvasSize;
  canvas.height = canvasSize;

  elementsSize = Math.floor(canvasSize / 10 - 1);

  game.font = `${elementsSize}px Verdana`;

  drawMap();
}

function drawMap() {
  game.clearRect(0, 0, canvas.width, canvas.height);

  map.forEach((row, y) => {
    row.forEach((emoji, x) => {
      game.fillText(emoji, x * elementsSize, (y + 1) * elementsSize);
    });
  });
}

function parseMap() {
  const mapString = maps[0].trim();
  const lines = mapString.split("\n").map((line) => line.trim());

  map = lines.map((line) => line.split("").map((symbol) => emojis[symbol]));
}

Interesante manera de usar los forEach anidados 馃槂

Con respecto a mi code anterior鈥olo quite el for y agregue un parametro a la funci贸n renderMap para que imprima el mapa que se envie como argumento.

function startGame(){
    game.font = elementSize + 'px Verdana';
    game.textAlign = 'end';

    const mapper = maps[0].match(/[IXO\-]+/g).map(x => x.split(""));

    mapper.forEach((row, y) => {
        row.forEach((col, x)  => {
            const emoji = emojis[col];
            const posX = elementSize *(x+1);
            const posY = elementSize *(y+1);
            game.fillText(emoji, posX, posY);
        });
        
    });