原生JavaScript贪吃蛇
在实例开发过程中还是能认识到很多不足的,并且加强了一些基础。

简单写一下制作过程:
1.创建画布
2.创建蛇和老鼠 坐标不能重叠
3.让蛇移动起来
4.添加死亡方法
5.添加转点坐标和方向
6.添加吃老鼠的方法
整个开发的难点有几个:
1.蛇身体的转向
2.吃老鼠添加蛇长度
总结:
1.原来玩的FC贪吃蛇100合一的小游戏其实就是根据画布大小/蛇的移动速度/蛇的长度来设置关卡。
2.最后测试时老有个bug就是删除了最后的转点但是蛇尾没转过去,一直找不到原因,虽然最后修复了,但不是很满意。
在线测试地址:http://jsfiddle.net/dtdxrk/aL9DF/embedded/result/
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>贪吃蛇JavaScript版</title>
<style type="text/css">
*{margin:0;padding: 0;line-height: 1;}
body{font-family: Arial, 'Microsoft Yahei', Simsun, sans-serif;background-color: #7bef70;}
#con{width:400px;margin: 20px auto;}
#con span.r{float: right;}
#con h1{text-align: center;}
#Canvas{margin: 20px auto;background-color: #f4f9f5;overflow: hidden;}
#Canvas table{width: 100%;border:2px solid #000;border-collapse: collapse;}
#Canvas table td{border-collapse: collapse;border:1px solid #bfcde9;width: 8px;height: 8px;}
#Canvas table td.SnakeBody{background-color: #82f170}
#Canvas table td.SnakeHead{background-color: #4ca72e;}
#Canvas table td.Mouse{background-color: red;}
/*#Canvas table td.SnakeBody, #Canvas table td.SnakeHead, #Canvas table td.Mouse{border:1px solid #000;*border:0;}*/
</style>
</head>
<body>
<div id="con">
<h1>贪吃蛇JavaScript版</h1>
<div id="Canvas">
</div> <div>
<span>分数:<i id="integral">0</i></span>
<span class="r">速度:<i id="speed">200</i></span>
</div>
</div> <script type="text/javascript">
var Snake = {
time : "",
mapX : 40,
mapY : 40,
speed : 200,
mousePos : {}, //老鼠坐标
snakeStartPos : {"x":10,"y":20}, //蛇起始位置
snakeDirection : "Right", //起始方向
snakeLen : 5, //长度
snakeArr : [], //蛇身体的坐标
pointArr : [], //转点数组
$ : function(id){
return document.getElementById(id);
},
init : function(){
this.CreateMap();
this.CreateSnake();
this.CreateMouse();
document.onkeydown = this.keyDirection;
this.timer = setInterval(this.MoveSnake, this.speed);
},
CreateMap : function(){ //创建画布
var x = this.mapX,
y = this.mapY,
html = ["<table>"];
for(var i=0; i<y; i++){
html.push("<tr>");
for(var j=0; j<x; j++){
html.push("<td id='map_"+j+"_"+i+"'></td>");
}
html.push("</tr>");
}
html.push("</table>");
this.$("Canvas").innerHTML = html.join("");
},
CreateMouse : function(){ //创建老鼠
var x,y,id,
that = this,
getMouse = function(){
for(var i in that.snakeArr){
if(x==that.snakeArr[i]["x"] && y==that.snakeArr[i]["y"]){ //如果坐标与snake身体重叠重置
return random();
}
}
that.mousePos.x = x;
that.mousePos.y = y;
that.$("map_"+x+"_"+y).className = "Mouse";
},
random = function(){
x = Math.floor(Math.random()*(that.mapX-1));
y = Math.floor(Math.random()*(that.mapY-1));
getMouse();
}; random();
},
CreateSnake : function(){
var $ = this.$,
snakeArr = this.snakeArr,
snakeLen = this.snakeLen,
posX = this.snakeStartPos.x,
posY = this.snakeStartPos.y,
n = snakeLen + posX;
for(var i = posX; i<n; i++){
if(i==n-1){
$("map_"+i+"_"+posY).className = "SnakeHead";
}else{
$("map_"+i+"_"+posY).className = "SnakeBody";
}
snakeLen--;
snakeArr[snakeLen] = [];
snakeArr[snakeLen]["x"] = i;
snakeArr[snakeLen]["y"] = posY;
snakeArr[snakeLen]["d"] = this.snakeDirection;
}
},
MoveSnake : function(){
var body,
_d,
snakeLen = Snake.snakeLen,
snakeArr = Snake.snakeArr; Snake.$('map_'+snakeArr[snakeLen-1]['x']+'_'+snakeArr[snakeLen-1]['y']).className = ""; //蛇尾去除css样式
for(var i=0,len =snakeLen; i<len; i++){
body = snakeArr[i];
if(i==0) {
Snake.$("map_"+body['x']+"_"+body['y']).className = "SnakeBody";
}
_d = Snake.getPoint(body['x'],body['y']);
if(_d) body['d'] = _d; //获取转点改变蛇的方向 //bug 删除转点的时候蛇尾没有转过来
if(i==snakeLen-1 && Snake.pointArr.length>0) Snake.delPoint(body['x'],body['y']); //删除转点 switch(body['d']){
case "Left":
if(i==0)Snake.GameOver(body['x']-1,body['y']), Snake.eatMouse(body['x']-1,body['y']);
body['x']--;
break;
case "Up":
if(i==0)Snake.GameOver(body['x'],body['y']-1), Snake.eatMouse(body['x'],body['y']-1);
body['y']--;
break;
case "Right":
if(i==0)Snake.GameOver(body['x']+1,body['y']), Snake.eatMouse(body['x']+1,body['y']);
body['x']++;
break;
case "Down":
if(i==0)Snake.GameOver(body['x'],body['y']+1), Snake.eatMouse(body['x'],body['y']+1);
body['y']++;
break;
} }
Snake.$("map_"+snakeArr[0]['x']+"_"+snakeArr[0]['y']).className = "SnakeHead";
},
GameOver : function(x,y){ //游戏结束
if(x<0 || y<0 || x>this.mapX-1 || y>this.mapY-1){ //超出边界
clearInterval(this.timer);
return alert("GameOver");
} for(var i in this.snakeArr){ //碰到身体
if(x==this.snakeArr[i]['x'] && y==this.snakeArr[i]['y']){
clearInterval(this.timer);
return alert("GameOver");
}
}
},
keyDirection : function(event){ //键盘控制方向
var event = event || window.event,
key = event.which || event.keyCode,
_snakeDirection = Snake.snakeDirection,
pointArr = Snake.pointArr,
pointNum = pointArr.length,
snakeArr = Snake.snakeArr,
bool = true;
switch(key){
case 37:
if(_snakeDirection=="Left"){
bool = false;
}else{
Snake.snakeDirection="Left";
}
break;
case 38:
if(_snakeDirection=="Up"){
bool = false;
}else{
Snake.snakeDirection="Up";
}
break;
case 39:
if(_snakeDirection=="Right"){
bool = false;
}else{
Snake.snakeDirection="Right";
}
break;
case 40:
if(_snakeDirection=="Down"){
bool = false;
}else{
Snake.snakeDirection="Down";
}
break;
}
if(bool){
if(pointNum>0){
if(pointArr[pointNum-1]['x']!= snakeArr[0]['x'] || pointArr[pointNum-1]['y'] != snakeArr[0]['y']) Snake.CreatePoint();
}else{
Snake.CreatePoint();
}
}
},
CreatePoint : function(){ //创建转点
var pointArr = this.pointArr,
pointNum = pointArr.length;
pointArr[pointNum] = [];
pointArr[pointNum]['x'] = this.snakeArr[0]['x'];
pointArr[pointNum]['y'] = this.snakeArr[0]['y'];
pointArr[pointNum]['d'] = this.snakeDirection;
},
getPoint : function(x,y){
var _d = "",
pointArr = Snake.pointArr;
for(var i in pointArr){
if(x==pointArr[i]['x'] && y==pointArr[i]['y']){
_d = pointArr[i]['d'];
}
}
return _d;
},
delPoint : function(x,y){ //删除转点
var pointArr = Snake.pointArr;
if(x==pointArr[0]['x'] && y==pointArr[0]['y']){
var _a = Snake.snakeArr[Snake.snakeArr.length-2],
_b = Snake.snakeArr[Snake.snakeArr.length-1];
if(_a['x']==_b['x'] && _a['y']==_b['y']) _b['d']=_a['d'];
Snake.pointArr.shift();
}
},
eatMouse : function(x,y){
if(x==this.mousePos.x && y==this.mousePos.y){
var _x, _y,
_tail = this.snakeArr[this.snakeLen-1];
this.snakeArr[this.snakeLen]=[];
this.snakeArr[this.snakeLen]['x'] = _tail['x'];
this.snakeArr[this.snakeLen]['y'] = _tail['y'];
this.snakeArr[this.snakeLen]['d'] = _tail['d'];
this.snakeLen++;
this.speed-=5;
clearInterval(this.timer);
this.CreateMouse();
this.integral();
this.timer = setInterval(this.MoveSnake, this.speed);
}
},
integral : function(){
this.$("integral").innerHTML= Number(this.$("integral").innerHTML)+5;
this.$("speed").innerHTML=this.speed;
}
} Snake.init();
</script>
</body>
</html>
原生JavaScript贪吃蛇的更多相关文章
- html+css+JavaScript贪吃蛇
写文记录一下最近新完成的贪吃蛇游戏案例,用到了html.css和JavaScript,难度不高,适合刚入坑的同学练习,欢迎大家交流. 下面贴源码: <!DOCTYPE html> < ...
- 原生Js贪吃蛇游戏实战开发笔记
前言 本课程是通过JavaScript结合WebAPI DOM实现的一版网页游戏---贪吃蛇的开发全过程,采用面向以象的思想设计开发.通过这个小游戏的开发, 不仅可以掌握JS的语法的应用,还可以学会D ...
- 原生js贪吃蛇
<!DOCTYPE html> <html> <head> <title></title> <meta charset="u ...
- JavaScript原生实现《贪吃蛇》
概述 JavaScript原生实现<贪吃蛇>,每吃掉一个食物,蛇的身体会变长,食物会重新换位置. 详细 代码下载:http://www.demodashi.com/demo/10728.h ...
- 原生JS制作贪吃蛇小游戏
感情都在代码里,来,干了!... <!doctype html> <html> <head> <meta http-equiv="Content-T ...
- 原生js写的贪吃蛇网页版游戏特效
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...
- javascript 编写的贪吃蛇
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JavaScript与html5写的贪吃蛇完整代码
JavaScript与html5写的贪吃蛇完整代码 查看运行效果可访问http://www.codesocang.com/texiao/youxitexiao/2014/0402/7045.html# ...
- javascript实现贪吃蛇
<html> <head> <style> body { background:#444; } .rect { border:1px solid #94F; wid ...
随机推荐
- Hi,this is May.
“山有木兮木有枝 心悦君兮君不知” 当一个现在的人正在思念过去的人,世间的一切也都会变成过去的样子. 声色的娱乐,本来就如闪电的光.击石的火.男女欢合不过埋香葬玉.赋别鹤离鸾之曲,臂膀一曲一伸的工夫罢 ...
- React vs Angular vs Vue 2019
React vs Angular vs Vue 看待这三个主流框架给出的想法 Angular is the entire kitchen that gives you all the tools ne ...
- Kubernetes 学习23 kubernetes资源指标API及自定义指标API
一.概述 1.上集中我们说到,官方文档提示说从k8s 1.11版本开始,将监控体系指标数据获取机制移向新一代的监控模型.也就意味着对于我们的k8s来讲现在应该有这样两种资源指标被使用.一种是资源指标, ...
- 孤独 & 失望
哪有人喜欢孤独,不过是害怕失望.
- QMutexLocker基于QMutex的便利类
首先需要注意的是:QMutexLocker这个类是基于QMutex的便利类,这个类不能够定义 私有成员变量 和 全局变量,只能够定义局部变量来使用. 使用方法:(1)先定义一个QMutex类的 ...
- luogu 1714
前缀和 + rmq #include <bits/stdc++.h> const int N = 5e5 + 10; int Pow[30], Log[N]; int n, m; int ...
- 用SAM实现后缀排序
因为本人几乎不会后缀数组,所以遇到这种SA的模板题也要拿SAM解决. 还是有一点思维难度的. 首先按照国际惯例,建反串的SAM. 然后对于这个反串,我们考虑两个前缀哪一个字典序小:因为是串是反的,所以 ...
- Pro自定义数据源原理
1. 概念 Connector:定义连接到一个数据源的连接信息,用于创建datastore. Datastore:代表一个数据源的实例,用于打开一个或多个tables或feature class. ...
- Large Kernel Matters —— Improve Semantic Segmentation by Global Convolutional Network(GCN全局卷积网络)
作者认为语义分割的两个挑战是分类和定位,而这两个挑战又是比较对立的.对于分类问题,模型需要有变形和旋转不变形,而对于定位问题,模型有需要对变形敏感. 提出的GCN遵循两个主要原则: 1.对定位问题,模 ...
- DM当中用文本输入点【转载】
摘自<ANSYS 13.0 Workbench数值模拟技术> 通过XYZ坐标的文本文件创建3D曲线,文本需要满足一定的格式,格式化文本中,#表示此行是注释,忽略空行,数据行包括5个数据域, ...