Cleaned up bus & systems; Finished constraint system. Layered screen.
This commit is contained in:
@@ -7,20 +7,21 @@ import java.nio.channels.FileLock;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import mightypork.rogue.bus.events.UpdateEvent;
|
||||
import mightypork.rogue.display.DisplaySystem;
|
||||
import mightypork.rogue.display.Screen;
|
||||
import mightypork.rogue.display.ScreenTestAnimations;
|
||||
import mightypork.rogue.display.screens.screenBouncy.TestLayeredScreen;
|
||||
import mightypork.rogue.input.InputSystem;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
import mightypork.rogue.sounds.SoundSystem;
|
||||
import mightypork.rogue.tasks.TaskTakeScreenshot;
|
||||
import mightypork.rogue.util.Utils;
|
||||
import mightypork.utils.control.Destroyable;
|
||||
import mightypork.utils.control.bus.MessageBus;
|
||||
import mightypork.utils.control.timing.TimerDelta;
|
||||
import mightypork.utils.control.timing.UpdateEvent;
|
||||
import mightypork.utils.control.timing.Updateable;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.logging.LogInstance;
|
||||
import mightypork.utils.patterns.Destroyable;
|
||||
import mightypork.utils.patterns.subscription.MessageBus;
|
||||
import mightypork.utils.time.TimerDelta;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
@@ -46,12 +47,16 @@ public class App implements Destroyable, AppAccess {
|
||||
/** Flag that screenshot is scheduled to be taken next loop */
|
||||
private boolean scheduledScreenshot = false;
|
||||
|
||||
/** Log instance; accessible as static via Log. */
|
||||
private LogInstance log;
|
||||
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Config.init();
|
||||
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler());
|
||||
|
||||
@@ -170,7 +175,7 @@ public class App implements Destroyable, AppAccess {
|
||||
events = new MessageBus();
|
||||
events.subscribe(this);
|
||||
|
||||
events.createChannel(UpdateEvent.class, UpdateEvent.Listener.class);
|
||||
events.createChannel(UpdateEvent.class, Updateable.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +185,7 @@ public class App implements Destroyable, AppAccess {
|
||||
private void initSound()
|
||||
{
|
||||
sounds = new SoundSystem(this);
|
||||
|
||||
sounds.setMasterVolume(1);
|
||||
}
|
||||
|
||||
@@ -229,6 +235,7 @@ public class App implements Destroyable, AppAccess {
|
||||
private void initDisplay()
|
||||
{
|
||||
display = new DisplaySystem(this);
|
||||
|
||||
display.createMainWindow(Const.WINDOW_W, Const.WINDOW_H, true, Config.START_IN_FS, Const.TITLEBAR);
|
||||
display.setTargetFps(Const.FPS_RENDER);
|
||||
}
|
||||
@@ -239,16 +246,18 @@ public class App implements Destroyable, AppAccess {
|
||||
*/
|
||||
private void initLogger()
|
||||
{
|
||||
LogInstance li = Log.create("runtime", Paths.LOGS, 10);
|
||||
li.enable(Config.LOGGING_ENABLED);
|
||||
li.enableSysout(Config.LOG_TO_STDOUT);
|
||||
log = Log.create("runtime", Paths.LOGS, 10);
|
||||
log.enable(Config.LOGGING_ENABLED);
|
||||
log.enableSysout(Config.LOG_TO_STDOUT);
|
||||
}
|
||||
|
||||
|
||||
private void start()
|
||||
{
|
||||
initialize();
|
||||
|
||||
mainLoop();
|
||||
|
||||
shutdown();
|
||||
}
|
||||
|
||||
@@ -256,9 +265,13 @@ public class App implements Destroyable, AppAccess {
|
||||
private TimerDelta timerRender;
|
||||
|
||||
|
||||
/**
|
||||
* App main loop
|
||||
*/
|
||||
private void mainLoop()
|
||||
{
|
||||
screen = new ScreenTestAnimations(this);
|
||||
screen = new TestLayeredScreen(this);
|
||||
|
||||
screen.setActive(true);
|
||||
|
||||
timerRender = new TimerDelta();
|
||||
@@ -281,17 +294,13 @@ public class App implements Destroyable, AppAccess {
|
||||
/**
|
||||
* Do take a screenshot
|
||||
*/
|
||||
public void takeScreenshot()
|
||||
private void takeScreenshot()
|
||||
{
|
||||
sounds.getEffect("gui.shutter").play(1);
|
||||
Utils.runAsThread(new TaskTakeScreenshot(display));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// static accessors
|
||||
//
|
||||
|
||||
/**
|
||||
* @return sound system of the running instance
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,7 @@ package mightypork.rogue;
|
||||
import mightypork.rogue.display.DisplaySystem;
|
||||
import mightypork.rogue.input.InputSystem;
|
||||
import mightypork.rogue.sounds.SoundSystem;
|
||||
import mightypork.utils.patterns.subscription.MessageBus;
|
||||
import mightypork.utils.control.bus.MessageBus;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@ package mightypork.rogue;
|
||||
import mightypork.rogue.display.DisplaySystem;
|
||||
import mightypork.rogue.input.InputSystem;
|
||||
import mightypork.rogue.sounds.SoundSystem;
|
||||
import mightypork.utils.patterns.subscription.MessageBus;
|
||||
import mightypork.utils.control.bus.MessageBus;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,7 @@ public class Config {
|
||||
mgr.cfgSeparateSections(true);
|
||||
|
||||
mgr.putInteger(PK_LAST_RUN_VERSION, def_LAST_RUN_VERSION);
|
||||
mgr.putBoolean(PK_START_IN_FS, def_START_IN_FS);
|
||||
mgr.putBoolean(PK_START_IN_FS, def_START_IN_FS, "Go to fullscreen on startup.");
|
||||
|
||||
load(); // load what has been "put"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package mightypork.rogue.bus;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.AppAdapter;
|
||||
import mightypork.utils.control.bus.MessageBus;
|
||||
import mightypork.utils.control.bus.clients.DelegatingClient;
|
||||
import mightypork.utils.control.bus.clients.ToggleableClient;
|
||||
|
||||
|
||||
/**
|
||||
* Client that can be attached to the {@link MessageBus}, or added as a child
|
||||
* client to another {@link DelegatingClient}
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class ChildClient extends AppAdapter implements DelegatingClient, ToggleableClient {
|
||||
|
||||
public ChildClient(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
private Set<Object> clients = new LinkedHashSet<Object>();
|
||||
private boolean listening = true;
|
||||
private boolean delegating = true;
|
||||
|
||||
|
||||
@Override
|
||||
public final Collection<Object> getChildClients()
|
||||
{
|
||||
return clients;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean doesDelegate()
|
||||
{
|
||||
return delegating;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isListening()
|
||||
{
|
||||
return listening;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a child subscriber to the {@link MessageBus}.<br>
|
||||
*
|
||||
* @param client
|
||||
*/
|
||||
public final void addChildClient(Object client)
|
||||
{
|
||||
if (client != null) {
|
||||
clients.add(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a child subscriber
|
||||
*
|
||||
* @param client subscriber to remove
|
||||
*/
|
||||
public final void removeChildClient(Object client)
|
||||
{
|
||||
if (client != null) {
|
||||
clients.remove(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether events should be received.
|
||||
*
|
||||
* @param listening receive events
|
||||
*/
|
||||
public final void setListening(boolean listening)
|
||||
{
|
||||
this.listening = listening;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether events should be passed on to child nodes
|
||||
*
|
||||
* @param delegating
|
||||
*/
|
||||
public final void setDelegating(boolean delegating)
|
||||
{
|
||||
this.delegating = delegating;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package mightypork.rogue.bus;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.AppAdapter;
|
||||
import mightypork.rogue.bus.events.UpdateEvent;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.patterns.Destroyable;
|
||||
import mightypork.utils.patterns.subscription.MessageBus;
|
||||
import mightypork.utils.patterns.subscription.clients.DelegatingClient;
|
||||
import mightypork.utils.patterns.subscription.clients.ToggleableClient;
|
||||
import mightypork.utils.time.Updateable;
|
||||
|
||||
|
||||
/**
|
||||
* App event bus client, to be used for subsystems, screens and anything that
|
||||
* needs access to the eventbus
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class DelegatingBusClient extends AppAdapter implements DelegatingClient, ToggleableClient, Destroyable, Updateable, UpdateEvent.Listener {
|
||||
|
||||
/** Subsystem children subscribing to MessageBus */
|
||||
private Set<Object> childSubscribers = new HashSet<Object>();
|
||||
|
||||
private boolean wantUpdates = true;
|
||||
private boolean eventsEnabled = true;
|
||||
|
||||
|
||||
public DelegatingBusClient(AppAccess app, boolean updates) {
|
||||
super(app);
|
||||
|
||||
bus().subscribe(this);
|
||||
|
||||
enableUpdates(updates);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a child subscriber to the {@link MessageBus}.<br>
|
||||
*
|
||||
* @param client
|
||||
* @return true on success
|
||||
*/
|
||||
public final boolean addChildSubscriber(Object client)
|
||||
{
|
||||
if (client == null) return false;
|
||||
|
||||
childSubscribers.add(client);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a child subscriber
|
||||
*
|
||||
* @param client subscriber to remove
|
||||
*/
|
||||
public final void removeChildSubscriber(Object client)
|
||||
{
|
||||
if (client == null) return;
|
||||
|
||||
childSubscribers.remove(client);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Collection<Object> getChildClients()
|
||||
{
|
||||
return childSubscribers;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean doesDelegate()
|
||||
{
|
||||
return doesSubscribe();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to receive {@link UpdateEvent}s (delta timing, one each
|
||||
* frame).<br>
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
public final void enableUpdates(boolean enable)
|
||||
{
|
||||
wantUpdates = enable;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean doesSubscribe()
|
||||
{
|
||||
return eventsEnabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether events should be received.
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
public final void enableEvents(boolean enable)
|
||||
{
|
||||
this.eventsEnabled = enable;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void receive(UpdateEvent event)
|
||||
{
|
||||
if (wantUpdates) update(event.getDeltaTime());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void destroy()
|
||||
{
|
||||
deinit();
|
||||
|
||||
enableUpdates(false);
|
||||
|
||||
bus().unsubscribe(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
Log.w("Client " + getClass().getSimpleName() + " receives updates, but does not override the update() method.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the subsystem<br>
|
||||
* (called during construction)
|
||||
*/
|
||||
protected void init()
|
||||
{
|
||||
// no impl
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deinitialize the subsystem<br>
|
||||
* (called during destruction)
|
||||
*/
|
||||
protected void deinit()
|
||||
{
|
||||
// no impl
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package mightypork.rogue.bus;
|
||||
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.AppAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* Simplest event bus client with app access
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class SimpleBusClient extends AppAdapter {
|
||||
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public SimpleBusClient(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
bus().subscribe(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package mightypork.rogue.bus;
|
||||
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.utils.control.Destroyable;
|
||||
import mightypork.utils.control.bus.clients.DelegatingClient;
|
||||
import mightypork.utils.control.bus.clients.ToggleableClient;
|
||||
|
||||
|
||||
/**
|
||||
* App event bus client, to be used for subsystems, screens and anything that
|
||||
* needs access to the eventbus
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class Subsystem extends ChildClient implements DelegatingClient, ToggleableClient, Destroyable {
|
||||
|
||||
public Subsystem(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
bus().subscribe(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void destroy()
|
||||
{
|
||||
deinit();
|
||||
|
||||
setListening(false);
|
||||
|
||||
bus().unsubscribe(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deinitialize the subsystem<br>
|
||||
* (called during destruction)
|
||||
*/
|
||||
protected abstract void deinit();
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package mightypork.rogue.bus;
|
||||
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.events.UpdateEvent;
|
||||
import mightypork.utils.time.Updateable;
|
||||
|
||||
|
||||
public abstract class UpdateReceiver extends SimpleBusClient implements UpdateEvent.Listener, Updateable {
|
||||
|
||||
public UpdateReceiver(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void receive(UpdateEvent event)
|
||||
{
|
||||
update(event.getDeltaTime());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void update(double delta);
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
import mightypork.utils.control.bus.Handleable;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Handleable;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Handleable;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
|
||||
|
||||
public class MouseMotionEvent implements Handleable<MouseMotionEvent.Listener> {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Handleable;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
|
||||
|
||||
public class ScreenChangeEvent implements Handleable<ScreenChangeEvent.Listener> {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
|
||||
|
||||
public class UpdateEvent implements Handleable<UpdateEvent.Listener> {
|
||||
|
||||
private final double deltaTime;
|
||||
|
||||
|
||||
public UpdateEvent(double deltaTime) {
|
||||
this.deltaTime = deltaTime;
|
||||
}
|
||||
|
||||
|
||||
public double getDeltaTime()
|
||||
{
|
||||
return deltaTime;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleBy(Listener handler)
|
||||
{
|
||||
handler.receive(this);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
public void receive(UpdateEvent event);
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,9 @@ import java.awt.image.BufferedImage;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.DelegatingBusClient;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.rogue.bus.events.ScreenChangeEvent;
|
||||
import mightypork.rogue.display.constraints.Bounding;
|
||||
import mightypork.rogue.display.constraints.RenderContext;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
@@ -20,27 +20,21 @@ import org.lwjgl.opengl.Display;
|
||||
import org.lwjgl.opengl.DisplayMode;
|
||||
|
||||
|
||||
public class DisplaySystem extends DelegatingBusClient implements Bounding {
|
||||
public class DisplaySystem extends Subsystem implements RenderContext {
|
||||
|
||||
private DisplayMode windowDisplayMode;
|
||||
private int targetFps;
|
||||
|
||||
|
||||
public DisplaySystem(AppAccess app) {
|
||||
super(app, true);
|
||||
enableUpdates(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void init()
|
||||
{
|
||||
super(app);
|
||||
|
||||
initChannels();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void deinit()
|
||||
protected void deinit()
|
||||
{
|
||||
Display.destroy();
|
||||
}
|
||||
@@ -178,6 +172,7 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
|
||||
*/
|
||||
public void beginFrame()
|
||||
{
|
||||
// handle resize
|
||||
if (Display.wasResized()) {
|
||||
bus().broadcast(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package mightypork.rogue.display;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.display.rendering.ScreenLayer;
|
||||
import mightypork.utils.control.timing.Updateable;
|
||||
|
||||
|
||||
public abstract class LayeredScreen extends Screen {
|
||||
|
||||
private List<ScreenLayer> layers = new ArrayList<ScreenLayer>();
|
||||
private final LinkedList<ScreenLayer> layers = new LinkedList<ScreenLayer>();
|
||||
|
||||
|
||||
public LayeredScreen(AppAccess app) {
|
||||
@@ -18,10 +17,6 @@ public abstract class LayeredScreen extends Screen {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected abstract void initScreen();
|
||||
|
||||
|
||||
@Override
|
||||
protected abstract void deinitScreen();
|
||||
|
||||
@@ -35,33 +30,43 @@ public abstract class LayeredScreen extends Screen {
|
||||
|
||||
|
||||
@Override
|
||||
protected void renderScreen()
|
||||
protected final void renderScreen()
|
||||
{
|
||||
// in reverse order (topmost added last)
|
||||
for (int i = layers.size() - 1; i >= 0; i--) {
|
||||
layers.get(i).render();
|
||||
for (ScreenLayer layer : layers) {
|
||||
layer.render();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update screen. Layers should implement {@link Updateable} to receive
|
||||
* updates directly from bus.
|
||||
*/
|
||||
@Override
|
||||
protected void updateScreen(double delta)
|
||||
protected abstract void updateScreen(double delta);
|
||||
|
||||
|
||||
/**
|
||||
* Add a layer to the screen.
|
||||
*
|
||||
* @param layer
|
||||
*/
|
||||
protected final void addLayer(ScreenLayer layer)
|
||||
{
|
||||
// no impl
|
||||
this.layers.add(layer); // will be rendered from last to first
|
||||
addChildClient(layer); // connect to bus
|
||||
}
|
||||
|
||||
|
||||
protected void addLayer(ScreenLayer layer)
|
||||
{
|
||||
this.layers.add(layer);
|
||||
addChildSubscriber(layer);
|
||||
}
|
||||
|
||||
|
||||
protected void removeLayer(ScreenLayer layer)
|
||||
/**
|
||||
* Remove a layer
|
||||
*
|
||||
* @param layer
|
||||
*/
|
||||
protected final void removeLayer(ScreenLayer layer)
|
||||
{
|
||||
this.layers.remove(layer);
|
||||
addChildSubscriber(layer);
|
||||
removeChildClient(layer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ package mightypork.rogue.display;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.DelegatingBusClient;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.rogue.bus.events.ScreenChangeEvent;
|
||||
import mightypork.rogue.display.constraints.Bounding;
|
||||
import mightypork.rogue.display.constraints.RenderContext;
|
||||
import mightypork.rogue.input.KeyBinder;
|
||||
import mightypork.rogue.input.KeyBindingPool;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
import mightypork.utils.control.timing.Updateable;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
@@ -21,18 +21,22 @@ import mightypork.utils.math.coord.Rect;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class Screen extends DelegatingBusClient implements KeyBinder, Bounding, ScreenChangeEvent.Listener {
|
||||
public abstract class Screen extends Subsystem implements Updateable, KeyBinder, RenderContext, ScreenChangeEvent.Listener {
|
||||
|
||||
private KeyBindingPool keybindings;
|
||||
private final KeyBindingPool keybindings = new KeyBindingPool();
|
||||
|
||||
private boolean active;
|
||||
|
||||
private boolean inited = false;
|
||||
|
||||
|
||||
public Screen(AppAccess app) {
|
||||
super(app, true);
|
||||
super(app);
|
||||
|
||||
// disable events initially
|
||||
enableEvents(false);
|
||||
setListening(false);
|
||||
|
||||
addChildClient(keybindings);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +54,13 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected final void deinit()
|
||||
{
|
||||
deinitScreen();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare for being shown
|
||||
*
|
||||
@@ -64,83 +75,20 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
|
||||
onSizeChanged(getRect().getSize());
|
||||
onScreenEnter();
|
||||
|
||||
// subscribe to event bus
|
||||
enableEvents(true);
|
||||
// enable events
|
||||
setListening(true);
|
||||
|
||||
} else {
|
||||
onScreenLeave();
|
||||
|
||||
active = false;
|
||||
|
||||
// unsusbcribe from event bus
|
||||
enableEvents(false);
|
||||
// disable events
|
||||
setListening(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setupGraphics()
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glClearDepth(1f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
setupViewport();
|
||||
}
|
||||
|
||||
|
||||
private void setupViewport()
|
||||
{
|
||||
// fix projection for changed size
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
Coord s = disp().getSize();
|
||||
glViewport(0, 0, s.xi(), s.yi());
|
||||
glOrtho(0, s.x, 0, s.y, -1000, 1000);
|
||||
|
||||
// back to modelview
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected final void init()
|
||||
{
|
||||
keybindings = new KeyBindingPool();
|
||||
|
||||
addChildSubscriber(keybindings);
|
||||
|
||||
initScreen();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected final void deinit()
|
||||
{
|
||||
deinitScreen();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize screen layout and key bindings.<br>
|
||||
* Called during screen construction.
|
||||
*/
|
||||
protected abstract void initScreen();
|
||||
|
||||
|
||||
/**
|
||||
* Clean up before screen is destroyed.
|
||||
*/
|
||||
@@ -177,13 +125,51 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
|
||||
|
||||
|
||||
/**
|
||||
* Update animations and timing
|
||||
* Update animations and timing.<br>
|
||||
*
|
||||
* @param delta time elapsed
|
||||
*/
|
||||
protected abstract void updateScreen(double delta);
|
||||
|
||||
|
||||
private void setupGraphics()
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glClearDepth(1f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
setupViewport();
|
||||
}
|
||||
|
||||
|
||||
private void setupViewport()
|
||||
{
|
||||
// fix projection for changed size
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
Coord s = disp().getSize();
|
||||
glViewport(0, 0, s.xi(), s.yi());
|
||||
glOrtho(0, s.x, 0, s.y, -1000, 1000);
|
||||
|
||||
// back to modelview
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render screen
|
||||
*/
|
||||
@@ -234,9 +220,6 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
|
||||
|
||||
renderBegin();
|
||||
renderScreen();
|
||||
|
||||
// TODO render layers ?
|
||||
|
||||
renderEnd();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package mightypork.rogue.display;
|
||||
|
||||
|
||||
import mightypork.rogue.bus.ChildClient;
|
||||
import mightypork.rogue.display.constraints.RenderContext;
|
||||
import mightypork.rogue.display.constraints.Renderable;
|
||||
import mightypork.utils.control.timing.Updateable;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
|
||||
/**
|
||||
* Screen display layer
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class ScreenLayer extends ChildClient implements Renderable, Updateable, RenderContext {
|
||||
|
||||
private Screen screen;
|
||||
|
||||
|
||||
public ScreenLayer(Screen screen) {
|
||||
super(screen); // screen as AppAccess
|
||||
|
||||
this.screen = screen;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void render();
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void update(double delta);
|
||||
|
||||
|
||||
protected Screen screen()
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* UNSUPPORTED
|
||||
*/
|
||||
@Override
|
||||
public final void setContext(RenderContext context)
|
||||
{
|
||||
throw new UnsupportedOperationException("ScreenLayer uses screen as it's context.");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return screen.getRect();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
|
||||
/**
|
||||
* A constraint based on a given {@link RenderContext}
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class BaseConstraint implements WithContext {
|
||||
|
||||
protected RenderContext context = null;
|
||||
|
||||
|
||||
public BaseConstraint(RenderContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setContext(RenderContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return context
|
||||
*/
|
||||
public RenderContext getContext()
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return context rect origin
|
||||
*/
|
||||
protected Coord getOrigin()
|
||||
{
|
||||
if (context == null) return Coord.zero();
|
||||
|
||||
return context.getRect().getOrigin();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return context rect size
|
||||
*/
|
||||
protected Coord getSize()
|
||||
{
|
||||
if (context == null) return Coord.zero();
|
||||
|
||||
return context.getRect().getSize();
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
|
||||
public abstract class Constraint implements Bounding {
|
||||
|
||||
protected Bounding context;
|
||||
|
||||
|
||||
public Constraint(Bounding context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assign a context
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void setContext(Bounding context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return context
|
||||
*/
|
||||
public Bounding getContext()
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return context rect origin
|
||||
*/
|
||||
protected Coord origin()
|
||||
{
|
||||
return context.getRect().getOrigin();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return context rect size
|
||||
*/
|
||||
protected Coord size()
|
||||
{
|
||||
return context.getRect().getSize();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract Rect getRect();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
|
||||
|
||||
import mightypork.utils.control.timing.animation.AnimDouble;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
|
||||
/**
|
||||
* Constraint factory.<br>
|
||||
* Import statically for best experience.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class ConstraintFactory {
|
||||
|
||||
public static NumConstraint c_min(final NumConstraint a, final NumConstraint b)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return Math.min(a.getValue(), b.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_max(final NumConstraint a, final NumConstraint b)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return Math.max(a.getValue(), b.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_abs(final NumConstraint a)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return Math.abs(a.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_round(final NumConstraint a)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return Math.round(a.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_round(RenderContext context)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return context.getRect().round();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_ceil(final NumConstraint a)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return Math.ceil(a.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_floor(final NumConstraint a)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return Math.floor(a.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_neg(final NumConstraint a)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return -a.getValue();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_add(final NumConstraint a, final NumConstraint b)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return a.getValue() + b.getValue();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_sub(final NumConstraint a, final NumConstraint b)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return a.getValue() - b.getValue();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_mul(final NumConstraint a, final NumConstraint b)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return a.getValue() * b.getValue();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_div(final NumConstraint a, final NumConstraint b)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return a.getValue() / b.getValue();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_percent(final NumConstraint whole, final NumConstraint percent)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return whole.getValue() * (percent.getValue() / 100);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_n(final double a)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_n(final AnimDouble a)
|
||||
{
|
||||
return new NumConstraint(null) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return a.getCurrentValue();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_width(final RenderContext context)
|
||||
{
|
||||
return new NumConstraint(context) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return getSize().x;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static NumConstraint c_height(final RenderContext context)
|
||||
{
|
||||
return new NumConstraint(context) {
|
||||
|
||||
@Override
|
||||
public double getValue()
|
||||
{
|
||||
return getSize().y;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_row(RenderContext context, final int rows, final int index)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
double height = context.getRect().getSize().y;
|
||||
double perRow = height / rows;
|
||||
|
||||
return Rect.fromSize(getOrigin().add(0, perRow * (rows - index - 1)), getSize().setY(perRow));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_column(RenderContext context, final int columns, final int index)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
double width = context.getRect().getSize().x;
|
||||
double perCol = width / columns;
|
||||
|
||||
return Rect.fromSize(getOrigin().add(perCol * index, 0), getSize().setX(perCol));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_shrink(RenderContext context, NumConstraint shrink)
|
||||
{
|
||||
return c_shrink(context, shrink, shrink, shrink, shrink);
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_shrink(RenderContext context, NumConstraint horiz, NumConstraint vert)
|
||||
{
|
||||
return c_shrink(context, horiz, vert, horiz, vert);
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_shrink(RenderContext context, final NumConstraint left, final NumConstraint top, final NumConstraint right, final NumConstraint bottom)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return context.getRect().shrink(left.getValue(), top.getValue(), right.getValue(), bottom.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_grow(RenderContext context, NumConstraint grow)
|
||||
{
|
||||
return c_grow(context, grow, grow, grow, grow);
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_grow(RenderContext context, NumConstraint horiz, NumConstraint vert)
|
||||
{
|
||||
return c_grow(context, horiz, vert, horiz, vert);
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_grow(RenderContext context, final NumConstraint left, final NumConstraint top, final NumConstraint right, final NumConstraint bottom)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return context.getRect().grow(left.getValue(), top.getValue(), right.getValue(), bottom.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_tile(RenderContext context, final int rows, final int cols, final int left, final int top)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
double height = getSize().y;
|
||||
double width = getSize().y;
|
||||
double perRow = height / rows;
|
||||
double perCol = width / cols;
|
||||
|
||||
return Rect.fromSize(getOrigin().add(perCol * left, perRow * (rows - top - 1)), perCol, perRow);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_sizedBox(RenderContext context, final NumConstraint left, final NumConstraint bottom, final NumConstraint width, final NumConstraint height)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
Coord origin = getOrigin();
|
||||
|
||||
//@formatter:off
|
||||
return Rect.fromSize(
|
||||
origin.x + left.getValue(),
|
||||
origin.y + bottom.getValue(),
|
||||
width.getValue(),
|
||||
height.getValue()
|
||||
);
|
||||
//@formatter:on
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_posBox(RenderContext context, final NumConstraint left, final NumConstraint bottom, final NumConstraint right, final NumConstraint top)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
Coord origin = getOrigin();
|
||||
|
||||
//@formatter:off
|
||||
return new Rect(
|
||||
origin.x + left.getValue(),
|
||||
origin.y + bottom.getValue(),
|
||||
origin.x + right.getValue(),
|
||||
origin.y + top.getValue()
|
||||
);
|
||||
//@formatter:on
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static RectConstraint c_move(RenderContext context, final NumConstraint x, final NumConstraint y)
|
||||
{
|
||||
return new RectConstraint(context) {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return context.getRect().add(x.getValue(), y.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.ChildClient;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
|
||||
public class ElementHolder extends ChildClient implements RenderContext, Renderable {
|
||||
|
||||
private LinkedList<Renderable> elements = new LinkedList<Renderable>();
|
||||
private RenderContext context;
|
||||
|
||||
|
||||
public ElementHolder(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
|
||||
public ElementHolder(AppAccess app, RenderContext context) {
|
||||
super(app);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setContext(RenderContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add element to the holder.
|
||||
*
|
||||
* @param elem
|
||||
*/
|
||||
public void add(Renderable elem)
|
||||
{
|
||||
if (elem == null) return;
|
||||
elem.setContext(this);
|
||||
elements.add(elem);
|
||||
addChildClient(elem);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add element to the holder.
|
||||
*
|
||||
* @param elem
|
||||
* @param constraint
|
||||
*/
|
||||
public void add(Renderable elem, RectConstraint constraint)
|
||||
{
|
||||
if (elem == null) return;
|
||||
|
||||
constraint.setContext(this);
|
||||
elem.setContext(constraint);
|
||||
|
||||
elements.add(elem);
|
||||
addChildClient(elem);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove element from the holder
|
||||
*
|
||||
* @param elem
|
||||
*/
|
||||
public void remove(Renderable elem)
|
||||
{
|
||||
if (elem == null) return;
|
||||
elements.remove(elem);
|
||||
removeChildClient(elem);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
for (Renderable element : elements) {
|
||||
element.render();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return context.getRect();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
|
||||
|
||||
/**
|
||||
* Constraint that provides size
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class NumConstraint extends BaseConstraint {
|
||||
|
||||
public NumConstraint(RenderContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
|
||||
public abstract double getValue();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
|
||||
/**
|
||||
* Constraint that provides a rect (RenderContext)
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class RectConstraint extends BaseConstraint implements RenderContext {
|
||||
|
||||
public RectConstraint(RenderContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract Rect getRect();
|
||||
|
||||
}
|
||||
+2
-2
@@ -5,11 +5,11 @@ import mightypork.utils.math.coord.Rect;
|
||||
|
||||
|
||||
/**
|
||||
* Bounding box provider - context for {@link Constraint}
|
||||
* Bounding box provider - context for {@link RectConstraint}
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface Bounding {
|
||||
public interface RenderContext {
|
||||
|
||||
/**
|
||||
* @return bounding rectangle
|
||||
@@ -0,0 +1,12 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
|
||||
|
||||
public interface Renderable extends WithContext {
|
||||
|
||||
public void render();
|
||||
|
||||
|
||||
@Override
|
||||
public void setContext(RenderContext context);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
|
||||
|
||||
public interface WithContext {
|
||||
|
||||
/**
|
||||
* Assign a context
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void setContext(RenderContext context);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package mightypork.rogue.display.rendering;
|
||||
|
||||
|
||||
public interface Renderable {
|
||||
|
||||
public void render();
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package mightypork.rogue.display.rendering;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
import mightypork.rogue.AppAdapter;
|
||||
import mightypork.rogue.bus.UpdateReceiver;
|
||||
import mightypork.rogue.display.Screen;
|
||||
import mightypork.rogue.input.KeyBinder;
|
||||
import mightypork.rogue.input.KeyBindingPool;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
import mightypork.utils.patterns.subscription.clients.DelegatingClient;
|
||||
import mightypork.utils.time.Updateable;
|
||||
|
||||
|
||||
/**
|
||||
* Screen layer<br>
|
||||
* Plugged into a screen as a child bus subscriber, receiving update and render
|
||||
* calls directly from the screen.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class ScreenLayer extends AppAdapter implements KeyBinder, DelegatingClient, Renderable, Updateable {
|
||||
|
||||
private Screen screen;
|
||||
|
||||
private KeyBindingPool keybindings;
|
||||
|
||||
private Collection<Object> layerChildClients = new LinkedHashSet<Object>();
|
||||
|
||||
|
||||
public ScreenLayer(Screen screen) {
|
||||
super(screen); // screen as AppAccess
|
||||
|
||||
this.screen = screen;
|
||||
|
||||
layerChildClients.add(keybindings = new KeyBindingPool());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public final void bindKeyStroke(KeyStroke stroke, Runnable task)
|
||||
{
|
||||
keybindings.bindKeyStroke(stroke, task);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void unbindKeyStroke(KeyStroke stroke)
|
||||
{
|
||||
keybindings.unbindKeyStroke(stroke);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void render();
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void update(double delta);
|
||||
|
||||
|
||||
protected Screen screen()
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<Object> getChildClients()
|
||||
{
|
||||
return layerChildClients;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean doesDelegate()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+33
-40
@@ -1,18 +1,19 @@
|
||||
package mightypork.rogue.display;
|
||||
package mightypork.rogue.display.screens;
|
||||
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.events.MouseButtonEvent;
|
||||
import mightypork.rogue.display.Screen;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
import mightypork.rogue.util.RenderUtils;
|
||||
import mightypork.rogue.textures.Render;
|
||||
import mightypork.utils.control.timing.animation.AnimDouble;
|
||||
import mightypork.utils.control.timing.animation.AnimDoubleDeg;
|
||||
import mightypork.utils.math.Polar;
|
||||
import mightypork.utils.math.color.RGB;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.easing.Easing;
|
||||
import mightypork.utils.time.animation.AnimDouble;
|
||||
import mightypork.utils.time.animation.AnimDoubleDeg;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.Display;
|
||||
@@ -22,6 +23,28 @@ public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Lis
|
||||
|
||||
public ScreenTestAnimations(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
bindKeyStroke(new KeyStroke(Keyboard.KEY_RIGHT), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
for (AnimDouble a : anims) {
|
||||
a.animate(0, 1, 1 + rand.nextDouble() * 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bindKeyStroke(new KeyStroke(Keyboard.KEY_LEFT), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
for (AnimDouble a : anims) {
|
||||
a.animate(1, 0, 1 + rand.nextDouble() * 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Random rand = new Random();
|
||||
@@ -47,9 +70,6 @@ public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Lis
|
||||
new AnimDouble(0, Easing.BOUNCE_OUT),
|
||||
new AnimDouble(0, Easing.BOUNCE_OUT),
|
||||
new AnimDouble(0, Easing.BOUNCE_OUT),
|
||||
new AnimDouble(0, Easing.BOUNCE_OUT),
|
||||
new AnimDouble(0, Easing.BOUNCE_OUT),
|
||||
new AnimDouble(0, Easing.BOUNCE_OUT),
|
||||
|
||||
// new AnimDouble(0, Easing.NONE),
|
||||
// new AnimDouble(0, Easing.LINEAR),
|
||||
@@ -96,33 +116,6 @@ public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Lis
|
||||
};
|
||||
//@formatter:on
|
||||
|
||||
@Override
|
||||
public void initScreen()
|
||||
{
|
||||
bindKeyStroke(new KeyStroke(Keyboard.KEY_RIGHT), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
for (AnimDouble a : anims) {
|
||||
a.animate(0, 1, 1 + rand.nextDouble() * 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bindKeyStroke(new KeyStroke(Keyboard.KEY_LEFT), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
for (AnimDouble a : anims) {
|
||||
a.animate(1, 0, 1 + rand.nextDouble() * 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinitScreen()
|
||||
{
|
||||
@@ -167,14 +160,14 @@ public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Lis
|
||||
for (int i = 0; i < anims.length; i++) {
|
||||
AnimDouble a = anims[i];
|
||||
|
||||
RenderUtils.setColor(RGB.GREEN);
|
||||
RenderUtils.quadSize(padding + a.getCurrentValue() * (screenW - perBoxH), screenH - perBoxH * i - perBoxH + padding, boxSide, boxSide);
|
||||
Render.setColor(RGB.GREEN);
|
||||
Render.quadSize(padding + a.getCurrentValue() * (screenW - perBoxH), screenH - perBoxH * i - perBoxH + padding, boxSide, boxSide);
|
||||
}
|
||||
|
||||
RenderUtils.setColor(RGB.YELLOW);
|
||||
RenderUtils.translate(new Coord(Display.getWidth() / 2, Display.getHeight() / 2));
|
||||
RenderUtils.rotateZ(degAnim.getCurrentValue());
|
||||
RenderUtils.quadSize(-10, -10, 20, 200);
|
||||
Render.setColor(RGB.YELLOW);
|
||||
Render.translate(new Coord(Display.getWidth() / 2, Display.getHeight() / 2));
|
||||
Render.rotateZ(degAnim.getCurrentValue());
|
||||
Render.quadSize(-10, -10, 20, 200);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package mightypork.rogue.display.screens.screenBouncy;
|
||||
|
||||
|
||||
import static mightypork.rogue.display.constraints.ConstraintFactory.*;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.rogue.display.constraints.NumConstraint;
|
||||
import mightypork.rogue.display.constraints.RectConstraint;
|
||||
import mightypork.rogue.display.constraints.RenderContext;
|
||||
import mightypork.rogue.display.constraints.Renderable;
|
||||
import mightypork.rogue.textures.Render;
|
||||
import mightypork.utils.control.timing.Updateable;
|
||||
import mightypork.utils.control.timing.animation.AnimDouble;
|
||||
import mightypork.utils.math.color.RGB;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
import mightypork.utils.math.easing.Easing;
|
||||
|
||||
|
||||
public class BouncyBox implements Renderable, Updateable, RenderContext {
|
||||
|
||||
private Random rand = new Random();
|
||||
|
||||
private RenderContext context;
|
||||
|
||||
private RectConstraint box;
|
||||
|
||||
private AnimDouble pos = new AnimDouble(0, Easing.BOUNCE_OUT);
|
||||
|
||||
|
||||
public BouncyBox() {
|
||||
NumConstraint side = c_height(this);
|
||||
|
||||
NumConstraint move_length = c_sub(c_width(this), side);
|
||||
|
||||
NumConstraint offset = c_mul(move_length, c_n(pos));
|
||||
|
||||
RectConstraint abox = c_sizedBox(this, offset, c_n(0), side, side);
|
||||
|
||||
NumConstraint margin = c_percent(side, c_n(10));
|
||||
|
||||
RectConstraint with_margin = c_shrink(abox, margin);
|
||||
|
||||
box = with_margin;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return context.getRect();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
Render.quadRect(box.getRect(), RGB.GREEN);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setContext(RenderContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
public void goLeft()
|
||||
{
|
||||
pos.animate(1, 0, 2 + rand.nextDouble() * 1);
|
||||
}
|
||||
|
||||
|
||||
public void goRight()
|
||||
{
|
||||
pos.animate(0, 1, 2 + rand.nextDouble() * 1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
pos.update(delta);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package mightypork.rogue.display.screens.screenBouncy;
|
||||
|
||||
|
||||
import static mightypork.rogue.display.constraints.ConstraintFactory.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import mightypork.rogue.display.Screen;
|
||||
import mightypork.rogue.display.ScreenLayer;
|
||||
import mightypork.rogue.display.constraints.ElementHolder;
|
||||
|
||||
|
||||
public class LayerBouncyBoxes extends ScreenLayer {
|
||||
|
||||
List<BouncyBox> boxes = new ArrayList<BouncyBox>();
|
||||
private ElementHolder layout;
|
||||
|
||||
|
||||
public LayerBouncyBoxes(Screen screen) {
|
||||
super(screen);
|
||||
|
||||
layout = new ElementHolder(screen, c_shrink(this, c_percent(c_height(this), c_n(8))));
|
||||
addChildClient(layout);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
BouncyBox bbr = new BouncyBox();
|
||||
layout.add(bbr, c_row(null, 32, i));
|
||||
boxes.add(bbr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
layout.render();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
// no impl
|
||||
}
|
||||
|
||||
|
||||
public void goLeft()
|
||||
{
|
||||
for (BouncyBox bbr : boxes) {
|
||||
bbr.goLeft();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void goRight()
|
||||
{
|
||||
for (BouncyBox bbr : boxes) {
|
||||
bbr.goRight();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package mightypork.rogue.display.screens.screenBouncy;
|
||||
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.display.LayeredScreen;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
public class TestLayeredScreen extends LayeredScreen {
|
||||
|
||||
private LayerBouncyBoxes layer;
|
||||
|
||||
|
||||
public TestLayeredScreen(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
layer = new LayerBouncyBoxes(this);
|
||||
|
||||
addLayer(layer);
|
||||
|
||||
bindKeyStroke(new KeyStroke(Keyboard.KEY_RIGHT), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
layer.goRight();
|
||||
}
|
||||
});
|
||||
|
||||
bindKeyStroke(new KeyStroke(Keyboard.KEY_LEFT), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
layer.goLeft();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinitScreen()
|
||||
{
|
||||
// no impl
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onScreenEnter()
|
||||
{
|
||||
// no impl
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onScreenLeave()
|
||||
{
|
||||
// no impl
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void updateScreen(double delta)
|
||||
{
|
||||
// no impl
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,10 +2,11 @@ package mightypork.rogue.input;
|
||||
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.DelegatingBusClient;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.rogue.bus.events.KeyboardEvent;
|
||||
import mightypork.rogue.bus.events.MouseButtonEvent;
|
||||
import mightypork.rogue.bus.events.MouseMotionEvent;
|
||||
import mightypork.utils.control.timing.Updateable;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
import org.lwjgl.LWJGLException;
|
||||
@@ -14,32 +15,27 @@ import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.Display;
|
||||
|
||||
|
||||
public class InputSystem extends DelegatingBusClient implements KeyBinder {
|
||||
public class InputSystem extends Subsystem implements Updateable, KeyBinder {
|
||||
|
||||
// listeners
|
||||
private KeyBindingPool keybindings;
|
||||
|
||||
|
||||
public InputSystem(AppAccess app) {
|
||||
super(app, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void init()
|
||||
{
|
||||
super(app);
|
||||
|
||||
initDevices();
|
||||
|
||||
initChannels();
|
||||
|
||||
// global keybindings
|
||||
keybindings = new KeyBindingPool();
|
||||
addChildSubscriber(keybindings);
|
||||
addChildClient(keybindings);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void deinit()
|
||||
public final void deinit()
|
||||
{
|
||||
Mouse.destroy();
|
||||
Keyboard.destroy();
|
||||
@@ -67,7 +63,7 @@ public class InputSystem extends DelegatingBusClient implements KeyBinder {
|
||||
|
||||
|
||||
@Override
|
||||
public void bindKeyStroke(KeyStroke stroke, Runnable task)
|
||||
public final void bindKeyStroke(KeyStroke stroke, Runnable task)
|
||||
{
|
||||
keybindings.bindKeyStroke(stroke, task);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
import mightypork.utils.control.Destroyable;
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.patterns.Destroyable;
|
||||
|
||||
import org.newdawn.slick.openal.Audio;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
import mightypork.utils.control.timing.Pauseable;
|
||||
import mightypork.utils.control.timing.Updateable;
|
||||
import mightypork.utils.control.timing.animation.AnimDouble;
|
||||
import mightypork.utils.objects.Mutable;
|
||||
import mightypork.utils.time.Pauseable;
|
||||
import mightypork.utils.time.Updateable;
|
||||
import mightypork.utils.time.animation.AnimDouble;
|
||||
|
||||
import org.lwjgl.openal.AL10;
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.DelegatingBusClient;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.utils.control.timing.Updateable;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.Calc.Buffers;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
@@ -25,7 +26,7 @@ import org.newdawn.slick.openal.SoundStore;
|
||||
* @author MightyPork
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SoundSystem extends DelegatingBusClient {
|
||||
public class SoundSystem extends Subsystem implements Updateable {
|
||||
|
||||
private static final Coord INITIAL_LISTENER_POS = new Coord(0, 0, 0);
|
||||
private static final int MAX_SOURCES = 256;
|
||||
@@ -78,19 +79,12 @@ public class SoundSystem extends DelegatingBusClient {
|
||||
|
||||
|
||||
public SoundSystem(AppAccess app) {
|
||||
super(app, true);
|
||||
super(app);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void init()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void deinit()
|
||||
public final void deinit()
|
||||
{
|
||||
for (AudioX r : resources) {
|
||||
r.destroy();
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
package mightypork.rogue.testing;
|
||||
|
||||
|
||||
import mightypork.rogue.display.constraints.Bounding;
|
||||
import mightypork.rogue.display.constraints.Constraint;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
|
||||
public class TestConstraints {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Bounding context = new Bounding() {
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return Rect.fromSize(new Coord(0, 0), new Coord(400, 300));
|
||||
}
|
||||
};
|
||||
|
||||
class Navbar extends Constraint {
|
||||
|
||||
private double height;
|
||||
|
||||
|
||||
public Navbar(Bounding context, double height) {
|
||||
super(context);
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return Rect.fromSize(origin().setY(size().y - height), size().setY(height));
|
||||
}
|
||||
}
|
||||
|
||||
class TileHorizontal extends Constraint {
|
||||
|
||||
private int count;
|
||||
private int tile;
|
||||
|
||||
|
||||
public TileHorizontal(Bounding context, int tileCount, int aTile) {
|
||||
super(context);
|
||||
this.count = tileCount;
|
||||
setTile(aTile);
|
||||
}
|
||||
|
||||
|
||||
public void setTile(int aTile)
|
||||
{
|
||||
if (aTile > count) throw new IndexOutOfBoundsException("Tile count exceeded: " + aTile + " max: " + count);
|
||||
this.tile = aTile;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
Coord size = size().mul(1D / count, 1);
|
||||
return Rect.fromSize(origin().add(size.x * tile, 0), size);
|
||||
}
|
||||
}
|
||||
|
||||
Navbar nb = new Navbar(context, 100);
|
||||
|
||||
TileHorizontal tile = new TileHorizontal(nb, 5, 0);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
tile.setTile(i);
|
||||
|
||||
System.out.println(tile.getRect());
|
||||
}
|
||||
|
||||
System.out.println("nb:" + nb.getRect());
|
||||
|
||||
System.out.println("ctx:" + context.getRect());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
package mightypork.rogue.testing;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
import mightypork.utils.patterns.subscription.MessageBus;
|
||||
import mightypork.utils.patterns.subscription.clients.DelegatingClient;
|
||||
import mightypork.utils.patterns.subscription.clients.ToggleableClient;
|
||||
|
||||
|
||||
public class TestMsgbus {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Log.create("runtime", new File("."), 0);
|
||||
|
||||
MessageBus bus = new MessageBus();
|
||||
|
||||
bus.createChannel(StringMessage.class, StringMessage.Listener.class);
|
||||
bus.createChannel(IntMessage.class, IntMessage.Listener.class);
|
||||
|
||||
Delegator deleg1 = new Delegator("Deleg1");
|
||||
Delegator deleg2 = new Delegator("Deleg2");
|
||||
Toggleable togg1 = new Toggleable("Tog1");
|
||||
Toggleable togg2 = new Toggleable("Tog2");
|
||||
Toggleable plain1 = new Toggleable("Plain1");
|
||||
Toggleable plain2 = new Toggleable("Plain2");
|
||||
Toggleable plain3 = new Toggleable("Plain3");
|
||||
|
||||
PlainInt pint = new PlainInt("Ints");
|
||||
PlainBoth pboth = new PlainBoth("Both");
|
||||
|
||||
bus.subscribe(deleg1);
|
||||
|
||||
deleg1.clients.add(togg1);
|
||||
deleg1.clients.add(plain2);
|
||||
deleg1.clients.add(deleg2);
|
||||
deleg1.clients.add(pint);
|
||||
|
||||
deleg2.clients.add(deleg1);
|
||||
deleg2.clients.add(togg1);
|
||||
deleg2.clients.add(plain3);
|
||||
deleg2.clients.add(pboth);
|
||||
|
||||
bus.subscribe(plain1);
|
||||
|
||||
bus.subscribe(togg2);
|
||||
|
||||
bus.broadcast(new StringMessage("<MSG>"));
|
||||
bus.broadcast(new IntMessage(7));
|
||||
bus.broadcast(new IntMessage(13));
|
||||
|
||||
deleg2.delegating = false;
|
||||
|
||||
bus.broadcast(new IntMessage(44));
|
||||
|
||||
deleg2.delegating = true;
|
||||
|
||||
bus.broadcast(new IntMessage(45));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Delegator extends Plain implements DelegatingClient {
|
||||
|
||||
List<Object> clients = new ArrayList<Object>();
|
||||
boolean delegating = true;
|
||||
|
||||
|
||||
public Delegator(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<Object> getChildClients()
|
||||
{
|
||||
return clients;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean doesDelegate()
|
||||
{
|
||||
return delegating;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Toggleable extends Plain implements ToggleableClient {
|
||||
|
||||
boolean subscribing = true;
|
||||
|
||||
|
||||
public Toggleable(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean doesSubscribe()
|
||||
{
|
||||
return subscribing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Plain implements StringMessage.Listener {
|
||||
|
||||
String name;
|
||||
|
||||
|
||||
public Plain(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void receive(StringMessage message)
|
||||
{
|
||||
System.out.println(name + " (STR) RECV: " + message.s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PlainInt implements IntMessage.Listener {
|
||||
|
||||
String name;
|
||||
|
||||
|
||||
public PlainInt(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void receive(IntMessage message)
|
||||
{
|
||||
System.out.println(name + " (INT) RECV: " + message.i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PlainBoth implements IntMessage.Listener, StringMessage.Listener {
|
||||
|
||||
String name;
|
||||
|
||||
|
||||
public PlainBoth(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void receive(IntMessage message)
|
||||
{
|
||||
System.out.println(name + " (both-INT) RECV: " + message.i);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void receive(StringMessage message)
|
||||
{
|
||||
System.out.println(name + " (both-STR) RECV: " + message.s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class StringMessage implements Handleable<StringMessage.Listener> {
|
||||
|
||||
String s;
|
||||
|
||||
|
||||
StringMessage(String str) {
|
||||
this.s = str;
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
public void receive(StringMessage message);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleBy(Listener handler)
|
||||
{
|
||||
handler.receive(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class IntMessage implements Handleable<IntMessage.Listener> {
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
IntMessage(int i) {
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
public void receive(IntMessage message);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleBy(Listener handler)
|
||||
{
|
||||
handler.receive(this);
|
||||
}
|
||||
}
|
||||
+99
-17
@@ -1,15 +1,20 @@
|
||||
package mightypork.rogue.util;
|
||||
package mightypork.rogue.textures;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import mightypork.rogue.textures.TextureManager;
|
||||
import mightypork.rogue.textures.TxQuad;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.color.HSV;
|
||||
import mightypork.utils.math.color.RGB;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
import org.newdawn.slick.opengl.TextureLoader;
|
||||
import org.newdawn.slick.util.ResourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
@@ -17,12 +22,15 @@ import org.newdawn.slick.opengl.Texture;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class RenderUtils {
|
||||
public class Render {
|
||||
|
||||
private static final Coord AXIS_X = new Coord(1, 0, 0);
|
||||
private static final Coord AXIS_Y = new Coord(0, 1, 0);
|
||||
private static final Coord AXIS_Z = new Coord(0, 0, 1);
|
||||
|
||||
public static Texture lastBinded = null;
|
||||
private static boolean inited = false;
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D
|
||||
@@ -85,18 +93,18 @@ public class RenderUtils {
|
||||
{
|
||||
double bdr = border;
|
||||
|
||||
RenderUtils.setColor(borderColor);
|
||||
setColor(borderColor);
|
||||
|
||||
//@formatter:off
|
||||
RenderUtils.quadCoord(minX, minY, minX + bdr, maxY);
|
||||
RenderUtils.quadCoord(maxX - bdr, minY, maxX, maxY);
|
||||
RenderUtils.quadCoord(minX + bdr, maxY - bdr, maxX - bdr, maxY);
|
||||
RenderUtils.quadCoord(minX + bdr, minY, maxX - bdr, minY + bdr);
|
||||
quadCoord(minX, minY, minX + bdr, maxY);
|
||||
quadCoord(maxX - bdr, minY, maxX, maxY);
|
||||
quadCoord(minX + bdr, maxY - bdr, maxX - bdr, maxY);
|
||||
quadCoord(minX + bdr, minY, maxX - bdr, minY + bdr);
|
||||
//@formatter:on
|
||||
|
||||
if (insideColor != null) {
|
||||
RenderUtils.setColor(insideColor);
|
||||
RenderUtils.quadCoord(minX + bdr, minY + bdr, maxX - bdr, maxY - bdr);
|
||||
setColor(insideColor);
|
||||
quadCoord(minX + bdr, minY + bdr, maxX - bdr, maxY - bdr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +337,7 @@ public class RenderUtils {
|
||||
|
||||
double bdr = border;
|
||||
|
||||
RenderUtils.setColor(leftTopC);
|
||||
setColor(leftTopC);
|
||||
|
||||
// left + top
|
||||
glBegin(GL_QUADS);
|
||||
@@ -344,7 +352,7 @@ public class RenderUtils {
|
||||
glVertex2d(maxX, maxY);
|
||||
glEnd();
|
||||
|
||||
RenderUtils.setColor(rightBottomC);
|
||||
setColor(rightBottomC);
|
||||
|
||||
// right + bottom
|
||||
glBegin(GL_QUADS);
|
||||
@@ -359,8 +367,8 @@ public class RenderUtils {
|
||||
glVertex2d(minX + bdr, minY + bdr);
|
||||
glEnd();
|
||||
|
||||
RenderUtils.setColor(fill);
|
||||
RenderUtils.quadCoord(minX + bdr, minY + bdr, maxX - bdr, maxY - bdr);
|
||||
setColor(fill);
|
||||
quadCoord(minX + bdr, minY + bdr, maxX - bdr, maxY - bdr);
|
||||
}
|
||||
|
||||
|
||||
@@ -524,11 +532,11 @@ public class RenderUtils {
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
setColor(tint);
|
||||
TextureManager.bind(texture);
|
||||
bindTexture(texture);
|
||||
|
||||
quadTexturedAbs(quad, txCoords.mul(1 / texture.getImageHeight()));
|
||||
|
||||
TextureManager.unbind();
|
||||
unbindTexture();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
@@ -946,4 +954,78 @@ public class RenderUtils {
|
||||
Coord vec = axis.norm(1);
|
||||
glRotated(angle, vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
|
||||
public static void push()
|
||||
{
|
||||
glPushMatrix();
|
||||
}
|
||||
|
||||
|
||||
public static void pop()
|
||||
{
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load texture
|
||||
*
|
||||
* @param resourcePath
|
||||
* @return the loaded texture
|
||||
*/
|
||||
public static Texture loadTexture(String resourcePath)
|
||||
{
|
||||
if (!inited) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
inited = true;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
String ext = FileUtils.getExtension(resourcePath);
|
||||
|
||||
Texture texture = TextureLoader.getTexture(ext.toUpperCase(), ResourceLoader.getResourceAsStream(resourcePath));
|
||||
|
||||
if (texture == null) {
|
||||
Log.w("Texture " + resourcePath + " could not be loaded.");
|
||||
}
|
||||
|
||||
return texture;
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e("Loading of texture " + resourcePath + " failed.", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind texture
|
||||
*
|
||||
* @param texture the texture
|
||||
* @throws RuntimeException if not loaded yet
|
||||
*/
|
||||
public static void bindTexture(Texture texture) throws RuntimeException
|
||||
{
|
||||
if (texture != lastBinded) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
|
||||
lastBinded = texture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unbind all
|
||||
*/
|
||||
public static void unbindTexture()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
lastBinded = null;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package mightypork.rogue.textures;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
import org.newdawn.slick.opengl.TextureLoader;
|
||||
import org.newdawn.slick.util.ResourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Texture manager
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TextureManager {
|
||||
|
||||
private static Texture lastBinded = null;
|
||||
|
||||
|
||||
/**
|
||||
* Load texture
|
||||
*
|
||||
* @param resourcePath
|
||||
* @return the loaded texture
|
||||
*/
|
||||
public static Texture load(String resourcePath)
|
||||
{
|
||||
try {
|
||||
String ext = resourcePath.substring(resourcePath.length() - 4);
|
||||
|
||||
Texture texture = TextureLoader.getTexture(ext.toUpperCase(), ResourceLoader.getResourceAsStream(resourcePath));
|
||||
|
||||
if (texture != null) {
|
||||
return texture;
|
||||
}
|
||||
|
||||
Log.w("Texture " + resourcePath + " could not be loaded.");
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
Log.e("Loading of texture " + resourcePath + " failed.", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind texture
|
||||
*
|
||||
* @param texture the texture
|
||||
* @throws RuntimeException if not loaded yet
|
||||
*/
|
||||
public static void bind(Texture texture) throws RuntimeException
|
||||
{
|
||||
if (texture != lastBinded) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
|
||||
lastBinded = texture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unbind all
|
||||
*/
|
||||
public static void unbind()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
lastBinded = null;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package mightypork.rogue.textures;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
|
||||
|
||||
// TODO rewrite to use hashmap with keys
|
||||
|
||||
/**
|
||||
* Texture loading class
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Textures {
|
||||
|
||||
protected static Texture logo;
|
||||
|
||||
private static final String GUI = "res/images/gui/";
|
||||
|
||||
|
||||
/**
|
||||
* Load what's needed for splash
|
||||
*/
|
||||
public static void load()
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
logo = TextureManager.load(GUI + "logo.png");
|
||||
|
||||
Tx.initForSplash();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
Tx.init();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package mightypork.rogue.textures;
|
||||
|
||||
|
||||
// TODO rewrite
|
||||
|
||||
/**
|
||||
* List of texture quads for GUIs
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Tx {
|
||||
|
||||
// logo
|
||||
public static TxQuad LOGO;
|
||||
|
||||
|
||||
public static void initForSplash()
|
||||
{
|
||||
// splash logo
|
||||
LOGO = TxQuad.fromSize(Textures.logo, 15, 9, 226, 132);
|
||||
}
|
||||
|
||||
|
||||
public static void init()
|
||||
{
|
||||
// title image (word art)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user