Javascript做的贪食蛇

首先声明: 这个贪食蛇的小游戏,是我闲来无事写的。没有参考任何范例,纯原创。

对于JS我是一个初学者 ,如有不足的地方,勿喷。

虽然只是一个小小的游戏,但还是有必要声明一下,仅供学习、参考使用,不得用于商业用途(我 是觉得不大可能)。

个人觉得功能还不完善,如果有哪位大神可以完善一下就更好了。

代码大概有五六百行,分为三个文件一个html文件和两个js文件,下面是这三个文件的代码。 

如果你觉得下面的代码看起来太麻烦,可以联系我的邮箱 jsennahe@foxmail.com ,我会将整个工程文件发给你。

由于嫌麻烦就没有将html、js、css 分开写,请见谅。

HTML文件 tancishe.html代码:

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>这是:贪食蛇</title>
		<link rel="stylesheet" >
		<style>
			#canvas{
				z-index: -1;
			}
			#Father{
				height: 655px;
				width: 1220px;
				margin: 0 auto;
				margin-top: 5px;
				/*background-color: #a9a9a9;*/
				border:none;
			}
			body{
				background-image:url(back4.jpg);
			}
			.ziti1{
				font-size: 50px;
				color: #FFFAFA;
				font-family: "楷体";
			}
			.ziti2{
				font-size: 30px;
				font-family: "楷体";
				color:#696969;
			}
			.ziti2:hover{
				color:#fff;
			}
			a{
				text-decoration: none;
			}
			.Top1{
				margin: 0 auto;
				width: 1220px;
				height: 30px;
				border-bottom: 3px dotted #696969;
				line-height: 30px;
				display: none;
			}
			.Top-left{
				width: 403px;
				height: 40px;
				float: left;
				line-height: 40px;
				z-index: 6;
			}
			.Top-right{
				width: 403px;
				height: 40px;
				float: right;
				line-height: 40px;
				z-index: 6
			}
			.fontstyle{
				
			}
			
		</style>
	</head>
	<body align="center" id="body">
		<!-- 顶部的展示部分 -->
		<div class="Top">
			<!-- <input type="text" width="100" height="20" /> -->
			
			<!-- <div class="Top-center"> --><!--<a><font class="ziti1">贪食蛇</font></a>--><!-- </div> -->
			
		</div>
		<!-- 中部游戏主界面 -->
		<div align="center" id="Father" >
			<div class="Top1" id="timeandlong">
			<!-- <input type="text" width="100" height="20" /> -->
			<div class="Top-left" ><font color="#696969" class="fontstyle">时间:</font><font color="#696969" id="Time">00</font></div>

			<!-- <div class="Top-center"> --><a href="javascript:window.opener=null;window.open('','_self');window.close();" ><font class="ziti2">关闭</font></a><!-- </div> -->

			<div class="Top-right"><font color="#696969"class="fontstyle">长度:</font><font color="#696969" id="Length" >00</font></div>
		</div>
			

			<canvas id="canvas" width="1210" height="610" >

			</canvas>
		<div>
		<!-- //背景音乐 -->
		<audio id = "sud" loop="loop" autoplay="autoplay"  hidden="true" >
			<source src="http://12844029.s21d-12.faiusrd.com//55//ABUIABA3GAAgkbWfxQUo7djo9QE" type="audio/mpeg" type="audio/mpeg" /> 
		</audio>

		<!-- //吃子音效 -->
		<audio id = "sud1" hidden="true">
			<source src="http://12844029.s21d-12.faiusrd.com/0/ABUIABAAGAAg6Z2fxQUopdGr9gM" type="audio/mpeg" />
		</audio>
		<!-- //结束音效 -->
		<audio id = "sud2" hidden="true">
			<source src="http://12844029.s21d-12.faiusrd.com/55/ABUIABA3GAAgpo6fxQUo4JnL4QE" type="audio/mpeg" />
		</audio>

		<script src="http://12844029.s21d-12.faiusrd.com//0//ABUIABAAGAAgoP7ZxQUonPGOMg"></script>
		<script src="http://12844029.s21d-12.faiusrd.com//0//ABUIABAAGAAgrduRxQUojMbG7wE"></script>
		<script>
		var audio0 = document.getElementById('sud'); //背景音乐
		var audio1 = document.getElementById('sud1'); //吃方块
		var audio2 = document.getElementById('sud2'); //结束游戏

			window.οnlοad=function(){
				//Our code here...
				var GTime=document.getElementById('Time');//显示时间元素
				var SLength=document.getElementById('Length');
				var timelong=document.getElementById("timeandlong");
				var father=document.getElementById('Father');
				var canvas = document.getElementById('canvas');
					context = canvas.getContext('2d');
					mouse = utils.captureMouse(canvas);
					var arr = [];  //数组用于存放身体的方块
					var fps = 500; //帧的刷新时间500ms
					var a=0;  //判断按钮文字颜色 1-开始游戏,2-结束游戏,3-游戏帮助
					var timer1;  //定时器1  频率是10毫秒
					var timer2;	 //定时器2 频率是400毫秒
					head =new HeadFang(); //new 的头方块
					//为头方块随机生成一个位置
					head.x = Math.floor(Math.random()*22) * 50;//Math.random() * canvas.width;
					head.y = Math.floor(Math.random()*10) * 50;//Math.random() * canvas.height;
					//初始化速度为零
					var vx=0,vy=0;
					//初始化三个方块的身体
					for(var fang,i = 0 ; i < 3; i++){
						fang = new Fang(20);
						fang.id = "fang" + i;
						fang.x = head.x*(i+1)*10;//Math.random() * canvas.width;
						fang.y = head.y*(i+1)*10;//Math.random() * canvas.height;
						arr.push(fang);
					}
					//监听键盘的上下左右键
					window.addEventListener('keydown',function(event){
						switch(event.keyCode){
							case 37:
								if(vy!=0){
									vy=0;
								}
								if(vx == 0){
									vx = -head.width;
								}
								
								break;
							case 39:
								if(vy!=0){
									vy=0;
								}
								if(vx == 0){
									vx = head.width;
									
								}
								break;
							case 38:
								if(vx!=0){
									vx=0;
								}
								if(vy == 0){
									vy = -head.width;
									
								}
								break;
							case 40:
								if(vx!=0){
									vx=0;
								}
								if(vy == 0){
									vy = head.width;
									
								}
								
								break;
						}
					},false);

					//一个递归方法,将后一个方块放到前一个方块的位置
					function draw(arrlang){
						if(arrlang>=arr.length-1)return;
						else{
							draw(arrlang+=1);

							if(arrlang!=0){
								arr[arrlang].x=arr[arrlang-1].x;
								arr[arrlang].y=arr[arrlang-1].y;
							}
							//console.log(arrlang+"  "+arr.length);
							arr[arrlang].draw(context);
						}
						
					}

					function ResetAll(){
						//重新计算头的坐标,并将速度置为零
        				head.x = Math.floor(Math.random()*22) * 50;
						head.y = Math.floor(Math.random()*10) * 50;
						vx=0;
						vy=0;
						//保留数组的前三个对象
						arr=arr.slice(0,3);

						for(var i=0;i<arr.length;i++){
							arr[i].x=head.x;
							arr[i].y=head.y;
						}
					}


					//游戏结束所绘制的东西
					function gameover(Over){
						//添加监听事件
        				canvas.addEventListener('mousedown',function(){
        					//判断鼠标是否在指定的区域内
							if(utils.containsPoint(Over.getBounds(),mouse.x,mouse.y)){
								//document.write("in ball : mousedown");
								console.log("***mousedown***");
								begin=0;
								value=0;
								Over=null;  //销毁结束画面对象

								//结束游戏是将游戏时间重置为零
								time1=0;
								//将画面的刷新时间重置
								fps=500;
								audio0.play();
								timelong.setAttribute('style','display: none;');
							}else {
								//document.write("canvas:mousedown");
							}
						},false);
						//调用重置方法
						ResetAll();
						
						//设置显示的文字
						Over.name1="Over";
						Over.name2="重新开始";
						btnstyle(Over);
						Over.draw(context);

    				}
    				//游戏开始所绘制的东西
    				function gamebegin(Begin){
    					//添加监听事件
        				canvas.addEventListener('mousedown',function(){
							//判断鼠标是否在指定的区域内
							if(utils.containsPoint(Begin.getBounds(),mouse.x,mouse.y)){
								//document.write("in ball : mousedown");
								//console.log("***mousedown***");
								//调用全屏的方法,点击开始游戏后就全屏显示
								quan();
								//window.open(document.location, 'big', 'fullscreen=yes');
								Begin=null;
								begin=1;
								var myDate = new Date();
								//var mytime=myDate.getTime();
								time=myDate.getTime();
								
								//显示边框和游戏参数
							    timelong.setAttribute('style','display: block;');
							    father.setAttribute('style','border:3px dotted #696969;')
							    
							    
							}
							else{
								
							}
							/*else if(utils.containsPoint(Begin.getBounds1(),mouse.x,mouse.y)){
								
								console.log("结束游戏");
								window.close();
								
							}
							else if(utils.containsPoint(Begin.getBounds2(),mouse.x,mouse.y)){
								
								console.log("游戏帮助");
								
							}*/
							
						},false);
						
							
						//按钮样式
						btnstyle(Begin);
						
						Begin.name1="贪吃蛇";
						Begin.name2="开始游戏";
						Begin.draw(context);
						
    				}
    				// 按钮样式
    				function btnstyle(be){
    					var obj=be;
    					if(utils.containsPoint(obj.getBounds(),mouse.x,mouse.y)){
								obj.color="#fff";
								obj.x1=50;
								a=1;
								canvas.style.cursor="pointer";
							
							}else if(utils.containsPoint(obj.getBounds1(),mouse.x,mouse.y)){
								obj.color1="#fff";
								obj.x2=50;
								a=2;
								canvas.style.cursor="pointer";
							}else if(utils.containsPoint(obj.getBounds2(),mouse.x,mouse.y)){
								obj.color2="#fff";
								obj.x3=50;
								a=3;
								canvas.style.cursor="pointer";
							}else{
								switch(a){
									case 1:
										Begin.color="#fff";
										Begin.x1=50;
										break;
									case 2:
										Begin.color1="#fff";
										Begin.x2=50;
										break;
									case 3:
										Begin.color2="#fff";
										Begin.x3=50;
										break;
								}
								canvas.style.cursor="auto";
							}
    				}
    				//监听其他按钮事件
    				function Anfun(BO){
    					canvas.addEventListener('mousedown',function(){
        					//判断鼠标是否在指定的区域内
							if(utils.containsPoint(BO.getBounds1(),mouse.x,mouse.y)){
								//console.log("结束游戏");
								window.close();
							}
							else if(utils.containsPoint(BO.getBounds2(),mouse.x,mouse.y)){
								//console.log("游戏帮助");
							}else {
								//console.log("无效的鼠标点击");
							}
						},false);
    				}

    				//判断是否自己撞自己
    				function Self(){
    					var value=0;
    					for(var i=3;i<arr.length-1;i++){
    						if(arr[i].x==head.x && arr[i].y==head.y){
    							value++;
    							break;
    						}
    					}
    					return value;
    				}
					
					//实现全屏
    				function requestFullScreen(element) {    
    					var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;    
    					if (requestMethod) {      
        						requestMethod.call(element);    
    					} 
    					else if (typeof window.ActiveXObject !== "undefined") {      
        						var wscript = new ActiveXObject("WScript.Shell");    
        						if (wscript !== null) {    
            						wscript.SendKeys("{F11}");    
        					}    
    					}    
					} 
					//全屏方法
					function quan(){     
    					var elem = document.getElementById("body");      
    					requestFullScreen(elem);     
					};     


					var value=0;  //由于判断新生成的方块是否被吃 没有被吃(1) 被吃(0) 
					var NewFang;  //新生成方块的名称
					var begin=0;  //判断是否是 开始游戏(0) 进行游戏(1) 结束游戏(2)
					//开始和结束游戏所绘制画面的两个对象
					var Begin;    
					var Over;
					var time=0;   //用来计时的
					var time1=0;	//游戏所用的秒数

					//开始或结束游戏绘制的主方法
					function drawFrame1(){
						context.clearRect(0,0,canvas.width,canvas.height);
						if(begin==0){
								Begin=new BOgame();
								gamebegin(Begin);
								Anfun(Begin);
								audio0.play();
								SLength.innerHTML=arr.length-1;
							
						}
						else if(begin==2){
								Over=new BOgame();
								gameover(Over);
								Anfun(Over);	
						}
						else {
							//清除开始或结束游戏的定时器,启用进行游戏的定时器
							clearInterval(timer1);
							timer2=setInterval(drawFrame,fps);
						}
					}
					//进行游戏绘制主方法
					function drawFrame(){
						//window.requestAnimationFrame(drawFrame,canvas);
						context.clearRect(0,0,canvas.width,canvas.height);
						
						//将时间打印到上
						GTime.innerHTML=time1;
					
						//否则判断是否结束游戏
						
							if(head.x >= canvas.width-10 || head.x <= -5 || head.y >= canvas.height-10 || head.y <= -5 || Self()!=0 )
							{
								Over=new BOgame();
								gameover(Over);
//								Anfun(Over);
								//将游戏状态置为结束
								begin=2;
								//开始播放结束音乐
								audio2.play();
								//停止播放背景音乐
								audio0.pause();
								audio0.currentTime = 0;
								//value=2;
								timelong.setAttribute('style','display: block;');
								father.setAttribute('style','border:none;')
								//清除进行游戏的定时器,启用开始或结束游戏的定时器
								clearInterval(timer2);
								timer1=setInterval(drawFrame1,10);
							}
						
							//否则进行游戏
							if(begin==1){
								canvas.style.cursor="none";
								//如果开始的速度等于零,则不进行移动
								if(vx!=0||vy!=0){
									arr[0].x=head.x;
									arr[0].y=head.y;
									//调用一个递归方法,形成蛇往前走的效果
									draw(0);
									head.x += vx;
									head.y += vy;
									head.draw(context);
									//fps+=10;

									var myDate = new Date();
									var mytime=0;
									mytime=myDate.getTime();
									if(mytime-time>=1000){
										time=myDate.getTime();
										time1=time1+1;
									}
									
								}
								head.draw(context);
						
								//当value=0时表示新生成的方块被吃,再重新生成一个方块
								if(value==0){
									NewFang =new Fang();
									NewFang.x = Math.floor(Math.random()*23) * 50;//Math.random() * canvas.width;
									NewFang.y = Math.floor(Math.random()*11) * 50;//Math.random() * canvas.height;
									value=1;
								}
								if(begin!=2){
									NewFang.draw(context);
								}
								//NewFang.draw(context);
								//判断是否吃到点,
								if(NewFang.x==head.x && NewFang.y==head.y){
									SLength.innerHTML=arr.length;
									audio1.play();
									value=0;
									if(fps>=150){
										fps-=10;
										//没吃到一个,就将画面的刷新的时间减少十毫秒
										clearInterval(timer2);
										timer2=setInterval(drawFrame,fps);
									}
									
									arr.push(NewFang);
								}
						
							}
						
				}

					//window.setInterval(drawFrame,fps);
					timer1=setInterval(drawFrame1,10);
					
			};
		</script>
	</body>
