之前没有写博客的习惯,这是我的第一个博客,有些的不好的地方,希望大家多多提意见

js版的贪吃蛇相对比较简单,废话不多说直接上代码,有需要注意的地方我会标红,github源码地址https://github.com/masterChunlinHan/snake.git

所有的代码都在一个文件中,因为总共就没多少代码

1,首先定义几个后面要用到的全局变量

地图定义为全局的是因为:后面的食物和蛇都要加到地图上,而添加的方法在食物和蛇各自的构造器中,需要地图是全局的才能被访问到

食物定义成全局的是因为:在蛇的移动方法中判断是否吃到食物,需要知道食物的坐标

蛇定义成全局的原因比较特殊:后面用键盘控制蛇头的方向,是window调用蛇的移动方法,在这个方法中this不再指向当前的对象(即蛇),而是window,所以要把蛇提升为全局变量

定时器定义成全局的是因为:在别的方法中需要取消定时或开始定时,比如暂停,还有吃到食物后更新速度加快

         var map;//地图
var food;//食物
var snake;//蛇
var timer;//定时器
var time=500;//定时器定的时间,默认为500ms

2,地图构造器

function Map(){
this.width= 600; //地图的宽
this.height = 400; //地图的高
this.position = 'relative'; //地图定位方式,这里为相对定位
this.backgroundColor = '#ccc'; //地图背景色
this.map=null; //一来用来保存地图,二来可以判断地图是不是已经存在,以免重复创建
//显示地图的方法
this.showMap = function(){
if(this.map===null){
//加个判断保证地图只会创建一次
this.map = document.createElement('div');
document.body.appendChild(this.map);
} this.map.style.width = this.width+'px';
this.map.style.height = this.height + 'px';
this.map.style.backgroundColor = this.backgroundColor;
this.map.style.position = this.position; }
}

3,食物构造器,原理基本上跟地图构造器一样

     function Food(){
this.width= 20;
this.height = 20;
this.x = 2; //这不是实际坐标,而是以食物的宽为单位
this.y = 2;
this.position = 'absolute';
this.backgroundColor = 'red';
this.food=null;
this.showFood=function(){
if(this.food===null){
this.food = document.createElement('div');
map.map.appendChild(this.food); //把食物添加到地图上
}
this.x = Math.floor(Math.random()*30); //食物的位置是随机的
this.y = Math.floor(Math.random()*20); this.food.style.width = this.width+'px';
this.food.style.height = this.height + 'px';
this.food.style.backgroundColor = this.backgroundColor;
this.food.style.position = this.position;
this.food.style.left = this.width*this.x + 'px';
this.food.style.top = this.height*this.y + 'px'; }
}

4,蛇的构造器

