Por si a alguien le queda desalineado le muestro el codigo para solucionarlo
ERROR:
SOLUCION:
Y para completar todo el canvas:
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 49
Preguntas 9
Por si a alguien le queda desalineado le muestro el codigo para solucionarlo
ERROR:
SOLUCION:
Y para completar todo el canvas:
el eje X siempre es el horizontal y el eje Y el vertical, no entiendo por qué dice que en canvas es diferente a las matematicas si, al contrario, es igual
ver a juan multiplicar por 0 y esperar un resultado diferente Xd
mi solución inicial no-responsive, fue básicamente
canvasSize = window.innerHeight * 0.75;
canvas.setAttribute('width',canvasSize);
canvas.setAttribute('height',canvasSize);
no es lo que esperaba, perooo en cuanto a tener una simple proporción, digamos que, visualmente adecuada a la dinámica del juego, tipo:
(no tomen en consideración este comentario de ninguna forma para la clase xD)
Yo encontré esta solución:
let canvasSize = Math.min(window.innerHeight, window.innerWidth)*0.75;
canvas.setAttribute('width', canvasSize);
canvas.setAttribute('height', canvasSize);
PD: A mí me enseñaron que el eje horizontal es el de las X y el vertical el de las Y
Lo intente de esta manera:
inner width genera un cálculo diferente a inner heigth
Esto se debe a que las pantallas no son cuadrados, por lo general una pantalla es un rectángulo. Si pensamos en un celular, los celulares tienen una pantalla donde su heigth es más grande que su width, al hacer window.innerWidth * 0.5, window.innerHeight * 05. Estamos pidiendo la mitad de esto, pero una mita puede ser 640px y la otra de 360px. Por eso nunca nos va a dar un cuadrado de esta forma.
me quedo desalineado y probé con los aportes de otro compañero y aun asi no cuadraba
entonces pude corregirlo volviendo el elemento un poco mas pequeño
este es el código
Bien, lo hice bien desde el principio!
Aquí como lo solucioné:
let canvasSize = window.innerWidth > window.innerHeight ?
window.innerHeight * 0.7 : window.innerWidth * 0.9
Yo pensé en algo parecido a los breakpoints para hacer más responsive el canvas. Incluso me gustaría hacer cambios en el html para posicionar los botones y textos del contador después, según el device.
Creo que tengo un problema en mi codigo:
me queda asi en el browser:
En mi vida jamás he usado JavaScript
del curso básico de css y html me salte para acá XD
Aquí va mi solución antes de mirar más, antes de volver a darle play al video
let canvasSize;
let wHeight = window.innerHeight;
let wWidth = window.innerWidth;
(wHeight < wWidth)
? canvasSize = wHeight * 0.75
: canvasSize = wWidth * 0.75;
canvas.setAttribute('width', canvasSize);
canvas.setAttribute('height', canvasSize);
Esta es mi solución:
Solución 1:
canvas.setAttribute("width", window.innerWidth * 0.75);
canvas.height = canvas.getAttribute("width");
canvas.style.maxWidth = `${window.innerHeight * 0.75}px`; // seria lo mismo 75vh
Para ajustar las bombitas mejor agrege a la iteración dentro del for sumar +15 para que se desplace a la derecha.
Pudria ser con un min, pero todavia tenermos que hacer que, cuando la ventana cambie de tamaño, se ejecute los siguientes comandos
let canvasSize;
canvasSize = Math.min(canvasSize = window.innerHeight *.7, canvasSize = window.innerWidth *.7);
canvas.setAttribute( 'width', canvasSize );
canvas.setAttribute( 'height', canvasSize);
Lección 3: Tamaño del canvas y sus elementos.
Objetivo de la lección: Vamos a definir el ancho y el alto del canvas y a partir de esto vamos a calcular el alto y el ancho de lo que deberían medir nuestros elementos internos dentro del canvas para hacer nuestra grilla 10 x 10 para los distintos niveles de nuestro juego.
Basandome en los aportes de los demas, asi solucione el error grafico que aparecia
function startGame(){
let canvasSize;
let elementSize
if(window.innerHeight > window.innerWidth){
//Con esto si el height es mayor al widht, le damos un 80% porciento del width al width y al heigth
canvasSize = window.innerWidth * 0.8;
} else{
//Con esto si el widht es mayor a el height, el damos un 80% porciento del height al width y al height
canvasSize = window.innerHeight * 0.8;
}
canvas.setAttribute('width', canvasSize);
canvas.setAttribute('height', canvasSize);
//Para saber el tamaño de cada elemento dividimos el el tamaño total (canvasSize) por 10, ya que la cuadricula sera de 10 x 10
elementSize = (canvasSize * 0.98) / 10;
console.log({ canvasSize, elementSize })
//Hay que definir una fuente
game.font = (elementSize - 12) + 'px Verdana';
game.textAlign = '';
for (let i = 0; i < 10; i++) {
for(let z = 1; z < 11; z++){
game.fillText(emojis['X'], elementSize * i, elementSize * z);
}
}
Primero creo dos variables y le declaro el valor del alto y el ancho y después sumo esos dos valores para obtener uno y lo divido entre 2, ya que para mí; hay que dividirlo porque tenemos dos valores que queremos medir y por último multipliqué a 0.55 para darle un poquito de tamaño y no ocupe el 100% de ancho ni alto de la pantalla.
let valueWidth = window.innerWidth;
let valueHeight = window.innerHeight;
let canvasSize = (valueWidth + valueHeight) / 2;
canvas.setAttribute('width', canvasSize * 0.55);
canvas.setAttribute('height', canvasSize * 0.55);
Profe, la razón por la que no le salían las bombas cuando multiplicaba 0 * i, es porque todo numero multiplicado 0 por da 0. xD lo aprendí en los cursos de matemáticas de platzi . |-.-|—Io
Mi solución:
window.addEventListener('load', game);
window.addEventListener('resize', size);
let width = canvas.width;
let height = canvas.height;
let canvasSize;
function game(){
if(window.innerWidth < window.innerHeight){
canvasSize = window.innerWidth * 0.6;
}else if(window.innerHeight > height){
canvasSize = window .innerHeight * 0.6;
}
canvas.setAttribute('width', canvasSize);
canvas.setAttribute('height', canvasSize);
}
function size(){
game()
}
Me exploto la cabezaaaaaaaaa … … . . . MUchas maths
Mi solucion seria la siguiente
let canvasSize = window.innerWidth * 0.70;
Asi siempre mediran lo mismo
Recuerden poner el código de los emojis después de haberse ejecutado el canvas, pues si no lo hacen así, no aparecerá los elementos!
Les comparto mi propuesta de código en mi caso estoy intentando generarlo en TS igual dejare el código usando JS
/**
* FileName: index.js or index.ts
* Description: Es te archivo como para TS y JS quedan iguales.
*/
document.onreadystatechange = () => {
const { readyState } = document;
if (readyState === "complete") {
const { element } = CONFIG;
CanvasInit.init(element);
}
};
El siguiente Script realiza todas las acciones hasta este momento las cuales son,
/**
* FileName: CanvasInit.ts
*/
const CanvasInit = (() => {
type canvasElement = {
canvas: HTMLCanvasElement,
context: CanvasRenderingContext2D,
};
/**
* Permite dibujar en el lienzo.
*
* @param {canvasElement} setting Referencias al elemento del dom.
*
* @return {void}
*/
const __draw = (setting: canvasElement) => {
const { canvas, context } = setting;
const MESURE = __getResize(canvas) / 10;
context.font = `${MESURE}px Verdana`;
context.textAlign = "end";
for (let index: number = 1; index <= 10; index++) {
context.fillText("❤️", MESURE, MESURE * index);
context.fillText("💜", MESURE * index, MESURE);
}
};
/**
* Permite validar la existencia del elemento canvas adeas
* de conseguir el contexto.
*
* @param {string} idElement Identificador del elemento HTML.
*
* @return {canvasElement}
*/
const __getCanvas = (idElement: string): canvasElement => {
const $ELEMENT = <HTMLCanvasElement>document.querySelector(idElement);
const CONTEXT = <CanvasRenderingContext2D>($ELEMENT ? $ELEMENT.getContext("2d") : "");
return { canvas: $ELEMENT, context: CONTEXT };
};
/**
* Permite conseguir las dimenciones para el canvas ademas de
* conseguir la medida para los componnetes a pintar.
*
* @param {HTMLCanvasElement} element Referencia al elemento canvas del DOM.
*
* @return {number}.
*/
const __getResize = (element: HTMLCanvasElement): number => {
let mesure = 0;
if (element) {
const { innerHeight, innerWidth } = window;
const SIZE: number = (innerHeight > innerWidth) ? innerWidth : innerHeight;
mesure = SIZE * .8;
element.height = mesure;
element.width = mesure;
}
return mesure;
};
const init = (idElement: string) => {
const $CANVAS: canvasElement = __getCanvas(idElement);
if ($CANVAS.canvas) {
__draw($CANVAS);
window.addEventListener("resize", () => __draw($CANVAS))
}
};
return { init };
})();
Comparto el código en JS, prácticamente es lo mismo
"use strict";
const CanvasInit = (() => {
/**
* Permite dibujar en el lienzo.
*
* @param {canvasElement} setting Referencias al elemento del dom.
*
* @return {void}
*/
const __draw = (setting) => {
const { canvas, context } = setting;
const MESURE = __getResize(canvas) / 10;
context.font = `${MESURE}px Verdana`;
context.textAlign = "end";
for (let index = 1; index <= 10; index++) {
context.fillText("❤️", MESURE, MESURE * index);
context.fillText("💜", MESURE * index, MESURE);
}
};
/**
* Permite validar la existencia del elemento canvas adeas
* de conseguir el contexto.
*
* @param {string} idElement Identificador del elemento HTML.
*
* @return {canvasElement}
*/
const __getCanvas = (idElement) => {
const $ELEMENT = document.querySelector(idElement);
const CONTEXT = ($ELEMENT ? $ELEMENT.getContext("2d") : "");
return { canvas: $ELEMENT, context: CONTEXT };
};
/**
* Permite conseguir las dimenciones para el canvas ademas de
* conseguir la medida para los componnetes a pintar.
*
* @param {HTMLCanvasElement} element Referencia al elemento canvas del DOM.
*
* @return {number}.
*/
const __getResize = (element) => {
let mesure = 0;
if (element) {
const { innerHeight, innerWidth } = window;
const SIZE = (innerHeight > innerWidth) ? innerWidth : innerHeight;
mesure = SIZE * .8;
element.height = mesure;
element.width = mesure;
}
return mesure;
};
const init = (idElement) => {
const $CANVAS = __getCanvas(idElement);
if ($CANVAS.canvas) {
__draw($CANVAS);
window.addEventListener("resize", () => __draw($CANVAS));
}
};
return { init };
})();
Solucion 1:
let canvasSize;
if (window.innerWidth < window.innerHeight) canvasSize = window.innerWidth * 0.75;
else canvasSize = window.innerHeight * 0.75;
canvas.setAttribute('width', canvasSize);
canvas.setAttribute('height', canvasSize);
Pense hacerlo con un if pero la manera de Juan fue mas fácil y menos código.
let canvasSize;
if(window.innerWidth <= 450){
canvasSize = 300
}else if (window.innerWidth > 450 && window.innerWidth <= 650) {
canvasSize = 400
} else {
canvasSize = 600;
}
canvas.setAttribute('width', canvasSize )
canvas.setAttribute('height', canvasSize )
Muy buena clase me encanto.
Posiblemente a algunos de nosotros nos sucedió que los emojis se encontraban desfasados o muy cercanos al borde de nuestro canvas. Al dividir el total del canvas sobre 10, estamos dejando demasiado ajustado el espacio, por lo cual al dividirlo sobre 11 (esta medida me funcionó perfecto a mi), damos un espacio adicional para que todas las figuras/emojis entren aparezcan no tan cercanas al mismo.
const elementsSize = (canvasSize / 11);
game.font = elementsSize + 'px Verdana'
game.textAlign = 'center';
for (let i = 1; i <= 10; i++) {
game.fillText(emojis['X'], elementsSize * i , elementsSize);
}
en el eje cartesiano X siempre fue el eje de las absisas. No sé en que clase de matematicas el eje vertical es el X, ya que el vertical SIEMPRE va a ser la ordenada al origen (Y).
Pero bueno, mas alla de tu interpretacion erronea de los ejes, gran cursos parsero.
Ubicación de las BOMBAS con el ciclo FOR
game.js
const canvas = document.querySelector("#game");
const game = canvas.getContext("2d");
window.addEventListener("load", startGame);
function startGame() {
const canvasSize = Math.min(window.innerHeight, window.innerWidth) * 0.75;
canvas.width = canvasSize;
canvas.height = canvasSize;
const elementsSize = canvasSize / 10 - 1;
game.font = `${elementsSize}px Verdana`;
for (let i = 0; i < 10; i++) {
game.fillText(emojis["X"], elementsSize * i, elementsSize);
}
}
No me pregunten como lo hice
Interesante el canvas, a ver q tal en responsive
Con respecto al primer reto de la clase…hice que el width y height tomen el valor del width…de esta forma siempre se formará un cuadrado.
veo que mas de una persona no le cuadra el código alguna razón para esto 🤔🤔🤔
Me estaba encontrando con este problema al usar la solucion propuesta en la clase, comparto mi solucion por si a alguien mas le pasa
Retoque un poco el alineado de los elementos de esta forma
function startGame () {
let canvasSize;
if (window.innerHeight > window.innerWidth) {
canvasSize = window.innerWidth * 0.8
} else {
canvasSize = window.innerHeight * 0.8
}
canvas.setAttribute('width', canvasSize);
canvas.setAttribute('height', canvasSize);
const elementsSize = (canvasSize / 10);
game.font = elementsSize + 'px Verdana';
game.textAlign = "end";
// Tuve que añadir el 15 en i y el 10 en z para alinear correctamente los elementos del canvas
for (let i= 1; i <= 10; i++) {
for (let z = 1; z <= 10; z++) {
game.fillText(emojis['X'], elementsSize * i + 15, elementsSize * z - 10);
}
}
}
Quedando de esta forma:
Aquí está mi solución
function startGame() {
let canvasSize = () => {
if (window.innerHeight > window.innerWidth) {
canvasSize = window.innerWidth * 0.8;
} else {
canvasSize = window.innerHeight * 0.8;
}
return canvasSize;
};
const result = canvasSize();
canvas.setAttribute('width', result);
canvas.setAttribute('height', result);
console.log('Content loaded.');
}
window.addEventListener('load', startGame);
Esta fue mi solución para el canvasSize
. Lo que hice fue definir un valor mínimo y un valor máximo, si el canvasSize
excede esos límites, entonces se hace el ajuste, si no, el valor será window.innerWidth * 0.75
:
let canvasSize = window.innerWidth * 0.75;
const canvasMinSize = 288;
const canvasMaxSize = 500;
if (canvasSize < canvasMinSize) {
canvasSize = canvasMinSize;
}
if (canvasSize > canvasMaxSize) {
canvasSize = canvasMaxSize;
}
canvas.setAttribute('width', canvasSize);
canvas.setAttribute('height', canvasSize);
Dejo mi solución: Canvas responsive, medidas de ancho y alto equivalentes, tamaño máximo 800x800.
let size = 800;
if(window.innerWidth < 900 || window.innerHeight < 900){
size = window.innerWidth - 100;
if(window.innerHeight < size){
size = window.innerHeight - 100;
}
if(window.innerHeight < 300 || window.innerWidth < 300){
size = 200;
}
}
canvas.width = size;
canvas.height = size;
Esta es mi solución, el único punto negativo que le veo es que debes recargar la pagina para que tome la forma que corresponde al tamaño de la pantalla
Intento de solución
function starGame() {
let canvasSize;
canvasSize = (innerWidth * 0.9) / 3;
canvas.setAttribute("width", canvasSize);
canvas.setAttribute("height", canvasSize);
window.innerHeight;
}
Mi solución antes de continuar con la clase.
let sWidth = window.innerWidth
let sHeight = window.innerHeight
let canvaSize = sWidth > sHeight ? sHeight * 0.7 : sWidth * 0.7
canvas.setAttribute('width', canvaSize)
canvas.setAttribute('height', canvaSize)
Por si quieres llenar todo el cuadrado de bombas, este es el codigo.
for(let ver=1; ver<=10; ver++){
for (let hor = 1; hor <=10; hor++) {
game.fillText(emojis['X'],elementsSize*hor,elementsSize*ver)
}
}
Mi solucion fue utilizar screen.width , junto con una division de 3, el resultado es un 'cuadrado ’ pero no es responsivo como tal
<code>
let canvasSize = screen.width/3.2;
canvas.setAttribute('height',canvasSize);
canvas.setAttribute('width', canvasSize);
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?