游戏规则:
在桌面弹球游戏中,玩家通过控制一个可以左右移动的挡板去阻止弹球落地。
当弹球与挡板碰撞,发生反弹后,如果与砖块碰撞,该砖块就会被消除掉。注意其中有一些砖块是有魔法的。
当有魔法的砖块被消除掉时,就会有一个道具落下,道具有两种,分别可以使挡板变长和变短。
如果挡板接住了道具,魔法就会起效。
当所有的砖块都被消除掉后,玩家就胜出,如果弹球球落下时没有被挡板接住,本轮游戏就失败了。
在游戏中,有挡板、弹球、砖块、道具这四种游戏对象,砖块是固定不动的,挡板的移动是由玩家通过键盘控制的,弹球和道具也是运动的。这些游戏对象都有共同的特性,有自己的位置,即 x 与 y 坐标,有图片属性,有速度属性。
BallComponent 作为 Brick (砖块)类、 Magic (道具)类、 Stick (挡板)类、 Ball (弹球)类的父类,包含了上面提到的几个共有的属性。当然,在 BallComponent 中至少要有一些获取和设置属性的方法,为了简单明了,图中并没有标出。
Magic(道具)类(该类中有一个用于使道具功能实现的抽象方法,供子类实现),道具类的子类有LongMagic和ShortMagic,作用是使挡板的长度变长或者变短,由magicDo(Stick stick)来实现。
确定了游戏对象各类后,还需要一个BallFrame类,一个画板类(BallPanel),一个BallService类来处理与游戏相关的业务逻辑。
下面分别思考下Brick(砖块)类、Stick(挡板)类、Magic(道具)类、Ball(弹球)类、LongMagic类、ShortMagic类该如何定义。
Brick(砖块)类的属性定义:
// 定义道具,1表示变长道具,2表示变短道具 private Magic magic = null; public static final int MAGIC_LONG_TYPE = 1; public static final int MAGIC_SHORT_TYPE = 2; // 定义一个boolean变量标记砖块是否有效,如果无效就不绘制在画板上 private boolean disable = false;
Brick(砖块)类的构造方法:
public Brick(String path, int type, int x, int y) throws IOException { super(path); if (type == Brick.MAGIC_LONG_TYPE) { this.magic = new LongMagic("img/long.gif", x, y); } else if (type == Brick.MAGIC_SHORT_TYPE) { this.magic = new ShortMagic("img/short.gif", x, y); } if (this.magic != null) { this.magic.setX(x); this.magic.setY(y); } }
注意构造方法的参数中,path指的是砖块图片地址;type指的是砖块的类型,0表示普通砖块,1表示有变长魔法的砖块,2表示有变短魔法的砖块;x,y分别表示道具的x,y坐标。
Stick(挡板)类的属性定义:
// 定义档板移动的速度 public static final int SPEED = 20; // 定义档板初始的长度 private int preWidth = 0;
Stick(挡板)类的构造器:
/** * 有参数构造器 * * @param panelWidth * int 画板宽度 * @param panelHeight * int 画板高度 * @param path * String 图片路径 */ public Stick(int panelWidth, int panelHeight, String path) throws IOException { // 调用父构造器 super(panelWidth, panelHeight, path); // 设置y坐标 this.setY(panelHeight - super.getImage().getHeight(null)); // 设置原本的长度 this.preWidth = super.getImage().getWidth(null); }
可以看到,利用构造器,可以把挡板定位在画板的底部。弹球类(Ball)的构造器与挡板类(Stick)的构造器很类似,弹球的初始状态是正好在挡板的正上方。
Ball(弹球)类的属性定义:
// 定义球的竖向速度 private int speedY = 10; // 定义弹球的横向速度 private int speedX = 8; // 定义是否在运动 private boolean started = false; // 定义是否结束运动 private boolean stop = false;
Magic(道具)类,LongMagic类、ShortMagic类的定义没有太大难度,关键是magicDo(Stick stick)的实现。