function Snake(){
this.position = 'absolute';
this.width = 20;
this.height = 20;
this.body = [[2,2,'red',null],[1,2,'blue',null],[0,2,'blue',null]];//蛇的身体,默认一个头,两个身体第一个为头,每个数组中的元素分别代表这节身体的x,y,颜色,以及负责显示这节身体的div
this.directionKeyCode=39; //键盘的keyCode,默认39代表右键
//显示蛇
this.showSnake = function(){
for(var i=0;i<this.body.length;i++){
if(this.body[i][3]===null){
this.body[i][3] = document.createElement('div');//把
map.map.appendChild(this.body[i][3]);
}
this.body[i][3].style.width =this.width+'px';
this.body[i][3].style.height =this.height+'px';
this.body[i][3].style.position = this.position;
this.body[i][3].style.backgroundColor = this.body[i][2];
this.body[i][3].style.left = this.width*this.body[i][0]+'px';
this.body[i][3].style.top = this.width*this.body[i][1]+'px'; }
}

5,移动蛇的方法,需要写在蛇的构造器里面,注意这个方法里的snake不能用this代替,原因上面已经说明

在这个方法中需要判断蛇是否撞到了墙壁或者自身

this.moveSnake = function(){
//这个方法里的snake不能用this代替,原因上面已经说明
//更新每节身体的位置,除了蛇头外其他每节的位置更新为上一节的位置
//注意要从最后一节更新,因为每节的新位置是上一节的老位置,需要在上一节更新之前才能获取它的老位置
for(var i=snake.body.length-1;i>0;i--){
snake.body[i][0] = snake.body[i-1][0];
snake.body[i][1] = snake.body[i-1][1];
}
//设置蛇头位置
switch (snake.directionKeyCode){
case 37: //左
snake.body[0][0] -=1;
break;
case 38: //上
snake.body[0][1] -=1;
break;
case 39: //右
snake.body[0][0] +=1;
break;
case 40: //下
snake.body[0][1] +=1;
break;
}
//吃到食物的判断
if(snake.body[0][0]==food.x && snake.body[0][1]==food.y){
var lastBody = snake.body[snake.body.length-1]
snake.body.push([lastBody[0],lastBody[1],'blue',null]);
//吃到食物后更新食物的位置
food.showFood();
if(time>=250){//减少更新时间,加快蛇的速度,减少到250ms以下后不再加快
time-=50;
clearInterval(timer);
timer = setInterval(snake.moveSnake,time);
} } //判断边界
if(snake.body[0][0]>29 || snake.body[0][0]<0||snake.body[0][1]>19||snake.body[0][1]<0){
confirm("GameOver,点确定重新开始");
location.href='?'; //刷新网页方法一 }
//判断是否碰到到自己
for(var i=1;i<snake.body.length;i++){
if(snake.body[0][0]==snake.body[i][0]&&snake.body[0][1]==snake.body[i][1]){
confirm("GameOver,点确定重新开始");
//location.href='?';
location.reload(); //刷新网页方法二
}
}
//显示蛇,此时蛇的位置已改变
snake.showSnake(); }

6,到这里主要工作已经做完,这一步主要来创建暂定、继续、上、下、左、右按键,不想创建也可以,这一步可以直接忽略,下一步不再调用这些方法即可,不影响游戏的运行

注:这些方法不属于任何构造器

     //停止按钮
function Stop(){
this.showStopBtn = function(){
var btn = document.createElement('button');
btn.innerHTML="暂停";
document.body.appendChild(btn); btn.onclick = function(){
clearInterval(timer);
confirm("暂停中,点确定开始");
timer =setInterval(snake.moveSnake,time);
}
}
}
//开始按钮
function Start(){
this.showStartBtn = function(){
var btn = document.createElement('button');
btn.innerHTML="开始";
document.body.appendChild(btn);
btn.onclick = function(){
clearInterval(timer);
timer =setInterval(snake.moveSnake,time);
}
}
}
//方向实体键
function DirectionButton(){
this.showDirectButtons=function(){
var btn = document.createElement('button');
btn.innerHTML="上";
document.body.appendChild(btn);
btn.onclick = function(){
snake.directionKeyCode=38;
} var btn = document.createElement('button');
btn.innerHTML="下";
document.body.appendChild(btn);
btn.onclick = function(){
snake.directionKeyCode=40;
} var btn = document.createElement('button');
btn.innerHTML="左";
document.body.appendChild(btn);
btn.onclick = function(){
snake.directionKeyCode=37;
} var btn = document.createElement('button');
btn.innerHTML="右";
document.body.appendChild(btn);
btn.onclick = function(){
snake.directionKeyCode=39;
}
} }

7,主要的创建流程

//创建并显示地图
map= new Map();
map.showMap();
//创建并显示食物
food = new Food();
food.showFood();
//创建并显示蛇
snake = new Snake();
snake.showSnake();
//设置定时器
// snake.moveSnake();
timer = window.setInterval(snake.moveSnake,time);
//添加键盘事件
document.body.onkeydown = function(e){
var event = window.event||e;
if(event.keyCode>=37&&event.keyCode<=40){//限制其他按键不起作用,只有上下左右四个按键起作用
snake.directionKeyCode = event.keyCode;
} }
//以下添加按键的步骤,可加可不加
//添加停止按钮
var stopBtn = new Stop();
stopBtn.showStopBtn();
//添加停止按钮
var startBtn = new Start();
startBtn.showStartBtn();
//添加上下左右按钮
var directionButtons = new DirectionButton();
directionButtons.showDirectButtons();

以上就是全部的代码,当然需要全部写在html中的<script>标签中,希望大家多多提意见哈

想看源码的小伙伴,这里有github地址https://github.com/masterChunlinHan/snake

js版贪吃蛇的更多相关文章

  1. OC版贪吃蛇

    昨天写了一个js版贪吃蛇,今天突然想写一个OC版的,来对比一下两种语言的区别 oc版功能,适配所有尺寸iphone,可暂停,可设置地图和蛇的比例,可加速 对比一下会发现js版的相对OC版的会简单一些, ...

  2. JS仿贪吃蛇:一串跟着鼠标的Div

    贪吃蛇是一款80后.90后比较熟悉的经典游戏,下面通过简单的JS代码来实现低仿版贪吃蛇效果:随着鼠标的移动,在页面中呈现所有Div块跟随鼠标依次移动,效果如下图所示. <!DOCTYPE htm ...

  3. TOJ 3973 Maze Again && TOJ 3128 简单版贪吃蛇

    TOJ3973传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3973 时间限制(普通 ...

  4. 如何用python制作贪吃蛇以及AI版贪吃蛇

    用python制作普通贪吃蛇 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...

  5. Javascript基础示例:用JS写简易版贪吃蛇(面向对象)

    废话不多说,代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...

  6. JavaScript 实现简易版贪吃蛇(Day_13)

    时光永远在变迁,你始终要丢下过去. 使用语言 JavaScript  概述 运用JavaScript  实现简易版<贪吃蛇>.     Html 页面 1 <!DOCTYPE htm ...

  7. JavaScript版—贪吃蛇小组件

    最近在学习JavaScript,利用2周的时间看完了<JavaScript高级编程>,了解了Js是一门面向原型编程的语言,没有像C#语言中的class,也没有私有.公有.保护等访问限制的级 ...

  8. 前端笔记之JavaScript面向对象(三)初识ES6&underscore.js&EChart.js&设计模式&贪吃蛇开发

    一.ES6语法 ES6中对数组新增了几个函数:map().filter().reduce() ES5新增的forEach(). 都是一些语法糖. 1.1 forEach()遍历数组 forEach() ...

  9. 原生JS制作贪吃蛇小游戏

    感情都在代码里,来,干了!... <!doctype html> <html> <head> <meta http-equiv="Content-T ...

随机推荐

  1. Linux离线安装Ruby详解

    很多时候我们会发现,真实的生成环境很多都没有外网,只有内网环境,这个时候我们又需要安装Ruby,则不能提供yum命令进行在线安装了,这个时候我们就需要下载安装包进行离线安装.本文主要简单介绍如果离线安 ...

  2. 跟我一起读postgresql源码(六)——Executor(查询执行模块之——查询执行策略)

    时光荏苒,岁月如梭.楼主已经很久没有更新了.之前说好的一周一更的没有做到.实在是事出有因,没能静下心来好好看代码.当然这不能作为我不更新的理由,时间挤挤还是有的,拖了这么久,该再写点东西了,不然人就怠 ...

  3. 腾讯地图JS API实现带方向箭头的线路Polyline

    最近产品提出一个需求,在我们使用的腾讯地图上为线路polyline添加线路方向.例如下图所示: 查找腾讯地图JS API提供的API,没有找到对应的支持,询问负责腾讯地图的人也得到了同样的答案,即地图 ...

  4. discuz 6.1.0F前台getshell(据说通用6.x , 7.x)

    EXP: 执行phpinfo()语句: GLOBALS[_DCACHE][smilies][searcharray]=/.*/eui; GLOBALS[_DCACHE][smilies][replac ...

  5. Android源码博文集锦2

    Android精选源码 android简单易用的Gallery android漂亮的加载效果 这可能是RxJava 2.x 最好的入门教程示例代码 android图片可拖拽排序 android用几行代 ...

  6. 关于delete使用limit的一些注意事项

    在使用delete删除记录时,如果表里面存在多条相同的记录,但是此刻你只想删除一条记录,那么limit就派上了用场.但是使用limit的时候得注意: 如图,您如果想着删除第一个名字叫做张三的,如果你这 ...

  7. 怎么在linux ubuntu 上的nginx 绑定域名

    前一篇介绍了,如果在ubuntu上运行nodejs,毕竟访问的时候都是用ip地址+端口号,但是上production 环境都需要域名的,IP地址当然不行 读过上一篇的朋友知道了,如果在upstart ...

  8. 中国(北方)大学生程序设计训练赛(第二周) (A B D G)

    比赛链接 A题是KMP,先把A拼接到B的后面,然后利用next数组的意义(包括其具体含义,以及失配时的应用),得到ans #include<bits/stdc++.h> using nam ...

  9. SLAM中的优化理论(一)—— 线性最小二乘

    最近想写一篇系列博客比较系统的解释一下 SLAM 中运用到的优化理论相关内容,包括线性最小二乘.非线性最小二乘.最小二乘工具的使用.最大似然与最小二 乘的关系以及矩阵的稀疏性等内容.一方面是督促自己对 ...

  10. Mac系统下STF的环境搭建和运行

    本文参考以下文章整理:MAC 下 STF 的环境搭建和运行 一. 前言 STF,全称是Smartphone Test Farm,WEB 端批量移动设备管理控制工具,就是可以用浏览器来批量控制你的移动设 ...