最終結果:
.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部分:
.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: "楷體";
}