閱讀947 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Html 5 坦克大戰(韓順平版本)

html 5代碼部分如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body onkeydown="getCommand();">
<h1>hmtl5-經典的坦克大戰</h1>
<!--坦克大戰的戰場-->
<canvas  width="400px" height="300px" ></canvas>
<span >數據</span>
<!--把tankGames.js引入到本頁麵-->
<script type="text/javascript" src="tankGame7.js"></script>
<script type="text/javascript">
	//得到畫布
	var canvas1=document.getElementById("tankMap");
	//得到繪圖上下文(你可以理解是畫筆)
	var cxt=canvas1.getContext("2d");	
	//我的坦克 hero
	//方向 
	var hero=new Hero(140,140,0,heroColor);
	//定義子彈數組
	var heroBullets=new Array();
	//定義敵人的坦克(敵人的坦克有多少? 思路 : 是單個單個的定義,還是放在數組中?)
	var enemyTanks=new Array();
	//定義敵人子彈的數組
	var enemyBullets=new Array();
	//定義一個炸彈數組(可以存放很多炸彈,)
	var bombs=new Array();
	//先死後活 ,定3個,後麵我們把敵人坦克的數量,作出變量
	//0->上, 1->右, 2->下 3->左
	for(var i=0;i<3;i++){		
		//創建一個坦克
		var enemyTank=new EnemyTank((i+1)*50,0,2,enmeyColor);
		//把這個坦克放入數組
		enemyTanks[i]=enemyTank;
		//啟動這個敵人的坦克
		window.setInterval("enemyTanks["+i+"].run()",50);
		//當創建敵人坦克時就分配子彈
		var eb=new Bullet(enemyTanks[i].x+9,enemyTanks[i].y+30,2,1.2,"enemy",enemyTanks[i]);
		enemyBullets[i]=eb;
		//啟動該子彈
		var ettimer=window.setInterval("enemyBullets["+i+"].run()",50);
		enemyBullets[i].timer=ettimer;		
	}
		//先調用一次
		flashTankMap();
	//專門寫一個函數,用於定時刷新我們的作戰區,把要在作戰區出現的元素(自己坦克,敵人坦克,子彈,炸彈,
	//障礙物...)->遊戲思想
	function flashTankMap(){	
		//把畫布清理
		cxt.clearRect(0,0,400,300); 
		//我的坦克
		drawTank(hero);
		//畫出自己的子彈
		//子彈飛效果是怎麼出現的?[答 : 首先我們應該每隔一定時間(setInterval)就去刷新作戰區,如果在刷新的時候,子彈坐標變換了,給人的感覺就是子彈在飛!]
		drawHeroBullet();
		//敵人的坦克
		//判斷一下敵人坦克是否擊中
		isHitEnemyTank();
		drawEnemyBomb();
		drawEnemyBullet();		
		//畫出所有敵人坦克
		for(var i=0;i<3;i++){
			drawTank(enemyTanks[i]);
		}			
	}
	//這是一個接受用戶按鍵函數
	function getCommand(){		
		//我怎麼知道,玩家按下的是什麼鍵
		//說明當按下鍵後 事件--->event對象----->事件處理函數()
		var code=event.keyCode;//對應字母的ascii碼->我們看碼表	
		switch(code){
			case 87://上
				hero.moveUp();				
			   break;
			case 68:			
			  hero.moveRight();
			   break;
			 case 83:				
				hero.moveDown();
				break;
			case 65:
				hero.moveLeft();
				break;
			case 74:
				hero.shotEnemy();
				break;
		}		
		//觸發這個函數 flashTankMap();
		flashTankMap();
		//重新繪製所有的敵人的坦克.你可以在這裏寫代碼(思想,我們幹脆些一個函數,專門用於定時刷新我們的畫布[作戰區])
	}	
	//每隔100毫秒去刷新一次作戰區
	window.setInterval("flashTankMap()",100);
</script>
</body>
</html>
javascript部分代碼如下:

//為了編程方便,我們定義兩個顏色數組
var heroColor=new Array("#BA9658","#FEF26E");
var enmeyColor=new Array("#00A2B5","#00FEFE");
//其它的敵人坦克,這裏的擴展性,還是不錯的.
//定義一個炸彈類
function Bomb(x,y){
	this.x=x;
	this.y=y;
	this.isLive=true; //炸彈是否活的,默認true;
	//炸彈有一個生命值
	this.blood=9;
	//減生命值
	this.bloodDown=function(){
		if(this.blood>0){
			this.blood--;
		}else{
			//說明炸彈死亡
			this.isLive=false;
		}
	}
}


