Add EventBus and GameScene from ecs

This commit is contained in:
3wc 2024-02-14 00:21:02 -03:00
parent cd8be645a3
commit 87302a3713
11 changed files with 297 additions and 163 deletions

View File

@ -1,13 +1,21 @@
text {
font : url("res/font/minecraftia_regular_6.fnt")
}
game-container {
background: blue;
}
.mybox { .mybox {
background: #080; background: #080;
padding: -10; padding: -10;
} }
view.mybox { heading.mybox {
padding: 10; padding: 10;
} }
title-screen { title-scene {
max-width: 300; max-width: 300;
layout: vertical; layout: vertical;
} }

View File

@ -16,8 +16,8 @@ class DialogueBox extends h2d.Object {
super(); super();
if (text == null) if (text == null)
text = "NULL"; text = "NULL";
game = Game.inst; game = Game.current;
game.scene.add(this, 1); game.root.add(this, 1);
bg = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5, this); bg = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5, this);
bg.colorKey = 0xFF00FF; bg.colorKey = 0xFF00FF;
tf = new h2d.Text(game.font, this); tf = new h2d.Text(game.font, this);

View File

@ -1,85 +1,164 @@
import Const; import h2d.Layers;
import DialogueBox; import h2d.Console;
import DialogueManager;
import DialogueManager.Option; import scene.TitleScene;
import scene.WorldMapScene;
import scene.GameScene;
import event.EventBus;
import event.ChangeSceneEvent;
import Const;
// import DialogueBox;
// import DialogueManager;
// import DialogueManager.Option;
@:uiComp("game-container")
class GameContainer extends h2d.Flow implements h2d.domkit.Object {
static var SRC = <game-container>
${scene}
</game-container>;
public var scene:GameScene;
public function new(?parent) {
super(parent);
initComponent();
}
}
@:publicFields
class Game extends hxd.App { class Game extends hxd.App {
public var scene:h2d.Scene;
public var font:h2d.Font; public var font:h2d.Font;
public var world:World;
public var curDialogue:h2d.Object; public var curDialogue:h2d.Object;
public var actions:Array<h2d.ScaleGrid> = []; public var actions:Array<h2d.ScaleGrid> = [];
public var dialogueManager:DialogueManager; public var dialogueManager:DialogueManager;
public var globalEventBus:EventBus;
public static var current:Game; // Current Game (singleton)
// var layer:Layers;
public var root:GameContainer;
var console:Console;
var style = null;
override function init() { override function init() {
scene = s2d;
s2d.scaleMode = Stretch(Const.W, Const.H + 12); s2d.scaleMode = Stretch(Const.W, Const.H + 12);
world = new World(Res.map, Res.tiles);
s2d.add(world.root, 0);
font = Res.font.minecraftia_regular_6.toFont(); #if hl
font.resizeTo(24); hxd.res.Resource.LIVE_UPDATE = true;
hxd.Res.initLocal();
#else
hxd.Res.initEmbed();
#end
dialogueManager = new DialogueManager(dialogue, renderActions); root = new GameContainer();
root.horizontalAlign = root.verticalAlign = Middle;
s2d.add(root);
onResize();
var yarnText = [ style = new h2d.domkit.Style();
hxd.Res.text.intro.entry.getText(), style.load(hxd.Res.style);
]; style.allowInspect = true;
var yarnFileNames = [ style.addObject(root);
hxd.Res.text.intro.entry.name,
]; globalEventBus = new EventBus(console);
dialogueManager.load(yarnText, yarnFileNames); globalEventBus.subscribe(ChangeSceneEvent, onChangeScene);
dialogueManager.runNode("Intro");
#if debug
setGameScene(new WorldMapScene(root));
#else
setGameScene(new TitleScene(root));
#end
// font = Res.font.minecraftia_regular_6.toFont();
// font.resizeTo(24);
//
// dialogueManager = new DialogueManager(dialogue, renderActions);
//
// var yarnText = [
// hxd.Res.text.intro.entry.getText(),
// ];
// var yarnFileNames = [
// hxd.Res.text.intro.entry.name,
// ];
// dialogueManager.load(yarnText, yarnFileNames);
// dialogueManager.runNode("Intro");
} }
public static var inst:Game; public function new() {
super();
function dialogue(manager:DialogueManager, t:String) { current = this;
var d = new DialogueBox(Const.W, 100, t);
d.y = 0;
d.onClick = function() {
manager.resume();
};
curDialogue = d;
} }
function renderActions(manager:DialogueManager, t:Array<Option>) { override function onResize() {
for (action in t) { root.minWidth = root.maxWidth = s2d.width;
addAction(action.text, action.callback); root.minHeight = root.maxHeight = s2d.height;
}
override function update(dt:Float) {
style.sync();
}
// function dialogue(manager:DialogueManager, t:String) {
// var d = new DialogueBox(Const.W, 100, t);
// d.y = 0;
// d.onClick = function() {
// manager.resume();
// };
//
// curDialogue = d;
// }
//
// function renderActions(manager:DialogueManager, t:Array<Option>) {
// for (action in t) {
// addAction(action.text, action.callback);
// }
// }
//
// function newPanel(w, h) {
// var g = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5);
// g.width = w;
// g.height = h;
// g.colorKey = 0xFF00FF;
// scene.add(g, 1);
// return g;
// }
//
// function addAction(a: String, callback: () -> Void) {
// var spr = newPanel(Const.W, 60);
// curDialogue.addChild(spr);
// var tf = new h2d.Text(font, spr);
// tf.text = a;
// tf.x = 10;
// tf.y = 10;
// spr.x = 0;
// spr.y = 100 + actions.length * 60;
// var int = new h2d.Interactive(spr.width, spr.height, spr);
// int.onClick = function(_) {
// for (action in actions) {
// action.remove();
// }
// callback();
// removeDialog();
// }
// int.cursor = Button;
// actions.push(spr);
// return spr;
// }
public function onChangeScene(event:ChangeSceneEvent) {
setGameScene(event.newScene);
}
public function setGameScene(gs:GameScene) {
#if debug
// console.resetCommands();
#end
if (root.scene != null) {
root.scene.getH2dObject().remove();
} }
}
function newPanel(w, h) { root.scene = gs;
var g = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5); style.addObject(gs.getH2dObject());
g.width = w;
g.height = h;
g.colorKey = 0xFF00FF;
scene.add(g, 1);
return g;
} }
function addAction(a: String, callback: () -> Void) {
var spr = newPanel(Const.W, 60);
curDialogue.addChild(spr);
var tf = new h2d.Text(font, spr);
tf.text = a;
tf.x = 10;
tf.y = 10;
spr.x = 0;
spr.y = 100 + actions.length * 60;
var int = new h2d.Interactive(spr.width, spr.height, spr);
int.onClick = function(_) {
for (action in actions) {
action.remove();
}
callback();
// removeDialog();
}
int.cursor = Button;
actions.push(spr);
return spr;
}
} }

