基于JavaSwing写的雷霆战机(飞机大战)

自学Java已经有一段时间了吧,一直都没有一个关于界面的完整的项目,计算器这些又太简单,所以就一直构思写一个基于JavaSwing的游戏。虽然在日常开发中使用到JavaSwing开发界面的很少。但是这个游戏也就当做一次对我前面所学习的知识的巩固吧,好了废话不多说,下面我们先来看看游戏运行的效果。图片素材都是网络上面找的。后面我会把所有资源都发上来(音频、图片、图标等)
游戏主界面
这里写图片描述
游戏运行界面
这里写图片描述
这只是一张GIF图片,实际运行的时候还有声音,玩的时候更有感觉
游戏暂停界面
这里写图片描述
游戏结束界面
游戏结束界面写的很简单
这里写图片描述
第一次写游戏,还是有很多不足的地方,大神轻喷。
下面开始给大家正式讲解我的思路:

1、首先使用面向对象的方法去思考,因为是飞行游戏,所以里面涉及到很多东西移动。敌机绘制和移动,敌机子弹移动,礼物移动,英雄机的移动,英雄机子弹的移动。爆炸效果图的出现,所以我们可以抽象一个父类出来。 这个父类就叫飞行器类吧。
下面是抽象类Flyer的变量和方法结构图:
Flyer类

下面是具体实现的代码:

package com.PlaneWars;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
/**
 * 
 * 封装所有飞行器的属性和方法
 * @author poc999
 *
 */
public abstract class Flyer {
    /*
     * 飞行器的坐标
     */
     public int x;
     public int y;
    /*
     * 飞行器的大小
     */
    public int WIDTH;
    public int HEIGHT;
    /*
     * 飞行器的图片
     */
     BufferedImage image;
    //初始化飞行器对象
     public Flyer(int x,int y,int WIDTH,int HEIGHT,BufferedImage image){
         this.x=x;
         this.y=y;
         this.WIDTH=WIDTH;
         this.HEIGHT=HEIGHT;
         this.image=image;
     }
    //每个飞行器都需要自己移动,但是需要子类自己去实现移动的方法
    public abstract void move(long time);
    //判断两个飞行器是否碰撞
    public static boolean boom(Flyer f1,Flyer f2){  
        //step1: 求出两个矩形的中心点  
        int f1x = f1.x + f1.WIDTH/2;  
        int f1y = f1.y + f1.HEIGHT/2;  
        int f2x = f2.x + f2.WIDTH/2;  
        int f2y = f2.y + f2.HEIGHT/2;  
        //step2: 横向和纵向碰撞检测  
        boolean H = Math.abs(f1x - f2x) < (f1.WIDTH + f2.WIDTH)/2;  
        boolean V = Math.abs(f1y -f2y) < (f1.HEIGHT + f2.HEIGHT)/2;  
        //step3: 必须两个方向同时碰撞  
        return H&V;  
    }
    //绘制出每个飞行物
    public void draw(Graphics g)
    {
        g.drawImage(image, x, y, WIDTH, HEIGHT, null);
    }

}

2、下面我们来构思需要那些物体在JPlane上面跑起来。
(1)敌机1.2.3
(2)爆炸效果
(3)敌机子弹
(4)礼物
(5)英雄子弹
(6)英雄机
(7)上面所有的这些类都继承Flyer抽象类。因为都是飞行器
下面是所有类的结构图:
效果图


下面我们就先来挨着实现每一个飞行器类:
①Enemy1类(A类敌机类):

package com.PlaneWars;

import java.util.Random;

public class Enemy1 extends Flyer{

    Random r=new Random();
    //构造方法
    public Enemy1(int x, int y) {
        super(x, y, 40, 40, ImageRead.enemyA);
        // TODO Auto-generated constructor stub
    }

    /*
     * A类敌机的移动方法,X,Y每次随机加上一个小于5的值
     */
    @Override
    public void move(long time) {
        // TODO Auto-generated method stub
        x+=r.nextInt(5);
        y+=r.nextInt(5);
        }
    /*
     * 
     * 敌机子弹是随着敌机位置出现的,所以这里写一个返回敌机火力的方法
     */
    public Enemybullet enemyfire(){

        Enemybullet e=new Enemybullet(this.x+WIDTH/4,this.y+HEIGHT);
        return e;
    }

}

