-
Notifications
You must be signed in to change notification settings - Fork 0
Boss enemies
In order to make threats in the game more interactive with the player, we decide to add five functional boss enemies that can shoot life-threatening bullets or lasers to the game character. We create boss enemies based on alien characteristics to suit the space theme and game background story. The player should be cautious when they appear to the boss as boss enemies are more powerful than general enemies (i.e. robot and ufo) and they can cause more damage.
Boss enemies belong to one alien family that rules the entire solar system. In the game, five alien boss enemies live on different planets (levels) and they have different attacking patterns. Each enemy character is inspired based on real-world animals.
- Blue octopus (called alien soldier): It appears at level one. It is the dumbest alien because its sensory system can't detect the game character's position. Instead, it only has a self-protection mechanism that shoots multiple bullets in arbitrary directions. Each time the game character gets hit by its bullet, the player will lose 20 health rates.
- Yellow box (called alien monster): It appears at level two. It spawns one baby alien to the player each time. This enemy will detect the game characters' position and shoot the baby alien bullet that traces the player. The player will lose 10 health rates if he gets hit by the baby alien.
- Spider queen (called alien boss): It appears at level three and it is the evilest alien. Its multiple bullets all trace the player character. Thus, the player needs to do some agile jumps or sprints to escape from this boss. The player will lose 20 health rates if he gets hit by any bullet.
- Green bee (called alien barbette or alien wasp): It appears at a random level. It only shoots one single bullet each time to its left-hand side. However, the shooting speed of this enemy and the moving speed of bullets are relatively quick. The player should either jump to avoid getting hurt or change to the platform. The player will lose 20 health rates if he gets hit by any bullet.
- Sleepy squid (called alien laser hole or alien squid): When the squid feels sleepy, it starts its self-protection mechanism, which is the transparent rainbow lasers. The player should not pass by the squid when lasers are on, else the player will lose 20 health rates.
-
AttackTask
: Defines how enemies shoot bullets. -
AttackListener
: Creates alienMonster's weapon. -
AlienBossAttackListener
: Create AlienBoss's weapon. -
AlienSoldierAttackListener
: Create AlienSoldier's weapon. -
AlienBarbetteAttackListener
: Create AlienBarbette's weapon. -
AlienLaserAttackListener
: Create AlienLaserHole's weapon. -
EnemyFactory
: Factory to create enemy and bullet entities, includingcreateAlienMonster()
,createAlienMonsterWeapon()
,createAlienSoldier()
,createAlienSoldierWeapon()
,createAlienBoss()
,createAlienBossWeapon()
,createALienBarbette()
,createAlienBarbetteWeapon()
,createAlienLaserHole()
,createAlienLaserHoleWeapon()
. -
ForestGameArea
,LevelTwoArea
,LevelThreeArea
,LevelFourArea
: Area for initializing all the enemy entities. -
BulletHitPlayer
: Bullets disappear when they touch the player and deal 20 damage.
Creating a new enemy can be divided into the following parts.
First create a task
for the enemy, it can set the way of enemy shoots bullets. The AttackTask
is written for all the enemy entities and could always be reused.
public AttackTask(Entity target, float waitTime, int priority, float distance) {
this.target = target;
this.waitTime = waitTime;
this.priority = priority;
this.distance = distance;
this.timeSource = ServiceLocator.getTimeSource();
}
@Override
public void start() {
super.start();
endtime = timeSource.getTime() + (int)(waitTime * 1000);
}
@Override
public void update() {
if (timeSource.getTime() >= endtime) {
this.owner.getEntity().getEvents().trigger("attack");
endtime = timeSource.getTime() + (int)(waitTime * 1000);
}
}
@Override
public void stop() {
super.stop();
}
@Override
public int getPriority() {
if (status == Status.ACTIVE) {
return Active();
}
return inActive();
}
private float DistanceToTarget() {
return owner.getEntity().getPosition().dst(target.getPosition());
}
private int Active() {
float dst = DistanceToTarget();
if (dst > distance) {
return -1;
}
return priority;
}
private int inActive() {
float dst = DistanceToTarget();
if (dst <= distance) {
return priority;
}
return -1;
}
}
Then set up the listener
, it can help create the entity of the bullet. For example, within the AttackListener
class, add the event listener to the attack()
function to create the weapon for the enemy.
@Override
public void create() {
super.create();
entity.getEvents().addListener("attack", this::attack);
}
void attack() {
gameArea.spawnEntity(EnemyFactory.createAlienMonsterWeapon(this.entity, target, gameArea));
}
Creating component of BulletHitPlayer
, it can make the bullet disappear and reduce the player's HP when the bullet hits the player. You can set the bullet damage here.
public BulletHitPlayer(Entity target, GameArea GameArea) {
this.target = target;
this.GameArea = GameArea;
}
@Override
public void create() {
super.create();
entity.getEvents().addListener("collisionStart", this::Hit);
}
private void Hit(Fixture attack, Fixture player) {
Entity bullet = ((BodyUserData) attack.getBody().getUserData()).entity;
Entity target = ((BodyUserData) player.getBody().getUserData()).entity;
if(target == this.target) {
bullet.getComponent(PhysicsComponent.class).getPhysics().addToDestroy(bullet);
target.getComponent(CombatStatsComponent.class).decreaseHealth(20);
}
}
Finally, add AttackTask
and AttackListener
while creating the enemy.
public static Entity createAlienMonster(Entity target, GameArea gameArea) {
AlienMonsterConfig config = configs.alienMonster;
AITaskComponent aiComponent =
new AITaskComponent()
.addTask(new WanderTask(new Vector2(3f, 2f), 0f))
.addTask(new AttackTask(target, 2, 10, 6f));
Entity alienMonster = new Entity()
.addComponent(new TextureRenderComponent("images/alien_monster.png"))
.addComponent(new PhysicsComponent())
.addComponent(new PhysicsMovementComponent())
.addComponent(new ColliderComponent())
.addComponent(new HitboxComponent().setLayer(PhysicsLayer.NPC))
.addComponent(new ColliderComponent().setLayer(PhysicsLayer.OBSTACLE))
.addComponent(new TouchAttackComponent(PhysicsLayer.PLAYER, 0f))
.addComponent(new CombatStatsComponent(config.health, config.baseAttack))
.addComponent(aiComponent)
.addComponent(new AttackListener(target, gameArea));
PhysicsUtils.setScaledCollider(alienMonster, 1f,1f);
alienMonster.scaleHeight(2f);
return alienMonster;
Add BulletHitPlayer
for the bullet and set the motion trajectory for the bullet.
public static Entity createAlienMonsterWeapon(Entity from, Entity target, GameArea gameArea) {
float x1 = from.getPosition().x;
float y1 = from.getPosition().y;
float x2 = target.getPosition().x;
float y2 = target.getPosition().y;
Vector2 newTarget = new Vector2(x2 - x1, y2 - y1);
newTarget = newTarget.scl(1000).add(from.getPosition());
Entity alienMonsterWeapon =
new Entity()
.addComponent(new TextureRenderComponent("images/alien_monster_weapon_02.png"))
.addComponent(new PhysicsComponent())
.addComponent(new PhysicsMovementComponent())
.addComponent(new ColliderComponent())
.addComponent(new BulletHitPlayer(target, gameArea));
alienMonsterWeapon.getComponent(TextureRenderComponent.class).scaleEntity();
alienMonsterWeapon.scaleHeight(0.5f);
PhysicsUtils.setScaledCollider(alienMonsterWeapon, 0.5f, 0.3f);
alienMonsterWeapon.setPosition(x1 - alienMonsterWeapon.getScale().x / 2 + from.getScale().x / 2,
y1 - alienMonsterWeapon.getScale().y / 2 + from.getScale().y / 2);
alienMonsterWeapon.getComponent(PhysicsMovementComponent.class).setTarget(newTarget);
alienMonsterWeapon.getComponent(PhysicsMovementComponent.class).setMoving(true);
alienMonsterWeapon.getComponent(ColliderComponent.class).setSensor(true);
return alienMonsterWeapon;
}
In order to make the enemies adapt to different difficulty and level settings, it is better to alter the attack attributes of the enemies corresponding to different gaming situations. First of all, if we want to change the movement properties of the enemy instead of holding it in a fixed position, there are two ways which we could choose to implement:
- Add the
WanderTask
for the enemy entity to make it move in a given x-y area at a given speed. For example, we implement this functionality for the alien monster enemy.
AITaskComponent aiComponent =
new AITaskComponent()
.addTask(new WanderTask(new Vector2(3f, 2f), 0f));
Entity alienMonster = new Entity().addComponent(aiComponent);
- Add the
ChaseTask
for the enemy entity to allow it to chase the player character in a given area. This will significantly increase the threat of the enemy. In the current level design, we did not enable the chase task for the enemies as it will significantly increase the difficulty of the game. However, one of the obstacles called UFO has been enabled this task. Secondly, we could also modify several settings of theAttackTask
for the enemy to change its attack attributes including the attack trigger distance, and the attack frequency. For example, for the alien barbette enemy, we gave it a relatively faster attack frequency by setting the waiting time to 1 and increased its attack trigger distance to 12f. Below is the example of the implementation code:
AITaskComponent aiComponent =
new AITaskComponent()
.addTask(new WanderTask(new Vector2(0f, 0f), 0f))
.addTask(new AttackTask(target, 1, 10, 12f));
In addition to changing the settings of the enemy entities themselves, we could also modify the settings of the enemy's weapon/bullet. There are several settings that can be modified to make significant changes. Firstly, the shooting direction could be set in two various ways:
- The direction of attack will depend on the position of the player character and the bullet will be fired directly to the positon of the player character before last movement. For example, this way has been used by the bullets of the alien monster. Here is the example of implementation code: The new target is the fire target for the weapon which is the position of the player character.
float x1 = from.getPosition().x;
float y1 = from.getPosition().y;
float x2 = target.getPosition().x;
float y2 = target.getPosition().y;
Vector2 newTarget = new Vector2(x2 - x1, y2 - y1);
newTarget = newTarget.scl(1000).add(from.getPosition());
Then, set the attack target and add the moving property to the bullets.
alienMonsterWeapon.getComponent(PhysicsMovementComponent.class).setTarget(newTarget);
alienMonsterWeapon.getComponent(PhysicsMovementComponent.class).setMoving(true);
alienMonsterWeapon.getComponent(ColliderComponent.class).setSensor(true);
- You can also give the weapon a fixed position as the fire target. The
AlienSoldierWeapon
is one of the example that uses this way.
float x1 = from.getPosition().x;
float y1 = from.getPosition().y;
Vector2 target1 = new Vector2(x1 + 1, 0);
Vector2 target2 = new Vector2(x1 - 10, 0);
Vector2 target3 = new Vector2(x1 + 10, 0);
Vector2 target4 = new Vector2(x1 - 30, 0);
Vector2 target5 = new Vector2(x1 + 30, 0);
All those five targets are the fixed given position, they will not be affected by the player characters' position.
Also, after we add a new constructor for the PhysicsMovementComponent
class, the moving speed of the bullet could be changed by initializing the PhysicsMovementComponent
class with a defined speed value. Below are the implementation of the new constructor of the PhysicsMovementComponent
class and how to use it in EnemyFactory
class when creating the enemy's weapon.
public PhysicsMovementComponent(Vector2 speed) {
maxSpeed = speed;
}
Entity alienSoldierWeapon1 =
new Entity()
.addComponent(new PhysicsComponent())
.addComponent(new PhysicsMovementComponent(new Vector2(5f, 5f)));
- Player UI
- Popup Menus
- Obstacles
- Boss Enemies
- Progress Tracker
- Checkpoint Design and Functionality
- Score System
- Lives System
- Game Background
- Multiple game-level
- Visual Improvements
- Tutorial Level
- Character Design and Animations
- Character Damage Animations
- Player Animation Functionalities
- Player and Serpent Portal Transition
- Pop-up Menus
- Obstacles
- Lives & Score User Testing
- Buffs & Debuffs
- Buffs & Debuffs redesign
- Obstacle Animation
- Background Design
- Level 2 Background Appearance
- Enemy Monster User Testing
- Level 1 Floor Terrain Testing
- Introduction Screens User Testing
- Character Movement Interviews & User Testing
- Sound user testing
- Level 2 Obstacles and enemy
- Story, Loading, Level 4 and Win Condition Sound Design User Testing
- Giant Bug and Purple Squid animation user testing
- General Gameplay and Tutorial Level User Testing
- Level 4 Terrain User Testing
- Game Outro User Testing