原生JS实现贪吃蛇游戏
贪吃蛇游戏(原生JavaScript)
贪吃蛇游戏思路分析
游戏思想:
面向对象的思想
三个js文件分别代表三个对象三个对象相互独立,在HTML中控制全局使用面向对象思想的好处
贪吃蛇游戏采用面向对象的思想去实现,我们的食物还有蛇以及地图是相互独立的,不会对彼此产生影响,可以单独调用
贪吃蛇游戏对象分析
游戏的场景(一个大的div)
场景的大小
场景的边框
场景在浏览器中的位置
游戏的主角(每一节是一个小的div)
蛇的属性
蛇的初始长度(四节)
蛇的每一节的形状
蛇的每一节的尺寸
蛇的颜色(蛇头的颜色,蛇身的颜色)
蛇的初始位置在哪
蛇的行为
可以自己移动,每一次移动一节的蛇身长
可以通过键盘控制方向
可以吃食物,并且吃完以后会长一节
食物
食物的属性
食物的大小
食物的颜色(随机)
食物的位置(随机)
食物的形状(圆形)
食物的方法
食物被蛇吃掉以后可以改变位置(随机)附加项
游戏场景附加项
游戏的障碍游戏的计分功能游戏中蛇的最长记录游戏的主角附加项
蛇可以加速游戏的关卡设置游戏的附加项大家有兴趣的话可以自己去尝试着添加,有什么问题,可以在下方评论进行讨论!
废话少说,直接上源码!
index.HTML
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>贪吃蛇</title><!-- 将三个js文件,通过外联的方式进行引入 --><script src="地图.js"></script><script src="蛇.js"></script><script src="食物.js"></script></head><body><script>//主界面HTML实现对游戏的全局控制//一,创建地图,并将地图添加到body中//实例化map对象var map = new Game_Map();//将map对象添加到body中document.body.appendChild(map);//三,创建食物//计算食物随机出现的范围是多少var countX = (map.offsetWidth - 40) / 20;var countY = (map.offsetHeight - 40) / 20;//实例化蛇对象,并且传参.var food = new Food(countX, countY, map);//二,创建蛇var snake = new Snake(3, 0, map, food)</script></body></html>
地图.js
//游戏场景//我们使用构造函数来写游戏场景function Game_Map() {// 用对象的属性来设置游戏场景的大小this.width = 1000;this.height = 800;//创建一个div来表示游戏场景var map = document.createElement("div");// 设置创建的div的长和宽map.style.width = this.width + "px";map.style.height = this.height + "px";//设置盒子的背景颜色map.style.backgroundColor = "rgba(211, 211, 211, 0.315)";// 设置盒子的边框map.style.border = "20px solid skyblue";//设置盒子的位置map.style.margin = "50px auto";//给地图一个相对定位(子绝父相)map.style.position = "relative";//返回值返回创建的div就是mapreturn map}
蛇.js
//蛇对象//面向对象使用构造函数function Snake(xindex, yindex, parent, food = null) {//使用构造函数的属性来设置蛇的长还有每一节的大小this.length = 4;this.size = 20;//获取传递的foodthis.food = food;//定义一个数组来存放蛇身this.list = new Array();// 一,创建蛇//蛇的的长度是4,所以我们使用for循环来创建for (var i = 0; i < this.length; i++) {//创建蛇的divvar item = document.createElement("div");//设置蛇的每一节的宽和高item.style.width = item.style.height = this.size + "px";//蛇的每一节是圆形,所以我们使用圆角边框item.style.borderRadius = "100%";// 使用if判断让蛇头的的颜色和身体的颜色不一样if (i == 0) {item.style.backgroundColor = "red";}else {item.style.backgroundColor = "green";}//蛇是在地图里面所以蛇使用的是绝对定位item.style.position = "absolute";//定义蛇的初始位置,我们一开始给蛇的传递两个参数,来设置蛇的初始位置//给的csx使用for循环是0 1 2 3 所以我们给的值是从右到左一个一个放置蛇身,csx是蛇身的初始横坐标item.style.left = (xindex - i) * this.size + "px";//给的csy是她的初始纵坐标item.style.top = yindex * this.size + "px";//给蛇设置一个自定义标签,为蛇当时的方向item.setAttribute("dir", "right");//把蛇身一节一节的放入到数组中this.list[i] = item;//然后再一节一节的添加到我们的map中parent.appendChild(item);}// move函数function move(list, size, food = null) {//for循环遍历让蛇进行移动for (var i = 0; i < list.length; i++) {//判断蛇的移动方向if (list[i].getAttribute("dir") === "down") {//移动之前先判断一下是否碰到墙了if (list[0].style.top == 800 + "px") {// 碰到的话,游戏结束alert("游戏结束!")} else {//没有碰到继续list[i].style.top = list[i].offsetTop + size + "px";}} else if (list[i].getAttribute("dir") === "up") {if (list[0].style.top == -20 + "px") {alert("游戏结束!")} else {list[i].style.top = list[i].offsetTop - size + "px";}} else if (list[i].getAttribute("dir") === "left") {if (list[0].style.left == -20 + "px") {alert("游戏结束!")} else {list[i].style.left = list[i].offsetLeft - size + "px";}} else if (list[i].getAttribute("dir") === "right") {if (list[0].style.left == 1000 + "px") {alert("游戏结束!")} else {list[i].style.left = list[i].offsetLeft + size + "px";}}}//让dir属性进行传递,使得蛇身和蛇头一起向同一方向移动for (var i = list.length - 1; i > 0; i--) {list[i].setAttribute("dir", list[i - 1].getAttribute("dir"));}//判断食物是否出现if (food == null) {console.log(null);return;// 食物出现的话,判断如果蛇头和食物的位置重叠的话,那么就让食物重新定义一个新的随机位置,并且调用蛇长身体的方法} else if (list[0].style.left == food.food.style.left && list[0].style.top == food.food.style.top) {food.setPosition();group();}};//二,实现蛇的移动this.movetime = setInterval(move, 100, this.list, this.size, this.food,);// 三,控制转弯document.addEventListener("keydown", changeDir,);var list = this.list;function changeDir(e) {switch (e.keyCode) {// 向上case 38:list[0].setAttribute("dir", "up");break;// 向下case 40:list[0].setAttribute("dir", "down");break;// 向左case 37:list[0].setAttribute("dir", "left");break;// 向右case 39:list[0].setAttribute("dir", "right");break;}}// 【4】蛇长身体var group = function () {// 蛇头和食物重叠以后,蛇身要长长一节,所以创建一个div,设置属性,加到蛇身的最后一节上var item = document.createElement("div");item.style.width = item.style.height = "20px";item.style.borderRadius = "100%";item.style.backgroundColor = "green";item.style.position = "absolute";item.style.left = list[list.length - 1].style.left;item.style.top = list[list.length - 1].style.top;list[list.length] = item;parent.appendChild(item);}}
食物.js
//食物对象//构造一个食物对象函数function Food(countX, countY, body) {//设置食物的大小this.size = 20;// 创建食物,设置食物的属性this.food = document.createElement("div");this.food.style.width = this.food.style.height = this.size + "px";this.food.style.borderRadius = "50%";this.food.style.position = "absolute";//定义食物的随机位置以及随机的颜色this.setPosition = function () {this.food.style.left = Math.floor(Math.random() * countX) * this.size + "px";this.food.style.top = Math.floor(Math.random() * countY) * this.size + "px";this.food.style.backgroundColor = `rgb(${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)})`;}this.setPosition();body.appendChild(this.food);}
注:本人小白一个,代码有什么问题的话,希望大家可以提出来,本人会及时改正!