</html>

JS文件 fang.js 代码:

function Fang() {
	this.x = 0;
	this.y = 0;
	this.width = 50;
	this.height = 50;
	this.rotation = 0;
	this.color = "#7FFFD4";
}
Fang.prototype.draw = function() {
	context.save();
	context.translate(this.x, this.y);
	context.rotate(this.rotation);
	context.lineWidth = 1;
	context.strokeStyle = "#00ffff";
	context.fillStyle = this.color;
	context.beginPath();
	context.moveTo(10, 10);
	context.lineTo(50, 10);
	context.lineTo(50, 50);
	context.lineTo(10, 50);
	context.lineTo(10, 10);
	context.closePath();
	context.stroke();
	context.restore();
};

function HeadFang() {
	this.x = 0;
	this.y = 0;
	this.width = 50;
	this.height = 50;
	this.rotation = 0;
	this.color = "#ff0000";
}
HeadFang.prototype.draw = function() {
	context.save();
	context.translate(this.x, this.y);
	context.rotate(this.rotation);
	context.lineWidth = 1;
	context.strokeStyle = "#ff0000";
	context.fillStyle = this.color;
	context.beginPath();
	context.moveTo(10, 10);
	context.lineTo(50, 10);
	//context.lineTo(75,30);
	context.lineTo(50, 50);
	context.lineTo(10, 50);
	// context.lineTo(50,30);
	// context.lineTo(10,50);
	context.lineTo(10, 10);
	context.closePath();
	context.stroke();
	context.restore();
};

