h5贪吃蛇
h5制作貪吃蛇
- html
- css
- js
- 游戲效果
使用canvas制作的一個貪吃蛇小游戲,寫了一寫比較簡單的算法,望大佬們多多指正!!!多的不說直接看代碼吧。
html
規劃一個游戲界面
<div class="mian"><canvas id='huaban'></canvas></div>css
html,body {padding: 0;margin: 0;}body {background: black;}.mian {margin: auto;width: 800px;height: 500px;margin-top: 30px;background: rgba(255, 251, 251, 0.089);}js
var s_X = 0, s_Y = 0;//存儲鼠標實時的位置var c_w = window.innerWidth / 2 - 400, c_h = 30;//初始窗口的大小var life = true;//蛇的生命var body_arr = [],//身體繼承存儲數組 body_jc = [],food_color = ['#1db0b8', '#de8100', '#3b200c', '#ff534d', '#edd0be'], //食物隨機顏色存儲的數組_bg,//背景的對象sk,//蛇的對象 speed = 1000 / 120,//定時器的速度food_number = 1,//單位大小內食物的個數zanti = 1,//暫停time = 0;//整體的時間線var food = [[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []],[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]];//食物池var huabu = document.querySelector('#huaban');var huaban = huabu.getContext('2d');function daxiao() {huabu.width = 800;huabu.height = 500;}//畫板的寬高daxiao();window.onresize = function () {c_w = window.innerWidth / 2 - 400;//當界面窗口發生變化時窗口大小}class bg {x = -800;y = -500;hua() {//使用兩個循環來制作地圖,而不是循環的嵌套,從而減輕計算機的負擔huaban.clearRect(0, 0, 800, 500);huaban.lineWidth = 1;huaban.strokeStyle = 'rgba(255, 251, 251, 0.25)';for (var i = 0; i < 2400 / 145; i++) {huaban.beginPath();huaban.moveTo(this.x, this.y + i * 120);huaban.lineTo(this.x + 800 * 3, this.y + i * 120);huaban.closePath();huaban.stroke();}for (var j = 0; j < 1500 / 72; j++) {huaban.beginPath();huaban.moveTo(this.x + j * 120, this.y);huaban.lineTo(this.x + j * 120, this.y + 500 * 3 + 420);huaban.closePath();huaban.stroke();}};move() {this.d = Math.sqrt((s_X - (sk.x + c_w)) ** 2 + (s_Y - (sk.y + c_h)) ** 2);//背景的位置與蛇的位置的距離,一切判斷基于此條件if (this.d != 0) {if (this.x < sk.x - sk.r - 2 && this.x + 800 * 3 > sk.x + sk.r + 2) {//范圍判斷this.x -= (s_X - (sk.x + c_w)) / this.d;sk.relative_x += (s_X - (sk.x + c_w)) / this.d;} else {life = false;// if (s_X > sk.x + c_w && this.x + 800 * 3 > sk.x + sk.r + 2) {// this.x -= (s_X - (sk.x + c_w)) / this.d;// }// if (s_X < sk.x + c_w && this.x < sk.x - sk.r - 2) {// this.x -= (s_X - (sk.x + c_w)) / this.d;// }//邊界不會超出}//注釋掉的代碼為當蛇到達x邊界時不會死亡只是不能超游戲界面外運動if (this.y < sk.y - sk.r - 2 && this.y + 600 * 3 + 120 > sk.y + sk.r + 2) {this.y -= (s_Y - (sk.y + c_h)) / this.d;sk.relative_y += (s_Y - (sk.y + c_h)) / this.d;} else {life = false;// if (s_Y > sk.x + c_h && this.y + 600 * 3 + 120 > sk.y + sk.r + 2) {// this.y -= (s_Y - (sk.y + c_h)) / this.d;// }// if (s_Y < sk.y + c_h && this.y < sk.y - sk.r - 2) {// this.y -= (s_Y - (sk.y + c_h)) / this.d;// }//邊界不會超出}//注釋掉的代碼為當蛇到達y邊界時不會死亡只是不能超游戲界面外運動}sk.body(sk.x - (s_X - (sk.x + c_w)) / this.d * 20, sk.y - (s_Y - (sk.y + c_h)) / this.d * 20);//一直傳遞蛇身體新的位置sk.eat();//畫食物this.hua();//背景畫for (var i = 0; i < 20; i++) {for (var j = 0; j < 16; j++) {for (var k = 0; k < food[i][j].length; k++) {food[i][j][k].x -= (s_X - (sk.x + c_w)) / this.d;food[i][j][k].y -= (s_Y - (sk.y + c_h)) / this.d;food[i][j][k].creta();}//食物的遍歷更新食物的位置}}// if (body_arr.length >= 9) {// console.log(body_jc, body_arr)// body_jc[0].x = body_arr[5].x;// body_jc[0].y = body_arr[5].y;// body_jc[0].hua();// }//對蛇身體開始更新位置sk.eye_x = 14 * ((s_X - (sk.x + c_w))) / this.d;sk.eye_y = 14 * (-(s_Y - (sk.y + c_h))) / this.d;//蛇眼睛珠子的位置隨著不同方向從而一直變化sk.head();//畫蛇頭time++;}run() {var time = setInterval(() => {this.move()if (life == false) {//當蛇死掉時清除定時器clearInterval(time);jieshu();}}, speed)}//蛇身體開始運動并且開始一直從新畫背景}class snake {x = 800 / 2;y = 500 / 2;r = 20;//蛇頭位置固定在屏幕中間color = '#ffa400';relative_x = 400;relative_y = 250;eye_x = 14;eye_y = 0;//眼睛珠子初始的位置weight = 0;head() {huaban.beginPath();huaban.fillStyle = 'white';huaban.arc(this.x, this.y, this.r + 2, 0, Math.PI * 2);huaban.fill();//蛇頭邊界huaban.beginPath();huaban.fillStyle = this.color;huaban.arc(this.x, this.y, this.r, 0, Math.PI * 2);huaban.fill();//蛇頭主體huaban.beginPath();huaban.fillStyle = 'white';huaban.arc(this.x + this.eye_y, this.y + this.eye_x, 10, 0, Math.PI * 2);huaban.fill();//蛇左眼睛huaban.beginPath();huaban.fillStyle = 'black';huaban.arc(this.x + this.eye_y, this.y + this.eye_x, 5, 0, Math.PI * 2);huaban.fill();//蛇左眼睛珠子huaban.beginPath();huaban.fillStyle = 'white';huaban.arc(this.x - this.eye_y, this.y - this.eye_x, 10, 0, Math.PI * 2);huaban.fill();//蛇右眼睛huaban.beginPath();huaban.fillStyle = 'black';huaban.arc(this.x - this.eye_y, this.y - this.eye_x, 5, 0, Math.PI * 2);huaban.fill();//蛇右眼睛珠子};//蛇頭的函數body(x, y) {body_arr.push({ 'x': x, 'y': y });if (body_arr.length >= 10) {body_arr.splice(0, 1);}};//將蛇頭的坐標傳遞進body_arr數組實現第二節身體繼承eat() {var i = 19 - Math.abs(parseInt((_bg.x - this.x + 800 * 3) / 120));var j = 15 - Math.abs(parseInt((_bg.y - this.y + 600 * 3 + 120) / 120));for (var k = 0; k < food[i][j].length; k++) {food[i][j][k].d = Math.sqrt((food[i][j][k].x - this.x) ** 2 + (food[i][j][k].y - this.y) ** 2);//計算食物與自己的距離// console.log('中心點'+sk.relative_x,'食物'+food[i][j][k].x);// console.log('中心點'+sk.relative_y,'食物'+food[i][j][k].y)if (food[i][j][k].d < food[i][j][k].r + this.r + 20) {food[i][j][k].move(i, j, k);this.weight += food[i][j][k].weight;}}}}//吃東西的函數function _body(x, y) {this.x = x;this.y = y;this.r = 15;this.d = 100;this.color = '#ffa400';this.hua = function () {huaban.beginPath();huaban.fillStyle = 'white';huaban.arc(this.x, this.y, this.r + 2, 0, Math.PI * 2);huaban.fill();//蛇頭邊界huaban.beginPath();huaban.fillStyle = this.color;huaban.arc(this.x, this.y, this.r, 0, Math.PI * 2);huaban.fill();//蛇頭主體}}//蛇身體的構造函數function _food(x, y) {this.x = x;this.y = y;this.r = suiji(1, 3);this.weight = this.r;this.color = food_color[parseInt(suiji(0, 4))];this.creta = function () {huaban.beginPath();huaban.fillStyle = this.color;huaban.arc(this.x, this.y, this.r + 2, 0, Math.PI * 2);huaban.fill();//畫食物};this.move = function (i, j, k) {var moveTime = setInterval(() => {if (this.d < sk.r) {clearInterval(moveTime);food[i][j].splice(k, 1);} else {this.c = Math.sqrt((this.x - sk.x) ** 2 + (this.y - sk.y) ** 2);this.x -= (this.x - sk.x) / this.c;this.y -= (this.y - sk.y) / this.c;//}}, 1000 / 60)}}//食物的構造函數function suiji(max, min) {return Math.random() * (max - min) + min;}//隨機數函數function add_food() {for (var i = 0; i < 20; i++) {for (var j = 0; j < 16; j++) {for (var k = 0; k < food_number; k++) {var _food_ = new _food(suiji(-800 + i * 120, -800 + (i + 1) * 120), suiji(-500 + j * 120, -500 + (j + 1) * 120));food[i][j].push(_food_);_food_.creta();}}}}//將食物添加進地圖并用food三維數組來存儲function start() {_bg = new bg();_bg.hua();sk = new snake();sk.head();_bg.run();add_food();body_jc.push[new _body(0, 0)];}//開始函數function jieshu() {// huaban.clearRect(0, 0, 800, 500);//清除屏幕}//蛇死掉時執行的函數start();//開始執行的函數function mouseMove(ev) {ev = ev || window.event;var mousePos = mouseCords(ev);s_X = mousePos.x, s_Y = mousePos.y;}//傳遞鼠標實時位置給s_X,s_Y。function mouseCords(ev) {if (ev.pageX || ev.pageY) {return {x: ev.pageX, y: ev.pageY};}//獲取鼠標的實時位置}document.onmousemove = mouseMove;//鼠標位置document.querySelector('.mian').onclick = function () {zanti++;zanti % 2 == 0 ? life = false : life = true;_bg.run();}游戲效果
游戲效果圖
食物池來來存放的食物,減輕計算機的工作量,更高效的運行這個游戲,對手還沒有寫,自己的身體也還沒有寫,涉及到一些繼承的算法,還在思考中,請大佬們賜教。
總結
- 上一篇: 杯具的无线鼠标安装记
- 下一篇: socket中的TCP编程(调用免费聊天