View File

@ -1,51 +1,5 @@
import screens.TitleScreen; class Main {
class Main extends hxd.App {
var center:h2d.Flow;
var style = null;
override function init() {
center = new h2d.Flow(s2d);
center.horizontalAlign = center.verticalAlign = Middle;
onResize();
var root = new TitleScreen(Right, center);
root.btnNewGame.onClick = function() {
Game.inst = new Game();
}
root.btnContinueGame.onClick = function() {
root.btnContinueGame.dom.addClass("highlight");
}
#if hl
root.btnQuit.onClick = function() {
Sys.exit(0);
}
#else
root.btnQuit.remove();
#end
style = new h2d.domkit.Style();
style.load(hxd.Res.style);
style.allowInspect = true;
style.addObject(root);
}
override function onResize() {
center.minWidth = center.maxWidth = s2d.width;
center.minHeight = center.maxHeight = s2d.height;
}
override function update(dt:Float) {
style.sync();
}
static function main() { static function main() {
#if hl new Game();
hxd.res.Resource.LIVE_UPDATE = true;
hxd.Res.initLocal();
#else
hxd.Res.initEmbed();
#end
new Main();
} }
} }

View File

@ -0,0 +1,11 @@
package event;
import scene.GameScene;
class ChangeSceneEvent implements IEvent {
public var newScene:GameScene;
public function new(gs:GameScene) {
this.newScene = gs;
}
}

47
src/event/EventBus.hx Normal file
View File

@ -0,0 +1,47 @@
package event;
import h2d.Console;
class EventBus {
var listeners = new Map<String, Array<Dynamic>>();
var console:Console;
public function new(console:Console) {
this.console = console;
}
public function subscribe<T:IEvent>(event:Class<T>, callback:(T) -> Void) {
var type = Type.getClassName(event);
if (!listeners.exists(type))
listeners.set(type, new Array<T>());
listeners.get(type).push(callback);
}
public function unsubscribe<T:IEvent>(event:Class<T>, callback:(T) -> Void) {
var type = Type.getClassName(event);
if (!listeners.exists(type))
return;
var callbacks = listeners.get(type);
for (c in callbacks) {
if (Reflect.compareMethods(c, callback)) {
callbacks.remove(c);
return;
}
}
}
public function publishEvent<T:IEvent>(event:T) {
var type = Type.getClassName(Type.getClass(event));
if (!listeners.exists(type)) {
#if debug
console.log('Publishing event with no listeners: $type');
#end
return;
}
for (func in listeners.get(type))
func(event);
}
}

3
src/event/IEvent.hx Normal file
View File

@ -0,0 +1,3 @@
package event;
interface IEvent {}

5
src/scene/GameScene.hx Normal file
View File

@ -0,0 +1,5 @@
package scene;
interface GameScene {
function getH2dObject():h2d.Object;
}

55
src/scene/TitleScene.hx Normal file
View File

