内容来自RyiSnow视频讲解
这一节讲的是Monster野兽、就是常说的游戏中的怪,打怪升级的那个怪。
前言
本节目标
- 实现怪
- 处理碰撞和伤害(当玩家player碰到怪会掉血)
实现
添加怪到窗口
这里只使用了2张图片,每个方向移动都是用这2个图片的逐帧动画表示。移动逻辑同老人NPC。
检测碰撞
在碰撞检测中实现了Entity之间的互相碰撞检测,这里有一个细节,就是由于npc和monster是数组,当调用checkEntity(Entity e, npc[]);checkEntity(Entity e, monster[])的方法进行判断的时候,要注意,要将数组中与e参数相等的元素排除掉,否则npc和monster将无法移动。
public int checkEntity(Entity entity, Entity[] target) {
//...
if (entity.solidArea.intersects(target[i].solidArea)) {
//Removing this class from target
if (target[i] != entity) {//把自己从target数组中“移除”,大意为避免自己和自己碰撞
entity.collisionOn = true;
index = i;
}
}
//...
}
这一节修改了许多地方,去掉了很多冗余重复的逻辑,具体可以参考项目代码。
player receives damage玩家接收伤害
当玩家碰到Monster怪的时候,处理逻辑为生命值-1,后续会有更精确的伤害计算。
public class Player {
public void update() {
//...
// check monster collision(player -> monsters)
int monsterIndex = gp.cChecker.checkEntity(this, gp.monster);
contactMonster(monsterIndex);
//...
}
public void contactMonster(int i) {
if (i != 999) {
// temp test, we will add more accurate calculate damage after attack,defense, equipment...
life -= 1;
}
}
}
当玩家碰到怪,收到伤害后,会有1秒的无敌时间。不然每秒60帧,life每一帧-1,玩家很快就死了。具体可以参考项目代码。invincible无敌的。
怪碰到玩家
前面的逻辑当玩家原地不动,怪走过来碰到玩家,玩家并不会掉血,这里增加一下这个逻辑。
Entity增加一个type变量,2代表怪。这个2硬编码后续会修改。临时用一下。
public class Entity {
public void update() {
//......
boolean contactPlayer = gp.cChecker.checkPlayer(this);
//2 means monster
if (this.type == 2 && contactPlayer) {
if (!gp.player.invincible) {
// we can give damage
gp.player.life -= 1;
gp.player.invincible = true;
}
}
}
}
- 效果
无敌状态增加视觉效果
public class Player {
public void draw(Graphics2D g2) {
// ...
if (invincible) {
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
}
g2.drawImage(image, screenX, screenY, null);
// Reset alpha
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
}
}
当玩家被攻击或碰到怪,掉血的时候会进入无敌状态,有一个半透明效果。替代前面的显示无敌帧数的调试信息。
下一节讲Player攻击Monster
代码
参考第6篇文章最后,可以使用git clone或直接下载获得完整项目