②Enemy2类(B类敌机类)和A类敌机的实现大同小异:

package com.PlaneWars;

import java.util.Random;

public class Enemy2 extends Flyer{

    Random r=new Random();
    public Enemy2(int x, int y) {
        super(x, y, 35, 35, ImageRead.enemyB);
        // TODO Auto-generated constructor stub
    }
//只能向左移动
    @Override
    public void move(long time) {
        // TODO Auto-generated method stub

        x-=r.nextInt(5);
        y+=r.nextInt(5);
    }

    public Enemybullet enemyfire(){

        Enemybullet e=new Enemybullet(this.x+WIDTH/4,this.y+HEIGHT);
        return e;
    }

}

③Enemy3类(C类敌机类,上同)

package com.langxikeji.PlaneWars;

import java.util.Random;

public class Enemy3 extends Flyer{

    Random r=new Random();
    public Enemy3(int x, int y) {
        super(x, y,30,30,ImageRead.enemyC);
        // TODO Auto-generated constructor stub
    }

/*
*和A类B类敌机移动不同,只能够在Y轴上面移动
*/
    @Override
    public void move(long time) {
        // TODO Auto-generated method stub
        y+=r.nextInt(5);
    }

    public Enemybullet enemyfire(){

        Enemybullet e=new Enemybullet(this.x+WIDTH/4,this.y+HEIGHT);
        return e;
    }
}

④enemyBullet类(敌机子弹类):

package com.PlaneWars;

public class Enemybullet extends Flyer{

    public Enemybullet(int x, int y) {
        super(x, y, 20, 26, ImageRead.enemybullet);
        // TODO Auto-generated constructor stub
    }
    @Override
    public void move(long time) {
        // TODO Auto-generated method stub
        if(time%20==0){
            y+=10;
        }
    }
}

⑤Gift类(礼物类):

package com.PlaneWars;


public class Gift extends Flyer{

    public Gift(int x, int y) {
        super(x, y, 30, 30, ImageRead.gift);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void move(long time) {
        // TODO Auto-generated method stub
            if(time%20==0){
                y+=10;
            }
    }

}

⑥Hero类(英雄机类):

package com。PlaneWars;
/*
 * 英雄机的类,因为英雄机需要键盘来控制移动,所以。移动的方法需要从新定义
 */
public class Hero extends Flyer{

    public Hero(int x, int y) {
        super(x, y, 40, 40, ImageRead.hero);
        // TODO Auto-generated constructor stub
    }
    public void MoveUp() { // 以防飞机上移出界,每次移五个单位
        if (y >= 10)
            y -= 10;
    }

    public void MoveDown() {
        if (y <= 606) // 游戏界面减去飞机高79和最小移动步长
            y += 10;
    }

    public void MoveLeft() {
        if (x >= 10)
            x -= 10;
    }

    public void MoveRight() {
        if (x <= 431)
            x += 10;
    }

    //飞机子弹发射的位置由飞机位置确定
    public Herobullet Herofire(){
        Herobullet bullet=new Herobullet(this.x+WIDTH/4,this.y);
        return bullet;
    }
    @Override
    public void move(long time) {
        // TODO Auto-generated method stub

    }
}

⑦HeroBullet类(英雄机子弹类):

package com.PlaneWars;
/*
 * 英雄机子弹的类
 */
public class Herobullet extends Flyer {

    public Herobullet(int x, int y) {
        super(x, y, 40,40, ImageRead.herobullet);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void move(long time) {
        // TODO Auto-generated method stub
        if(time%20==0){
            y-=10;
        }
    }
}

⑧Blast类(爆炸效果类):

package com.PlaneWars;

/*
 *  英雄机子弹和敌机相撞的爆炸类
 */
public class Blast extends Flyer{

