(java项目)坦克大战 2.0

这个版本,只能算是一个雏形,把最基本的东西给完成了,不过,后面可添加的也不多。有一点,还是想去实现,那就是敌方坦克自己寻找对手!也就是游戏AI.

emmm, 什么时候可以了解一下这个AI。顺便学学python。

这个帖子只是为了贴上代码,对后续的代码作为优化和添加游戏AI做准备的。


1. 各类接口

package Event;
/*
 *具有攻击力的接口
 */
public interface Attackable {
    /*
     * 校验具有攻击力的实物, 和, 具有被攻击的实物,是否能撞在一起
     *
     */
    boolean checkAttack(Hitable hit);
}
package Event;
/*
 * 具有阻挡功能的实物
 */
public interface Blockable {

}
package Event;
/*
 * 能被销毁的类
 */
import domain.Blast;
/*
 * 销毁接口
 */
public interface Destoryable {
    /*
     * 判断是否需要销毁
     */
    boolean isDestoryable();
    
    /*
     * 销毁时,绘制爆炸物
     */
    Blast showDestory();
}
package Event;

import domain.Blast;
/*
 * 能被攻击的类
 */
public interface Hitable {
    Blast showAttack();
}
package Event;
/*
 * 具有移动功能的事物
 * 
 */
public interface Moveable {
    boolean checkHit(Blockable blockable);
}

2.各类游戏元素的父类

package domain;

/*
 * 父类:
 * 是砖墙,坦克,水墙等所有元素的抽象出来的抽象类
 */
public abstract class Element {
    /*
     * 属性
     * 坐标
     */
    protected int x;
    protected int y;
    //宽高
    protected int width;
    protected int hight;
    
    //构造函数
    //空参构造函数
    public Element() {super();}        //可以不写super(),java会自己调用,也就是调用抽象类的父类
    
    public Element(int x, int y) {
        this.x=x;        this.y=y;
    }
    
    /*
     * 绘制元素
     */
    public abstract void draw();
    
    /*
     * 设置元素的渲染级别,数字越高,渲染级别越高
     */
    public int getOrder() {return 0;}
}

坦克的父类

package domain;

import org.itheima.game.utils.CollisionUtils;

import Event.Blockable;
import Event.Destoryable;
import Event.Hitable;
import Event.Moveable;
/*
 * 所有坦克的父类\
 * 坦克具有移动,阻挡,被攻击,被销毁的功能
 * 
 */
public abstract class Tank extends Element implements Moveable, Blockable, Hitable,Destoryable{
    /*
     * 属性
     */
    //攻击力
    protected int power=1;
    //血量
    protected int blood=5;
    
    //坦克的移动方向
    protected Direction direction=Direction.UP;
    
    //每次移动的速度
    protected int speed=3;
    
    //记录最后一颗子弹的发射时间
    protected long lastTime;
    
    //记录坦克不能移动的方向
    protected Direction badDirection;
    
    //记录坦克碰撞的最小移动距离
    protected int badSpeed;
    
    
    /*
     * 构造函数
     */
    public Tank() {super();}
    public Tank(int x, int y) {super(x, y);}
    
    /*
     * 绘制坦克
     */
    public abstract void draw();
    
    /*
     * 发射子弹
     */
    public Bullet shot() {
        //思路:如歌最后一颗子弹  - 当前发射的时间  > 650ms 就发射子弹
        //获取当前时间
        long newTime=System.currentTimeMillis();
        if(newTime-lastTime<650) {
            return null;    //不发射子弹
        }else {
            lastTime=newTime;
            return new Bullet(this);        //谁调用了就是谁的子弹
        }
    }
    
    /*
     * 获取坦克的移动方向
     */
    public Direction getDirection() {return direction;}
    