//子彈類
//type表示:這顆子彈是敵人的,還是自己的
//tank表示對象,說明這顆子彈,屬於哪個坦克.
function Bullet(x,y,direct,speed,type,tank){
	this.x=x;
	this.y=y;
	this.direct=direct;
	this.speed=speed;
	this.timer=null;
	this.isLive=true;
	this.type=type;
	this.tank=tank;
	this.run=function run(){
		
			//在該表這個子彈的坐標時,我們先判斷子彈是否已經到邊界
			//子彈不前進,有兩個邏輯,1.碰到邊界,2. 碰到敵人坦克.
			if(this.x<=0||this.x>=400||this.y<=0||this.y>=300||this.isLive==false){
				//子彈要停止.
				window.clearInterval(this.timer);
				//子彈死亡
				this.isLive=false;

				if(this.type=="enemy"){
						this.tank.bulletIsLive=false;
				}
			}else{
				//這個可以去修改坐標
				switch(this.direct){
					case 0:
							this.y-=this.speed;
							break;
					case 1:
							this.x+=this.speed;
							break;
					case 2:
							this.y+=this.speed;
							break;
					case 3:
							this.x-=this.speed;
							break;
				}
			}

			document.getElementById("aa").innerText="子彈x="+this.x+" 子彈y="+this.y;
	}
}

//這是一個Tank類
function Tank(x,y,direct,color){
	
		this.x=x;
		this.y=y;
		this.speed=1;
		this.isLive=true;
		this.direct=direct;
		//一個坦克,需要兩個顏色.
		this.color=color;
		//上移
		this.moveUp=function(){
			this.y-=this.speed;
			this.direct=0;
		}
		//向右
		this.moveRight=function(){
			this.x+=this.speed;
			this.direct=1;
		}

		//下移
		this.moveDown=function(){
			this.y+=this.speed;
			this.direct=2;
		}
		//左
		this.moveLeft=function(){
			this.x-=this.speed;
			this.direct=3;
		}
}

