Skip to content

Commit

Permalink
Merge branch 'Mohamad-Maps' into team-2-sound
Browse files Browse the repository at this point in the history
  • Loading branch information
The-AhmadAA committed Sep 29, 2023
2 parents fb5a7c6 + a9c5805 commit c0ebd40
Show file tree
Hide file tree
Showing 14 changed files with 232 additions and 10 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified source/core/assets/images/grass_2.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/highlight_tile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 13 additions & 2 deletions source/core/src/main/com/csse3200/game/areas/ForestGameArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import com.csse3200.game.areas.terrain.TerrainComponent;
import com.csse3200.game.components.ProjectileEffects;
import com.csse3200.game.areas.terrain.TerrainFactory;
import com.csse3200.game.areas.terrain.TerrainFactory.TerrainType;
Expand Down Expand Up @@ -114,7 +115,15 @@ public class ForestGameArea extends GameArea {
"images/mobboss/demon.png",
"images/mobboss/demon2.png",
"images/mobs/fire_worm.png",
"images/mobboss/patrick.png"
"images/mobboss/patrick.png",
"images/GrassTile/grass_tile_1.png",
"images/GrassTile/grass_tile_2.png",
"images/GrassTile/grass_tile_3.png",
"images/GrassTile/grass_tile_4.png",
"images/GrassTile/grass_tile_5.png",
"images/GrassTile/grass_tile_6.png",
"images/GrassTile/grass_tile_7.png",
"images/highlight_tile.png"
};
private static final String[] forestTextureAtlases = {
"images/economy/econ-tower.atlas",
Expand Down Expand Up @@ -285,7 +294,9 @@ private void displayUI() {
private void spawnTerrain() {

terrain = terrainFactory.createTerrain(TerrainType.ALL_DEMO);
spawnEntity(new Entity().addComponent(terrain));
// TODO: We might need a MapService
Entity entity = new Entity().addComponent(terrain);
spawnEntity(entity);

// Terrain walls
float tileSize = terrain.getTileSize();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
package com.csse3200.game.areas.terrain;

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Timer;
import com.csse3200.game.rendering.RenderComponent;
import com.csse3200.game.services.ResourceService;
import com.csse3200.game.services.ServiceLocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Render a tiled terrain for a given tiled map and orientation. A terrain is a map of tiles that
* shows the 'ground' in the game. Enabling/disabling this component will show/hide the terrain.
*/
public class TerrainComponent extends RenderComponent {
private static final Logger logger = LoggerFactory.getLogger(TerrainComponent.class);
private static final int TERRAIN_LAYER = 0;

private final TiledMap tiledMap;
private final TiledMapRenderer tiledMapRenderer;
private final OrthographicCamera camera;
private final TerrainOrientation orientation;
private final float tileSize;
private TiledMapTileLayer.Cell lastHoveredCell = null;
private TiledMapTile originalTile = null;
private TextureRegion originalRegion = null;



public TerrainComponent(
OrthographicCamera camera,
Expand All @@ -33,6 +48,7 @@ public TerrainComponent(
this.orientation = orientation;
this.tileSize = tileSize;
this.tiledMapRenderer = renderer;

}

public Vector2 tileToWorldPosition(GridPoint2 tilePos) {
Expand Down Expand Up @@ -70,6 +86,7 @@ public TiledMap getMap() {
@Override
public void draw(SpriteBatch batch) {
tiledMapRenderer.setView(camera);
hoverHighlight();
tiledMapRenderer.render();
}

Expand All @@ -89,6 +106,88 @@ public int getLayer() {
return TERRAIN_LAYER;
}

// TODO : This is just a visual effect that we might not need in the end but just keeping it here for now
public void colorTile(final int x, final int y) {
final TiledMapTileLayer tileLayer = (TiledMapTileLayer) tiledMap.getLayers().get(0);
final TiledMapTile originalTile = tileLayer.getCell(x, y).getTile();

ResourceService resourceService = ServiceLocator.getResourceService();

// Load all the tiles into an array
final TerrainTile[] terrainTiles = new TerrainTile[7];
for (int i = 0; i < 7; i++) {
Texture texture = resourceService.getAsset("images/GrassTile/grass_tile_" + (i + 1) + ".png", Texture.class);
terrainTiles[i] = new TerrainTile(new TextureRegion(texture));
}

final float interval = 0.2f; // Switch every 0.2 seconds
final float duration = 1.4f; // 7 images * 0.2 seconds each

Timer.schedule(new Timer.Task() {
float timeElapsed = 0.0f;

@Override
public void run() {
timeElapsed += interval;

if (timeElapsed >= duration) {
tileLayer.getCell(x, y).setTile(originalTile); // Reset to original tile after the total duration
this.cancel(); // End the timer task
} else {
int index = (int) (timeElapsed / interval);
tileLayer.getCell(x, y).setTile(terrainTiles[index]);
}
}
}, 0, interval, (int) (duration / interval) - 1); // Scheduling the task
}

/**
* Highlights the tile under the mouse cursor by changing its texture region.
*
* <p>When hovering over a tile on the terrain, this method performs the following:
* <ol>
* <li>Unprojects the mouse's screen position to the world position using the camera.</li>
* <li>Calculates the tile's coordinates based on the world position and tile size.</li>
* <li>If there was a previously highlighted tile, it restores its original texture region.</li>
* <li>If the current tile under the mouse is different from the last hovered tile, it updates
* the tile's texture region to a highlight texture.</li>
* <li>Updates the reference to the last hovered tile.</li>
* </ol>
* </p>
*
* @see TiledMapTileLayer
* @see TiledMapTileLayer.Cell
* @see TextureRegion
*/

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


int tileX = (int) (mousePos.x / tileSize);
int tileY = (int) (mousePos.y / tileSize);

final TiledMapTileLayer tileLayer = (TiledMapTileLayer) tiledMap.getLayers().get(0);
TiledMapTileLayer.Cell currentCell = tileLayer.getCell(tileX, tileY);


if (lastHoveredCell != null && lastHoveredCell != currentCell && originalRegion != null) {
lastHoveredCell.getTile().setTextureRegion(originalRegion);
}


if (currentCell != null && currentCell != lastHoveredCell) {
originalRegion = currentCell.getTile().getTextureRegion();

ResourceService resourceService = ServiceLocator.getResourceService();
Texture texture = resourceService.getAsset("images/highlight_tile.png", Texture.class);
currentCell.getTile().setTextureRegion(new TextureRegion(texture));
}

lastHoveredCell = currentCell;
}

public enum TerrainOrientation {
ORTHOGONAL,
ISOMETRIC,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.csse3200.game.areas.terrain;

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile;
import com.badlogic.gdx.math.GridPoint2;
import com.csse3200.game.components.CameraComponent;
import com.csse3200.game.services.ResourceService;
Expand Down Expand Up @@ -81,7 +83,7 @@ private TerrainComponent createTerrain(float tileWorldSize, TextureRegion terrai
* @return A TiledMapRenderer instance suitable for the given map and scale.
*/

private TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) {
public TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) {
switch (orientation) {
case ORTHOGONAL:
return new OrthogonalTiledMapRenderer(tiledMap, tileScale);
Expand All @@ -100,9 +102,8 @@ private TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) {
private TiledMap createTiles(GridPoint2 tileSize, TextureRegion terrain) {
TiledMap tiledMap = new TiledMap();

TerrainTile Tile = new TerrainTile(terrain);
TiledMapTileLayer Layer = new TiledMapTileLayer(20, 8, tileSize.x, tileSize.y);
fillInvisibleTiles(Layer, new GridPoint2(20, 8), Tile);
TiledMapTileLayer Layer = new TiledMapTileLayer(20, 6, tileSize.x, tileSize.y);
fillInvisibleTiles(Layer, new GridPoint2(20, 6), terrain);
tiledMap.getLayers().add(Layer);

return tiledMap;
Expand All @@ -114,11 +115,12 @@ private TiledMap createTiles(GridPoint2 tileSize, TextureRegion terrain) {
*
* @param layer The tile layer to fill.
* @param mapSize The size of the map in tiles.
* @param tile The tile used to fill the layer.
* @param terrain The tile used to fill the layer.
*/
private void fillInvisibleTiles(TiledMapTileLayer layer, GridPoint2 mapSize, TerrainTile tile) {
private void fillInvisibleTiles(TiledMapTileLayer layer, GridPoint2 mapSize, TextureRegion terrain) {
for (int x = 0; x < mapSize.x; x++) {
for (int y = 2; y < mapSize.y; y++) {
for (int y = 0; y < mapSize.y; y++) {
TerrainTile tile = new TerrainTile(terrain);
Cell cell = new Cell();
cell.setTile(tile);
layer.setCell(x, y, cell);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.MapLayers;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.math.Vector2;
import com.csse3200.game.areas.terrain.TerrainComponent.TerrainOrientation;
import com.csse3200.game.extensions.GameExtension;
import static org.mockito.Mockito.*;

import com.csse3200.game.services.ResourceService;
import com.csse3200.game.services.ServiceLocator;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

Expand All @@ -35,6 +46,42 @@ void shouldConvertPositionHexagonal() {
TerrainComponent component = makeComponent(TerrainOrientation.HEXAGONAL, 3f);
}

@Test
void shouldHighlightTileOnHover1() {

TerrainComponent component = makeComponent(TerrainOrientation.ORTHOGONAL, 1f);

// Mock Gdx input to return specific mouse position
Gdx.input = mock(Input.class);
when(Gdx.input.getX()).thenReturn(2);
when(Gdx.input.getY()).thenReturn(4);


MapLayers mockLayers = mock(MapLayers.class);
when(component.getMap().getLayers()).thenReturn(mockLayers);

TiledMapTileLayer mockTileLayer = mock(TiledMapTileLayer.class);
when(mockLayers.get(0)).thenReturn(mockTileLayer);

TiledMapTileLayer.Cell mockCell = mock(TiledMapTileLayer.Cell.class);
when(mockTileLayer.getCell(2, 4)).thenReturn(mockCell);

TiledMapTile mockTile = mock(TiledMapTile.class);
when(mockCell.getTile()).thenReturn(mockTile);


Texture mockTexture = mock(Texture.class);
ServiceLocator.registerResourceService(mock(ResourceService.class));
when(ServiceLocator.getResourceService().getAsset("images/highlight_tile.png", Texture.class))
.thenReturn(mockTexture);


component.hoverHighlight();

// Verify that the tile's texture region was changed
verify(mockTile).setTextureRegion(any(TextureRegion.class));
}

private static TerrainComponent makeComponent(TerrainOrientation orientation, float tileSize) {
OrthographicCamera camera = mock(OrthographicCamera.class);
TiledMap map = mock(TiledMap.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.csse3200.game.areas.terrain;

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.csse3200.game.components.CameraComponent;
import com.csse3200.game.services.ResourceService;
import com.csse3200.game.services.ServiceLocator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class TerrainFactoryTest {

private TerrainFactory terrainFactory;
private CameraComponent mockedCameraComponent;
private OrthogonalTiledMapRenderer mockedRenderer;
private ResourceService mockResourceService;
private Texture mockTexture;

@BeforeEach
public void setUp() {
// Create mocks
mockedCameraComponent = mock(CameraComponent.class);
mockedRenderer = mock(OrthogonalTiledMapRenderer.class);
mockResourceService = mock(ResourceService.class);
mockTexture = mock(Texture.class);


ServiceLocator.registerResourceService(mockResourceService);


OrthographicCamera mockedCamera = mock(OrthographicCamera.class);
when(mockedCameraComponent.getCamera()).thenReturn(mockedCamera);


terrainFactory = spy(new TerrainFactory(mockedCameraComponent));


// When createRenderer is called on terrainFactory return the mockedRenderer
doReturn(mockedRenderer).when(terrainFactory).createRenderer(any(TiledMap.class), anyFloat());
}

@Test
public void testCreateTerrainGeneral() {
// Given the texture is taken from the ResourceService
when(mockResourceService.getAsset("images/terrain_use.png", Texture.class)).thenReturn(mockTexture);


TerrainComponent terrainComponent = terrainFactory.createTerrain(TerrainFactory.TerrainType.ALL_DEMO);
TiledMapTileLayer layer = (TiledMapTileLayer) terrainComponent.getMap().getLayers().get(0);

// the terrainComponent should not be null
assertNotNull(terrainComponent, "TerrainComponent should not be null");
assertEquals(6,layer.getHeight()); // 6 lanes
assertEquals(20,layer.getWidth()); // 20 tiles per lane

}
}

0 comments on commit c0ebd40

Please sign in to comment.