此項目主要使用到了Graphics 繪圖類,要想實作此Demo需要熟練掌握此類,以及它的對象是如何建立的,此項目凡是可以飛行的都可以寫一個頂級父類,其子類用來繼承,我在項目後期才發現可是項目已經實作了很多要想修改需要時間由于我們項目時間很短,是以并沒有來得及修改,如果有同學願意修改,可以嘗試一下,聯系一下繼承和接口嘛,謝謝!
package com.view;
import javax.swing.JFrame;
import com.listener.FrameMouseMotionListener;
import com.model.Enemy001;
import com.model.Enemy002;
//設定架構
public class MyFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public static int frameWidth=450;//要用類調用
public static int frameHeight=700;
//關聯,需要把面闆添加到架構中
public MyPanel panel;
//存放滑鼠移動監聽器
public FrameMouseMotionListener frameMouseMotionListener;
public MyFrame() {
//調用父類構造,設定視窗名稱
super("飛機大戰....");
//設定視窗的大小
setBounds(0, 0, frameWidth, frameHeight);
//設定視窗的位置,居中
setLocationRelativeTo(null);
//布局方式
setLayout(null);
//設定可見
setVisible(true);
//視窗大小不可調整
setResizable(false);
this.panel=new MyPanel();
//設定面闆的大小
this.panel.setBounds(0, 0, frameWidth, frameHeight);
//将面闆添加到架構中
this.add(this.panel);
//視窗關閉
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//調用監聽器封裝函數
setTouchListener();
//添加敵機的類型
addEnemyType(Enemy001.class);
addEnemyType(Enemy002.class);
}
//封裝監聽器函數
public void setTouchListener() {
this.frameMouseMotionListener=new FrameMouseMotionListener();
this.frameMouseMotionListener.MyFrame=this;
//注冊監聽器
this.addMouseMotionListener(this.frameMouseMotionListener);
}
public void addEnemyType(Class c) {
this.panel.enemyType.add(c);
}
}
package com.view;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import javax.swing.JPanel;
import com.Thread.DrawableThread;
import com.model.Bullet;
import com.model.Enemy;
import com.model.Player;
public class MyPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
public Image bgImage;
public DrawableThread drawableThread;
public Player player;
//存放所有子彈對象
public ArrayList<Bullet> bullets=new ArrayList<Bullet>();
//存放所有的敵機
public ArrayList<Enemy> enemys=new ArrayList<Enemy>();
//存放所有的敵機類型
@SuppressWarnings("rawtypes")
public ArrayList<Class> enemyType=new ArrayList<Class>();
private int top=0;
public int timer=0;//計時器
//加載背景圖檔到面闆上
public MyPanel() {
this.bgImage=Toolkit.getDefaultToolkit().getImage("photos/bgground.jpg");
//建立線程,重繪
this.drawableThread=new DrawableThread(this);
//啟動線程
this.drawableThread.start();
//建立玩家
this.player=new Player(this);
}
//繪制元件
public void paintComponent(Graphics g) {
super.paintComponent(g);
//重載,6個參數
g.drawImage(this.bgImage, 0,top-this.bgImage.getHeight(this),
this.bgImage.getWidth(this) ,this.bgImage.getHeight(this),null);
//兩幅圖,構成滾動特效
g.drawImage(this.bgImage, 0,top,this.bgImage.getWidth(this) ,this.bgImage.getHeight(this),null);
timer++;
if(timer==10000){
timer=0;
}
//實利用top,控制坐标,達到滾動的效果
if(timer%10==0) {//每繪制10次,向下移動
top++;
if(top>=this.bgImage.getHeight(this)) {
top=0;
}
}
//繪制玩家
this.player.drawSelf(g);
//繪制子彈
if(timer%100==0) {
//單倍火力值
if(this.player.attackMode==1){
//建立子彈對象
Bullet bullet=new Bullet(this);
//設定坐标
bullet.x=this.player.x+this.player.width/2-bullet.width;
bullet.y=this.player.y;
//存取子彈
this.bullets.add(bullet);
//雙倍火力值
}else if(this.player.attackMode==2){
//建立子彈對象
Bullet bullet1=new Bullet(this);
//設定坐标
bullet1.x=this.player.x+this.player.width/3-bullet1.width;
bullet1.y=this.player.y;
//存取子彈
this.bullets.add(bullet1);
//建立子彈對象
Bullet bullet2=new Bullet(this);
//設定坐标
bullet2.x=this.player.x+this.player.width*2/3-bullet2.width;
bullet2.y=this.player.y;
//存取子彈
this.bullets.add(bullet2);
}
}
//畫出所有的子彈
for(int i=0;i<bullets.size();i++) {
this.bullets.get(i).drawSelf(g);
}
//建立敵機
if(this.timer%300==0){
if(this.enemyType.size()>0) {
//随機一種類型對象的下标
int index=(int)(Math.random()*this.enemyType.size());
//通過反射建立對象
Enemy enemy=null;
try {
enemy=(Enemy)(this.enemyType.get(index).getConstructors()[0].newInstance(new Object[] {this}));
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | SecurityException e) {
e.printStackTrace();
}
this.enemys.add(enemy);
}
}
//将所有的敵機畫出來
for(int i=0;i<this.enemys.size();i++) {
this.enemys.get(i).drawSelf(g);
}
//畫分數
g.setColor(Color.GRAY);
g.setFont(new Font("楷體",Font.PLAIN,30));
g.drawString("分數:"+this.player.count+"",10, 50);
//畫玩家生命值
g.setColor(Color.red);
g.setFont(new Font("楷體",Font.PLAIN,20));
g.drawString("生命值:"+this.player.life+"",10, 20);
}
}
package com.model;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import com.view.MyFrame;
import com.view.MyPanel;
public class Player {
public MyPanel panel;
public int width=100;
public int height=100;
public int x;
public int y;
//玩家得分
public int count=0;
//玩家命數
public int life=3;
//設定火力等級
public int attackMode=1;
private Image[] image=new Image[] {
Toolkit.getDefaultToolkit().getImage("photos/hero0.png"),
Toolkit.getDefaultToolkit().getImage("photos/hero1.png")
};//用圖檔組成,動态
private int imageIndex=0;//圖檔下标
public Player(MyPanel panel) {
this.panel=panel;
this.x=(MyFrame.frameWidth-width)/2;
this.y=MyFrame.frameHeight-height*2;
}
//繪制玩家,用數組下标
public void drawSelf(Graphics g) {
g.drawImage(image[imageIndex], x, y, width, height,null);
if(this.panel.timer%50==0) {
imageIndex++;
if(this.imageIndex==this.image.length) {
this.imageIndex=0;
}
}
for(int i=0;i<this.panel.enemys.size();i++) {
Enemy e=this.panel.enemys.get(i);
if(this.x==e.x&&this.y>=e.y-this.height&&this.y<=e.y+e.height+this.height) {
life--;
this.panel.enemys.remove(i);
}
}
if(life==0) {
this.panel.bgImage=Toolkit.getDefaultToolkit().getImage("photos/gameover.png");
if(this.panel.timer%1000==0) {
System.exit(-1);
}
}
}
}
package com.model;
import java.awt.Graphics;
import java.awt.Image;
import com.view.MyFrame;
import com.view.MyPanel;
//定義敵機父類
public class Enemy {
public MyPanel panel;
public int width;
public int height;
public int x;
public int y;
public Image image;
public int hp;//生命值
public int count;//分數
public Enemy(MyPanel panel) {
this.panel=panel;
}
//畫敵機
public void drawSelf(Graphics g) {
//判斷敵機是否被擊中
if(hp>0) {
g.drawImage(this.image, x, y, width, height, null);
}
else{//被殺死
killed();
}
//讓敵機向下移動
if(this.panel.timer%3==0) {
y++;
if(y>=MyFrame.frameHeight) {
this.panel.enemys.remove(this);
}
}
}
//殺死
public void killed () {
this.panel.player.count+=this.count;
this.panel.enemys.remove(this);
}
//打中
public void underAttrack() {
if(hp>0) {
this.hp--;
}
}
}
package com.model;
import java.awt.Toolkit;
import com.view.MyFrame;
import com.view.MyPanel;
//普通敵機
public class Enemy001 extends Enemy {
public Enemy001(MyPanel panel) {
super(panel);
this.width=49;
this.height=36;
this.x=(int)(Math.random()*(MyFrame.frameWidth-this.width));
this.y=-36;
this.count=5;
this.hp=3;
this.image=Toolkit.getDefaultToolkit().getImage("photos/airplane.png");
}
}
package com.model;
import java.awt.Toolkit;
import com.view.MyFrame;
import com.view.MyPanel;
//小蜜蜂敵機
public class Enemy002 extends Enemy {
public Enemy002(MyPanel panel) {
super(panel);
this.width=49;
this.height=36;
this.x=(int)(Math.random()*(MyFrame.frameWidth-this.width));
this.y=-36;
this.count=10;
this.hp=5;
this.image=Toolkit.getDefaultToolkit().getImage("photos/bee.png");
}
}
package com.model;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import com.view.MyPanel;
public class Bullet {
public MyPanel panel;
public int width=8;
public int height=8;
public int x;
public int y;
//存放子彈數組
public Image[] image=new Image[] {
Toolkit.getDefaultToolkit().getImage("photos/bullet.png"),
Toolkit.getDefaultToolkit().getImage("photos/bullet.png")
};
public int imageIndex=0;
public Bullet(MyPanel panel) {
this.panel=panel;
}
//畫子彈
public void drawSelf(Graphics g) {
g.drawImage(this.image[imageIndex], x, y, width, height,null);
if(this.panel.timer%1==0) {
imageIndex++;
if(imageIndex==this.image.length) {
imageIndex=0;
}
y--;
if(y<0) {
//從面闆移除子彈,減少記憶體的浪費
this.panel.bullets.remove(this);
}
}
for(int i=0;i<this.panel.enemys.size();i++) {
Enemy e=this.panel.enemys.get(i);
if(this.x>=e.x-this.width&&this.x<=e.x+e.width+this.width
&&this.y>=e.y-this.height&&this.y<=e.y+e.height+this.height) {
//子彈銷毀
this.panel.bullets.remove(this);
//敵機被攻擊
e.underAttrack();
}
}
}
}
package com.Thread;
import com.view.MyPanel;
public class DrawableThread extends Thread {
//用成員變量來存放對象
public MyPanel panel;
//重繪面闆,是以傳面闆過來
public DrawableThread(MyPanel panel) {
this.panel=panel;
}
public void run() {
//一直進行重繪
while(true) {
panel.repaint();//重繪,調用paintComponent(),隻要發生面闆發生變化,就會調用
try {
this.currentThread().sleep(1);//每隔1ms重繪
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package com.listener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import com.view.MyFrame;
public class FrameMouseMotionListener implements MouseMotionListener {
//需要使用坐标
public MyFrame MyFrame;
@Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseMoved(MouseEvent e) {
this.MyFrame.panel.player.x=e.getX()-this.MyFrame.panel.player.width/2;
this.MyFrame.panel.player.y=e.getY()-this.MyFrame.panel.player.height/2;
}
}
package com.view;
public class Test {
public static void main(String[] args) {
new MyFrame();
}
}
此代碼注釋較為詳細,在此我就不做過多說明,希望大家可以看懂并實作,謝謝!