Java飛機大戰小遊戲(三):天花亂墜,敵機降臨

  • 項目:飛機大戰小遊戲之繪製敵方飛機的隨機降臨
  • 項目簡介:飛機大戰小遊戲的角色,特徵+行爲
  • 開發工具:eclipse
  • 語言:Java
  • 知識點:Random、模塊化、監聽器、定時器

代碼架構:程序分兩個包,共四個類
在這裏插入圖片描述

操作效果圖:
在這裏插入圖片描述

ImageUtil.java:遊戲加載圖片的工具類

SmallPlane.java:敵方飛機

package com.demo.model;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.demo.util.ImageUtil;

/**
 * 小敵機
 */
public class SmallPlane {

	private BufferedImage image = ImageUtil.readImage("smallplane0.png");
	private int x; // 飛機放置在面板上的x軸
	private int y; // 飛機放置在面板上的y軸

	// 定義構造函數
	public SmallPlane() {
		this.x = new Random().nextInt(GameStart.WIDTH - image.getWidth());
		this.y = -image.getHeight();
	}

	/**
	 * 行爲
	 */
	// 移動
	public void movePlane() {
		this.y += 3;
	}

	// 子彈的移動
	public void moveBullet() {
		this.y += 3;
	}

	// 開火的方法
	public List<EnemyBullet> fire() {
		List<EnemyBullet> list = new ArrayList<EnemyBullet>();
		list.add(new EnemyBullet(this.x + image.getWidth() / 2, this.y + image.getHeight() / 2));
		return list;
	}
	
	//是否越界
	public boolean isOutOfBound() {
		return  this.y > GameStart.HEIGHT + image.getHeight();
	}
	
	//getters/setters方法

}

小型敵機與大型敵機和轟炸機的區別其實就是圖片和開火的子彈條數,故更換一下圖片修改一下開火的方法即可

// 小型敵機的開火方法
public List<EnemyBullet> fire() {
	List<EnemyBullet> list = new ArrayList<EnemyBullet>();
	list.add(new EnemyBullet(this.x + image.getWidth() / 2, this.y + image.getHeight() / 2));
	return list;
}

// 大型敵機的開火方法
public List<EnemyBullet> fire() {
	List<EnemyBullet> list = new ArrayList<EnemyBullet>();
	list.add(new EnemyBullet(this.getX()+image.getWidth()/3-8,this.getY()+image.getHeight()/2));	//敵機子彈的位置偏移
	list.add(new EnemyBullet(this.getX()+image.getWidth()*2/3,this.getY()+image.getHeight()/2));	
	return list;
}

// 轟炸機的開火方法
public List<EnemyBullet> fire() {
	List<EnemyBullet> list = new ArrayList<>();
	list.add(new EnemyBullet(this.getX()+image.getWidth()/6,this.getY()+image.getHeight()/2));	//敵機子彈的位置偏移
	list.add(new EnemyBullet(this.getX()+image.getWidth()*2/6,this.getY()+image.getHeight()/2));
	list.add(new EnemyBullet(this.getX()+image.getWidth()*3/6,this.getY()+image.getHeight()/2));
	list.add(new EnemyBullet(this.getX()+image.getWidth()*4/6,this.getY()+image.getHeight()/2));
	list.add(new EnemyBullet(this.getX()+image.getWidth()*5/6,this.getY()+image.getHeight()/2));
	return list;
}

EnemyBullet.java:敵方飛機子彈

package com.demo.model;

import java.awt.image.BufferedImage;

import com.demo.util.ImageUtil;

/**
 * 敵機子彈
 */
public class EnemyBullet {
	/**
	 * 特徵
	 */
	private BufferedImage image = ImageUtil.readImage("enemybullet0.png");
	private int x; // 在畫布的x軸
	private int y; // 在畫布的y軸

	public EnemyBullet(int x, int y) {
		this.x = x;
		this.y = y;
	}

	/**
	 * 行爲
	 */
	// 子彈的移動
	public void move() {
		this.y += 3;
	}
	//判斷是否越界
	public boolean isOutOfBound() {
		return  this.y > GameStart.HEIGHT + image.getHeight();
	}

	//getters/setters方法

}

GameStart.java:主程序

package com.demo.model;

import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

import com.demo.util.ImageUtil;

/**
 * 飛機大戰小遊戲(三):敵方飛機騷起來
 * @author suoyue_zhan
 */
public class GameStart extends JPanel {
	public static final int WIDTH = 400;		//遊戲界面寬度
	public static final int HEIGHT = 654; 		//遊戲界面長度

	
	private BufferedImage background1 = ImageUtil.readImage("background.jpg");		// 背景圖片:靜態
	
