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 4 Levels - General Levels Updates #200

Merged
merged 36 commits into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
3b8cafe
clean up
samsully Sep 15, 2023
b97baee
fixed entity removed before shoot task complete error
samsully Sep 15, 2023
6f3f098
Created Wave Implementation
meganroxburgh Sep 20, 2023
b2956ac
Edited WaveTask and WaveService, need to still incorporate WaveClass
meganroxburgh Sep 26, 2023
f04593b
Modifies spawnXenoGrunts() into spawnMob() to allow for different mob…
bojyyy Sep 27, 2023
f809149
Fixed merge conflicts
bojyyy Sep 27, 2023
8b8bd25
Adds wave spawning functionality
bojyyy Sep 27, 2023
925989d
Implements WaveClass
bojyyy Sep 27, 2023
e3ef337
Fixes bugs in wave functionality
bojyyy Sep 27, 2023
477e2fc
Adds LevelWaves class, which can store and spawn waves
bojyyy Sep 27, 2023
ea67bfe
Adds functionality to support multiple waves in a level
bojyyy Sep 27, 2023
2e9bf49
Merging main into updated changes to waves
BlairCannon97 Sep 28, 2023
97c2a99
Added sounds for wave start/finishing. Added sound triggers in the Wa…
BlairCannon97 Sep 28, 2023
177f725
Added comments to WaveClass, WaveTask and ForestGameArea
meganroxburgh Sep 28, 2023
b9845da
Fixed build error in WaveTask
meganroxburgh Sep 28, 2023
547562a
Merge branch 'Team-4---Waves' into team4-waves-megan2
meganroxburgh Sep 28, 2023
a963180
Fixes bugs in wave functionality and allows for different mob types
bojyyy Sep 28, 2023
358bfd7
Added a check to WaveTask to see if level has been completed (no wave…
meganroxburgh Sep 28, 2023
a3929fd
Added comments to wave related tasks in ForestGameArea, LevelWaves, W…
meganroxburgh Sep 28, 2023
3f16139
Updated comments in WaveService
meganroxburgh Sep 28, 2023
ca4a8ed
Fixed bug where wave sounds were causing crashes due to incorrect loa…
BlairCannon97 Sep 28, 2023
14fd5a5
Merge branch 'Team-4---Waves' of github.com:UQcsse3200/2023-studio-3 …
BlairCannon97 Sep 28, 2023
c1d2ad6
Added test directory 'waves' to test suite, and WaveTaskTest class
BlairCannon97 Sep 28, 2023
251b0a6
Added some basic tests into WaveTaskTest. Added a new method into Wav…
BlairCannon97 Sep 28, 2023
772789a
Sounds trigger correctly at the beginning and end of each wave
BlairCannon97 Sep 29, 2023
df754e8
Added WaveCount to WaveService.java and added code that increases wav…
Sep 29, 2023
0911e15
Merge remote-tracking branch 'origin/Team-4---Waves' into Team-4---Wa…
Sep 29, 2023
c624480
Changed logger info for waveService waveNumber in WaveTask.java
Sep 29, 2023
3c5b5e6
Adds functionality to WaveService to allow for an indication of which…
bojyyy Sep 29, 2023
40b6967
Adds functionality to WaveService to allow for an indication of which…
bojyyy Sep 29, 2023
6ac2e1f
Fixes merge conflicts
bojyyy Sep 29, 2023
6e056bc
Added Test classes WaveFactoryTest, LevelWavesTest and WaveClassTest …
BlairCannon97 Sep 30, 2023
1dd91e6
Merge branch 'Team-4---Waves' into Team-4---Blair
BlairCannon97 Sep 30, 2023
24e36dd
Added further tests into the wave test classes. Some helper methods h…
BlairCannon97 Sep 30, 2023
60ff3da
Added methods for UI team giving a timeStamp of when the next mobs wi…
Sep 30, 2023
2b80bc8
Merge remote-tracking branch 'origin/Team-4---Waves' into Team-4---Waves
Sep 30, 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
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
66 changes: 48 additions & 18 deletions source/core/src/main/com/csse3200/game/areas/ForestGameArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,17 @@ public class ForestGameArea extends GameArea {
"sounds/engineers/firing_auto.mp3",
"sounds/engineers/firing_single.mp3",
"sounds/projectiles/on_collision.mp3",
"sounds/projectiles/explosion.mp3"
"sounds/projectiles/explosion.mp3",
"sounds/waves/wave-start/Wave_Start_Alarm.ogg",
"sounds/waves/wave-end/Wave_Over_01.ogg"
};
private static final String backgroundMusic = "sounds/background/Sci-Fi1.ogg";
private static final String[] forestMusic = {backgroundMusic};

private final TerrainFactory terrainFactory;

private Entity player;
private Entity waves;

// Variables to be used with spawn projectile methods. This is the variable
// that should occupy the direction param.
Expand All @@ -192,7 +195,9 @@ public ForestGameArea(TerrainFactory terrainFactory) {
this.terrainFactory = terrainFactory;
}

// Add this method to start the wave spawning timer when the game starts.
/**
* Add this method to start the wave spawning timer when the game starts.
*/
private void startWaveTimer() {
waveTimer = new Timer();
waveTimer.scheduleAtFixedRate(new TimerTask() {
Expand All @@ -203,14 +208,19 @@ public void run() {
}, 0, 10000); // 10000 milliseconds = 10 seconds
}

// Add this method to stop the wave timer when the game ends or as needed.
/**
* Add this method to stop the wave timer when the game ends or as needed.
*/
private void stopWaveTimer() {
if (waveTimer != null) {
waveTimer.cancel();
waveTimer = null;
}
}

/**
* Cases to spawn a wave
*/
private void spawnWave() {
wave++;
switch (wave) {
Expand Down Expand Up @@ -255,13 +265,17 @@ public void create() {

// Set up infrastructure for end game tracking
player = spawnPlayer();
player.getEvents().addListener("spawnWave", this::spawnWave);

waves = WaveFactory.createWaves();
spawnEntity(waves);
waves.getEvents().addListener("spawnWave", this::spawnMob);

playMusic();
spawnXenoGrunts();
startWaveTimer();
//spawnXenoGrunts();
//startWaveTimer();
spawnScrap();
spawnDeflectXenoGrunt(15, 5);
spawnSplittingXenoGrunt(15, 4);
//spawnDeflectXenoGrunt(15, 5);
//spawnSplittingXenoGrunt(15, 4);
spawnScrap();
spawnTNTTower();
spawnWeaponTower();
Expand Down Expand Up @@ -469,17 +483,33 @@ private void spawnProjectile(Vector2 position, short targetLayer, int space, int
Entity Projectile = ProjectileFactory.createFireBall(targetLayer, new Vector2(direction, position.y + space), speed);
Projectile.setPosition(position);
spawnEntity(Projectile);
}

private void spawnXenoGrunts() {
int[] pickedLanes = random.ints(1, 7)
.distinct().limit(5).toArray();
for (int i = 0; i < NUM_GRUNTS; i++) {
GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]);
Entity xenoGrunt = NPCFactory.createXenoGrunt();
xenoGrunt.setScale(1.5f, 1.5f);
spawnEntityAt(xenoGrunt, randomPos, true, false);
}

/**
* Spawn an entity on the map. Is called during a wave. Add cases here for each mob type
* @param entity mob to be spawned
* @param randomPos position to be spawned at
*/
public void spawnMob(String entity, GridPoint2 randomPos) {
Entity mob;
switch (entity) {
case "Xeno":
mob = NPCFactory.createXenoGrunt();
break;
case "SplittingXeno":
mob = NPCFactory.createSplittingXenoGrunt();
break;
case "DodgingDragon":
mob = NPCFactory.createDodgingDragonKnight();
break;
case "DeflectXeno":
mob = NPCFactory.createDeflectXenoGrunt();
break;
default:
mob = NPCFactory.createBaseNPC();
}
mob.setScale(1.5f, 1.5f);
spawnEntityAt(mob, randomPos, true, false);
}

// * TEMPORARY FOR TESTING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,17 @@ private void onCollisionEnd(Fixture me, Fixture other) {
}
}

/**
* Choose the weapon to use against the given fixture.
*
* If the fixture has been removed (died) return null, else return the weapon to use.
* */
public Weapon chooseWeapon(Fixture other) {
Entity target = ((BodyUserData) other.getBody().getUserData()).entity;
BodyUserData data = ((BodyUserData) other.getBody().getUserData());
if (data == null) {
return null;
}
Entity target = data.entity;
Weapon weapon = null;
if (target.getComponent(CombatStatsComponent.class) != null) {
weapon = combatStats.getWeapon(target);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,29 +65,27 @@ public void start() {
@Override
public void update() {

//Update the position of the mob
// Update the position of the mob
mobPosition = owner.getEntity().getPosition();

// If the mob is at zero health, kill the mob,
// play the death animation and stop the task
// This method is the idea of Ahmad who very kindly helped
// with section, massive props to him for his help!
// This method is the idea of Ahmad who very kindly helped with section, massive props to him for his help!
if (!isDead && owner.getEntity().getComponent(CombatStatsComponent.class).isDead()) {
this.owner.getEntity().getEvents().trigger("dieStart");
currentTask.stop();
isDead = true;
ServiceLocator.getWaveService().updateEnemyCount();
}

// Check if the mob has finished death animation
else if (isDead && owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) {

// Drop scrap at the mobs location for player
// to collect.
// Drop scrap at the mobs location
Entity scrap = DropFactory.createScrapDrop();
scrap.setPosition(mobPosition.x,mobPosition.y);
ServiceLocator.getEntityService().register(scrap);

// Delete the mob.
// Delete the mob and update count for number of mobs remaining in the wave
owner.getEntity().setFlagForDelete(true);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ else if (isDead && owner.getEntity().getComponent(AnimationRenderComponent.class
Entity scrap = DropFactory.createScrapDrop();
scrap.setPosition(mobPosition.x,mobPosition.y);
ServiceLocator.getEntityService().register(scrap);
ServiceLocator.getWaveService().updateEnemyCount();

// Delete the mob.
owner.getEntity().setFlagForDelete(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.csse3200.game.components.tasks.waves;

import com.badlogic.gdx.math.GridPoint2;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.services.GameTime;
import com.csse3200.game.services.ServiceLocator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

public class LevelWaves extends Entity {
List<WaveClass> waves = new ArrayList<>();
private float spawnDelay;
private GameTime gameTime;
private long startTime;
private Random rand = new Random();
private int currentRandom = 0;
private int previousRandom = 0;
private int mobIndex;
private int waveIndex;
private int numWaves;

/**
* Constructor for the LevelWaves class
* @param spawnDelay time to elapse between each wave
*/
public LevelWaves(int spawnDelay) {
this.spawnDelay = spawnDelay;
this.gameTime = ServiceLocator.getTimeSource();
this.startTime = this.gameTime.getTime();
this.mobIndex = 0;
this.waveIndex = 0;
this.numWaves = 0;

long currentTime = ServiceLocator.getTimeSource().getTime();
// Setting the timestamp for when the next mobs will spawn.
// Currently, the delay of mobs spawning after wave start
// is hardcoded but will fix in the next push.
ServiceLocator.getWaveService().setNextWaveTime(currentTime + 10000);
}

/**
* Add a wave to the level and increment the total number of waves
* @param wave to be added
*/
public void addWave(WaveClass wave) {
this.numWaves++;
this.waves.add(wave);
}

/**
* Retrieve a wave at an index in the list
* @param index wave number to be retireved
* @return instance of a wave class
*/
public WaveClass getWave(int index) {
return this.waves.get(index);
}

/**
* Spawn the wave and all the associated mobs for that wave
*/
public void spawnWave() {
if (gameTime.getTime() >= startTime + spawnDelay * 1000) {
do {
currentRandom = rand.nextInt(1, 7);
} while (currentRandom == previousRandom);
ServiceLocator.getWaveService().setNextLane(currentRandom);
GridPoint2 randomPos = new GridPoint2(19, currentRandom);
this.getEvents().trigger("spawnWave", waves.get(waveIndex)
.getMobs().get(mobIndex), randomPos);
startTime = gameTime.getTime();
mobIndex++;
previousRandom = currentRandom;
} else if (mobIndex == waves.get(waveIndex).getSize()) {
this.getEvents().trigger("waveFinishedSpawning");
mobIndex = 0;
}
}

/**
* Set the wave index
* @param index
*/
public void setWaveIndex(int index) {
this.waveIndex = index;
}

/**
* Get the total number of waves in this level
* @return number of waves in the level
*/
public int getNumWaves() {
return this.numWaves;
}

public float getSpawnDelay() {
return this.spawnDelay;
}

public long getStartTime() {
return this.startTime;
}

/**
* Get the current mob index
* @return mob index
*/
public int getMobIndex() {
return this.mobIndex;
}

/**
* Get the current wave index
* @return wave index
*/
public int getWaveIndex() {
return this.waveIndex;
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.csse3200.game.components.tasks.waves;

import com.badlogic.gdx.math.GridPoint2;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.services.GameTime;
import com.csse3200.game.services.ServiceLocator;

import java.util.*;


public class WaveClass {
private HashMap<String, Integer> entities;
private GameTime gameTime;
private long startTime;
private List<String> wave;
private Random rand = new Random();
private int mobIndex;

/**
* Constructor for the WaveClass
* @param entities: HashMap of entities and the quantity of them to be spawned in this wave
*/
public WaveClass(HashMap<String, Integer> entities) {
this.entities = entities;
this.wave = entitiesToWave();
this.mobIndex = 0;
}

/**
* Get the entities that are part of this wave and randomise the order they are spawned
* @return mobs for the wave
*/
private List<String> entitiesToWave() {
List<String> enemies = new ArrayList<>();
for (Map.Entry<String, Integer> set : entities.entrySet()) {
for (int i = 0; i < set.getValue(); i++) {
enemies.add(set.getKey());
}
}
Collections.shuffle(enemies);
return enemies;
}

/**
* Gets the current number of entities spawned in the wave
* @return size of the current wave (number of entities)
*/
public int getSize() {
return this.wave.size();
}

/**
* Gets the current entities that have spawned in the wave
* @return list of mobs in the current wave
*/
public List<String> getMobs() {
return this.wave;
}

}
Loading
Loading