jQuery 贪吃蛇
2008-03-25 16:50 迷 阅读(902) 评论(0) 编辑 收藏 举报
jQuery是个好东西,不过一直没忙得过来做点什么,于是模仿它的风格写了一个贪吃蛇游戏练练手。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>贪吃蛇 By:iSLee</title>
<style type="text/css">
div { font-family:Verdana, Arial, Helvetica, sans-serif; font-size:12px; padding:10px; }
#toolbar { border:1px solid #6699CC; }
#footer { clear:both; }
.place { border:1px solid #ccc; border-collapse:collapse; }
.place td { border:1px solid #ccc; width:10px; height:10px; font-size:0; }
.sbody { background-color:blue; }
.space { background-color:#fff; }
.apple { background-color:red; }
.speedup { background-color:green; }
.speeddown { background-color:yellow; }
.control td { width:70px; }
.control td input { width:100%; font-family:Verdana, Arial, Helvetica; }
</style>
<script type="text/javascript" language="JavaScript" src="jquery.pack.js"></script>
</head>
<body>
<div id="toolbar">
<table>
<tr>
<td>
<table class="control">
<tr>
<td></td>
<td><input type="button" value="Up (W)" onclick="up()" /></td>
<td></td>
</tr>
<tr>
<td><input type="button" value="Left (A)" onclick="left()" /></td>
<td><input type="button" value="Stop (P)" onclick="stop()" /></td>
<td><input type="button" value="Right (D)" onclick="right()" /></td>
</tr>
<tr>
<td></td>
<td><input type="button" value="Down (S)" onclick="down()" /></td>
<td></td>
</tr>
</table>
</td>
<td>
<input type="button" value="尾巴+" onclick="appendbody('+',1)" />
<input type="button" value="尾巴++" onclick="appendbody('+',2)" />
<input type="button" value="尾巴-" onclick="appendbody('-',1)" />
</td>
<td>
(需要 jQuery 包支持)<br />
<span class='sbody'> </span>:障碍物,蛇身亦是障碍物。<br />
<span class='apple'> </span>:食物,吃后可增加蛇身长度。<br />
<span class='speedup'> </span>:速度,吃后可增加移动速度。<br />
<span class='speeddown'> </span>:速度恢复,恢复到初始速度。
</td>
<tr>
</table>
</div>
<div id="place"></div>
<div id="info"></div>
<div id="footer">
<hr size="1" />
Copyright iSLee 2008.2
</div>
<script type="text/javascript" language="JavaScript">
/*
代码写的比较乱,主要是想练手一下不同写法和不同模式,基本上是随想到哪里就写到哪里。
使用了 jQuery 1.21 版本,函数记忆不熟,有些代码还可以通过它简化。
最后就是执行效率好像不是很高,没太多考虑,不过作为贪吃蛇游戏是足够了,还有很多改进空间,但就到这里吧,我懒得写了 :P
*/
//地区数据设计:0空白地带 1障碍物 2食物 3加速宝物 4恢复速度宝物
Game = {
Snark : { //蛇
Body : [
{ x:9, y:9 },
{ x:9, y:8 },
{ x:9, y:7 }
],
Dir : 'down',
Length : 3,
Speed : 400
},
Place : { //活动区域
Body : new Array(), //区域数据
Size : null, //大小
Create : function() { //创建数据
for (i = 0; i < this.Size; i++) {
x = new Array()
for (j = 0; j < this.Size; j++) {
if (i == 0 || i == this.Size - 1 || j == 0 || j == this.Size - 1) {
x.push(1);
} else {
x.push(0);
}
}
this.Body.push(x);
}
},
//绘制地图
Draw : function(obj) {
way = 'string';
switch (way) {
case 'jQuery':
// jQuery 组合元素方法,速度很慢
tb = $('<table border="1" cellpadding="0" cellspacing="0" class="place"></table>');
x = this.Size; y = this.Size;
for (i = 0; i < x; i++) {
tr = $('<tr></tr>');
tb.append(tr);
for (j = 0; j < y; j++) {
switch (this.Body[i][j]) {
case 0:
tr.append($('<td class="space" id="x' + j + 'y' + i + '"></td>'));
break;
case 1:
tr.append($('<td class="sbody" id="x' + j + 'y' + i + '"></td>'));
break;
}
}
}
break;
case 'insertRow':
// insertRow 方法,速度一般
tb = $('<table border="1" cellpadding="0" cellspacing="0" class="place"></table>')[0];
for (i = 0; i < this.Size; i++) {
tr = tb.insertRow();
for (j = 0; j < this.Size; j++) {
td = tr.insertCell(j);
td.id = 'x' + j + 'y' + i;
switch (this.Body[i][j]) {
case 0:
td.className = 'space';
break;
case 1:
td.className = 'sbody';
break;
}
}
}
break;
case 'string':
// 组合字符串方法,速度最快
tb = '<table border="1" cellpadding="0" cellspacing="0" class="place">';
for (i = 0; i < this.Size; i++) {
tb += '<tr>';
for (j = 0; j < this.Size; j++) {
tb += '<td id="x' + j + 'y' + i + '"';
switch (this.Body[i][j]) {
case 0:
tb += ' class="space"';
break;
case 1:
tb += ' class="sbody"';
break;
}
tb += '></td>';
}
tb += '</tr>';
}
tb += '</table>';
break;
}
$(obj).html(tb);
}
}
}
//初始化
Game.Place.Size = 40;
Game.Place.Create();
Game.Place.Draw('#place');
//取得随机整数
function GetRandom(min, max) {
return parseInt(Math.random() * (max - min + 1) + min)
}
//创建食物
function CreateApply() {
x = GetRandom(1, 19);
y = GetRandom(1, 19);
if (Game.Place.Body[y][x] != 0) {
CreateApply();
} else {
GetGrid(x,y).removeClass().addClass('apple');
Game.Place.Body[y][x] = 2;
}
}
//创建3个食物
CreateApply();
CreateApply();
CreateApply();
//创建速度宝物
function CreateSpeed(css,val) {
x = GetRandom(1, 19);
y = GetRandom(1, 19);
if (Game.Place.Body[y][x] != 0) {
CreateSpeed(css,val);
} else {
GetGrid(x,y).removeClass().addClass(css);
Game.Place.Body[y][x] = val;
}
}
//创建一个加速宝物,一个减速宝物
CreateSpeed('speedup',3);
CreateSpeed('speeddown',4);
createSnark = function() {
for (i = 0; i< Game.Snark.Length; i++) {
showbody(Game.Snark.Body[i]);
}
}
//获取表格单元格子
function GetGrid(x, y) {
return $('#x' + x + 'y' + y);
}
showbody = function(o) {
GetGrid(o.x,o.y).removeClass().addClass('sbody');
}
showspace = function(o) {
GetGrid(o.x,o.y).removeClass().addClass('space');
Game.Place.Body[o.y][o.x] = 0;
}
//增加或减少身体长度,小于等于0时游戏将出错
appendbody = function(m,n) {
for (i = 0; i < n; i++) {
switch (m) {
case "+":
Game.Snark.Body.push(Game.Snark.Body[Game.Snark.Length - 1]);
Game.Snark.Length++;
break;
case "-":
showspace(Game.Snark.Body[Game.Snark.Length - 1]);
Game.Snark.Body.pop();
Game.Snark.Length--;
break;
}
}
}
//操控函数
dirchanged = false; //方向是否被改变
//改变方向
function changedir(a,b) {
if (dirchanged == false) {
if (Game.Snark.Dir != a) {
Game.Snark.Dir = b;
dirchanged = true;
}
}
}
up = function() {
changedir('down','up');
}
down = function() {
changedir('up','down');
}
left = function() {
changedir('right','left');
}
right = function() {
changedir('left','right');
}
stop = function() { Game.Snark.Dir = ''; dirchanged = true; }
//行动
changed = false;
move = function() {
//检查方向
switch (Game.Snark.Dir) {
case 'up':
change(0, -1, 0);
break;
case 'down':
change(0, 1, 0);
break;
case 'left':
change(-1, 0, 0);
break;
case 'right':
change(1, 0, 0);
break;
}
//显示测试数据,打开显示将导致执行速度降低
//showinfo(Game.Snark.Body[0].x, Game.Snark.Body[0].y);
//循环
setTimeout('move()', Game.Snark.Speed);
}
//获取键盘
keydown = function(key) {
switch (key) {
case 119: up(); break;
case 115: down(); break;
case 97: left(); break;
case 100: right(); break;
case 112: stop(); break;
}
}
//信息
showinfo = function(x, y) {
$('#info').html('x:' + x + ' y:' + y + '<br />speed:' + Game.Snark.Speed + '<br />');
str = '';
for (i = 0; i < Game.Place.Size; i++) {
for (j = 0; j < Game.Place.Body[i].length; j++) {
str += '' + Game.Place.Body[i][j];
}
str += '<br />';
}
$('#info').append(str);
}
//逻辑
change = function(x, y, n) {
dirchanged = false;
//消除尾巴
showspace(Game.Snark.Body[Game.Snark.Length - 1]);
//取得当前头部坐标
_x = Game.Snark.Body[0].x + x;
_y = Game.Snark.Body[0].y + y;
//将要移动到的坐标
point = { x:_x, y:_y };
//增加头部数据
Game.Snark.Body.unshift(point);
//检查区域数据
switch (Game.Place.Body[point.y][point.x]) {
case 1:
//碰撞障碍物,游戏结束
stop();
alert('Game Over');
break;
case 2:
//吃到食物
appendbody('+',1);
CreateApply();
break;
case 3:
//增加速度,关闭测试数据可增加执行速度,否则速度到一定时将不会增加,实际速度可能远不如100毫秒。
if ((Game.Snark.Speed - 50) >= 100) {
Game.Snark.Speed = Game.Snark.Speed - 50
}
CreateSpeed('speedup',3);
break;
case 4:
//恢复默认速度
Game.Snark.Speed = 400;
CreateSpeed('speeddown',4);
break;
}
//修改区域数据
Game.Place.Body[point.y][point.x] = 1;
//绘制头部
showbody(Game.Snark.Body[0]);
}
//开始游戏,游戏停止后可能会无法再复原,只能刷新页面。我还是懒
createSnark();
move();
$(document.body).keypress(function(){keydown(window.event.keyCode)});
/*
综上所述,我还是相当的懒的 *^_^*
*/
</script>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>贪吃蛇 By:iSLee</title>
<style type="text/css">
div { font-family:Verdana, Arial, Helvetica, sans-serif; font-size:12px; padding:10px; }
#toolbar { border:1px solid #6699CC; }
#footer { clear:both; }
.place { border:1px solid #ccc; border-collapse:collapse; }
.place td { border:1px solid #ccc; width:10px; height:10px; font-size:0; }
.sbody { background-color:blue; }
.space { background-color:#fff; }
.apple { background-color:red; }
.speedup { background-color:green; }
.speeddown { background-color:yellow; }
.control td { width:70px; }
.control td input { width:100%; font-family:Verdana, Arial, Helvetica; }
</style>
<script type="text/javascript" language="JavaScript" src="jquery.pack.js"></script>
</head>
<body>
<div id="toolbar">
<table>
<tr>
<td>
<table class="control">
<tr>
<td></td>
<td><input type="button" value="Up (W)" onclick="up()" /></td>
<td></td>
</tr>
<tr>
<td><input type="button" value="Left (A)" onclick="left()" /></td>
<td><input type="button" value="Stop (P)" onclick="stop()" /></td>
<td><input type="button" value="Right (D)" onclick="right()" /></td>
</tr>
<tr>
<td></td>
<td><input type="button" value="Down (S)" onclick="down()" /></td>
<td></td>
</tr>
</table>
</td>
<td>
<input type="button" value="尾巴+" onclick="appendbody('+',1)" />
<input type="button" value="尾巴++" onclick="appendbody('+',2)" />
<input type="button" value="尾巴-" onclick="appendbody('-',1)" />
</td>
<td>
(需要 jQuery 包支持)<br />
<span class='sbody'> </span>:障碍物,蛇身亦是障碍物。<br />
<span class='apple'> </span>:食物,吃后可增加蛇身长度。<br />
<span class='speedup'> </span>:速度,吃后可增加移动速度。<br />
<span class='speeddown'> </span>:速度恢复,恢复到初始速度。
</td>
<tr>
</table>
</div>
<div id="place"></div>
<div id="info"></div>
<div id="footer">
<hr size="1" />
Copyright iSLee 2008.2
</div>
<script type="text/javascript" language="JavaScript">
/*
代码写的比较乱,主要是想练手一下不同写法和不同模式,基本上是随想到哪里就写到哪里。
使用了 jQuery 1.21 版本,函数记忆不熟,有些代码还可以通过它简化。
最后就是执行效率好像不是很高,没太多考虑,不过作为贪吃蛇游戏是足够了,还有很多改进空间,但就到这里吧,我懒得写了 :P
*/
//地区数据设计:0空白地带 1障碍物 2食物 3加速宝物 4恢复速度宝物
Game = {
Snark : { //蛇
Body : [
{ x:9, y:9 },
{ x:9, y:8 },
{ x:9, y:7 }
],
Dir : 'down',
Length : 3,
Speed : 400
},
Place : { //活动区域
Body : new Array(), //区域数据
Size : null, //大小
Create : function() { //创建数据
for (i = 0; i < this.Size; i++) {
x = new Array()
for (j = 0; j < this.Size; j++) {
if (i == 0 || i == this.Size - 1 || j == 0 || j == this.Size - 1) {
x.push(1);
} else {
x.push(0);
}
}
this.Body.push(x);
}
},
//绘制地图
Draw : function(obj) {
way = 'string';
switch (way) {
case 'jQuery':
// jQuery 组合元素方法,速度很慢
tb = $('<table border="1" cellpadding="0" cellspacing="0" class="place"></table>');
x = this.Size; y = this.Size;
for (i = 0; i < x; i++) {
tr = $('<tr></tr>');
tb.append(tr);
for (j = 0; j < y; j++) {
switch (this.Body[i][j]) {
case 0:
tr.append($('<td class="space" id="x' + j + 'y' + i + '"></td>'));
break;
case 1:
tr.append($('<td class="sbody" id="x' + j + 'y' + i + '"></td>'));
break;
}
}
}
break;
case 'insertRow':
// insertRow 方法,速度一般
tb = $('<table border="1" cellpadding="0" cellspacing="0" class="place"></table>')[0];
for (i = 0; i < this.Size; i++) {
tr = tb.insertRow();
for (j = 0; j < this.Size; j++) {
td = tr.insertCell(j);
td.id = 'x' + j + 'y' + i;
switch (this.Body[i][j]) {
case 0:
td.className = 'space';
break;
case 1:
td.className = 'sbody';
break;
}
}
}
break;
case 'string':
// 组合字符串方法,速度最快
tb = '<table border="1" cellpadding="0" cellspacing="0" class="place">';
for (i = 0; i < this.Size; i++) {
tb += '<tr>';
for (j = 0; j < this.Size; j++) {
tb += '<td id="x' + j + 'y' + i + '"';
switch (this.Body[i][j]) {
case 0:
tb += ' class="space"';
break;
case 1:
tb += ' class="sbody"';
break;
}
tb += '></td>';
}
tb += '</tr>';
}
tb += '</table>';
break;
}
$(obj).html(tb);
}
}
}
//初始化
Game.Place.Size = 40;
Game.Place.Create();
Game.Place.Draw('#place');
//取得随机整数
function GetRandom(min, max) {
return parseInt(Math.random() * (max - min + 1) + min)
}
//创建食物
function CreateApply() {
x = GetRandom(1, 19);
y = GetRandom(1, 19);
if (Game.Place.Body[y][x] != 0) {
CreateApply();
} else {
GetGrid(x,y).removeClass().addClass('apple');
Game.Place.Body[y][x] = 2;
}
}
//创建3个食物
CreateApply();
CreateApply();
CreateApply();
//创建速度宝物
function CreateSpeed(css,val) {
x = GetRandom(1, 19);
y = GetRandom(1, 19);
if (Game.Place.Body[y][x] != 0) {
CreateSpeed(css,val);
} else {
GetGrid(x,y).removeClass().addClass(css);
Game.Place.Body[y][x] = val;
}
}
//创建一个加速宝物,一个减速宝物
CreateSpeed('speedup',3);
CreateSpeed('speeddown',4);
createSnark = function() {
for (i = 0; i< Game.Snark.Length; i++) {
showbody(Game.Snark.Body[i]);
}
}
//获取表格单元格子
function GetGrid(x, y) {
return $('#x' + x + 'y' + y);
}
showbody = function(o) {
GetGrid(o.x,o.y).removeClass().addClass('sbody');
}
showspace = function(o) {
GetGrid(o.x,o.y).removeClass().addClass('space');
Game.Place.Body[o.y][o.x] = 0;
}
//增加或减少身体长度,小于等于0时游戏将出错
appendbody = function(m,n) {
for (i = 0; i < n; i++) {
switch (m) {
case "+":
Game.Snark.Body.push(Game.Snark.Body[Game.Snark.Length - 1]);
Game.Snark.Length++;
break;
case "-":
showspace(Game.Snark.Body[Game.Snark.Length - 1]);
Game.Snark.Body.pop();
Game.Snark.Length--;
break;
}
}
}
//操控函数
dirchanged = false; //方向是否被改变
//改变方向
function changedir(a,b) {
if (dirchanged == false) {
if (Game.Snark.Dir != a) {
Game.Snark.Dir = b;
dirchanged = true;
}
}
}
up = function() {
changedir('down','up');
}
down = function() {
changedir('up','down');
}
left = function() {
changedir('right','left');
}
right = function() {
changedir('left','right');
}
stop = function() { Game.Snark.Dir = ''; dirchanged = true; }
//行动
changed = false;
move = function() {
//检查方向
switch (Game.Snark.Dir) {
case 'up':
change(0, -1, 0);
break;
case 'down':
change(0, 1, 0);
break;
case 'left':
change(-1, 0, 0);
break;
case 'right':
change(1, 0, 0);
break;
}
//显示测试数据,打开显示将导致执行速度降低
//showinfo(Game.Snark.Body[0].x, Game.Snark.Body[0].y);
//循环
setTimeout('move()', Game.Snark.Speed);
}
//获取键盘
keydown = function(key) {
switch (key) {
case 119: up(); break;
case 115: down(); break;
case 97: left(); break;
case 100: right(); break;
case 112: stop(); break;
}
}
//信息
showinfo = function(x, y) {
$('#info').html('x:' + x + ' y:' + y + '<br />speed:' + Game.Snark.Speed + '<br />');
str = '';
for (i = 0; i < Game.Place.Size; i++) {
for (j = 0; j < Game.Place.Body[i].length; j++) {
str += '' + Game.Place.Body[i][j];
}
str += '<br />';
}
$('#info').append(str);
}
//逻辑
change = function(x, y, n) {
dirchanged = false;
//消除尾巴
showspace(Game.Snark.Body[Game.Snark.Length - 1]);
//取得当前头部坐标
_x = Game.Snark.Body[0].x + x;
_y = Game.Snark.Body[0].y + y;
//将要移动到的坐标
point = { x:_x, y:_y };
//增加头部数据
Game.Snark.Body.unshift(point);
//检查区域数据
switch (Game.Place.Body[point.y][point.x]) {
case 1:
//碰撞障碍物,游戏结束
stop();
alert('Game Over');
break;
case 2:
//吃到食物
appendbody('+',1);
CreateApply();
break;
case 3:
//增加速度,关闭测试数据可增加执行速度,否则速度到一定时将不会增加,实际速度可能远不如100毫秒。
if ((Game.Snark.Speed - 50) >= 100) {
Game.Snark.Speed = Game.Snark.Speed - 50
}
CreateSpeed('speedup',3);
break;
case 4:
//恢复默认速度
Game.Snark.Speed = 400;
CreateSpeed('speeddown',4);
break;
}
//修改区域数据
Game.Place.Body[point.y][point.x] = 1;
//绘制头部
showbody(Game.Snark.Body[0]);
}
//开始游戏,游戏停止后可能会无法再复原,只能刷新页面。我还是懒
createSnark();
move();
$(document.body).keypress(function(){keydown(window.event.keyCode)});
/*
综上所述,我还是相当的懒的 *^_^*
*/
</script>
</body>
</html>