function BOgame() {
	this.x = 15;	//三个按钮的横坐标
	
	this.x1= 25;    //开始游戏按钮上文字的横坐标
	this.x2= 25;    //结束游戏按钮上文字的横坐标
	this.x3= 25;    //游戏帮助按钮上文字的横坐标
	
	this.y = 365;	//开始游戏按钮‘框’纵坐标
	this.y1= 445;  //结束游戏按钮‘框’纵坐标
	this.y2= 525	//游戏帮助按钮‘框’纵坐标
	this.width = 215;
	this.height = 65;
	//三个按钮的颜色
	this.color = "#DF5326";
	this.color1 = "#DF5326";
	this.color2 = "#DF5326";
	this.name = "Game";
	this.name1 = "贪吃蛇";
	this.name2 = "开始游戏";
	this.name3 = "退出游戏";
	this.name4 = "游戏指南";
}
BOgame.prototype.draw = function() {
	//上部左边文字
		context.font = 'bold 144px consolas';
		context.textAlign = 'left';
		context.textBaseline = 'top';
		context.strokeStyle = '#DF5326';
		context.strokeText(this.name, 15, 150);
	//this.txt(this.name, false, 'bold 144px consolas', '#DF5326', 15, 249);
	上部右边文字
		context.font = 'bold 90px arial';
		context.strokeStyle = '#DF5326';
		//context.fillStyle = 'red';
		context.strokeText(this.name1, 350,200);
	//this.txt(this.name1, false, 'bold 90px consolas', '#DF5326', 350, 249);
	按钮文字-开始游戏-
		context.font = 'bold 50px 楷体';
		context.fillStyle = this.color;
		context.fillText(this.name2, this.x1,380);
	//this.txt(this.name2, true, 'bold 50px 楷体', this.color, this.x1, 380);
	按钮文字-退出游戏-
		context.font = 'bold 50px 楷体';
		context.fillStyle = this.color1;
		context.fillText(this.name3, this.x2,460);
	//this.txt(this.name3, true, 'bold 50px 楷体', this.color1, this.x2, 460);
	按钮文字-游戏指南-
		context.font = 'bold 50px 楷体';
		context.fillStyle = this.color2;
		context.fillText(this.name4, this.x3,540);
	//this.txt(this.name4, true, 'bold 50px 楷体', this.color2, this.x3, 540);

};
//鼠标范围-开始游戏
BOgame.prototype.getBounds = function() {
	return {
		x: this.x,
		y: this.y,
		width: this.width,
		height: this.height,
	};
};
//鼠标范围-退出游戏
BOgame.prototype.getBounds1 = function() {
	return {
		x: this.x,
		y: this.y1,
		width: this.width,
		height: this.height,
	};
};
//鼠标范围-游戏帮助
BOgame.prototype.getBounds2 = function() {
	return {
		x: this.x,
		y: this.y2,
		width: this.width,
		height: this.height,
	};
};

第二个JS文件 utils.js代码:

var utils={};
utils.captureMouse=function(element){
	var mouse={x:0,y:0};
	element.addEventListener('mousemove',function(event){
	var x,y;
	if(event.pageX||event.pageY){
		x=event.pageX;
		y=event.pageY;
	}else{
		x=event.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;
		y=event.clientY+document.body.scrollTop+document.documentElement.scrollTop;
	}
	x-=element.offsetLeft;
	y-=element.offsetTop;

	mouse.x=x;
	mouse.y=y;
},false);
	return mouse;
};

utils.containsPoint = function (rect, x, y){
	return !(x < rect.x || x > rect.x + rect.width || y < rect.y || y > rect.y + rect.height);
};

这是一开始的画面



这是游戏进行时的画面


这是游戏结束时的画面




  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值