From 555f710ae42c48aef9052371085ebed05a2a32d2 Mon Sep 17 00:00:00 2001 From: TheRealEmissions Date: Tue, 19 Mar 2024 19:04:23 +0000 Subject: [PATCH] Sprite loading --- .../src/uk/ac/york/student/player/Player.java | 149 ++++++++++++++++++ .../ac/york/student/player/PlayerScore.java | 20 ++- .../ac/york/student/screens/GameScreen.java | 73 +++++++-- .../york/student/screens/MainMenuScreen.java | 4 +- 4 files changed, 223 insertions(+), 23 deletions(-) create mode 100644 core/src/uk/ac/york/student/player/Player.java diff --git a/core/src/uk/ac/york/student/player/Player.java b/core/src/uk/ac/york/student/player/Player.java new file mode 100644 index 0000000..b70a50c --- /dev/null +++ b/core/src/uk/ac/york/student/player/Player.java @@ -0,0 +1,149 @@ +package uk.ac.york.student.player; + +import com.badlogic.gdx.Input; +import com.badlogic.gdx.InputProcessor; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.maps.tiled.TiledMap; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Actor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +@Getter +public class Player extends Actor implements PlayerScore, InputProcessor { + private static final float SPRITE_SCALE = 7.5f; + private final Sprite sprite; + private final TiledMap map; + private final TextureAtlas textureAtlas = new TextureAtlas("sprite-atlases/character-sprites.atlas"); + public Player(TiledMap map, @NotNull Vector2 startPosition) { + super(); + this.map = map; + sprite = textureAtlas.createSprite("char3_left"); + sprite.setPosition(startPosition.x, startPosition.y); + sprite.setAlpha(1); + // scale sprite + sprite.setSize(sprite.getWidth() * SPRITE_SCALE, sprite.getHeight() * SPRITE_SCALE); + setBounds(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight()); + + + } + + @Getter + private enum Movement { + UP, DOWN, LEFT, RIGHT, BOOST; + + private boolean is; + + void set(boolean is) { + this.is = is; + } + } + + @Override + public void draw(Batch batch, float parentAlpha) { + int amount = Movement.BOOST.is ? 4 : 2; + if (Movement.UP.is) { + sprite.translateY(amount); + } + if (Movement.DOWN.is) { + sprite.translateY(-amount); + } + if (Movement.LEFT.is) { + sprite.translateX(-amount); + } + if (Movement.RIGHT.is) { + sprite.translateX(amount); + } + sprite.draw(batch); + super.draw(batch, parentAlpha); + } + + @Override + public boolean keyDown(int keycode) { + switch (keycode) { + case Input.Keys.W: + Movement.UP.set(true); + break; + case Input.Keys.S: + Movement.DOWN.set(true); + break; + case Input.Keys.A: + Movement.LEFT.set(true); + break; + case Input.Keys.D: + Movement.RIGHT.set(true); + break; + case Input.Keys.CONTROL_LEFT: + Movement.BOOST.set(true); + break; + default: + return false; + } + return true; + } + + @Override + public boolean keyUp(int keycode) { + switch (keycode) { + case Input.Keys.W: + Movement.UP.set(false); + break; + case Input.Keys.S: + Movement.DOWN.set(false); + break; + case Input.Keys.A: + Movement.LEFT.set(false); + break; + case Input.Keys.D: + Movement.RIGHT.set(false); + break; + case Input.Keys.CONTROL_LEFT: + Movement.BOOST.set(false); + break; + default: + return false; + } + return true; + } + + @Override + public boolean keyTyped(char character) { + return false; + } + + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button) { + return false; + } + + @Override + public boolean touchUp(int screenX, int screenY, int pointer, int button) { + return false; + } + + @Override + public boolean touchCancelled(int screenX, int screenY, int pointer, int button) { + return false; + } + + @Override + public boolean touchDragged(int screenX, int screenY, int pointer) { + return false; + } + + @Override + public boolean mouseMoved(int screenX, int screenY) { + return false; + } + + @Override + public boolean scrolled(float amountX, float amountY) { + return false; + } + + public void dispose() { + textureAtlas.dispose(); + } +} diff --git a/core/src/uk/ac/york/student/player/PlayerScore.java b/core/src/uk/ac/york/student/player/PlayerScore.java index 9e8e89f..b8411c2 100644 --- a/core/src/uk/ac/york/student/player/PlayerScore.java +++ b/core/src/uk/ac/york/student/player/PlayerScore.java @@ -1,11 +1,9 @@ package uk.ac.york.student.player; -import lombok.experimental.UtilityClass; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -@UtilityClass -public final class PlayerScore { +public interface PlayerScore { /** * Calculate a score for the student/player. *

@@ -31,9 +29,9 @@ public final class PlayerScore { * to. * @return An int score out of 100 calculated with the given variable. */ - public static int calculate(float energy, float maxEnergy, float studyTime, - float maxStudyTime, int difficulty, - int maxDifficulty) { + default int calculateScore(float energy, float maxEnergy, float studyTime, + float maxStudyTime, int difficulty, + int maxDifficulty) { float energyScore = Math.min(energy / maxEnergy, 1.0f) * 100; float studyScore = Math.min(studyTime / maxStudyTime, 1.0f) * 100; @@ -49,10 +47,10 @@ public static int calculate(float energy, float maxEnergy, float studyTime, return (int) Math.round(percentScoreDouble); } - public static int calculate(int energy, int maxEnergy, int studyTime, - int maxStudyTime, int difficulty, - int maxDifficulty) { - return calculate( + default int calculateScore(int energy, int maxEnergy, int studyTime, + int maxStudyTime, int difficulty, + int maxDifficulty) { + return calculateScore( (float) energy, (float) maxEnergy, (float) studyTime, (float) maxStudyTime, difficulty, maxDifficulty ); @@ -62,7 +60,7 @@ public static int calculate(int energy, int maxEnergy, int studyTime, * Output an associated degree class given a score (out of 100). */ @Contract(pure = true) - public static @NotNull String convertToString(int score) { + default @NotNull String convertScoreToString(int score) { if (score >= 70) { return "First-class Honours"; } else if (score >= 60) { diff --git a/core/src/uk/ac/york/student/screens/GameScreen.java b/core/src/uk/ac/york/student/screens/GameScreen.java index 2c81588..85b8f50 100644 --- a/core/src/uk/ac/york/student/screens/GameScreen.java +++ b/core/src/uk/ac/york/student/screens/GameScreen.java @@ -1,32 +1,44 @@ package uk.ac.york.student.screens; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.InputMultiplexer; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.maps.MapGroupLayer; -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.TmxMapLoader; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.maps.*; +import com.badlogic.gdx.maps.objects.RectangleMapObject; +import com.badlogic.gdx.maps.tiled.*; import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.World; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.viewport.FitViewport; import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.badlogic.gdx.utils.viewport.StretchViewport; import lombok.Getter; import uk.ac.york.student.GdxGame; +import uk.ac.york.student.player.Player; import java.util.List; public class GameScreen extends BaseScreen implements InputProcessor { @Getter private final Stage processor; + private final Player player; private final TiledMap map; private TiledMapRenderer renderer; public GameScreen(GdxGame game) { super(game); + + // Set up the tilemap + // Cannot extract into a method because class variables are set as final + //#region Load Tilemap TmxMapLoader.Parameters parameter = new TmxMapLoader.Parameters(); parameter.textureMinFilter = Texture.TextureFilter.Nearest; parameter.textureMagFilter = Texture.TextureFilter.Nearest; @@ -36,9 +48,41 @@ public GameScreen(GdxGame game) { int tileHeight = layer.getTileHeight(); float scale = Math.max(Gdx.graphics.getWidth() / (layer.getWidth() * tileWidth), Gdx.graphics.getHeight() / (layer.getHeight() * tileHeight)); renderer = new OrthogonalTiledMapRenderer(map, scale); + //#endregion + + Vector2 startingPoint = new Vector2(25, 25); + MapLayer gameObjectsLayer = map.getLayers().get("gameObjects"); + MapObjects objects = gameObjectsLayer.getObjects(); + for (MapObject object : objects) { + if (!object.getName().equals("startingPoint")) continue; + MapProperties properties = object.getProperties(); + if (!properties.containsKey("spawnpoint")) continue; + Boolean spawnpoint = properties.get("spawnpoint", Boolean.class); + if (spawnpoint == null || Boolean.FALSE.equals(spawnpoint)) continue; + RectangleMapObject rectangleObject = (RectangleMapObject) object; + Rectangle rectangle = rectangleObject.getRectangle(); + startingPoint = new Vector2(rectangle.getX() * scale, rectangle.getY() * scale); + break; + } + + + player = new Player(map, startingPoint); processor = new Stage(new ScreenViewport()); + renderer.setView((OrthographicCamera) processor.getCamera()); Gdx.input.setInputProcessor(processor); + + processor.addListener(new InputListener() { + @Override + public boolean keyDown(InputEvent event, int keycode) { + return GameScreen.this.keyDown(keycode); + } + + @Override + public boolean keyUp(InputEvent event, int keycode) { + return GameScreen.this.keyUp(keycode); + } + }); } @Override @@ -46,6 +90,10 @@ public void show() { float width = Gdx.graphics.getWidth(); float height = Gdx.graphics.getHeight(); + Batch batch = processor.getBatch(); + batch.begin(); + player.draw(batch, 1f); + batch.end(); processor.getViewport().update((int) width, (int) height); @@ -56,13 +104,19 @@ public void render(float v) { Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0); OrthographicCamera camera = (OrthographicCamera) processor.getCamera(); camera.update(); + Batch batch = processor.getBatch(); + batch.begin(); + player.draw(batch, 1f); + batch.end(); + renderer.setView(camera); renderer.render(); - + processor.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); processor.draw(); } @@ -96,17 +150,18 @@ public void hide() { @Override public void dispose() { - + map.dispose(); + processor.dispose(); } @Override public boolean keyDown(int keycode) { - return false; + return player.keyDown(keycode); } @Override public boolean keyUp(int keycode) { - return false; + return player.keyUp(keycode); } @Override diff --git a/core/src/uk/ac/york/student/screens/MainMenuScreen.java b/core/src/uk/ac/york/student/screens/MainMenuScreen.java index 058ff34..b5a82aa 100644 --- a/core/src/uk/ac/york/student/screens/MainMenuScreen.java +++ b/core/src/uk/ac/york/student/screens/MainMenuScreen.java @@ -112,9 +112,7 @@ public void fadeOut() { alpha.updateAndGet(v -> v <= 0 ? 0 : v - 0.01f); }, 0, period, TimeUnit.MILLISECONDS); - executorService.schedule(() -> { - scheduledFuture.cancel(true); - }, duration, timeUnit); + executorService.schedule(() -> scheduledFuture.cancel(true), duration, timeUnit); } @Override