//定義一個Hero類
	//x 表示坦克的 橫坐標, y 表示縱坐標, direct 方向	
	function Hero(x,y,direct,color){
	
		//下麵兩句話的作用是通過對象冒充,達到繼承的效果
		this.tank=Tank;
		this.tank(x,y,direct,color);

		//增加一個函數,射擊敵人坦克.
		this.shotEnemy=function(){
			
			//創建子彈, 子彈的位置應該和hero有關係,並且和hero的方向有關.!!!
			//this.x 就是當前hero的橫坐標,這裏我們簡單的處理(細化)

			switch(this.direct){
				case 0:
				heroBullet=new Bullet(this.x+9,this.y,this.direct,1,"hero",this);
				break;
				case 1:
				heroBullet=new Bullet(this.x+30,this.y+9,this.direct,1,"hero",this);
				break;
				case 2:
				heroBullet=new Bullet(this.x+9,this.y+30,this.direct,1,"hero",this);
				break;
				case 3: //右
				heroBullet=new Bullet(this.x,this.y+9,this.direct,1,"hero",this);
				break;
			}

			//把這個子彈對象放入到數組中	 -> push函數
			heroBullets.push(heroBullet);
			//調用我們的子彈run, 50 是老師多次測試得到的一個結論., 這裏技術難度比較大.
			//就算你工作過1-2年,你也未必想到, 下麵啟動方式,每個子彈的定時器是獨立,如果按原來的方法
			//則所有子彈共享一個定時器.
			var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);
			//把這個timer賦給這個子彈(js對象是引用傳遞!)
			heroBullets[heroBullets.length-1].timer=timer;

		}



	}

	//定義一個EnemyTank類
	function EnemyTank (x,y,direct,color){
		
		//也通過對象冒充,來繼承Tank
		this.tank=Tank;
		this.count=0;
		this.bulletIsLive=true;
		
		this.tank(x,y,direct,color);

		this.run=function run(){
			
			//判斷敵人的坦克當前方向
			switch(this.direct){
				
				case 0:
					if(this.y>0){
						this.y-=this.speed;
					}	
					break;
				case 1:
					if(this.x+30<400){
						this.x+=this.speed;
					}
					break;
				case 2:
					if(this.y+30<300){
						this.y+=this.speed;
					}
					break;
				case 3:
					if(this.x>0){
						this.x-=this.speed;
					}
					break;
			}
			//改變方向,走30次,再改變方向
			if(this.count>30){
				this.direct=Math.round(Math.random()*3);//隨機生成 0,1,2,3
				this.count=0;
			}
			this.count++;

			//判斷子彈是否已經死亡,如果死亡,則增加新的一顆子彈
			if(this.bulletIsLive==false){
				//增子彈,這是需要考慮當前這個敵人坦克的方向,在增加子彈
					switch(this.direct){
						case 0:
						etBullet=new Bullet(this.x+9,this.y,this.direct,1,"enemy",this);
						break;
						case 1:
						etBullet=new Bullet(this.x+30,this.y+9,this.direct,1,"enemy",this);
						break;
						case 2:
						etBullet=new Bullet(this.x+9,this.y+30,this.direct,1,"enemy",this);
						break;
						case 3: //右
						etBullet=new Bullet(this.x,this.y+9,this.direct,1,"enemy",this);
						break;
				}

				//把子彈添加到敵人子彈數組中
				enemyBullets.push(etBullet);
				//啟動新子彈run
				var mytimer=window.setInterval("enemyBullets["+(enemyBullets.length-1)+"].run()",50);
				enemyBullets[enemyBullets.length-1].timer=mytimer;

				this.bulletIsLive=true;
			}

		}
	}

		//畫出自己的子彈,多說一句,你也可以把該函數封裝到Hero類中
		function drawHeroBullet(){

				//現在要畫出所有子彈
				for( var i=0;i<heroBullets.length;i++){
					var heroBullet=heroBullets[i];
					//這裏,我們加入了一句話,但是要知道這裏加,是需要對整個程序有把握
					if(heroBullet!=null&&heroBullet.isLive){
						cxt.fillStyle="#FEF26E";
						cxt.fillRect(heroBullet.x,heroBullet.y,2,2);
					}
				}

		}

		//這裏我們還需要添加一個函數,用於畫出敵人的子彈,當然,畫出敵人的子彈和自己的子彈是可以合並的.
		function drawEnemyBullet(){
			
			//現在要畫出所有子彈
				for( var i=0;i<enemyBullets.length;i++){
					var etBullet=enemyBullets[i];
					//這裏,我們加入了一句話,但是要知道這裏加,是需要對整個程序有把握
					if(etBullet.isLive){
						cxt.fillStyle="#00FEFE";
						cxt.fillRect(etBullet.x,etBullet.y,2,2);
					}
				}
		}
	
	//繪製坦克(敵人坦克和自己的坦克)
	function drawTank(tank){
	
		//說明所有的坦克都要isLive這個屬性
		if(tank.isLive){
		

			//考慮方向
			switch(tank.direct){

			case 0: //上
			case 2:// 下
				//畫出自己的坦克,使用前麵的繪圖技術
				//設置顏色
				cxt.fillStyle=tank.color[0];
				//韓老師使用 先死--->後活 (初學者最好用這個方法)
				//先畫出左麵的矩形
				cxt.fillRect(tank.x,tank.y,5,30);
				//畫出右邊的矩形(這時請大家思路->一定要一個參照點)
				cxt.fillRect(tank.x+15,tank.y,5,30);
				//畫出中間矩形
				cxt.fillRect(tank.x+6,tank.y+5,8,20);
				//畫出坦克的蓋子
				cxt.fillStyle=tank.color[1];
				cxt.arc(tank.x+10,tank.y+15,4,0,360,true);
				cxt.fill();
				//畫出炮筒(直線)
				cxt.strokeStyle=tank.color[1];
				//設置線條的寬度
				cxt.lineWidth=1.5;
				cxt.beginPath();
				cxt.moveTo(tank.x+10,tank.y+15);
				
				if(tank.direct==0){
				cxt.lineTo(tank.x+10,tank.y);
				}else if(tank.direct==2){
				cxt.lineTo(tank.x+10,tank.y+30);
				}

				cxt.closePath();
				cxt.stroke();
				break;
			case 1: //右和左
			case 3:
				//畫出自己的坦克,使用前麵的繪圖技術
				//設置顏色
				cxt.fillStyle=tank.color[0];
				//韓老師使用 先死--->後活 (初學者最好用這個方法)
				//先畫出左麵的矩形
				cxt.fillRect(tank.x,tank.y,30,5);
				//畫出右邊的矩形(這時請大家思路->一定要一個參照點)
				cxt.fillRect(tank.x,tank.y+15,30,5);
				//畫出中間矩形
				cxt.fillRect(tank.x+5,tank.y+6,20,8);
				//畫出坦克的蓋子
				cxt.fillStyle=tank.color[1];
				cxt.arc(tank.x+15,tank.y+10,4,0,360,true);
				cxt.fill();
				//畫出炮筒(直線)
				cxt.strokeStyle=tank.color[1];
				//設置線條的寬度
				cxt.lineWidth=1.5;
				cxt.beginPath();
				cxt.moveTo(tank.x+15,tank.y+10);
				//向右
				if(tank.direct==1){
				cxt.lineTo(tank.x+30,tank.y+10);
				}else if(tank.direct==3){ //向左
				cxt.lineTo(tank.x,tank.y+10);
				}

				cxt.closePath();
				cxt.stroke();
				break;

			}
		}
	}

