Java的一个飞机游戏项目的编程记录

第一步:绘制图形窗口
创建MyGameFrame类
1)建立游戏框架

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;

public class MyGameFrame extends JFrame{
        
  /**
   * 初始化窗口
   */
   public void launchFrame() {
	   this.setTitle("飞机大战—程序猿阿康作品");
	   this.setVisible(true);
	   this.setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);
	   this.setLocation(300, 300);
	   
	   this.addWindowListener(new WindowAdapter() {
	        @Override
	        public void windowClosing(WindowEvent e) {
	        	System.exit(0);
	        }
	   });
	   
   }

   public static void main(String[] args) {
	   MyGameFrame gf=new MyGameFrame();
	   gf.launchFrame();
   }

}

2)创建了Constant类

public class Constant {
       static final int GAME_WIDTH=480;
       static final int GAME_HEIGHT=500;
       
}

二、重写paint方法

1)重写paint

  //重写paint方法,绘制图形
  @Override
  public void paint(Graphics g) {
	   
  }	

2)加载图片类GameUtil

/**
 * 加载指定路径下的图片对象
 */

	import java.awt.Image;
	import java.awt.image.BufferedImage;
	import java.io.IOException;
	import java.net.URL;
	
	import javax.imageio.ImageIO;
	
	
	public class GameUtil {
	     
	 private  GameUtil(){
		 
	 }
	 
	 public static Image getImage(String path) {
		 BufferedImage bi=null;

	 try {
		 URL u=GameUtil.class.getClassLoader().getResource(path);
		 bi=ImageIO.read(u);
	 } catch (IOException e) {
		 e.printStackTrace();
	 }
	 return bi;
		 
	 }
	 
	}

3)创建GameObject父类

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;

public class GameObject {
     double x,y;
     int width,height;
     Image img;
     
 public void drawSelf(Graphics g) {
	 g.drawImage(img, (int)x, (int)y, null);
 }

public GameObject(double x, double y, int width, int height, Image img) {
	super();
	this.x = x;
	this.y = y;
	this.width = width;
	this.height = height;
	this.img = img;
 }

public GameObject(double x, double y, Image img) {
	super();
	this.x = x;
	this.y = y;
	this.img = img;
 }
 
 public GameObject() {
 }
 //矩阵检测,用于后续物体碰撞检测
 public  Rectangle getRect() {
	 return new Rectangle ((int)x,(int)y,width,height);
 }

}

4)加载飞机与背景图片

 Image planeImg=GameUtil.getImage("images/life.png");
	 Image bg=GameUtil.getImage("images/background.png");
	 
 Plane plane=new Plane(planeImg,250,250);
 

  //重写paint方法,绘制图形
  @Override
  public void paint(Graphics g) {
	  
	  g.drawImage(bg, 0, 0, null);
	  
	  plane.drawSelf(g); 
  }	

三、重画图形线程paintThread
1)增加重画窗口线程

        class paintThread extends Thread{
    	  @Override
    	  public void run() {
    		  while(true) {
    			  repaint();
    	    		try {
    					Thread.sleep(40);
    				} catch (InterruptedException e) {
					
					e.printStackTrace();
				}
		  }
	  }
  }

2)启动重画窗口线程

   new paintThread().start();

3)帮助飞机移动

	 public void drawSelf(Graphics g) {
	    	 g.drawImage(img,(int)x,(int)y,null);
	    	 x++;
	     }

四、增加键盘监听及键盘控制原理
1)添加键盘监听

 class  keyMonitor extends KeyAdapter{
	       @Override
	    public void keyPressed(KeyEvent e) {
	    	
	    }
	       @Override
	    public void keyReleased(KeyEvent e) {
	      
	    }
  }