    /*
     * 校验:移动物(坦克)是否与障碍物是否撞上
     */
    public boolean checkHit(Blockable block){
        Element e=(Element)block;
        int x1=e.x;
        int y1=e.y;
        int w1=e.width;
        int h1=e.hight;
        
        //预判坦克的坐标
        int x2=x;
        int y2=y;
        switch (direction) {
        case UP:
            y2-=speed;
            break;
        case DOWN:
            y2+=speed;
            break;
        case LEFT:
            x2-=speed;
            break;
        case RIGHT:
            x2+=speed;
            break;
        default:
            break;
        }
        boolean flag=CollisionUtils.isCollsionWithRect(x1, y1, w1, h1, x2, y2, width, hight);
        if(flag) {
            //说明预判可以撞上,不仅要记录不能移动的方向,还要记录最小间隙
            badDirection=direction;
            switch (direction) {
            case UP:
                badSpeed=y-y1-h1;
                break;
            case DOWN:
                badSpeed = y1 - y - hight;
                break;
            case LEFT:
                badSpeed = x - x1 - w1;
                break;
            case RIGHT:
                badSpeed = x1 - w1 - width;
                break;
            default:
                break;
            }
        }else {
            badDirection=null;        //没有撞上的话,就没有坏的方向
        }
        return flag;
    }
    
    /*
     * 销毁的方法
     */
    public boolean isDestory() {return blood<=0;}
    
    /*
     * 被销毁物,在被销毁时的表现。
     */
    public Blast showDestory() {return new Blast(this);}
    
    
}

各种游戏元素

package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;
import org.itheima.game.utils.SoundUtils;

import Event.Blockable;
import Event.Destoryable;
import Event.Hitable;

/*
 * 
 * 爆炸物类
 * 
 */
public class Blast extends Element implements Destoryable{
    /*
     * 属性
     */
    //1.图片
    private String[]arr= {"res/img/blast_1.gif", "res/img/blast_2.gif", "res/img/blast_3.gif", "res/img/blast_4.gif",
            "res/img/blast_5.gif", "res/img/blast_6.gif", "res/img/blast_7.gif", "res/img/blast_8.gif"};
    //2.定义变量,记录要绘制的图片索引
    private int index;
    
    //3.定义变量,记录是否需要销毁该爆炸物
    //true:销毁, false :不销毁
    private boolean isDestory;