@ -0,0 +1,55 @@
package scene;
import scene.WorldMapScene;
import event.ChangeSceneEvent;
import components.MenubuttonComponent;
@:uiComp("heading")
class HeadingComp extends h2d.Flow implements h2d.domkit.Object {
static var SRC = <heading class="mybox" min-width="200">
<text text={"Glass House"}/>
for( i in icons )
<bitmap src={i} id="icons[]"/>
</heading>;
public function new(icons:Array<h2d.Tile>, ?parent) {
super(parent);
initComponent();
}
}
@:uiComp("title-scene")
class TitleScene extends h2d.Flow implements GameScene implements h2d.domkit.Object {
static var SRC = <title-scene>
<heading([]) id="view"/>
<menubutton("New game") public id="btnNewGame"/>
<menubutton("Continue game") public id="btnContinueGame"/>
<menubutton("Credits") public id="btnCredits"/>
<menubutton("Quit") public id="btnQuit"/>
</title-scene>;
public function new(?parent) {
super(parent);
initComponent();
btnNewGame.onClick = function() {
Game.current.globalEventBus.publishEvent(new ChangeSceneEvent(new WorldMapScene(Game.current.root)));
}
btnContinueGame.onClick = function() {
btnContinueGame.dom.addClass("highlight");
}
#if hl
btnQuit.onClick = function() {
Sys.exit(0);
}
#else
btnQuit.remove();
#end
}
public function getH2dObject() {
return this;
}
}

View File

@ -1,8 +1,8 @@
class World { package scene;
var game:Game;
var map:hxd.res.TiledMap.TiledMapData;
public var root:h2d.Object; @:uiComp("world-map-scene")
class WorldMapScene extends h2d.Flow implements GameScene implements h2d.domkit.Object {
var map:hxd.res.TiledMap.TiledMapData;
var layers:Map<String, { var layers:Map<String, {
name:String, name:String,
@ -15,16 +15,17 @@ class World {
public var width:Int; public var width:Int;
public var height:Int; public var height:Int;
public function new(r:hxd.res.TiledMap, tiles:hxd.res.Image) { public function new(?parent) {
game = Game.inst; super(parent);
root = new h2d.Object(); initComponent();
map = r.toMap();
root = new h2d.Object(); var root = new h2d.Object(this);
map = Res.map.toMap();
width = map.width; width = map.width;
height = map.height; height = map.height;
var t = tiles.toTile(); var t = Res.tiles.toTile();
layers = new Map(); layers = new Map();
var font:h2d.Font = hxd.res.DefaultFont.get();
this.tiles = [ this.tiles = [
for (y in 0...Std.int(t.height) >> 5) for (x in 0...Std.int(t.width) >> 5) t.sub(x * 32, y * 32, 32, 32) for (y in 0...Std.int(t.height) >> 5) for (x in 0...Std.int(t.width) >> 5) t.sub(x * 32, y * 32, 32, 32)
]; ];
@ -37,13 +38,16 @@ class World {
g: new h2d.TileGroup(t, root), g: new h2d.TileGroup(t, root),
alpha: ld.opacity, alpha: ld.opacity,
} }
// l.g.colorKey = 0x1D8700;
l.g.alpha = ld.opacity; l.g.alpha = ld.opacity;
layers.set(ld.name, l); layers.set(ld.name, l);
rebuildLayer(ld.name); rebuildLayer(ld.name);
} }
} }
public function getH2dObject() {
return this;
}
function rebuildLayer(name:String) { function rebuildLayer(name:String) {
var l = layers.get(name); var l = layers.get(name);
if (l == null) if (l == null)
@ -51,8 +55,9 @@ class World {
var pos = 0; var pos = 0;
var g = l.g; var g = l.g;
g.clear(); g.clear();
while (g.numChildren > 0) while (g.numChildren > 0) {
g.getChildAt(0).remove(); g.getChildAt(0).remove();
}
for (y in 0...height) for (y in 0...height)
for (x in 0...width) { for (x in 0...width) {

View File

@ -1,33 +0,0 @@
package screens;
import components.MenubuttonComponent;
@:uiComp("heading")
class HeadingComp extends h2d.Flow implements h2d.domkit.Object {
static var SRC = <heading class="mybox" min-width="200" content-halign={align}>
<text text={"Rewild"}/>
for( i in icons )
<bitmap src={i} id="icons[]"/>
</heading>;
public function new(align:h2d.Flow.FlowAlign, icons:Array<h2d.Tile>, ?parent) {
super(parent);
initComponent();
}
}
@:uiComp("title-screen")
class TitleScreen extends h2d.Flow implements h2d.domkit.Object {
static var SRC = <title-screen>
<heading(align,[]) id="view"/>
<menubutton("New game") public id="btnNewGame"/>
<menubutton("Continue game") public id="btnContinueGame"/>
<menubutton("Credits") public id="btnCredits"/>
<menubutton("Quit") public id="btnQuit"/>
</title-screen>;
public function new(align:h2d.Flow.FlowAlign, ?parent) {
super(parent);
initComponent();
}
}