-
Notifications
You must be signed in to change notification settings - Fork 0
Obstacles
To make the game become more challenging and immerse the player into the atmosphere of the game, we aim to implement the obstacle feature for the game. Initially, once the player starts the game, several types of obstacles will appear on the game map. In addition, different types of obstacles will cause different amounts of damage to the game character, and also they will have different movements and functionalities. In order to survive the game, the player must try to avoid as many obstacles as possible.
Static obstacles:
- Asteroid: A type of static obstacle that appears once the game starts and the position of each asteroid remains stable within the game. It does not have any damage to the player but the player cannot pass it directly.
- Asteroid fire: A type of static obstacle that appears once the game starts and the position of each asteroid fire remains stable within the game. For those asteroid fire obstacles on the map, if the player touches them (inside of the attack range of the asteroid fire), the player's health will be reduced by 10.
- Platform: A type of static obstacle that appears once the game starts and the position of each platform remains stable within the game. For those platform obstacles on the map, the player could jump onto them and move freely. This obstacle would not cause any damage to the player. Therefore, the player could use them effectively to avoid other types of obstacles.
- Portal: A static obstacle that appears at the end of every map. Once the player collides with this they will be shown the win screen and prompted to go to the next level. This was implemented so it made more sense how players were travelling between levels.
- Rocks: When the game starts, rocks are randomly distributed on the horizontal surface, and the types of rocks will also change randomly. Rocks will block the player's walking, but the player can jump over the rocks, and the rocks cannot cause damage.(Not adopted)
- Buildings: The building does not affect the player in any way, it is part of the background.(Not adopted)
Kinematic obstacle:
- HorizontalMovingPlatform: A type of Kinematic obstacle that appears once the game starts. The platform moves horizontally (left to right) at a constant speed. Players can stand on a moving platform and follow the platform to move. The moving platform could increase the difficulty of the game and the player must consider the time to jump onto it.
- VerticalMovingPlatform: A type of Kinematic obstacle that appears once the game starts. The platform moves vertically (top to bottom) at a constant speed. Players can stand on a moving platform and follow the platform to move. The moving platform could increase the difficulty of the game and the player must consider the time to jump onto it.
Dynamic obstacles:
- UFO: A type of dynamic obstacle that randomly appears in the upper area of the map When the game is running, and randomly moves in different directions during the game. When the player collides with the UFO, the player will lose a certain amount of blood that is 25.
- Robot: A type of dynamic obstacle that appears once the game starts and the position of the robot should be constantly changing. During the game, the robot will move left and right at a constant speed. For the robot on the map, if the player collides with it(inside of the attack range of the robot), the player's health will be reduced by 20.
-
obstacle.json
This JSON file includes the initial properties (health, baseAttack) of all the aggressive obstacles. -
ObstacleConfig
Defines all Obstacle configs to be loaded by the Obstacle Factory. -
AsteroidConfig
RobotConfig
UfoConfig
Defines the properties stored in obstacle config files to be loaded by the Obstacle Factory. -
ObstacleFactory
Factory to create obstacle entities, all types of obstacles are created and implemented here, includingcreateAsteroid()
,createAsteroidFire()
,createRobot()
,createUfo()
,createPlatform1()
,createPlatform3()
. -
ForestGameArea
Area for initializing game entities, including all the obstacles.spawnAsteriod()
,spawnAsteroidFire()
,spawnRobot()
,spawnUFO()
,spawnPlatform1()
andspawnPortal()
are implemented here. -
PlatformTask
Set a task for the platform to move it left and right.
public static Entity createAsteroid() {
Entity asteroid =
new Entity()
.addComponent(new TextureRenderComponent("images/broken_asteriod.png"))
.addComponent(new PhysicsComponent())
.addComponent(new ColliderComponent().setLayer(PhysicsLayer.OBSTACLE));
asteroid.getComponent(PhysicsComponent.class).setBodyType(BodyType.StaticBody);
asteroid.getComponent(TextureRenderComponent.class).scaleEntity();
asteroid.scaleHeight(0.7f);
PhysicsUtils.setScaledCollider(asteroid, 0.7f, 0.5f);
return asteroid;
}
public static Entity createRobot(Entity target) {
RobotConfig config = configs.robot;
AITaskComponent aiComponent =
new AITaskComponent()
.addTask(new WanderTask(new Vector2(10f, 0f), 0f));
Entity robot =
new Entity()
.addComponent(new PhysicsComponent())
.addComponent(new PhysicsMovementComponent())
.addComponent(new ColliderComponent().setLayer(PhysicsLayer.OBSTACLE))
.addComponent(new HitboxComponent().setLayer(PhysicsLayer.NPC))
.addComponent(new TouchAttackComponent(PhysicsLayer.PLAYER, 0f))
.addComponent(new TextureRenderComponent("images/robot1.png"))
.addComponent(new CombatStatsComponent(config.health, config.baseAttack))
.addComponent(aiComponent);
robot.getComponent(PhysicsComponent.class).setBodyType(BodyType.DynamicBody);
return robot;
}
You can initialize and change the properties of the obstacle here obstacle.json
{
"asteroidFire": {
"health": 100,
"baseAttack": 10
},
"robot": {
"health": 100,
"baseAttack": 20
},
"ufo": {
"health": 100,
"baseAttack": 25
}
}
You can add the obstacle to forest game area here and modify the position of obstacles.
private void spawnRobot() {
GridPoint2 pos1 = new GridPoint2(12, 16);
Entity robot1 = ObstacleFactory.createRobot(player);
spawnEntityAt(robot1, pos1, true, true);
}
Then, you can initialise the obstacles inside create()
public void create() {
spawnAsteriod();
spawnAsteroidFire();
spawnRobot();
spawnPlatform1();
spawnUFO();
}
Obstacles will randomly appear at different positions on the horizontal line of the map
private void spawnBuilding() {
GridPoint2 minPos = new GridPoint2(2, 10);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 20);
for (int i = 0; i < NUM_BUILDINGS; i++) {
GridPoint2 randomPos = RandomUtils.random(minPos, maxPos);
Entity building = ObstacleFactory.createBuilding1();
spawnEntityAt(building, randomPos, true, false);
}
}
private void spawnRocks() {
GridPoint2 minPos = new GridPoint2(5, 10);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 20);
Random r = new Random();
for (int i = 0; i < NUM_ROCKS; i++) {
GridPoint2 randomPos = RandomUtils.random(minPos, maxPos);
Entity rock1 = ObstacleFactory.createRock1();
Entity rock2 = ObstacleFactory.createRock2();
Entity rock3 = ObstacleFactory.createRock3();
Entity rock4 = ObstacleFactory.createRock4();
if(r.nextInt(4) == 0) {
spawnEntityAt(rock1, randomPos, true, false);
} else if(r.nextInt(4) == 1) {
spawnEntityAt(rock2, randomPos, true, false);
} else if(r.nextInt(4) == 2) {
spawnEntityAt(rock3, randomPos, true, false);
} else {
spawnEntityAt(rock4, randomPos, true, false);
}
}
The method of creating a moving platform is similar to the method of creating a stationary platform, we only need to add PlatformTask
to it when creating a moving platform and change its setBodyType
to BodyType.KinematicBody
.
public class PlatformTask extends DefaultTask implements PriorityTask {
private final int priority;
private final float x;
private float p_x = 0;
private boolean isMove = true;
/**
* @param priority Task priority when chasing (0 when not chasing).
*/
public PlatformTask(float x, int priority) {
this.x = x;
this.priority = priority;
}
@Override
public void start() {
super.start();
p_x = this.owner.getEntity().getPosition().x;
}
@Override
public void update() {
float position_x = this.owner.getEntity().getPosition().x;
if (isMove) {
if(position_x <= p_x + x/2) {
this.owner.getEntity().getComponent(PhysicsComponent.class).getBody().setLinearVelocity(new Vector2(1,0));
} else {
isMove = false;
}
} else {
if(position_x >= p_x - x/2) {
this.owner.getEntity().getComponent(PhysicsComponent.class).getBody().setLinearVelocity(new Vector2(-1,0));
} else {
isMove = true;
}
}
}
@Override
public void stop() {
super.stop();
}
@Override
public int getPriority() {
return priority;
}
}
- 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