实例:贪吃蛇游戏
第一部分:设置游戏界面,创建3个简单的函数:
- 游戏画板边框函数
- 计分函数
- 结束游戏函数
第二部分:制作游戏人物
- Block构造函数添加三个方法:
drawSquare
、drawCircle
、equal
- Snake构造函数添加四个方法:
draw
、move
、checkCollision
、setDirection
- Apple构造函数添加2个方法:
draw
、move
第三部分:添加事件处理程序
添加keydown事件处理程序
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<script>
//设置游戏界面
var canvas = document.getElementById("canvas"); //获取到canvas的id
var ctx = canvas.getContext("2d"); //在canvas上绘制2d图像
var width = canvas.width; //游戏界面宽为画板宽
var height = canvas.height; //游戏界面高为画板高
var bolckSize = 10; //一个格子10像素
var widthInBlocks = width / bolckSize; //宽分为10个格子
var heightInBlocks = height / bolckSize; //高分为10个格子
//游戏画板边框函数,边框在画布之内
var drawBroder = function () {
ctx.fillStyle = "gray"; //边框颜色
ctx.fillRect(0,0,width,bolckSize); //上边框,坐标(0,0),宽是400像素,高10像素
ctx.fillRect(0,height-bolckSize,width,bolckSize); //下边框,坐标(0,390),宽是400像素,高10像素
ctx.fillRect(0,0,bolckSize,height); //左边框,坐标(0,0),宽是10像素,高400像素
ctx.fillRect(height-bolckSize,0,bolckSize,height); //右边框,减去10个像素,坐标(390,0),宽是10像素,高400像素
};
//绘制计分函数
var score = 0; //初始化得分为0
var drawScore = function () {
ctx.font = "20px courier"; //文本大小和字体
ctx.fillStyle = "black"; //文本颜色
ctx.textAlign = "left"; //文本基线点在左
ctx.textBaseline = "top"; //文本基线在上
ctx.fillText("Score: " + score,bolckSize,bolckSize);
};
//结束游戏函数
var gameOver = function () {
clearInterval(intervalId); //清理画布
ctx.font = "60 Courier";
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("GAME OVER",width/2,height/2);
};
//Block构造方法,使用Block来创建网格中的方块对象,可以用来做蛇的身体段和苹果
var Block = function (col, row) { //Block构造函数接收两个参数坐标点
this.col = col;
this.row = row;
};
//添加drawSquare方法,是用来绘制蛇的身体段,接收一个参数——颜色
Block.prototype.drawSquare = function (color) { //这边需要注意的是坐标所在的位置是方块的左上角顶点,不是方块的中心
var x = this.col * bolckSize; //x轴,因为是以blockSize 为像素单位,所以需要乘上blockSize
var y = this.row * bolckSize; //y轴,同上
ctx.fillStyle = color; //设置方块的颜色
ctx.fillRect(x,y,bolckSize,bolckSize); //绘制方块,大小为blockSize
};
//圆函数,绘制苹果时需要
var circle = function (x,y,radius,boolean) { //圆函数接受4个参数,坐标轴x、y,半径以及是填充还是画圈
ctx.beginPath();
ctx.arc(x,y,radius,0,Math.PI *2,false);
if(boolean){
ctx.fill();
}else{
ctx.stroke();
}
};
//添加drawCircle方法,是用来绘制苹果的,接受一个参数——颜色
Block.prototype.drawCircle = function (color) { //圆圈方法为了在方块的中间,所以需要加上blockSize的一半
var centerX = this.col * bolckSize + bolckSize/2; //确定苹果 x 方向的位置,中心位置
var centerY = this.row * bolckSize + bolckSize/2; //确定苹果 y 方向的位置,中心位置
ctx.fillStyle = color; //确定苹果的颜色
circle(centerX,centerY,bolckSize/2,true); //绘制圆圈,半径为blockSize的一半
};
//添加equal方法,用来比较蛇头和苹果或蛇身任意部位是否在相同位置,接收一个参数——苹果或者蛇身的坐标
Block.prototype.equal=function (otherBlock) { //返回boolean,如果x,y都相同返回true,否则返回false
return this.col === otherBlock.col && this.row === otherBlock.row;
};
//Snake构造方法,初始化三个方块,并向右移动
var Snake = function () {
this.segments = [ //蛇身体分割为3个格子
new Block(7,5),
new Block(6,5),
new Block(5,5)
];
// this.direction = "right"; //貌似可以省略
this.nextDirection = "right"; //向右移动
};
//添加draw方法,给蛇上色
Snake.prototype.draw = function () {
for(var i = 0; i < this.segments.length; i++){ //遍历蛇的每一个方块,并给它上色
this.segments[i].drawSquare("blue"); //Block的drawSquare方法用来绘制蛇的身体段的的颜色
}
};
//添加move方法,控制蛇的方向
Snake.prototype.move = function () {
var head = this.segments[0];
var newHead;
this.direction = this.nextDirection; //把下一个方向赋值给当前方向
//实例化Block,作为蛇头,赋值给newHead,这里面的数字代表方格
if(this.direction === "right"){
newHead = new Block(head.col + 1,head.row);
}else if(this.direction === "down"){
newHead = new Block(head.col,head.row+1);
}else if(this.direction === "left"){
newHead = new Block(head.col - 1,head.row);
}else if(this.direction === "up"){
newHead = new Block(head.col,head.row - 1);
}
if(this.checkCollision(newHead)){ //检查有没有碰到头,如果碰到头游戏结束,并跳出move函数
gameOver();
return;
}
this.segments.unshift(newHead); //每次移动的时候在segments数组初始位置加上新的蛇头
if(newHead.equal(apple.position)) { //如果蛇头碰到苹果的位置,得分加1,苹果移动到新的位置
score++;
apple.move();
}
else{ //否则删除蛇的尾巴,这句是对应unshift那句,移动的时前面+1,并且后面-1
this.segments.pop();
}
};
//添加checkCollision方法,检查蛇头有没碰到边框或者自身,接受一个参数——蛇头,就是在move方法中的newHead
Snake.prototype.checkCollision =function (head) {
var leftCollision = (head.col === 0); //左边框,第0列是边框
var topCollision = (head.row === 0); //上边框,第0列是边框
var rightCollision = (head.col === widthInBlocks-1); //右边框,第39列是边框
var bottomCollision = (head.row === heightInBlocks -1); //下边框,第39列是边框
var wallCollision = leftCollision || topCollision || rightCollision ||bottomCollision; //判断是否是真
// var selfCollision = false;
for(var i = 0; i < this.segments.length; i++){ //遍历蛇的每一个方块
if(head.equal(this.segments[i])){ //如果蛇头等于蛇身的某一个方块,那么就是蛇头碰到自身了
var selfCollision = true;
}
}
return wallCollision || selfCollision; //返回boolean,只要一个是真的就返回
};
//添加设置方向方法,接受一个参数——新方向
Snake.prototype.setDirection = function(newDirection){
if(this.direction === "up" && newDirection === "down"){ //如果当前方向是上,新方向是下,新方向无效
return;
}else if(this.direction === "right" && newDirection === "left"){ //同上
return;
}else if(this.direction === "down" && newDirection === "up"){ //同上
return;
}else if(this.direction === "left" && newDirection === "right"){ //同上
return;
}
this.nextDirection = newDirection; //否则把新方向赋值给下一个方向
};
//Apple构造函数,绘制苹果
var Apple = function () {
this.position = new Block(10,10); //初始化苹果位置
};
//添加draw方法,绘制苹果
Apple.prototype.draw = function () {
this.position.drawCircle("limeGreen") //绘制一个绿色苹果
};
//添加move方法,移动苹果
Apple.prototype.move = function () {
var randomCol = Math.floor(Math.random() * (widthInBlocks -2)) + 1; //1-38随机数
var randomRow = Math.floor(Math.random() * (heightInBlocks -2)) + 1; //同上
this.position = new Block(randomCol,randomRow); //赋值给新坐标
};
var snake = new Snake();
var apple = new Apple();
//用setInterval来实现游戏动画
var intervalId = setInterval(function () {
ctx.clearRect(0,0,width,height);
drawScore();
snake.move();
snake.draw();
apple.draw();
drawBroder();
},200);
//添加keydow事件处理程序
var directions ={
37:"left",
38:"up",
39:"right",
40:"down"
};
$("body").keydown(function (event) {
var newDirection = directions[event.keyCode];
if(newDirection !== undefined){
snake.setDirection(newDirection);
}
});
</script>
</body>
这两天在学习贪吃蛇游戏,这些代码虽然已经能够看懂了,但是不看代码自己写,还是不知道怎么下手,难道这是新手普遍问题嘛?
贪吃蛇代码写到一半,没有思路了,笔记也没有整体脉络,心情很烦躁,去看了其他的学习视频,突然想到可以用思维导图来梳理程序脉络。
晚饭后花了两小时整理的程序脉络,有了这张图之后自己对程序框架了解也更显清晰了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。