Projectile - UQcsse3200/2024-studio-1 GitHub Wiki
Projectile Overview
Main Classes:
ProjectileConfig
, ProjectileFactory
, ProjectileAttackComponent
, and ProjectileActions
.
Speed-run Summary
A Projectile is made up of two types of variable:
- Config -> Re-usable (eg; animation asset, damage, speed, size, ect) - You'd read these variables on the side of the Ammunition box.
- Constructor Args -> Instance specific (eg; position, direction) - These variables are new when the bullet is shot.
The ProjectileConfig is used to store variables that a group of projectiles might share in common, they are re-usable. A ProjectileConfig object is then passed to the constructor createProjectile() along side Instance specific variables.
The projectile constructor is part of the ProjectileFactory. ProjectileFactory is used to load assets and collate components that are needed for a projectile. Unique to this factory, are projectile specific components such as ProjectileAttackComponent
, and ProjectileActions
. Furthermore, the physics collider of a projectile entity is set to sensor, If you'd like projectiles to block or collide physically this sensor will need to be unset and managed. Assets are loaded according to LoadedFactory documentation.
How to make a projectile
Here is an example of creating and spawning a projectile from Components/Weapon/FiringController
Sample Implementation
Having a Closer Look.
Config
You can see that the gun has a projectile config defined in the class. this.projectileConfig, If the gun needs to make quick changes to the projectiles stats, like the damage going up or down, or the speed changes.
Direction
The direction var is which way the projectile is shot. This is given as a rectangular vector. The magnitude is also used as the projectiles speed. Effectively the speed var in the config will multiply the direction vectors Magnitude. So if you want the speed var in the config to reign supreme (which is mostly what you want), you should try to make sure the magnitude of this direction vector one. Note this is default behaviour for player direction variable and VectorUtils.LEFT/VectorUtils.UP and similar.
If the word vector is scary: LibreTexts-Vectors
This is also describes the polar transforms for calculating the shotgun bullet angles.
Position and Spawning
The SpawnEntityAt method will then unsurprisingly spawn the projectile on the map. However, the gridPoint is not used the projectile will move to the specified this.getEntity().getPosition() on the first update in projectileAttackComponent.
Factory
Multiple projectiles can be created using this factory.
New projectile configurations can be made as public createprojectile() methods in this factory such as the shotgun projectile.
Should I use projectile components on non-projectiles
Yes!
Projectile specific components are designed to be uncoupled from ProjectileFactory entities, many things can act like a projectile, or have projectiles lifecycle (shot, collide, attack, dispose). By apply projectile components to non-projectile entities.
Implementations
Lets say you want to make a npc that charges like a bull when a player shoots their gun. This is a perfect application for ProjectileActionsComponent. The bull will charge on command and stop charging after a collision. It wont be disposed and if it hits anything along the way the npc touchAttackComponent will trigger and attempt an attack.
Similarly, lets say you are designing an object entity, that if bumped, shoots across the map in the direction pushed. Adding both ProjectileAttackComponent and ProjectileActionsComponent after being pushed for a few seconds would do the trick. Now that rock or tree is a big old flying wall. Give it a combatStatsComponent and now thats a serious weapon or leave it out and now you have some cool puzzle game style sliding walls or falling rocks.
Now don't be fooled, that is a simple way of describing a hard little feature but its a good application either way.
This uncoupling is important architecture. If you are extending projectiles, try to maintain the idea that components are contained value adds all on their own.
ProjectileActions.
This component is dependant on a phsyicsMovmentComponent, and an animationRenderComponent. This component takes its entity to the position of its parent on the first update, then moves it in a straight line on a given layer at speed, it will also trigger an animation for its voyage. This action occurs on shoot() method.
ProjectileAttackComponent.
This component depends on projectileActions, ColliderComponent, CombatStatsComponent and renderAnimaitonComponent. This component will force any qualifying entity into a projectile lifecycle. Entities with this component are expected to behave like a bullet. They are shot on creation, and a collision is waited on, when collided they attempt an attack, and are then disposed.
Assets
Projectile default animation.
Images/Projectile/GreenShoot.png
Images/Projectile/GreenShoot.atlas
Citation: (ho88it,2020)
Made By: https://ho88it.itch.io/ date: 2020
Sourced From: https://ho88it.itch.io/2-d-projectile-sprites-wild-west-character-pack date: 2024
this is the size they will approximately come up in the game.
A closer look.
ho88it has agreed for the public use of the pixel art.
Animal Projectiles
Dragon
Dragon projectile are from this file: images/npc/dragon/dragon.png
Cthulhu and Kitsune
All the projectile assets are from the following open-source website: [Free Effect and Bullet 16x16]https://bdragon1727.itch.io/free-effect-and-bullet-16x16)
Cthulhu:
Kitsune:
- Last phases:
- Normal phases:
Conclusion
By implementing a well-defined projectile system that includes the ProjectileFactory
, ProjectileAttackComponent
, and ProjectileActions
, the game significantly enhances the combat experience. This provides players with various strategic options when using different weapons, ensuring a more engaging and dynamic gameplay experience. Understanding projectile behavior and their interactions within the game world is crucial for maintaining fun and challenge.