参考博客:http://blog.csdn.net/sunxing007/article/details/4187038

上面的博客是一个参考,竟第一次做。真让自己盲人摸象做不出来。

只是我在其上做了一些改进。界面等效果看起来更好一些。

下图是在Chrome上执行的效果,可是火狐IE会不兼容。onkeydown事件不能正确调用

这里用了一张图把贪吃蛇制作过程的思想画了出来,画的有点简陋:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDgwMDUzMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

以下就是把代码发上来。上边有具体的解释:

<html>
<head>
<title>贪吃蛇 By Big_Adamapple</title>
<style>
body{
margin-left:auto;
margin-right:auto;
font-size:9px;
background:#333333;
}
table{margin:140px auto 10px auto; overflow:hidden; border-collapse:collapse; }
td {width:20px; height:20px; border:1px solid #eee; background:#f4f4f4}
input{width:80px; height:30px; margin-left:10px;}
#operate{margin-left:650px; font-size:20px;}
#speed,#core{height:30px; width:50px; text-align:center; color:red; font-size:20px;}
#operate span{color:white;}
</style>
</head>
<script>
function $(id){return document.getElementById(id);} //贪吃蛇类
var Snake = {
tbl: null,
/**
* body: 蛇身。数组放蛇的每一节,
* 数据结构{x:x0, y:y0, color:color0},
* x,y表示坐标,color表示颜色
**/
body: [],
//当前移动的方向,取值0,1,2,3, 分别表示向上,右,下,左, 按键盘方向键能够改变它
direction: 0,
//定时器
timer: null,
//速度
speed: 250,
//是否已经暂停
paused: true,
//行数
rowCount: 20,
//列数
colCount: 20,
//分数
core: 0, //初始化
init: function(){
this.tbl = $("main");
var x = 0;
var y = 0;
this.direction = Math.floor(Math.random()*4); //产生随机移动方向 //产生table
for(var row=0;row<this.rowCount;row++){
var tr=this.tbl.insertRow(-1);
for(var col=0;col<this.colCount;col++) {
var td=tr.insertCell(-1);
}
}
//初始化产生食物
for(var i=0; i<1; i++){
x = Math.floor(Math.random()*this.colCount);
y = Math.floor(Math.random()*this.rowCount); if(!this.isCellFilled(x,y)){
this.tbl.rows[y].cells[x].style.backgroundColor = '#009933';
}
}
//产生蛇头
while(true){
x = Math.floor(Math.random()*this.colCount);
y = Math.floor(Math.random()*this.rowCount);
if(!this.isCellFilled(x,y)){
this.tbl.rows[y].cells[x].style.backgroundColor = "#3399CC";
this.body.push({x:x,y:y,color:'black'});
break;
}
}
this.paused = true; //设置開始
//加入键盘事件
document.onkeydown= function(e){
if (!e)
e = e || window.event;
switch(e.which){
case 13: {
if(Snake.paused){
Snake.move();
Snake.paused = false;
}
else{
//假设没有暂停,则停止移动
Snake.pause();
Snake.paused = true;
}
break;
}
case 37:{//left
//阻止蛇倒退走
if(Snake.direction==1){
break;
}
Snake.direction = 3;
break;
}
case 38:{//up
//快捷键在这里起作用
if(event.ctrlKey){
Snake.speedUp(-20);
break;
}
if(Snake.direction==2){//阻止蛇倒退走
break;
}
Snake.direction = 0;
break;
}
case 39:{//right
if(Snake.direction==3){//阻止蛇倒退走
break;
}
Snake.direction = 1;
break;
}
case 40:{//down
if(event.ctrlKey){
Snake.speedUp(20);
break;
}
if(Snake.direction==0){//阻止蛇倒退走
break;
}
Snake.direction = 2;
break;
}
}
}
},
//移动
move: function(){
$("btn").value="暂停";
this.timer = setInterval(function(){
Snake.erase();
Snake.moveOneStep();
Snake.paint();
$("core").value = Snake.core;
$("speed").value = Snake.speedClass(); }, this.speed);
},
//移动一节身体
moveOneStep: function(){ if(this.checkNextStep()==-1){
clearInterval(this.timer);
alert("Game Over");
return;
}
if(this.checkNextStep()==1){
var _point = this.getNextPos();
var _x = _point.x;
var _y = _point.y;
var _color = 'red';
Snake.core += 10;
this.body.unshift({x:_x,y:_y,color:_color}); this.generateDood(); //由于吃了一个食物。所以再产生一个食物
return;
}
var point = this.getNextPos(); var color = '#3399CC'; //蛇尾减一节。 蛇头加一节,呈现蛇前进的效果
this.body.pop();
this.body.unshift({x:point.x,y:point.y,color:color}); }, pause: function(){
$("btn").value="開始";
clearInterval(Snake.timer);
this.paint();
},
//探寻下一步将走到什么地方
getNextPos: function(){
var x = this.body[0].x;
var y = this.body[0].y; //向上
if(this.direction==0){
y--;
}
//向右
else if(this.direction==1){
x++;
}
//向下
else if(this.direction==2){
y++;
}
//向左
else{
x--;
}
//返回一个坐标
return {x:x,y:y};
},
//检查将要移动到的下一步是什么
checkNextStep: function(){
var point = this.getNextPos();
var x = point.x;
var y = point.y;
if(x<0 || x>=this.colCount || y<0 || y>=this.rowCount){
return -1;//触边界,游戏结束
}
for(var i=0; i<this.body.length; i++){
if(this.body[i].x==x && this.body[i].y==y){
return -1;//碰到自己的身体,游戏结束
}
}
if(this.isCellFilled(x,y)){
return 1;//有东西
}
return 0;//空地
},
//擦除蛇身
erase: function(){
for(var i=0; i<this.body.length; i++){
this.eraseDot(this.body[i].x, this.body[i].y);
}
},
//绘制蛇身
paint: function(){
for(var i=0; i<this.body.length; i++){
this.paintDot(this.body[i].x, this.body[i].y,'#3399CC');
}
},
//擦除一节
eraseDot: function(x,y){
this.tbl.rows[y].cells[x].style.backgroundColor = "";
},
paintDot: function(x,y,color){
this.tbl.rows[y].cells[x].style.backgroundColor = color;
}, //检查一个坐标点有没有被填充
isCellFilled: function(x,y){
if(this.tbl.rows[y].cells[x].style.backgroundColor == ""){
return false;
}
return true;
},
//又一次開始
restart: function(){
if(this.timer){
clearInterval(this.timer);
}
for(var i=0; i<this.rowCount;i++){
this.tbl.deleteRow(0);
}
this.body = [];
this.init();
this.speed = 250;
},
//加速
speedUp: function(time){
if(!this.paused){
if(this.speed+time<10||this.speed+time>2000){
return;
}
this.speed +=time;
this.pause();
this.move();
}
},
speedClass:function(){
var speedClass = (250-Snake.speed)/20;
return speedClass;
},
//产生食物。
generateDood: function(){
var x = Math.floor(Math.random()*this.colCount);
var y = Math.floor(Math.random()*this.rowCount);
var color = '#009933';
while (true) {
if (!this.isCellFilled(x, y)) {
this.tbl.rows[y].cells[x].style.backgroundColor = color;
break;
}
x = Math.floor(Math.random()*this.colCount);
y = Math.floor(Math.random()*this.rowCount);
}
}
};
</script>
<body onLoad="Snake.init();">
<div id="pannel">
<table id="main" border="1" cellspacing="0" cellpadding="0">
</table>
<div id="operate">
<input type="button" id="btn" value="開始" />
<input type="button" id="reset" value="又一次開始" />
<input type="button" id="upSpeed" value="加速" />
<input type="button" id="downSpeed" value="减速" /><br><br>
<span>当前分数:<input type="text" id="core" value=0 readonly="readonly" /></span>
     <span>当前速度<input type="text" id="speed" value=0 readonly="readonly" /></span>
<div>
</div>
<script>
$('btn').onclick = function(){
if(Snake.paused){
Snake.move();
Snake.paused = false;
}
else{
Snake.pause();
Snake.paused = true;
}
};
$("reset").onclick = function(){
Snake.restart();
this.blur();
};
$("upSpeed").onclick = function(){
Snake.speedUp(-20);
};
$("downSpeed").onclick = function(){
Snake.speedUp(20);
};
</script>
</body>
</html>

代码可能有点多,并且bug也有好几个。可是对于刚開始学习的人我感觉应该是挺easy理解的。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

javascript它【蛇系列】第一弹:简单的蛇实现的更多相关文章

  1. 深入理解javascript选择器API系列第一篇——4种元素选择器

    × 目录 [1]id属性 [2]标签名 [3]name属性[4]all 前面的话 说到最常见的DOM应用,恐怕就要数取得特定的某个或某组元素的引用了.DOM定义了许多方式来选取元素,包括getElem ...

  2. 深入理解javascript函数进阶系列第一篇——高阶函数

    前面的话 前面的函数系列中介绍了函数的基础用法.从本文开始,将介绍javascript函数进阶系列,本文将详细介绍高阶函数 定义 高阶函数(higher-order function)指操作函数的函数 ...

  3. 深入理解javascript函数系列第一篇——函数概述

    × 目录 [1]定义 [2]返回值 [3]调用 前面的话 函数对任何一门语言来说都是一个核心的概念.通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行.在javascript里,函数即 ...

  4. 深入理解javascript函数系列第一篇

    前面的话 函数对任何一门语言来说都是核心的概念.通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行.在javascript里,函数即对象,程序可以随意操控它们.函数可以嵌套在其他函数中 ...

  5. Javascript事件模型系列(四)我所理解的javascript自定义事件

    被我拖延了将近一个月的javascript事件模型系列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情,公司的个人的,搞的自己心烦意乱浮躁了一 ...

  6. 学习javascript基础知识系列第三节 - ()()用法

    总目录:通过一段代码学习javascript基础知识系列 注意: 为了便于执行和演示,建议使用chrome浏览器,按F12,然后按Esc(或手动选择)打开console,在console进行执行和演示 ...

  7. JavaScript中的三种弹出对话框

    学习过js的小伙伴会发现,我们在一些实例中用到了alert()方法.prompt()方法.prompt()方法,他们都是在屏幕上弹出一个对话框,并且在上面显示括号内的内容,使用这种方法使得页面的交互性 ...

  8. 原生JavaScript运动功能系列(四):多物体多值链式运动

    原生JavaScript运动功能系列(一):运动功能剖析与匀速运动实现 原生JavaScript运动功能系列(二):缓冲运动 原生JavaScript运动功能系列(三):多物体多值运动 多物体多值链式 ...

  9. 在JavaScript中闭包的作用和简单的用法

    在JavaScript中闭包的作用和简单的用法 一.闭包的简介 作用域链:在js中只有函数有作用域的概念,由于函数内能访问函数外部的数据,而函数外部不能访问函数内部的数据,由上述形成一种作用域访问的链 ...

  10. 关于『进击的Markdown』:第一弹

    关于『进击的Markdown』:第一弹 建议缩放90%食用 比起隐蔽物下的狙击手,Markdown更像冲锋陷阵的阵头兵 简单.粗暴.直接.而且好上手 各位晚上好! 早饭吃了吗您 我 今 天 没 吃 M ...

随机推荐

  1. Silverlight技术调查(3)——国际化

    原文 Silverlight技术调查(3)——国际化 网上有很多关于Silverlight国际化的说明,包括MSDN的示例,都没有强调一点,下面以红色标示,基础国际化知识请先参考MSDN相关章节,关键 ...

  2. Java+7入门经典 - 6 扩展类与继承 Part 1/2

    第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...

  3. php使用 _before_index() 来实现访问页面前,判断登录

    C:\wamp\www\DEVOPS\Home\Lib\Action: <?php class IndexAction extends Action { function index(){ $t ...

  4. javascript 如何获取return回来的对象值

    function aa(){ var b = 1; var c = b+2; return{ a1:b, a2:c } } var bb=aa(); alert(bb.a1);

  5. 一起talk GDB吧(第六回:GDB改动程序执行环境)

    各位看官们,大家好,上一回中我们说的是GDB查看信息的功能,而且说了怎样使用GDB查看程序执行时的 信息.这一回中,我们继续介绍GDB的调试功能:改动程序执行环境.当然了,我们也会介绍怎样使用GDB ...

  6. [置顶] PMBOOK第四版-ITO与数据流图总结

    具体文档下载地址: 点击打开文档下载地址 :http://download.csdn.net/detail/lyjluandy/6694205 一.过程组与知识领域表(简图) 二.输入 - 工具 - ...

  7. IdHttpServer实现webservice(130篇DataSnap文章)

    IdHttpServer实现webservice   朋友有个项目,通信协议使用HTTP,数据序列使用BIN(二进制).他不知道要选用何种技术方案. REST webservice是http+json ...

  8. 14.1.1 InnoDB as the Default MySQL Storage Engine

    14.1 Introduction to InnoDB 14.1.1 InnoDB as the Default MySQL Storage Engine 14.1.2 Checking InnoDB ...

  9. CF437D(The Child and Zoo)最小生成树

    题目: D. The Child and Zoo time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  10. 正确理解Python文件读写模式字w+、a+和r+

    w+ 和 r+的差别不难理解.还有a+ +同一时候读写,就可以读又可写,边写边读.边读边写,不用flush,用seek 和 tell可測得. fp = open("a.txt", ...