Ranged Weapon Implementation - UQdeco2800/2022-studio-2 GitHub Wiki
Summary
This wiki page will explain the implementation of ranged weapons like bows to deal damage to enemies without needing to be in close proximity with the enemy. This implementation is heavily based on Projectile Skill by team 02. Therefore, this documentation will talk about the changes made with respect to their code, and not the code from scratch.
PlayerTouchAttackComponent
Located in: source/core/src/main/com/deco2800/game/components/player/PlayerTouchAttackComponent.java
In the attack
function, if the weapon equipped is a ranged weapon, then the spawnWeaponProjectile()
method is called in the current gameArea, be it ForestGameArea
or UndergroundGameArea
.
else if (weaponEquipped != null && weaponEquipped.checkEntityType(EntityTypes.RANGED)) {
if (ServiceLocator.getGameArea() instanceof ForestGameArea) {
((ForestGameArea) ServiceLocator.getGameArea()).spawnWeaponProjectile();
}
else if (ServiceLocator.getGameArea() instanceof UndergroundGameArea){
((UndergroundGameArea) ServiceLocator.getGameArea()).spawnWeaponProjectile();
}
}
GameArea
Located in: source/core/src/main/com/deco2800/game/areas/___GameArea.java
In the gameAreas at source/core/src/main/com/deco2800/game/areas/terrain, the spawnWeaponProjectile()
method initialises a new projectile entity with createWeaponProjectile()
from ProjectileFactory
at the players position,
public void spawnWeaponProjectile() { //TEAM 04
Entity newProjectile = ProjectileFactory.createWeaponProjectile(player, 0);
spawnEntityAt(newProjectile,
new GridPoint2((int) player.getCenterPosition().x, (int) player.getCenterPosition().y),
true, true);
}
ProjectileFactory
Located in: source/core/src/main/com/deco2800/game/entities/factories/ProjectileFactory.java
In the ProjectileFactory
, the createWeaponProjectile()
initialises an projectile entity with a CombatStatsComponent
tied to it. The damage
value being inserted into the component is the damage value of the equipped ranged weapon with the following code
double dmg = player.getComponent(InventoryComponent.class).getEquipable(0).getComponent(PhysicalWeaponStatsComponent.class).getDamage();
The other difference with respect to createBasePlayerProjectile()
created by team02 is that the animation atlases' path is changed to the plungerBowProjectile's path. Also, the frameDuration
parameter in addAnimation
is adjusted to refine the animations displayed.
AnimationRenderComponent projectileAnimator = new AnimationRenderComponent(
ServiceLocator.getResourceService().getAsset("images/CombatItems/animations/PlungerBow/plungerBowProjectile.atlas",
TextureAtlas.class));
projectileAnimator.addAnimation("upright",0.05f, Animation.PlayMode.LOOP);
projectileAnimator.addAnimation("right",0.05f, Animation.PlayMode.LOOP);
projectileAnimator.addAnimation("downright",0.05f, Animation.PlayMode.LOOP);
projectileAnimator.addAnimation("down",0.05f, Animation.PlayMode.LOOP);
projectileAnimator.addAnimation("downleft",0.05f, Animation.PlayMode.LOOP);
projectileAnimator.addAnimation("left",0.05f, Animation.PlayMode.LOOP);
projectileAnimator.addAnimation("upleft",0.05f, Animation.PlayMode.LOOP);
projectileAnimator.addAnimation("up",0.05f, Animation.PlayMode.LOOP);
Compared to the projectile
entity in createBasePlayerProjectile
, instead of adding a PlayerSkillProjectileComponent
to the entity, a WeaponArrowProjectileComponent
is added to the entity.
WeaponArrowProjectileComponent
Located in: source/core/src/main/com/deco2800/game/components/CombatItemsComponents/WeaponArrowProjectileComponent.java
This component is basically a copy of PlayerSkillProjectileComponent
, with changes differences stated below.
The velocity of the projectile is changed to 6 instead of the 15 in PlayerSkillProjectileComponent
.
private final Vector2 projectileVelocity = new Vector2(6, 6);
Next, in the create()
method, an extra listener is added
entity.getEvents().addListener("collisionStart", this::onCollisionStart);
The onCollisionStart
method is called when there is a collision between the arrow with another entity. If the entity that collides with the arrow is an ememy (checked with their fixtures), then the given attack sounds will play.
private void onCollisionStart(Fixture me, Fixture other) {
Entity enemy = ((BodyUserData) other.getBody().getUserData()).entity;
if (enemy.checkEntityType(EntityTypes.ENEMY)) {
Sound attackSound = ServiceLocator.getResourceService().getAsset("sounds/plungerArrowSound.mp3", Sound.class);
attackSound.play();
}
}
Back to Combat Items Contents Page
Author
- Eugene Chong
- GitHub: @eugene2341
- Discord: gene#0005
- Slack: Eugene Chong