Skip to content

Commit

Permalink
Add splitting mobs functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
freshc0w committed Sep 21, 2023
1 parent 1c7bd90 commit a67634a
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 9 deletions.
20 changes: 11 additions & 9 deletions source/core/src/main/com/csse3200/game/areas/ForestGameArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import com.csse3200.game.services.ResourceService;
import com.csse3200.game.services.ServiceLocator;
import com.csse3200.game.components.gamearea.GameAreaDisplay;
import com.csse3200.game.components.npc.SplitMoblings;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Random;
Expand Down Expand Up @@ -250,12 +252,12 @@ public void create() {
// spawnSplitFireWorksFireBall(new Vector2(2, 5), PhysicsLayer.NPC, towardsMobs, new Vector2(2f, 2f), 12);
// spawnEffectProjectile(new Vector2(2, 6), PhysicsLayer.NPC, towardsMobs, new Vector2(2f, 2f), ProjectileEffects.SLOW, false);
// spawnXenoGrunts();
// spawnWeaponTower();
spawnWeaponTower();

// spawnDragonKnight();
spawnFireWorm(19, 5); // * TEMPORARY
spawnXenoGrunt(19, 4);
// spawnDemonBoss();
spawnFireWorm(19, 5); // * TEMPORARY for testing
spawnSplittingXenoGrunt(17, 5);
spawnDemonBoss();
// spawnFireWorm();

//mobBoss1 = spawnMobBoss1();
Expand Down Expand Up @@ -495,11 +497,11 @@ private void spawnXenoGrunts() {
}

// * TEMPORARY FOR TESTING
private void spawnXenoGrunt(int x, int y) {
private void spawnSplittingXenoGrunt(int x, int y) {
GridPoint2 pos = new GridPoint2(x, y);
Entity xenoGrint = NPCFactory.createXenoGrunt(player);
xenoGrint.setScale(1.5f, 1.5f);
spawnEntityAt(xenoGrint, pos, true, true);
Entity xenoGrunt = NPCFactory.createSplittingXenoGrunt();
xenoGrunt.setScale(1.5f, 1.5f);
spawnEntityAt(xenoGrunt, pos, false, true);
}

private void spawnFireWorm() {
Expand Down Expand Up @@ -665,7 +667,7 @@ private void spawnSplitFireWorksFireBall(Vector2 position, short targetLayer, in
private void spawnWeaponTower() {
GridPoint2 minPos = new GridPoint2(0, 0);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2);

for (int i = 0; i < NUM_WEAPON_TOWERS; i++) {
GridPoint2 randomPos1 = RandomUtils.random(minPos, maxPos);
GridPoint2 randomPos2 = RandomUtils.random(minPos, maxPos);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package com.csse3200.game.components.npc;

import com.csse3200.game.components.Component;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.entities.factories.NPCFactory;
import com.csse3200.game.services.ServiceLocator;

/**
* A component that splits the target mob entity into multiple entities after
* after the mob dies. This class adds a method to the exisiting event listener
* "dieStart".
* <p>
* Amount of moblings spawned must be provided in the construcor.
* Scaled size of the moblings can be altered in the X and Y direction if
* desired. If not provided scaling alteration is assumed to be 0.75.
* </p>
*/
public class SplitMoblings extends Component {
private int amount;
private float scaleX, scaleY;
public static final float DEFAULT_MINIFIED_SCALE = 0.75f;
public static final double OFFSET_DISTANCE = 1.5;
public static final int FULL_CIRCLE_ANGLE = 360;
public static final float MIN_X_BOUNDS = 1;
public static final float MAX_X_BOUNDS = (float) 18.5;
public static final float MIN_Y_BOUNDS = 0;
public static final float MAX_Y_BOUNDS = 8;

/**
* Initialises a component that splits mob into multiple moblings. Amount of
* moblings split based on the amount provided param.
*
* @param amount Amount of moblings to be split.
* @require amount > 0
*/
public SplitMoblings(int amount) {
this.amount = amount;
scaleX = scaleY = DEFAULT_MINIFIED_SCALE;
}

/**
* Initialises a component that splits mob into multiple moblings. Amount of
* moblings split is based on the amount provided param.
* The overalling scaling (x and y) is also altered in the param.
*
* @param amount Amount of moblings to be split.
* @param scale X and Y scaling of the moblings in respect to the original size
* of the mobs.
* @require amount > 0
*/
public SplitMoblings(int amount, float scale) {
this.amount = amount;
this.scaleX = this.scaleY = scale;
}

/**
* Initialises a component that splits mob into multiple moblings. Amount of
* moblings split is based on the amount provided param.
* The individual scaling (x and y) is also altered in the param.
*
* @param amount Amount of moblings to be split.
* @param scaleX X scaling of the moblings compared to original size.
* @param scaleY Y scaling of the moblings compared to original size.
* @require amount > 0
*/
public SplitMoblings(int amount, float scaleX, float scaleY) {
this.amount = amount;
this.scaleX = scaleX;
this.scaleY = scaleY;
}

@Override
public void create() {
entity.getEvents().addListener("dieStart", this::onDeath);
}

/**
* Splits into multiple xeno grunts after death
*/
private void onDeath() {
float initialScaleX = entity.getScale().x;
float initialScaleY = entity.getScale().y;

// If there's only one amount to be spawned, spawn it 1 x-coordinate to the
// left.
if (amount == 1) {
float newXPosition = (float) (entity.getPosition().x - OFFSET_DISTANCE);
float newYPosition = (float) (entity.getPosition().y);

if (withinBounds(newXPosition, newYPosition))
spawnAdditionalMob(newXPosition, newYPosition, initialScaleX, initialScaleY);
}

// Inspired by:
// https://stackoverflow.com/questions/37145768/distribute-points-evenly-on-circle-circumference-in-quadrants-i-and-iv-only
for (int i = 0; i < amount; i++) {
float currAngle = (360 / amount) * i;
double radians = currAngle * Math.PI / 180;

float newX = entity.getPosition().x + (float) OFFSET_DISTANCE *
(float) Math.cos(radians);
float newY = entity.getPosition().y + (float) OFFSET_DISTANCE *
(float) Math.sin(radians);

if (withinBounds(newX, newY))
spawnAdditionalMob(newX, newY, initialScaleX, initialScaleY);
}
}

/**
* Helper function that spawns a xeno grunt based on a x and y-coordinate and
* scales down/up the entity based on the initial scale and this object's
* scale.
*
* @param positionX New spawn x-coordinate
* @param positionY New spawn y-coordinate
* @param initialScaleX Initial horizontal scale of the entity
* @param initialScaleY Initial vertical scale of the entity
*/
public void spawnAdditionalMob(float positionX, float positionY, float initialScaleX, float initialScaleY) {
// ? ENTITY PARAM KINDA USELESS?
Entity xenoGrunt = NPCFactory.createXenoGrunt(new Entity());
xenoGrunt.setPosition(positionX, positionY);

xenoGrunt.setScale(initialScaleX * scaleX, initialScaleY * scaleY);

ServiceLocator.getEntityService().register(xenoGrunt);
}

/**
* Helper to check if the current projectile position is within map bounds.
* Prevents spawning of mobs outof bounds.
*
* @param currX x-coordinate of the gamegrid.
* @param currY y-coordinate of the gamegrid.
* @return true if current position is within bounds of the map constraints.
* False otherwise.
*/
private boolean withinBounds(float currX, float currY) {
if (currX >= MIN_X_BOUNDS
&& currX <= MAX_X_BOUNDS
&& currY >= MIN_Y_BOUNDS
&& currY <= MAX_Y_BOUNDS) {
return true;
}
;
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.csse3200.game.components.npc.DragonKnightAnimationController;
import com.csse3200.game.components.npc.FireWormAnimationController;
import com.csse3200.game.components.npc.GhostAnimationController;
import com.csse3200.game.components.npc.SplitMoblings;
import com.csse3200.game.components.npc.XenoAnimationController;
import com.csse3200.game.components.tasks.MobAttackTask;
import com.csse3200.game.components.tasks.MobWanderTask;
Expand Down Expand Up @@ -222,6 +223,15 @@ public static Entity createBaseNPC(Entity target) {
private NPCFactory() {
throw new IllegalStateException("Instantiating static util class");
}

public static Entity createSplittingXenoGrunt() {
Entity splitXenoGrunt = createXenoGrunt(new Entity())
// add the scaling yourself. can also scale the X and Y component,
// leading to some very interesting mob designs.
.addComponent(new SplitMoblings(7, 2.25f));

return splitXenoGrunt;
}
}


0 comments on commit a67634a

Please sign in to comment.