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

Mohamad juice #256

Merged
merged 6 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 added source/core/assets/images/green_tile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added source/core/assets/images/red_tile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Timer;
import com.csse3200.game.rendering.RenderComponent;
import com.csse3200.game.services.CurrencyService;
import com.csse3200.game.services.ResourceService;
import com.csse3200.game.services.ServiceLocator;
import org.slf4j.Logger;
Expand Down Expand Up @@ -157,8 +158,8 @@ public void run() {
* @see TiledMapTileLayer.Cell
* @see TextureRegion
*/

public void hoverHighlight() {
CurrencyService currencyService = ServiceLocator.getCurrencyService();
Vector3 mousePos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(mousePos);

Expand All @@ -179,11 +180,18 @@ public void hoverHighlight() {
originalRegion = currentCell.getTile().getTextureRegion();

ResourceService resourceService = ServiceLocator.getResourceService();
Texture texture = resourceService.getAsset("images/highlight_tile.png", Texture.class);
currentCell.getTile().setTextureRegion(new TextureRegion(texture));
}
if (currencyService.getTower() != null) {
if (!ServiceLocator.getEntityService().entitiesInTile(tileX, tileY) && currencyService.getScrap().canBuy(Integer.parseInt(currencyService.getTower().getPrice()))) {
Texture texture = resourceService.getAsset("images/green_tile.png", Texture.class);
currentCell.getTile().setTextureRegion(new TextureRegion(texture));
} else {
Texture texture = resourceService.getAsset("images/red_tile.png", Texture.class);
currentCell.getTile().setTextureRegion(new TextureRegion(texture));
}

lastHoveredCell = currentCell;
lastHoveredCell = currentCell;
}
}
}

