start of game gui, added tilesheet

This commit is contained in:
Ondřej Hruška
2014-04-18 12:09:54 +02:00
parent 56494e04f9
commit b2cf0d14a0
25 changed files with 531 additions and 89 deletions
+20 -24
View File
@@ -6,6 +6,7 @@ import java.util.Locale;
import mightypork.gamecore.control.BaseApp;
import mightypork.gamecore.control.GameLoop;
import mightypork.gamecore.control.events.ScreenRequestEvent;
import mightypork.gamecore.gui.screens.ScreenRegistry;
import mightypork.gamecore.input.InputSystem;
import mightypork.gamecore.input.KeyStroke;
@@ -14,12 +15,16 @@ import mightypork.gamecore.loading.AsyncResourceLoader;
import mightypork.gamecore.render.DisplaySystem;
import mightypork.rogue.events.ActionRequest;
import mightypork.rogue.events.ActionRequest.RequestType;
import mightypork.rogue.screens.CrossfadeOverlay;
import mightypork.rogue.screens.CrossfadeRequest;
import mightypork.rogue.screens.FpsOverlay;
import mightypork.rogue.screens.ingame.ScreenGame;
import mightypork.rogue.screens.main_menu.ScreenMainMenu;
import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy;
import mightypork.rogue.screens.test_cat_sound.ScreenTestCat;
import mightypork.rogue.screens.test_render.ScreenTestRender;
import mightypork.util.control.eventbus.EventBus;
import mightypork.util.control.eventbus.events.Event;
import mightypork.util.logging.Log;
import mightypork.util.logging.writers.LogWriter;
@@ -69,10 +74,12 @@ public class App extends BaseApp {
screens.addScreen(new ScreenTestCat(this));
screens.addScreen(new ScreenTestRender(this));
screens.addScreen(new ScreenMainMenu(this));
screens.addScreen(new ScreenGame(this));
screens.addOverlay(new FpsOverlay(this));
screens.addOverlay(new CrossfadeOverlay(this));
screens.showScreen("rogue.menu");
screens.showScreen("main_menu");
}
@@ -110,33 +117,22 @@ public class App extends BaseApp {
@Override
protected void initInputSystem(InputSystem input)
{
// Go fullscreen
input.bindKey(new KeyStroke(Keys.F11), new Runnable() {
// this will work only with reusable events (such as requests)
bindToKey(new ActionRequest(RequestType.FULLSCREEN), Keys.F11);
bindToKey(new ActionRequest(RequestType.SCREENSHOT), Keys.F2);
bindToKey(new ActionRequest(RequestType.SHUTDOWN), Keys.L_CONTROL, Keys.Q);
bindToKey(new CrossfadeRequest("main_menu"), Keys.L_CONTROL, Keys.M);
}
private void bindToKey(final Event<?> event, int... keys)
{
getInput().bindKey(new KeyStroke(keys), new Runnable() {
@Override
public void run()
{
getEventBus().send(new ActionRequest(RequestType.FULLSCREEN));
}
});
// Take screenshot
input.bindKey(new KeyStroke(Keys.F2), new Runnable() {
@Override
public void run()
{
getEventBus().send(new ActionRequest(RequestType.SCREENSHOT));
}
});
// Exit
input.bindKey(new KeyStroke(Keys.L_CONTROL, Keys.Q), new Runnable() {
@Override
public void run()
{
getEventBus().send(new ActionRequest(RequestType.SHUTDOWN));
getEventBus().send(event);
}
});
}
+22
View File
@@ -15,6 +15,7 @@ import mightypork.gamecore.render.textures.FilterMode;
import mightypork.gamecore.render.textures.TextureBank;
import mightypork.gamecore.render.textures.TxQuad;
import mightypork.gamecore.render.textures.WrapMode;
import mightypork.util.constraints.rect.Rect;
import org.newdawn.slick.opengl.Texture;
@@ -78,6 +79,27 @@ public class Res {
texture.setWrap(WrapMode.CLAMP);
textures.loadTexture("test.kitten", texture);
texture = new DeferredTexture("/res/img/gui1.png");
texture.setFilter(FilterMode.NEAREST);
texture.setWrap(WrapMode.CLAMP);
textures.loadTexture("gui1", texture);
final double p16 = 0.25D;
final double p8 = 0.125D;
//@formatter:off
textures.makeQuad("item_frame", Rect.make(0, 0, p16, p16));
textures.makeQuad("sword", Rect.make(p16, 0, p16, p16));
textures.makeQuad("meat", Rect.make(p16*2, 0, p16, p16));
textures.makeQuad("heart_on", Rect.make(0, p16, p8, p8));
textures.makeQuad("heart_off", Rect.make(p8, p16, p8, p8));
textures.makeQuad("xp_on", Rect.make(0, p16+p8, p8, p8));
textures.makeQuad("xp_off", Rect.make(p8, p16+p8, p8, p8));
textures.makeQuad("panel", Rect.make(0, p16*4-p8/2, p16*4, p8/2));
//@formatter:off
}
@@ -0,0 +1,77 @@
package mightypork.rogue.screens;
import mightypork.gamecore.control.AppAccess;
import mightypork.gamecore.control.events.ScreenRequestEvent;
import mightypork.gamecore.gui.components.painters.QuadPainter;
import mightypork.gamecore.gui.screens.Overlay;
import mightypork.util.constraints.num.mutable.NumAnimated;
import mightypork.util.control.timing.TimedTask;
import mightypork.util.math.Easing;
import mightypork.util.math.color.Color;
public class CrossfadeOverlay extends Overlay implements CrossfadeRequest.Listener {
private static final double T_IN = 0.5;
private static final double T_OUT = 0.7;
NumAnimated level = new NumAnimated(0);
Color color = Color.dark(level);
String requestedScreenName;
TimedTask tt = new TimedTask() {
@Override
public void run()
{
if(requestedScreenName == null) shutdown();
getEventBus().send(new ScreenRequestEvent(requestedScreenName));
}
};
TimedTask tt2 = new TimedTask() {
@Override
public void run()
{
level.setEasing(Easing.SINE_OUT);
level.fadeOut(T_OUT);
}
};
public CrossfadeOverlay(AppAccess app) {
super(app);
QuadPainter qp = new QuadPainter(color);
qp.setRect(root);
root.add(qp);
updated.add(level);
updated.add(tt);
updated.add(tt2);
}
@Override
public int getPriority()
{
return Integer.MAX_VALUE - 1; // let FPS go on top
}
@Override
public void goToScreen(String screen)
{
tt.start(T_IN);
tt2.start(T_IN);
level.setEasing(Easing.SINE_IN);
level.fadeIn(T_IN);
requestedScreenName = screen;
}
}
@@ -0,0 +1,35 @@
package mightypork.rogue.screens;
import mightypork.util.control.eventbus.events.Event;
/**
* @author MightyPork
*/
public class CrossfadeRequest implements Event<CrossfadeRequest.Listener> {
private String screen;
/**
* @param screen screen key to show. Null = exit the app.
*/
public CrossfadeRequest(String screen) {
super();
this.screen = screen;
}
public interface Listener {
void goToScreen(String screen);
}
@Override
public void handleBy(Listener handler)
{
handler.goToScreen(screen);
}
}
@@ -0,0 +1,62 @@
package mightypork.rogue.screens.ingame;
import mightypork.gamecore.gui.AlignX;
import mightypork.gamecore.gui.components.Component;
import mightypork.gamecore.gui.components.layout.HorizontalFixedFlowLayout;
import mightypork.gamecore.gui.components.painters.ImagePainter;
import mightypork.gamecore.gui.components.painters.QuadPainter;
import mightypork.gamecore.gui.screens.Screen;
import mightypork.gamecore.gui.screens.ScreenLayer;
import mightypork.rogue.Res;
import mightypork.util.constraints.num.Num;
import mightypork.util.constraints.rect.Rect;
import mightypork.util.math.color.PAL16;
public class GameGui extends ScreenLayer {
public GameGui(Screen screen) {
super(screen);
Num h = root.height();
Num w = root.width();
Num minWH = w.min(h).max(700); // avoid too small shrinking
Component qp = new QuadPainter(PAL16.VOID);
qp.setRect(root);
root.add(qp);
ImagePainter nav = new ImagePainter(Res.getTxQuad("panel"));
nav.setRect(root.bottomEdge().growUp(minWH.perc(7)));
root.add(nav);
HorizontalFixedFlowLayout itemSlots = new HorizontalFixedFlowLayout(root, nav.height().mul(1.8), AlignX.LEFT);
itemSlots.setRect(nav.growUp(nav.height()).move(nav.height().mul(0.2), nav.height().mul(-0.2)));
root.add(itemSlots);
itemSlots.add(new NavItemSlot(Res.getTxQuad("meat")));
itemSlots.add(new NavItemSlot(Res.getTxQuad("sword")));
Rect shrunk = root.shrink(minWH.perc(3));
Num displays_height = minWH.perc(6);
HeartBar hearts = new HeartBar(6, 3, Res.getTxQuad("heart_on"), Res.getTxQuad("heart_off"), AlignX.LEFT);
Rect hearts_box = shrunk.topLeft().startRect().growDown(displays_height);
hearts.setRect(hearts_box);
root.add(hearts);
HeartBar experience = new HeartBar(6, 2, Res.getTxQuad("xp_on"), Res.getTxQuad("xp_off"), AlignX.RIGHT);
Rect xp_box = shrunk.topRight().startRect().growDown(displays_height);
experience.setRect(xp_box);
root.add(experience);
}
@Override
public int getPriority()
{
return 100;
}
}
@@ -0,0 +1,66 @@
package mightypork.rogue.screens.ingame;
import mightypork.gamecore.gui.AlignX;
import mightypork.gamecore.gui.components.VisualComponent;
import mightypork.gamecore.render.Render;
import mightypork.gamecore.render.textures.TxQuad;
import mightypork.util.constraints.num.Num;
import mightypork.util.constraints.num.mutable.NumVar;
import mightypork.util.constraints.rect.Rect;
public class HeartBar extends VisualComponent {
private TxQuad img_on;
private TxQuad img_off;
private int total;
private int active;
NumVar index = new NumVar(0);
Rect heart;
/**
* @param total
* @param active
* @param img_on
* @param img_off
* @param align
*/
public HeartBar(int total, int active, TxQuad img_on, TxQuad img_off, AlignX align) {
super();
this.total = total;
this.active = active;
this.img_on = img_on;
this.img_off = img_off;
Num h = height();
Num w = width();
switch (align) {
case LEFT:
heart = leftEdge().growRight(h).moveX(index.mul(h));
break;
case RIGHT:
heart = rightEdge().growLeft(h).moveX(h.mul(-total+1).add(index.mul(h)));
break;
case CENTER:
heart = leftEdge().moveX(w.half().add(h.mul(-total/2D))).growRight(h).moveX(index.mul(h));
break;
}
}
@Override
protected void renderComponent()
{
for (int i = 0; i < total; i++) {
index.setTo(i);
Render.quadTextured(heart, (i < active ? img_on : img_off));
}
}
}
@@ -0,0 +1,88 @@
package mightypork.rogue.screens.ingame;
import mightypork.gamecore.gui.components.ClickableComponent;
import mightypork.gamecore.gui.components.InputComponent;
import mightypork.gamecore.render.Render;
import mightypork.gamecore.render.textures.TxQuad;
import mightypork.rogue.Res;
import mightypork.util.constraints.num.Num;
import mightypork.util.constraints.num.mutable.NumAnimated;
import mightypork.util.constraints.rect.Rect;
import mightypork.util.constraints.rect.caching.RectCache;
import mightypork.util.constraints.vect.Vect;
import mightypork.util.control.timing.Updateable;
import mightypork.util.math.Easing;
import mightypork.gamecore.control.events.MouseMotionEvent;
public class NavItemSlot extends ClickableComponent implements MouseMotionEvent.Listener, Updateable {
private TxQuad image;
private TxQuad frame;
private RectCache paintBox;
private NumAnimated yOffset;
private boolean wasInside = false;
public NavItemSlot(TxQuad image) {
this.image = image;
this.frame = Res.getTxQuad("item_frame");
Rect ref = shrink(height().perc(8));
yOffset = new NumAnimated(0, Easing.LINEAR);
yOffset.setDefaultDuration(0.05);
Num h = ref.width().min(ref.height());
this.paintBox = ref.bottomLeft().startRect().grow(Num.ZERO, h, h, Num.ZERO).moveY(yOffset.mul(h.perc(-5))).cached();
}
@Override
protected void renderComponent()
{
Render.quadTextured(paintBox, frame);
Render.pushMatrix();
Render.translateXY(paintBox.center());
Render.scaleXY(0.7);
Render.rotateZ(45);
Render.quadTextured(Rect.make(paintBox.height()).centerTo(Vect.ZERO), image);
Render.popMatrix();
}
@Override
public void updateLayout()
{
paintBox.poll();
}
@Override
public void receive(MouseMotionEvent event)
{
if (event.getPos().isInside(this) != wasInside) {
if (wasInside) {
// left
yOffset.fadeOut();
} else {
// entered
yOffset.fadeIn();
}
wasInside = !wasInside;
}
}
@Override
public void update(double delta)
{
if (yOffset.isInProgress()) {
yOffset.update(delta);
paintBox.poll();
}
}
}
@@ -0,0 +1,21 @@
package mightypork.rogue.screens.ingame;
import mightypork.gamecore.control.AppAccess;
import mightypork.gamecore.gui.screens.LayeredScreen;
public class ScreenGame extends LayeredScreen {
public ScreenGame(AppAccess app) {
super(app);
addLayer(new GameGui(this));
}
@Override
public String getName()
{
return "game_screen";
}
}
@@ -11,6 +11,7 @@ import mightypork.gamecore.gui.screens.ScreenLayer;
import mightypork.rogue.Res;
import mightypork.rogue.events.ActionRequest;
import mightypork.rogue.events.ActionRequest.RequestType;
import mightypork.rogue.screens.CrossfadeRequest;
import mightypork.util.constraints.num.Num;
import mightypork.util.constraints.rect.Rect;
import mightypork.util.control.Action;
@@ -28,7 +29,7 @@ class MenuLayer extends ScreenLayer {
private void init()
{
final Rect menuBox = root.shrink(Num.ZERO, root.height().mul(0.18)).moveY(root.height().mul(-0.03));
final Rect menuBox = root.shrink(Num.ZERO, root.height().mul(0.18)); //.moveY(root.height().mul(-0.03))
final GridLayout layout = new GridLayout(root, menuBox, 17, 1);
layout.enableCaching(true);
@@ -40,25 +41,39 @@ class MenuLayer extends ScreenLayer {
root.add(layout);
TextPainter tp;
MenuButton b1, b2, b3, b4;
tp = new TextPainter(Res.getFont("main_menu_title"), AlignX.CENTER, PAL16.SLIMEGREEN, "Rogue!");
MenuButton b0, b1, b2, b3, b4;
tp = new TextPainter(Res.getFont("main_menu_title"), AlignX.CENTER, PAL16.ZORNSKIN, "Rogue!");
b0 = new MenuButton("Ingame", PAL16.SLIMEGREEN);
b1 = new MenuButton("Gradientz", PAL16.BLAZE);
b2 = new MenuButton("Bouncy Cubes", PAL16.NEWPOOP);
b3 = new MenuButton("Flying Cat", PAL16.PIGMEAT);
b4 = new MenuButton("Bye!", PAL16.BLOODRED);
layout.put(tp, 1, 0, 4, 1);
layout.put(b1, 6, 0, 2, 1);
layout.put(b2, 8, 0, 2, 1);
layout.put(b3, 10, 0, 2, 1);
layout.put(b4, 13, 0, 2, 1);
int r=0;
layout.put(tp, r, 0, 4, 1); r += 5;
layout.put(b0, r, 0, 2, 1); r += 3;
layout.put(b1, r, 0, 2, 1); r += 2;
layout.put(b2, r, 0, 2, 1); r += 2;
layout.put(b3, r, 0, 2, 1); r += 3;
layout.put(b4, r, 0, 2, 1);
root.add(layout);
b0.setAction(new Action() {
@Override
protected void execute()
{
getEventBus().send(new CrossfadeRequest("game_screen"));
}
});
b1.setAction(new Action() {
@Override
protected void execute()
{
getEventBus().send(new ScreenRequestEvent("test.render"));
getEventBus().send(new CrossfadeRequest("test.render"));
}
});
@@ -67,7 +82,7 @@ class MenuLayer extends ScreenLayer {
@Override
protected void execute()
{
getEventBus().send(new ScreenRequestEvent("test.bouncy"));
getEventBus().send(new CrossfadeRequest("test.bouncy"));
}
});
@@ -76,7 +91,7 @@ class MenuLayer extends ScreenLayer {
@Override
protected void execute()
{
getEventBus().send(new ScreenRequestEvent("test.cat"));
getEventBus().send(new CrossfadeRequest("test.cat"));
}
});
@@ -86,7 +101,7 @@ class MenuLayer extends ScreenLayer {
@Override
protected void execute()
{
getEventBus().send(new ActionRequest(RequestType.SHUTDOWN));
getEventBus().send(new CrossfadeRequest(null)); // null -> fade and halt
}
});
}
@@ -17,7 +17,7 @@ public class ScreenMainMenu extends LayeredScreen {
@Override
public String getName()
{
return "rogue.menu";
return "main_menu";
}
}
@@ -55,7 +55,7 @@ public class LayerBouncyBoxes extends ScreenLayer {
}
final TextPainter tp = new TextPainter(Res.getFont("default"), AlignX.LEFT, Color.WHITE);
tp.setText("Press \"C\" for \"Cat\" screen.");
tp.setText("Press left & right to move.");
final Num shadowOffset = tp.height().div(16);
tp.setShadow(Color.RED, Vect.make(shadowOffset, shadowOffset));