用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

游戏--坦克大战

2015-12-20 作者:永夜极光举报

[java]代码库

1.主类
package s1230坦克大战;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

import 工具类.ThreadSleep;

public class Tank1 extends JFrame {
static int panelXLength=700;
static int panelYlength=700;
static int gameXLength=500;
static int gameYLength=500;
static int zidanNum=0;


	MyPanel mp=null;
	
	public static void main(String[] args) 
	{
		Tank1 t1=new Tank1();
	}

	public  Tank1() 
	{	mp=new MyPanel();
	    this.add(mp);
		this.setTitle("坦克大战");             										                //设置窗体的标题	        
    	this.setLocationRelativeTo(null);   										                //设置窗体出现位置居中
    	this.setDefaultCloseOperation(3);  											                //设置窗体的关闭操作
    	this.setResizable(true);                                                               		//设置禁止调整窗体的大小
    	this.setIconImage((new ImageIcon("E:/Michael/javaImage/扫雷图片/bomb.png").getImage()));		//设置标题栏图标      
    	this.setSize(panelXLength,panelYlength);              										//设置窗体的大小 		       
    	this.setLocationRelativeTo(null);                                                      		//设置窗体出现在屏幕中间   
    	this.addKeyListener(mp);
    	this.setVisible(true);		  
    	
    	Thread o=new Thread(mp);                                                                    //添加线程很重要 不然子弹不会动
    	o.start();                                                                                  //这个线程的作用是不断执行MyPanel
	}
	      
    class MyPanel extends JPanel implements KeyListener,Runnable
    {
        MyTank mt=null;      //有什么作用?
        Vector<EnemyTank> dtk=new Vector<EnemyTank>();             //new 出一个新的vector对象,vector多线程
        int tankNum=3;
        
       public MyPanel()
       {
          mt=new MyTank(250,400);                                     //创建我方坦克    
          for(int i=0;i<tankNum;i++)                                  //批量创建敌方坦克,要用到vector
          { EnemyTank dt=new EnemyTank((i)*180+5,10);                 
            dtk.add(dt);
            Thread r=new Thread(dt);                                  //让坦克动起来的线程                      
     	     r.start();
          }
       }

    public void paint(Graphics g)
    {
     super.paint(g);
      g.fillRect(0,0,gameXLength,gameYLength);                                       
      this.drawTank(mt.getX(),mt.getY(),g,mt.leixing,mt.fangxiang);     //在界面上绘制我方坦克,x(坐标),y(坐标),画笔g,类型,方向
      
      for(int i=0;i<tankNum;i++)                                        //在界面上批量绘制敌方坦克
      {   if(dtk.get(i).life==true)
    	  {this.drawTank(dtk.get(i).getX(),dtk.get(i).getY(),g,0,dtk.get(i).fangxiang);       //x(坐标),y(坐标),画笔g,类型,方向
    	   
    	   for(int j=0;j<dtk.get(i).dzd.size();j++)
    	     {  
    		   Zidan zd=dtk.get(i).dzd.get(j);
    	        dtk.get(i).shoot();
    	        
               if(zd!=null&&zd.life==true)    //mt.zd.life==true 控制子弹的范围
               {  
        	    g.setColor(Color.RED);                                      //设置子弹颜色
        	    g.fill3DRect(zd.x, zd.y, 3,3, false);                   //绘制子弹,如何让子弹动起来    	  
               }   
                 if(zd.life==false)            //除去Vector中的zd对象,目的是为了实现子弹数量限制
                	 dtk.get(i).dzd.remove(zd);
    	     }
    	  }
      }
      
      
      for(int i=0;i<mt.aa.size();i++)            //绘制我方坦克子弹
      {  Zidan zd=mt.aa.get(i);
        
         if(zd!=null&&mt.zd.life==true)    //mt.zd.life==true 控制子弹的范围
         {  
    	  g.setColor(Color.RED);                                      //设置子弹颜色
    	  g.fill3DRect(zd.x, zd.y, 3, 3, false);                   //绘制子弹,如何让子弹动起来    	  
         }   
         if(zd.life==false)            //除去Vector中的zd对象,目的是为了实现子弹数量限制
        	 mt.aa.remove(zd);
      }
      
    }

