vue实现打砖块
Vue 实现打砖块游戏
游戏初始化
创建 Vue 项目并安装依赖,使用 canvas 绘制游戏元素。初始化游戏画布、小球、挡板和砖块数组。
<template>
<canvas ref="gameCanvas" width="800" height="600"></canvas>
</template>
<script>
export default {
mounted() {
this.initGame();
},
methods: {
initGame() {
const canvas = this.$refs.gameCanvas;
this.ctx = canvas.getContext('2d');
this.setupGameElements();
this.gameLoop();
}
}
};
</script>
游戏元素设置
定义小球、挡板和砖块的初始属性。小球包括位置、速度和半径;挡板包括位置、宽度和高度;砖块生成二维数组。

setupGameElements() {
this.ball = { x: 400, y: 300, dx: 4, dy: -4, radius: 10 };
this.paddle = { x: 350, y: 550, width: 100, height: 15 };
this.bricks = [];
const brickRowCount = 5;
const brickColumnCount = 10;
for (let i = 0; i < brickRowCount; i++) {
this.bricks[i] = [];
for (let j = 0; j < brickColumnCount; j++) {
this.bricks[i][j] = { x: 0, y: 0, status: 1 };
}
}
}
绘制游戏元素
在 canvas 上绘制小球、挡板和砖块。砖块状态为 1 时绘制,为 0 时消失。
drawBall() {
this.ctx.beginPath();
this.ctx.arc(this.ball.x, this.ball.y, this.ball.radius, 0, Math.PI * 2);
this.ctx.fillStyle = '#0095DD';
this.ctx.fill();
this.ctx.closePath();
}
drawPaddle() {
this.ctx.beginPath();
this.ctx.rect(this.paddle.x, this.paddle.y, this.paddle.width, this.paddle.height);
this.ctx.fillStyle = '#0095DD';
this.ctx.fill();
this.ctx.closePath();
}
drawBricks() {
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 10; j++) {
if (this.bricks[i][j].status === 1) {
const brickX = j * 80 + 30;
const brickY = i * 30 + 50;
this.bricks[i][j].x = brickX;
this.bricks[i][j].y = brickY;
this.ctx.beginPath();
this.ctx.rect(brickX, brickY, 75, 20);
this.ctx.fillStyle = '#0095DD';
this.ctx.fill();
this.ctx.closePath();
}
}
}
}
游戏循环与碰撞检测
通过 requestAnimationFrame 实现游戏循环。检测小球与墙壁、挡板及砖块的碰撞,更新游戏状态。

gameLoop() {
this.ctx.clearRect(0, 0, 800, 600);
this.drawBricks();
this.drawBall();
this.drawPaddle();
this.collisionDetection();
if (this.ball.x + this.ball.dx > 800 - this.ball.radius || this.ball.x + this.ball.dx < this.ball.radius) {
this.ball.dx = -this.ball.dx;
}
if (this.ball.y + this.ball.dy < this.ball.radius) {
this.ball.dy = -this.ball.dy;
} else if (this.ball.y + this.ball.dy > 600 - this.ball.radius) {
if (this.ball.x > this.paddle.x && this.ball.x < this.paddle.x + this.paddle.width) {
this.ball.dy = -this.ball.dy;
} else {
alert('Game Over');
document.location.reload();
}
}
this.ball.x += this.ball.dx;
this.ball.y += this.ball.dy;
requestAnimationFrame(this.gameLoop);
}
collisionDetection() {
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 10; j++) {
const brick = this.bricks[i][j];
if (brick.status === 1) {
if (
this.ball.x > brick.x &&
this.ball.x < brick.x + 75 &&
this.ball.y > brick.y &&
this.ball.y < brick.y + 20
) {
this.ball.dy = -this.ball.dy;
brick.status = 0;
}
}
}
}
}
挡板控制
监听键盘事件控制挡板移动,限制挡板不超出画布边界。
mounted() {
this.initGame();
document.addEventListener('keydown', this.keyDownHandler);
document.addEventListener('keyup', this.keyUpHandler);
},
methods: {
keyDownHandler(e) {
if (e.key === 'Right' || e.key === 'ArrowRight') {
this.rightPressed = true;
} else if (e.key === 'Left' || e.key === 'ArrowLeft') {
this.leftPressed = true;
}
},
keyUpHandler(e) {
if (e.key === 'Right' || e.key === 'ArrowRight') {
this.rightPressed = false;
} else if (e.key === 'Left' || e.key === 'ArrowLeft') {
this.leftPressed = false;
}
}
}
游戏状态更新
在游戏循环中更新挡板位置,并检测游戏胜利条件。
gameLoop() {
if (this.rightPressed && this.paddle.x < 800 - this.paddle.width) {
this.paddle.x += 7;
} else if (this.leftPressed && this.paddle.x > 0) {
this.paddle.x -= 7;
}
let bricksLeft = 0;
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 10; j++) {
if (this.bricks[i][j].status === 1) {
bricksLeft++;
}
}
}
if (bricksLeft === 0) {
alert('You Win!');
document.location.reload();
}
}