2)添加飞机的键盘响应

 public class Plane extends GameObject{
 
 int speed=3;
 
 boolean left,right,up,down;
 
 public Plane (Image img,double x,double y) {
	 this.img=img;
	 this.x=x;
	 this.y=y;
 }
 
 //键盘响应
 public void drawSelf(Graphics g) {
	 g.drawImage(img,(int)x,(int)y,null);
	 if(left) {
		  x -=speed;
	 }
	 if(right) {
	      x +=speed;
     }
	 if(up) {
	      y -=speed;
     }
	 if(down) {
  		  y +=speed;
  	  }
 }
 
 
 
 public void addDirection(KeyEvent e) {
	 switch(e.getKeyCode()) {
       case KeyEvent.VK_LEFT:
    	   left=true;
    	   break;
       case KeyEvent.VK_RIGHT:
    	   right=true;
    	   break;
       case KeyEvent.VK_UP:
    	   up=true;
    	   break;
       case KeyEvent.VK_DOWN:
    	   down=true;
    	   break;
	 }
 }
 
 public void minusDirection(KeyEvent e) {
	 switch(e.getKeyCode()) {
       case KeyEvent.VK_LEFT:
    	   left=false;
    	   break;
       case KeyEvent.VK_RIGHT:
    	   right=false;
    	   break;
       case KeyEvent.VK_UP:
    	   up=false;
    	   break;
       case KeyEvent.VK_DOWN:
    	   down=false;
    	   break;
	 }
 }

}
3)初始化键盘监听线程

    new paintThread().start();
	addKeyListener(new keyMonitor());

五、炮弹类Shell
1)创建炮弹类

import java.awt.Color;
import java.awt.Graphics;

public class Shell extends GameObject{
	 int speed;
	 double degree;

 Shell(){
	 x=200;
	 y=200;
	 speed=4;
	 width=10;
	 height=10;
	 
	 degree=Math.random()*Math.PI*2;
 }
 
 @Override
public void drawSelf(Graphics g) {
	 Color c=g.getColor();
	 g.setColor(Color.YELLOW);
	 g.fillOval((int)x, (int)y, width, height);
	 
	 //炮弹沿任意角度飞行
	 x +=speed*Math.cos(degree);
	 y +=speed*Math.sin(degree);
	 
	 //边沿检测
	 if(x<width||x>Constant.GAME_WIDTH-width) {
		 degree=Math.PI-degree;
	 }
	 if(y<35||y>Constant.GAME_HEIGHT-height) {
		 degree=-degree;
	 }
	 
	 g.setColor(c);
	 
} 
    
}

2)创建炮弹对象、初始化炮弹数组并绘制炮弹

       Shell[] shells=new Shell[20];   
      
              //初始化
	           for(int i=0;i<shells.length;i++) {
				   shells[i]=new Shell();
			   }
			   //绘制炮弹
	    for(int i=0;i<shells.length;i++) {
		  shells[i].drawSelf(g);
	  }

六、飞机与炮弹的碰撞检测
1)碰撞检测

        boolean peng=shells[i].getRect().intersects(plane.getRect());
         //获取飞机的形状尺寸
         public Plane (Image img,double x,double y) {
	    	 this.img=img;
	    	 this.x=x;
	    	 this.y=y;
	    	 this.width=img.getWidth(null);
	    	 this.height=img.getHeight(null);
       }

2)飞机死亡

	  public void drawSelf(Graphics g) {
	    	 if (live) {
		    	 g.drawImage(img,(int)x,(int)y,null);
		    	 if(left) {
		    		  x -=speed;
		    	 }
		    	 if(right) {
		   		      x +=speed;
		   	     }
		    	 if(up) {
		   		      y -=speed;
		   	     }
		    	 if(down) {
		      		  y +=speed;
		      	  }
		    	 
	    	 }
	     }
        //发生碰撞。则飞机坠毁
	    if(peng) {
	    			  plane.live=false;
	    		  }

七、添加爆炸效果
1)创建爆炸类

import java.awt.Graphics;
import java.awt.Image;

public class Explode {
       double x,y;
       static Image[] imgs=new Image[16];
       static {
    	   for(int i=0;i<imgs.length;i++) {
    		     imgs[i]=GameUtil.getImage("images/explode/e"+(i+1)+".gif");
    		     imgs[i].getWidth(null);
    	   }
    	   
       }
   
