即时可玩web小游戏(二):打砖块(支持移动端版) - 集成InsCode快来阅读并即时体验吧~

建议全屏或者新页面运行、首次运行需要冷启动,时间要一点,不如倒杯茶去~白屏也是需要等一下即可

已经实现的游戏一览:

游戏界面

游戏实现解析

代码参考Inscode - 查看文件即可,在本节,我将分步解析一个使用HTML5 Canvas和JavaScript实现的经典打砖块游戏。通过拆解游戏的各个模块,你将了解如何通过代码实现碰撞检测、动画循环和用户交互等核心功能。

页面布局与交互元素

index.html文件中,我们主要设置了游戏的基本界面,包括画布区域、得分显示、速度选择、控制按钮和开始按钮。

html 复制代码
<div class="game-container">
    <div style="display:flex;width:100%;justify-content:space-between;">
        <div id="score">得分: 0</div>
        <div class="settings">
            <select id="speedSelect" class="speed-select">
                <option value="1">慢速</option>
                <option value="2" selected>中速</option>
                <option value="3">快速</option>
            </select>
        </div>
    </div>
    <canvas id="gameCanvas"></canvas>
    <div class="controls">
        <button class="btn" id="leftBtn">←</button>
        <button class="btn" id="rightBtn">→</button>
    </div>
    <button id="startBtn">开始游戏</button>
</div>
  • <canvas id="gameCanvas">:用于绘制游戏元素(小球、砖块和挡板),游戏的主要区域。
  • 得分和速度选择:实时更新得分,速度选择允许玩家选择游戏的难度。
  • 控制按钮:使用左右箭头按钮(适用于触屏设备)控制挡板的移动。
  • 开始按钮:用于控制游戏的开始、暂停和重置。

JavaScript游戏逻辑与渲染

JavaScript部分实现了整个游戏的核心逻辑和绘图。

画布初始化与参数设置
javascript 复制代码
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
canvas.width = Math.min(400, window.innerWidth - 40);
canvas.height = 500;

我们创建画布并获取绘图上下文 (ctx)。接着,设定画布尺寸,使其在较小的屏幕上自适应宽度(限制最大宽度为400像素)。

游戏参数配置
javascript 复制代码
const paddleHeight = 10, paddleWidth = 75;
const brickRowCount = 5, brickColumnCount = 5, brickWidth = 60, brickHeight = 20;
const brickPadding = 8, brickOffsetTop = 30;
  • 挡板:宽75高10,用于控制小球的反弹。
  • 砖块:5行5列,每个砖块宽60高20,行列之间有8像素的间距。

这些参数定义了游戏的布局,确保砖块和挡板的尺寸适合画布。

速度配置与选择事件
javascript 复制代码
const speedConfigs = {
    1: { dx: 2, dy: -2, paddleSpeed: 5 },
    2: { dx: 3, dy: -3, paddleSpeed: 7 },
    3: { dx: 4, dy: -4, paddleSpeed: 9 }
};
let currentSpeed = speedConfigs[2];

游戏的难度通过speedConfigs配置。dxdy是小球在X和Y轴上的移动速度,paddleSpeed表示挡板的移动速度。玩家可以通过速度选择菜单 (speedSelect) 改变这些配置。

游戏初始化 (initGame)

initGame函数用于重置游戏状态,包括小球位置、挡板位置、砖块状态和得分。

javascript 复制代码
function initGame() {
    // 初始化挡板位置
    paddleX = (canvas.width - paddleWidth) / 2;
    // 初始化小球位置与速度
    x = canvas.width / 2;
    y = canvas.height - 30;
    dx = currentSpeed.dx;
    dy = currentSpeed.dy;
    // 初始化砖块数组
    for (let c = 0; c < brickColumnCount; c++) {
        bricks[c] = [];
        for (let r = 0; r < brickRowCount; r++) {
            bricks[c][r] = { x: 0, y: 0, status: 1 };
        }
    }
    // 重置得分
    score = 0;
    scoreElement.textContent = `得分: ${score}`;
    draw();
}
  • 挡板和小球初始位置:使小球位于画布下方中心,挡板位于画布底部中心。
  • 砖块数组 :砖块存储在二维数组bricks中。status属性表示砖块是否存在(1表示存在,0表示已被打掉)。
  • 重置分数:得分清零并更新显示。
