Java小遊戲——飛機大戰

北渺發表於2021-01-05

1. 常量類

public class Constant {
    public static final int WINDOW_WIDTH = 700;
    public static final int WINDOW_HEIGHT = 700;
}

2.工具類

public class GameUtil {
   //工具最好將構造器私有化
   private GameUtil(){

   }

   //返回指定路徑檔案的圖片物件
   public static Image getImage(String path){
       BufferedImage bufferedImage = null;
       try {
           URL url = GameUtil.class.getClassLoader().getResource(path);
           bufferedImage = ImageIO.read(url);
       }catch (IOException e){
           e.printStackTrace();
       }
       return bufferedImage;
   }
}

3.遊戲物件父類

public class GameObject {
   private Image image;
   private double x,y;
   private int speed;
   private int width,height;

   public void drawSelf(Graphics graphics){
       graphics.drawImage(image,(int)x,(int)y,null);
   }

   public GameObject() {
   }

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

   //返回物體所在的矩形,便於後續的碰撞檢測
   public Rectangle getRect(){
      return new Rectangle((int)x,(int)y,width,height);
   }

   public Image getImage() {
       return image;
   }

   public void setImage(Image image) {
       this.image = image;
   }

   public double getX() {
       return x;
   }

   public void setX(double x) {
       this.x = x;
   }

   public double getY() {
       return y;
   }

   public void setY(double y) {
       this.y = y;
   }

   public int getSpeed() {
       return speed;
   }

   public void setSpeed(int speed) {
       this.speed = speed;
   }

   public int getWidth() {
       return width;
   }

   public void setWidth(int width) {
       this.width = width;
   }

   public int getHeight() {
       return height;
   }

   public void setHeight(int height) {
       this.height = height;
   }

}

4.飛機類

public class Plane extends GameObject {
   boolean left;
   boolean right;
   boolean up;
   boolean down;

   //飛機狀態
   boolean live = true;

   public Plane(Image airplane, double x, double y, int width, int height,int speed) {
       this.setImage(airplane);
       this.setX(x);
       this.setY(y);
       this.setWidth(width);
       this.setHeight(height);
       setSpeed(speed);
   }

   @Override
   public void drawSelf(Graphics graphics){
       if(live){
           graphics.drawImage(this.getImage(),(int)this.getX(),(int)this.getY(),null);


           if(left){
               setX(getX() - getSpeed());
           }
           if(up){
               setY(getY() - getSpeed());
           }
           if(right){
               setX(getX() + getSpeed());
           }
           if(down){
               setY(getY() + getSpeed());
           }
       }

   }


   //按下某鍵 增加相應的方向
   public void addDirection(KeyEvent keyEvent){
       switch (keyEvent.getKeyCode()){
           case KeyEvent.VK_LEFT:
               left = true;
               break;
           case KeyEvent.VK_UP:
               up = true;
               break;
           case KeyEvent.VK_RIGHT:
               right = true;
               break;
           case KeyEvent.VK_DOWN:
               down = true;
               break;
       }
   }

   //抬起某鍵 減少相應的方向
   public void minusDirection(KeyEvent keyEvent){
       switch (keyEvent.getKeyCode()){
           case KeyEvent.VK_LEFT:
               left = false;
               break;
           case KeyEvent.VK_UP:
               up = false;
               break;
           case KeyEvent.VK_RIGHT:
               right = false;
               break;
           case KeyEvent.VK_DOWN:
               down = false;
               break;
       }
   }
}

5.炸彈類

public class Shell extends GameObject{

   double degree;

   public Shell(){
       setX(200);
       setY(200);
       setWidth(20);
       setHeight(20);
       setSpeed(5);
       degree = Math.random()*Math.PI*2;
   }

   public void draw(Graphics graphics){
       //儲存原來畫筆顏色
       Color color = graphics.getColor();
       //畫出炮彈
       graphics.setColor(Color.YELLOW);
       graphics.fillOval((int)getX(),(int)getY(),getWidth(),getHeight());
       //計算炮彈下個位置
       setX((int) (getX() + getSpeed()*Math.cos(degree)));
       setY((int) (getY() + getSpeed()*Math.sin(degree)));

       //碰到邊界反彈
       if(getX()<0 || getX()>Constant.WINDOW_WIDTH-getWidth()){
           degree = Math.PI - degree;
       }
       if(getY()<0 || getY()>Constant.WINDOW_HEIGHT-getHeight()){
           degree = - degree;
       }

       graphics.setColor(color);
   }
}

6.主類

public class MyGameFrame extends JFrame {

   Image background = GameUtil.getImage("com/shangxuetang/airplanegame/1111.jpg");
   Image airplane = GameUtil.getImage("com/shangxuetang/airplanegame/airplane.jpg");

   Plane plane = new Plane(airplane,500,500,25,25,10);
   Shell shell = new Shell();
   Shell[] shells = new Shell[50];

   Date startTime = new Date();
   Date endTime;
   int liveTime;
   boolean flag = true;


   //在介面上操作  函式自動呼叫
   @Override
   public void paint(Graphics g){//g相當於一支畫筆

       g.drawImage(background,0,0,null);
       //畫飛機
       plane.drawSelf(g);
       //畫炮彈
       for (int i = 0; i < shells.length; i++) {
           shells[i].draw(g);
           //判斷是否發生碰撞
           if(shells[i].getRect().intersects(plane.getRect())){
               //讓飛機死掉
               plane.live = false;
               if(flag){
                   endTime = new Date();
                   liveTime =(int)((endTime.getTime() - startTime.getTime())/1000);
               }
               flag = false;


           }
       }
       if(!plane.live){
           //飛機死亡
           g.setColor(Color.white);
           Font font = new Font("宋體",Font.PLAIN,100);
           g.setFont(font);
           g.drawString("遊戲時長:"+liveTime,100,350);
       }
   }

   //執行緒
   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);
           System.out.println(e.getKeyCode());
       }

       @Override
       public void keyReleased(KeyEvent e) {
           plane.minusDirection(e);
           System.out.println(e.getKeyCode());
       }
   }

   //初始化
   public void launchFrame(){
       //設定標題
       this.setTitle("作者: 北渺");
       //建立介面
       this.setVisible(true);
       //設定介面大小
       this.setSize(Constant.WINDOW_WIDTH,Constant.WINDOW_HEIGHT);
       //設定介面位置
       this.setLocation(180,180);
       //啟動重畫視窗的執行緒
       new PaintThread().start();
       //給視窗增加鍵盤的監聽
       addKeyListener(new KeyMonitor());
       //初始化炮彈
       for (int i = 0; i < shells.length; i++) {
           shells[i] = new Shell();
       }
       //退出介面
       this.addWindowFocusListener(new WindowAdapter() {
           @Override
           public void windowClosed(WindowEvent event){
               System.exit(0);
           }
       });
   }

}

7.測試類

public class Test {

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

}

相關文章