Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Team 2 alasdair branch #97

Merged
merged 67 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
21e7687
Added direction variables for projectiles i.e. towards mobs or toward…
JSLLW Aug 24, 2023
b907d19
Fixed bug that I had accidentally introduced in the last commit.
JSLLW Aug 24, 2023
a6b4dd9
Merge branch 'Team-1--Projectiles' of https://github.com/UQcsse3200/2…
MiniSoda17 Aug 24, 2023
93bfc36
Added more parameters to spawn projectile functions for better adapta…
JSLLW Aug 24, 2023
8508a17
Merge branch 'Team-1--Projectiles' of https://github.com/UQcsse3200/2…
MiniSoda17 Aug 24, 2023
1ca17c6
Added ability to spawn multiple projectiles of any odd number greater…
JSLLW Aug 24, 2023
d4cd555
Merge branch 'Team-1--Projectiles' of https://github.com/UQcsse3200/2…
JSLLW Aug 24, 2023
43e519b
Improved spawnMultiProjectile function
JSLLW Aug 24, 2023
f5bcfbb
Add minor temporary changes for testing
freshc0w Aug 25, 2023
88c9388
Add togglable feature for destroying projectile on collision
freshc0w Aug 25, 2023
22e218f
Add selective targeting for projectiles and configure exception handl…
freshc0w Aug 25, 2023
dcdf9fd
Make base projectile factory method and create fireball factory method
freshc0w Aug 25, 2023
9694abf
Initialise aoe fireball class
freshc0w Aug 25, 2023
e66be18
Change json naming for config
freshc0w Aug 25, 2023
3081ca5
Merge remote-tracking branch 'origin/main' into interaction
freshc0w Aug 25, 2023
710f088
Revert "Change json naming for config"
freshc0w Aug 25, 2023
904fc65
Change projectile to fireball in config.json
freshc0w Aug 25, 2023
9cd1bad
Merge main into team1 branch
freshc0w Aug 26, 2023
cd8d41f
Initialise collider test
freshc0w Aug 26, 2023
ebcc19f
Created aoe fireball entity and touch attack component with aoe size …
gregchan550 Aug 26, 2023
88d7dd9
Removing code smells from Team-1--Projectiles branch
MiniSoda17 Aug 26, 2023
611c93c
Added new method in entity service which gets nearby entities and als…
gregchan550 Aug 27, 2023
3cc0dd3
Fixed bug where game was crashing because createaoefireball was tryin…
gregchan550 Aug 27, 2023
373ae0d
Update README.md
The-AhmadAA Aug 27, 2023
e79570b
Merge pull request #56 from UQcsse3200/Team-2--Towers
Mohamad11Dab Aug 28, 2023
a39787b
added event listener so that aoe damage can be applied on collision end
gregchan550 Aug 28, 2023
996623e
Added JUnit testing to the ProjectileFactory
cindyle1 Aug 28, 2023
f212be4
Merge branch 'Team-1--Projectiles' of github.com:UQcsse3200/2023-stud…
cindyle1 Aug 28, 2023
55ad213
Removed a variable which caused the TowerProjectileFactory Junit test…
cindyle1 Aug 28, 2023
a1fc6fb
Removed the function that caused JUnit test failure
cindyle1 Aug 28, 2023
112ecc6
Removed 'static' in maxSpeed variable from PhysicsMovementComponent t…
cindyle1 Aug 28, 2023
d045449
Fixed bug in setSpeed
cindyle1 Aug 28, 2023
92f007e
Added FireBall entity to test in Junit
MiniSoda17 Aug 28, 2023
53ef509
Merge branch 'Team-1--Projectiles' of https://github.com/UQcsse3200/2…
MiniSoda17 Aug 28, 2023
9421369
fixed bug where when aoe damage is applied it deals double damage
gregchan550 Aug 28, 2023
d890cac
fixed .vimrc nocompatible, relativenumber, fillchars+=eob:~
gregchan550 Aug 28, 2023
fd72989
Merge branch 'Team-1--Projectiles' of https://github.com/UQcsse3200/2…
MiniSoda17 Aug 28, 2023
5edf61a
Added some javadocs c:; cd 'c:\Users\Joey\OneDrive\Desktop\CSSE3200\r…
JSLLW Aug 28, 2023
d255a26
Added to javadocs
JSLLW Aug 28, 2023
d5f1bc1
Merge branch 'Team-1--Projectiles' of https://github.com/UQcsse3200/2…
MiniSoda17 Aug 28, 2023
fed85e9
Implemented additional Junit testing for ProjectileFactory creation o…
MiniSoda17 Aug 28, 2023
0224fb5
Add dispose testing and remove fireball testing.
MiniSoda17 Aug 29, 2023
ed364e9
Remove code smells
MiniSoda17 Aug 29, 2023
305973a
Merge with Team-2 towers state
MiniSoda17 Aug 29, 2023
7a430a8
Pull from main
MiniSoda17 Aug 29, 2023
19334e3
Pull from main
MiniSoda17 Aug 29, 2023
9069ebc
Fix merge conflicts
MiniSoda17 Aug 29, 2023
8e1abd9
Merge pull request #65 from UQcsse3200/Team-2--Towers
The-AhmadAA Aug 29, 2023
95764bd
Fix merge conflicts with Tower combat stats and combatstats component
MiniSoda17 Aug 29, 2023
e4a2738
merge main
MiniSoda17 Aug 29, 2023
569fb24
fixed merge conflict
The-AhmadAA Aug 29, 2023
0841f6e
Att getEntityAtPosition at EntityService
MiniSoda17 Aug 29, 2023
7efc04e
fix merge conflict
The-AhmadAA Aug 29, 2023
07ab4db
commented out line checkAndDeleteBodies()
The-AhmadAA Aug 29, 2023
449c63a
Merge pull request #71 from UQcsse3200/Team-1--Projectiles
The-AhmadAA Aug 29, 2023
cb83eb8
bump
Jonoym Aug 29, 2023
d307431
Merge pull request #72 from UQcsse3200/test
Jonoym Aug 29, 2023
cc9a4c2
Update gradle_release.yaml
Jonoym Aug 29, 2023
6a3ae93
Updated javadocs
Jonoym Aug 29, 2023
0dddd12
Created new TowerUpgraderComponent class, which listens for an event …
AlasdairS4698737 Aug 31, 2023
9cde24a
Added capabilty for TowerUpgraderComponent to increase the the base a…
AlasdairS4698737 Aug 31, 2023
0d189ca
Merge branch 'main' into Team-2--Alasdair-Branch
AlasdairS4698737 Sep 1, 2023
98c3dc5
Fixed filename typo
AlasdairS4698737 Sep 3, 2023
c75f782
Implemented the upgrading of a tower's max health, including changes …
AlasdairS4698737 Sep 3, 2023
82715be
Added fire rate upgrade functionality to TowerUpgraderComponent, also…
AlasdairS4698737 Sep 6, 2023
705c3e2
TowerUpgraderComponent is now added to tower entities when they are c…
AlasdairS4698737 Sep 6, 2023
23d4e6e
Added repair capability to TowerUpgraderComponent
AlasdairS4698737 Sep 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/gradle_release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
GRADLE_DIR: 'source' # Modify this to wherever './gradlew' is

