兼容IE10 FIREFOX CHROME 效果见下图

tcs.html
<html>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312" />
<head>
<title>贪吃蛇</title>
<style>
.desktop{
background-color:gray;
border:1px solid green;
width:500px;
height:500px;
}
.textbox{
width:500px;
height:500px;
top:8px;
left:550px;
position:absolute;
}
.msgbox{
top:258px;
left:200px;
color:red;
text-align:center;height:10px;line-height:10px;
position:absolute;
}
.bd{
width:10px;
height:10px;
text-align:center;height:10px;line-height:10px;
border:1px solid gray;
position:absolute;
}
.snake{
background-color:yellow;
}
.food{
background-color:red;
}
.gz{
background-color:green;
}
</style>
<script src="tcs.js"></script>
</head>
<body>
<div id="desktop" class="desktop"></div>
<div id="textbox" class="textbox">
得分:<input id="score" type="text" value="0" readonly="true"></input>
<BR/>坐标:<textarea id="vertex" cols="70" rows="5"></textarea>
</div>
<div id="msg" class="msgbox"></div>
<br/>
<input id="showGz" type="checkbox"/><label for="showGz">显示格子</label>
<input id="startbtn" type="button" value="start"/>
</body>
</html>
tcs.js
//全局参数
var snakeTrain = [],//蛇身
allFood=[],//食物仓库
block,//自动行走定时器
direction=39,//默认方向
desktop ={top:0,left:0},//桌布
foodBox = {x:0,y:0},//食物BOX
nextRandFoodIndex=0,//下一个食物随机点索引
score=0,//得分
gameStatus = 0;//游戏状态 0未启动 1运行中 -1游戏结束
//初始化方法
window.onload = function(e){
desktop.top = getTop($("desktop"));
desktop.left = getLeft($("desktop"));
initallFood();
initKeyDownListener();
$("startbtn").onclick = function(){
gameStatus = 1;
if ($("showGz").checked){
initGz();
}
initSnake();
initFood();
block = window.setInterval("startTrain()",500);
};
}
//根据id获得dom对象
function $(id){
return document.getElementById(id);
}
//随机产生一个界于min和max之间的整数
function getRandomNum(Min,Max)
{
var Range = Max - Min;
var Rand = Math.random();
return(Min + Math.round(Rand * Range));
}
//获得dom对象的top
function getTop(e){
var offset=e.offsetTop;
if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
return offset;
}
//获得dom对象的left
function getLeft(e){
var offset=e.offsetLeft;
if(e.offsetParent!=null) offset+=getLeft(e.offsetParent);
return offset;
}
//初始化食物池
function initallFood(){
for(var i=0;i<50;i++){
for(var j=0;j<50;j++){
allFood.push({x:i*10,y:j*10});
}
}
var len = allFood.length;
for(var i=0;i<len*2;i++){
var n1 = getRandomNum(0,len-1);
var n2 = getRandomNum(0,len-1);
var tmp = allFood[n1];
allFood[n1] = allFood[n2];
allFood[n2] = tmp;
}
}
//初始化食物
function initFood(addScore){
var len = allFood.length;
if (nextRandFoodIndex == len-1){
nextRandFoodIndex = 0;
}
for(var i=nextRandFoodIndex++;i<len;i++){
if (!inSnakeTrain(allFood[i].x, allFood[i].y)){
createBox(allFood[i].x, allFood[i].y, "food");
foodBox = {x:allFood[i].x , y:allFood[i].y};
break;
}
}
if (addScore){
score += 10;
$("score").value = score;
}
}
//初始化格子
function initGz(){
for(var i=0;i<50;i++){
for(var j=0;j<50;j++){
createBox(10*i,10*j,"gz");
}
}
}
//初始化蛇
function initSnake(){
var n = 3;
for(var i=0;i<n;i++){
createBox(10*i,0,"snake");
snakeTrain.push({x:10*i,y:0});
}
drawHead();
}
//初始化键盘监听事件
function initKeyDownListener(){
document.onkeydown = function(e){
if (gameStatus != 1){
return -1;
}
var code = e.keyCode;
if (code<37 || code>40){
return -1;
}
startTrain(code);
}
}
//上下左右手动行走
function leftGo(){
if (direction == 39){//朝右走,不能左转
return -1;
}
if (outside("x-")){
gameOver("撞墙啦!Game Over");
return -1;
}
if (eatSelf("x-")){
gameOver("咬到自己啦!Game Over");
return -1;
}
var len = snakeTrain.length;
var snake = snakeTrain[len-1];
if (foodBox.x == snake.x-10 && foodBox.y == snake.y){//eatting
removeBox(foodBox.x,foodBox.y,"food");
createBox(foodBox.x,foodBox.y,"snake");
snakeTrain.push({x:foodBox.x , y:foodBox.y});
initFood(true);
}else{
trainGo();
snake.x -= 10;
drawSnakeTrain();
}
}
function upGo(){
if (direction == 40){//朝下走,不能北上
return -1;
}
if (outside("y-")){
gameOver("撞墙啦!Game Over");
return -1;
}
if (eatSelf("y-")){
gameOver("咬到自己啦!Game Over");
return -1;
}
var len = snakeTrain.length;
var snake = snakeTrain[len-1];
if (foodBox.x == snake.x && foodBox.y == snake.y-10){//eatting
removeBox(foodBox.x,foodBox.y,"food");
createBox(foodBox.x,foodBox.y,"snake");
snakeTrain.push({x:foodBox.x , y:foodBox.y});
initFood(true);
}else{
trainGo();
snake.y -= 10;
drawSnakeTrain();
}
}
function rightGo(){
if (direction == 37){//朝左走,不能右转
return -1;
}
if (outside("x+")){
gameOver("撞墙啦!Game Over");
return -1;
}
if (eatSelf("x+")){
gameOver("咬到自己啦!Game Over");
return -1;
}
var len = snakeTrain.length;
var snake = snakeTrain[len-1];
if (foodBox.x == snake.x+10 && foodBox.y == snake.y){//eatting
removeBox(foodBox.x,foodBox.y,"food");
createBox(foodBox.x,foodBox.y,"snake");
snakeTrain.push({x:foodBox.x , y:foodBox.y});
initFood(true);
}else{
trainGo();
snake.x += 10;
drawSnakeTrain();
}
}
function downGo(){
if (direction == 38){//朝上走,不能南下
return -1;
}
if (outside("y+")){
gameOver("撞墙啦!Game Over");
return -1;
}
if (eatSelf("y+")){
gameOver("咬到自己啦!Game Over");
return -1;
}
var len = snakeTrain.length;
var snake = snakeTrain[len-1];
if (foodBox.x == snake.x && foodBox.y == snake.y+10){//eatting
removeBox(foodBox.x,foodBox.y,"food");
createBox(foodBox.x,foodBox.y,"snake");
snakeTrain.push({x:foodBox.x , y:foodBox.y});
initFood(true);
}else{
trainGo();
snake.y += 10;
drawSnakeTrain();
}
}
//蛇身跟上蛇头
function trainGo(){
var len = snakeTrain.length;
var i = len-1;
var tmp = snakeTrain[i];
while(i>=1){
removeBox(tmp.x,tmp.y,"snake");
var tmp2 = {'x':snakeTrain[i-1].x , 'y':snakeTrain[i-1].y};
snakeTrain[i-1].x = tmp.x;
snakeTrain[i-1].y = tmp.y;
tmp = tmp2;
i--;
}
removeBox(tmp.x,tmp.y,"snake");
}
//画蛇
function drawSnakeTrain(){
var len = snakeTrain.length;
var str = "";
for(var i=0;i<len;i++){
var snake = snakeTrain[i];
createBox(snake.x,snake.y,"snake");
str += " {x:"+snake.x+",y:"+snake.y+"}";
}
$("vertex").value = str;
}
//装饰蛇头
function drawHead(){
var snake = snakeTrain[snakeTrain.length-1];
var snake2 = snakeTrain[snakeTrain.length-2];
$("snake_"+snake.x+"_"+snake.y).style.backgroundColor = "orange";
$("snake_"+snake2.x+"_"+snake2.y).style.backgroundColor = "yellow";
}
//是否出界
function outside(act){
var snake = snakeTrain[snakeTrain.length-1];
switch(act){
case "x+":
return snake.x + 10 > 490;
case "x-":
return snake.x - 10 < 0;
case "y+":
return snake.y + 10 > 490;
case "y-":
return snake.y - 10 < 0;
}
}
//是否咬到自己
function eatSelf(act){
var snake = snakeTrain[snakeTrain.length-1];
switch(act){
case "x+":
return inSnakeTrain(snake.x + 10 , snake.y);
case "x-":
return inSnakeTrain(snake.x - 10 , snake.y);
case "y+":
return inSnakeTrain(snake.x ,snake.y + 10);
case "y-":
return inSnakeTrain(snake.x ,snake.y - 10);
}
}
//是否在火车车厢内
function inSnakeTrain(x,y){
for(var i=0;i<snakeTrain.length;i++){
var train = snakeTrain[i];
if (x== train.x && y == train.y){
return true;
}
}
return false;
}
//创建方块
function createBox(x,y,sl){
var newNode = document.createElement("div");//创建P标签
newNode.id = sl+"_"+x+"_"+y;
newNode.name = "boxs";
newNode.className="bd "+sl;
if (sl == "gz"){
newNode.style.zIndex = 1;
}else{
newNode.style.zIndex = 9;
}
document.body.appendChild(newNode);
newNode.style.left = (desktop.left+x)+"px";
newNode.style.top = (desktop.top+y)+"px";
}
//移除方块
function removeBox(x,y,sl){
document.body.removeChild($(sl+"_"+x+"_"+y));
}
//自动开火车
function startTrain(code){
if ("undefined" == typeof(code)){
code = direction;
}
var rs = 0;
switch(code){
case 37://左
rs = leftGo();
break;
case 38://上
rs = upGo();
break;
case 39://右
rs = rightGo();
break;
case 40://下
rs = downGo();
break;
}
if (rs != -1){
direction = code;
drawHead();
}
}
function gameOver(msg){
gameStatus = -1;
var link = '<a href="javascript:reloadGame()">再来一次</a>';
$("msg").innerHTML = msg+"<br/><br/>"+link;
$("msg").style.zIndex=10;
window.clearInterval(block);
}
function reloadGame(){
location.replace(location.href);
}
本文详细介绍了贪吃蛇游戏的实现过程,包括界面设计、逻辑编程、定时器使用等关键技术点,并提供了兼容多种浏览器的代码实现。通过随机生成食物、自动行走定时器、键盘事件监听等功能,实现了游戏的动态交互与趣味性。同时,文中还讨论了游戏状态管理、边界处理、自我碰撞检测等关键问题,为开发者提供了一个完整的贪吃蛇游戏实例。
7万+

被折叠的 条评论
为什么被折叠?