//編寫一個函數,專門用於判斷我的子彈,是否擊中了某個敵人坦克
function isHitEnemyTank(){
	
		//取出每顆子彈
		for(var i=0;i<heroBullets.length;i++){
			
				//取出一顆子彈
				var heroBullet=heroBullets[i];
				if(heroBullet.isLive){ //子彈是活的,才去判斷
				//讓這顆子彈去和遍曆每個敵人坦克判斷
				for(var j=0;j<enemyTanks.length;j++){
					
							var enemyTank=enemyTanks[j];
						
							if(enemyTank.isLive){
							//子彈擊中敵人坦克的條件是什麼? 很多思路 , 韓老師的思想是
							//(看看這顆子彈,是否進入坦克所在矩形)
							//根據當時敵人坦克的方向來決定
							switch(enemyTank.direct){
								case 0: //敵人坦克向上
								case 2://敵人坦克向下
									if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+20
										&&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+30){
										//把坦克isLive 設為false ,表示死亡
										enemyTank.isLive=false;
										//該子彈也死亡
										heroBullet.isLive=false;
										//創建一顆炸彈
										var bomb=new Bomb(enemyTank.x,enemyTank.y);
										//然後把該炸彈放入到bombs數組中
										bombs.push(bomb);
									}
								break;
								case 1: //敵人坦克向右
								case 3://敵人坦克向左
									if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+30
										&&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+20){
										//把坦克isLive 設為false ,表示死亡
										enemyTank.isLive=false;
										heroBullet.isLive=false;

										//創建一顆炸彈
										var bomb=new Bomb(enemyTank.x,enemyTank.y);
										//然後把該炸彈放入到bombs數組中
										bombs.push(bomb);
									}
								break;

							}

						}


				}//for
			}
		}
}

//畫出敵人炸彈 
function drawEnemyBomb(){
	
	for(var i=0;i<bombs.length;i++){
	
		//取出一顆炸彈
		var bomb=bombs[i];
		if(bomb.isLive){


			
			//更據當前這個炸彈的生命值,來畫出不同的炸彈圖片
			if(bomb.blood>6){  //顯示最大炸彈圖
				var img1=new Image();
				img1.src="bomb_1.gif";
				var x=bomb.x;
				var y=bomb.y;
				img1.onload=function(){
					cxt.drawImage(img1,x,y,30,30);
				}
			}else if(bomb.blood>3){
				var img2=new Image();
				img2.src="bomb_2.gif";
				var x=bomb.x;
				var y=bomb.y;
				img2.onload=function(){
					cxt.drawImage(img2,x,y,30,30);
				}
			}else {
				var img3=new Image();
				img3.src="bomb_3.gif";
				var x=bomb.x;
				var y=bomb.y;
				img3.onload=function(){
					cxt.drawImage(img3,x,y,30,30);
				}
			}

			//減血
			bomb.bloodDown();
			if(bomb.blood<=0){
				//怎麼辦?把這個炸彈從數組中去掉
				bombs.splice(i,1);

			}
		}
	}
}
代碼下載地址:https://download.csdn.net/detail/xunzaosiyecao/7847405


最後更新:2017-04-03 05:40:09

  上一篇:go Html 5 坦克大戰(韓順平版本)
  下一篇:go 同學幫改膚色檢測(未完成版)