	//敵機的集合
	private List<SmallPlane> enemyPlanes = new ArrayList<>();
	//敵機登場
	private void enemyPlaneEnter() {
		enemyPlanes.add(new SmallPlane());
	}
	//繪製敵機
	private void paintEnemyPhane(Graphics g) {
		for (int i = 0; i < enemyPlanes.size(); i++) {
			SmallPlane enemyPlane = enemyPlanes.get(i);
			BufferedImage image = enemyPlane.getImage();
			if(image != null && !enemyPlane.isOutOfBound()) {
				g.drawImage(image, enemyPlane.getX(), enemyPlane.getY(), null);
			}
		}
	}
	//小敵機移動
	public void enemyPlaneMove() {
		for (SmallPlane enemyPlane : enemyPlanes) {
				enemyPlane.movePlane();

		}
	}

	private List<EnemyBullet> enemyBullets = new ArrayList<EnemyBullet>(); //敵機子彈集合
	//敵機發送子彈
	private void enemyPlaneFire() {
		for (int i = 0; i < enemyPlanes.size(); i++) {
			SmallPlane enemyPlane = enemyPlanes.get(i);
			List<EnemyBullet> list = enemyPlane.fire();
			enemyBullets.addAll(list);
		}
	}
	//繪製敵機子彈:當子彈出界後,不要繪製出來
	private void paintEnemyBullet(Graphics g) {
		for(int i = 0; i < enemyBullets.size(); i++) {
			EnemyBullet enemyBullet = enemyBullets.get(i);
			BufferedImage image = enemyBullet.getImage();
			if(image != null && !enemyBullet.isOutOfBound()) {
				g.drawImage(image, enemyBullet.getX(), enemyBullet.getY(), null);
			}
		}
	}

	//敵機子彈移動
	private void enemyBulletMove() {
		for (EnemyBullet enemyBullet : enemyBullets) {
			enemyBullet.move();
		}
	}
		
	// 重寫JPanel的繪製方法-->>所有圖片都在該方法上執行
	@Override
	public void paint(Graphics g) {
		g.drawImage(background1, 0, 0, null);	//繪製背景圖		
		this.paintEnemyPhane(g);				//繪製敵機
		this.paintEnemyBullet(g);				//繪製敵機子彈
	}
	
	/**
	 * 窗口初始化
	 */
	public void init() {
		JFrame jFrame = new JFrame("飛機大戰"); // 設置窗口標題

		jFrame.add(this); // this表示主類,也表示畫板

		jFrame.setSize(WIDTH, HEIGHT); // 設置窗口大小
		jFrame.setLocationRelativeTo(null); // 設置窗口居中
		jFrame.setAlwaysOnTop(true); // 設置窗口總是在頂端
		jFrame.setResizable(false); // 設置不允許拖拉
		jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 關閉窗口時退出程序
		jFrame.setIconImage(new ImageIcon("./images/icon.png").getImage()); // 設置圖標
		jFrame.setVisible(true); // 使窗口顯示出來
				
		initListener();		//安裝程序監聽器	
		initTimer();		//設置定時器,用於實現遊戲中所有的動態邏輯效果
	}
	
	/**
	 * 監控鼠標的監聽器
	 */
	private void initListener() {
		//使用鼠標監聽器的適配器
		MouseAdapter adapter = new MouseAdapter() {
			@Override
			public void mouseMoved(MouseEvent e) {
				//獲取鼠標的x座標與y座標
				System.out.println("x: " + e.getX() + "y: " + e.getY());

			}
		};		
		//添加鼠標監聽器
		this.addMouseListener(adapter);
		this.addMouseMotionListener(adapter);		
	
	}
	
	/**
	 * 定時器
	 */
	private long count = 0;	//控制頻率
	public void initTimer(){
		
		Timer timer = new Timer();		//定時器對象
		long delay = 10; 
		long period = 10;
		//定時執行操作
		//參數1:每隔一段時間執行的操作
		//參數2:幾毫米之後執行定時器
		//參數3:每個幾毫米執行一次
		timer.schedule(new TimerTask() {
			@Override
			public void run() {		
			
				//敵機登場
				if(count % 50 == 0) {
					enemyPlaneEnter();
				}			
				//敵機移動
				if(count % 2 == 0) {
					enemyPlaneMove();
				}
				//敵機發送子彈
				if(count % 50 == 0) {
					enemyPlaneFire();
				}
				//敵機子彈的移動
				enemyBulletMove();
				
				if(count == Long.MAX_VALUE-1){
					count = 0;
				}
				count++;		
			
				repaint(); //重新繪製頁面
			}
		}, delay,period);
	}

	/*
	 * 程序入口main()
	 */
	public static void main(String[] args) {
		System.out.println("遊戲開始了.....");

		GameStart gameStart = new GameStart();
		gameStart.init(); //顯示主界面
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章