     //子弹是否击中tank的判断方法************************************* 
       public void jizhong(Zidan zd,EnemyTank dt)
       {   switch(dt.fangxiang)
    	   {
            case 0:
            case 1:
            	if(zd.x>dt.x&&zd.x<dt.x+20&&zd.y>dt.y&&zd.y<dt.y+30)
            	{ zd.life=false; dt.life=false;}
            break;
            
            case 2:
            case 3:
            	if(zd.x>dt.x&&zd.x<dt.x+30&&zd.y>dt.y&&zd.y<dt.y+20)
            	{ zd.life=false; dt.life=false;}
            break;
    	   }   
       }
     //子弹是否击中tank的判断方法*************************************  
 
    
	        private void drawTank(int x, int y, Graphics g, int leixing, int fangxiang) //绘制坦克的方法
	{
	
		  switch(leixing)                                             //设置坦克颜色,0为黄色,1为绿色
    	  {
    	  case 0:  g.setColor(Color.YELLOW);break;
    	  case 1:  g.setColor(Color.GREEN);break;
    	  }
    	  
    	  switch(fangxiang)    //坦克方向,case0表示面朝上方的坦克,1表示面朝右方,2表示面朝下方,3表示面朝左方 
    	  {   
    	  case 0:	  g.fill3DRect(x, y, 5, 30, false);                   //履带
       	              g.fill3DRect(x+15, y, 5, 30, false);                //履带
       	              g.fill3DRect(x+5, y+5, 10, 20, false);              //中间正方形车体
       	              g.fillOval(x+5, y+10, 10, 10);                      //椭圆炮台
       	              g.drawLine(x+10, y+15, x+10, y-3);                  //炮管:绝对长度为18
       	              break;
       	              
    	  case 1:     g.fill3DRect(x, y, 30, 5, false); 				  //履带
             		  g.fill3DRect(x, y+15, 30, 5, false); 				  //履带
             		  g.fill3DRect(x+5, y+5, 20, 10, false); 			  //中间正方形车体
             		  g.fillOval(x+10, y+5, 10, 10); 					  //椭圆炮台
             		  g.drawLine(x+15, y+10, x-3, y+10);				  //炮管:绝对长度为18
                      break;
                      
    	  case 2:     g.fill3DRect(x, y, 5, 30, false); 			   	  //履带
 		  			  g.fill3DRect(x+15, y, 5, 30, false); 				  //履带
 		  			  g.fill3DRect(x+5, y+5, 10, 20, false); 			  //中间正方形车体
 		  			  g.fillOval(x+5, y+10, 10, 10); 					  //椭圆炮台
 		  			  g.drawLine(x+10, y+15, x+10, y+33); 				  //炮管:绝对长度为18
 		  			  break;
 		  			  
    	  case 3:     g.fill3DRect(x, y, 30, 5, false);	   			 	  //履带
    	  			  g.fill3DRect(x, y+15, 30, 5, false); 				  //履带
    	  			  g.fill3DRect(x+5, y+5, 20, 10, false); 			  //中间正方形车体
    	  			  g.fillOval(x+5, y+5, 10, 10); 					  //椭圆炮台
    	  			  g.drawLine(x+10, y+10, x+28, y+10);				  //炮管:绝对长度为18
    	  			  break;
    	  }
	}      
    	    public void keyTyped(KeyEvent e) {}                           
    	    public void keyReleased(KeyEvent e) {}
  	        public void keyPressed(KeyEvent e) 
  	        {   //坦克的方向控制,依次是上下左右,对应按键是w s a d。
  	        	 if(e.getKeyCode()==KeyEvent.VK_W)
  	        	 {  	        	   
  	        	   this.mt.setFangxiang(0);
  	        	   this.mt.upMove();
  	        	   
  	        	 }
  	        	
  	        	 if(e.getKeyCode()==KeyEvent.VK_S)
  	        	 { this.mt.setFangxiang(2);
  	        	   this.mt.downMove();
  	        	 }
  	        	 if(e.getKeyCode()==KeyEvent.VK_A)
  	        	 { this.mt.setFangxiang(1);
  	        	   this.mt.leftMove();
  	        	 }
  	        	 if(e.getKeyCode()==KeyEvent.VK_D)
  	        	 { this.mt.setFangxiang(3);
  	        	   this.mt.rightMove();
  	        	 }
  	        	 
  	        	 if(e.getKeyCode()==KeyEvent.VK_J)               //监听发射子弹的按钮
  	        	 {   if(mt.aa.size()<8)                          //限制子弹发射的数量为8颗
  	        		 this.mt.shoot();
  	        	 }	 
  	        	 
  	        	 this.repaint();                                //还没搞懂这个是干嘛的?
  	        }
  	        	 
