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 ahmad - control improvements #248

Merged
merged 11 commits into from
Oct 13, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
Expand All @@ -15,6 +16,7 @@
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.csse3200.game.services.GameTime;
import com.csse3200.game.services.ServiceLocator;
import com.csse3200.game.ui.UIComponent;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
Expand Down Expand Up @@ -89,6 +91,15 @@ public void updateScrapsStats() {
scrapsTb.getLabel().setText(text);
}

/**
* Displays a warning animation of the scraps display if the player tries to
* build something that costs more than the balance
*/
public void scrapBalanceFlash() {
// TODO: IMPLEMENT THIS
scrapsTb.setText("Insufficient!");
}

/**
* Updates the currency (Crystals) value on the UI component
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,19 @@

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Array;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.entities.factories.TowerFactory;
import com.csse3200.game.screens.TowerType;
import com.csse3200.game.services.ServiceLocator;
import com.csse3200.game.ui.ButtonFactory;
import com.csse3200.game.ui.UIComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.Set;

/**
* Displays a button to represent the remaining mobs left in the current wave and a button to skip to the next wave.
Expand All @@ -40,8 +31,6 @@ public class UIElementsDisplay extends UIComponent {
};
private Sound click;
private Sound hover;
// private TextButton remainingMobsButton = new ButtonFactory().createButton("Mobs left:");
// private final TextButton timerButton = new ButtonFactory().createButton("Next wave:");
private TextButton remainingMobsButton;
private TextButton timerButton;
private final int timer = 110;
Expand All @@ -62,14 +51,11 @@ private void addActors() {
remainingMobsButton = new TextButton("Mobs:"
+ ServiceLocator.getWaveService().getEnemyCount(), skin);
buttonTable.top().right();
towerTable.top();
towerTable.top().padTop(80f);

buttonTable.setFillParent(true);
towerTable.setFillParent(true);

towerTable.setDebug(true);
towerTable.padTop(50f);

TowerType[] defaultTowers = {
TowerType.TNT,
TowerType.DROID,
Expand Down Expand Up @@ -98,6 +84,10 @@ private void addActors() {
}
}

// Update the centrally located towerTypes list -
ServiceLocator.setTowerTypes(towers);

// Create the buttons - TODO This needs overhauling to pretty buttons
TextButton tower1 = new TextButton(towers.get(0).getTowerName(), skin);
TextButton tower2 = new TextButton(towers.get(1).getTowerName(), skin);
TextButton tower3 = new TextButton(towers.get(2).getTowerName(), skin);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public boolean entitiesInTile(int x_coord, int y_coord) {
try {
mp = (TiledMapTileLayer)ServiceLocator.getMapService().getComponent().getMap().getLayers().get(0);
} catch (NullPointerException e) {
// MapService is not running
// MapService is not running - consider this occupied (invalid tile)
return true;
}
if (mp.getCell(x_coord, y_coord) != null) {
Expand Down
111 changes: 104 additions & 7 deletions source/core/src/main/com/csse3200/game/input/BuildInputComponent.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.csse3200.game.input;

import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.csse3200.game.areas.ForestGameArea;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.entities.EntityService;
import com.csse3200.game.entities.factories.TowerFactory;
import com.csse3200.game.screens.TowerType;
import com.csse3200.game.services.CurrencyService;
import com.csse3200.game.services.ServiceLocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -28,6 +32,9 @@ public class BuildInputComponent extends InputComponent {
};
private Sound buildSound;
private Sound errorSound;
private Array<TowerType> towers = new Array<>();
private Array<TowerType> defaultTowers = new Array<>();
private boolean multipleTowerBuild = false;

/**
* Constructor for the BuildInputComponent
Expand All @@ -37,6 +44,22 @@ public BuildInputComponent(Camera camera) {
this.entityService = ServiceLocator.getEntityService();
this.camera = camera;
loadSounds();
towers.addAll(ServiceLocator.getTowerTypes());

logger.debug("selected towers in buildInputComponent are " + towers);
TowerType[] defaultTowerTypes = {
TowerType.TNT,
TowerType.DROID,
TowerType.INCOME,
TowerType.WALL,
TowerType.WEAPON
};
defaultTowers.addAll(defaultTowerTypes);

if (towers.isEmpty()) {
ServiceLocator.setTowerTypes(defaultTowers);
towers = defaultTowers;
}
}

/**
Expand Down Expand Up @@ -72,8 +95,57 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) {

// check that no entities are occupying the tile
if (!tileOccupied) {
buildTower((int)cursorPosition.x, (int)cursorPosition.y);
logger.debug("spawning a tower at {}, {}", cursorPosition.x, cursorPosition.y);
return buildTower((int)cursorPosition.x, (int)cursorPosition.y);
} else {
// TODO: Create a tile indication of invalid placement here??
return false;
}
}

/**
* Configures shortcut keys for building towers. Pressing the shortcut key
* sets the 'tower to build' variable in CurrencyService
*
* @return whether the input was processed
* @see InputProcessor#keyDown(int)
*/
@Override
public boolean keyUp(int keycode) {
switch (keycode) {
case Input.Keys.NUM_1:
ServiceLocator.getCurrencyService().setTowerType(towers.get(0));
return true;
case Input.Keys.NUM_2:
ServiceLocator.getCurrencyService().setTowerType(towers.get(1));
return true;
case Input.Keys.NUM_3:
ServiceLocator.getCurrencyService().setTowerType(towers.get(2));
return true;
case Input.Keys.NUM_4:
ServiceLocator.getCurrencyService().setTowerType(towers.get(3));
return true;
case Input.Keys.NUM_5:
ServiceLocator.getCurrencyService().setTowerType(towers.get(4));
return true;
case Input.Keys.CONTROL_LEFT:
// After multiple placement, deselect tower and prevent further builds
ServiceLocator.getCurrencyService().setTowerType(null);
multipleTowerBuild = false;
return true;
default:
return false;
}
}

