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 obstacle
  • type - environmental obstacle type from ENUM
  • EnvironmentalObstacle
  • heightScale - scales the height of the obstacle
  • scaleX - scales x size of entity
  • scaleY - scales y size of entity
  • collisionEffct - effect on collision
  • speedModifier - 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 an Entity to the class for future checking of collision
  • wouldCollide - check if the given Entity would collide with any Entities stored within the class
  • checkTileIsWater - check if the given X,Y position would result in a water tile
  • isNearWater - check if the tiles near X,Y are near water by calling checkTileIsWater

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

CollisionEffectComponents allow EnvironmentalObjects 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.

Class Diagram Map

image