116行纯 JavaScript 的 Stick Champ 游戏

前端迷

共 4179字,需浏览 9分钟

 ·

2021-11-27 12:17

<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>


代码步骤拆解


[1-8] 行设置了 HTML5 Canvas 和包含 spritesheet的 2d 上下文

[9-10] 不可见图像(运行序列的 20 帧,1 次跌倒,1 次庆祝)

[11-13] 声明游戏变量和常量:

[11] 最大石头数(=要覆盖的距离),精灵的大小(40x40 像素)

[12] 棒的初始角度 - 它直线上升

[13] x - x 冠军的坐标

y - y摇杆

框架顶部坐标- 当前动画帧

currentStone - 已经达到了多少石头

mode - 游戏模式(wait/pointerdown/stickFall/gameOver)

run - 当前运行

偏移的长度- 屏幕水平滚动偏移

stickLength - 棍子的当前扩展

- 石头对象数组


[15-32] 将所有变量重置为初始值

[24-29] 随机化石头位置和宽度


[34-96] 主游戏循环:

[35] 清除框架

[36] 在屏幕上显示剩余距离

[37-40] 绘制石头(即使它们不适合屏幕 - 为简单起见)

[42] 绘制精灵的当前动画帧,如果您需要详细信息关于drawImage 的工作原理,点击这里

[44-46] 如果指针(鼠标/触摸)被按下,增加棍子长度

[47-51] 如果棍子正在下降,增加角度。

[49-50]如果一直往下掉,把游戏模式改成“跑”

[52-80] 如果我们处于“运行”模式:

[53-54] 增加偏移量和运行长度

[55] 精灵帧每 2 个动画帧改变一次

[56-57] 如果我们到达终点在 spritesheet 中的动画序列中,如果运行的长度等于摇杆的末端,则返回开始[58-62],重置摇杆长度、角度、运行并切换到“等待”模式

[63-74] ] 检查我们是否落在石头上:

[63] 假设我们落在一个空的空间

[64-65] 比较每个石头的英雄坐标

[66] 如果英雄落在石头上,更正 [63] 中的悲观假设

[67] 计算当前的石头

[68-71] 如果到达最后一块石头,你就赢了!

[75-78] 如果冠军降落在空地上,切换模式到 gameOver 并

在“gameOver”模式中显示下落姿势[81-87]:

[82-84] 如果你输了,你就下落

[85-86] ] 如果你赢了,你就赢了。

[88-89] 计算摇杆末端的坐标

[90-93] 绘制摇杆

[94] 如果点击/触摸屏幕,则触发下一个动画帧[97-107]:

[98-101] 如果我们正在等待,如果我们处于“gameOver”模式,我们切换到“pointerdown”模式[102-105],如果释放指针并且我们处于“pointerdown”模式,游戏将重新启动[108-111],我们切换到“stickFall”模式

[112] 启动游戏

[113] 开始动画

浏览 26
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报