/**
*
* @param keycode one of the constants in {@link Input.Keys}
* @return
*/
public boolean keyDown(int keycode) {
if (keycode == Input.Keys.CONTROL_LEFT) {
multipleTowerBuild = true;
return true;
}
return false;
Expand All @@ -86,14 +158,21 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) {
* @param x x-coordinate int value
* @param y y-coordinate int value
*/
public void buildTower(int x, int y) {
public boolean buildTower(int x, int y) {
TowerType tower;
CurrencyService currencyService;
// fetch the currently set TowerType in the currency service, and its associated build cost.
TowerType tower = ServiceLocator.getCurrencyService().getTower();
currencyService = ServiceLocator.getCurrencyService();
if (currencyService == null) {
// if the currency service fails or is not running
return false;
}
tower = currencyService.getTower();
if (tower != null) {
// fetch the price of the selected tower and attempt to instantiate
int cost = Integer.parseInt(ServiceLocator.getCurrencyService().getTower().getPrice());
int cost = Integer.parseInt(currencyService.getTower().getPrice());

if (cost <= ServiceLocator.getCurrencyService().getScrap().getAmount()) {
if (cost <= currencyService.getScrap().getAmount()) {
Entity newTower = switch (tower) {
case WEAPON -> TowerFactory.createWeaponTower();
case INCOME -> TowerFactory.createIncomeTower();
Expand All @@ -105,20 +184,38 @@ public void buildTower(int x, int y) {
};
// build the selected tower
newTower.setPosition(x, y);
ServiceLocator.getEntityService().register(newTower);
EntityService entityService;

entityService = ServiceLocator.getEntityService();
if (entityService == null){
return false;
}
entityService.register(newTower);

// Decrement currency and show a popup that reflects the cost of the build
ServiceLocator.getCurrencyService().getScrap().modify(-cost);
ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats();
ServiceLocator.getCurrencyService().getDisplay().currencyPopUp(x, y, -cost, 10);

long soundId = buildSound.play();
buildSound.setVolume(soundId, 0.4f);

// deselect the tower after building
if (!multipleTowerBuild) {
ServiceLocator.getCurrencyService().setTowerType(null);
}
return true;
} else {
// play a sound to indicate an invalid action
long soundId = errorSound.play();
errorSound.setVolume(soundId, 0.5f);
errorSound.setVolume(soundId, 1f);
ServiceLocator.getCurrencyService().getDisplay().scrapBalanceFlash();
// TODO: add a visual indication of the build fail, through
// currency display flash

}
}
return false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.csse3200.game.GdxGame;
import com.csse3200.game.services.ResourceService;
Expand Down Expand Up @@ -115,7 +116,12 @@ public void clicked(InputEvent event, float x, float y) {
@Override
public void clicked(InputEvent event, float x, float y) {
// Store the selected towers in the ServiceLocator for transferring across screens
ServiceLocator.setTowerTypes(selectedTurrets);;
// (as an Array)
Array<TowerType> towers = new Array<>();
for (TowerType t : selectedTurrets) {
towers.add(t);
}
ServiceLocator.setTowerTypes(towers);;
game.setScreen(GdxGame.ScreenType.MAIN_GAME);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public CurrencyDisplay getDisplay() {
return display;
}

/**
* Sets the tower type to build - triggered by pressing a tower build button in-game
* newTower can be a towertype or a null value to indicate clearing the value?
* @param newTower The towertype to be set for building, null if deselecting
*/
public void setTowerType(TowerType newTower) {
if (tower == newTower) {
tower = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class ServiceLocator {
private static WaveService waveService;
private static MapService mapService;

private static Set<TowerType> towerTypes = new HashSet<>();
private static Array<TowerType> towerTypes = new Array<>();

public static CurrencyService getCurrencyService() {
return currencyService;
Expand Down Expand Up @@ -120,12 +120,13 @@ public static void registerMapService(MapService source) {
mapService = source;
}

public static void setTowerTypes(Set<TowerType> selectedTowers) {
public static void setTowerTypes(Array<TowerType> selectedTowers) {

towerTypes.clear();
towerTypes.addAll(selectedTowers);
}

public static Set<TowerType> getTowerTypes() {
public static Array<TowerType> getTowerTypes() {
return towerTypes;
}

Expand All @@ -139,6 +140,7 @@ public static void clear() {
gameEndService = null;
waveService = null;
mapService = null;
towerTypes.clear();
}

private ServiceLocator() {
Expand Down
4 changes: 4 additions & 0 deletions source/core/src/main/com/csse3200/game/ui/UIComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@ public int getLayer() {
public float getZIndex() {
return 1f;
}

public static Skin getSkin() {
return skin;
}
}
Loading
Loading