最终结果:
![](https://img.haomeiwen.com/i13855172/ccc7265a9e10433d.png)
.js文件部分:
/*——————初始化部分——————*/
var nodeWH = 10 //初始化矩形的大小为10*10
var direction = 'right' //初始化蛇的运动方向,即开始游戏蛇的移动方向
var timer = null //初始化一个定时器,赋值为空
var nodes = []//初始化一个结点数组,用于存放蛇
var food = null//定义一个全局变量来初始化食物
var context = wx.createContext()//通过调用createContext()函数创建并返回绘图上下文
var lastPoint = null//定义一个全局变量,存放最后的一点
var isGameOver = false//定义一个全局变量,用到判定游戏的结束与否
var that//通过定义一个变量,到后面起到指定作用
var score = 0//初始化分数,定义一个全局变量
//定义一个函数获取单位结点的x,y轴坐标
function Node(x, y) {
this.x = x;
this.y = y;
}
/*——————创建蛇部分——————*/
function createSnake() {
//使用splice() 方法直接对数组进行修改
nodes.splice(0, nodes.length)
//初始化蛇身长度为3,用for来进行栈的自增
for (var i = 3; i >= 0; i--) {
//满足循环体的条件,下一个单位结点就往前推移
var node = new Node(nodeWH * (i + 0.5), nodeWH * 0.5)
//将每个新的单位结点入栈
nodes.push(node);
}
}
/*——————创建食物部分——————*/
function createFood() {
//食物刷新的生成的坐标
var x = parseInt(Math.random() * 24) * nodeWH + nodeWH * 0.5
var y = parseInt(Math.random() * 24) * nodeWH + nodeWH * 0.5
//如果食物的坐标在蛇身上,则重新创建
for (var i = 0; i < nodes.length; i++) {
//定义一个变量来存放每个节点
var node = nodes[i]
//判断每个结点的坐标是否和蛇身的节点坐标重叠,若是重叠,重新刷新坐标
if (node.x == x && node.y == y) {
createFood()
return
}
}
//若是坐标不重叠,直接创建食物坐标
food = new Node(x, y)
}
/*——————绘制食物和蛇部分——————*/
function draw() {
//对蛇的绘制
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i]
if (i == 0) {
context.setFillStyle('#531a74')
} else {
context.setFillStyle('#c7e139')
}
context.beginPath()
context.rect(node.x, node.y, nodeWH, nodeWH)
context.closePath()
context.fill()
}
//对食物的绘制
context.setFillStyle('#30ff00')
context.beginPath()
context.rect(food.x, food.y, nodeWH, nodeWH)
context.closePath()
context.fill()
wx.drawCanvas({
canvasId: 'snakeCanvas',
actions: context.getActions()
})
}
/*——————开始游戏部分——————*/
function startGame() {
//调用方向、创建蛇和食物等变量或函数来启动游戏
if (isGameOver) {
direction = 'right'
createSnake()
createFood()
score = 0
isGameOver = false
}
//控制蛇移动的速度,即画布刷新
timer = setInterval(move, 200)
}
/*——————判断蛇是否吃到食物以及得分部分——————*/
function isEatedFood() {
//定义一个变量来存放蛇头结点
var head = nodes[0]
//进行判断,若蛇头结点和食物的坐标重复即为吃到食物
if (head.x == food.x && head.y == food.y) {
//吃到吃食物后,分数增加
score++
//吃到食物后,将食物入栈,即增加蛇的长度
nodes.push(lastPoint)
//调用创建食物函数,再次刷新食物
createFood()
}
}
/*——————蛇的移动部分——————*/
function move() {
//将身体长度存放在一起,作为一个整体处理
lastPoint = nodes[nodes.length - 1]
//定义一个变量存放蛇头结点
var node = nodes[0]
//定义一个变量获取移动后的坐标
var newNode = { x: node.x, y: node.y }
switch (direction) {
//向上移动,即在Y轴方向上减去同等的单位大小,后面以此类推
case 'up':
newNode.y -= nodeWH;
break;
case 'left':
newNode.x -= nodeWH;
break;
case 'right':
newNode.x += nodeWH;
break;
case 'down':
newNode.y += nodeWH;
break;
}
//移动后将原有位置的元素出栈
nodes.pop()
//利用unshift向数组的开头添加一个或更多元素,并返回新的长度。
nodes.unshift(newNode)
moveEnd()
}
/*——————每次移动结束后部分——————*/
function moveEnd() {
//判定是否吃到食物
isEatedFood()
//判定是否超过画布或者撞到自身
isDestroy()
//绘制部分
draw()
}
/*——————游戏结束弹框部分——————*/
function gameOver() {
//游戏结束
isGameOver = true
//清空计时器,即清空画布的刷新,贪吃蛇不再移动
clearInterval(timer)
//调用显示弹框
wx.showModal({
//弹框标题
title: 'Game Over',
//弹框内容
content: '总得分:' + score + ',不服再来?',
confirmText: '不服',
//接口调用成功回调的函数
success: function (e) {
//若用户点击确定按钮,便回调startGame()函数,重新开始游戏
if (e.confirm == true) {
startGame()
}
//若用户点击取消按钮,不再回调任何函数
else {
console.log('cancel')
//等用户点击开始按钮再开始游戏
that.setData({
btnTitle: '开始'
})
}
}
})
}
/*——————判断蛇是否超过画布或撞到自身部分——————*/
function isDestroy() {
//定义一个变量存放蛇头结点
var head = nodes[0]
for (var i = 1; i < nodes.length; i++) {
//定义一个变量存放身体结点
var node = nodes[i]
//若蛇头结点坐标与身体结点坐标重合,这调用游戏结束函数
if (head.x == node.x && head.y == node.y) {
gameOver()
}
}
//判断蛇身是否在水平方向越界
if (head.x < 5 || head.x > 245) {
gameOver()
}
//判断蛇身是否在垂直方向越界
if (head.y < 5 || head.y > 245) {
gameOver()
}
}
/*——————对于绑定数据的处理部分——————*/
Page({
data: {
//绑定开始游戏数据
btnTitle: '开始'
},
//加载函数体内的函数
onLoad: function () {
that = this
createSnake()
createFood()
draw()
},
//改变方向数据函数
changeDirection: function (e) {
//若data.btnTitle的值为“开始”,这返回此值,并进行相应的操作
if ('开始' == this.data.btnTitle) return
//定义一个变量,使其成为触发事件的节点
var title = e.target.id
//若该节点事件为down这对应的事件为蛇向下移动
if (title == 'down' || title == 'up') {
if (direction == 'down' || direction == 'up') return
} else if (direction == 'left' || direction == 'right') return
direction = title;
},
//开始游戏的数据绑定函数
startGame: function () {
//定义一个变量来存放data.btnTitle的值
var title = this.data.btnTitle
//若data.btnTitle的值为“暂停”,则清除定时器,同时data.btnTitle的值显示为“开始”
if (title == '暂停') {
clearInterval(timer)
this.setData({
btnTitle: '开始'
})
}
//否则游戏呈进行状态,data.btnTitle的值显示为“暂停”
else {
startGame()
this.setData({
btnTitle: '暂停'
})
}
},
click:function(){
wx.redirectTo({
url: '../home/home',
})
}
})
.wxml部分:
![](https://img.haomeiwen.com/i13855172/4c1b2b32efd0f8de.png)
.wxss部分:
page{
height:100%;
width: 100%;
background-color: beige;
}
.canvas {
width:250px;
height:250px;
border: 5px solid black;
border-radius: 20rpx;
}
.backView {
width: 100%;
height: 55%;
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
}
.controlView {
width: 100%;
background-size: 100% 100%;
}
.btnClass{
background: transparent;
background-color: gray;
width:20%;
}
.btnClass_02{
background: transparent;
background-color: gray;
width:40%;
margin-top:20rpx;
}
.mid_control{
display: flex;
margin-top: 20rpx;
margin-bottom: 20rpx;
}
text{
font-family: "楷体";
}
网友评论