之前的程序,一直没时间改进优化。因为看了网上慕课,有更好的架构。用更加通用的类的设计,可以实现同一个架构,做出不同的游戏。
慕课案例中的写法,也只是方法之一,仍然有一些地方可以改进。比如,加入状态,加入消息队列。用消息和事件的解析,触发一个功能。
大型游戏,各式各样的功能都是一个消息的解析、然后触发事件。所谓事件触发器。
一个更好的案例分析要点如下:
通用的父类、模式(不仅仅是设计模式中的23种方案)
通用模块:
判断两个矩形是否碰撞
业务逻辑:
ArrayList<Element>
一个大数组存放所有游戏单元
(坦克,子弹,墙,铁皮,水,草地)
通用父类:Element
具体子类domain:子弹,墙,铁皮,水,草地
没有独立的坦克数组,没有独立的子弹数组
游戏功能:
五个接口:1.可以发出攻击2.被攻击
3.被销毁(草地,水)4.可移动 5.有阻挡功能
domain实体模型,类的设计
通用父类public abstract class Element
其他类:
public class MyTank extends Element implements Moveable
public class Bullet extends Element
implements Attackable, Destroyable
public class Wall extends Element
implements Blockable, Hitable, Destroyable
public class Grass extends Element
public class Water extends Element implements Blockable
接口的判断e1 instanceof Moveable
事件的触发: 调接口函数checkHit.
for (Element e1 : list) {
for (Element e2 : list) {
// 如果e1是 具有移动功能的事物, 并且 e2 是具有阻挡功能的事物, 就校验他们有没有碰撞上.
if (e1 instanceof Moveable && e2 instanceof Blockable) {
boolean flag = ((Moveable) e1).checkHit((Blockable) e2);
// 如果碰上了, 直接return即可
if (flag) {
break;
}
}
坦克的移动
坦克类(带接口 Moveable )的checkHit实现:
判断是否碰到了目标(带接口Blockable),如果碰到,求坦克和障碍物的最小距离。
public boolean checkHit(Blockable block) {
Element element = (Element)block; //因为Blockable接口有几个子类: Wall,Steel,Water, 而这些类也是Element类的子类
//获取铁墙的坐标和宽高
int x1 = element.x;
int y1 = element.y;
int w1 = element.width;
int h1 = element.height;
//方案1:预判坦克的下一步坐标
//方案2:方向也可以用其他方式表示[1,0]右 [-1,0]下,等等
int x2 = x;
int y2 = y;
switch (direction) {
case UP:
y2 -= speed;
break;
case DOWN: //... ...
}
//通过工具类 CollisionUtils工具类校验 有没有碰撞上, 移动要预判坦克的下一步坐标, 然后用预判的坐标做校验
boolean flag = CollisionUtils.isCollsionWithRect(x1, y1, w1, h1, x2, y2, width, height);
//如果碰上了, 就用badDirection变量记录 坦克不能移动的方向
//如果碰上了,求坦克和障碍物的最小距离badSpeed
if (flag) {
//说明撞上了, 获取坦克不能移动的方向, 和 最小间隙值
badDirection = direction;
//一定要注意: 最小间隙的计算方式: 是通过 坦克当前的坐标计算的, 千万不要用预判的坐标去算, 因为预判的坐标只是预判, 坦克并没有往预判的这个位置移动呢.
switch (direction) {
case UP:
badSpeed = y - y1 - h1; //坦克当前的y轴 - 铁墙的y轴 - 铁墙的高度
break;
case DOWN:
//... ...
}
} else {
//说明没有撞上, 对badDirection变量, badSpeed变量进行重置
badDirection = null;
badSpeed = 0;
}
//不管有没有碰撞上, 都要返回flag的值
return flag;
}
子弹和目标,也是两个接口的检测,然后触发对应的事件。我在视频中介绍。
多录视频,我都怕自己忘了。
视频讲解,下载地址:
链接: https://pan.baidu.com/s/13zTj06nhDTxPFkDcOEcCKw 提取码: wfap