飞机大战学习总结

一.游戏窗体的建立。

一款游戏肯定是设立在一个基础的窗体上的,首先我们就需要一个能装下所有游戏组件的界面。

public class Gameui extends JFrame {
    public void iniUI() {
        //界面绘制
        this.setTitle("游戏界面");
        this.setSize(1000, 800);
        this.setDefaultCloseOperation(3);
        this.setLayout(new FlowLayout());
        this.setVisible(true);
        Graphics g = this.getGraphics();
}

    @Override
    public void paint(Graphics g) {
        super.paint(g);
    }

    public static void main(String[] args) {
        Gameui gu=new Gameui();
        gu.iniUI();
    }
}

二.创建一个所有角色的共有接口

package textgame;

import java.awt.*;
import java.util.ArrayList;

//所有角色共有接口的定义
public interface IRole {
    //移动
    public void move();
    //自我重绘
    public void paintself(Graphics G);
    //碰撞检测


}

三.创建一个画布类,通过双缓冲的方法将所有元素画在画布上。

public class ThreadDraw extends Thread{
    private ArrayList<IRole> ros;
    private ArrayList<IRole> remove;
    private Graphics g;
    public int count=1;

    public ThreadDraw (ArrayList<IRole> ros, Graphics g,ArrayList<IRole> remove){
        this.ros=ros;
        this.g=g;
        this.remove=remove;

    }

    @Override
    public void run() {
        while (true){
            BufferedImage bi=new BufferedImage(1000,800,BufferedImage.TYPE_INT_RGB );
            Graphics gb= bi.getGraphics();
            for(int i=0;i<this.ros.size();i++){
                IRole ro= ros.get(i);
                ro.move();
                ro.paintself(gb);
            }
            ros.removeAll(remove);
            g.drawImage(bi,0,0,1000,800,null);
            count++;
            System.out.println(" "+count);
            try {
                Thread.sleep(20);
            }catch (Exception ef){}

        }

    }

四.创建一个公共队列来存放所有组件里的元素,利用生成消费者的模型,便于对所有要添加删除的元素进行处理。

ArrayList<IRole> ros=new ArrayList<IRole>();
ThreadDraw TD=new ThreadDraw(ros,g,remove);
TD.start();
playerObj plane= new playerObj(this,ros,player,enemy,bullet,remove);
ros.add(plane);
player.add(plane);

五.在此基础下添加所需要的组件如敌机,子弹,玩家。

以玩家为例:

public class tankObj implements IRole {
    private int x = 500, y = 300, width, height;
    private ArrayList<IRole> ros;
    private ArrayList<tankObj> player;
    private ArrayList<enemyObj> enemylist;
    private ArrayList<bulletObj> bulletlist;
    private ArrayList<IRole> removelist;
    public double speed;
    private ImageIcon tank = new ImageIcon("imgs/Playplane.png");
    private Image im = tank.getImage();
    public JFrame jf;

    public tankObj(JFrame jf, ArrayList<IRole> ros, ArrayList<tankObj> player, ArrayList<enemyObj> enemy, ArrayList<bulletObj> bullet, ArrayList<IRole> remove) {
        this.jf = jf;
        this.ros = ros;
        this.player = player;
        this.bulletlist = bullet;
        this.enemylist = enemy;
        this.removelist = remove;
    }

    @Override
    public void move() {
        this.jf.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                x = e.getX();
                y = e.getY();

            }
        });


    }

    @Override
    public void paintself(Graphics g) {
        g.drawImage(im, x, y, width = 50, height = 50, null);
        for (enemyObj enemy : enemylist) {
            if ((Math.abs(this.x - enemy.x) < enemy.widht|| Math.abs(enemy.x - this.x) < this.width) && (Math.abs(enemy.y - this.y) < this.height || Math.abs(this.y - enemy.y) < enemy.height) ) {
                this.x=-1000;
                this.y=-1000;
                enemy.x=-1000;
                enemy.y=-1000;
                explore ep=new explore(this.x,this.y);
                ep.paintself(g);
                ros.add(ep);
                removelist.add(ep);
                removelist.add(this);
                removelist.add(enemy);

            }
        }

    }
}

因为角色是随鼠标移动所以移动方法里使用的是利用鼠标监听器获得鼠标拖动的位置x,y。再不断的将这个更新的x和y更新给队列,在画板上画出新位置的飞机。

同时在绘制自身的方法中可以通过对两种类队列中的元素位置信息进行判断是否发生了碰撞,再将发生碰撞的元素移除屏幕后再将该元素添加到removelist中好方便后续的删除,以减少内容占用。

六.爆炸效果的实现

通过创建一个image类型的静态数组将一连串的图片存入其中,再遍历数组绘制实现爆炸效果。

public class explorerObj extend IRole{
public int x,y;
public explorerObj (int x,inty){
this.x=x;
this.y=y;
}
static Image[] explodePic=new Image[12];
int explodeCount=0;
static{
for(int i=0;i<explodePic.length;i++){
explodePic[i]=Toolkit.getDefowltToolkit().getImage("image/explode/e"+(i+1)+"gif");
}
}
 public void move(){
}
  public void paintself(Graphics g) {
super.paintself(g);
if(explodeCount<16){
super.img=explodePic[eexplodeCount]
explodeCount++;
}
 g.drawImage(explodePic[explodeCount], x, y, width = 50, height = 50, null);
}
}

再在碰撞位置创建爆炸对象再添加到爆炸集合当中再添加到移除队列中去。实现爆炸效果的实现。

7.添加敌方BOSS单位。

以一个BOSS为例:创建BOSS类与其他类创建类似,添加BOSS需要的图片,重写接口方法,这里需要注意的是,因为BOSS是需要游戏进行一段时候后才能出来,我是以页面的绘制次数为count

if(count==1000&&(!ros.countains(boss1))){
ros.add(boss1);
}

剩下的就是在BOSS类中去补充所需要的常规方法,例如碰撞检测,爆炸。

需要注意的是这里的BOSS的移动方式是在被消灭前一直在窗口内活动。

所以在重新move方法时需要注意

public void move(){
if(y<150){
y+=2}else{
x=-speed;
if(x>800||x<10){
speed=-speed;
}}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值