diff --git a/res/style.css b/res/style.css index df632ff..509cf09 100644 --- a/res/style.css +++ b/res/style.css @@ -52,3 +52,22 @@ menubutton:hover text { menubutton:active { background: #666; } + +flow.dialogue-container { + fill-width: true; + height: 20; + debug: true; +} + +dialogue-box { + fill-width: true; + height: 20; +} + +scale-grid#dialogueBackground { + /* fill-width: true; */ +} + +/* text#dialogueText { */ +/* font : url("res/font/minecraftia_regular_6.fnt"); */ +/* } */ diff --git a/src/Game.hx b/src/Game.hx index aeb9478..e757091 100644 --- a/src/Game.hx +++ b/src/Game.hx @@ -7,13 +7,8 @@ import scene.GameScene; import event.EventBus; import event.ChangeSceneEvent; import Const; -import dialogue.DialogueBox; +import listeners.DialogueBoxController; import dialogue.DialogueManager; -import dialogue.event.LineShown; -import dialogue.event.OptionsShown; -import dialogue.event.OptionSelected; -import dialogue.event.DialogueComplete; -import dialogue.event.NextLine; import dialogue.command.OpenRoomCommand; @:uiComp("game-container") @@ -31,24 +26,20 @@ class GameContainer extends h2d.Flow implements h2d.domkit.Object { } class Game extends hxd.App { - public var font:h2d.Font; - public var curDialogue:h2d.Object; - public var options:Array = []; - public var dialogueManager:DialogueManager; - - public var globalEventBus:EventBus; - + public static var loader = new tiled.Tiled(); public static var current:Game; // Current Game (singleton) - var layer:Layers; - + public var font:h2d.Font; + public var options:Array = []; + public var dialogueManager:DialogueManager; public var root:GameContainer; public var console:Console; + public var globalEventBus:EventBus; + var dialogueBoxController:DialogueBoxController; + var layer:Layers; var style = null; - public static var loader = new tiled.Tiled(); - override function init() { s2d.scaleMode = Stretch(Const.W, Const.H); layer = new Layers(s2d); @@ -62,7 +53,6 @@ class Game extends hxd.App { root = new GameContainer(); root.horizontalAlign = root.verticalAlign = Middle; - // s2d.add(root); layer.addChildAt(root, 1); onResize(); @@ -72,14 +62,13 @@ class Game extends hxd.App { style.addObject(root); font = Res.font.minecraftia_regular_6.toFont(); + font.resizeTo(18); #if debug console = new Console(font); layer.addChildAt(console, 4); #end - font.resizeTo(20); - globalEventBus = new EventBus(console); globalEventBus.subscribe(ChangeSceneEvent, onChangeScene); @@ -89,12 +78,15 @@ class Game extends hxd.App { var yarnFileNames = [hxd.Res.text.intro.entry.name, hxd.Res.text.rooms.entry.name,]; dialogueManager.load(yarnText, yarnFileNames); - globalEventBus.subscribe(LineShown, dialogue); - globalEventBus.subscribe(OptionsShown, renderOptions); - globalEventBus.subscribe(OptionSelected, onOptionSelected); - globalEventBus.subscribe(DialogueComplete, onDialogueComplete); dialogueManager.addCommandHandler(new OpenRoomCommand(globalEventBus)); + var dialogueParent = new h2d.Flow(); + dialogueParent.dom = domkit.Properties.create("flow", dialogueParent); + dialogueParent.dom.addClass('dialogue-container'); + style.addObject(dialogueParent); + layer.addChildAt(dialogueParent, 2); + dialogueBoxController = new DialogueBoxController(globalEventBus, dialogueParent, style); + #if debug setGameScene(new WorldMapScene(root)); #else @@ -116,70 +108,6 @@ class Game extends hxd.App { style.sync(); } - function dialogue(event:LineShown) { - if (curDialogue != null) { - curDialogue.remove(); - } - var d = new DialogueBox(Const.W, 100, event.line()); - d.y = 0; - d.onClick = function() { - globalEventBus.publishEvent(new NextLine()); - }; - - curDialogue = d; - } - - function renderOptions(event:OptionsShown) { - for (option in event.options) { - addOption(option.text, option.enabled, function() { - if (option.enabled) { - globalEventBus.publishEvent(new OptionSelected(option.index)); - } - }); - } - } - - function newPanel(w, h) { - var g = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5); - g.width = w; - g.height = h; - g.colorKey = 0xFF00FF; - root.scene.getH2dObject().getScene().add(g, 1); - return g; - } - - function addOption(o:String, enabled:Bool, callback:() -> Void) { - var spr = newPanel(Const.W, 60); - curDialogue.addChild(spr); - var tf = new h2d.Text(font, spr); - if (!enabled) { - tf.color = new Vector4(0.5, 0.5, 0.5, 1); - } - tf.text = o; - tf.x = 10; - tf.y = 10; - spr.x = 0; - spr.y = 100 + options.length * 60; - var int = new h2d.Interactive(spr.width, spr.height, spr); - int.onClick = function(_) { - callback(); - } - int.cursor = Button; - options.push(spr); - return spr; - } - - function onOptionSelected(event:OptionSelected) { - for (o in options) { - o.remove(); - } - options.splice(0, options.length); - } - - function onDialogueComplete(event:DialogueComplete) { - curDialogue.remove(); - } - public function onChangeScene(event:ChangeSceneEvent) { setGameScene(event.newScene); } diff --git a/src/components/DialogueBoxComponent.hx b/src/components/DialogueBoxComponent.hx new file mode 100644 index 0000000..5195138 --- /dev/null +++ b/src/components/DialogueBoxComponent.hx @@ -0,0 +1,135 @@ +package components; + +import dialogue.event.NextLine; + +@:uiComp("dialogue-option") +class DialogueOptionComponent extends h2d.Flow implements h2d.domkit.Object { + static var SRC = + + ; + + public var label(get, set):String; + + function get_label() + return labelTxt.text; + + function set_label(s) { + labelTxt.text = s; + return s; + } + + public function new(label:String, ?parent) { + super(parent); + initComponent(); + enableInteractive = true; + interactive.onClick = function(_) onClick(); + interactive.onOver = function(_) { + dom.hover = true; + }; + interactive.onPush = function(_) { + dom.active = true; + }; + interactive.onRelease = function(_) { + dom.active = false; + }; + interactive.onOut = function(_) { + dom.hover = false; + }; + } + + public dynamic function onClick() {} +} + +@:uiComp("dialogue-options") +class DialogueOptionsComponent extends h2d.Flow implements h2d.domkit.Object { + static var SRC = + ${options} + ; + + public var options:Array; +} + +@:uiComp("dialogue-box") +class DialogueBoxComponent extends h2d.Flow implements h2d.domkit.Object { + var timer:haxe.Timer; + var chan:hxd.snd.Channel; + var textPos:Int = 0; + var game:Game; + + static var SRC = + + + + + + public var displayedText(get, set):String; + + function get_displayedText() + return dialogueText.text; + + function set_displayedText(s) { + dialogueText.text = s; + return s; + } + + public var internalText(default, set):String; + + function set_internalText(t) { + internalText = t; + timer = new haxe.Timer(30); + timer.run = updateText; + displayedText = ""; + textPos = 0; + return t; + } + + public function new(text:String, ?parent) { + this.game = Game.current; + super(parent); + initComponent(); + internalText = text; + this.dialogueBackground.tile = Res.ui.toTile(); + this.dialogueBackground.borderWidth = 5; + this.dialogueBackground.borderHeight = 5; + this.dialogueBackground.colorKey = 0xFF00FF; + this.dialogueBackground.width = this.innerWidth; + this.dialogueBackground.height = this.innerHeight; + // trace(this.dialogueBackground.width); + + enableInteractive = true; + interactive.onClick = function(_) onClick(); + } + + function updateText() { + if (textPos == internalText.length) { + timer.stop(); + // onReady(); + // if (chan != null) + // chan.stop(); + return; + } + // if (chan != null) { + // switch (text.charCodeAt(textPos)) { + // case " ".code, "\n".code: + // chan.volume = 0; + // default: + // if (chan.volume == 0) + // chan.volume = 1 + // else + // chan.volume *= 0.9; + // } + // } + textPos++; + displayedText = internalText.substr(0, textPos); + } + + public dynamic function onClick() { + if (textPos == internalText.length) + Game.current.globalEventBus.publishEvent(new NextLine()); + else if (textPos < internalText.length) { + textPos = internalText.length; + displayedText = internalText; + updateText(); + }; + } +} diff --git a/src/dialogue/DialogueBox.hx b/src/dialogue/DialogueBox.hx deleted file mode 100644 index 4bac05b..0000000 --- a/src/dialogue/DialogueBox.hx +++ /dev/null @@ -1,107 +0,0 @@ -package dialogue; - -class DialogueBox extends h2d.Object { - var game:Game; - var bg:h2d.ScaleGrid; - var tf:h2d.Text; - var timer:haxe.Timer; - var int:h2d.Interactive; - - public var width(default, set):Int; - public var height(default, set):Int; - public var text(default, set):String; - - var textPos:Int = 0; - var chan:hxd.snd.Channel; - - public function new(width:Int, height:Int, text:String) { - super(); - if (text == null) - text = "NULL"; - game = Game.current; - cast(game.root, h2d.Object).getScene().add(this, 1); - bg = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5, this); - bg.colorKey = 0xFF00FF; - tf = new h2d.Text(game.font, this); - tf.y = 5; - tf.x = 7; - tf.dropShadow = { - dx: 0, - dy: 1, - color: 0, - alpha: 0.3 - }; - int = new h2d.Interactive(0, 0, this); - int.onClick = function(_) click(); - this.width = width; - this.height = height; - this.text = text; - } - - override function onRemove() { - super.onRemove(); - if (chan != null) - chan.stop(); - timer.stop(); - } - - function updateText() { - if (textPos == text.length) { - timer.stop(); - onReady(); - if (chan != null) - chan.stop(); - return; - } - if (chan != null) { - switch (text.charCodeAt(textPos)) { - case " ".code, "\n".code: - chan.volume = 0; - default: - if (chan.volume == 0) - chan.volume = 1 - else - chan.volume *= 0.9; - } - } - textPos++; - tf.text = text.substr(0, textPos); - } - - public function click() { - if (textPos == text.length) - onClick() - else if (textPos < text.length) { - textPos = text.length; - tf.text = text; - updateText(); - }; - } - - public dynamic function onClick() {} - - public dynamic function onReady() {} - - function set_text(t) { - text = t; - timer = new haxe.Timer(30); - timer.run = updateText; - tf.text = ""; - textPos = 0; - return t; - } - - function set_width(w:Int) { - bg.width = w; - int.width = w; - tf.maxWidth = w - 14; - tf.text = text; - return width = w; - } - - function set_height(h:Int) { - bg.height = h; - int.height = h; - return height = h; - } -} diff --git a/src/event/EventBus.hx b/src/event/EventBus.hx index 901c243..0999b7b 100644 --- a/src/event/EventBus.hx +++ b/src/event/EventBus.hx @@ -40,6 +40,7 @@ class EventBus { #end return; } + trace('Publishing event $type'); for (func in listeners.get(type)) func(event); diff --git a/src/listeners/DialogueBoxController.hx b/src/listeners/DialogueBoxController.hx new file mode 100644 index 0000000..2a74136 --- /dev/null +++ b/src/listeners/DialogueBoxController.hx @@ -0,0 +1,125 @@ +package listeners; + +import Game; + +import event.EventBus; + +import dialogue.DialogueManager; + +import dialogue.event.LineShown; +import dialogue.event.OptionsShown; +import dialogue.event.OptionSelected; +import dialogue.event.DialogueComplete; +import dialogue.event.NextLine; + +import components.DialogueBoxComponent; + +class DialogueBoxController { + public var curDialogue:DialogueBoxComponent; + + var game:Game; + var bg:h2d.ScaleGrid; + var tf:h2d.Text; + var int:h2d.Interactive; + var eventBus:EventBus; + var parent:h2d.Object; + var style:h2d.domkit.Style; + + public function new(eventBus:EventBus, parent:h2d.Object, style:h2d.domkit.Style) { + this.parent = parent; + this.style = style; + // game = Game.current; + // parent.getScene().add(this, 1); + // bg = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5, this); + // bg.colorKey = 0xFF00FF; + // tf = new h2d.Text(game.font, this); + // tf.y = 5; + // tf.x = 7; + // tf.dropShadow = { + // dx: 0, + // dy: 1, + // color: 0, + // alpha: 0.3 + // }; + // int = new h2d.Interactive(0, 0, this); + // int.onClick = function(_) click(); + + eventBus.subscribe(LineShown, dialogue); + // eventBus.subscribe(OptionsShown, renderOptions); + // eventBus.subscribe(OptionSelected, onOptionSelected); + eventBus.subscribe(DialogueComplete, onDialogueComplete); + } + + // override function onRemove() { + // super.onRemove(); + // // if (chan != null) + // // chan.stop(); + // // timer.stop(); + // } + + public dynamic function onClick() {} + + public dynamic function onReady() {} + + function dialogue(event:LineShown) { + if (curDialogue != null) { + curDialogue.remove(); + } + var d = new DialogueBoxComponent(event.line(), this.parent); + style.addObject(d); + + curDialogue = d; + } + + // function renderOptions(event:OptionsShown) { + // for (option in event.options) { + // addOption(option.text, option.enabled, function() { + // if (option.enabled) { + // globalEventBus.publishEvent(new OptionSelected(option.index)); + // } + // }); + // } + // } + // + // function newPanel(w, h) { + // var g = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5); + // g.width = w; + // g.height = h; + // g.colorKey = 0xFF00FF; + // root.scene.getH2dObject().getScene().add(g, 1); + // return g; + // } + // + // function addOption(o:String, enabled:Bool, callback:() -> Void) { + // var spr = newPanel(Const.W, 60); + // curDialogue.addChild(spr); + // var tf = new h2d.Text(font, spr); + // if (!enabled) { + // tf.color = new Vector4(0.5, 0.5, 0.5, 1); + // } + // tf.text = o; + // tf.x = 10; + // tf.y = 10; + // spr.x = 0; + // spr.y = 100 + options.length * 60; + // var int = new h2d.Interactive(spr.width, spr.height, spr); + // int.onClick = function(_) { + // callback(); + // } + // int.cursor = Button; + // options.push(spr); + // return spr; + // } + // + // function onOptionSelected(event:OptionSelected) { + // for (o in options) { + // o.remove(); + // } + // options.splice(0, options.length); + // } + + function onDialogueComplete(event:DialogueComplete) { + curDialogue.remove(); + } + +}