6

Stick Champ game in 90 lines of pure JavaScript

 2 years ago
source link: https://slicker.me/javascript/champ/stick_champ.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Stick champ game

Here's the code of our little game where our champ uses a stick to jump over stones (detailed explanation below):<html><body><canvas id="myCanvas" width="600" height="500" style='position:absolute; left: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 = 6, size = 40;let angle = -Math.PI / 2;let x, y, frame, currentStone, mode, run, offset, stickLength, stones; function reset() {    currentStone = 0;    x = 100;    y = 360;    frame = 0;    stones = [];    stickLength = 0;    offset = 0;    run = 0;    for (let i = 0; i < maxStones; i++) {        stones[i] = {            x: i * 300 + Math.floor(Math.random() * 80),            width: 50 + Math.floor(Math.random() * 50)        };    }    stones[0].x = 80;    mode = 'wait';} function animate() {    context.clearRect(0, 0, canvas.width, canvas.height);    context.fillText('Distance remaining: ' + (maxStones - currentStone - 1), 250, 100);    stones.forEach((stone)=>{        context.fillRect(stone.x - offset, 398, stone.width, 600);    }    );     context.drawImage(image, Math.floor(frame) * size, 0, size, size, x + size / 2, y, size, size);    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(currentStone, index);                    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 over. Click to restart', 20, 60);        } else            context.fillText('You win! Click to restart', 20, 60);    }    let x2 = x + (stickLength - run) * Math.cos(angle);    let y2 = y + (stickLength - run) * Math.sin(angle);    context.beginPath();    context.moveTo(x + size - run, y + 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>

Lines [1-8] set up the HTML5 Canvas and the 2d context
[9-10] invisible image that holds the spritesheet (20 frames of run sequence, 1 fall, 1 celebration):

sprite.png

[11-13] Declare game variables and constants:
[11] maximum number of stones (=distance to be covered), size of the sprite (40x40 pixels)
[12] initial angle of the stick - it goes straight up
[13] x - x coordinate of the champ
y - y coordinate of the top of the stick
frame - current animation frame
currentStone - how many stones have been reached
mode - game mode (wait/pointerdown/stickFall/gameOver)
run - the length of the current run
offset - the horizontal scroll offset of screen
stickLength - the current extension of the stick
stones - array of stone objects

[15-32] reset all variables to initial values
[24-29] randomize stone positions and widths

[34-96] main game loop:
[35] clear the frame
[36] show the remaining distance on the screen
[37-40] draw the stones (even if they don't fit on the screen - to keep things simple)
[42] draw the current animation frame of the sprite
If you need details about how drawImage works, click here
[44-46] if the pointer (mouse/touch) is pressed, increase the stick length
[47-51] if the stick is falling, increase the angle.
[49-50] if it fell all the way down, change game mode to "run"
[52-80] if we're in the 'run' mode:
[53-54] increase the offset and the length of the run
[55] sprite frame changes every 2 animation frames
[56-57] if we reached the end of the animation sequence in the spritesheet, go back to the beginning
[58-62] if the length of the run equals the end of the stick, reset the stick length, angle, run and switch to 'wait' mode
[63-74] check if we landed on the stone:
[63] assume we landed on an empty space
[64-65] compare the champ coordinates with each stone
[66] if the champ landed on a stone, correct the pessimistic assumption from [63]
[67] calculate the currentStone
[68-71] if the last stone was reached, you win!
[75-78] if the champ landed on an empty space, switch mode to gameOver and show the falling pose
[81-87] in the 'gameOver' mode:
[82-84] if you lost, you fall
[85-86] if you won, you won.
[88-89] calculate the coords of the end of the stick
[90-93] draw the stick
[94] trigger the next animation frame

[97-107] if the screen is clicked/touched:
[98-101] if we were waiting, we switch to the 'pointerdown' mode
[102-105] if we were in the 'gameOver' mode, the game is restarted
[108-111] if the pointer is released and we were in the 'pointerdown' mode, we switch to the 'stickFall' mode
[112] initiate the game
[113] start the animation

Enjoy the game!

Check out these programming tutorials:

JavaScript:

Goldmine - idle game (~200 lines)

Tunnel run game (~170 lines)

Tower game (84 lines)

Optical illusion (18 lines)

Spinning squares - visual effect (25 lines)

Oldschool fire effect (20 lines)

Fireworks (60 lines)

Animated fractal (32 lines)

Physics engine for beginners

Physics engine - interactive sandbox

Physics engine - silly contraption

Starfield (21 lines)

Yin Yang with a twist (4 circles and 20 lines)

Tile map editor (70 lines)

Sine scroller (30 lines)

Interactive animated sprites

Image transition effect (16 lines)

Your first program in JavaScript: you need 5 minutes and a notepad


Fractals in Excel

Python in Blender 3d:


3d fractal in Blender Python



About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK