Skip to content

Commit

Permalink
Game of life enhance (#117)
Browse files Browse the repository at this point in the history
* prototyping color change

* restructure packages and add ui

* better menu

* fix for mouse pressed continouusly

* fix for mouse pressed continouusly

* bugfix fullscreen on osx

* fix fullscreen on osx

* fix
  • Loading branch information
srcimon committed Nov 4, 2023
1 parent 05392b9 commit a89531f
Show file tree
Hide file tree
Showing 15 changed files with 184 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
public final class Color implements Serializable {


private static final Random RANDOM = new Random();

private static final long serialVersionUID = 1L;
Expand All @@ -20,6 +21,11 @@ public final class Color implements Serializable {
private final int b;
private final Percent opacity;

/**
* The color grey.
*/
public static final Color GREY = Color.rgb(128, 128, 128);

/**
* The color black.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public void mouseEntered(final MouseEvent e) {

@Override
public void mouseExited(final MouseEvent e) {
pressed.clear();
isCursorOnScreen = false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ public class MacOsWindowFrame extends WindowFrame {
@Override
public void makeFullscreen(final GraphicsDevice graphicsDevice) {
try {
Thread.sleep(500); // fixes Problem when called to fast after closing a window, I am sorry!
final var screenUtils = Class.forName("com.apple.eawt.FullScreenUtilities");
final var canFullscreenMethod = screenUtils.getMethod("setWindowCanFullScreen", Window.class, Boolean.TYPE);
canFullscreenMethod.invoke(screenUtils, this, true);

final var application = Class.forName("com.apple.eawt.Application");
final var fullScreenMethod = application.getMethod("requestToggleFullScreen", Window.class);
fullScreenMethod.invoke(application.getConstructor().newInstance(), this);

} catch (final Exception e) {
throw new IllegalStateException(
"Please add jvm parameters to allow native fullscreen on MacOs: --add-opens java.desktop/com.apple.eawt=ALL-UNNAMED",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
package io.github.srcimon.screwbox.examples.gameoflife;

import io.github.srcimon.screwbox.core.Engine;
import io.github.srcimon.screwbox.core.Percent;
import io.github.srcimon.screwbox.core.ScrewBox;
import io.github.srcimon.screwbox.core.entities.Entity;
import io.github.srcimon.screwbox.core.entities.systems.LogFpsSystem;
import io.github.srcimon.screwbox.core.entities.systems.QuitOnKeyPressSystem;
import io.github.srcimon.screwbox.core.keyboard.Key;
import io.github.srcimon.screwbox.examples.gameoflife.components.GridComponent;
import io.github.srcimon.screwbox.examples.gameoflife.systems.*;
import io.github.srcimon.screwbox.core.ui.KeyboardAndMouseInteractor;
import io.github.srcimon.screwbox.examples.gameoflife.camera.CameraControlSystem;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridComponent;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridInteractionSystem;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridRenderSystem;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridUpdateSystem;
import io.github.srcimon.screwbox.examples.gameoflife.sidebar.SidebarLayouter;
import io.github.srcimon.screwbox.examples.gameoflife.sidebar.SidebarMenu;
import io.github.srcimon.screwbox.examples.gameoflife.sidebar.SidebarRenderer;
import io.github.srcimon.screwbox.examples.gameoflife.sidebar.SidebarOpacitySystem;

public class GameOfLifeExample {

Expand All @@ -19,13 +28,19 @@ public static void main(String[] args) {
.add(new GridUpdateSystem())
.add(new GridRenderSystem())
.add(new GridInteractionSystem())
.add(new PauseSystem(Key.SPACE))
.add(new QuitOnKeyPressSystem(Key.ESCAPE))
.add(new SidebarOpacitySystem())
.add(new LogFpsSystem())
.add(new CameraControlSystem());

engine.graphics().configuration().setUseAntialiasing(true);

engine.ui()
.setRenderer(new SidebarRenderer(Percent.min()))
.setLayouter(new SidebarLayouter())
.setInteractor(new KeyboardAndMouseInteractor())
.openMenu(new SidebarMenu());

engine.graphics().updateCameraZoom(6);
engine.start();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.srcimon.screwbox.examples.gameoflife.systems;
package io.github.srcimon.screwbox.examples.gameoflife.camera;

import io.github.srcimon.screwbox.core.Engine;
import io.github.srcimon.screwbox.core.entities.EntitySystem;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.github.srcimon.screwbox.examples.gameoflife.components;
package io.github.srcimon.screwbox.examples.gameoflife.grid;

import io.github.srcimon.screwbox.core.Bounds;
import io.github.srcimon.screwbox.core.Grid;
import io.github.srcimon.screwbox.core.Grid.Node;
import io.github.srcimon.screwbox.core.entities.Component;
import io.github.srcimon.screwbox.core.graphics.Color;
import io.github.srcimon.screwbox.core.utils.ListUtil;

import java.util.List;
Expand All @@ -14,6 +15,10 @@ public class GridComponent implements Component {

public Grid grid;

public Color noNeighboursColor = Color.RED;
public Color oneNeighboursColor = Color.BLUE;
public Color twoNeighboursColor = Color.WHITE;

public GridComponent() {
grid = new Grid(Bounds.$$(-480, -480, 960, 960), 2);
List<Node> nodes = grid.nodes();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.github.srcimon.screwbox.examples.gameoflife.systems;
package io.github.srcimon.screwbox.examples.gameoflife.grid;

import io.github.srcimon.screwbox.core.Engine;
import io.github.srcimon.screwbox.core.Vector;
import io.github.srcimon.screwbox.core.entities.Archetype;
import io.github.srcimon.screwbox.core.entities.Entities;
import io.github.srcimon.screwbox.core.entities.EntitySystem;
import io.github.srcimon.screwbox.core.mouse.MouseButton;
import io.github.srcimon.screwbox.examples.gameoflife.components.GridComponent;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridComponent;

public class GridInteractionSystem implements EntitySystem {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.github.srcimon.screwbox.examples.gameoflife.grid;

import io.github.srcimon.screwbox.core.Bounds;
import io.github.srcimon.screwbox.core.Engine;
import io.github.srcimon.screwbox.core.Vector;
import io.github.srcimon.screwbox.core.entities.Archetype;
import io.github.srcimon.screwbox.core.entities.EntitySystem;
import io.github.srcimon.screwbox.core.graphics.Color;
import io.github.srcimon.screwbox.core.graphics.World;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridComponent;

public class GridRenderSystem implements EntitySystem {

private static final Archetype GRID_HOLDER = Archetype.of(GridComponent.class);

@Override
public void update(final Engine engine) {
final var gridComponent = engine.entities().forcedFetch(GRID_HOLDER).get(GridComponent.class);
final World world = engine.graphics().world();
for (final var node : gridComponent.grid.nodes()) {
if (gridComponent.grid.isBlocked(node)) {
final int neighbors = gridComponent.grid.blockedNeighbors(node).size();
final var color = colorByCountOf(neighbors, gridComponent);
final Bounds worldBounds = gridComponent.grid.worldArea(node);
world.fillCircle(worldBounds.position(), (int) worldBounds.width(), color);
}
}

final Vector snappedMousePosition = gridComponent.grid.snap(engine.mouse().worldPosition());
world.fillCircle(snappedMousePosition, 2, Color.YELLOW);
}

private Color colorByCountOf(final int neighbors, final GridComponent gridComponent) {
if (neighbors == 1) {
return gridComponent.oneNeighboursColor;
}
if (neighbors == 2) {
return gridComponent.twoNeighboursColor;
}
return gridComponent.noNeighboursColor;
}

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.github.srcimon.screwbox.examples.gameoflife.systems;
package io.github.srcimon.screwbox.examples.gameoflife.grid;

import io.github.srcimon.screwbox.core.Engine;
import io.github.srcimon.screwbox.core.Grid;
import io.github.srcimon.screwbox.core.Grid.Node;
import io.github.srcimon.screwbox.core.entities.Archetype;
import io.github.srcimon.screwbox.core.entities.EntitySystem;
import io.github.srcimon.screwbox.core.utils.Timer;
import io.github.srcimon.screwbox.examples.gameoflife.components.GridComponent;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridComponent;

import static io.github.srcimon.screwbox.core.Duration.ofMillis;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.github.srcimon.screwbox.examples.gameoflife.sidebar;

import io.github.srcimon.screwbox.core.graphics.Screen;
import io.github.srcimon.screwbox.core.graphics.WindowBounds;
import io.github.srcimon.screwbox.core.ui.UiLayouter;
import io.github.srcimon.screwbox.core.ui.UiMenu;
import io.github.srcimon.screwbox.core.ui.UiMenuItem;

public class SidebarLayouter implements UiLayouter {

@Override
public WindowBounds calculateBounds(UiMenuItem item, UiMenu menu, Screen screen) {
var index = menu.itemIndex(item);
return new WindowBounds(20, 30 * index + 30, 200, 30);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.github.srcimon.screwbox.examples.gameoflife.sidebar;

import io.github.srcimon.screwbox.core.Engine;
import io.github.srcimon.screwbox.core.graphics.Color;
import io.github.srcimon.screwbox.core.ui.UiMenu;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridComponent;
import io.github.srcimon.screwbox.examples.gameoflife.grid.GridUpdateSystem;

public class SidebarMenu extends UiMenu {

public SidebarMenu() {
addItem(engine -> "fps: " + engine.loop().fps()).activeCondition(engine -> false);
addItem(engine -> "frame: " + engine.loop().frameNumber()).activeCondition(engine -> false);
addItem("colors").onActivate(engine -> {
var grid = engine.entities().forcedFetchHaving(GridComponent.class).get(GridComponent.class);
grid.noNeighboursColor = Color.random();
grid.oneNeighboursColor = Color.random();
grid.twoNeighboursColor = Color.random();
});

addItem(engine -> engine.entities().isSystemPresent(GridUpdateSystem.class) ? "pause" : "resume")
.onActivate(engine -> engine.entities().toggleSystem(new GridUpdateSystem()));

addItem(engine -> engine.graphics().configuration().isUseAntialising() ? "high quality" : "low quality").onActivate(engine -> engine.graphics().configuration().toggleAntialising());
addItem("mode").onActivate(engine -> engine.graphics().configuration().toggleFullscreen());
addItem("save").onActivate(engine -> engine.savegame().create("save"));
addItem("load").onActivate(engine -> engine.savegame().load("save")).activeCondition(engine -> engine.savegame().exists("save"));
addItem("exit").onActivate(Engine::stop);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.github.srcimon.screwbox.examples.gameoflife.sidebar;

import io.github.srcimon.screwbox.core.Engine;
import io.github.srcimon.screwbox.core.Percent;
import io.github.srcimon.screwbox.core.entities.EntitySystem;

public class SidebarOpacitySystem implements EntitySystem {

@Override
public void update(Engine engine) {
Percent opacity = Percent.of((300 - engine.mouse().position().x()) / 300.0);
engine.ui().setRenderer(new SidebarRenderer(opacity));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.github.srcimon.screwbox.examples.gameoflife.sidebar;

import io.github.srcimon.screwbox.core.Percent;
import io.github.srcimon.screwbox.core.graphics.Font;
import io.github.srcimon.screwbox.core.graphics.Screen;
import io.github.srcimon.screwbox.core.graphics.WindowBounds;
import io.github.srcimon.screwbox.core.ui.UiRenderer;

import static io.github.srcimon.screwbox.core.graphics.Color.*;
import static io.github.srcimon.screwbox.core.graphics.Offset.at;

public class SidebarRenderer implements UiRenderer {

private final Percent opacity;

public SidebarRenderer(final Percent opacity) {
this.opacity = opacity;
}

private static final Font FONT = new Font("Arial", 18, Font.Style.BOLD);

@Override
public void renderSelectableItem(String label, WindowBounds bounds, Screen screen) {
if (!opacity.isMinValue()) {
screen.drawText(at(bounds.offset().x(), bounds.center().y()), label, FONT, WHITE.opacity(opacity));
}
}

@Override
public void renderSelectedItem(String label, WindowBounds bounds, Screen screen) {
if (!opacity.isMinValue()) {
screen.drawText(at(bounds.offset().x(), bounds.center().y()), label, FONT, RED.opacity(opacity));
}
}

@Override
public void renderInactiveItem(String label, WindowBounds bounds, Screen screen) {
if (!opacity.isMinValue()) {
screen.drawText(at(bounds.offset().x(), bounds.center().y()), label, FONT, GREY.opacity(opacity));
}
}

}

This file was deleted.

This file was deleted.

0 comments on commit a89531f

Please sign in to comment.