- 項目:飛機大戰小遊戲之繪製我方飛機的騷操作
- 項目簡介:飛機大戰小遊戲的主角,採用兩張圖片交替顯示來達到動態效果,鍵盤事件更改飛機火力(監聽器)
- 開發工具:eclipse
- 語言:Java
- 知識點:模塊化、監聽器、定時器
代碼架構:程序分兩個包,共四個類
操作效果圖:
ImageUtil.java:遊戲加載圖片的工具類
HeroPlane.java:我方飛機
package com.demo.model;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import com.demo.util.ImageUtil;
/**
* 英雄飛機
*/
public class HeroPlane {
/**
* 飛機的特徵
*/
//用數組定義多張圖片
private static BufferedImage[] images;
//靜態塊
static{
images = new BufferedImage[2];
for(int i=0;i<images.length;i++){
images[i] = ImageUtil.readImage("heroplane"+i+".png");
}
}
//生命:默認10條
private int life = 10;
//分數:默認0分
private int score = 0;
//飛機所在的位置x/y軸
private int x;
private int y;
/**
* 行爲特徵
*/
//移動
public void move(int x,int y){
this.x = x;
this.y = y;
}
//射擊
public List<HeroBullet> fire() {
List<HeroBullet> list = new ArrayList<HeroBullet>();
list.add(new HeroBullet(this.x, this.y)); //發射一枚子彈
return list;
}
private boolean flag = true;
//獲取飛機圖標
public BufferedImage getImage() {
flag = !flag;
return images[flag?0:1];
}
//getters/setters方法
//...
public int getScore() {
return ++score; //移動加分
}
public void setScore(int score) {
this.score = score;
}
}
HeroBullet.java:我方飛機子彈
package com.demo.model;
import java.awt.image.BufferedImage;
import com.demo.util.ImageUtil;
public class HeroBullet{
protected int x; //畫布的x軸
protected int y; //畫布的y軸
//子彈圖片
private static BufferedImage image = ImageUtil.readImage("herobullet0.png");
//構造函數
public HeroBullet(int x,int y){
this.x = x;
this.y = y;
}
//行爲-> 移動
public void move(){
this.y -= 3;
}
//出界
public boolean isOutOfBound(){
return this.y<0;
}
public static BufferedImage getImage() {
return image;
}
public static void setImage(BufferedImage image) {
HeroBullet.image = image;
}
//...x/y的 getters/setters方法
}
GameStart.java:主程序
package com.demo.model;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
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 HeroPlane heroPlane = new HeroPlane(); //英雄機
//英雄飛機子彈對象->list集合
private List<HeroBullet> heroBullets = new ArrayList<HeroBullet>();
//將背景繪製到面板中
private void paintHeroPlane(Graphics g) {
BufferedImage image = heroPlane.getImage();
if(heroPlane.getX() == 0) { //飛機剛出來時候
g.drawImage(image,WIDTH/2-image.getWidth()/2, HEIGHT/2+image.getHeight(), null);
}else {
g.drawImage(image,heroPlane.getX()-image.getWidth()/2, heroPlane.getY() - image.getHeight()/2, null);
}
}
//繪製飛機的分數與生命
private void paintScoreAndLife(Graphics g) {
g.setColor(new Color(255, 0, 0)); //設置畫筆顏色 紅0 綠0 藍0 (0~255)
g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 20)); //設置字體 字體、樣式、字號
g.drawString("score: "+heroPlane.getScore(), 10, 25);
g.drawString("life: "+heroPlane.getLife(), 10, 45);
}
//默認一條火力線
private boolean flag1 = true;
//兩條火力線
private boolean flag2 = false;
//三條火力線
private boolean flag3 = false;
//控制子彈移動速度的標記
private boolean flagMax = false;
//繪製飛機子彈
public void paintHeroBullet(Graphics g){
for(int i=0;i<heroBullets.size();i++){
//每個英雄的子彈
HeroBullet heroBullet = heroBullets.get(i);
BufferedImage image = heroBullet.getImage();
BufferedImage hImage = heroPlane.getImage();
if(image != null && !heroBullet.isOutOfBound()) {
if(flag1) {
g.drawImage(image, heroBullet.getX(), heroBullet.getY(), null);
}
if(flag2) {
g.drawImage(image, heroBullet.getX()-hImage.getWidth()/3, heroBullet.getY(), null);
g.drawImage(image, heroBullet.getX()+hImage.getWidth()/3, heroBullet.getY(), null);
}
if(flag3) {
g.drawImage(image, heroBullet.getX()-hImage.getWidth()/3, heroBullet.getY(), null); //左邊
g.drawImage(image, heroBullet.getX(), heroBullet.getY(), null); //中間
g.drawImage(image, heroBullet.getX()+hImage.getWidth()/3, heroBullet.getY(), null); //右邊
}
}
}
}
// 重寫JPanel的繪製方法-->>所有圖片都在該方法上執行
@Override
public void paint(Graphics g) {
//繪製背景圖
g.drawImage(background1, 0, 0, null);
//調用方法,繪製飛機
this.paintHeroPlane(g);
//調用方法繪製飛機子彈
this.paintHeroBullet(g);
//繪製飛機的分數與生命
this.paintScoreAndLife(g);
}
/**
*********遊戲邏輯方法--------------
*/
//英雄飛機發射子彈
private void heroPlaneFire(){
List<HeroBullet> list = heroPlane.fire();
//收集子彈,動態繪製
heroBullets.addAll(list);
}
//英雄子彈移動
private void heroBulletMove() {
for (HeroBullet heroBullet : heroBullets) {
heroBullet.move();
}
}
/**
* 窗口初始化
*/
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());
//飛機跟隨鼠標移動
heroPlane.move(e.getX(), e.getY());
repaint(); //重新繪製飛機, 底層是重寫執行paint方法
}
};
//添加鼠標監聽器
this.addMouseListener(adapter);
this.addMouseMotionListener(adapter);
//設置鍵盤監聽事件
this.setFocusable(true);
//鍵盤的監控
KeyAdapter k = new KeyAdapter() {
//鍵盤按鍵按下時執行方法
@Override
public void keyPressed(KeyEvent e) {
//鍵盤的按鍵編碼
int keyCode = e.getKeyCode();
//鍵盤按鍵編碼對應的文字
String text = KeyEvent.getKeyText(keyCode);
if("1".equals(text)) {
flag1 = true;
flag2 = false;
flag3 = false;
}
if("2".equals(text)) {
flag1 = false;
flag2 = true;
flag3 = false;
}
if("3".equals(text)) {
flag1 = false;
flag2 = false;
flag3 = true;
}
if("M".equals(text)) {
flagMax = !flagMax; //M鍵快掛
}
}
};
this.addKeyListener(k);
}
/**
* 定時器
*/
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 % 10 == 0 || flagMax){
heroPlaneFire();
}
//英雄子彈移動
//if(count % 2 == 0){
heroBulletMove();
//}
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(); //顯示主界面
}
}