summaryrefslogtreecommitdiff
path: root/core/src/main/java
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <me@liz.coffee>2026-02-28 10:34:19 -0800
committerElizabeth Alexander Hunt <me@liz.coffee>2026-02-28 10:37:02 -0800
commit5179800abc24ebf6b39761ff2e62e8134770d3b2 (patch)
tree87400c6ef12ccb01831e53f28218f8f0f54576c7 /core/src/main/java
parente9b0b0ddde8475860b8278e5d0b08543c8fe0a4d (diff)
downloaddyl-5179800abc24ebf6b39761ff2e62e8134770d3b2.tar.gz
dyl-5179800abc24ebf6b39761ff2e62e8134770d3b2.zip
Minor stress test
Diffstat (limited to 'core/src/main/java')
-rw-r--r--core/src/main/java/coffee/liz/dyl/DylGame.java1
-rw-r--r--core/src/main/java/coffee/liz/dyl/components/BoundingBox.java21
-rw-r--r--core/src/main/java/coffee/liz/dyl/components/Transform.java18
-rw-r--r--core/src/main/java/coffee/liz/dyl/components/Velocity.java5
-rw-r--r--core/src/main/java/coffee/liz/dyl/components/graphic/Graphic.java4
-rw-r--r--core/src/main/java/coffee/liz/dyl/components/graphic/TextureGraphic.java14
-rw-r--r--core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java2
-rw-r--r--core/src/main/java/coffee/liz/dyl/systems/InputSystem.java26
-rw-r--r--core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java14
-rw-r--r--core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java10
-rw-r--r--core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java11
-rw-r--r--core/src/main/java/coffee/liz/ecs/math/Mat2.java88
-rw-r--r--core/src/main/java/coffee/liz/ecs/math/Vec2.java88
-rw-r--r--core/src/main/java/coffee/liz/ecs/math/Vec2f.java61
-rw-r--r--core/src/main/java/coffee/liz/ecs/math/Vec2i.java65
15 files changed, 372 insertions, 56 deletions
diff --git a/core/src/main/java/coffee/liz/dyl/DylGame.java b/core/src/main/java/coffee/liz/dyl/DylGame.java
index aa25617..1166d42 100644
--- a/core/src/main/java/coffee/liz/dyl/DylGame.java
+++ b/core/src/main/java/coffee/liz/dyl/DylGame.java
@@ -17,7 +17,6 @@ import lombok.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;
diff --git a/core/src/main/java/coffee/liz/dyl/components/BoundingBox.java b/core/src/main/java/coffee/liz/dyl/components/BoundingBox.java
new file mode 100644
index 0000000..481e91e
--- /dev/null
+++ b/core/src/main/java/coffee/liz/dyl/components/BoundingBox.java
@@ -0,0 +1,21 @@
+package coffee.liz.dyl.components;
+
+import coffee.liz.ecs.math.Vec2;
+import coffee.liz.ecs.model.Component;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+@AllArgsConstructor
+@Getter
+@Setter
+public class BoundingBox implements Component, Comparable<BoundingBox> {
+ private Vec2<Float> position;
+ private Vec2<Integer> dimensions;
+ private int z;
+
+ @Override
+ public int compareTo(final BoundingBox other) {
+ return Integer.compare(z, other.getZ());
+ }
+}
diff --git a/core/src/main/java/coffee/liz/dyl/components/Transform.java b/core/src/main/java/coffee/liz/dyl/components/Transform.java
deleted file mode 100644
index b2d5a60..0000000
--- a/core/src/main/java/coffee/liz/dyl/components/Transform.java
+++ /dev/null
@@ -1,18 +0,0 @@
-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<Transform> {
- 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
index 170fa84..f31e861 100644
--- a/core/src/main/java/coffee/liz/dyl/components/Velocity.java
+++ b/core/src/main/java/coffee/liz/dyl/components/Velocity.java
@@ -1,7 +1,8 @@
package coffee.liz.dyl.components;
+import coffee.liz.ecs.math.Vec2;
+import coffee.liz.ecs.math.Vec2f;
import coffee.liz.ecs.model.Component;
-import com.badlogic.gdx.math.Vector2;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -12,5 +13,5 @@ import lombok.Setter;
@Getter
@Setter
public class Velocity implements Component {
- private Vector2 velocity = Vector2.Zero.cpy();
+ private Vec2<Float> velocity = Vec2f.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
index 648a930..c70b382 100644
--- a/core/src/main/java/coffee/liz/dyl/components/graphic/Graphic.java
+++ b/core/src/main/java/coffee/liz/dyl/components/graphic/Graphic.java
@@ -1,6 +1,6 @@
package coffee.liz.dyl.components.graphic;
-import coffee.liz.dyl.components.Transform;
+import coffee.liz.dyl.components.BoundingBox;
import coffee.liz.ecs.model.Component;
import com.badlogic.gdx.graphics.g2d.Batch;
@@ -9,5 +9,5 @@ public interface Graphic extends Component {
return Graphic.class;
}
- void draw(final Batch batch, final Transform transform);
+ void draw(final Batch batch, final BoundingBox boundingBox);
}
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
index 0d12f1a..6f29759 100644
--- a/core/src/main/java/coffee/liz/dyl/components/graphic/TextureGraphic.java
+++ b/core/src/main/java/coffee/liz/dyl/components/graphic/TextureGraphic.java
@@ -1,9 +1,9 @@
package coffee.liz.dyl.components.graphic;
-import coffee.liz.dyl.components.Transform;
+import coffee.liz.dyl.components.BoundingBox;
import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
-import com.badlogic.gdx.graphics.g2d.TextureRegion;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -11,11 +11,15 @@ import lombok.Getter;
@AllArgsConstructor
public class TextureGraphic implements Graphic {
private Color color;
- private TextureRegion textureRegion;
+ private Texture texture;
@Override
- public void draw(final Batch batch, final Transform transform) {
+ public void draw(final Batch batch, final BoundingBox boundingBox) {
batch.setColor(color);
- batch.draw(textureRegion, transform.getPosition().x, transform.getPosition().y);
+ batch.draw(texture,
+ boundingBox.getPosition().getX(), boundingBox.getPosition().getY(),
+ 0, 0,
+ boundingBox.getDimensions().getX(), boundingBox.getDimensions().getY()
+ );
}
}
diff --git a/core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java b/core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java
index f7344c7..8655447 100644
--- a/core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java
+++ b/core/src/main/java/coffee/liz/dyl/entities/PlayerFactory.java
@@ -22,7 +22,7 @@ public class PlayerFactory {
texture.getWidth() / PENGUIN_FRAMES_X,
texture.getHeight() / PENGUIN_FRAMES_Y);
return world.createEntity()
- .add(new TextureGraphic(Color.PINK, tmp[0][0]))
+ .add(new TextureGraphic(Color.PINK, tmp[0][0].getTexture()))
.add(new Controllable())
.add(new Velocity());
}
diff --git a/core/src/main/java/coffee/liz/dyl/systems/InputSystem.java b/core/src/main/java/coffee/liz/dyl/systems/InputSystem.java
index 8a357ba..d5dfe0b 100644
--- a/core/src/main/java/coffee/liz/dyl/systems/InputSystem.java
+++ b/core/src/main/java/coffee/liz/dyl/systems/InputSystem.java
@@ -1,12 +1,14 @@
package coffee.liz.dyl.systems;
import coffee.liz.dyl.FrameState;
-import coffee.liz.dyl.components.Transform;
+import coffee.liz.dyl.components.BoundingBox;
import coffee.liz.dyl.components.Velocity;
import coffee.liz.dyl.config.KeyBinds;
+import coffee.liz.ecs.math.Vec2;
+import coffee.liz.ecs.math.Vec2f;
+import coffee.liz.ecs.math.Vec2i;
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;
@@ -22,20 +24,20 @@ public class InputSystem implements System<FrameState> {
final Set<KeyBinds.Action> currentlyActive = state.getSettings().getKeyBinds()
.filterActiveActions(state.getIsKeyPressed());
- final Vector2 momentum = Vector2.Zero.cpy();
- currentlyActive.stream().map(InputSystem::actionToMovement).forEach(momentum::add);
+ final Vec2<Float> momentum = currentlyActive.stream().map(InputSystem::actionToMovement)
+ .reduce(Vec2::plus)
+ .orElse(Vec2f.ZERO);
- world.queryable().allOf(Velocity.class, Transform.class).forEach(e -> {
- e.get(Velocity.class).getVelocity().set(momentum);
- });
+ world.queryable().allOf(Velocity.class, BoundingBox.class)
+ .forEach(e -> e.get(Velocity.class).setVelocity(momentum));
}
- private static Vector2 actionToMovement(final KeyBinds.Action action) {
+ private static Vec2<Float> 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);
+ case MOVE_UP -> Vec2i.NORTH.floatValue();
+ case MOVE_DOWN -> Vec2i.SOUTH.floatValue();
+ case MOVE_LEFT -> Vec2i.WEST.floatValue();
+ case MOVE_RIGHT -> Vec2i.EAST.floatValue();
};
}
}
diff --git a/core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java b/core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java
index 3fb9b76..cd7d7b1 100644
--- a/core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java
+++ b/core/src/main/java/coffee/liz/dyl/systems/IntegrationSystem.java
@@ -1,11 +1,11 @@
package coffee.liz.dyl.systems;
import coffee.liz.dyl.FrameState;
-import coffee.liz.dyl.components.Transform;
+import coffee.liz.dyl.components.BoundingBox;
import coffee.liz.dyl.components.Velocity;
+import coffee.liz.ecs.math.Vec2;
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;
@@ -20,11 +20,13 @@ public class IntegrationSystem implements System<FrameState> {
@Override
public void update(final World<FrameState> world, final FrameState state, final float deltaSeconds) {
- world.queryable().allOf(Velocity.class, Transform.class)
+ world.queryable().allOf(Velocity.class, BoundingBox.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));
+ final Vec2<Float> velocity = e.get(Velocity.class).getVelocity();
+ final BoundingBox box = e.get(BoundingBox.class);
+ final Vec2<Float> position = box.getPosition()
+ .plus(velocity.scale(deltaSeconds, deltaSeconds));
+ box.setPosition(position);
});
}
}
diff --git a/core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java b/core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java
index 2f185cd..86c18fd 100644
--- a/core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java
+++ b/core/src/main/java/coffee/liz/dyl/systems/RenderSystem.java
@@ -2,7 +2,7 @@ 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.dyl.components.BoundingBox;
import coffee.liz.ecs.model.System;
import coffee.liz.ecs.model.World;
import com.badlogic.gdx.graphics.Color;
@@ -39,12 +39,12 @@ public class RenderSystem implements System<FrameState> {
batch.begin();
batch.setColor(Color.WHITE);
- world.queryable().allOf(Transform.class, Graphic.class).stream()
- .sorted(Comparator.comparing(e -> e.get(Transform.class)))
+ world.queryable().allOf(BoundingBox.class, Graphic.class).stream()
+ .sorted(Comparator.comparing(e -> e.get(BoundingBox.class)))
.forEach(e -> {
- final Transform transform = e.get(Transform.class);
+ final BoundingBox boundingBox = e.get(BoundingBox.class);
final Graphic graphic = e.get(Graphic.class);
- graphic.draw(batch, transform);
+ graphic.draw(batch, boundingBox);
});
batch.setColor(Color.WHITE);
diff --git a/core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java b/core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java
index b04a4df..c3e1c2d 100644
--- a/core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java
+++ b/core/src/main/java/coffee/liz/dyl/world/DylGameWorld.java
@@ -2,13 +2,14 @@ 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.components.BoundingBox;
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;
+import coffee.liz.ecs.math.Vec2f;
+import coffee.liz.ecs.math.Vec2i;
public class DylGameWorld extends DAGWorld<FrameState> {
public DylGameWorld(final DylGame game) {
@@ -17,7 +18,9 @@ public class DylGameWorld extends DAGWorld<FrameState> {
new IntegrationSystem(),
new RenderSystem(game.getBatch(), game.getViewport())
);
- PlayerFactory.addTo(this)
- .add(new Transform(Vector2.One, 1));
+ for (int i = 0; i < 8000; i++) {
+ PlayerFactory.addTo(this)
+ .add(new BoundingBox(new Vec2f(i / 200f, i/ 200f), new Vec2i(1, 1), 1));
+ }
}
}
diff --git a/core/src/main/java/coffee/liz/ecs/math/Mat2.java b/core/src/main/java/coffee/liz/ecs/math/Mat2.java
new file mode 100644
index 0000000..ed9493c
--- /dev/null
+++ b/core/src/main/java/coffee/liz/ecs/math/Mat2.java
@@ -0,0 +1,88 @@
+package coffee.liz.ecs.math;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public final class Mat2 {
+ private Mat2() {
+ }
+
+ /**
+ * Initializes a mutable 2d matrix of given type.
+ *
+ * @param dimensions
+ * the dimensions
+ * @param constructor
+ * the constructor
+ * @return row-indexed 2d matrix of {@param dimensions}
+ */
+ public static <T> List<List<T>> init(final Vec2<Integer> dimensions, final Function<Vec2<Integer>, T> constructor) {
+ final List<List<T>> rows = new ArrayList<>();
+ for (int y = 0; y < dimensions.getY(); y++) {
+ final List<T> row = new ArrayList<>(dimensions.getX());
+ for (int x = 0; x < dimensions.getX(); x++)
+ row.add(constructor.apply(Vec2i.builder().y(y).x(x).build()));
+ rows.add(row);
+ }
+ return rows;
+ }
+
+ /**
+ * Convolves a {@link Convolver} across a matrix reaching neighbors around the
+ * grid like a torus.
+ *
+ * @param mat
+ * is the row-indexed 2d matrix to convolve.
+ * @param axes
+ * are the x/y major/minor axes.
+ * @param init
+ * is the initial value of the convolution.
+ * @param convolver
+ * is the {@link Convolver}.
+ * @param finalReduction
+ * to apply after {@param convolver}.
+ * @return result of {@param convolver} applied along axes at each cell.
+ * @param <T>
+ * is the type of the matrix to convolve.
+ * @param <R>
+ * is the type of the resulting type of each convolution.
+ */
+ public static <T, R, U> List<List<U>> convolveTorus(final List<List<T>> mat, final Vec2<Integer> axes,
+ final Supplier<R> init, final Convolver<T, R> convolver, final BiFunction<T, R, U> finalReduction) {
+ final List<List<R>> rows = new ArrayList<>();
+ for (int y = 0; y < mat.size(); y++) {
+ final List<R> row = new ArrayList<>(mat.get(y).size());
+ for (int x = 0; x < mat.get(y).size(); x++) {
+ final T center = mat.get(y).get(x);
+ R result = init.get();
+ for (int dy = -axes.getY(); dy <= axes.getY(); dy++) {
+ final int ry = Math.floorMod(y + dy, mat.size());
+ for (int dx = -axes.getX(); dx <= axes.getX(); dx++) {
+ final int rx = Math.floorMod(x + dx, mat.get(ry).size());
+ result = convolver.convolve(mat.get(ry).get(rx), Vec2i.builder().x(dx).y(dy).build(), result);
+ }
+ }
+ row.add(result);
+ }
+ rows.add(row);
+ }
+
+ final List<List<U>> reductions = new ArrayList<>();
+ for (int y = 0; y < mat.size(); y++) {
+ final List<U> reduction = new ArrayList<>(mat.get(y).size());
+ for (int x = 0; x < mat.get(y).size(); x++) {
+ reduction.add(finalReduction.apply(mat.get(y).get(x), rows.get(y).get(x)));
+ }
+ reductions.add(reduction);
+ }
+ return reductions;
+ }
+
+ @FunctionalInterface
+ public interface Convolver<T, R> {
+ R convolve(final T center, final Vec2<Integer> rel, final R reduction);
+ }
+}
diff --git a/core/src/main/java/coffee/liz/ecs/math/Vec2.java b/core/src/main/java/coffee/liz/ecs/math/Vec2.java
new file mode 100644
index 0000000..dde6e51
--- /dev/null
+++ b/core/src/main/java/coffee/liz/ecs/math/Vec2.java
@@ -0,0 +1,88 @@
+package coffee.liz.ecs.math;
+
+import java.util.function.Function;
+
+/**
+ * Cartesian vectors.
+ *
+ * @param <T>
+ * the numeric type of vector components
+ */
+public interface Vec2<T> {
+ /**
+ * @return the x coordinate
+ */
+ T getX();
+
+ /**
+ * @return the y coordinate
+ */
+ T getY();
+
+ /**
+ * Adds another vector to this vector.
+ *
+ * @param other
+ * the vector to add
+ * @return a new vector with the result
+ */
+ Vec2<T> plus(final Vec2<T> other);
+
+ /**
+ * Subtracts another vector from this vector.
+ *
+ * @param other
+ * the vector to subtract
+ * @return a new vector with the result
+ */
+ Vec2<T> minus(final Vec2<T> other);
+
+ /**
+ * Scales this vector by the given factors.
+ *
+ * @param scaleX
+ * the x scale factor
+ * @param scaleY
+ * the y scale factor
+ * @return a new scaled vector
+ */
+ Vec2<T> scale(final T scaleX, final T scaleY);
+
+ /**
+ * Scales this vector by the given vector.
+ *
+ * @param scale
+ * scale vec.
+ * @return a new scaled vector
+ */
+ default Vec2<T> scale(final Vec2<T> scale) {
+ return scale(scale.getX(), scale.getY());
+ }
+
+ /**
+ * Length of the vector.
+ *
+ * @return length.
+ */
+ float length();
+
+ /**
+ * @return Vec2<Integer> components of {@link Vec2<T>}
+ */
+ Vec2<Integer> intValue();
+
+ /**
+ * @return Vec2<Float> components of {@link Vec2<T>}
+ */
+ Vec2<Float> floatValue();
+
+ /**
+ * @param xTransform
+ * transform of x component.
+ * @param yTransform
+ * transform of y component.
+ * @return transformed vec applying {@param xTransform} to x component,
+ * {@param yTransform} to y component.
+ */
+ Vec2<T> transform(final Function<T, T> xTransform, final Function<T, T> yTransform);
+}
diff --git a/core/src/main/java/coffee/liz/ecs/math/Vec2f.java b/core/src/main/java/coffee/liz/ecs/math/Vec2f.java
new file mode 100644
index 0000000..42b73e7
--- /dev/null
+++ b/core/src/main/java/coffee/liz/ecs/math/Vec2f.java
@@ -0,0 +1,61 @@
+package coffee.liz.ecs.math;
+
+import static java.lang.Math.sqrt;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.function.Function;
+
+/** Float impl of {@link Vec2}. */
+@Getter
+@RequiredArgsConstructor
+@Data
+@Builder
+public final class Vec2f implements Vec2<Float> {
+ /** X coordinate. */
+ private final Float x;
+
+ /** Y coordinate. */
+ private final Float y;
+
+ @Override
+ public Vec2<Float> plus(final Vec2<Float> other) {
+ return new Vec2f(x + other.getX(), y + other.getY());
+ }
+
+ @Override
+ public Vec2<Float> minus(final Vec2<Float> other) {
+ return new Vec2f(x - other.getX(), y - other.getY());
+ }
+
+ @Override
+ public Vec2<Float> scale(final Float scaleX, final Float scaleY) {
+ return new Vec2f(x * scaleX, y * scaleY);
+ }
+
+ @Override
+ public float length() {
+ return (float) sqrt(x * x + y * y);
+ }
+
+ @Override
+ public Vec2<Float> floatValue() {
+ return this;
+ }
+
+ @Override
+ public Vec2<Float> transform(final Function<Float, Float> xTransform, final Function<Float, Float> yTransform) {
+ return new Vec2f(xTransform.apply(getX()), yTransform.apply(getY()));
+ }
+
+ @Override
+ public Vec2<Integer> intValue() {
+ return Vec2i.builder().x(this.x.intValue()).y(this.y.intValue()).build();
+ }
+
+ /** Zero float vec */
+ public static Vec2<Float> ZERO = Vec2f.builder().x(0f).y(0f).build();
+}
diff --git a/core/src/main/java/coffee/liz/ecs/math/Vec2i.java b/core/src/main/java/coffee/liz/ecs/math/Vec2i.java
new file mode 100644
index 0000000..326a5df
--- /dev/null
+++ b/core/src/main/java/coffee/liz/ecs/math/Vec2i.java
@@ -0,0 +1,65 @@
+package coffee.liz.ecs.math;
+
+import static java.lang.Math.sqrt;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.function.Function;
+
+/** Integer impl of {@link Vec2}. */
+@Getter
+@RequiredArgsConstructor
+@Builder
+@Data
+public final class Vec2i implements Vec2<Integer> {
+ /** X coordinate. */
+ private final Integer x;
+
+ /** Y coordinate. */
+ private final Integer y;
+
+ @Override
+ public Vec2<Integer> plus(final Vec2<Integer> other) {
+ return new Vec2i(x + other.getX(), y + other.getY());
+ }
+
+ @Override
+ public Vec2<Integer> minus(final Vec2<Integer> other) {
+ return new Vec2i(x - other.getX(), y - other.getY());
+ }
+
+ @Override
+ public Vec2<Integer> scale(final Integer scaleX, final Integer scaleY) {
+ return new Vec2i(x * scaleX, y * scaleY);
+ }
+
+ @Override
+ public Vec2<Float> floatValue() {
+ return Vec2f.builder().x(this.x.floatValue()).y(this.y.floatValue()).build();
+ }
+
+ @Override
+ public Vec2<Integer> transform(final Function<Integer, Integer> xTransform,
+ final Function<Integer, Integer> yTransform) {
+ return new Vec2i(xTransform.apply(getX()), yTransform.apply(getY()));
+ }
+
+ @Override
+ public Vec2<Integer> intValue() {
+ return this;
+ }
+
+ @Override
+ public float length() {
+ return (float) sqrt(x * x + y * y);
+ }
+
+ public static final Vec2<Integer> NORTH = new Vec2i(0, 1);
+ public static final Vec2<Integer> SOUTH = new Vec2i(0, -1);
+ public static final Vec2<Integer> EAST = new Vec2i(1, 0);
+ public static final Vec2<Integer> WEST = new Vec2i(-1, 0);
+ public static final Vec2<Integer> ZERO = new Vec2i(0, 0);
+}