	int count ;
	
	public void draw(Graphics g) {
		if(count<=15) {
			g.drawImage(imgs[count], (int)x, (int)y, null);
			count++;
		}
	}
	   
	public Explode(double x,double y) {   
		this.x=x;
		this.y=y;
	}
  
}

2)创建爆炸类对象

  Explode bao;
   //绘制爆炸效果      
   if(peng) {
			  plane.live=false;
			  
			  if(bao==null) {
				  bao=new Explode(plane.x,plane.y);
			  }
			  
			  bao.draw(g);
		  }

八、添加计时功能
1)创建时间类对象

 Date startTime=new Date();
 Date endTime;
 int period;

2)实例化对象

 endTime=new Date();
 period=(int)((endTime.getTime()-startTime.getTime())/1000);

3)时间显示

		  if(!plane.live) {
			  Color c=g.getColor();
			  g.setColor(Color.RED);
			  Font f=new Font("宋体",Font.BOLD,35);
			  g.setFont(f);
			  g.drawString("时间:"+period+"秒",(int)plane.x,(int)plane.y);
    		  g.setColor(c);
		  }

九、主程序代码

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;

import javax.swing.JFrame;

public class MyGameFrame extends JFrame{
  
 Image planeImg=GameUtil.getImage("images/life.png");
 Image bg=GameUtil.getImage("images/background.png");
 
 Plane plane=new Plane(planeImg,250,250);
 
 Shell[] shells=new Shell[10];
 
 Explode bao;
 
 Date startTime=new Date();
 Date endTime;
 int period;

  //重写paint方法,绘制图形
  @Override
  public void paint(Graphics g) {
	  
	  g.drawImage(bg, 0, 0, null);
	  
	  plane.drawSelf(g);
	  
	  for(int i=0;i<shells.length;i++) {
		  shells[i].drawSelf(g);
		  
		  boolean peng=shells[i].getRect().intersects(plane.getRect());
		  if(peng) {
			  plane.live=false;
		
			  if(bao==null) {
				  bao=new Explode(plane.x,plane.y);
				  
				  endTime=new Date();
    			  period=(int)((endTime.getTime()-startTime.getTime())/1000);
			  }
		
			  bao.draw(g);
		  }
		  
		  if(!plane.live) {
			  Color c=g.getColor();
			  g.setColor(Color.RED);
			  Font f=new Font("宋体",Font.BOLD,35);
			  g.setFont(f);
			  g.drawString("时间:"+period+"秒",(int)plane.x,(int)plane.y);
    		  g.setColor(c);
		  }
		  
		  
	  }
  }	

  class paintThread extends Thread{
	  @Override
	  public void run() {
		  while(true) {
			  repaint();
	    		try {
					Thread.sleep(40);
				} catch (InterruptedException e) {
					
					e.printStackTrace();
				}
		  }
	  }
  }

  class  keyMonitor extends KeyAdapter{
	       @Override
	    public void keyPressed(KeyEvent e) {
	    	plane.addDirection(e);
	    }
	       @Override
	    public void keyReleased(KeyEvent e) {
	        plane.minusDirection(e);
	    }
  }
  
  

  /**
   * 初始化窗口
   */
   public void launchFrame() {
	   this.setTitle("飞机大战—程序猿阿康作品");
	   this.setVisible(true);
	   this.setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);
	   this.setLocation(300, 300);
	   
	   this.addWindowListener(new WindowAdapter() {
	        @Override
	        public void windowClosing(WindowEvent e) {
	        	System.exit(0);
	        }
	   });
	   
	   new paintThread().start();
	   addKeyListener(new keyMonitor());
	   
	   for(int i=0;i<shells.length;i++) {
		   shells[i]=new Shell();
	   }
	   
   }
   
   public static void main(String[] args) {
	   MyGameFrame gf=new MyGameFrame();
	   gf.launchFrame();
   }
   
   
}

代码参考了https://www.bilibili.com/video/av43896218?from=search&seid=18142291238569744969

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值