控制事件

我们为触摸按钮和键盘添加事件监听,使玩家能够通过左右方向键或按钮移动挡板。

javascript 复制代码
document.addEventListener('keydown', (e) => { /*...*/ });
document.addEventListener('keyup', (e) => { /*...*/ });

通过这些事件,leftPressedrightPressed 控制挡板的移动方向。

碰撞检测 (collisionDetection)

collisionDetection 函数实现小球与砖块的碰撞检测,破坏被碰撞的砖块并更新得分。

javascript 复制代码
function collisionDetection() {
    for (let c = 0; c < brickColumnCount; c++) {
        for (let r = 0; r < brickRowCount; r++) {
            const b = bricks[c][r];
            if (b.status === 1) {
                if (x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
                    dy = -dy;
                    b.status = 0;
                    score++;
                    scoreElement.textContent = `得分: ${score}`;
                    if (score === brickRowCount * brickColumnCount) {
                        alert('恭喜你赢了!');
                        initGame();
                        return;
                    }
                }
            }
        }
    }
}
  • 碰撞检测 :检查小球是否在砖块范围内,若是则反转dy方向,破坏砖块(将其status设为0)。
  • 游戏胜利检测:如果破坏的砖块数等于总砖块数,显示胜利信息并重置游戏。
绘制函数
  1. 小球 :使用arc绘制圆形小球。
  2. 挡板 :使用rect绘制矩形挡板。
  3. 砖块 :遍历bricks数组,绘制每个未被破坏的砖块。
javascript 复制代码
function drawBall() { /*...*/ }
function drawPaddle() { /*...*/ }
function drawBricks() { /*...*/ }
游戏主循环 (draw)

draw函数作为主循环,不断更新游戏状态和画布绘制。

javascript 复制代码
function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBricks();
    drawBall();
    drawPaddle();

    if (gameStarted) {
        collisionDetection();

        // 小球碰到左右边界时反弹
        if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) dx = -dx;
        // 小球碰到顶部时反弹,碰到底部未击中挡板时游戏结束
        if (y + dy < ballRadius) dy = -dy;
        else if (y + dy > canvas.height - ballRadius) { /*...*/ }

        // 挡板移动
        if (rightPressed && paddleX < canvas.width - paddleWidth) paddleX += currentSpeed.paddleSpeed;
        else if (leftPressed && paddleX > 0) paddleX -= currentSpeed.paddleSpeed;

        // 更新小球位置
        x += dx;
        y += dy;
    }

    animationId = requestAnimationFrame(draw);
}
  • 清除画布:在每帧绘制前清除画布,避免前一帧图像残留。
  • 碰撞检测 :调用collisionDetection,更新小球的移动方向和砖块状态。
  • 边界反弹:小球到达边界时反弹,若未击中挡板则游戏结束。
  • 挡板移动:根据按键更新挡板位置。
  • 位置更新 :将小球的新位置传递给draw以绘制下一帧。
开始和重新开始

startBtn按钮控制游戏开始和重置。点击"开始游戏"将启动draw函数动画循环,再次点击会重置游戏状态。

总结

通过阅读本文,相信你不只是成功摸鱼(运行了前面的代码),还通过阅读代码解析,看到了HTML5 Canvas的强大绘图能力与JavaScript结合可实现流畅的动画和交互功能。

游戏的核心流程了解的差不多了,记得事件下哈~

相关推荐
码界奇点几秒前
Java Web学习 第1篇前端基石HTML 入门与核心概念解析
java·前端·学习·xhtml
云枫晖6 分钟前
Webpack系列-开发环境
前端·webpack
Rverdoser11 分钟前
制作网站的价格一般由什么组成
前端·git·github
拉不动的猪11 分钟前
深入理解 JavaScript 中的静态属性、原型属性与实例属性
前端·javascript·面试
linda261819 分钟前
链接形式与跳转逻辑总览
前端·javascript
怪可爱的地球人23 分钟前
骨架屏
前端
用户6778471506227 分钟前
前端将html导出为word文件
前端
前端付豪29 分钟前
如何使用 Vuex 设计你的数据流
前端·javascript·vue.js
李雨泽31 分钟前
通过 Prisma 将结构推送到数据库
前端
前端小万36 分钟前
使用 AI 开发一款聊天工具
前端·全栈