  	        public void run()
  	        	 {  
  	        		 while(true)
  	        		 {
  	        			 ThreadSleep.threadSleep(100);
  	  	 
  	        	           for(int i=0;i<mt.aa.size();i++)            //2层循环的作用是,让每一颗子弹和每一辆坦克的坐标对比,来确定被打中的坦克
  	        	           {  Zidan zd=mt.aa.get(i);                  //取出子弹
  	        	                if(zd.life)                             //如果子弹有效
  	        	              {  
  	        	    	        for(int j=0;j<dtk.size();j++)     
  	        	    	        {EnemyTank dt=dtk.get(j);     //取出坦克对象
 	        	    	    	 if(dt.life)  this.jizhong(zd,dt);//判断子弹是否击中tank   	        	    	    	                   	            	
  	        	    	        }
  	        	              } 
  	        	           }  
    	                    this.repaint();                         //还没搞懂这个是干嘛的?
  	        	     }        		 
  	        	 }
    }
}



2.sucai类
package s1230坦克大战;

import java.util.Random;
import java.util.Vector;
	
class Tank {
    int x=0,y=0; //横纵坐标
    int speed=9;
    int fangxiang=0;
    int leixing=1;
    int time=0;
    boolean life=true;
    
	public Tank(int x,int y)           //构造方法
   	{this.x=x;
   	 this.y=y;
   	}

