javascript实现多人贪吃蛇-画布大小可控-移动速度-宝藏数可修改

代码如下,不引入任何其他js库

<html>
<center>
<h1 id = 'hd' style='margin: 3px'>贪吃蛇</h1>
<canvas id='can' width=450px height=450px style="background:black"></canvas><br/>
<div width = 20px id = 'puller' onMouseOver = "document.getElementById('config').removeAttribute('hidden');">^</div>
<div id = 'config'>
<label>速度(1-100)</label>
<input type = 'text' id = 'speed' style='width: 30px' value = '70'></input>
<label>宝藏数</label>
<input type = 'text' id = 'treasureCount' style='width: 20px' value = '1'></input>
<input name='players' type='radio' checked>单人</input>
<input name='players' type='radio'>双人</input>
<input name='players' type='radio'>三人</input>
<input name='players' type='radio'>四人</input>
<br/><br/>
<label>宽度</label>
<input type = 'text' id = 'cwidth' style='width: 40px' value = '450'></input>
<label>个数</label>
<input type = 'text' id = 'xNum' style='width: 30px' value = '20'></input>
<label>高度</label>
<input type = 'text' id = 'cheight' style='width: 40px' value = '450'></input>
<label>个数</label>
<input type = 'text' id = 'yNum' style='width: 30px' value = '20'></input>
<button onclick = snake.resetSheet()>改变大小</button>
<br/><br/>
<button onclick = snake.reset()>开始</button>
</div>
</center>
<html>
<script>

