因为小蛇和食物都是相对于地图显示的,所以小蛇和食物都是地图的子元素是随机位置显示的,所以食物和小蛇需要脱离文档流(设置样式position: absolute),地图也需要脱离文档流(设置样式position: relative)。 附上在线HTML/CSS/JavaScript代码运行工具:HTML/CSS/Javascript在线代码运行工具。
一、对贪吃蛇进行梳理
1.页面上的主要元素
属性:宽、高;背景颜色。
方法:显示食物;删除食物。
属性:每截身体的宽、高;移动的方向;每截身体的x、y坐标和颜色。
方法:显示小蛇;小蛇的移动;删除小蛇。2.游戏逻辑
二、运行效果图
三、全部代码展示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js实现贪吃蛇小游戏</title> <style> * { margin: 0; padding: 0; } .title { text-align: center; margin-top: 20px; } .btn { width: 80px; height: 30px; border: 1px solid rgb(51, 50, 50); background-color: #eee; margin: 20px auto 0; display: block; } .map { width: 800px; height: 400px; background-color: #ccc; margin: 0 auto; position: relative; } </style> </head> <body> <h2 class="title">贪吃蛇小游戏</h2> <button id="btn" class="btn" type="button">开始游戏</button> <div id="map" class="map"></div> <script> var map = document.getElementById("map"); // 存放food的数组,用来删除food var foodElements = []; function Food() { this.x = 0; this.y = 0; // Food的width、height和color属性并不需要修改,所以为了节省内存空间,采用原型对象的方式创建这三个属性 Food.prototype.width = 20; Food.prototype.height = 20; Food.prototype.color = "green"; // 动态原型模式创建对象。用来完成数据共享,节省内存空间 /* 判断this.init的类型是不是function 如果不是function则证明是第一次创建对象,则把这个funcion添加到原型中 如果是function,则代表原型中已经有了这个方法,则不需要再添加该方法。 */ // 初始化food if (typeof this.init != "function") { Food.prototype.init = function () { // 先删除之前的food food.remove(); // 创建元素 var div = document.createElement("div"); // 设置food的样式 div.style.width = this.width + "px"; div.style.height = this.height + "px"; div.style.backgroundColor = this.color; // 设置为相对定位 div.style.position = "absolute"; this.x = parseInt(Math.random() * (map.offsetWidth / this.width)); this.y = parseInt(Math.random() * (map.offsetHeight / this.height)); // 设置食物出现的位置不是当前小蛇身体所在位置 for (var i = 0; i < snake.body.length; i++) { while (this.x == snake.body[i].x && this.y == snake.body[i].y) { this.x = parseInt(Math.random() * (map.offsetWidth / this.width)); this.y = parseInt(Math.random() * (map.offsetHeight / this.height)); continue; } } div.style.left = this.x * this.width + "px"; div.style.top = this.y * this.height + "px"; // 将食物添加到map和foodElements数组中 map.appendChild(div); foodElements.push(div); }; } // 删除food if (typeof this.remove != "function") { Food.prototype.remove = function () { for (var i = 0; i < foodElements.length; i++) { // 删除该元素 map.removeChild(foodElements[i]); // 删除foodElements数组中的内容 foodElements.splice(i, 1); } }; } }; // 存放snake的数组,用来删除snake var snakeElements = []; function Snake() { this.direction = "right"; this.body = [{ x: 3, y: 2, color: "red" }, { x: 2, y: 2, color: "orange" }, { x: 1, y: 2, color: "orange" } ]; // 使用原型对象的方式设置Snake的width和height Snake.prototype.width = 20; Snake.prototype.height = 20; // 动态原型模式创建对象 // 初始化snake if (!(this.init instanceof Function)) { // 判断是否为function的另一种方式 Snake.prototype.init = function () { this.remove(); for (var i = 0; i < this.body.length; i++) { // 设置snake的样式 var obj = this.body[i]; var div = document.createElement("div"); map.appendChild(div); div.style.width = this.width + "px"; div.style.height = this.height + "px"; div.style.position = "absolute"; div.style.backgroundColor = obj.color; div.style.left = obj.x * this.width + "px"; div.style.top = obj.y * this.height + "px"; // 设置头部为圆角,可省略 while (i == 0) { switch (this.direction) { case "right": div.style.borderTopRightRadius = "15px"; div.style.borderBottomRightRadius = "15px"; break; case "left": div.style.borderTopLeftRadius = "15px"; div.style.borderBottomLeftRadius = "15px"; break; case "top": div.style.borderTopRightRadius = "15px"; div.style.borderTopLeftRadius = "15px"; break; case "bottom": div.style.borderBottomRightRadius = "15px"; div.style.borderBottomLeftRadius = "15px"; break; } break; } // 将snake的每个节点添加到数组中,以便后期删除使用 snakeElements.push(div); } }; } // 删除snake if (!(this.remove instanceof Function)) { Snake.prototype.remove = function () { for (var i = snakeElements.length - 1; i >= 0; i--) { // 在map中移除snake这个子节点 map.removeChild(snakeElements[i]); // 删除snakeElements数组中的内容 snakeElements.splice(i, 1); } }; } // 移动snake if (!(this.move instanceof Function)) { Snake.prototype.move = function () { // 改变小蛇的身体的坐标位置 for (var i = this.body.length - 1; i > 0; i--) { this.body[i].x = this.body[i - 1].x; this.body[i].y = this.body[i - 1].y; } // 根据direction属性确定蛇头移动的方向并改变小蛇的头的坐标位置 switch (this.direction) { case "right": this.body[0].x += 1; break; case "left": this.body[0].x -= 1; break; case "top": this.body[0].y -= 1; break; case "bottom": this.body[0].y += 1; break; } // 如何让蛇看起来像是在移动: // 在小蛇移动后,删除之前的蛇(删除方法在init()中调用了),然后重新显示蛇 this.init(); // 判断是否吃到食物,吃到则蛇身加一节,删除吃掉的食物,生成新的食物 // 蛇头的x、y与食物的x、y均相等则为吃到食物 if (this.body[0].x == food.x && this.body[0].y == food.y) { var last = this.body[this.body.length - 1]; this.body.push({ x: last.x, y: last.y, color: last.color }); // 删除吃掉的食物,生成新的食物 food.init(); } // 判断是否撞墙,撞墙 即死 var maxX = map.offsetWidth / this.width; // map中最大的x值 var maxY = map.offsetHeight / this.height; // map中最大的y值 var headX = this.body[0].x; // 蛇头所在位置的x值 var headY = this.body[0].y; // 蛇头所在位置的y值 if (headX < 0 || headX > maxX - 1 || headY < 0 || headY > maxY - 1) { // 清除定时器 clearInterval(timeId); alert("对不起,您撞墙了,游戏结束!"); // 移除snake this.remove(); // 还原Snake中direction和body的初始值,让蛇恢复原状 this.direction = "right"; this.body = [{ x: 3, y: 2, color: "red" }, { x: 2, y: 2, color: "orange" }, { x: 1, y: 2, color: "orange" } ]; // 重新显示snake this.init(); // 结束游戏 return false; } // 判断是否吃到自己,吃到自己 即死 // 因为蛇长为5时才能吃到自己,所以i从4开始 for (var i = 4; i < this.body.length; i++) { // 如果头部的x、y与身体某一段的x、y相等则为吃到自己 if (this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) { // 清除定时器 clearInterval(timeId); alert("对不起,您把自己吃了,游戏结束!"); // 移除snake this.remove(); // 还原Snake中direction和body的初始值,让蛇恢复原状 this.direction = "right"; this.body = [{ x: 3, y: 2, color: "red" }, { x: 2, y: 2, color: "orange" }, { x: 1, y: 2, color: "orange" } ]; // 重新显示snake this.init(); // 结束游戏 return false; } } }; } }; // 初始化food和snake var food = new Food(); var snake = new Snake(); // 显示food和snake food.init(); snake.init(); // 给页面添加键盘按下事件, document.onkeydown = function (e) { var eve = e || window.event; // 兼容低版本IE switch (eve.keyCode) { case 37: // ←键的keyCode case 65: // A键的keyCode if (snake.direction != "right") { // 不允许后退的简单处理。不过有bug,手速够快的话还是会后退... snake.direction = "left"; } break; case 38: // ↑键的keyCode case 87: // W键的keyCode if (snake.direction != "bottom") { snake.direction = "top"; } break; case 39: // →键的keyCode case 68: // D键的keyCode if (snake.direction != "left") { snake.direction = "right"; } break; case 40: // ↓键的keyCode为38 case 83: // S键的keyCode if (snake.direction != "top") { snake.direction = "bottom"; } break; } }; var btn = document.getElementById("btn"); var timeId; // 给按钮注册点击事件,点击按钮开始游戏 function begin() { clearInterval(timeId); // 防止多次点击造成多次触发setInterval timeId = setInterval("snake.move()", 200); }; btn.onclick = begin; </script> </body> </html>
谢谢您的查看,希望能对您有所帮助!
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算