    public Blast(int x, int y) {
        super(x-20, y-20,50,50,ImageRead.blast );
        // TODO Auto-generated constructor stub
    }
        //并没有移动,爆炸图刚刚出现就消失了
    @Override
    public void move(long time) {
        // TODO Auto-generated method stub

    }
}

上面是所以飞行器的类,这只是我写的这么多类,如果你还要增加敌机或者
一些其他的飞行物体。你可以按照我的方法在增加类。下面是资源加载类!

⑨资源加载类(ImageRead类)

package com.PlaneWars;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;

import javax.imageio.ImageIO;

/*
 * 所有资源加载类
 */
public class ImageRead {
    public static BufferedImage enemyA;// 敌机一
    public static BufferedImage enemyB;// 敌机二
    public static BufferedImage enemyC;// 敌机三
    public static BufferedImage hero;// 英雄机
    public static BufferedImage herobullet;// 英雄机子弹
    public static BufferedImage enemybullet;// 敌机子弹
    public static BufferedImage gift;// 礼物
    public static BufferedImage blast;// 爆炸
    public static BufferedImage map1;//地图
    public static BufferedImage b1;
    public static BufferedImage b2;
    public static BufferedImage b3;
    public static BufferedImage b4;
    public static BufferedImage icon;

    /*
     * 资源加载使用静态初始化块
     * 因为只需要启动的时候使用一次
     */
    static {
        try {
            enemyA = ImageIO.read(new FileInputStream("./素材/Boss/BOSS1.png"));
            enemyB = ImageIO.read(new FileInputStream("./素材/Boss/BOSS2.png"));
            enemyC = ImageIO.read(new FileInputStream("./素材/Boss/BOSS3.png"));
            hero = ImageIO.read(new FileInputStream("./素材/Hero1/hero.png"));
            herobullet = ImageIO.read(new FileInputStream("./素材/Bullet/双弹1.png"));
            enemybullet = ImageIO.read(new FileInputStream("./素材/Bullet/蓝弹1.png"));
            gift = ImageIO.read(new FileInputStream("./素材/Gift/gift.png"));
            blast = ImageIO.read(new FileInputStream("./素材/Blast/blast_2_2.png"));
            map1=ImageIO.read(new FileInputStream("./素材/Maps/map5.jpg"));
            icon=ImageIO.read(new FileInputStream("./素材/Icon/图标.jpg"));
            b1=ImageIO.read(new FileInputStream("./素材/Maps/map4.jpg"));
            b2=ImageIO.read(new FileInputStream("./素材/Maps/b2.jpg"));
            b3=ImageIO.read(new FileInputStream("./素材/Maps/b3.png"));
            b4=ImageIO.read(new FileInputStream("./素材/Maps/b4.png"));
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

}

⑩PlaneFrame类(顶层窗体类)。是画板的载体,自己可以根据背景的大小来设置

主窗体

package com.PlaneWars;

import java.awt.BorderLayout;

import javax.swing.JFrame;

/**
 * @author poc999
 * 
 */
public class PlaneFrame extends JFrame {

    private static final long serialVersionUID = 1L;
    // 创建JPlane的对象
    PlaneWars pw = new PlaneWars();

    // 创建PlaneFrame的构造器,初始化对象
    public PlaneFrame() {
        // 将JPanel的焦点状态设置为true。
        pw.setFocusable(true);
        // 让JFrame先获得焦点,然后JPanel在获得焦点
        pw.requestFocus();
        this.add(pw, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        // 创建主窗口的对象
        PlaneFrame pf = new PlaneFrame();
        // 设置主窗体的名字
        pf.setTitle("PlaneWars by2.0");
        // 设置主窗体的大小
        pf.setSize(500, 700);
        // 设置主窗体居中显示
        pf.setLocationRelativeTo(null);
        // 设置游戏界面图标
        pf.setIconImage(ImageRead.icon);
        // 设置主窗体的关闭和退出
        pf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 显示主窗体
        pf.setVisible(true);
        // 主窗体不可拉伸
        pf.setResizable(false);
    }

}

⑾PlaneWars(最后一个类,也是最重要的一个类)

package com.PlaneWars;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class PlaneWars extends JPanel implements KeyListener {
    /**
        1、简单描述就是:迭代器遍历元素的时候,
           通过集合是不能修改元素的。 
        2、游戏暂停需要重新请求焦点。
        3、每一判断碰撞之后需要跳出循环,继续回到上一次碰撞的地方判断
     */
    private static final long serialVersionUID = 1L;

    // 指定按键的初始状态
    private boolean up, down, left, right, VK_Z, VK_X, VK_ENTER = false;
    // 开始状态
    private int state = START;
    // 设置游戏的各种状态的值
    private static int START = 0;
    private static int RUNNING = 1;
    private static int PAUSE = 2;
    private static int GAME_OVER = 3;
    // 时间初始化
    private int time = 0;
    // 背景的连续移动初始值
    private int backgroundmove = 0;
    // 记录英雄机的分数
    private int score = 0;
    // 设置游戏的关数的初始值
    private int stage = 0;
    // 导弹的初始数量
    private int bomb = 10;
    // 英雄机的初始血量
    private int life = 20;
    // 用于产生随机数,敌机的初始X坐标
    Random r = new Random();
    // 背景音乐,爆炸 导弹 子弹音效
    private AudioClip bgmusic;
    private AudioClip blastmusic;
    private AudioClip bombmusic;
    private AudioClip bulletmusic;
    // 分数 炸弹 生命 关卡标签
    private JLabel scorelabel;
    private JLabel bomblabel;
    private JLabel lifelabel;
    private JLabel pointlabel;
    // 使用集合保存所有对象
    private Hero hero;
    private Gift gift;
    private List<Blast> blast = new ArrayList<>();
    private List<Enemy1> enemy1 = new ArrayList<>();
    private List<Enemy2> enemy2 = new ArrayList<>();
    private List<Enemy3> enemy3 = new ArrayList<>();
    private List<Enemybullet> enemybullet = new ArrayList<>();
    private List<Herobullet> herobullet = new ArrayList<>();

    public PlaneWars() {
        URL u1 = PlaneWars.class.getResource("/bgmusic.wav");
        URL u2 = PlaneWars.class.getResource("/blastmusic.wav");
        URL u3 = PlaneWars.class.getResource("/Bomb.wav");
        URL u4 = PlaneWars.class.getResource("/bulletmusic.wav");

        bgmusic = Applet.newAudioClip(u1);
        blastmusic = Applet.newAudioClip(u2);
        bombmusic = Applet.newAudioClip(u3);
        bulletmusic = Applet.newAudioClip(u4);

        // 初始化面板
        board();
        // 使用线程
        Thread game = new Thread() {

            public void run() {

                // 背景音乐的循环播放
                bgmusic.loop();

                while (true) {
                    /*
                     * 英雄机的移动,moving()方法需要写在外面。 因为刚开始需要控制键盘enter键。
                     * 使用到线程,使state变为RUNNING
                     */
                    moving();
                    if (state == RUNNING && stage == 1) {
                        // 控制关卡的分数
                        if (score > 5000) {
                            stage = 2;
                            pointlabel.setText("第二关");
                        }
                        // 敌机的移动
                        enemymoving(time);
                        // 英雄机子弹的移动
                        herobulletmoving(time);
                        // 敌机子弹的移动
                        enemybulletmoving(time);
                        // 生成敌机
                        enemy(time);
                        // 生成敌机子弹
                        enemyfire(time);
                        // 英雄机子弹和敌机碰撞
                        collision(time);
                        // 敌机子弹和英雄机碰撞
                        crash(time);
                        // 礼物和英雄机的碰撞
                        giftcrash(time);

                        // 时间的递增
                        time += 40;
                        try {
                            Thread.sleep(40);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    // 第二关(把所有方法执行两次)
                    if (state == RUNNING && stage == 2) {
                        // 敌机的移动
                        enemymoving(time);
                        enemymoving(time);
                        // 英雄机子弹的移动
                        herobulletmoving(time);
                        herobulletmoving(time);
                        // 敌机子弹的移动
                        enemybulletmoving(time);
                        enemybulletmoving(time);
                        // 生成敌机
                        enemy(time);
                        enemy(time);
                        // 生成敌机子弹
                        enemyfire(time);
                        enemyfire(time);
                        // 英雄机子弹和敌机
                        collision(time);
                        collision(time);
                        // 敌机子弹和英雄机
                        crash(time);
                        crash(time);
                        // 礼物和英雄机的碰撞
                        giftcrash(time);
                        giftcrash(time);
                        // 时间的递增
                        time += 40;
                        try {
                            Thread.sleep(40);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    repaint();
                }
            }

            // 飞机移动和操作
            public void moving() {
                if (up) {
                    hero.MoveUp();
                }
                if (down) {
                    hero.MoveDown();
                }
                if (left) {
                    hero.MoveLeft();
                }
                if (right) {
                    hero.MoveRight();
                }
                if (VK_Z && bomb > 0) {
                    // 播放爆炸音效
                    bombmusic.play();
                    bomb--;
                    // 全屏爆炸的效果
                    int l1 = enemy1.size();
                    int l2 = enemy2.size();
                    int l3 = enemy3.size();
                    for (int i = 0; i < l1; i++) {
                        for (int j = 0; j < l2; j++) {
                            for (int k = 0; k < l3; k++) {
                                Blast blast1 = new Blast(enemy1.get(i).x,
                                        enemy1.get(i).y);
                                Blast blast2 = new Blast(enemy2.get(j).x,
                                        enemy2.get(j).y);
                                Blast blast3 = new Blast(enemy3.get(k).x,
                                        enemy3.get(k).y);
                                blast.add(blast1);
                                blast.add(blast2);
                                blast.add(blast3);
                                l1--;
                                l2--;
                                l3--;
                                break;
                            }
                        }
                    }
                    // 加上全屏敌机的分数
                    score += (1 * enemy1.size() + 2 * enemy2.size() + 3 * enemy3
                            .size());
                    // 敌机集合清空
                    enemy1.clear();
                    enemy2.clear();
                    enemy3.clear();
                    // 敌机子弹清空
                    enemybullet.clear();
                    scorelabel.setText("分数:" + score);
                    // 刷新显示炸弹数
                    bomblabel.setText("炸弹" + bomb);
                }
                if (VK_X) {
                    // 生成英雄机子弹对象
                    Herobullet herofire = hero.Herofire();
                    // 控制子弹的生成速度
                    if (time % 200 == 0) {
                        bulletmusic.play();
                        herobullet.add(herofire);
                    }
                }
                if (VK_ENTER) {
                    // 判断游戏的是否为初始状态
                    if (state == START && stage == 0) {
                        state = RUNNING;
                        stage = 1;
                    }else if(state == GAME_OVER){
                        state=RUNNING;
                        Restart();
                    }
                }

            }

            //从新开始游戏
            public void Restart(){
                //所有对象集合初始化
                herobullet.clear();
                enemy1.clear();
                enemy2.clear();
                enemy3.clear();
                enemybullet.clear();
                state=1;
                score=0;
                life=20;
                bomb=10;
                //初始化面板
                board();
            }
            // 敌机和英雄子弹子弹碰撞的方法
            public void collision(long time) {
                // 英雄机子弹集合的长度
                int l1 = herobullet.size();
                // A敌机集合的长度
                int l2 = enemy1.size();
                // B敌机集合的长度
                int l3 = enemy2.size();
                // C敌机集合的长度
                int l4 = enemy3.size();
                // 遍历A敌机和子弹集合
                for (int i = 0; i < l1; i++) {
                    for (int j = 0; j < l2; j++) {
                        if (Flyer.boom(herobullet.get(i), enemy1.get(j))) {
                            // 一旦碰撞就开始播放爆炸音效
                            blastmusic.play();
                            Herobullet hb = herobullet.get(i);
                            Blast blast4 = new Blast(hb.x, hb.y);
                            // 加入爆炸对象集合
                            blast.add(blast4);
                            // 一旦碰撞,移除当前位置的英雄机子弹和敌机
                            herobullet.remove(herobullet.get(i));
                            enemy1.remove(enemy1.get(j));

                            score += 20;
                            scorelabel.setText("分数:" + score);
                            // 创建爆炸图效果
                            // 敌机和子弹集合的长度分别减1
                            l1--;
                            l2--;
                            // 返回上一次当前位置继续监测
                            i--;
                            j--;
                            // 一旦碰撞,跳出循环
                            break;
                        }
                    }
                }
                // 遍历B敌机和子弹集合
                for (int i = 0; i < l1; i++) {
                    for (int j = 0; j < l3; j++) {
                        // 如果碰撞
                        if (Flyer.boom(herobullet.get(i), enemy2.get(j))) {
                            // 一旦碰撞就开始播放爆炸音效
                            blastmusic.play();
                            // 创建爆炸图效果
                            Herobullet hb = herobullet.get(i);
                            Blast blast1 = new Blast(hb.x, hb.y);
                            // 加入爆炸对象集合
                            blast.add(blast1);
                            // 一旦碰撞,移除当前位置的英雄机子弹和敌机
                            herobullet.remove(herobullet.get(i));
                            enemy2.remove(enemy2.get(j));

                            score += 30;
                            scorelabel.setText("分数:" + score);
                            // 敌机和子弹集合的长度分别减1
                            l1--;
                            l3--;
                            // 返回上一次当前位置继续监测
                            i--;
                            j--;
                            // 一旦碰撞,跳出循环
                            break;
                        }
                    }
                }
                // 遍历C敌机和子弹集合
                for (int i = 0; i < l1; i++) {
                    for (int j = 0; j < l4; j++) {
                        if (Flyer.boom(herobullet.get(i), enemy3.get(j))) {
                            // 一旦碰撞就开始播放爆炸音效
                            blastmusic.play();
                            score += 50;
                            scorelabel.setText("分数:" + score);
                            // 创建爆炸图效果
                            Herobullet hb = herobullet.get(i);
                            Blast blast1 = new Blast(hb.x, hb.y);
                            // 加入爆炸对象集合
                            blast.add(blast1);
                            // 一旦碰撞,移除当前位置的英雄机子弹和敌机
                            herobullet.remove(herobullet.get(i));
                            enemy3.remove(enemy3.get(j));
                            // 敌机和子弹集合的长度分别减1
                            l1--;
                            l4--;
                            // 返回上一次当前位置继续监测
                            i--;
                            j--;
                            // 一旦碰撞,跳出循环
                            break;
                        }
                    }
                }
            }

            // 判断礼物和英雄机碰撞的方法
            public void giftcrash(long time) {
                // 如果碰撞
                if (Flyer.boom(hero, gift)) {
                    // 礼物初始化
                    gift = new Gift(0, 0);
                    // 获得礼物可能加生命,可能加导弹
                    if (r.nextInt(2) == 1) {
                        // 导弹个数不能大于5个
                        if (bomb > 5) {
                            bomb = 5;
                            // 不能小于0个
                        } else {
                            // 每次导弹加一颗
                            bomb++;
                        }
                    } else {

                        // 生命值不能大于20点
                        if (life > 20) {
                            life = 20;
                        } else {
                            // 每次生命值回复2点
                            life += 2;
                        }
                    }
                    lifelabel.setText("生命:" + life);
                    bomblabel.setText("导弹:" + bomb);
                }
            }

            // 敌机子弹和英雄机的碰撞方法
            public void crash(long time) {
                int l3 = enemybullet.size();
                for (int i = 0; i < l3; i++) {
                    if (Flyer.boom(enemybullet.get(i), hero)) {
                        enemybullet.remove(enemybullet.get(i));
                        life--;
                        lifelabel.setText("生命:" + life);
                        // 如果生命减少到0,游戏结束
                        if (life <= 0) {
                            state = GAME_OVER;
                        }
                        l3--;
                        i--;
                        break;
                    }
                }
            }

            // 敌机移动
            public void enemymoving(long time) {
                for (int i = 0; i < enemy1.size(); i++) {
                    enemy1.get(i).move(time);
                }
                for (int i = 0; i < enemy2.size(); i++) {
                    enemy2.get(i).move(time);
                }
                for (int i = 0; i < enemy3.size(); i++) {
                    enemy3.get(i).move(time);
                }
                gift.move(time);
            }

            public void herobulletmoving(long time) {
                for (int i = 0; i < herobullet.size(); i++) {
                    herobullet.get(i).move(time);
                }

            }

            public void enemybulletmoving(long time) {
                for (int i = 0; i < enemybullet.size(); i++) {
                    enemybullet.get(i).move(time);
                }
            }

            public void enemyfire(long time) {
                // 敌机A发射子弹
                if (time % 2000 == 0) {
                    for (int i = 0; i < enemy1.size(); i++) {
                        Enemybullet b = enemy1.get(i).enemyfire();
                        enemybullet.add(b);
                    }
                }
                // 敌机B发射子弹
                if (time % 3000 == 0) {

                    for (int i = 0; i < enemy2.size(); i++) {
                        Enemybullet b = enemy2.get(i).enemyfire();
                        enemybullet.add(b);
                    }
                }
                // 敌机C发射子弹
                if (time % 4000 == 0) {

                    for (int i = 0; i < enemy3.size(); i++) {
                        Enemybullet b = enemy3.get(i).enemyfire();
                        enemybullet.add(b);
                    }
                }
            }

            public void enemy(long time) {
                // 生成敌机1的时间
                if (time % 600 == 0) {
                    Enemy1 e = new Enemy1(r.nextInt(450), 0);
                    enemy1.add(e);
                }
                // 生成敌机2的时间
                if (time % 400 == 0) {
                    Enemy2 e = new Enemy2(r.nextInt(450), 0);
                    enemy2.add(e);
                }
                // 生成礼物的时间
                if (score != 0 && score % 1000 == 0) {
                    gift = new Gift(r.nextInt(450), 0);
                }
                // 生成敌机3的时间
                if (time % 800 == 0) {
                    Enemy3 e = new Enemy3(r.nextInt(450), 0);
                    enemy3.add(e);
                }

            }

        };
        // 启动线程
        game.start();
    }

    /*
     * 连续背景的绘制
     */
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        try {
            BufferedImage image;
            if (backgroundmove > 600) {
                backgroundmove = 0;
            }
            image = ImageIO.read(new FileInputStream("./素材/Maps/map3.jpg"));// 加载背景
            g.drawImage(image, 0, backgroundmove, 600, 800, null);
            backgroundmove += 1;
            g.drawImage(image, 0, -600 + backgroundmove, 600, 800, null); // 使得背景是持续的
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 分数、炸弹、生命面板
    public void board() {
        // 清除容器内所有内容
        this.removeAll();
        this.addKeyListener(this);
        // 初始化礼物对象
        gift = new Gift(0, 0);
        // 关卡标签
        pointlabel = new JLabel("第一关");
        pointlabel.setForeground(Color.green);
        Font font = new Font("黑体", Font.PLAIN, 20);
        pointlabel.setFont(font);
        // 分数标签
        scorelabel = new JLabel("分数:" + score);
        // 设置背景颜色
        scorelabel.setForeground(Color.RED);
        // 炸弹标签
        bomblabel = new JLabel("导弹:" + bomb);
        bomblabel.setForeground(Color.RED);
        // 生命标签
        lifelabel = new JLabel("生命:" + life);
        lifelabel.setForeground(Color.RED);
        // 游戏继续按钮
        final JButton gameon = new JButton("继续");
        gameon.setForeground(Color.RED);
        // 设置按钮为透明
        gameon.setContentAreaFilled(false);
        // 游戏暂停按钮
        JButton gamestop = new JButton("暂停");
        gamestop.setForeground(Color.RED);
        gamestop.setContentAreaFilled(false);
        // 继续按钮添加监听
        gameon.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if (state == PAUSE) {
                    state = RUNNING;
                    /*
                     * 重新使JPanel成为焦点!一定需要从新请求焦点。不然暂停一次键盘就直接失灵了
                     */
                    PlaneWars.this.requestFocusInWindow();
                }
            }
        });
        // 暂停按钮添加监听
        gamestop.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (state == RUNNING) {
                    state = PAUSE;
                }
            }
        });
        // 新建一个面板,把按钮和标签都加入到面板中间
        JPanel jp = new JPanel();
        // 设置背景颜色为黑色
        jp.setBackground(Color.BLACK);
        // 使用浮动布局管理器
        jp.setLayout(new FlowLayout(FlowLayout.LEADING, 30, 10));
        jp.add(pointlabel);
        jp.add(bomblabel);
        jp.add(scorelabel);
        jp.add(lifelabel);
        jp.add(gameon);
        jp.add(gamestop);
        // JPanel 面板添加这个面板
        this.add(jp);
        // 英雄机的初始位置
        hero = new Hero(230, 600);
    }

    @Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        // 如果为初始状态
        if (state == START) {
            paintstart(g);
            // 如果为游戏运行状态
        } else if (state == RUNNING) {
            // 绘制英雄机
            painthero(g);
            // 绘制敌机
            paintenemy(g);
            // 绘制一组敌机子弹
            paintenemybullets(g);
            // 绘制英雄机子弹
            paintherobullets(g);
            // 绘制爆炸效果和移除爆炸效果
            paintblast(g);
            // 绘制礼物
            paintgift(g);
        } else if (state == PAUSE) {
            g.setFont(new Font("黑体", Font.BOLD, 50));
            g.setColor(Color.RED);
            g.drawString("游戏暂停!!!", 120, 330);
        }
        // 如果为游戏结束状态
        else if (state == GAME_OVER) {
            paintover(g);
        }

    }

    // 该方法为绘制游戏结束界面
    public void paintover(Graphics g) {
        g.drawImage(ImageRead.b1, 0, 0, 500, 800, null);
        g.drawImage(ImageRead.b2, 0, 0, 500, 150, null);
        Font font1 = new Font("黑体", Font.ITALIC, 60);
        Font font2 = new Font("黑体", Font.PLAIN, 30);
        g.setColor(Color.RED);
        g.setFont(font1);
        g.drawString("GAME OVER", 100, 300);
        g.setFont(font2);
        g.drawString("score:" + score + "---你已经很棒啦!", 80, 400);
        g.setFont(font2);
        g.drawString("按ENTER键从新开始游戏", 100, 500);
    }

    // 该方法为绘制初始界面
    public void paintstart(Graphics g) {
        g.drawImage(ImageRead.b1, 0, 0, 500, 800, null);
        g.drawImage(ImageRead.b2, 0, 0, 500, 150, null);
        g.drawImage(ImageRead.b3, 50, 200, null);
        g.drawImage(ImageRead.b4, 150, 200, 300, 400, null);
        Font font = new Font("黑体", Font.PLAIN, 20);
        g.setColor(Color.RED);
        g.setFont(font);
        g.drawString("按ENTER键开始游戏", 50, 500);
        g.drawString("X:控制子弹,Z:控制超级武器", 50, 550);
        g.drawString("方向键:↑,↓,←,→", 50, 600);
        g.drawString("作者:poc999", 50, 650);
    }

    // 绘制礼物
    public void paintgift(Graphics g) {
        // 因为礼物的初始位置为坐标为0和0,
        if (gift.x != 0 && gift.y != 0) {
            g.drawImage(ImageRead.gift, gift.x, gift.y, 20, 20, null);
        }
    }

    // 绘制英雄机
    public void painthero(Graphics g) {

        g.drawImage(ImageRead.hero, hero.x, hero.y, 60, 60, null);
    }

    // 绘制爆炸图
    public void paintblast(Graphics g) {

        int l3 = blast.size();
        for (int i = 0; i < l3; i++) {
            Blast b = blast.get(i);
            // 绘制之后立即移除
            b.draw(g);
            blast.remove(b);
            l3--;
            i--;
            break;
        }
    }

    // 绘制所有敌机
    public void paintenemy(Graphics g) {

        for (int i = 0; i < enemy1.size(); i++) {
            Enemy1 e = enemy1.get(i);
            e.draw(g);

        }

        for (int i = 0; i < enemy2.size(); i++) {
            Enemy2 e = enemy2.get(i);
            e.draw(g);

        }

        for (int i = 0; i < enemy3.size(); i++) {
            Enemy3 e = enemy3.get(i);
            e.draw(g);

        }
    }

    // 绘制A类敌机子弹
    public void paintenemybullets(Graphics g) {

        for (int i = 0; i < enemybullet.size(); i++) {
            Enemybullet eb = enemybullet.get(i);
            eb.draw(g);

        }
    }

    // 绘制英雄机子弹
    public void paintherobullets(Graphics g) {

        for (int i = 0; i < herobullet.size(); i++) {
            Herobullet hb = herobullet.get(i);
            hb.draw(g);
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    // 键盘按下
    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
        case KeyEvent.VK_UP:
            up = true;
            break;
        case KeyEvent.VK_DOWN:
            down = true;
            break;
        case KeyEvent.VK_LEFT:
            left = true;
            break;
        case KeyEvent.VK_RIGHT:
            right = true;
            break;
        case KeyEvent.VK_Z:
            VK_Z = true;
            break;
        case KeyEvent.VK_X:
            VK_X = true;
            break;
        case KeyEvent.VK_ENTER:
            VK_ENTER = true;
            break;
        default:
            break;

        }
        repaint();
    }

    // 键盘释放
    @Override
    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()) {
        case KeyEvent.VK_UP:
            up = false;
            break;
        case KeyEvent.VK_DOWN:
            down = false;
            break;
        case KeyEvent.VK_LEFT:
            left = false;
            break;
        case KeyEvent.VK_RIGHT:
            right = false;
            break;
        case KeyEvent.VK_Z:
            VK_Z = false;
            break;
        case KeyEvent.VK_X:
            VK_X = false;
            break;
        case KeyEvent.VK_ENTER:
            VK_ENTER = false;
            break;
        default:
            break;
        }
    }
}

资源下载地址:http://download.csdn.net/detail/weixin_38179324/9913390

  • 35
    点赞
  • 137
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值