	public int  getSpeed()          			{return speed;}
	public void setSpeed(int speed)			    {this.speed = speed;}
 	public int  getX() 							{return x;}
 	public void setX(int x) 					{this.x = x;}
 	public int  getY() 							{return y;}
	public void setY(int y)    					{this.y = y;}
	public void upMove()						{if(y>5)  y-=speed;}    	                //向上移动
	public void downMove()						{if(y<460)y+=speed;}  					//向下移动
	public void leftMove()						{if(x>5)  x-=speed;}						//向左移动
	public void rightMove()					 	{if(x<460)x+=speed;}						//向右移动
	public int  getFangxiang()      			{return fangxiang;}
	public void setFangxiang(int fangxiang)  	{this.fangxiang = fangxiang;}
	public int getLeixing()                     {return leixing;}
	public void setLeixing(int leixing)         {this.leixing = leixing;}
		

}

 class MyTank extends Tank
 {   Vector<Zidan> aa=new Vector<Zidan>();      //专门存放子弹,来解决一按发射键子弹消失的问题
	 Zidan zd=null;
       
	public MyTank(int x,int y)
		{super(x,y);}			       //调用父类的构造方法

	public void shoot()
	{  switch(this.fangxiang)
		{	case 0: zd=new Zidan(x+10,y,0);   	aa.add(zd);break;		 //每发射一颗子弹都加入到容器Vector中
			case 1: zd=new Zidan(x,y+10,1);  	aa.add(zd);break;			
			case 2: zd=new Zidan(x+10,y+30,2);	aa.add(zd);break;		
			case 3: zd=new Zidan(x+30,y+10,3);	aa.add(zd);break;
		}
		Thread t=new Thread(zd);                                        //这个线程是为了让子弹动起来
		t.start();		
	}
 }


 class EnemyTank extends Tank implements Runnable
 {   int speed=1;                      //每次线程调用,坦克前进一次的距离
     Zidan zd=null;
   
     Vector<Zidan> dzd=new Vector<Zidan>();      //专门存放子弹,来解决一按发射键子弹消失的问题
	 public EnemyTank(int x,int y)
		{super(x,y);}			       //调用父类的构造方法
	 
	 
	 public void shoot()
		{  switch(this.fangxiang)
			{	case 0: zd=new Zidan(x+10,y,0);  	dzd.add(zd);break;		 //每发射一颗子弹都加入到容器Vector中
				case 1: zd=new Zidan(x,y+10,1);		dzd.add(zd);break;			
				case 2: zd=new Zidan(x+10,y+30,2);	dzd.add(zd);break;		
				case 3: zd=new Zidan(x+30,y+10,3);	dzd.add(zd);break;
			}
			Thread t=new Thread(zd);                                        //这个线程是为了让子弹动起来
			t.start();		
		}
	 
	 public void run()
	 {
		 while(true)
		 {  
		    int length;
		    Random a=new Random();
			this.fangxiang=(int)(Math.random()*4);           //随机产生方向
			switch(this.fangxiang)
			    { case 0:                             
				           length=a.nextInt(59)+13;                     //每次随机方向,坦克前进的距离为 次数*speed,就是每次随机方向前进的总距离		    	      
				           for(int i=0;i<length;i++)
			    	       {
			    	    	   if(y>5)y-=speed; 
			    	    	   else break;
			    	    	   try {Thread.sleep(50);} 				      //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
			    	    	   catch (Exception e) {}
			    	       }
			               break;		
			    
			      case 1:                            
			               length=a.nextInt(59)+13;                     //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
			      		   for(int i=0;i<length;i++)
			      		   {
			      			   if(x>5)x-=speed; 
			      			   else break;
			      			   try {Thread.sleep(50);} 				      //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
			      			   catch (Exception e) {}
			      		   }
			      		   break;	
			              
			      case 2:                            
		           		  length=a.nextInt(59)+13;                     //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
		           		  for(int i=0;i<length;i++)
		           		  {
		           			  if(y<480)y+=speed; 
		           			  else break;
		           			  try {Thread.sleep(50);} 				      //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
		           			  catch (Exception e) {}
		           		  }
		           		  break;
		           		  
			      case 3:                           
		           	      length=a.nextInt(59)+13;                     //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
		           	      for(int i=0;i<length;i++)
		           	      {
		           	    	  if(x<470)x+=speed; 
		           	    	  else break;
		           	    	  try {Thread.sleep(50);} 				      //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
		           	    	  catch (Exception e) {}
		           	      }
		           	      break;				 
			    }
	 
			 if(this.life==false)    break;      //如果坦克被子弹击中,那么就退出循环 
			 Vector<Zidan> dzd=new Vector<Zidan>();
			 //坦克发子弹的代码
			 time++;
			 if(time%2==0)
			 {    if(life)
			     {
				     if(dzd.size()<5)
				     {  Zidan zd=null;
				    	switch(fangxiang)
				    	{
				    	 case 0: zd=new Zidan(x+10,y,0);
				    	 		 dzd.add(zd);
				    	 		 break;
				    	 		 
				    	 case 1: zd=new Zidan(x+10,y,1);
				    	  	     dzd.add(zd);
				    	  	     break;
		    	 		 
				    	 case 2: zd=new Zidan(x+10,y,2);
		    	 		 		 dzd.add(zd);
		    	 		 		 break;
		    	 		 
				    	 case 3: zd=new Zidan(x+10,y,3);
		    	 		 		 dzd.add(zd);
		    	 		 		 break;
				    	}
				    	
				    	Thread t5=new Thread(zd);
				    	t5.start();	    	
   			      }
			     }
				  
			 }
		 }
		 
		 
	 }
 
 }
 
 class Zidan implements Runnable
 { int x,y;
   int fangxiang;
   int speed=9;
   boolean life=true;

   public Zidan(int x,int y,int fangxiang)
   {this.x=x;
    this.y=y;
    this.fangxiang=fangxiang;
   }
   
   public void run()
   {
	   while(true)                 //线程下面有死循环都要有休眠时间
	   { 
		    try {Thread.sleep(50);} 				
			catch (Exception e) {}
			
			switch(fangxiang)
			{ 	case 0: y-=speed;break;
		    	case 1: x-=speed;break;
		    	case 2: y+=speed;break;			
		    	case 3: x+=speed;break;
			}
		
			if(x<0||x>500||y<0||y>500)  //子弹出了游戏边界就自动就将生命值设为false
			{this.life=false;  break;}
		
	   }
   }
 
 }

[源代码打包下载]




分享到:
更多

网友评论    (发表评论)

共8 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。