内容来自RyiSnow视频讲解
这一节讲的是Projectiles查了下字典,意思如下。
[prəˈdʒektaɪl]
n.射弹;抛射体;导弹
前言
按照作者的意思,这一节是要讲丢弃物品的,就是怪被杀死后,掉落物品。但是有许多人评论要求讲实现远程攻击的方法,发射一个火球什么的。
类似超级玛丽里面的发射一速火焰的那种武器效果。这里作者以发射火球为例讲解了这样的功能实现方法,根据这节的讲解,可以自己实现自己的远程武器,比如射箭、发射子弹、扔斧子……
修复bug
有人提出,当怪物死亡,出于闪烁状态的时候,如果玩家碰到它,玩家还会掉血。
效果图
这里是向下发射了一枚火球,80帧后火球会消失。
实现
为了处理飞行的远程武器,增加了一个类Projectile继承自Entity类。火球类继承自Projectile类。
新增火球资源图片
8张图片,每个方向2张,实现火球飞行动画。
按键发射火球
作者用的是F键,考虑到双手操作不太方便,这里使用了J键。
public class KeyHandler {
......
playState() {
if (code == KeyEvent.VK_J) {
shotKeyPressed = true;
}
}
public void keyReleased(KeyEvent e) {
int code = e.getKeyCode();
......
if (code == KeyEvent.VK_J) {
shotKeyPressed = false;
}
}
}
设置火球属性
在玩家的构造方法中,初始化了一个火球对象,这样游戏开局就有了火球武器。
当按下J键,设置火球坐标位置和方向、是否存活状态等属性。
public class Projectile ...{
public void set(int worldX, int worldY, String direction, boolean alive, Entity user) {
this.worldX = worldX;
this.worldY = worldY;
this.direction = direction;
this.alive = alive;
this.user = user;
this.life = this.maxLife;
}
}
更新位置
在Projectile类的update方法中,更新火球的位置、生命值(80帧递减直到0,火球消失)等属性。然后在GamePanel类中调用这个更新方法即可。
public class GamePanel {
...
public void update() {
...
// projectile
for (int i = 0; i < projectileList.size(); i++) {
Projectile projectile = projectileList.get(i);
if (projectile != null) {
if (projectile.alive) {
projectile.update();
} else {
projectileList.set(i, null);
}
}
}
}
}
绘制渲染
在GamePanel的paintComponent方法中调用对应方法即可。具体参考项目代码。
效果
在这个示例程序中,火球速度为5,飞行80帧后消失,这些属性可以根据自己的需求,进行修改。
让火球发挥作用
由于目前没有判断碰撞,所以火球现在不能发挥作用,对怪物造成伤害。这里有一个问题需要注意,原来的damageMonster方法中的攻击值是基于玩家的力量和武器,火球的攻击值与之有区别,所以这里增加了一个参数,用于传递不同的attack进行伤害计算。
public class Projectile {
public void update() {
if (user == gp.player) {//如果是玩家发射的火球,检测与怪物的碰撞
int monsterIndex = gp.cChecker.checkEntity(this, gp.monster);
if (monsterIndex != 999) {
gp.player.damageMonster(monsterIndex, attack);
alive = false;//火球击中目标后消失
}
} else {
}
}
}
火球发射的bug
如果玩家发射火球的时候距离怪物足够近,那么一枚火球碰到怪后,后续火球会立即发出,连续发射,中间几乎没有间隔时间。
虽然只按下了一次发射键,看上面这个发射的判断,如果alive为false才会发射火球,但是由于火球碰到怪后alive就为false了,所以这时候如果你还在按住发射键没松开,玩家就会立即发射新的火球。这是一个问题,作为游戏来说。
这里作者添加了一个shotAvailableCounter变量,每次update方法执行变量+1,当变量值为30,才可以发射火球,这样一来,发射火球后,需要等30帧才可以继续发射火球。
关于火球发射,作者的考虑很细节啊。本来觉得这样一来,首次发射火球还要等待30帧才能响应发射按键,显示了一下showAvaiableCounter变量发现多虑了,由于游戏循环一直在进行,游戏开始后只需要半秒,30的值就准备好了,除非在游戏开始半秒内进行发射操作,这几乎不会发生。
代码
参考第6篇文章最后gitee仓库链接,可以使用git clone命令clone一下或直接下载获得完整项目