var snake = {

getCanvas : function() {if (this.canvas) return this.canvas; var can = document.getElementById('can');if (!can) {var cans = doument.getElementsByTagName('canvas');can = cans[0];} this.canvas = can; if (!can) alert('not avaliable!'); return can;},

getContext : function() {if (!this.context) this.context = this.getCanvas().getContext('2d'); return this.context; },

getWidth : function() {if (this.width) return this.width; if (this.canvas) this.width = this.canvas.width; else this.width = this.getCanvas().width; return this.width;},

getHeight : function() {if (!this.height) this.height = this.getCanvas().height; return this.height;},

fill : function(a,b, color) {
var con = this.getContext();
if (color)
con.fillStyle = color;
var pos = this.getPos(a,b);
con.fillRect(pos.x,pos.y,pos.w,pos.h);
if(this.map[a][b]==0) this.map[a][b] = -1;
},

clear : function(a,b) {
var con = this.getContext();
var pos = this.getPos(a,b);
con.clearRect(pos.x-0.1*pos.w,pos.y-0.1*pos.h,1.2*pos.w,1.2*pos.h);
this.map[a][b] = 0;
},

//重置画布,修改画布大小时调用
resetProperties : function() {
var f;
for (f in this) {
if (!(this[f] instanceof Function)){
this[f] = undefined;
}
this.treasure_color = 'red';
this.treasure_flag = 99;
}
},

getPos : function(a,b) {
var sx = this.getSx();
var sy = this.getSy();
var sw = this.getSw();
var sh = this.getSh();
return {x:sx+a*sw+0.1*sw,
y:sy+b*sh+0.1*sh,
w:0.8*sw,
h:0.8*sh};
},

getSx : function() {if (!this.sx) this.sx = this.getWidth() %this.getXNum()/2; return this.sx; },
getSy : function() {if (!this.sy) this.sy = this.getHeight()%this.getYNum()/2; return this.sy; },
getSw : function() {if (!this.sw) this.sw = (this.getWidth()-2*this.getSx())/this.getXNum(); return this.sw;},
getSh : function() {if (!this.sh) this.sh = (this.getHeight()-2*this.getSy())/this.getYNum(); return this.sh;},
getXNum : function() {if (!this.xNum) {var x = document.getElementById('xNum').value; if(isNaN(x)) this.xNum = 20; else this.xNum = x;} return this.xNum;},
getYNum : function() {if (!this.yNum) {var y = document.getElementById('yNum').value; if(isNaN(y)) this.yNum = 20; else this.yNum = y;} return this.yNum;},

treasure_color : 'red',
treasure_flag : 99,

//开始
start : function() {
this.resetSheet();
var i = 0, j = 0;
this.map = new Array();
for (i = 0; i < this.getXNum(); i++) {
this.map[i] = new Array(this.getYNum());
for (j = 0; j < this.getYNum(); j++)
this.map[i][j] = 0;
}

//隐藏设置参数
var conf = document.getElementById('config');
if (conf) conf.setAttribute('hidden', true);
conf = null;
document.getElementById('hd').setAttribute('hidden', true);

//放蛇
this.snakes = new Array();
this.snakes[0] = {headx:2, heady:0, dir:{x:1,y:0},trace:[{x:0,y:0},{x:1,y:0},{x:2,y:0}], color:'blue', flag: 1, left:37,up:38,right:39,down:40};

//选择蛇数量
var count = document.getElementsByName('players');
var playerNum = 1;
for (i = 0; i < count.length; i++) {
if (count[i].checked) {
playerNum = i+1;
break;
}
}

if (playerNum >= 2) this.snakes[1] = {headx:this.getXNum()-3, heady:0, dir:{x:-1,y:0},trace:[{x:this.getXNum()-1,y:0},{x:this.getXNum()-2,y:0}, {x:this.getXNum()-3,y:0}], color:'green', flag: 2, left:65,up:87,right:68,down:83};

if (playerNum >= 3) this.snakes[2] = {headx:2, heady:this.getYNum()-1, dir:{x:1,y:0},trace:[{x:0,y:this.getYNum()-1},{x:1,y:this.getYNum()-1}, {x:2,y:this.getYNum()-1}], color:'yellow', flag: 3, left:74,up:73,right:76,down:75};

//初始化蛇位置颜色
this.fill(0,0,this.snakes[0].color);
this.fill(1,0,this.snakes[0].color);
this.fill(2,0,this.snakes[0].color);
if (this.snakes[1]) {
this.fill(this.getXNum()-1,0,this.snakes[1].color);
this.fill(this.getXNum()-2,0,this.snakes[1].color);
this.fill(this.getXNum()-3,0,this.snakes[1].color);
}
if (this.snakes[2]) {
this.fill(0,this.getYNum()-1,this.snakes[2].color);
this.fill(1,this.getYNum()-1,this.snakes[2].color);
this.fill(2,this.getYNum()-1,this.snakes[2].color);
} 
if (this.snakes[3]) {
this.fill(this.getXNum()-1,this.getYNum()-1,this.snakes[3].color);
this.fill(this.getXNum()-2,this.getYNum()-1,this.snakes[3].color);
this.fill(this.getXNum()-3,this.getYNum()-1,this.snakes[3].color);
}

//放宝藏
var trec = document.getElementById('treasureCount').value;
if (isNaN(trec)) trec = 1;
for (i = 0; i < trec; i++)
 this.putTreasure();

document.addEventListener('keydown', function(event){
var keyCode = event.keyCode; 
var i;
if(!snake.snakes) return;
for (i = 0; i < snake.snakes.length; i++){
var ss = snake.snakes[i];
if (ss.unchangeable) continue;
if(keyCode == ss.left && ss.dir.x != 1) {ss.dir = {x:-1,y:0}; ss.unchangeable = true;}
else if(keyCode == ss.up && ss.dir.y != 1) {ss.dir = {x:0,y:-1}; ss.unchangeable = true;}
else if(keyCode == ss.right && ss.dir.x != -1) {ss.dir = {x:1,y:0}; ss.unchangeable = true;}
else if(keyCode == ss.down && ss.dir.y != -1) {ss.dir = {x:0,y:1}; ss.unchangeable = true;}
}
});


this.loop();
},
//开始函数结束

resetSheet : function() {
this.stop();
this.resetProperties();
var ca = this.getCanvas();
var w = Number.parseInt(document.getElementById('cwidth').value);
var h = Number.parseInt(document.getElementById('cheight').value);
if (isNaN(w) || isNaN(h)) w = h = 500;
if (w < 100) w = 100;
if (h < 100) h = 100;
ca.width = w;
ca.height = h;
this.canvas = undefined;
},

stop : function() {
if(this.interval) {
clearInterval(this.interval);this.getContext().clearRect(0,0,this.getWidth(), this.getHeight());
}
},

reset : function() {
this.stop();
this.start();
},

loop : function() {
//速度
var speed = document.getElementById('speed').value;
if (!speed instanceof Number) speed = 50;
if (speed > 100) speed = 100;
if (speed <= 0) speed = 1;
this.interval = setInterval(this.act, 450-4*speed);
},

act : function() {
var i, alive = 0;
with(snake) {
for (i = 0; i < snakes.length; i++) {
if(!snakes[i].dead) {
alive++;
snakes[i].unchangeable = false;
move(snakes[i]);
}
}
if (alive == 0) {
clearInterval(interval);
document.getElementById('config').removeAttribute('hidden');
}
}
},

putTreasure : function() {
pos = this.getEmptyBlock();
this.fill(pos.x, pos.y, this.treasure_color);
this.map[pos.x][pos.y] = this.treasure_flag;
},

move : function(snak) {
with(snake){
var next_x = snak.headx+snak.dir.x;
var next_y = snak.heady+snak.dir.y;
if (outRange(next_x, next_y)) { snak.dead = true; this.clearSnake(snak); return;}
snak.trace.push({x:next_x, y:next_y});
if (!isTreasure(next_x, next_y)) {
var pop = snak.trace.shift();
clear(pop.x, pop.y);
} else putTreasure();
snak.headx = next_x;
snak.heady = next_y;
fill(next_x, next_y, snak.color);
this.map[next_x][next_y] = snak.flag;
}
},

clearSnake : function(s) {
do{
var p = s.trace.shift();
this.clear(p.x, p.y);
} while (s.trace.length)
},

isTreasure : function(a,b) {return this.map[a][b]==this.treasure_flag;},

getEmptyBlock : function() {
var times = 0;
var pos = {x:Math.floor(Math.random()*this.getXNum()), y:Math.floor(Math.random()*this.getYNum())};
if(this.map[pos.x][pos.y]) {
 var i = pos.x, j = pos.y;
 do {
 j = pos.y
 do {
 if (!this.map[i][j]) return {x:i,y:j};
 j = (j+1)%this.getYNum();
 } while (j!=pos.y)
 i = (i+1)%this.getXNum();
 } while (i!=pos.x)
} else return pos;
alert('噢!格子满了!全吃完了吗,你这条贪吃蛇!');
this.stop();
return pos;
},

outRange : function(a,b) { return a>=this.getXNum() || a < 0 || b < 0 || b >= this.getYNum() || (this.map[a][b]!=0 && this.map[a][b]!=this.treasure_flag);}

}

</script>


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值