Y yo como loco haciendo querer funcionar el Clearect jaja
Introducción
Programemos un juego con JavaScript
Canvas
¿Qué es canvas en JavaScript?
Tamaño del canvas y sus elementos
Canvas responsive
Mapa del juego
¿Qué es un array bidimensional?
Arreglos multidimensionales en JavaScript
Refactor del mapa de juego
Movimientos del jugador
Eventos y botones
Objeto playerPosition
Limpieza de movimientos
No te salgas del mapa
Colisiones
Detectando colisiones fijas
Detectando colisiones con arrays
Victoria: subiendo de nivel
Derrota: perdiendo vidas
Bonus: adictividad
Sistema de vidas y corazones
Sistema de tiempo y puntajes
¿Qué es localStorage?
Guardando records del jugador
Deploy
Depurando errores del juego
Desplegando el juego a GitHub Pages
Próximos pasos
Reto: reinicio del juego
Reto: timeouts de victoria o derrota
¿Quieres un simulador laboral?
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Juan David Castro Gallego
Aportes 52
Preguntas 0
Y yo como loco haciendo querer funcionar el Clearect jaja
Aquí mi solución para que la calaverita no se salga del canvas:
psdt: Lo del playerPosition.get() es por que lo hice con el objeto Map 😉.
function moveUp() {
let move = playerPosition.get('y') - elementSize;
(move < 20)
? playerPosition.set('y', playerPosition.get('y'))
: playerPosition.set('y', move);
startGame();
log({ playerPosition });
}
function moveDown() {
let move = playerPosition.get('y') + elementSize;
(move > canvasSize)
? playerPosition.set('y', playerPosition.get('y'))
: playerPosition.set('y', move);
startGame();
log({ playerPosition });
// log('Me quiero mover hacia abajo');
}
function moveLeft() {
let move = playerPosition.get('x') - elementSize;
(move < 20)
? playerPosition.set('x', playerPosition.get('x'))
: playerPosition.set('x', move);
startGame();
log({ playerPosition });
// log('Me quiero mover hacia la izquierda');
}
function moveRight() {
let move = playerPosition.get('x') + elementSize;
(move > canvasSize)
? playerPosition.set('x', playerPosition.get('x'))
: playerPosition.set('x', move);
startGame();
log({ playerPosition });
// log('Me quiero mover hacia la derecha');
}
Esta es la forma que utilicé después de unos ajustes; dentro de la función startGame():
if ((playerPos.x - elementSize) < 0){
buttonRIGHT();
} else if (playerPos.x > canvasSize + 1) {
buttonLEFT();
} else if (playerPos.y > (canvasSize + 1)) {
buttonUP();
} else if ((playerPos.y - elementSize) < 0) {
buttonDOWN();
}
Esta es mi solución para que que el jugador no se salga del mapa
function moveUp() {
if (playerPosition.y <= elementsSize + 1) {
console.log("no se mueve", playerPosition.y, elementsSize);
} else {
console.log("se mueve", playerPosition.y, elementsSize);
playerPosition.y -= elementsSize;
startGame();
}
console.log("Arriba");
}
function moveLeft() {
if (playerPosition.x <= elementsSize + 1) {
console.log("no se mueve",);
} else{
console.log("se mueve");
playerPosition.x -= elementsSize;
startGame();
}
console.log("Izquierda", playerPosition.x, elementsSize, canvasSize);
}
function moveRight() {
if (playerPosition.x >= canvasSize) {
console.log("no se mueve");
} else {
console.log("se mueve");
playerPosition.x += elementsSize;
startGame();
}
console.log("Derecha",playerPosition.x,elementsSize, canvasSize);
}
function moveDown() {
if (playerPosition.y >= canvasSize) {
console.log("no se mueve", playerPosition.y, canvasSize);
} else {
console.log("se mueve", playerPosition.y, canvasSize);
playerPosition.y += elementsSize;
startGame();
}
console.log("Abajo");
}
Lo solucione de esta forma. Ya que no podemos garantizar las medidas del canvas y no siempre dará 0 exacto. O llegar al borde exacto.
funcion ARRIBA
if(playerPosition.y>elementsSize)playerPosition.y -= elementsSize;
funcion IZQUIERDA
if(playerPosition.x>2*elementsSize)playerPosition.x -= elementsSize;
funcion DERECHA
if(playerPosition.x<canvasSize)playerPosition.x += elementsSize;
funcion ABAJO
if(playerPosition.y<canvasSize-elementsSize)playerPosition.y += elementsSize;
y con eso no se sale de los bordes
Esta es mi solución para que el player no se salga del canvas, pero deseando ver la solución del profe y del resto de compañeros:
function withinTheMargin() {
if (
playerPosition.x >= elementSize &&
playerPosition.x <= canvasSize &&
playerPosition.y >= elementSize &&
playerPosition.y <= canvasSize
) {
return true;
}
}
function moveUp() {
playerPosition.y -= elementSize;
if (withinTheMargin()) {
startGame();
} else {
playerPosition.y += elementSize;
}
}
esta fue mi solución para limitar el movimiento del jugador:
function moveUp(){
if(playerPosicion.y > 2*elementSize){
playerPosicion.y = (playerPosicion.y - elementSize)
movePlayer()
}
}
function moveLeft(){
if(playerPosicion.x > 2*elementSize){
playerPosicion.x = (playerPosicion.x - elementSize)
movePlayer()
}
}
function moveRight(){
if(playerPosicion.x < 9*elementSize){
playerPosicion.x = (playerPosicion.x + elementSize)
movePlayer()
}
}
function moveDown(){
if(playerPosicion.y < 10*elementSize){
playerPosicion.y = (playerPosicion.y + elementSize)
movePlayer()
}
}
function mapLimit() {
const canvasLimit = elementSize* 10
if (playerPosition.x >= canvasLimit) {
playerPosition.x -= elementSize
}
if (playerPosition.x < 0) {
playerPosition.x += elementSize
}
if (playerPosition.y >= canvasLimit) {
playerPosition.y -= elementSize
}
if (playerPosition.y < 0) {
playerPosition.y += elementSize
}
}
La llamaría después de detectar el movimiento
function movePlayer(direction) {
moves++
switch (direction) {
case 'moveUp':
playerPosition.y -= elementSize
break;
case 'moveLeft':
playerPosition.x -= elementSize
break;
case 'moveRight':
playerPosition.x += elementSize
break;
case 'moveDown':
playerPosition.y += elementSize
break;
default:
break;
}
mapLimit()
printMap()
game.fillText(emojis['PLAYER'], playerPosition.x, playerPosition.y)
}
Me paso lo mismo que en el minuto 5:20, tarde como 15 minutos en entender por qué no pasaba nada jaja.
Mi solución
Mi solución para el resto de movimientos: DERECHA, IZQUIERDA y ABAJO
Reto de clase: Limitar el movimiento hacia ARRIBA
Reto de clase: Limitar el movimiento hacia la IZQUIERDA
Reto de clase: Limitar el movimiento hacia la DERECHA
_
Reto de clase: Limitar el movimiento hacia ABAJO
hace un clases atras estaba pensando en eso, entrar en el ciclo for y hacer los re renders, aunque me parecia complicado podia ocupar mucha memoria.
mi solución fu colocar un condicional que no sobre pasara los limites del mapa a cada movimiento aunque el único movimiento que no limita tan exactamente es hacia la izquierda
function moverArriba(){
console.log('moverarriba');
if (playerPosition.y >= elementSize){
playerPosition.y -= elementSize
startGame();
}
}
function moverAbajo(){
console.log('moverabajo');
if (playerPosition.y <= (canvasSize-elementSize)){
playerPosition.y += elementSize
startGame();
}
}
function moverDerecha(){
console.log('moverderecha');
if (playerPosition.x <= (canvasSize-elementSize)){
playerPosition.x += (elementSize-1)
startGame();
}
}
function moverIzquierda(){
console.log('moverizquierda');
if (playerPosition.x >= elementSize){
playerPosition.x -= elementSize
startGame();
}
}
game.js
const canvas = document.querySelector("#game");
const game = canvas.getContext("2d");
window.addEventListener("DOMContentLoaded", startGame);
window.addEventListener("resize", setCanvasSize);
// Obtener referencias a los botones
const upButton = document.getElementById("up");
const leftButton = document.getElementById("left");
const rightButton = document.getElementById("right");
const downButton = document.getElementById("down");
// Agregar manejadores de eventos a los botones
upButton.addEventListener("click", () => movePlayer("up"));
leftButton.addEventListener("click", () => movePlayer("left"));
rightButton.addEventListener("click", () => movePlayer("right"));
downButton.addEventListener("click", () => movePlayer("down"));
document.addEventListener("keydown", handleKeyDown);
let playerPosition = {
x: undefined,
y: undefined,
};
function handleKeyDown(event) {
const key = event.key.toLowerCase();
let direction;
switch (key) {
case "arrowup":
case "w":
direction = "up";
break;
case "arrowleft":
case "a":
direction = "left";
break;
case "arrowright":
case "d":
direction = "right";
break;
case "arrowdown":
case "s":
direction = "down";
break;
default:
return;
}
// Realizar alguna acción basada en la dirección detectada
// Por ejemplo, llamar a una función para mover al jugador en esa dirección
movePlayer(direction);
}
let elementsSize;
let map;
function startGame() {
parseMap();
setCanvasSize();
}
function movePlayer(direction) {
// Realizar acciones según la dirección recibida
switch (direction) {
case "up":
if (playerPosition.y > 0) {
playerPosition.y -= 1;
// Lógica para mover al jugador hacia arriba
}
break;
case "left":
if (playerPosition.x > 0) {
playerPosition.x -= 1;
// Lógica para mover al jugador hacia la izquierda
}
break;
case "right":
if (playerPosition.x < 9) {
playerPosition.x += 1;
// Lógica para mover al jugador hacia la derecha
}
break;
case "down":
if (playerPosition.y < 9) {
playerPosition.y += 1;
// Lógica para mover al jugador hacia abajo
}
break;
default:
return;
}
// Actualizar el juego, dibujar el mapa actualizado, etc.
// ...
drawMap();
}
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);
if (emoji === "🚪") {
if (playerPosition.x === undefined && playerPosition.y === undefined) {
playerPosition = { x, y };
} // Utiliza object destructuring para simplificar la asignación de coordenadas
game.fillText(
emojis.PLAYER,
playerPosition.x * elementsSize,
(playerPosition.y + 1) * elementsSize
); // Utiliza la notación de puntos para acceder a las propiedades del objeto emojis
}
});
});
}
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]));
}
Mi solución fue bastante sencilla:
if(playerPosition.x <canvasSize/10){
return null
}
else{
playerPosition.x -= elementSize
}
Se puede hacer una condición que no haga nada si se cumple y caso contrario ejecute el movimiento.
function move_up(){
if(player_position.y > elements_size + 1){
player_position.y -= elements_size;
calculate_canvas_size();
}
console.log(player_position, canvas_size, elements_size);
}
function move_left(){
if(player_position.x +1 > elements_size){
player_position.x -= elements_size;
calculate_canvas_size();
}
console.log(player_position, canvas_size, elements_size);
}
function move_right(){
if(player_position.x < canvas_size*0.8){
player_position.x += elements_size;
calculate_canvas_size();
}
console.log(player_position, canvas_size * 0.8, elements_size);
}
function move_down(){
if(player_position.y < canvas_size * 0.9){
player_position.y += elements_size;
calculate_canvas_size();
}
console.log(player_position, canvas_size, elements_size);
}
Reto cumplido, solo agregue unas condicionales a cada direcci+on de movimiento.
Yo SI pude usando clearRect XD … Esta es mi solución, es bastante diferente, espero se entienda.
Explicacion del codigo:
function moveCharacter(dir, blocksSize) {
game.clearRect(
playerPosition.x,
playerPosition.y - blocksSize * 0.85,
blocksSize,
blocksSize
);
if (
playerPosition.x - startPosition.x <= blocksSize * 0.1 &&
playerPosition.y - startPosition.y <= blocksSize * 0.1
)
game.fillText(emojis["O"], startPosition.x, startPosition.y);
if (dir == "ArrowUp") playerPosition.y = playerPosition.y - blocksSize;
else if (dir == "ArrowRight")
playerPosition.x = playerPosition.x + blocksSize;
else if (dir == "ArrowDown") playerPosition.y = playerPosition.y + blocksSize;
else if (dir == "ArrowLeft") playerPosition.x = playerPosition.x - blocksSize;
game.fillText(emojis["PLAYER"], playerPosition.x, playerPosition.y);
}
Que pasa si no se pone el ClearRect?, no lo ponia y se reseteaba el juego, pero lo sobreescribe?, consume mas memoria?, para no salir del cuadro use:
function moveUp(){
if(playerPosition.y>elementSize){
playerPosition.y-=elementSize;
}
setCanvasSize();
}
function moveLeft(){
if(playerPosition.x > elementSize+1){
playerPosition.x -= elementSize;
}
setCanvasSize();
}
function moveRight(){
if(playerPosition.x<elementSize*10){
playerPosition.x+=elementSize;
}
setCanvasSize();
}
function moveDown(){
if(playerPosition.y < elementSize*10){
playerPosition.y+=elementSize;
}
setCanvasSize();
}
Solución al reto
if(direccion == 'Arriba'){
if(playerPosition.y != 0){
playerPosition.y -= size;
}
}else if(direccion == 'Abajo'){
if(playerPosition.y != canvas.height - size){
playerPosition.y += size;
}
}else if(direccion == 'Derecha'){
if(playerPosition.x != (canvas.width - size)){
playerPosition.x += size;
}
}else if(direccion == 'Izquierda'){
if(playerPosition.x != 0){
playerPosition.x -= size;
}
}
Intente resolver el reto y funciona. PERO, si se le da resize a la ventana se tiene que actualizar la página para que siga funcionando. 😒
function moveUp() {
console.log({playerPosition,elementSize,canvasSize});
if(playerPosition.y == elementSize) {
return;
}
playerPosition.y = parseFloat((playerPosition.y - elementSize).toFixed(2));
startGame();
}
function moveDown() {
console.log({playerPosition,elementSize,canvasSize});
if(playerPosition.y == canvasSize) {
return;
}
playerPosition.y = parseFloat((playerPosition.y + elementSize).toFixed(2));
startGame();
}
function moveLeft() {
console.log({playerPosition,elementSize,canvasSize});
if(playerPosition.x == elementSize) {
return;
}
playerPosition.x = parseFloat((playerPosition.x - elementSize).toFixed(2));
startGame();
}
function moveRight() {
console.log({playerPosition,elementSize,canvasSize});
if(playerPosition.x == canvasSize) {
return;
}
playerPosition.x = parseFloat((playerPosition.x + elementSize).toFixed(2));
startGame();
}
Esta fue mi solución para no salirme del mapa. Hice una función llamada limitMovement()
que se ejecuta cada vez que se quiera mover al jugador, es decir, la ejecución en encuentra dentro de la función movePlayer()
. Esta función evalúa si la posición del jugador es menor que 0, o mayor que el canvasSize
en ambas cordenadas (x, y). Si resulta que el jugador está fuera de los límites, corrige la posición sumando o restando 1 elementSize
respectivamente.
// Movement
function movePlayer() {
limitMovement();
game.fillText(emojis['PLAYER'], playerPosition.x, playerPosition.y);
}
function limitMovement() {
if (playerPosition.x < 0) {
console.log('Player left out');
playerPosition.x += elementSize;
}
if (playerPosition.x > (canvasSize - elementSize)) {
console.log('Player right out');
playerPosition.x -= elementSize;
}
if (playerPosition.y < 0) {
console.log('Player up out');
playerPosition.y += elementSize;
}
if (playerPosition.y > (canvasSize - elementSize)) {
console.log('Player down out');
playerPosition.y -= elementSize;
}
}
Yo solamente pude hacer mover la calaverita pero se me borraban todos los elementos. no encontre la forma de hacer que se queden todos los elementos
Esta es mi solucion para que no se salga del mapa.
Intente hacerlo con una funcion y no me dio.
function moveUp() {
clearGame();
if ((playerPosition.y - elementsSize) > 0) {
playerPosition.y -= elementsSize;
}
startGame();
movePlayer();
}
function moveLeft() {
clearGame();
if ((playerPosition.x - elementsSize - 3) > 0) {
playerPosition.x -= elementsSize;
}
startGame();
movePlayer();
}
function moveRight() {
clearGame();
if ((playerPosition.x + elementsSize - 4) < canvasSize) {
playerPosition.x += elementsSize;
}
startGame();
movePlayer();
}
function moveDown() {
clearGame();
if ((playerPosition.y + elementsSize - 4) < canvasSize) {
playerPosition.y += elementsSize;
}
startGame();
movePlayer();
}
function startGame(){
game.font = elemtSize + 'px Verdana';
game.textAlign = 'end';
const map = maps[0];
const mapRow = map.trim().split('\n');
const mapRowCol = mapRow.map(row => row.trim().split(''));
game.clearRect(0,0,canvasSize, canvasSize);
mapRowCol.forEach((row, x)=>{
row.forEach((column, y)=>{
const emoji=emojis[column]
const posX = elemtSize*(y+1)+10;
const posY = elemtSize*(x+1)-10;
game.fillText(emoji,posX ,posY);
if(column=='O'){
if(!playerPos.x && !playerPos.y){
playerPos.x = posX;
playerPos.y = posY;
}
}
})
});
movePlayer();
}
function movePlayer(){
game.fillText(emojis['PLAYER'], playerPos.x, playerPos.y)
console.log({playerPos})
}
//funciones para el movimiento
function moveUp(){
console.log('arriba')
//if(elemtSize<playerPos.y){
playerPos.y -= elemtSize;
startGame();
//}
}
function moveLeft(){
console.log('izquierda')
playerPos.x -= elemtSize;
startGame();
}
function moveRight(){
console.log('derecha')
playerPos.x += elemtSize;
startGame();
}
function moveDown(){
console.log('abajo')
playerPos.y += elemtSize;
startGame();
}
// funcion para el movimiento con las flechas
function pressArrow(event){
switch (event.key){
case 'ArrowUp':
moveUp();
break;
case 'ArrowLeft':
moveLeft();
break;
case 'ArrowRight':
moveRight();
break;
case 'ArrowDown':
moveDown();
break;
}
}
Mi solución para solo borrar el casillero actual y no el tablero.
https://i.imgur.com/RX9wjtn.png
Estoy utilizando el método clearRect para borrar el casillero por donde esta pasando el jugador y fillText para dibujar los elementos correspondiente a cada posición.
También estoy almacenando el mapa seleccionado en un variable global.
Saludos!
I use a flag to do that logic.
that logic
const renderMap = () => {
renderClear();
let map = maps[0];
map = map.trim().split('\n');
map = map.map(element => element.trim().split(''));
// console.log(map);
map.forEach((row, rowIndex) => {
row.forEach((col, colIndex) => {
const emoji = emojis[col];
const postX = elementsSize * (rowIndex + 1);
const postY = elementsSize * (colIndex + 1);
// *Establecemos la posición inicial del jugador
if (col == 'O') {
if (isStartGame) {
playerPosition.x = postY;
playerPosition.y = postX;
isStartGame = false;
}
}
game.fillText(emoji, postY, postX);
})
});
};```
Esta es mi solucion para no salirme del mapa:
function moveUp(){
playerPosition.y -= elementSize;
playerPosition.y = Math.max(elementSize, playerPosition.y)
startGame();
}
function moveDown(){
playerPosition.y += elementSize;
playerPosition.y = Math.min(canvasSize, playerPosition.y)
startGame();
}
function moveLeft(){
playerPosition.x -= elementSize;
playerPosition.x = Math.max(elementSize, playerPosition.x)
startGame();
}
function moveRight(){
playerPosition.x += elementSize;
playerPosition.x = Math.min(canvasSize, playerPosition.x)
startGame();
}
mi solucion
nota el metodo to fixed es para limitar los decimales si no
lo quieres no es necesario
crear un variable global llamada let arrayEspacio=[];
crear un funcion contructora
<function posicionesDisponibles(espacioX,espacioY) {
this.espacioX=espacioX;
this.espacioY=espacioY;
}>
en la funcion de startGame hacer estos cambios:
<mapRowCols.forEach((emoji,y) => {
emoji.forEach((emoji,x)=>{
if (emoji == ‘O’ && playerPosition.y==undefined && playerPosition.y undefined) {
playerPosition.x = elementsSize*(x);
playerPosition.y = elementsSize*(y+1);
let pd =new posicionesDisponibles(elementsSize*(x),elementsSize*(y+1));
arrayEspacio.push(pd);
}else if ((emoji == ‘-’ || emoji == ‘I’) && playerPosition.yundefined && playerPosition.y ==undefined) {
let pd =new posicionesDisponibles(elementsSize*(x),elementsSize*(y+1));
arrayEspacio.push(pd);
}
game.fillText(emojis[emoji],elementsSize*(x),elementsSize*(y+1));
});
});>
la funcionmoveUp quedaria asi:
<
function moveUp() {
let mover=false;
arrayEspacio.forEach(objeto=>{
if ((objeto.espacioY).toFixed(0)(playerPosition.y-elementsSize).toFixed(0)
&& (objeto.espacioX).toFixed(0)(playerPosition.x).toFixed(0)) {
console.log(“me movi”, (objeto.espacioY).toFixed(0),(playerPosition.y).toFixed(0));
mover=true;
}else{
console.log(“no me puedo mover”, (objeto.espacioY).toFixed(0),(playerPosition.y).toFixed(0));
}
});
if (mover) {
playerPosition.y -= elementsSize;
}
movePlayer();
setCanvasSize();
}>
Condicionales en cada movimiento, aplicando logica.
function moveUp(){
if(playerPosition.y < elementSize +2){
playerPosition.y = playerPosition.y
console.log(playerPosition);
renderPlayer();
}else{
playerPosition.y -= elementSize;
console.log(playerPosition);
starGame();
}
}
function moveDown(){
if(playerPosition.y >= canvasSize){
playerPosition.y = playerPosition.y
console.log(playerPosition);
starGame();
}else{
playerPosition.y += elementSize;
console.log(playerPosition);
starGame();
}
}
function moveR(){
if(playerPosition.x > (canvasSize-elementSize - 4)){
playerPosition.x = playerPosition.x
console.log(playerPosition);
starGame();
}else{
playerPosition.x += elementSize;
console.log(playerPosition);
starGame();
}
}
function moveL(){
if(playerPosition.x < 4){
playerPosition.x
console.log(playerPosition);
starGame();
}else{
playerPosition.x -= elementSize;
console.log(playerPosition);
starGame();
}
}
Mi solución. No es muy elegante, pero funciona
function moveUp() {
if (playerPosition.y - elementsSize > 0) {
playerPosition.y -= elementsSize;
startGame();
}
}
function moveLeft() {
if (playerPosition.x - elementsSize > elementsSize) {
playerPosition.x -= elementsSize;
startGame();
}
}
function moveRight() {
if (playerPosition.x + elementsSize < canvasSize + elementsSize) {
playerPosition.x += elementsSize;
startGame();
}
}
function moveDown() {
if (playerPosition.y + elementsSize < canvasSize + elementsSize) {
playerPosition.y += elementsSize;
startGame();
}
}
Esto fue lo que hice para no salirme del mapa:
function moveUp () {
console.log('Move up');
playerPossition.y -= elementSize;
if(playerPossition.y < 1) playerPossition.y = elementSize
startGame();
}
function moveLeft () {
console.log('Move Left')
playerPossition.x -= elementSize;
if(playerPossition.x < 0) playerPossition.x = 0
startGame();
}
function moveRight () {
console.log('Move Right')
playerPossition.x += elementSize;
if(playerPossition.x > canvasSize) playerPossition.x = canvasSize - elementSize
startGame();
}
function moveDown () {
console.log('Move Down')
playerPossition.y += elementSize;
if(playerPossition.y > canvasSize) playerPossition.y = canvasSize
startGame();
}
Código para que el PLAYER no se salga del canvas:
function moveUp() {
if(playerPosition.y - elementsSize > elementsSize) {
playerPosition.y = playerPosition.y - elementsSize;
startGame();
}
}
function moveLeft() {
if(playerPosition.x - elementsSize > elementsSize) {
playerPosition.x = playerPosition.x - elementsSize;
startGame();
}
}
function moveRight() {
if(playerPosition.x + elementsSize <= canvasSize) {
playerPosition.x = playerPosition.x + elementsSize;
startGame();
}
}
function moveDown() {
if(playerPosition.y + elementsSize <= canvasSize) {
playerPosition.y = playerPosition.y + elementsSize;
startGame();
}
}
como no estoy usando una matriz de 2 dimensiones mi solución es diferente a la de los demás
para mi caso yo lo hice de esta forma:
la razón de esto es que cree un array único en ves de una matriz ¿por que ? pues la vardad es que me encanta hardcorear XD
function cargarMapa(){
if(nivel_actual == nivel) return;
nivel_actual = nivel;
mapa = map[nivel].match(/[IOX-]/g);}
En fin asi queda mi codigo :
decidí hacerlo mas eficiente o casi ya saben usaría for en vez de forEach XD como sea por eso cree funciones que evitan la recarga con una bandera que indica cuando debe de recargarse y así 😄
//contect
const canvas = document.querySelector('#game');
const btnArriba = document.querySelector('#arriba');
const btnAbajo = document.querySelector('#abajo');
const btnDer = document.querySelector('#derecha');
const btnIzq = document.querySelector('#izquierda');
const juego = canvas.getContext('2d');
//signals:
window.addEventListener('load', resizeEvent);
window.addEventListener('resize', resizeEvent);
let posJugador = undefined; let mapa = Array(); let nivel = 0;
let prePosJugador = undefined; let celda_t = 0; let nivel_actual = undefined;
let canvas_t = 0; var actualizado = Boolean(false);
function resizeEvent(){
actualizado = false;
canvas_t = (window.innerWidth < window.innerHeight ? window.innerWidth : window.innerHeight) *.75 ;
canvas.setAttribute('width', canvas_t);
canvas.setAttribute('height',canvas_t);
celda_t = canvas_t / 10;
juego.textAlign='end';
juego.font = celda_t - celda_t / 10 +'px arial';
update();}
function update(){
cargarMapa();
clear();
paintEvent();
paintEventPlayer();
actualizado = true;}
function cargarMapa(){
if(nivel_actual == nivel) return;
nivel_actual = nivel;
mapa = map[nivel].match(/[IOX-]/g);}
function clear(){
if(!actualizado) {
juego.clearRect(0,0, canvas_t, canvas_t);
return;}
if(posJugador == prePosJugador) return;
// las sumas y restas de celda_t es mera estetica al momento de borrar no tiene mucha importancia
const x = posX(posJugador ) - celda_t / 10;
const y = posY(posJugador) + celda_t / 5;
const xp = posX(prePosJugador) - celda_t / 10;
const yp = posY(prePosJugador) + celda_t / 5;
juego.clearRect(x ,y , - celda_t, - celda_t);
juego.clearRect(xp - 2, yp - 1, -celda_t, -celda_t);}
function posY(indice){ return (~~(indice/10) + 1) * celda_t - celda_t / 5; }
function posX(indice){ return (indice - (~~(indice/10) * 10) + 1) * celda_t + celda_t / 10;}
function paintEvent(){
if(!actualizado)
mapa.forEach((char, idx) => {
if(char == 'O' && posJugador == undefined) posJugador = idx;
juego.fillText(emojis[char], posX(idx), posY(idx) );});}
function paintEventPlayer(){
if(mapa[posJugador] == 'I') {
nivel = nivel + 1 <= 2 ? ++nivel : 0;
posJugador = prePosJugador = undefined;
actualizado = false;
update();
return;}
if(posJugador != undefined && prePosJugador != posJugador){
const x = posX(posJugador);
const y = posY(posJugador);
if(mapa[posJugador] == 'X') juego.fillText(emojis['BOMB_COLLISION'], x, y); // agragar mas cosillas ;D
else juego.fillText(emojis['PLAYER'], x, y);
juego.fillText(emojis[mapa[prePosJugador]],posX(prePosJugador),posY(prePosJugador));}}
//signals:
window.addEventListener('keydown',keyMov);
btnArriba.addEventListener('click', movArriba);
btnAbajo.addEventListener('click', movAbajo);
btnDer.addEventListener('click', movDer);
btnIzq.addEventListener('click', movIzq);
//slots:
function keyMov(event){
switch(event.keyCode){
case 37: movIzq(); break;//izquierda
case 38: movArriba(); break;//arriba
case 39: movDer(); break; //derecha
case 40: movAbajo(); break;//abajo
default: break;}}
function movArriba(){
prePosJugador = posJugador;
posJugador -= 10;
if(posJugador < 0) posJugador = prePosJugador;
update();}
function movAbajo(){
prePosJugador = posJugador;
posJugador += 10;
if(posJugador >= 100) posJugador = prePosJugador;
update();}
function movDer(){
prePosJugador = posJugador;
const pered = (~~(posJugador / 10)) *10 + 10;
++posJugador;
if(posJugador >= pered) posJugador = prePosJugador;
update();}
function movIzq(){
prePosJugador = posJugador;
const pered = ~~(posJugador /10) * 10;
--posJugador;
if(posJugador < pered) posJugador = prePosJugador;
update();}
Usé los siguientes condicionales para evitar que se salga de los bordes.
function moveUp(){
console.log('mover arriba');
if(!(player.y < elementSize)){
game.fillText(emojis['PLAYER'], player.x, player.y-=(elementSize));
startGame();
}
}
function moveDown(){
console.log('mover abajo');
if(!(player.y > canvasSize-elementSize)){
game.fillText(emojis['PLAYER'], player.x, player.y+=(elementSize));
startGame();
}
}
function moveLeft(){
console.log('mover izquierda')
if(!(player.x < elementSize*2)){
game.fillText(emojis['PLAYER'], player.x-=(elementSize), player.y);
console.log(player.x);
startGame();
}
}
function moveRight(){
console.log('mover derecha')
if(!(player.x > canvasSize)){
game.fillText(emojis['PLAYER'], player.x+=(elementSize), player.y);
startGame();
}
}
Esto del canvas es muy interesante pero hay que darle una atención más profunda.
Esta es mi solución, hice una funcion para renderizar el juego, no se que tan diferente quede de la planteada en la clase
const mapa = maps[0]
// El método trim elimina los espacios en blanco
const mapRows = mapa.trim().split('\n');
const mapRowCols = mapRows.map(row => row.trim().split(''))
function startGame() {
console.log('Mapas:', mapa, mapRows, mapRowCols)
if (!game) {
console.error('El contexto del lienzo no está disponible');
return;
}
game.font= elementSize + 'px Verdana'
mapRowCols.forEach((row, i) => {
row.forEach((col, j) => {
const emoji = emojis[col]
let posX = j * elementSize
let posY = (i+1) * elementSize
if (col == 'O'){
playerPosition = {
x: posX,
y: posY
}
console.log(playerPosition)
}
game.fillText(emoji, posX, posY)
movePlayer()
})
})
}
function renderGame() {
if (!game) return;
game.clearRect(0, 0, canvas.width, canvas.height);
mapRowCols.forEach((row, i) => {
row.forEach((col, j) => {
const emoji = emojis[col];
let posX = j * elementSize;
let posY = (i + 1) * elementSize;
game.fillText(emoji, posX, posY);
});
});
}
function movePlayer() {
if (!game) return
renderGame()
game.fillText(player, playerPosition.x, playerPosition.y);
}
function moveUp(){
playerPosition.y -= elementSize
movePlayer()
}
function moveLeft(){
playerPosition.x -= elementSize
movePlayer()
}
function moveRight(){
playerPosition.x += elementSize
movePlayer()
}
function moveDown(){
playerPosition.y += elementSize
movePlayer()
}
Solucion al reto
// Agregar eventos de clic a los botones
upButton.addEventListener('click', function() {
mover('arriba');
//Evitar que la salida del mapa
if(playerPosition.y>100){
playerPosition.y-=elementsSize;
}
startGame()
});
leftButton.addEventListener('click', function() {
mover('izquierda');
//Evitar que la salida del mapa
if(playerPosition.x>elementsSize){
playerPosition.x-=elementsSize;
}
startGame()
});
rightButton.addEventListener('click', function() {
mover('derecha');
//Evitar que la salida del mapa
if(playerPosition.x<canvasSize){
playerPosition.x += elementsSize;
}
startGame()
});
downButton.addEventListener('click', function() {
mover('abajo');
//Evitar que la salida del mapa
if(playerPosition.y<canvasSize){
playerPosition.y+=elementsSize;
}
startGame()
});
Yo tuve un problema en mi código!
al cambiar la tamaño del canvas, la posición del jugador se mantenía en la misma posición del tamaño anterior. y se descuadraba al punto de perder su posición
así que creé una variable global (fuera de la función) y la función de renderizado la dejé así:
if(window.innerHeight > window.innerWidth){
canvasSize= window.innerWidth *0.8
}
else{
canvasSize= window.innerHeight * 0.8
}
canvas.setAttribute('height',canvasSize)
canvas.setAttribute('width',canvasSize)
elementSize = canvasSize / 10
game.font = elementSize+'px Verdana'
game.textAlign='right'
let mapsRows=maps[level].trim().split('\n')
let levelMap=mapsRows.map(row=> row.trim().split(''))
for(let row=1; row <= 10; row++){
for(let col=1; col <= 10; col++){
game.fillText(emojis[levelMap[row-1][col-1]], elementSize*col, elementSize*row*0.97)
if(levelMap[row-1][col-1]=="O" && playerPosition.plx==undefined){
playerPosition.plx=elementSize*row*0.97
playerPosition.ply=elementSize*col
playerSize=elementSize
}
}
}
game.fillText(emojis['PLAYER'],playerPosition.plx,playerPosition.ply)
if(playerPosition.plx !== undefined){
if(playerSize !== elementSize){
let growth=elementSize / playerSize
playerPosition.plx= playerPosition.plx * growth
playerPosition.ply= playerPosition.ply * growth
playerSize=elementSize
}
}
}
Ah pues al final si había que renderizar el mapa de nuevo, no habrá otra manera xd?
Este codigo me ayudo a entender la funcion:
function moveUp() {
if (playerPosition.y - elementsSize > 0) {
playerPosition.y -= elementsSize;
}
console.log("Me quiero mover hacia arriba");
startGame();
}
function moveLeft() {
if (playerPosition.x - elementsSize > elementsSize) {
playerPosition.x -= elementsSize;
console.log("Me quiero mover hacia la izquierda");
startGame();
}
}
function moveRight() {
if (playerPosition.x + elementsSize < canvasSize + elementsSize) {
playerPosition.x += elementsSize;
console.log("Me quiero mover hacia la derecha");
startGame();
}
}
function moveDown() {
if (playerPosition.y + elementsSize < canvasSize + elementsSize) {
playerPosition.y += elementsSize;
console.log("Me quiero mover hacia abajo");
startGame();
}
}
Tuve que hace muchos cmabios al codigo pero logre completar el reto, espero que no me dé problemas mas adelante con los sieguientes modulos de la clase, lo que hice en principio fue desglosar el render del map en un sola funcion y esa funcion solo renderiza el mapa, luego hay otra funcion que renderiza el jugar, al cargar la pagina hay un render iniciar para cargar la posicion del jugador pero no se vuelve a llamar, cuando se mueve el jugador el vuelve a llamar el render del mapa el cual ahi limpia todo el canvas y vuelve a cargar el map, y luego llama a una funcion que es la que realiza el movimiento de la calavera
const canvas = document.querySelector('#game');
const game = canvas.getContext('2d');
const btnUp = document.getElementById('up');
const btnDown = document.getElementById('down');
const btnLeft = document.getElementById('left');
const btnRight = document.getElementById('right');
let canvasSize;
let elementsSize;
const playerPosition = {
x: '',
y: '',
initialX: '',
initialY: '',
}
window.addEventListener('load', setCanvasSize);
window.addEventListener('resize', setCanvasSize);
function setCanvasSize() {
if (window.innerHeight > window.innerWidth) {
canvasSize = window.innerWidth * 0.8
} else {
canvasSize = window.innerHeight * 0.8
}
canvas.setAttribute('width', canvasSize+16);
canvas.setAttribute('height', canvasSize+16);
elementsSize = canvasSize /10;
startGame();
}
function renderMap() {
game.font = `${elementsSize}px Verdana`;
game.textAlign = 'end';
const map = maps[0];
const mapRows = map.trim().split('\n'); //trim() es un metodo que remueve los espacios en blanco de los treing y lo devuelve en un nuevo `string` sin modificar el original, el .split, elimina el caracter que se le indique en el argumento
const mapRowsCols = mapRows.map(row => row.trim().split(''));
game.clearRect(0, 0, canvasSize, canvasSize);
mapRowsCols.forEach((row, rowIndex) => {
row.forEach((col, colIndex) => {
const emoji = emojis[col];
const posX = (elementsSize * (colIndex + 1))+12;
const posY = elementsSize * (rowIndex + 1);
if (col == 'O') {
playerPosition.initialX = posX;
playerPosition.initialY = posY;
};
game.fillText(emoji, posX, posY);
});
});
}
function renderPlayerPosition(){
game.fillText(emojis['PLAYER'], playerPosition.initialX, playerPosition.initialY)
}
function startGame() {
renderMap()
renderPlayerPosition()
playerPosition.x = playerPosition.initialX;
playerPosition.y = playerPosition.initialY;
}
function movePlayer() {
game.fillText(emojis['PLAYER'], playerPosition.x, playerPosition.y)
}
window.addEventListener('keyup', moveByKeys)
btnUp.addEventListener('click', moveUp);
btnLeft.addEventListener('click', moveLeft);
btnRight.addEventListener('click', moveRight);
btnDown.addEventListener('click', moveDown);
function moveByKeys(event) {
switch (event.key) {
case "ArrowUp": moveUp(); break;
case "ArrowLeft": moveLeft(); break;
case "ArrowRight": moveRight(); break;
case "ArrowDown": moveDown(); break;
}
}
function moveUp() {
console.log('Me quiero mover hacia arriba');
renderMap();
playerPosition.y -= elementsSize;
console.log({playerPosition});
movePlayer();
}
function moveLeft() {
console.log('Me quiero mover hacia a la izquierda');
renderMap();
playerPosition.x -= elementsSize;
console.log({playerPosition});
movePlayer();
}
function moveRight() {
console.log('Me quiero mover hacia a la derecha');
renderMap();
playerPosition.x += elementsSize;
console.log({playerPosition});
movePlayer();
}
function moveDown() {
console.log('Me quiero mover hacia abajo');
renderMap();
playerPosition.y += elementsSize;
console.log({playerPosition});
movePlayer();
}
Les comparto mi solución
Mi solución
Explicación:
Cada que muevo el player le pregunto si está en “borde”.Es decir, cuando llega a una posición donde el valor es el del elemento o e del tamaño del canvas.
Entonces, si su posición es igual al tamaño del elemento, su posición siempre será ese tamaño, si no es ese tamaño, entonces si puede moverte
function moveUp() {
map.playerPosition.x === canvasElement
? map.playerPosition.x = canvasElement
: map.playerPosition.x -= canvasElement
startGame()
}
function moveLeft() {
map.playerPosition.y === canvasElement
? map.playerPosition.y = canvasElement
: map.playerPosition.y -= canvasElement
startGame()
}
function moveRight() {
map.playerPosition.y === canvasSize
? map.playerPosition.y = canvasSize
: map.playerPosition.y += canvasElement
startGame()
}
function moveDown() {
map.playerPosition.x === canvasSize
? map.playerPosition.x = canvasSize
: map.playerPosition.x += canvasElement
startGame()
}
Aquí dejo todo mi codigo
const canvas = document.getElementById('game');
const game = canvas.getContext("2d");
const btnUp = document.querySelector('#up');
const btnLeft = document.querySelector('#left');
const btnRight = document.querySelector('#right');
const btnDown = document.querySelector('#down')
let canvasSize;
let canvasElement;
const map = {
lvl: 0,
playerPosition: {
x: undefined,
y: undefined,
render: function () {
game.fillText(emojis["PLAYER"], this.y, this.x);
}
},
render: function () {
if (this.lvl >= maps.length) {
return console.log("Ese mapa no existe")
}
const Map = maps[this.lvl].match(/[IXO\-]+/g)
.map(a => a.split(""))
game.clearRect(0, 0, canvasSize, canvasSize)
game.font = canvasElement + "px Verdana"
game.textAlign = "end"
Map.forEach((x, xi) => {
x.forEach((y, yi) => {
const posX = canvasElement * (xi + 1)
const posY = canvasElement * (yi + 1)
game.fillText(emojis[y], posY, posX)
if (this.playerPosition.x === undefined && this.playerPosition.y === undefined) {
if (y === "O") {
this.playerPosition.x = posX
this.playerPosition.y = posY
}
}
})
})
}
}
// const playerPosition={
// }
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 = 2
map.render()
map.playerPosition.render()
}
//moviemientos
window.addEventListener("keyup", moveByKey)
btnUp.addEventListener("click", moveUp)
btnLeft.addEventListener("click", moveLeft)
btnRight.addEventListener("click", moveRight)
btnDown.addEventListener("click", moveDown)
function moveUp() {
map.playerPosition.x === canvasElement
? map.playerPosition.x = canvasElement
: map.playerPosition.x -= canvasElement
startGame()
}
function moveLeft() {
map.playerPosition.y === canvasElement
? map.playerPosition.y = canvasElement
: map.playerPosition.y -= canvasElement
startGame()
}
function moveRight() {
map.playerPosition.y === canvasSize
? map.playerPosition.y = canvasSize
: map.playerPosition.y += canvasElement
startGame()
}
function moveDown() {
map.playerPosition.x === canvasSize
? map.playerPosition.x = canvasSize
: map.playerPosition.x += canvasElement
startGame()
}
function moveByKey(event) {
if (event.key === "ArrowUp") moveUp();
if (event.key === "ArrowLeft") moveLeft();
if (event.key === "ArrowRight") moveRight();
if (event.key === "ArrowDown") moveDown();
}
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?