Haz clic y mantén presionado en el cuadro azul para levantar el palo



Juego Stick champ

Aquí está el código de nuestro pequeño juego donde nuestro campeón usa un palo para saltar sobre piedras (explicación detallada abajo):

<html>
<body>
<canvas id="myCanvaswidth="600height="500style='position:absoluteleft:0;'></canvas>
<script>
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
context.font = 'bold 30px sans-serif';
context.lineWidth = 4;
let image = new Image();
image.src = "sprite.png";
const maxStones = 6size = 40;
let angle = -Math.PI / 2;
let xyframecurrentStonemoderunoffsetstickLengthstones;
 
function reset() {
    currentStone = 0;
    x = 100;
    y = 360;
    frame = 0;
    stones = [];
    stickLength = 0;
    offset = 0;
    run = 0;
    for (let i = 0i < maxStonesi++) {
        stones[i] = {
            xi * 300 + Math.floor(Math.random() * 80),
            width50 + Math.floor(Math.random() * 50)
        };
    }
    stones[0].x = 80;
    mode = 'wait';
}
 
function animate() {
    context.clearRect(00canvas.widthcanvas.height);
    context.fillText('Distance remaining: ' + (maxStones - currentStone - 1), 250100);
    stones.forEach((stone)=>{
        context.fillRect(stone.x - offset398stone.width600);
    }
    );
 
    context.drawImage(imageMath.floor(frame) * size0sizesizex + size / 2ysizesize);
    switch (mode) {
    case 'pointerdown':
        stickLength++;
        break;
    case 'stickFall':
        angle = angle + Math.PI / 64;
        if (angle >= 0)
            mode = 'run';
        break;
    case 'run':
        offset++;
        run++;
        frame = frame + .5;
        if (frame == 20)
            frame = 0;
        if (stickLength == run) {
            mode = 'wait';
            angle = -Math.PI / 2;
            stickLength = 0;
            run = 0;
            let gameOver = true;
            stones.forEach((stone,index)=>{
                if (offset + x + size > stone.x && offset + x < stone.x + stone.width - size) {
                    gameOver = false;
                    currentStone = Math.max(currentStoneindex);
                    if (currentStone == maxStones - 1) {
                        mode = 'gameOver';
                        frame = 21;
                    }
                }
            }
            );
            if (gameOver) {
                mode = 'gameOver';
                frame = 20;
            }
        }
        break;
    case 'gameOver':
        if (currentStone < maxStones - 1) {
            y++;
            context.fillText('Game overClick to restart', 2060);
        } else
            context.fillText('You winClick to restart', 2060);
    }
    let x2 = x + (stickLength - run) * Math.cos(angle);
    let y2 = y + (stickLength - run) * Math.sin(angle);
    context.beginPath();
    context.moveTo(x + size - runy + size);
    context.lineTo(x2 + size, y2 + size);
    context.stroke();
    window.requestAnimationFrame(animate);
}
 
window.onpointerdown = function() {
    switch (mode) {
    case 'wait':
        mode = 'pointerdown';
        break;
    case 'gameOver':
        mode = 'wait';
        reset();
    }
};
 
window.onpointerup = function() {
    if (mode == 'pointerdown')
        mode = 'stickFall';
};
reset();
animate();
</script>
</body>
</html>



Las líneas [1-8] configuran el Canvas HTML5 y el contexto 2d
[9-10] imagen invisible que contiene la hoja de sprites (20 cuadros de secuencia de carrera, 1 caída, 1 celebración):



[11-13] Declarar variables y constantes del juego:
[11] número máximo de piedras (=distancia a cubrir), tamaño del sprite (40x40 píxeles)
[12] ángulo inicial del palo - va directo hacia arriba
[13] x - coordenada x del campeón
y - coordenada y de la parte superior del palo
frame - cuadro de animación actual
currentStone - cuántas piedras se han alcanzado
mode - modo de juego (wait/pointerdown/stickFall/gameOver)
run - la longitud de la carrera actual
offset - el desplazamiento horizontal de la pantalla
stickLength - la extensión actual del palo
stones - matriz (array) de objetos de piedra

[15-32] restablecer todas las variables a sus valores iniciales
[24-29] aleatorizar posiciones y anchos de las piedras

[34-96] bucle principal del juego:
[35] limpiar el cuadro
[36] mostrar la distancia restante en la pantalla
[37-40] dibujar las piedras (incluso si no caben en la pantalla - para mantener las cosas simples)
[42] dibujar el cuadro de animación actual del sprite
Si necesitas detalles sobre cómo funciona drawImage, haz clic aquí
[44-46] si se presiona el puntero (ratón/táctil), aumentar la longitud del palo
[47-51] si el palo está cayendo, aumentar el ángulo.
[49-50] si cayó completamente, cambiar el modo de juego a "run"
[52-80] si estamos en el modo 'run':
[53-54] aumentar el desplazamiento y la longitud de la carrera
[55] el cuadro del sprite cambia cada 2 cuadros de animación
[56-57] si llegamos al final de la secuencia de animación en la hoja de sprites, volver al principio
[58-62] si la longitud de la carrera es igual al final del palo, restablecer la longitud del palo, ángulo, carrera y cambiar al modo 'wait'
[63-74] comprobar si aterrizamos en la piedra:
[63] asumir que aterrizamos en un espacio vacío
[64-65] comparar las coordenadas del campeón con cada piedra
[66] si el campeón aterrizó en una piedra, corregir la suposición pesimista de [63]
[67] calcular la currentStone (piedra actual)
[68-71] si se alcanzó la última piedra, ¡ganaste!
[75-78] si el campeón aterrizó en un espacio vacío, cambiar el modo a gameOver y mostrar la pose de caída
[81-87] en el modo 'gameOver':
[82-84] si perdiste, caes
[85-86] si ganaste, ganaste.
[88-89] calcular las coordenadas del extremo del palo
[90-93] dibujar el palo
[94] activar el siguiente cuadro de animación

[97-107] si se hace clic/toca la pantalla:
[98-101] si estábamos esperando, cambiamos al modo 'pointerdown'
[102-105] si estábamos en el modo 'gameOver', el juego se reinicia
[108-111] si se suelta el puntero y estábamos en el modo 'pointerdown', cambiamos al modo 'stickFall'
[112] iniciar el juego
[113] comenzar la animación

¡Disfruta el juego!



Repositorio de GitHub
Todo el código se proporciona bajo la licencia MIT