zoukankan      html  css  js  c++  java
  • Html 5 坦克大战(韩顺平县版本号)

    html 5例如,下面的代码段:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8"/>
    </head>
    <body onkeydown="getCommand();">
    <h1>hmtl5-经典的坦克大战</h1>
    <!--坦克大战的战场-->
    <canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas>
    <span id="aa">数据</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); } } } }

    代码下载地址:http://download.csdn.net/detail/xunzaosiyecao/7847405


    版权声明:笔者:jiankunking 资源:http://blog.csdn.net/jiankunking 本文版权归作者和CSDN共同拥有,欢迎转载,但是,如果没有从本节宣布提交权限必须保留,并连接到原来的文章页给出视在位置。

  • 相关阅读:
    linux常用操作命令
    golang的goroutine调度机制,GC机制
    数据库原理
    linux各文件夹的作用
    c++面试题
    EF 新增数据时提示it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element
    EF 批量插入,sqlhelper 批量插入
    C# 自己用到的几个参数转换方法
    asp.net MVC EF Where 过滤条件怎么写
    EF Code First 数据迁移命令
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4840843.html
Copyright © 2011-2022 走看看