0%

原生js写贪吃蛇| JavaScript高级学习(二)

玩过的最早手机游戏——贪吃蛇🐍,满满都是回忆。快来试试吧(游戏链接在文末)

本文主要使用构造函数法

本文主要使用构造函数法

分析贪吃蛇游戏

所谓面向对象编程,对于所描述的物体,

物体的特征即为对象的属性、

物体的行为即为对象的方法。

所以可以把游戏分为两个对象,一个是食物food,一个是小蛇snake

贪吃蛇gif

food

构造food对象,food的属性有位置x,y、大小width,height、颜色color

1
2
3
4
5
6
7
function Food(x,y,width,height,color){ 
this.x = x || 0
this.y = y || 0
this.width = width || "15"
this.height = height || "15"
this.color = color || "black"
}

food是随机出现在地图map上,所以是脱离文档流的

初始化food

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//初始化食物,作为原型的方法
Food.prototype.init = function(map){
//创建div
var div = document.createElement("div")
map.appendChild(div)
//设置div样式
div.style.position = "absolute"
div.style.width = this.width + 'px'
div.style.height = this.height + 'px'
div.style.background = this.color
//随机出现食物位置
this.x = parseInt(Math.random()*(map.offsetWidth/this.width-2))
this.y = parseInt(Math.random()*(map.offsetHeight/this.height-2))
div.style.left = this.x*this.width + "px"
div.style.top = this.y*this.height + "px"
}

snake

把小蛇看成多个div块并跟随第一个头移动,把多个div存在一个数组里

1
2
3
4
5
6
7
8
9
10
11
12
13
function Snake(width,height,direction){
this.width = width || 15
this.height = height || 15

this.direction = direction || "right"
//小蛇的身体
this.body = [
{x:3,y:2,color:"black"}, //头
{x:2,y:2,color:"black"},
{x:1,y:2,color:"black"},
]

}

初始化小蛇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Snake.prototype.init = function(map){
//先清除以前的小蛇
remove()
for(var i=0 ; i<this.body.length ; i++){
//创建div
var div = document.createElement('div')
map.appendChild(div)
//设置样式
div.style.height = this.height + 'px'
div.style.width = this.width + 'px'
div.style.backgroundColor = this.body[i].color
div.style.position = "absolute"
div.style.left = this.body[i].x * this.width + 'px'
div.style.top = this.body[i].y * this.height + 'px'
//存起来
elements.push(div)
}
}

设置小蛇的移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Snake.prototype.move = function(food,map){

var i = this.body.length-1
for( ; i>0 ; i--){
this.body[i].x = this.body[i-1].x
this.body[i].y = this.body[i-1].y
}
//根据方向,蛇头移动
switch(this.direction){
case "up": {
this.body[0].y--
break
}
case "down": {
this.body[0].y++
break
}
case "right": {
this.body[0].x++
break
}
case "left": {
this.body[0].x--
break
}
}
//小蛇当前坐标
headX = this.body[0].x
headY = this.body[0].y
//食物当前坐标
foodX = food.x
foodY = food.y
var last
//设置吃食物,小蛇长度增加
if(headX == foodX && headY == foodY){

//更新食物
food.init(map)
//小蛇长度加一
last = this.body[this.body.length-1]
this.body.push({
x: last.x,
y: last.y,
color:last.color
})
//设置得分

}
//判断小蛇吃自己
var j = this.body.length-1

for(j=1; j<this.body.length ; j++){
if(headX === this.body[j].x && headY === this.body[j].y){

clearInterval(timer)
alert('游戏结束')
window.toHome()
}
}
}

Game

用geme对象初始化游戏来调用小蛇和食物

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
function Game(map,speed){
this.snake = new Snake()
this.food = new Food()
this.map = map
this.speed = speed || 150
that = this
}
Game.prototype.init = function(){
//初始化食物
this.food.init(this.map)
//根据按键改变方向
this.bindKey(this.snake,this.speed)
//小蛇移动
this.runSnake(this.food,this.map,this.speed)
}
Game.prototype.runSnake = function(food,map,speed){
clearInterval(timer)
//设置x轴最长距离
var maxX = map.offsetWidth/this.snake.width-2 //减去边框
var maxY = map.offsetHeight/this.snake.height-2
//定义小蛇头的坐标
var headX = this.snake.body[0].x
var headY = this.snake.body[0].y
//定义食物坐标
var foodX = food.x
var foodY = food.y

//设置小蛇一直走
timer = setInterval(function(){
//小蛇当前坐标
headX = this.snake.body[0].x
headY = this.snake.body[0].y
//食物当前坐标
foodX = food.x
foodY = food.y
this.snake.init(map)
this.snake.move(this.food,this.map)

//设置撞墙,游戏结束
if(headX >= maxX || headX <0){

alert("游戏结束!!!")
clearInterval(timer)
window.toHome()
}
if(headY >= maxY || headY <0){
alert("游戏结束!!!")
clearInterval(timer)
window.toHome()
}
return window.timer = timer
clearInterval(timer)
}.bind(that),speed)

}

监听键盘的方向建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Game.prototype.bindKey = function(snake,speed){
//获取用户按键,改变小蛇移动
document.addEventListener("keydown",function(e){
switch(e.keyCode){
case 40 :{
if(snake.direction !== 'up'){
snake.direction = "down"
}
break
}
case 38 :{
if(snake.direction !== "down"){
snake.direction = 'up'
}
break
}
case 37 :{
if(snake.direction !== "right"){
snake.direction = "left"
}
break
}
case 39 :{
if(snake.direction !== "left")
snake.direction = "right"
break
}
}

},false)
}

项目源码: https://github.com/Inkwall233/snake

项目演示: https://inkwall.cn/snake 快来试试吧🐍

案例学习于黑马js教程,需要学习资料的可以直接加我呦(这句话听着好熟悉的Σ(っ °Д °;)っ),一起学习,加油!