此项目主要使用到了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 bullets=new ArrayList();
//存放所有的敌机
public ArrayList enemys=new ArrayList();
//存放所有的敌机类型
@SuppressWarnings("rawtypes")
public ArrayList enemyType=new ArrayList();
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;i0) {
//随机一种类型对象的下标
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
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=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=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();
}
}
此代码注释较为详细,在此我就不做过多说明,希望大家可以看懂并实现,谢谢!