canvas 绘制贪吃蛇游戏

3次阅读

共计 3224 个字符,预计需要花费 9 分钟才能阅读完成。

效果如下

代码
<!DOCTYPE html>
<html lang=”zh_CN”>
<head>
<meta charset=”UTF-8″>
<title> 贪吃蛇 </title>
<script src=”https://code.jquery.com/jquery-3.3.1.js”></script>
</head>
<body>
<canvas id=”canvas” width=”400″ height=”400″></canvas>
<script src=”./js/main.js”></script>
</body>
</html>
let canvas = document.getElementById(“canvas”);
let context = canvas.getContext(“2d”);
// 分数记录
let fraction = 0;
// 定义贪吃蛇的组成,方块对象
class Block{
// 按照 size 的大小划分行列
// 列
col;
// 行
row;
// 大小
size;
constructor(col, row, size){
this.col = col;
this.row = row;
this.size = size;
}
// 画方法
draw(){
context.fillRect(this.col * this.size, this.row * this.size, this.size, this.size);
}
}
// 蛇类
class Snake{
body = [new Block(20, 20, 10), new Block(20, 21, 10)];
direction = “right”;
apple;
constructor(apple) {
this.apple = apple;
}
draw(){
for(let i = 0; i < this.body.length; i++){
this.body[i].draw();
}
};
move(){
let head = this.body[0];
// 用于生成新蛇的方块
let newhead;
if(this.direction == “right”){
newhead = new Block(head.col + 1, head.row, head.size);
}
if(this.direction == “left”){
newhead = new Block(head.col – 1, head.row, head.size);
}
if(this.direction == “up”){
newhead = new Block(head.col, head.row – 1, head.size);
}
if(this.direction == “down”){
newhead = new Block(head.col, head.row + 1, head.size);
}
// 增加头部
this.body.unshift(newhead);
// 进行判断蛇头是否碰到了苹果,若碰到了则不删除最后一个方块,反之删除最后一个方块
if(newhead.col == this.apple.col
&& newhead.row == this.apple.row){
// 进行检测,如果生成在蛇身上,继续生成,反之结束循环
while(true){
this.apple.initialization();
for(let i = 0; i < this.body.length; i++){
if(this.apple.row == this.body[i].row
&& this.apple.col == this.body[i].col){
this.apple.initialization();
}
}
break;
}
// 分数加入
fraction++;
}else{
// 弹出
this.body.pop();
}
};
// 碰撞检测
impactChecking(){
// 获取头节点
let newBody = this.body[0];
console.log(newBody.col);
// 查看行,列是否超过边界
if(newBody.col > 40
|| newBody.row > 40
|| newBody.row < 0
|| newBody.col < 0){
alert(“ 游戏结束 ”);
fraction = 0;
this.body = [new Block(20, 20, 10), new Block(20, 21, 10)];
}
// 查看是否碰到自己身体
for(let i = 1; i < this.body.length; i++){
if(newBody.col == this.body[i].col
&& newBody.row == this.body[i].row){
alert(“ 游戏结束 ”);
fraction = 0;
this.body = [new Block(20, 20, 10), new Block(20, 21, 10)];
}
}
}
}
// 实物,苹果类
class Apple{
// 列
col;
// 行
row;
sizeR;
constructor(){
this.initialization();
};
// 初始化苹果
initialization(){
// 生成列坐标
this.col = Math.floor(Math.random() * (40 – 1) + 1);
// 生成行坐标
this.row = Math.floor(Math.random() * (40 – 1) + 1);
// 设置苹果半径
this.sizeR = 5;
}
// 画苹果的方法
draw(){
// 颜色
context.fillStyle = “Red”;
// 画苹果
context.beginPath();
// 圆心坐标
context.arc(this.col * this.sizeR * 2 + this.sizeR, this.row * this.sizeR * 2 + this.sizeR, this.sizeR, 0, Math.PI * 2, false);
// 填充
context.fill();
// 恢复原来颜色
context.fillStyle = “Black”;
}
}
// 生成一个苹果
let apple = new Apple();
// 生成一个蛇
let snake = new Snake(apple);
setInterval(() => {
context.clearRect(0, 0, 400, 400);
// 绘制分数
context.fillText(“ 分数为 ” + fraction, 10, 10);
// 绘制蛇
snake.draw();
// 对蛇进行移动
snake.move();
// 绘制苹果
apple.draw();
// 进行检测
snake.impactChecking();
context.strokeRect(0, 0, 400, 400);
}, 200);
// 对贪吃蛇控制
// 上下左右运动
$(“body”).keydown((event) => {
// 左
if(event.keyCode == 37 && snake.direction != “right”){
snake.direction = “left”;
}
// 上
if(event.keyCode == 38 && snake.direction != “down”){
snake.direction = “up”;
}
// 右
if(event.keyCode == 39 && snake.direction != “left”){
snake.direction = “right”;
}
// 下
if(event.keyCode == 40 && snake.direction != “up”){
snake.direction = “down”;
}
});
思路
思路,蛇由两个类组成,方块类和蛇类,蛇类的存在依赖于方块类。蛇类当中的 body 保存当前蛇类的所有的方块。绘图,直接遍历 body 内部的所有绘图方法。移动,根据保存的私有变量方向用来对数组中保存的方块对象进行更改还有一个苹果类。用于进行随机生成吃苹果,在移动方法中,如果蛇的头方块和苹果方块重合那么吃到苹果,重新调用生成苹果方法。碰撞检测,如果行和列超过范围,即碰撞发生最重要的,坐标行和列化,使用的时候乘以一个数就行

正文完
 0