public enum TerrainOrientation {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ public void createTimerButton() {
*/
public void updateTimerButton() {
int totalSecs = (int) (timer - (ServiceLocator.getTimeSource().getTime() / 1000));

// TODO : THESE SHOULD BE REMOVED AND PLACED WHEREVER THE BOSS MOB GETS SPAWNED
if (totalSecs % 20 == 0) {
ServiceLocator.getMapService().shakeCameraMap();
ServiceLocator.getMapService().shakeCameraGrid();
}
int seconds = totalSecs % 60;
int minutes = (totalSecs % 3600) / 60;
String finalTime = String.format("%02d:%02d", minutes, seconds);
Expand Down
187 changes: 187 additions & 0 deletions source/core/src/main/com/csse3200/game/rendering/CameraShaker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package com.csse3200.game.rendering;

import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
@author antz
@version 1.0.0
November 2022
See https://github.com/antzGames/libGDX-cameraShake for more information.

Loosely based on 'Mastering LibGDX Game Development' - Chapter 9 - Camera Shake
Book: https://www.amazon.com/Mastering-LibGDX-Game-Development-Patrick/dp/1785289365

*/

public class CameraShaker {
private static final Logger logger = LoggerFactory.getLogger(CameraShaker.class);
private Camera camera;
private boolean isShaking = false;
private float origShakeRadius;
private float minimumShakeRadius;
private float radiusFallOffFactor;
private float shakeRadius;
private float randomAngle;
private float timer;
private Vector3 offset;
private Vector3 currentPosition;
public Vector3 origPosition;

/**
* Constructor
*
* @param camera supports any camera implementation
* @param shakeRadius original was set to 30.0f, must be greater than 0
* @param minimumShakeRadius original was set to 2.0f, must be greater than 0 and less than shakeRadius
* @param radiusFallOffFactor original was set to 0.9f, must be greater than 0 and less than 1
*/
public CameraShaker(Camera camera, float shakeRadius, float minimumShakeRadius, float radiusFallOffFactor){
checkParameters(shakeRadius, minimumShakeRadius, radiusFallOffFactor);
this.camera = camera;
this.offset = new Vector3();
this.currentPosition = new Vector3();
this.origPosition = camera.position.cpy();
logger.info("Start | Camera Position: " + camera.position);
reset();
}

/**
* Constructor - simple version
*
* Use this constructor to create a camera shaker with default values
*
* shakeRadius = 0.05f; // must be positive
* minimumShakeRadius = 0.001f; // must be positive and less than shakeRadius, aim for 5-15% of shake radius
* radiusFallOffFactor = 0.8f; // must be greater than 0 and less than 1
*
* @param camera supports any camera implementation
*/
public CameraShaker(Camera camera){
shakeRadius = 0.05f;
minimumShakeRadius = 0.001f;
radiusFallOffFactor = 0.8f;
checkParameters(shakeRadius, minimumShakeRadius, radiusFallOffFactor);
this.camera = camera;
this.offset = new Vector3();
this.currentPosition = new Vector3();
this.origPosition = camera.position.cpy();
logger.info("Start | Camera Position: " + camera.position);
reset();
}

/**
* Call this after a player collision/impact/explosion to start the camera shaking.
*/
public void startShaking(){
reset();
isShaking = true;
}

/**
* Always call this in your game's main update/render method.
*
* Make sure batch.setProjectionMatrix(camera.combined) is set prior to call.
*/
public void update(float delta){
if (!isCameraShaking()) return;

// only update camera shake 60 times a second max
timer += delta;
if (timer >= 1f/60f) {
computeCameraOffset();
computeCurrentPosition();
diminishShake();
camera.position.set(currentPosition);
camera.update();
timer = 0;
}
}

/**
* Called by diminishShake() when minimum shake radius reached.
*
* But you can also stop a camera shake by calling this method if needed.
*/
public void reset(){
shakeRadius = origShakeRadius;
isShaking = false;
seedRandomAngle();
currentPosition = origPosition.cpy();
timer = 0;

}

/**
* This allows to reconfigure parameters. Check if not shaking before calling, or else current shake will end.
*
* @param shakeRadius original was set to 30.0f, must be greater than 0
* @param minimumShakeRadius original was set to 2.0f, must be greater than 0 and less than shakeRadius
* @param radiusFallOffFactor original was set to 0.9f, must be greater than 0 and less than 1
*/
public void resetAndReconfigure(float shakeRadius, float minimumShakeRadius, float radiusFallOffFactor){
checkParameters(shakeRadius, minimumShakeRadius, radiusFallOffFactor);
isShaking = false;
seedRandomAngle();
currentPosition = origPosition.cpy();
timer = 0;
}

/**
* You can check if camera is currently shaking.
*
* @return is the camera currently shaking.
*/
public boolean isCameraShaking(){
return isShaking;
}

/**
Private methods below
*/

private void seedRandomAngle(){
randomAngle = MathUtils.random(1, 360);
}

private void computeCameraOffset(){
float sine = MathUtils.sinDeg(randomAngle);
float cosine = MathUtils.cosDeg(randomAngle);
offset.x = cosine * shakeRadius;
offset.y = sine * shakeRadius;
}

private void computeCurrentPosition() {
currentPosition.x = origPosition.x + offset.x;
currentPosition.y = origPosition.y + offset.y;

}

private void diminishShake(){
if(shakeRadius < minimumShakeRadius){
reset();
return;
}
isShaking = true;
shakeRadius *= radiusFallOffFactor;
randomAngle = MathUtils.random(1, 360);
}

private void checkParameters(float shakeRadius, float minimumShakeRadius, float radiusFallOffFactor) {
// validation checks on parameters
if (radiusFallOffFactor >= 1f) radiusFallOffFactor = 0.9f; // radius fall off factor must be less than 1
if (radiusFallOffFactor <= 0) radiusFallOffFactor = 0.9f; // radius fall off factor must be greater than 0
if (shakeRadius <= 0) shakeRadius = 30f; // shake radius must be greater than 0
if (minimumShakeRadius < 0) minimumShakeRadius = 0; // minimum shake radius must be greater than 0
if (minimumShakeRadius >= shakeRadius) // minimum shake radius must be less than shake radius, if not
minimumShakeRadius = 0.15f * shakeRadius; // then set minimum shake radius to 15% of shake radius

this.shakeRadius = shakeRadius;
this.origShakeRadius = shakeRadius;
this.minimumShakeRadius = minimumShakeRadius;
this.radiusFallOffFactor = radiusFallOffFactor;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ public class AssetLoader {
"images/GrassTile/grass_tile_6.png",
"images/GrassTile/grass_tile_7.png",
"images/highlight_tile.png",
"images/ui/Sprites/UI_Glass_Toggle_Bar_01a.png"
"images/ui/Sprites/UI_Glass_Toggle_Bar_01a.png",
"images/green_tile.png",
"images/red_tile.png"
};

public static final String[] textureAtlases = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ public MainGameScreen(GdxGame game) {

renderer = RenderFactory.createRenderer();
renderer.getCamera().getEntity().setPosition(CAMERA_POSITION);
renderer.getCamera().getCamera().position.set(CAMERA_POSITION.x,CAMERA_POSITION.y,0);
renderer.getDebug().renderPhysicsWorld(physicsEngine.getWorld());
InputComponent inputHandler = new DropInputComponent(renderer.getCamera().getCamera());
InputComponent buildHandler = new BuildInputComponent(renderer.getCamera().getCamera());
Expand All @@ -147,7 +148,7 @@ public MainGameScreen(GdxGame game) {

loadAssets();
createUI();
ServiceLocator.registerMapService(new MapService(renderer.getCamera()));
ServiceLocator.registerMapService(new MapService(renderer.getCamera(),camera));
logger.debug("Initialising main game screen entities");
ForestGameArea forestGameArea = new ForestGameArea();
forestGameArea.create();
Expand Down Expand Up @@ -195,9 +196,11 @@ public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

ServiceLocator.getMapService().updateShakerGrid(delta);
// Update the camera and set the batch's projection matrix
camera.update();
batch.setProjectionMatrix(camera.combined);
ServiceLocator.getMapService().updateShakerMap(delta);

// Begin the batch
batch.begin();
Expand Down
47 changes: 46 additions & 1 deletion source/core/src/main/com/csse3200/game/services/MapService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.csse3200.game.services;

import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.csse3200.game.areas.terrain.TerrainComponent;
import com.csse3200.game.areas.terrain.TerrainFactory;
import com.csse3200.game.components.CameraComponent;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.rendering.CameraShaker;



/**
* Provides services related to map functionalities such as tiles and lanes in genral.
Expand All @@ -12,15 +17,20 @@ public class MapService {

private Entity entity;
private final TerrainFactory terrainFactory;
private final CameraShaker cameraShakerMap;
private final CameraShaker cameraShakerGrid;

/**
* Constructs a new MapService instance based on the provided camera.
*
* @param camera The camera component used for the terrain creation.
*/
public MapService(CameraComponent camera) {
public MapService(CameraComponent camera,Camera cam) {
this.terrainFactory = new TerrainFactory(camera);
this.entity = new Entity().addComponent(terrainFactory.createTerrain(TerrainFactory.TerrainType.ALL_DEMO));
this.cameraShakerGrid = new CameraShaker(camera.getCamera());
this.cameraShakerMap = new CameraShaker(cam,2,0.1f,0.8f);

}

/**
Expand All @@ -32,6 +42,8 @@ public MapService(CameraComponent camera) {
public MapService(Entity entity, TerrainFactory terrainFactory) {
this.entity = entity;
this.terrainFactory = terrainFactory;
this.cameraShakerMap = new CameraShaker(new OrthographicCamera());
this.cameraShakerGrid = new CameraShaker(new OrthographicCamera());
}

/**
Expand Down Expand Up @@ -73,4 +85,37 @@ public int getWidth() {

return entity.getComponent(TerrainComponent.class).getMapBounds(0).x;
}

/**
* Update method for the Grid Camera Shaker. Calls this method in the main game loop.
*
* @param delta Time since the last frame.
*/
public void updateShakerGrid(float delta) {
cameraShakerGrid.update(delta);
}

/**
* Starts the Grid shaking process
*/
public void shakeCameraGrid() {
cameraShakerGrid.startShaking();
}

/**
* Update method for the Background Camera Shaker. Calls this method in the main game loop.
*
* @param delta Time since the last frame.
*/
public void updateShakerMap(float delta) {
cameraShakerMap.update(delta);
}

/**
* Starts the Background shaking process
*/
public void shakeCameraMap() {
cameraShakerMap.startShaking();
}

}
Loading