Landscape Objects - UQdeco2800/2022-studio-1 GitHub Wiki
Details about the design process can be found on this page.
Jump to:
General
Landscape objects are Entities
that implement EnvironmentalComponent
. They may also implement CollisionEffectComponent
. They are generated in the ObstacleFactory, and placed on the map in the ForestGameArea file. They are removable by the player.
Environmental Component
The Environmental Component
is the base component/class that holds the information releated to obstacles on the map and is used by ObstacleFactory
to create Environmental Obstacles. It consists only of getters to allow functions to get either the Obstacle as an enum, the ResourceType
and ResourceValue
. The ResourceType
is the type of resource this obstacle would return when destroyed while ResourceValue
returns the number of resources. E.g. Tree
would return WOOD
with the value 20
.
These values are stored via the use of ENUMS
allowing for easy change of values depending on future teams and saves extensive abstraction/inheristance by creating a individiual class for every resource type.
Placement
To place environmental obstacles the ForestGameArea
must be used specifically with the function SpawnEnvironmentalObstacles
. SpawnEnvironmnetalObstacles
, as the name implies, spawns all of the obstacles on the map using semi random amounts of TREES
, ROCKS
etc. It calls SpawnEnvironmentalObstacle
which will spawn the given obstacle at a random X,Y pos. It does this by creating an Entity
via calling ObstacleFactory
and if the spawn position is valid via the environmentalCollision
class.
Obstacle Factory
The base obstacle factory was abstracted and modified to allow for easier expansion and addition of EnvironmentalObstacles
. Specifically the createEnvironmentalObject
method was created which spawns the generic obstacle with the standard set of components:
TextureRenderComponent
PhysicsComponent
ColliderComponent
EnvironmentalComponent
CollisionEffectComponent
This requires a set of inputs:
imgPath
- path to image of the obstacletype
- environmental obstacle type from ENUMEnvironmentalObstacle
heightScale
- scales the height of the obstaclescaleX
- scales x size of entityscaleY
- scales y size of entitycollisionEffct
- effect on collisionspeedModifier
- the speed multiple which the obstacle applies to the playyer
Every EnvironmentalObstacle does require it's own create method and follows the template - public static Entity {Obstacle}
- and should consist of a single call to createEnvironmentalObject
with the above corresponding values.
Environmental Collision
To handle Environmental Collisions a class called EnvironmentalCollision
was created and must be used in the placement process. In simple terms it is a HashTable that maps positions of an entity to the entity itself allowing for collision checking and determining what tile the Entity
is on. It consists of four main methods at the moment:
addEntity
- add anEntity
to the class for future checking of collisionwouldCollide
- check if the givenEntity
would collide with anyEntities
stored within the classcheckTileIsWater
- check if the givenX,Y
position would result in a water tileisNearWater
- check if the tiles nearX,Y
are near water by callingcheckTileIsWater
When placing an object the wouldCollide function must be checked and if true a new position must be used. This is to avoid overlaying obstacles. If the obstacle can not be placed in water it is recommend to use the isNearWater
to not cause a collision/misplacement onto water.
Removal
To remove environmental obstacles the ForestGameArea
must be used specifically with the function removeEnvironmentalObject
. removeEnvironmentalObject
removes an environmental obstacle on a given grid position. It does this by iterating through the areaEntities
list from GameArea
to find the entity on that location. It also checks whether said entity is an environmental object by checking if it has EnvironmentalComponent
attached to it.
The function returns a tuple of the resource type and its value, the tuple uses the ValueTuple
class which pairs an EnvironmentalComponent.ResourceTypes
enum and an Integer
.
Bugs
It was not able to be tested properly, however. Given the fact that it is mostly tied to the ForestGameArea
class it cannot be simply tested from the EnvironmentalComponent
class. Attempts to pass the ForestGameArea
class to the EnvironmentalComponent
class to call the function from the latter class was not able to be done without an error. This method of testing was able to run only for a few seconds, at which duration environment objects do get removed, before throwing a nested iteration error.
CollisionEffect Component
CollisionEffectComponent
s allow EnvironmentalObject
s to enact various effects on the player/npcs. These effects include:
SLOW
(although this is a misnomer as they can also be used to increase speed - simply give the EnvironmentalComponent a speed aspect > 1)DAMAGE
KNOCKBACK
- and basic collision effects (
DIVERT
&NONE
)
Entities implementing CollisionEffectComponent
should also implement ColliderComponent
, PhysicsComponent
, and EnvironmentalComponent
. If you want the effect to extend past the bounds of the collider (i.e. in an area of effect), HitboxComponent
should also be implemented and given a size
Effects can be configured to effect either the player, npcs, or both. By default, effects work on all entities that collide with them, but this can be changed using SetEffectTarget()
and the EffectTarget
enum.
The effects work using the engine's collision handler, and effects are applied on collision and, if necessary, removed when the collision ends.
The Slow Effect
The SLOW
effect is implemented by accessing a method added to player & NPC movement components (SetPlayerSpeed()
in PlayerActions.java
and SetMaxSpeed()
in PhysicsMovementComponent.java
respectively. Speed is changed by multiplying the entity's current speed by the speedModifier
, and this debuff is removed on collision end by multiplying the speed by 1/speedModifier
. We have tried to test to ensure floating point errors don't end up with the entity moving at a drastically different speed after many collisions, but this is still possible. the ResetSpeed()
functions can be implemented to fix this if necessary.
Initially, we tried to implement the SLOW
effect using the engine's physics library & applying friction / linear damping. If you are considering refactoring this effect to be used in this way, tread carefully! It will (we think) require some tinkering with the engine's PreSolve
function in the PhysicsContactListener
to add additional friction between colliding bodies regardless of the friction on individual bodies.
The Damage & Knockback) Effect
By default DAMAGE
also knocks back the entity. This behaviour can be changed by using SetKnockback()
and setting knockback to 0f
Test Plan
Code Test Plan
The test plan for programming was to design and develop the relevant classes and to test manually via visual confirmation. Code reviews by peers were also conducted on a regular basis to catch errors and bugfixes. Once class design was confirmed Junit tests were produced to do further testing of edge cases of implemented functionality and to ensure future modifications of the code base do not unexpectedly cause errors or bugs.
All functions that can be tested were tested with functions that work on randomness such as SpawnEnvironmentalObjects
tested by hand and confirmed via peer reviews.