    /*
     * 构造方法
     * 爆炸物的坐标依赖墙的坐标
     */
    public Blast(Hitable hit) {
        this(hit, false);
        try {
            SoundUtils.play("res/snd/blast.wav");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /*
     * flag :true表示挨打,绘制1~4的图片
     *         false 说明是销毁,绘制1~8的图片
     */
    public Blast(Hitable hit, boolean flag) {
        Element element=(Element)hit;
        //计算爆炸物的位置
        //获取墙的坐标和宽高
        int x1=element.x;
        int y1=element.y;
        int w1=element.width;
        int h1=element.hight;
        //获取爆炸物的宽度
        try {
            int size[]=DrawUtils.getSize("res/img/blast_1.gif");
            width=size[0];    hight=size[1];
            
            //计算爆炸物的坐标
            x=x1+(w1-width)/2;
            y=y1+(h1-hight)/2;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        if(flag) {
            arr=new String[] {"res/img/blast_1.gif", "res/img/blast_2.gif", "res/img/blast_3.gif", "res/img/blast_4.gif"};
            try {
                SoundUtils.play("res/snd/hit.wav");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    @Override
    public void draw() {
        // TODO Auto-generated method stub
        //定义变量,记录要绘制的图片的路径
        String res=arr[index++];
        if(index>=arr.length) {
            index=0;
            //说明爆炸物已经绘制过一次了可以销毁
            isDestory=true;
        }
        try {
            DrawUtils.draw(res, x, y);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    /*
     * 获取爆炸物的状态
     */
    public boolean isDestoryable() {
        // TODO Auto-generated method stub
        return isDestory;
    }
    /*
     * 销毁时,绘制销毁的爆炸物
     */
    public Blast showDestory() {return null;}
    
    
}
View Code
package domain;

import java.io.IOException;

import org.itheima.game.utils.CollisionUtils;
import org.itheima.game.utils.DrawUtils;
import org.itheima.game.utils.SoundUtils;

import Event.Attackable;
import Event.Destoryable;
import Event.Hitable;
import Grame.config;

/*
 * 子弹类,具有攻击能力,被销毁的能力
 */
public class Bullet extends Element implements Attackable, Destoryable {

    //记录子弹移动的方向
    private Direction direction;
    //记录子弹的速度
    private int speed=7;
    //定义变量,记录子弹所属的坦克
    private Tank tank;
    
    
    /*
     * 构造函数(non-Javadoc)
     * @see Event.Destoryable#isDestoryable()
     */
    //子弹的坐标依赖坦克
    public Bullet(Tank tank) {
        // TODO Auto-generated constructor stub
        super();
        //用变量tank记录,子弹所属的坦克
        this.tank=tank;
        
        //获取坦克的坐标,宽高,方向
        int tankX=tank.x;
        int tankY=tank.y;
        int tankWidth=tank.width;
        int tankHight=tank.hight;
        direction=tank.getDirection();
        
        //获取子弹的宽高
        try {
            int size[]=DrawUtils.getSize("res/img/bullet_u.gif");
            width=size[0];        hight=size[1];
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        //计算子弹的坐标
        switch (direction) {
        case UP:
            x = tankX + (tankWidth - width)/2;
            y = tankY - hight / 2;
            break;
        case DOWN:
            x = tankX + (tankWidth - width)/2;
            y = tankY + tankHight - hight /2;
            break;
        case LEFT:
            x=tankX-width;
            y=tankY+(tankHight-hight)/2;
            break;
        case RIGHT:
            x = tankX + tankWidth - width / 2;
            y = tankY + (tankHight - hight)/2;
            break;
        default:
            break;
        }
        
        try {
            SoundUtils.play("res/snd/fire.wav");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    /* 出边界
     * 销毁子弹  true:销毁,false:不销毁(non-Javadoc)
     * @see Event.Destoryable#isDestoryable()
     */
    @Override
    public boolean isDestoryable() {
        // TODO Auto-generated method stub
        if(x<0||x>config.WIDTH||y<0||y>config.HIGHT) return true;
        return false;
    }

    /*
     * 子弹销毁时的反映(non-Javadoc)
     * @see Event.Destoryable#showDestory()
     */
    @Override
    public Blast showDestory() {
        // TODO Auto-generated method stub
        return null;
    }
    /*校验是否与阻碍物碰上
     * (non-Javadoc)
     * @see Event.Attackable#checkAttack(Event.Hitable)
     */
    @Override
    public boolean checkAttack(Hitable hit) {
        // TODO Auto-generated method stub
        Element e=(Element)hit;
        int x1=e.x;
        int y1=e.y;
        int w1=e.width;
        int h1=e.hight;
        //第一个矩形:障碍物,第二个撞击物:子弹
        return CollisionUtils.isCollsionWithRect(x1, y1, w1, h1, x, y, width, hight);
    }

    
    /*
     * 绘制子弹(non-Javadoc)
     * @see domain.Element#draw()
     */
    @Override
    public void draw() {
        // TODO Auto-generated method stub
        String res="";
        //判断坦克方向
        switch (direction) {
        case UP:
            res = "res/img/bullet_u.gif";
            y-=speed;
            break;
        case DOWN:
            res = "res/img/bullet_d.gif";
            y += speed;
            break;
        case LEFT:
            res = "res/img/bullet_l.gif";
            x -= speed;
            break;
        case RIGHT:
            res = "res/img/bullet_r.gif";
            x += speed;
            break;
        default:
            break;
        }
        
        try {
            DrawUtils.draw(res, x, y);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /*
     * 获取子弹所属坦克
     */
    public Tank getTank() {
        return tank;
    }
}
View Code
package domain;
/*
 * 枚举四个方向
 */
public enum Direction {
    UP,DOWN,LEFT,RIGHT;
}
View Code
 
package domain;

import java.io.IOException;
import java.util.Random;

import org.itheima.game.utils.DrawUtils;

import Grame.config;

public class EnemyTank extends Tank{

    /*
     * 属性(non-Javadoc)
     * @see Event.Hitable#showAttack()
     */
    public EnemyTank(int x, int y) {
        super(x, y);
        try {
            int size[]=DrawUtils.getSize("res/img/enemy_u.gif");
            width=size[0];    hight=size[1];
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public EnemyTank() {super();}
    
    
    @Override
    public Blast showAttack() {
        // TODO Auto-generated method stub
        //扣血
        blood-=new Mytank().power;
        return new Blast(this, true);
    }

    @Override
    public boolean isDestoryable() {
        // TODO Auto-generated method stub
        return blood<=0;
    }

    /*
     * 坦克的绘制(non-Javadoc)
     * @see domain.Tank#draw()
     */
    @Override
    public void draw() {
        // TODO Auto-generated method stub
        String res="";
        //判断坦克的方向
        switch (direction) {
        case UP:
            res = "res/img/enemy_u.gif";
            break;
        case DOWN:
            res = "res/img/enemy_d.gif";
            break;
        case LEFT:
            res = "res/img/enemy_l.gif";
            break;
        case RIGHT:
            res = "res/img/enemy_r.gif";
            break;
        default:
            break;
        }
        
        try {
            DrawUtils.draw(res, x, y);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    /*
     * 随机获取敌方坦克的方向
     */
    public Direction getRandDirection() {
        int num=new Random().nextInt(4);
        switch (num) {
        case 0:
            return Direction.UP;
        case 1:
            return Direction.DOWN;
        case 2:
            return Direction.LEFT;
        case 3:
            return Direction.RIGHT;
        default:
            break;
        }
        return Direction.UP;
    }
    
    /*
     * 移动
     */
    public void move() {
        //如果传过来的方向,与坦克不能移动的方向相同,则移动最小距离
        if(direction==badDirection) {
            switch (direction) {
            case UP:
                y-=badSpeed;
                break;
            case DOWN:
                y+=badSpeed;
                break;
            case LEFT:
                x-=badSpeed;
                break;
            case RIGHT:
                x+=badSpeed;
                break;
            default:
                break;
            }
            //不能移动就随机换一下方向
            direction=getRandDirection();
            return ;
        }
        
        switch (direction) {
        case UP:
            y-=speed;
            break;
        case DOWN:
            y+=speed;
            break;
        case LEFT:
            x-=speed;
            break;
        case RIGHT:
            x+=speed;
            break;
        default:
            break;
        }
        
        //边界处理
        if(x<0) {
            x=0;
            direction=getRandDirection();
        }
        if(x>config.WIDTH-64) {
            x=config.WIDTH-64;
            direction=getRandDirection();
        }
        if(y<0) {
            y=0;
            direction=getRandDirection();
        }
        if(y>config.HIGHT-64) {
            y=config.HIGHT-64;
            direction=getRandDirection();
        }
    }
}
View Code
 
package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;
/*
 * 草坪
 */
public class Grass extends Element{

    public Grass(int x, int y) {
        // TODO Auto-generated constructor stub
        super(x, y);
        //获取宽高
        try {
            int size[]=DrawUtils.getSize("res/img/grass.gif");
            width=size[0];        hight=size[1];
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    @Override
    public void draw() {
        // TODO Auto-generated method stub
        try {
            DrawUtils.draw("res/img/grass.gif", x, y);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /*
     * 修改草坪的渲染级别
     */
    public int getOrder() {return 1;}
}
View Code
package domain;

import java.io.IOException;

import javax.swing.plaf.DimensionUIResource;

import org.itheima.game.utils.DrawUtils;

import Grame.config;

public class Mytank extends Tank{
    public Mytank(int x, int y) {
        // TODO Auto-generated constructor stub
        super(x, y);
        //初始化速度
        speed=30;    power=2;    blood=10;
        
        //获取坦克的宽高
        try {
            int size[] = DrawUtils.getSize("res/img/tank_u.gif");
            width=size[0];
            hight=size[1];
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public Mytank() {
        // TODO Auto-generated constructor stub
        super();
        power=2;
    }
    
    
    /*
     * 挨打方法(non-Javadoc)
     * @see Event.Hitable#showAttack()
     */
    @Override
    public Blast showAttack() {
        // TODO Auto-generated method stub
        //扣血
        blood-=new EnemyTank().power;
        return new Blast(this, true);
    }

    @Override
    public boolean isDestoryable() {
        // TODO Auto-generated method stub
        return blood<=0;
    }

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        String res="";
        switch (direction) {
        case UP:
            res = "res/img/tank_u.gif";
            break;
        case DOWN:
            res = "res/img/tank_d.gif";
            break;
        case LEFT:
            res = "res/img/tank_l.gif";
            break;
        case RIGHT:
            res = "res/img/tank_r.gif";
            break;
        default:
            break;
        }
        try {
            DrawUtils.draw(res, x, y);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /*
     * 坦克的移动
     */
    public void move(Direction direction) {
        //如果传过来的方向和坦克不能动的方向一致,则移动最小
        if(badDirection==direction) {
            //移动最小间距
            switch (direction) {
            case UP:
                y -= badSpeed;
                break;
            case DOWN:
                y += badSpeed;
                break;
            case LEFT:
                x -= badSpeed;
                break;
            case RIGHT:
                x += badSpeed;
                break;
            default:
                break;
            }
            return ;
        }
        
        //刷新方向,用户按下的方向传给坦克:坦克的方向
        if(this.direction!=direction)
        {
            this.direction=direction;
            return ;
        }
        
        switch (direction) {
        case UP:
            y -= speed;
            break;
        case DOWN:
            y += speed;
            break;
        case LEFT:
            x -= speed;
            break;
        case RIGHT:
            x += speed;
            break;
        default:
            break;
        }
        
        /*
         * 边界处理
         */
        if(x<0) {x=0;}
        if(x>config.WIDTH-64) {x=config.WIDTH-64;}
        if(y<0) {y=0;}
        if(y>config.HIGHT-64) {y=config.HIGHT-64;}
    }
    
}
View Code
 
package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;

import Event.Blockable;
import Event.Destoryable;
import Event.Hitable;

public class Steel extends Element implements Blockable, Hitable, Destoryable{
    /*
     * 属性:
     */
    //1.血量
    private int blood=5;
    
    public Steel(int x, int y) {
        super(x, y);
        
        //获取铁墙的宽高
        try {
            int size[]=DrawUtils.getSize("res/img/steel.gif");
            width=size[0];
            hight=size[1];
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    

    

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        try {
            DrawUtils.draw("res/img/steel.gif", x, y);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /*
     * 挨打后的反映(non-Javadoc)
     * @see Event.Hitable#showAttack()
     */
    @Override
    public Blast showAttack() {
        // TODO Auto-generated method stub
        blood--;
        return new Blast(this,true);
    }
    
    /*
     * 销毁时响应的动作(non-Javadoc)
     * @see Event.Destoryable#showDestory()
     */
    @Override
    public Blast showDestory() {
        // TODO Auto-generated method stub
        return new Blast(this);
    }
    
    
    /*
     * 销毁铁墙(non-Javadoc)
     * @see Event.Destoryable#isDestoryable()
     */
    @Override
    public boolean isDestoryable() {
        // TODO Auto-generated method stub
        return blood<=0;
    }
}
package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;

import Event.Blockable;
import Event.Destoryable;
import Event.Hitable;

public class Wall extends Element implements Hitable, Blockable, Destoryable{

    //血量
    private int blood=3;
    
    /*
     * 含参数的构造函数
     */
    public Wall(int x, int y) {
        // TODO Auto-generated constructor stub
        super(x, y);
        
        //获取宽度,长度
        try {
            int size[]=DrawUtils.getSize("res/img/wall.gif");
            width=size[0];
            hight=size[1];
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    /*
     *绘制
     * @see domain.Element#draw()
     */
    @Override
    public void draw() {
        try {
            DrawUtils.draw("res/img/wall.gif", x, y);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /*
     * 挨打
     * Blast爆炸类
     */
    public Blast showAttack() {
        blood--;        //挨打一次血量减少
        return new Blast(this, true);
    }
    
    /*
     * 销毁判断,血量小于等于0时,就销毁
     */
    public boolean isDestoryable() {return blood<=0;}
    
    /*
     * 销毁响应动作
     */
    public Blast showDestory() {return new Blast(this);}

}
package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;

import Event.Blockable;

public class Water extends Element implements Blockable{

    public Water(int x, int y) {
        super(x, y);
        try {
            int size[]=DrawUtils.getSize("res/img/water.gif");
            width=size[0];    hight=size[1];
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    @Override
    public void draw() {
        try {
            DrawUtils.draw("res/img/water.gif", x, y);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
package Grame;

public class APP {
        /*
         * 游戏的主入口,所有代码的主入口
         */
    public static void main(String[] args) {
        //绘制窗口
        MyWindows gr=new MyWindows(config.TITLE, config.WIDTH, config.HIGHT, config.PFS);
        
        //开始游戏
        gr.start();
        
    }
    
}
 
 
package Grame;

public interface config {
    String TITLE="坦克大战";
    int WIDTH=64*15;
    int HIGHT=64*10;
    int PFS=50;
}
package Grame;

import java.awt.HeadlessException;
import java.awt.Window;
import java.io.IOException;
import java.nio.file.Watchable;
import java.util.Comparator;
import java.util.concurrent.CopyOnWriteArrayList;

import org.itheima.game.utils.DrawUtils;
import org.itheima.game.utils.SoundUtils;
import org.lwjgl.input.Keyboard;
import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID;

import Event.Attackable;
import Event.Blockable;
import Event.Destoryable;
import Event.Hitable;
import Event.Moveable;
import domain.Blast;
import domain.Bullet;
import domain.Direction;
import domain.Element;
import domain.EnemyTank;
import domain.Grass;
import domain.Mytank;
import domain.Steel;
import domain.Tank;
import domain.Wall;
import domain.Water;


/*
 * 游戏窗口类
 * 
 */
public class MyWindows extends org.itheima.game.Window{

    //定义:集合,存储元素
            //CopyOnWeiteArrayList 可以解决并发修改异常的集合
            CopyOnWriteArrayList<Element>list=new CopyOnWriteArrayList<>();
            //创建坦克对象
            Mytank mt;
            //创建敌方坦克
            EnemyTank et1;
            EnemyTank et2;
    
    public MyWindows(String title, int width, int height, int fps) {super(title, width, height, fps);}

    /*
     * 绘制窗口时运行
     */
    @Override
    protected void onCreate() {
        //播放开始音乐
        try {
            SoundUtils.play("res/snd/start.wav");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        //创建砖墙
        for(int i=0;i<config.WIDTH/64-1;++i) {
            Wall wall=new Wall(i*64, 64);
            addElement(wall);
        }
        //创建水墙
        for(int i=1;i<config.WIDTH/64;++i) {
            Water water=new Water(i*64, 64*3);
            addElement(water);
        }
        //绘制铁墙
        for(int i=0;i<config.WIDTH/64-1;++i) {
            Steel steel=new Steel(i*64, 64*5);
            addElement(steel);
        }
        //创造草坪
        for(int i=1;i<config.WIDTH/64;++i) {
            Grass grass=new Grass(i*64, 64*7);
            addElement(grass);
        }
        
        
        //创造己方坦克
        mt=new Mytank(config.WIDTH/2-32, config.HIGHT-64);
        addElement(mt);
        //创建敌方坦克
        et1=new EnemyTank(0, 0);
        et2=new EnemyTank(config.WIDTH-64, 0);
        addElement(et1);
        addElement(et2);
    }

    //鼠标事件
    @Override
    protected void onMouseEvent(int key, int x, int y) {
        // TODO Auto-generated method stub
        
    }

    //键盘事件
    @Override
    protected void onKeyEvent(int key) {
        // TODO Auto-generated method stub
        switch (key) {
        case Keyboard.KEY_UP:
            mt.move(Direction.UP);
            break;
        case Keyboard.KEY_DOWN:
            mt.move(Direction.DOWN);
            break;
        case Keyboard.KEY_LEFT:
            mt.move(Direction.LEFT);
            break;
        case Keyboard.KEY_RIGHT:
            mt.move(Direction.RIGHT);
            break;
        case Keyboard.KEY_SPACE:    //回车键
            Bullet shot=mt.shot();        //发射子弹
            //对子弹进行非空校验
            if(shot!=null) {
                addElement(shot);
            }
            break;
        default:
            break;
        }
    }

    //事实刷新
    @Override
    protected void onDisplayUpdate() {
        // TODO Auto-generated method stub
        //如果己方坦克已经销毁,或者敌方坦克都销毁,则游戏结束
        if(mt.isDestory()||(et1.isDestory()&&et2.isDestory())) {
            list.clear();
            //绘制结束图片
            try {
                DrawUtils.draw("res/img/gameover.gif", (config.WIDTH-96)/2, (config.HIGHT-96)/2);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            //停止所有音乐
            SoundUtils.stop("res/snd/fire.wav");
            
            return;
        }
        
        //绘制元素
        for(Element e:list) {
            e.draw();
        }
        
        //调用敌方坦克的随机移动的功能
        for(Element e:list) {
            if(e instanceof EnemyTank) {
                //如果是敌方坦克,就随机移动
                ((EnemyTank)e).move();
                
                //如果是敌方坦克,就调用其发射子弹的能力
                Bullet shot=((EnemyTank)e).shot();
                if(shot!=null) {
                    addElement(shot);
                }
            }
        }
        
        //销毁出界子弹
        for(Element e:list) {
            //如果是子弹
            if(e instanceof Bullet) {
                //判断子弹是否出界
                boolean flag=((Bullet)e).isDestoryable();
                if(flag) {
                    list.remove(e);
                }
            }
        }
        
        //销毁所有需要销毁的实物
        for(Element e:list) {
            //判断事物是否需要销毁
            if( e instanceof Destoryable) {
            boolean blast=((Destoryable)e).isDestoryable();
            if(blast) {
                //说明事物需要销毁
                //1.绘制销毁时的爆炸物
                Blast blast2=((Destoryable)e).showDestory();
                if(blast2!=null) {
                    addElement(blast2);
                }
                
                //消除该事物
                list.remove(e);
                }
            }
        }
        
        /*
         * 校验:运动物体 与 障碍物 的碰撞
         */
        for(Element e1:list) {
            for(Element e2:list) {
                if(e1!=e2&&e1 instanceof Moveable&&e2 instanceof Blockable) {
                    //说明 e1运动物  与 e2 障碍物 
                    boolean flag=((Moveable)e1).checkHit((Blockable)e2);
                    if(flag) {        //说明碰撞了
                        break;
                    }
                }
            }
        }
        
        /*
         * 攻击者 与 被攻击者 是否碰撞
         */
        for(Element e1: list) {
            for(Element e2: list) {
                if(e1 instanceof Attackable&&e2 instanceof Hitable) {
                    //说明  e1 攻击者 e2 被攻击者
                    boolean flag=((Attackable)e1).checkAttack((Hitable)e2);
                    if(flag) {
                        //校验:是己方坦克发过来的子弹,是则不能攻击,否则能产生攻击
                        if(((Bullet)e1).getTank().getClass()==e2.getClass()) {
                            continue;
                        }
                        
                        //校验:能不能攻击敌军
                        //子弹销毁
                        list.remove(e1);
                        //被攻击者受到攻击,绘制出爆炸物
                        Blast blast=((Hitable)e2).showAttack();
                        addElement(blast);
                    }
                }
            }
        }
        
    }

    
    
    /*
     * 添加元素
     */
    public void addElement(Element e) {
        list.add(e);
        
        //对集合按照渲染级别进行排序
        list.sort(new Comparator<Element>() {

            @Override
            public int compare(Element o1, Element o2) {
                // TODO Auto-generated method stub
                return o1.getOrder()-o2.getOrder();
            }
        });
    }

    
}
 

猜你喜欢

转载自www.cnblogs.com/ALINGMAOMAO/p/9862239.html
今日推荐