From 6e2fb9b12870a24f99071ea726d1c49ed57593ad Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Fri, 27 Feb 2026 20:00:05 -0800 Subject: Moving penguin --- core/src/main/java/coffee/liz/dyl/DylGame.java | 53 ++++++++++++++++++++++ core/src/main/java/coffee/liz/dyl/FirstScreen.java | 45 ------------------ core/src/main/java/coffee/liz/dyl/FrameState.java | 16 +++++++ core/src/main/java/coffee/liz/dyl/Main.java | 11 ----- .../coffee/liz/dyl/components/Controllable.java | 6 +++ .../java/coffee/liz/dyl/components/Transform.java | 18 ++++++++ .../java/coffee/liz/dyl/components/Velocity.java | 16 +++++++ .../coffee/liz/dyl/components/graphic/Graphic.java | 13 ++++++ .../liz/dyl/components/graphic/TextureGraphic.java | 21 +++++++++ .../main/java/coffee/liz/dyl/config/KeyBinds.java | 41 +++++++++++++++++ .../main/java/coffee/liz/dyl/config/Settings.java | 16 +++++++ .../coffee/liz/dyl/entities/PlayerFactory.java | 31 +++++++++++++ .../java/coffee/liz/dyl/screen/GameScreen.java | 51 +++++++++++++++++++++ .../java/coffee/liz/dyl/systems/InputSystem.java | 41 +++++++++++++++++ .../coffee/liz/dyl/systems/IntegrationSystem.java | 30 ++++++++++++ .../java/coffee/liz/dyl/systems/RenderSystem.java | 53 ++++++++++++++++++++++ .../java/coffee/liz/dyl/world/DylGameWorld.java | 23 ++++++++++ 17 files changed, 429 insertions(+), 56 deletions(-) create mode 100644 core/src/main/java/coffee/liz/dyl/DylGame.java delete mode 100644 core/src/main/java/coffee/liz/dyl/FirstScreen.java create mode 100644 core/src/main/java/coffee/liz/dyl/FrameState.java delete mode 100644 core/src/main/java/coffee/liz/dyl/Main.java create mode 100644 core/src/main/java/coffee/liz/dyl/components/Controllable.java create mode 100644 core/src/main/java/coffee/liz/dyl/components/Transform.java create mode 100644 core/src/main/java/coffee/liz/dyl/components/Velocity.java create mode 100644 core/src/main/java/coffee/liz/dyl/components/graphic/Graphic.java create mode 100644 core/src/main/java/coffee/liz/dyl/components/graphic/TextureGraphic.java create mode 100644 core/src/main/java/coffee/liz/dyl/config/KeyBinds.java create mode 100644 core/src/main/java/coffee/liz/dyl/config/Settings.java create mode 100644 core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java create mode 100644 core/src/main/java/coffee/liz/dyl/screen/GameScreen.java create mode 100644 core/src/main/java/coffee/liz/dyl/systems/InputSystem.java create mode 100644 core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java create mode 100644 core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java create mode 100644 core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java (limited to 'core/src/main/java/coffee/liz/dyl') diff --git a/core/src/main/java/coffee/liz/dyl/DylGame.java b/core/src/main/java/coffee/liz/dyl/DylGame.java new file mode 100644 index 0000000..aa25617 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/DylGame.java @@ -0,0 +1,53 @@ +package coffee.liz.dyl; + +import coffee.liz.dyl.config.Settings; +import coffee.liz.dyl.screen.GameScreen; +import com.badlogic.gdx.Game; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.InputMultiplexer; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import lombok.Getter; + +@Getter +public class DylGame extends Game { + public static final float WORLD_WIDTH = 10f; + public static final float WORLD_HEIGHT = 10f; + public static final float UNIT_SCALE = 1/10f; + + private InputMultiplexer inputMultiplexer; + private Batch batch; + private OrthographicCamera camera; + private Viewport viewport; + private Settings settings = Settings.builder().build(); + + @Override + public void create() { + inputMultiplexer = new InputMultiplexer(); + Gdx.input.setInputProcessor(inputMultiplexer); + + batch = new SpriteBatch(); + camera = new OrthographicCamera(); + viewport = new FitViewport(WORLD_WIDTH, WORLD_HEIGHT, camera); + + setScreen(new GameScreen(this)); + } + + @Override + public void render() { + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + super.render(); + } + + @Override + public void resize(final int width, final int height) { + viewport.update(width, height, true); + super.resize(width, height); + } +} diff --git a/core/src/main/java/coffee/liz/dyl/FirstScreen.java b/core/src/main/java/coffee/liz/dyl/FirstScreen.java deleted file mode 100644 index 4901283..0000000 --- a/core/src/main/java/coffee/liz/dyl/FirstScreen.java +++ /dev/null @@ -1,45 +0,0 @@ -package coffee.liz.dyl; - -import com.badlogic.gdx.Screen; - -/** First screen of the application. Displayed after the application is created. */ -public class FirstScreen implements Screen { - @Override - public void show() { - // Prepare your screen here. - } - - @Override - public void render(float delta) { - // Draw your screen here. "delta" is the time since last render in seconds. - } - - @Override - public void resize(int width, int height) { - // If the window is minimized on a desktop (LWJGL3) platform, width and height are 0, which causes problems. - // In that case, we don't resize anything, and wait for the window to be a normal size before updating. - if(width <= 0 || height <= 0) return; - - // Resize your screen here. The parameters represent the new window size. - } - - @Override - public void pause() { - // Invoked when your application is paused. - } - - @Override - public void resume() { - // Invoked when your application is resumed after pause. - } - - @Override - public void hide() { - // This method is called when another screen replaces this one. - } - - @Override - public void dispose() { - // Destroy screen's assets here. - } -} \ No newline at end of file diff --git a/core/src/main/java/coffee/liz/dyl/FrameState.java b/core/src/main/java/coffee/liz/dyl/FrameState.java new file mode 100644 index 0000000..7d70cde --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/FrameState.java @@ -0,0 +1,16 @@ +package coffee.liz.dyl; + +import coffee.liz.dyl.config.Settings; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.function.Predicate; + +@Builder +@Getter +@RequiredArgsConstructor +public class FrameState { + private final Settings settings; + private final Predicate isKeyPressed; +} diff --git a/core/src/main/java/coffee/liz/dyl/Main.java b/core/src/main/java/coffee/liz/dyl/Main.java deleted file mode 100644 index 24fa3de..0000000 --- a/core/src/main/java/coffee/liz/dyl/Main.java +++ /dev/null @@ -1,11 +0,0 @@ -package coffee.liz.dyl; - -import com.badlogic.gdx.Game; - -/** {@link com.badlogic.gdx.ApplicationListener} implementation shared by all platforms. */ -public class Main extends Game { - @Override - public void create() { - setScreen(new FirstScreen()); - } -} \ No newline at end of file diff --git a/core/src/main/java/coffee/liz/dyl/components/Controllable.java b/core/src/main/java/coffee/liz/dyl/components/Controllable.java new file mode 100644 index 0000000..c476c91 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/components/Controllable.java @@ -0,0 +1,6 @@ +package coffee.liz.dyl.components; + +import coffee.liz.ecs.model.Component; + +public class Controllable implements Component { +} diff --git a/core/src/main/java/coffee/liz/dyl/components/Transform.java b/core/src/main/java/coffee/liz/dyl/components/Transform.java new file mode 100644 index 0000000..b2d5a60 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/components/Transform.java @@ -0,0 +1,18 @@ +package coffee.liz.dyl.components; + +import coffee.liz.ecs.model.Component; +import com.badlogic.gdx.math.Vector2; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class Transform implements Component, Comparable { + private Vector2 position; + private int z; + + @Override + public int compareTo(final Transform other) { + return Integer.compare(z, other.getZ()); + } +} diff --git a/core/src/main/java/coffee/liz/dyl/components/Velocity.java b/core/src/main/java/coffee/liz/dyl/components/Velocity.java new file mode 100644 index 0000000..eb981f7 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/components/Velocity.java @@ -0,0 +1,16 @@ +package coffee.liz.dyl.components; + +import coffee.liz.ecs.model.Component; +import com.badlogic.gdx.math.Vector2; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class Velocity implements Component { + private Vector2 velocity = Vector2.Zero; +} diff --git a/core/src/main/java/coffee/liz/dyl/components/graphic/Graphic.java b/core/src/main/java/coffee/liz/dyl/components/graphic/Graphic.java new file mode 100644 index 0000000..648a930 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/components/graphic/Graphic.java @@ -0,0 +1,13 @@ +package coffee.liz.dyl.components.graphic; + +import coffee.liz.dyl.components.Transform; +import coffee.liz.ecs.model.Component; +import com.badlogic.gdx.graphics.g2d.Batch; + +public interface Graphic extends Component { + default Class getKey() { + return Graphic.class; + } + + void draw(final Batch batch, final Transform transform); +} diff --git a/core/src/main/java/coffee/liz/dyl/components/graphic/TextureGraphic.java b/core/src/main/java/coffee/liz/dyl/components/graphic/TextureGraphic.java new file mode 100644 index 0000000..0d12f1a --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/components/graphic/TextureGraphic.java @@ -0,0 +1,21 @@ +package coffee.liz.dyl.components.graphic; + +import coffee.liz.dyl.components.Transform; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class TextureGraphic implements Graphic { + private Color color; + private TextureRegion textureRegion; + + @Override + public void draw(final Batch batch, final Transform transform) { + batch.setColor(color); + batch.draw(textureRegion, transform.getPosition().x, transform.getPosition().y); + } +} diff --git a/core/src/main/java/coffee/liz/dyl/config/KeyBinds.java b/core/src/main/java/coffee/liz/dyl/config/KeyBinds.java new file mode 100644 index 0000000..762dc48 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/config/KeyBinds.java @@ -0,0 +1,41 @@ +package coffee.liz.dyl.config; +import com.badlogic.gdx.Input; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; + +@Builder +@AllArgsConstructor +@RequiredArgsConstructor +@Getter +public class KeyBinds { + @Builder.Default + private Set moveUpKeys = Set.of(Input.Keys.K, Input.Keys.UP, Input.Keys.W); + @Builder.Default + private Set moveDownKeys = Set.of(Input.Keys.J, Input.Keys.DOWN, Input.Keys.S); + @Builder.Default + private Set moveLeftKeys = Set.of(Input.Keys.H, Input.Keys.LEFT, Input.Keys.A); + @Builder.Default + private Set moveRightKeys = Set.of(Input.Keys.L, Input.Keys.RIGHT, Input.Keys.D); + + public Set filterActiveActions(final Predicate isDown) { + final Set actions = new HashSet<>(); + Map.of(moveUpKeys, Action.MOVE_UP, moveDownKeys, Action.MOVE_DOWN, moveRightKeys, Action.MOVE_RIGHT, + moveLeftKeys, Action.MOVE_LEFT).forEach((keys, action) -> { + if (keys.stream().anyMatch(isDown)) { + actions.add(action); + } + }); + return actions; + } + + public enum Action { + MOVE_UP, MOVE_LEFT, MOVE_DOWN, MOVE_RIGHT; + } +} diff --git a/core/src/main/java/coffee/liz/dyl/config/Settings.java b/core/src/main/java/coffee/liz/dyl/config/Settings.java new file mode 100644 index 0000000..13fbb3c --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/config/Settings.java @@ -0,0 +1,16 @@ +package coffee.liz.dyl.config; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Builder +@AllArgsConstructor +@Getter +public class Settings { + @Builder.Default + private boolean skipIntro = true; + @Builder.Default + private boolean playMusic = true; + @Builder.Default + private KeyBinds keyBinds = KeyBinds.builder().build(); +} diff --git a/core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java b/core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java new file mode 100644 index 0000000..f7344c7 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java @@ -0,0 +1,31 @@ +package coffee.liz.dyl.entities; + +import coffee.liz.dyl.components.Controllable; +import coffee.liz.dyl.components.Velocity; +import coffee.liz.dyl.components.graphic.TextureGraphic; +import coffee.liz.ecs.model.Entity; +import coffee.liz.ecs.model.World; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; + +public class PlayerFactory { + private static final int PENGUIN_FRAMES_Y = 4; + private static final int PENGUIN_FRAMES_X = 8; + private static final FileHandle FILE = Gdx.files.internal("player.png"); + + public static Entity addTo(final World world) { + final Texture texture = new Texture(FILE); + final TextureRegion[][] tmp = TextureRegion.split(texture, + texture.getWidth() / PENGUIN_FRAMES_X, + texture.getHeight() / PENGUIN_FRAMES_Y); + return world.createEntity() + .add(new TextureGraphic(Color.PINK, tmp[0][0])) + .add(new Controllable()) + .add(new Velocity()); + } + + private PlayerFactory() { } +} diff --git a/core/src/main/java/coffee/liz/dyl/screen/GameScreen.java b/core/src/main/java/coffee/liz/dyl/screen/GameScreen.java new file mode 100644 index 0000000..54dfda3 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/screen/GameScreen.java @@ -0,0 +1,51 @@ +package coffee.liz.dyl.screen; + +import coffee.liz.dyl.DylGame; +import coffee.liz.dyl.FrameState; +import coffee.liz.dyl.world.DylGameWorld; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class GameScreen implements Screen { + private final DylGame game; + + private DylGameWorld dylGameWorld; + private FrameState frameState; + + @Override + public void show() { + dylGameWorld = new DylGameWorld(game); + frameState = FrameState.builder() + .settings(game.getSettings()) + .isKeyPressed(Gdx.input::isKeyPressed) + .build(); + } + + @Override + public void render(final float delta) { + dylGameWorld.update(frameState, delta); + } + + @Override + public void resize(final int width, final int height) { + } + + @Override + public void pause() { + } + + @Override + public void resume() { + } + + @Override + public void hide() { + } + + @Override + public void dispose() { + dylGameWorld.dispose(); + } +} diff --git a/core/src/main/java/coffee/liz/dyl/systems/InputSystem.java b/core/src/main/java/coffee/liz/dyl/systems/InputSystem.java new file mode 100644 index 0000000..8a357ba --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/systems/InputSystem.java @@ -0,0 +1,41 @@ +package coffee.liz.dyl.systems; + +import coffee.liz.dyl.FrameState; +import coffee.liz.dyl.components.Transform; +import coffee.liz.dyl.components.Velocity; +import coffee.liz.dyl.config.KeyBinds; +import coffee.liz.ecs.model.System; +import coffee.liz.ecs.model.World; +import com.badlogic.gdx.math.Vector2; + +import java.util.Collection; +import java.util.Set; + +public class InputSystem implements System { + @Override + public Collection>> getDependencies() { + return Set.of(); + } + + @Override + public void update(final World world, final FrameState state, final float deltaSeconds) { + final Set currentlyActive = state.getSettings().getKeyBinds() + .filterActiveActions(state.getIsKeyPressed()); + + final Vector2 momentum = Vector2.Zero.cpy(); + currentlyActive.stream().map(InputSystem::actionToMovement).forEach(momentum::add); + + world.queryable().allOf(Velocity.class, Transform.class).forEach(e -> { + e.get(Velocity.class).getVelocity().set(momentum); + }); + } + + private static Vector2 actionToMovement(final KeyBinds.Action action) { + return switch (action) { + case MOVE_UP -> new Vector2(0, 1); + case MOVE_DOWN -> new Vector2(0, -1); + case MOVE_LEFT -> new Vector2(-1, 0); + case MOVE_RIGHT -> new Vector2(1, 0); + }; + } +} diff --git a/core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java b/core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java new file mode 100644 index 0000000..3fb9b76 --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java @@ -0,0 +1,30 @@ +package coffee.liz.dyl.systems; + +import coffee.liz.dyl.FrameState; +import coffee.liz.dyl.components.Transform; +import coffee.liz.dyl.components.Velocity; +import coffee.liz.ecs.model.System; +import coffee.liz.ecs.model.World; +import com.badlogic.gdx.math.Vector2; +import lombok.extern.log4j.Log4j2; + +import java.util.Collection; +import java.util.List; + +@Log4j2 +public class IntegrationSystem implements System { + @Override + public Collection>> getDependencies() { + return List.of(InputSystem.class); + } + + @Override + public void update(final World world, final FrameState state, final float deltaSeconds) { + world.queryable().allOf(Velocity.class, Transform.class) + .forEach(e -> { + final Vector2 velocity = e.get(Velocity.class).getVelocity(); + final Vector2 position = e.get(Transform.class).getPosition(); + position.add(velocity.cpy().scl(deltaSeconds)); + }); + } +} diff --git a/core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java b/core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java new file mode 100644 index 0000000..2f185cd --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java @@ -0,0 +1,53 @@ +package coffee.liz.dyl.systems; + +import coffee.liz.dyl.FrameState; +import coffee.liz.dyl.components.graphic.Graphic; +import coffee.liz.dyl.components.Transform; +import coffee.liz.ecs.model.System; +import coffee.liz.ecs.model.World; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.utils.viewport.Viewport; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Set; + +public class RenderSystem implements System { + private final Batch batch; + private final OrthographicCamera camera; + private final Viewport viewport; + + public RenderSystem(final Batch batch, final Viewport viewport) { + this.batch = batch; + this.viewport = viewport; + this.camera = (OrthographicCamera) viewport.getCamera(); + } + + @Override + public Collection>> getDependencies() { + return Set.of(IntegrationSystem.class); + } + + @Override + public void update(final World world, final FrameState state, final float deltaSeconds) { + viewport.apply(); + camera.update(); + + batch.setProjectionMatrix(camera.combined); + batch.begin(); + batch.setColor(Color.WHITE); + + world.queryable().allOf(Transform.class, Graphic.class).stream() + .sorted(Comparator.comparing(e -> e.get(Transform.class))) + .forEach(e -> { + final Transform transform = e.get(Transform.class); + final Graphic graphic = e.get(Graphic.class); + graphic.draw(batch, transform); + }); + + batch.setColor(Color.WHITE); + batch.end(); + } +} diff --git a/core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java b/core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java new file mode 100644 index 0000000..b04a4df --- /dev/null +++ b/core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java @@ -0,0 +1,23 @@ +package coffee.liz.dyl.world; + +import coffee.liz.dyl.DylGame; +import coffee.liz.dyl.FrameState; +import coffee.liz.dyl.components.Transform; +import coffee.liz.dyl.entities.PlayerFactory; +import coffee.liz.dyl.systems.InputSystem; +import coffee.liz.dyl.systems.IntegrationSystem; +import coffee.liz.dyl.systems.RenderSystem; +import coffee.liz.ecs.DAGWorld; +import com.badlogic.gdx.math.Vector2; + +public class DylGameWorld extends DAGWorld { + public DylGameWorld(final DylGame game) { + super( + new InputSystem(), + new IntegrationSystem(), + new RenderSystem(game.getBatch(), game.getViewport()) + ); + PlayerFactory.addTo(this) + .add(new Transform(Vector2.One, 1)); + } +} -- cgit v1.2.3-70-g09d2