- name: Automatic Release # note the path for the files on this one
uses: marvinpinto/action-automatic-releases@v1.1.1
uses: marvinpinto/action-automatic-releases@v1.2.1
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
Expand All @@ -58,4 +58,4 @@ jobs:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# GRADLE_DIR: 'source' # Modify this to wherever './gradlew' is
# run: ./gradlew sonarqube --info
# run: ./gradlew sonarqube --info
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# UQ 2023 Studio 3
# UQ 2023 Studio 3

## Description

Expand All @@ -12,6 +12,7 @@ You are welcome to use the game engine for your own purposes. It is released und
- [SonarCloud](https://sonarcloud.io/project/overview?id=UQcsse3200_2023-studio-3)


## Team 2 - Tower Branch
## Outworld Outposts - A tower defense game.

Implements defense towers in the Outworld Outposts game. Any questions or discussion, please contact Team 2
This is the main branch for Outworld Outposts, a game developed by Studio 3 of CSSE3200 (Semester 2 2023).
A game developed in the CSSE3200 adaptation of the LibGDX game engine. For details and documentation, refer to the [Wiki](https://github.com/UQcsse3200/2023-studio-3/wiki)
7 changes: 6 additions & 1 deletion source/core/assets/configs/NPCs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
"health": 40,
"baseAttack": 10
},
"projectile": {
"ghostKing": {
"health": 100,
"baseAttack": 25,
"spookyFactor": 7
},
"fireBall": {
"health": 100,
"baseAttack": 10
}
Expand Down
128 changes: 97 additions & 31 deletions source/core/src/main/com/csse3200/game/areas/ForestGameArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public class ForestGameArea extends GameArea {
private int bossSpawnInterval = 10000; // 1 minute in milliseconds

private static final int NUM_WEAPON_TOWERS = 3;
private static final GridPoint2 PLAYER_SPAWN = new GridPoint2(10, 10);
private static final GridPoint2 PLAYER_SPAWN = new GridPoint2(0, 15);
// Temporary spawn point for testing
private static final float WALL_WIDTH = 0.1f;

private static final GridPoint2 BOSS_SPAWN = new GridPoint2(5, 5);
Expand Down Expand Up @@ -99,11 +100,15 @@ public class ForestGameArea extends GameArea {
"sounds/stow.mp3"
};
private static final String backgroundMusic = "sounds/Sci-Fi1.ogg";

private static final String[] forestMusic = {backgroundMusic};

private final TerrainFactory terrainFactory;

private Entity player;

// Variables to be used with spawn projectile methods. This is the variable
// that should occupy the direction param.
private static final int towardsMobs = 100;
private Entity bossKing1;
private Entity bossKing2;

Expand Down Expand Up @@ -131,6 +136,12 @@ public void create() {
spawnMountains();
player = spawnPlayer();

playMusic();

// Types of projectile
spawnAoeProjectile(new Vector2(0, 10), player, towardsMobs, new Vector2(2f, 2f), 1);
spawnProjectile(new Vector2(0, 10), player, towardsMobs, new Vector2(2f, 2f));
spawnMultiProjectile(new Vector2(0, 10), player, towardsMobs, 20, new Vector2(2f, 2f), 7);
spawnXenoGrunts();

spawnGhosts();
Expand Down Expand Up @@ -221,6 +232,13 @@ private Entity spawnPlayer() {
return newPlayer;
}

// Spawn player at a specific position
private Entity spawnPlayer(GridPoint2 position) {
Entity newPlayer = PlayerFactory.createPlayer();
spawnEntityAt(newPlayer, position, true, true);
return newPlayer;
}

private void spawnGhosts() {
GridPoint2 minPos = new GridPoint2(0, 0);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(0, 2);
Expand All @@ -237,21 +255,59 @@ private void spawnGhosts() {
private Entity spawnBossKing1() {
GridPoint2 minPos = new GridPoint2(0, 0);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2);
GridPoint2 randomPos
= new GridPoint2(0, 0);
Entity ghostKing = NPCFactory.createGhostKing(player);
spawnEntityAt(ghostKing, randomPos, true, true);
return ghostKing;
}

for (int i = 0; i < NUM_BOSS; i++) {
int fixedX = terrain.getMapBounds(0).x - 1; // Rightmost x-coordinate
int randomY = MathUtils.random(0, maxPos.y);
GridPoint2 randomPos = new GridPoint2(fixedX, randomY);
bossKing1 = BossKingFactory.createBossKing1(player);
spawnEntityAt(bossKing1,
randomPos,
true,
false);
}
return bossKing1;
/**
* Spawns a projectile that only heads towards the enemies in its lane.
*
* @param position The position of the Entity that's shooting the projectile.
* @param target The enemy entities of the "shooter".
* @param direction The direction the projectile should head towards.
* @param speed The speed of the projectiles.
*
*/
private void spawnProjectile(Vector2 position, Entity target, int direction, Vector2 speed) {
Entity Projectile = ProjectileFactory.createFireBall(target, new Vector2(direction, position.y), speed);
Projectile.setPosition(position);
spawnEntity(Projectile);
}

/**
* Spawns a projectile to be used for multiple projectile function.
*
* @param position The position of the Entity that's shooting the projectile.
* @param target The enemy entities of the "shooter".
* @param space The space between the projectiles' destination.
* @param direction The direction the projectile should head towards.
* @param speed The speed of the projectiles.
*
*/
private void spawnProjectile(Vector2 position, Entity target, int space, int direction, Vector2 speed) {
Entity Projectile = ProjectileFactory.createFireBall(target, new Vector2(direction, position.y + space), speed);
Projectile.setPosition(position);
spawnEntity(Projectile);
}

// private Entity spawnBossKing() {
// for (int i = 0; i < NUM_BOSS; i++) {
// int fixedX = terrain.getMapBounds(0).x - 1; // Rightmost x-coordinate
// int randomY = MathUtils.random(0, maxPos.y);
// GridPoint2 randomPos = new GridPoint2(fixedX, randomY);
// bossKing1 = BossKingFactory.createBossKing1(player);
// spawnEntityAt(bossKing1,
// randomPos,
// true,
// false);
// }
// return bossKing1;

// }

private void spawnXenoGrunts() {
GridPoint2 minPos = terrain.getMapBounds(0).sub(1, 5);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(1, 25);
Expand Down Expand Up @@ -293,27 +349,37 @@ private Entity spawnBossKing2() {
}

/**
* Spawns a projectile currently just in the center of the game
*
* @return a new projectile
* Creates multiple projectiles that travel simultaneous. They all have same
* the starting point but different destinations.
*
* @param position The position of the Entity that's shooting the projectile.
* @param target The enemy entities of the "shooter".
* @param direction The direction the projectile should head towards.
* @param space The space between the projectiles' destination.
* @param speed The speed of the projectiles.
* @param quantity The amount of projectiles to spawn.
*/
private void spawnProjectile(Vector2 speed) {
Entity newProjectile = ProjectileFactory.createProjectile(bossKing1, player, new Vector2(100, bossKing1.getPosition().x), speed);
newProjectile.setPosition(bossKing1.getPosition());
spawnEntity(newProjectile);
private void spawnMultiProjectile(Vector2 position, Entity target, int direction, int space, Vector2 speed, int quantity) {
int half = quantity / 2;
for (int i = 0; i < quantity; i++) {
spawnProjectile(position, target, space * half, direction, speed);
--half;
}
}

private void spawnMultiProjectile(Vector2 speed) {
Entity newTopProjectile = ProjectileFactory.createProjectile(bossKing1, player, new Vector2(100, player.getPosition().x + 30), speed);
newTopProjectile.setPosition(player.getPosition());
Entity newMiddleProjectile = ProjectileFactory.createProjectile(bossKing1, player, new Vector2(100, player.getPosition().x), speed);
newMiddleProjectile.setPosition(player.getPosition());
Entity newBottomProjectile = ProjectileFactory.createProjectile(bossKing1, player, new Vector2(100, player.getPosition().x - 30), speed);
newBottomProjectile.setPosition(player.getPosition());

spawnEntity(newTopProjectile);
spawnEntity(newMiddleProjectile);
spawnEntity(newBottomProjectile);
/**
* Returns projectile that can do an area of effect damage
*
* @param position The position of the Entity that's shooting the projectile.
* @param target The enemy entities of the "shooter".
* @param direction The direction the projectile should head towards.
* @param speed The speed of the projectiles.
* @param aoeSize The size of the area of effect.
*/
private void spawnAoeProjectile(Vector2 position, Entity target, int direction, Vector2 speed, int aoeSize) {
Entity Projectile = ProjectileFactory.createAOEFireBall(target, new Vector2(direction, position.y), speed, aoeSize);
Projectile.setPosition(position);
spawnEntity(Projectile);
}

private void spawnWeaponTower() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.csse3200.game.components;

import com.badlogic.gdx.physics.box2d.Fixture;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.physics.BodyUserData;
import com.csse3200.game.physics.components.HitboxComponent;
import com.csse3200.game.services.ServiceLocator;

import com.badlogic.gdx.utils.Array;

public class AoeComponent extends Component {
private final float radius;
private HitboxComponent hitboxComponent;

/**
* Constructor for the AoEComponent.
*
* @param radius The radius of the area-of-effect.
*/
public AoeComponent(float radius) {
this.radius = radius;
}

@Override
public void create() {
entity.getEvents().addListener("collisionStart", this::onCollisionStart);
entity.getEvents().addListener("collisionEnd", this::onCollisionEnd);
hitboxComponent = entity.getComponent(HitboxComponent.class);
}

private void onCollisionStart(Fixture me, Fixture other) {
// Nothing to do on collision start
}

private void onCollisionEnd(Fixture me, Fixture other) {
if (hitboxComponent.getFixture() != me) {
// Not triggered by hitbox, ignore
return;
}
applyAoeDamage();
}
/**
* Apply damage to all entities within the area of effect (radius).
*/
public void applyAoeDamage() {
Entity hostEntity = getEntity();
CombatStatsComponent hostCombatStats = hostEntity.getComponent(CombatStatsComponent.class);

if (hostCombatStats == null) {
// The host entity does not have a CombatStatsComponent to deal damage
return;
}

Array<Entity> nearbyEntities = ServiceLocator.getEntityService().getNearbyEntities(hostEntity, radius);

for (Entity targetEntity : nearbyEntities) {
CombatStatsComponent targetCombatStats = targetEntity.getComponent(CombatStatsComponent.class);
if (targetCombatStats != null) {
targetCombatStats.hit(hostCombatStats);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class CombatStatsComponent extends Component {
private static final Logger logger = LoggerFactory.getLogger(CombatStatsComponent.class);
private int health;
private int baseAttack;
private final int fullHealth;
private int fullHealth;
private String state;
private ArrayList<Integer> drops;
private ArrayList<Melee> closeRangeAbilities;
Expand Down Expand Up @@ -99,6 +99,25 @@ public void addHealth(int health) {
changeState();
}

/**
* Returns the entity's fullHealth value (note that this does not influence the ability to set its actual health)
*
* @return The entity's fullHealth variable
*/
public int getMaxHealth() {
return fullHealth;
}

/**
* Sets the entity's fullHealth variable.
* Intended for when the entity's maximum health must be changed after creation, like upgrading a turret's HP.
*
* @param newMaxHealth The new value fullHealth should be set to
*/
public void setMaxHealth(int newMaxHealth) {
fullHealth = newMaxHealth;
}

/**
* Returns the entity's base attack damage.
*
Expand Down Expand Up @@ -130,6 +149,12 @@ public void hit(Integer damage) {
changeState();
}

// Default CombatStatsComponent that relies on the attacker's combatStatsComponent.
public void hit(CombatStatsComponent attacker) {
int newHealth = getHealth() - attacker.getBaseAttack();
setHealth(newHealth);
}

/**
* pick a random number from range 0 to the size of the list provided
* */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
public class TouchAttackComponent extends Component {
private short targetLayer;
private float knockbackForce = 0f;
private boolean disposeOnHit = false;
private int aoeSize = 0;
private CombatStatsComponent combatStats;
private HitboxComponent hitboxComponent;

Expand All @@ -41,9 +43,22 @@ public TouchAttackComponent(short targetLayer, float knockback) {
this.knockbackForce = knockback;
}

/**
* Create a component which attacks entities on collision, with knockback and self-dispose.
* @param targetLayer The physics layer of the target's collider.
* @param knockback The magnitude of the knockback applied to the entity.
* @param disposeOnHit Whether this entity should be disposed on hit.
*/
public TouchAttackComponent(short targetLayer, float knockback, boolean disposeOnHit) {
this.targetLayer = targetLayer;
this.knockbackForce = knockback;
this.disposeOnHit = disposeOnHit;
}

@Override
public void create() {
entity.getEvents().addListener("collisionStart", this::onCollisionStart);
entity.getEvents().addListener("collisionEnd", this::onCollisionEnd);
combatStats = entity.getComponent(CombatStatsComponent.class);
hitboxComponent = entity.getComponent(HitboxComponent.class);
}
Expand All @@ -70,7 +85,6 @@ private void onCollisionStart(Fixture me, Fixture other) {
targetStats.hit(combatStats.getBaseAttack());
}
}

// Apply knockback
PhysicsComponent physicsComponent = target.getComponent(PhysicsComponent.class);
if (physicsComponent != null && knockbackForce > 0f) {
Expand All @@ -79,5 +93,15 @@ private void onCollisionStart(Fixture me, Fixture other) {
Vector2 impulse = direction.setLength(knockbackForce);
targetBody.applyLinearImpulse(impulse, targetBody.getWorldCenter(), true);
}

if (disposeOnHit) {
Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity;
projectile.setFlagForDelete(true);
}
}

private void onCollisionEnd(Fixture me, Fixture other) {
// Nothing to do on collision end
}
}

Loading