前言
第三版是对第二版的完善,第二版基本实现了大小敌机、蜜蜂等飞行物的移动,以及自己操控的战斗机已经实现了子弹的射出。第三版完成了鼠标事件的实现,以及英雄机能够跟随鼠标进行移动,子弹、英雄与敌机的碰撞都以实现,得分、生命、火力加成等都以实现,最后就是碰撞需要实现都爆炸效果还没实现,目前只是使敌机和子弹在发生碰撞时一起消失而已。
Bee类
package PlaneGame.plane;
public class Bee extends Father implements Award{
private int speedy;
private int speedx=3;
private int awardType = (int)Math.random()*2;//奖励随机
public Bee() {
super((int)(Math.random()*Test.width-Test.beepicture.getWidth()),0,Test.beepicture,1,
Test.beepicture.getWidth(),Test.beepicture.getHeight());
this.speedy = 3;
}
@Override
public void move() {
setX(getX()+speedx);
if (getX() <= 0){
speedx = 1;
}
if (getX() >= Test.width-Test.beepicture.getWidth()){
speedx = -1;
}
setY(getY()+speedy);
}
@Override
public int getAward() {//获得随机奖励类型
return awardType;
}
}
BigPlane类
package PlaneGame.plane;
public class Bee extends Father implements Award{
private int speedy;
private int speedx=3;
private int awardType = (int)Math.random()*2;//奖励随机
public Bee() {
super((int)(Math.random()*Test.width-Test.beepicture.getWidth()),0,Test.beepicture,1,
Test.beepicture.getWidth(),Test.beepicture.getHeight());
this.speedy = 3;
}
@Override
public void move() {
setX(getX()+speedx);
if (getX() <= 0){
speedx = 1;
}
if (getX() >= Test.width-Test.beepicture.getWidth()){
speedx = -1;
}
setY(getY()+speedy);
}
@Override
public int getAward() {//获得随机奖励类型
return awardType;
}
}
Father 类
package PlaneGame.plane;
public class Bee extends Father implements Award{
private int speedy;
private int speedx=3;
private int awardType = (int)Math.random()*2;//奖励随机
public Bee() {
super((int)(Math.random()*Test.width-Test.beepicture.getWidth()),0,Test.beepicture,1,
Test.beepicture.getWidth(),Test.beepicture.getHeight());
this.speedy = 3;
}
@Override
public void move() {
setX(getX()+speedx);
if (getX() <= 0){
speedx = 1;
}
if (getX() >= Test.width-Test.beepicture.getWidth()){
speedx = -1;
}
setY(getY()+speedy);
}
@Override
public int getAward() {//获得随机奖励类型
return awardType;
}
}
Hero 类
package PlaneGame.plane;
import java.awt.image.BufferedImage;
public class Hero extends Father{
private int score=0;
private Bullet bullet;
private int doublebullet=0;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Hero() {
super(160,400,Test.heropicture1,3,Test.heropicture1.getWidth(),Test.heropicture1.getHeight());
this.score = 0;
}
private int count=0;
private BufferedImage[] images = {Test.heropicture2,Test.heropicture1};
@Override
public void move() {//使英雄机在两张图片之间迅速切换
count++;
if(count%2==0){
this.setImg(Test.heropicture1);
}else{
this.setImg(Test.heropicture2);
}
this.setImg(images[count%2]);
}
public Bullet[] shoot(){//子弹产生
Bullet[] bullets;
if (doublebullet ==0)
{
bullets =new Bullet[1];
bullets[0] = new Bullet((Test.heropicture1.getWidth()/2+this.getX()),this.getY());
}else{
bullets =new Bullet[2];
bullets[0] = new Bullet((Test.heropicture1.getWidth()/2+this.getX()),this.getY());
bullets[1] = new Bullet((Test.heropicture1.getWidth()/4+this.getX()),this.getY());
}
return bullets;
}
public void addFire(){//火力加成
doublebullet=+20;
}
public void addLife(){//生命加成
this.setLife(this.getLife()+1);
}
}
SmallPlane 类
package PlaneGame.plane;
public class SmallPlane extends Father implements Enemy{
int speed;
private int score;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public SmallPlane() {
super((int)(Math.random()*Test.width-Test.smallpicture.getWidth()),0,Test.smallpicture,1,
Test.smallpicture.getWidth(),Test.smallpicture.getHeight());
this.speed = 2;
this.score = 1;
}
@Override
public void move() {
setY(getY()+speed);
}
}
Bullet 类
package PlaneGame.plane;
public class Bullet extends Father{
int speed;
public Bullet(int x,int y) {
super(x,y,Test.bulletpicture,1,Test.bulletpicture.getWidth(),Test.bulletpicture.getHeight());
speed = -5;
}
@Override
public void move() {
setY(getY()+speed);
}
}
##Enemy敌机得分类
package PlaneGame.plane;
/**敌机分值计算*/
public interface Enemy {
int getScore();
}
##Award奖励类
package PlaneGame.plane;
/**奖励加成:1、火力加成 2、生命加1*/
public interface Award {
public static final int Double_Bullet=0;
public static final int life=1;
int getAward();
}
Test 测试类
package PlaneGame.plane;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.TimerTask;
public class Test extends JPanel{
public static BufferedImage bg;//背景对象
public static int width=400;//窗口的长
public static int height=600;//窗口的宽
public static final int START = 0; //启动状态
public static final int RUNNING = 1; //运行状态
public static final int PAUSE = 2; //暂停状态
public static final int GAME_OVER = 3; //游戏结束状态
private int state = START; //当前状态(默认为启动状态)
public static BufferedImage bigpicture;//大敌机对象
public static BufferedImage beepicture;//小蜜蜂对象
public static BufferedImage heropicture1;//英雄机1对象
public static BufferedImage smallpicture;//小敌机对象
public static BufferedImage bulletpicture;//子弹对象
public static BufferedImage heropicture2;
public static BufferedImage start;//开始界面对象
public static BufferedImage pause;//暂停界面对象
public static BufferedImage gameover;//游戏结束界面对象
static {
try {
bg = ImageIO.read(Test.class.getResourceAsStream("image/background.png"));
bigpicture = ImageIO.read(Test.class.getResourceAsStream("image/bigplane.png"));
beepicture = ImageIO.read(Test.class.getResourceAsStream("image/bee.png"));
heropicture1 = ImageIO.read(Test.class.getResourceAsStream("image/hero0.png"));
heropicture2 = ImageIO.read(Test.class.getResourceAsStream("image/hero1.png"));
smallpicture = ImageIO.read(Test.class.getResourceAsStream("image/airplane.png"));
bulletpicture = ImageIO.read(Test.class.getResourceAsStream("image/bullet.png"));
start = ImageIO.read(Test.class.getResourceAsStream("image/start.png"));
pause = ImageIO.read(Test.class.getResourceAsStream("image/pause.png"));
gameover = ImageIO.read(Test.class.getResourceAsStream("image/gameover.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**所有飞行物的集合*/
private ArrayList<Father> flyall = new ArrayList<>();
/**创建定时器*/
java.util.Timer timer = new java.util.Timer();
/**判断游戏结束*/
public void checkGameOverAction() {
if(hero.getLife()<=0) { //表示游戏结束了
state = GAME_OVER; //将当前状态修改为游戏结束状态
}
}
public void action(){
MouseAdapter ma = new MouseAdapter() {
/**重写鼠标的移动事件*/
public void mouseMoved(MouseEvent e){
if(state==RUNNING) {
int x = e.getX();//获取鼠标的x坐标
int y = e.getY();//获取鼠标的y坐标
hero.setX(x);
hero.setY(y);
}
repaint();
}
/**重写鼠标的点击事件*/
@Override
public void mouseClicked(MouseEvent e) {
// if (e.getButton() == MouseEvent.BUTTON1){
//
// }
//根据当前状态的不同,进行相应的处理
switch (state) {
case START:
state = RUNNING;
break;
case GAME_OVER:
hero.setScore(0);
//sky = new Sky();
hero = new Hero();
//flys = new FlyingObject[0];
//bullets = new Bullet[0];
state = START;//修改状态为开始状态
break;
}
}
/**重写鼠标的移入事件*/
@Override
public void mouseEntered(MouseEvent e) {
if (state == PAUSE) {
state = RUNNING;
}
}
/**重写鼠标的移出事件*/
@Override
public void mouseExited(MouseEvent e) {
if (state == RUNNING) {
state = PAUSE;
}
}
};
this.addMouseListener(ma);//处理鼠标的操作事件
this.addMouseMotionListener(ma);//处理鼠标的移动事件
timer.schedule(new TimerTask() {
@Override
public void run() {
if (state == RUNNING){
hero.move();//英雄机移动
createfly();//创建飞行物
createbullet();//创建子弹
allmove();//所有飞行物移动
outfly();//越界的飞行物
checkGameOverAction();//监测游戏是否结束
bulletAction();//监测子弹是否与敌机碰撞
heroAction();//监测英雄机是否与敌机碰撞
bulletmove();//子弹移动
}
repaint();//页面的刷新
}
},100,50);
}
/**创建子弹集合*/
private ArrayList<Bullet> bulletall = new ArrayList<>();
/**子弹的移动方法*/
private void bulletmove() {
for (int i = 0; i < bulletall.size(); i++) {
Bullet bs = bulletall.get(i);
bs.move();
}
}
/**创建子弹*/
private int bulletflag=0;
private void createbullet() {
bulletflag++;
if (bulletflag%5==0){
Bullet[] bullets = hero.shoot();
for (int i = 0; i < bullets.length; i++) {
bulletall.add(bullets[i]);
}
}
}
/**飞行物的越界问题*/
private void outfly() {
for (int i = 0; i < flyall.size(); i++) {
Father fly = flyall.get(i);
if(fly.getY()>=Test.height){
flyall.remove(i);
i--;
}
}
}
/**所有飞行物的移动问题*/
private void allmove() {
for (int i = 0; i < flyall.size(); i++) {
Father flymove = flyall.get(i);
flymove.move();
}
}
/**创建三大飞行物:小蜜蜂、大敌机、小敌机的概率*/
private int flyflag = 0;
private void createfly() {
Father fly;
flyflag++;
if (flyflag % 10 == 0){
int ran = (int)(Math.random()*10);
if (ran == 0 || ran ==1){
fly = new Bee();
}else if (ran ==2 ||ran == 3|| ran ==4||ran==5){
fly = new BigPlane();
}else {
fly = new SmallPlane();
}
flyall.add(fly);//随机生成的三大飞行物都添加到flyall这个集合当中去
}
}
/**子弹与敌人的碰撞*/
private void bulletAction(){
for(int i=0;i<bulletall.size();i++) { //遍历所有子弹
for(int j=0;j<flyall.size();j++){ //遍历所有敌人
Bullet b = bulletall.get(i);
Father f = flyall.get(j);
//判断子弹是否与敌机接触
if (b.getX()>=f.getX()&&b.getX()<=f.getX()+f.getWidth()
&&b.getY()>=f.getY()&&b.getY()<=f.getY()+f.getHeight()){
f.setLife(f.getLife()-1);
if (f.getLife() == 0){
if (f instanceof Enemy){//若飞行物是敌机则进行添加分数
Enemy enemy = (Enemy)f;
hero.setScore(hero.getScore()+enemy.getScore());
}
if(f instanceof Award) { //若被撞敌人为奖励
Award ea = (Award)f; //将被撞敌人强转为奖励接口
int type = ea.getAward(); //获取奖励类型
switch(type) { //根据奖励类型来获取不同的奖励
case Award.Double_Bullet: //若奖励类型为火力
hero.addFire(); //则英雄机得分
break;
case Award.life: //若奖励类型为名
hero.addLife(); //则英雄机增命
break;
}
}
flyall.remove(j);
i--;
break;
}
}
}
}
}
/**英雄机与敌人撞*/
private void heroAction() {
for(int i=0;i<flyall.size();i++) { //遍历所有敌人
Father f = flyall.get(i); //获取每个敌人
//判断英雄机的坐标是否与敌机重合
if (hero.getX()>=f.getX()&&hero.getX()<=f.getX()+f.getWidth()
&&hero.getY()>=f.getY()&&hero.getY()<=f.getY()+f.getHeight()){
hero.setLife(hero.getLife()-1);//如果坐标重合则英雄机的生命减去1
if (f.getLife()==0){
flyall.remove(i);
i--;
break;
}
}
if (hero.getLife()==0){//如果英雄机的生命为0,则游戏结束
state = GAME_OVER;
}
}
}
Hero hero = new Hero();
/**添加窗口上面的画板*/
public void paint(Graphics g) {
super.paint(g);
g.drawImage(bg,0,0,this);//添加背景
g.drawString("life:"+hero.getLife(),8,15);//添加生命值显示
g.drawString("score:"+hero.getScore(),8,25);//添加得分值显示
paintfly(g);//把三大飞行物添加到画板上
paintbullets(g);//把子弹添加到画板上
g.drawImage(hero.getImg(),hero.getX(),hero.getY(),this);//添加英雄机
paintstate(g);//添加游戏状态
}
/**把子弹画到画板上*/
private void paintbullets(Graphics g) {
for (int i = 0; i < bulletall.size(); i++) {
Bullet bs = bulletall.get(i);
g.drawImage(bs.getImg(),bs.getX(),bs.getY(),this);
}
}
/**把创建的三大飞行物画到画板上*/
private void paintfly(Graphics g) {
for (int i = 0; i < flyall.size(); i++) {
Father flyallpaint = flyall.get(i);
g.drawImage(flyallpaint.getImg(),flyallpaint.getX(),flyallpaint.getY(),this);
}
}
/**状态显示*/
private void paintstate(Graphics g){
switch (state){
case START:
g.drawImage(start,0,0,this);
break;
case PAUSE:
g.drawImage(pause,0,0,this);
break;
case GAME_OVER:
g.drawImage(gameover,0,0,this);
break;
}
}
/**主函数*/
public static void main(String[] args) {
JFrame jFrame = new JFrame("飞机大战");
Test test = new Test();
jFrame.add(test);
jFrame.setSize(width,height);
jFrame.setLocationRelativeTo(jFrame.getOwner());
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);
test.action();
}
}
注意要点:
如想测试效果,记得需要把测试类中的图片链接进行更换(“image/background.png”),同时需要注意的是图片包必须跟创建的各个类处在同一个大包下才能加载成功,否则会报错。所需要的代码我已上传资源包