├── pages ├── index │ ├── index.json │ ├── index.wxss │ ├── index.wxml │ └── index.js ├── snakeGame │ ├── snakeGame.json │ ├── snakeGame.wxss │ ├── snakeGame.wxml │ └── snakeGame.js └── logs │ ├── logs.json │ ├── logs.wxss │ ├── logs.wxml │ └── logs.js ├── demo.gif ├── app.wxss ├── README.md ├── app.json ├── utils └── util.js ├── app.js └── LICENSE /pages/index/index.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /pages/snakeGame/snakeGame.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /pages/logs/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "查看启动日志" 3 | } -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/---snakeGame/HEAD/demo.gif -------------------------------------------------------------------------------- /pages/snakeGame/snakeGame.wxss: -------------------------------------------------------------------------------- 1 | /* pages/snake/snake.wxss */ 2 | page{ 3 | height: 100% 4 | 5 | } -------------------------------------------------------------------------------- /pages/logs/logs.wxss: -------------------------------------------------------------------------------- 1 | .log-list { 2 | display: flex; 3 | flex-direction: column; 4 | padding: 40rpx; 5 | } 6 | .log-item { 7 | margin: 10rpx; 8 | } 9 | -------------------------------------------------------------------------------- /pages/snakeGame/snakeGame.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /pages/logs/logs.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{index + 1}}. {{log}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 微信小程序-贪吃蛇snakeGame 2 | ### 微信小程序-小游戏项目(贪吃蛇) 3 | 微信小程序-贪吃蛇 功能: 得分计算/蛇长计算/游戏加速/蛇加长 (吃到食物, 蛇加长, 移动速度加快, 游戏结束计算得分/蛇长) 4 | 5 | ### 效果图集 6 | ![](/demo.gif) 7 | ### [简书地址](http://www.jianshu.com/p/df01c387fd66) http://www.jianshu.com/p/df01c387fd66 8 | 9 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/index/index", 4 | "pages/logs/logs", 5 | "pages/snakeGame/snakeGame" 6 | ], 7 | "window":{ 8 | "backgroundTextStyle":"light", 9 | "navigationBarBackgroundColor": "#fff", 10 | "navigationBarTitleText": "Peak", 11 | "navigationBarTextStyle":"black" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /pages/logs/logs.js: -------------------------------------------------------------------------------- 1 | //logs.js 2 | var util = require('../../utils/util.js') 3 | Page({ 4 | data: { 5 | logs: [] 6 | }, 7 | onLoad: function () { 8 | this.setData({ 9 | logs: (wx.getStorageSync('logs') || []).map(function (log) { 10 | return util.formatTime(new Date(log)) 11 | }) 12 | }) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | .userinfo { 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | } 7 | 8 | .userinfo-avatar { 9 | width: 128rpx; 10 | height: 128rpx; 11 | margin: 20rpx; 12 | border-radius: 50%; 13 | } 14 | 15 | .userinfo-nickname { 16 | color: #aaa; 17 | } 18 | 19 | .usermotto { 20 | margin-top: 200px; 21 | } -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{userInfo.nickName}} 6 | 7 | 8 | {{motto}} 9 | 10 | 11 | 12 | 点击此处或头像进入贪吃蛇 13 | 14 | 15 | -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | var app = getApp() 4 | Page({ 5 | data: { 6 | motto: 'Hello Peak', 7 | userInfo: {} 8 | }, 9 | //事件处理函数 10 | bindViewTap: function() { 11 | wx.navigateTo({ 12 | url: '../snakeGame/snakeGame' 13 | }) 14 | }, 15 | onLoad: function () { 16 | console.log('onLoad') 17 | var that = this 18 | //调用应用实例的方法获取全局数据 19 | app.getUserInfo(function(userInfo){ 20 | //更新数据 21 | that.setData({ 22 | userInfo:userInfo 23 | }) 24 | }) 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | function formatTime(date) { 2 | var year = date.getFullYear() 3 | var month = date.getMonth() + 1 4 | var day = date.getDate() 5 | 6 | var hour = date.getHours() 7 | var minute = date.getMinutes() 8 | var second = date.getSeconds() 9 | 10 | 11 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 12 | } 13 | 14 | function formatNumber(n) { 15 | n = n.toString() 16 | return n[1] ? n : '0' + n 17 | } 18 | 19 | module.exports = { 20 | formatTime: formatTime 21 | } 22 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | //调用API从本地缓存中获取数据 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | }, 9 | getUserInfo:function(cb){ 10 | var that = this 11 | if(this.globalData.userInfo){ 12 | typeof cb == "function" && cb(this.globalData.userInfo) 13 | }else{ 14 | //调用登录接口 15 | wx.login({ 16 | success: function () { 17 | wx.getUserInfo({ 18 | success: function (res) { 19 | that.globalData.userInfo = res.userInfo 20 | typeof cb == "function" && cb(that.globalData.userInfo) 21 | } 22 | }) 23 | } 24 | }) 25 | } 26 | }, 27 | globalData:{ 28 | userInfo:null 29 | } 30 | }) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 CoderPeak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pages/snakeGame/snakeGame.js: -------------------------------------------------------------------------------- 1 | 2 | // 手指开始位置 3 | var startX = 0; 4 | var startY = 0; 5 | 6 | // 手指移动路径 7 | var moveX = 0; 8 | var moveY = 0; 9 | 10 | // 差值 11 | var diffX = 0; 12 | var diffY = 0; 13 | 14 | var snakeW = 10; 15 | var snakeH = 10; 16 | 17 | var context = null; 18 | 19 | // 蛇头 20 | var snakeHead = { 21 | color: "#0000ff", 22 | x: 0, 23 | y: 0, 24 | w: snakeW, 25 | h: snakeH 26 | }; 27 | 28 | // 蛇身 数组 29 | var snakeBodys = []; 30 | 31 | // 窗口宽/高 32 | var windowW = 0; 33 | var windowH = 0; 34 | 35 | // 食物 36 | var foods = []; 37 | 38 | // 蛇头移动方向 39 | var snakeMoveDirection = "right"; 40 | 41 | // 总得分(吃到的食物大小-宽度的总和) 42 | var score = 0; 43 | // 蛇身总长(每得perSocre分 +1) 44 | var snakeLength = 0; 45 | // 是否变长/即移除蛇身 (每得perSocre分 变长-蛇身+1) 46 | var shouldRemoveBody = true; 47 | // (每得perSocre分 变长-蛇身+1) 48 | var perSocre = 5; 49 | // 得了count个perSocre分 50 | var count = 1; 51 | // 蛇移动的速度(帧频率-----越大越慢) 52 | var defaultSpeedLevel = 10; 53 | var moveSpeedLevel = defaultSpeedLevel; 54 | // 减慢动画 55 | var perform = 0; 56 | 57 | // 吃到食物的次数 58 | var eatFoodCount=0; 59 | // 每 speederPerFood 次吃到食物加速 60 | var speederPerFood = 2; 61 | 62 | Page({ 63 | touchStart: function (e){ 64 | 65 | startX = e.touches[0].x; 66 | startY = e.touches[0].y; 67 | 68 | // console.log("开始点击"); 69 | }, 70 | 71 | touchMove: function (e){ 72 | // console.log("开始拖动手指"); 73 | moveX = e.touches[0].x; 74 | moveY = e.touches[0].y; 75 | 76 | diffX = moveX - startX; 77 | diffY = moveY - startY; 78 | 79 | 80 | if ( Math.abs(diffX) > Math.abs(diffY) && diffX>0 && !(snakeMoveDirection == "left") ){ 81 | // 向右 82 | snakeMoveDirection = "right"; 83 | // console.log("向右"); 84 | } else if (Math.abs(diffX) > Math.abs(diffY) && diffX<0 && !(snakeMoveDirection == "right") ){ 85 | // 向左 86 | snakeMoveDirection = "left"; 87 | // console.log("向左"); 88 | } else if (Math.abs(diffX) < Math.abs(diffY) && diffY>0 && !(snakeMoveDirection == "top") ){ 89 | // 向下 90 | snakeMoveDirection = "bottom"; 91 | // console.log("向下"); 92 | } else if (Math.abs(diffX) < Math.abs(diffY) && diffY<0 && !(snakeMoveDirection == "bottom") ){ 93 | // 向上 94 | snakeMoveDirection = "top"; 95 | // console.log("向上"); 96 | } 97 | }, 98 | 99 | 100 | 101 | 102 | onReady: function (e) { 103 | 104 | // (A,B)中随机一个数 105 | function randomAB(A,B) { 106 | return parseInt(Math.random()*(B-A)+A); 107 | } 108 | // 食物构造方法 109 | function Food() { 110 | this.color = "rgb("+randomAB(0,255)+","+randomAB(0,255)+","+randomAB(0,255)+")"; 111 | this.x = randomAB(0, windowW); 112 | this.y = randomAB(0, windowH); 113 | var w = randomAB(10,20); 114 | this.w = w; 115 | this.h = w; 116 | 117 | // 重置位置 118 | this.reset = function (){ 119 | this.color = "rgb("+randomAB(0,255)+","+randomAB(0,255)+","+randomAB(0,255)+")"; 120 | this.x = randomAB(0, windowW); 121 | this.y = randomAB(0, windowH); 122 | var w = randomAB(10,20); 123 | this.w = w; 124 | this.h = w; 125 | } 126 | } 127 | 128 | // 吃到食物函数 129 | function eatFood(snakeHead, food){ 130 | var sL = snakeHead.x; 131 | var sR = sL+snakeHead.w; 132 | var sT = snakeHead.y; 133 | var sB = sT+snakeHead.h; 134 | 135 | var fL = food.x; 136 | var fR = fL+food.w; 137 | var fT = food.y; 138 | var fB = fT+food.h; 139 | 140 | if ( sR>fL && sB>fT && sL5){ 232 | 233 | if (score/perSocre>=count){ // 得分 234 | 235 | count++; 236 | 237 | 238 | shouldRemoveBody = false; 239 | 240 | } 241 | 242 | if(shouldRemoveBody ){ 243 | 244 | snakeBodys.shift(); 245 | } 246 | shouldRemoveBody = true; 247 | } 248 | switch(snakeMoveDirection){ 249 | case "left": 250 | snakeHead.x -= snakeHead.w; 251 | break; 252 | case "right": 253 | snakeHead.x += snakeHead.w; 254 | break; 255 | case "top": 256 | snakeHead.y -= snakeHead.h; 257 | break; 258 | case "bottom": 259 | snakeHead.y += snakeHead.h; 260 | break; 261 | } 262 | 263 | // 游戏失败 264 | if(snakeHead.x>windowW || snakeHead.x<0 || snakeHead.y>windowH || snakeHead.y<0){ 265 | // console.log("游戏结束"); 266 | wx.showModal({ 267 | title: "总得分:"+score+"分-----蛇身总长:"+snakeBodys.length+"", 268 | content: '游戏失败, 重新开始, 咱又是一条好🐍', 269 | success: function(res) { 270 | console.log(res) 271 | if (res.confirm) { 272 | // console.log('用户点击确定') 273 | beginGame(); 274 | 275 | } else { 276 | initGame(); 277 | wx.navigateBack({ 278 | delta: 1 279 | }) 280 | } 281 | } 282 | }) 283 | 284 | return; 285 | } 286 | 287 | } 288 | 289 | 290 | 291 | 292 | // 绘制蛇头 293 | drawObj(snakeHead); 294 | 295 | // 绘制蛇身体 296 | for (var i=0; i