坦克大战项目需求文档

01_坦克大战案例演示
 * 略
    1. 创建游戏窗体
    2. 绘制地图(阻碍物,坦克)
    3. 坦克可以移动,也可以发射子弹
    4. 碰撞(坦克和阻碍物的碰撞,子弹和阻碍物的碰撞,子弹和子弹碰撞)

02_准备工作之新建工作空间
 * 步骤
     * 1.新建一个工作空间.
     * 2.把工作空间的字符编码改为: UTF-8.
     * 3.对工作空间进行基本设置.
         * 显示行号
         * 更改字体大小.
     * 注意:
         * 坦克大战案例要求大家使用的JDK版本必须是JDK1.8(或更高版本).


 03_准备工作之非抽象方法里面可以调用抽象方法

 04_坦克大战案例之坦克隐藏到草坪中
 * a. 先绘制坦克,在绘制草坪(扩展性不强,不推荐).  
 * b. 采用Comparator比较器接口的方式, 对集合中的元素按照渲染层级进行排序. 
     * 渲染层级越高,元素的顺序越靠后(Element#getOrder()).
     * 此处用CopyOnWriteArrayList集合实现.

05_坦克大战案例之坦克和砖墙的碰撞检测
 * 步骤

    a. MyTank#checkHit(Steel steel); 在该方法中完成功能代码. 
       定义两个成员变量用于记录当前坦克不能移动的方向(badDirection)和碰撞的最小间隙(badSpeed),
       获取铁墙的坐标以及宽高, 同时获取当前坦克的坐标和宽高,
       预判坦克的下一步动作, 然后调用CollisionUtils#isCollisionWithRect();进行碰撞检测, 并用flag记录返回结果,
       判断flag的值, 如果为true,就将当前方向赋值给badDirection,并且根据坦克当前坐标计算 badSpeed的值,
       如果flag的值为false, 说明没碰上, 就重置badDirection和badSpeed的值, 并返回flag的值.
    b. MyTank#move(Direction direction); 在该方法中优化代码
       判断badDirection是否不等于空, 并且badDirection和direction是否相等,
       如果为true,说明撞上了, 就根据坦克方向将当前坦克坐标移动最小间隙, 并提示"不可移动",然后return, 如果为false,说明没撞上,什么都不操作,方法继续往下执行,
       判断传过来的方向和坦克当前方向是否相同,如果不相同,就将传过来的方向赋值给坦克方向,然后return, 如果相同,什么都不操作,方法继续往下执行,
       坦克正常移动代码(根据坦克方向,进行对应的坐标计算, 注意要有坦克坐标的越界处理)
    c. GameWindow#OnDisplayUpdate()中做测试, 嵌套遍历集合, 判断当前遍历到的元素是否分别是: 坦克和铁墙,
       如果是,就调用MyTank#checkHit(Steel steel);校验是否碰撞上, 如果碰撞上就直接break, 否则什么都不操作.


06_坦克大战案例之抽取接口,具有移动功能的事物和具有阻挡功能的事物
 * 步骤

    a. 在包com.itheima.game.business中定义两个接口: Moveable, Blockable.
       其中Moveable接口中定义一个方法: public abstract boolean checkHit(Blockable block); 用于校验是否碰撞上.
    b. 让MyTank类实现Moveable接口, 然后将MyTank#checkHit();方法的形参类型从Steel类改为Blockable接口类型(对应方法体的代码修改下即可).
    c. 让Steel类,Wall类,Water类都实现Blockable接口.
    d. 修改下GameWindow#OnDisplayUpdate()方法中关于"移动功能事物和阻挡功能事物碰撞校验"的代码.
       从之前校验MyTank和Steel, 改为校验Moveable和Blockable.
    

07_坦克大战案例之子弹和铁墙的碰撞检测
 * 步骤

    a. 在Bullet#checkAttack(Steel steel);方法中做校验, 获取到铁墙的坐标和宽高以及子弹的坐标和宽高, 然后调用CollisionUtils#isCollisionWithRect()判断是否撞上.
       撞上返回true, 没有撞上返回false.
    b. 在GameWindow#onDisplayUpdate();方法中调用, 循环嵌套遍历list集合, 然后判断当前遍历到的元素是否是子弹和铁墙,
       如果是,就调用Bullet#checkAttack()校验有没有碰上, 没有碰上就什么都不操作.
       如果碰上了, 针对于子弹: 销毁.  针对于铁墙: 给一个响应(调用Steel#showAttack()返回一个爆炸物, 创建爆炸物对象的时候,要播放声音)
       注意: 遗留的三个小Bug(爆炸物的坐标, 爆炸物的绘制次数, 爆炸图片的绘制个数)最后解决.


08_坦克大战案例之抽取接口,具有攻击能力的事物和具有挨打能力的事物
 * 步骤
    a. 在com.itheima.game.business包中创建两个接口: Attackable(攻击能力)和Hitable(阻挡能力).
       其中Attackable接口中定义一个方法: public abstract boolean checkAttack(Hitable hitable); 用于校验攻击事物是否打上挨打事物
       其中Hitable接口中定义一个方法: public abstract Blast showAttack();
    b. 让Bullet类实现Attackable接口, 然后将Bullet#checkAttack();方法的形参类型从Steel类改为Hitable接口类型(对应方法体的代码修改下即可).
    c. 让Steel类,Wall类都实现Hitable接口.
    d. 修改下GameWindow#OnDisplayUpdate()方法中关于"攻击功能事物和挨打功能事物碰撞校验"的代码.
       从之前校验Bullet和Steel, 改为校验Attackable和Hitable.
    

08_坦克大战案例之优化爆炸物的坐标问题(即: 按顺序逐步解决第15步遗留的三个小Bug)
 * 在Blast类的构造方法中完成代码, 根据挨打事物的坐标和宽高以及爆炸物的宽高, 计算爆炸物的坐标.

09_坦克大战案例之优化爆炸图片的绘制个数
 * 步骤:
     * 在Blast类的构造方法中完成代码, 即: 构造方法加一个参数boolean flag, 
     * 值为true代表挨打状态(绘制一部分爆炸图片即可),
     * 值为false, 代表销毁状态, 绘制所有的爆炸图片即可.


10_坦克大战案例之提取接口, 具有销毁功能的事物
 *步骤
    
    a. 在com.itheima.game.business包中创建一个接口: Destroyable(销毁能力).
       Destroyable接口中定义两个方法: 
        public abstract boolean isDestroy(); 用于校验销毁事物是否 需要销毁
        public abstract Blast showDestroy(); 用于销毁事物销毁时, 返回一个爆炸物对象
    b. 让Bullet类,Blast类,Steel类,Wall类都实现Destroyable接口, 重写接口中的两个方法.
       针对于showDestroy()方法, 类Steel,Wall重写该方法时返回一个爆炸物对象, 类Bullet,Blast重写该方法时, 返回一个null即可.
    d. 修改下GameWindow#OnDisplayUpdate()方法中关于"销毁功能事物 销毁时的"的代码.
       从之前校验Bullet或者Steel, 改为校验Destroyable.

分析:
    敌方坦克和自己的坦克都有挨打的能力和显示爆炸物的能力

猜你喜欢

转载自blog.csdn.net/Kfie66/article/details/81569823