Compare commits
22 Commits
cd8be645a3
...
even-moar-
Author | SHA1 | Date | |
---|---|---|---|
2ad54aa613 | |||
ed8bc13402 | |||
d6b042f2a4 | |||
c768073503 | |||
32885707de | |||
bb7690e606 | |||
4b00d713a9 | |||
8be7c18d4f | |||
fd6b9ee8dd | |||
808958f7cc | |||
b16b27e03d | |||
e0d3ca8021 | |||
c1b102860e | |||
bb9db51560 | |||
867b33aef5 | |||
05fc9156b0 | |||
8921f231bd | |||
010aa5323d | |||
dd9fc47787 | |||
021aac9914 | |||
477b57e2a7 | |||
87302a3713 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
/bin/*
|
/bin/*
|
||||||
|
/res/.tmp/
|
||||||
|
/res/rewild.tiled-*
|
||||||
|
25
README.md
25
README.md
@ -2,10 +2,31 @@
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
* `haxe`
|
||||||
|
* `haxelib`
|
||||||
|
* Haxelib dependencies; run `haxelib install compile-hl.hxml`
|
||||||
|
* `automake`
|
||||||
|
|
||||||
### Compiling
|
### Compiling
|
||||||
|
|
||||||
`haxe compile.hxml`
|
`make debug`
|
||||||
|
|
||||||
|
You can alternatively run `make watch` to automatically rebuild on changes to
|
||||||
|
`.hx` files.
|
||||||
|
|
||||||
### Running
|
### Running
|
||||||
|
|
||||||
`hl rewild.hl`
|
`make run`
|
||||||
|
|
||||||
|
### Making a release
|
||||||
|
|
||||||
|
**TODO**: Making a redistributable `hl` version
|
||||||
|
|
||||||
|
#### Web
|
||||||
|
|
||||||
|
```
|
||||||
|
make bin/rewild.js
|
||||||
|
abra app cp <domain> bin/rewild.js app:/usr/share/nginx/html/bin/
|
||||||
|
```
|
||||||
|
27
TODO.md
Normal file
27
TODO.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# TODO
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Saving and loading games
|
||||||
|
- Character select
|
||||||
|
- Stats
|
||||||
|
- Better open / closed state graphics for rooms
|
||||||
|
- Displaying sprites (characters, objects)
|
||||||
|
- Inventory
|
||||||
|
- Room labels
|
||||||
|
- Background music
|
||||||
|
- Sound effects
|
||||||
|
|
||||||
|
## Bugs
|
||||||
|
|
||||||
|
- Fix console rendering issues
|
||||||
|
|
||||||
|
### Dialogue
|
||||||
|
|
||||||
|
- Text formatting
|
||||||
|
- Character profiles / speaker ID
|
||||||
|
|
||||||
|
## Code architecture
|
||||||
|
|
||||||
|
- Move dialogue- and option-drawing out of `Game.hx`
|
||||||
|
- Use domkit for dialogue
|
@ -1,6 +1,7 @@
|
|||||||
-cp src
|
-cp src
|
||||||
--macro Init.setup()
|
--macro Init.setup()
|
||||||
-lib heaps
|
-lib heaps:git:https://github.com/HeapsIO/heaps.git
|
||||||
|
-lib tiledhx
|
||||||
-lib hxyarn
|
-lib hxyarn
|
||||||
-main Main
|
-main Game
|
||||||
-lib domkit
|
-lib domkit
|
||||||
|
10
makefile
10
makefile
@ -1,4 +1,4 @@
|
|||||||
.PHONY: watch
|
.PHONY: watch run
|
||||||
|
|
||||||
default: bin/rewild.hl
|
default: bin/rewild.hl
|
||||||
|
|
||||||
@ -10,8 +10,14 @@ bin/rewild.hl: $(SOURCES)
|
|||||||
bin/rewild.js: $(SOURCES)
|
bin/rewild.js: $(SOURCES)
|
||||||
haxe compile-js.hxml
|
haxe compile-js.hxml
|
||||||
|
|
||||||
|
debug: $(SOURCES)
|
||||||
|
haxe --debug compile-hl.hxml
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f bin/rewild.hl bin/rewild.js
|
rm -f bin/rewild.hl bin/rewild.js
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
@inotifywait --recursive --monitor --event modify,move,create,delete --include '.*.hx$$' ./ | while read changed; do echo $$changed; make; done
|
@inotifywait --recursive --monitor --event modify,move,create,delete --include '.*.hx$$' ./ | while read changed; do echo $$changed; make debug; done
|
||||||
|
|
||||||
|
run:
|
||||||
|
hl bin/rewild.hl
|
||||||
|
@ -21,6 +21,6 @@
|
|||||||
<object id="7" name="medical" x="96" y="96" width="224" height="128"/>
|
<object id="7" name="medical" x="96" y="96" width="224" height="128"/>
|
||||||
<object id="8" name="generator" x="96" y="416" width="192" height="128"/>
|
<object id="8" name="generator" x="96" y="416" width="192" height="128"/>
|
||||||
<object id="9" name="quarters" x="320" y="416" width="288" height="128"/>
|
<object id="9" name="quarters" x="320" y="416" width="288" height="128"/>
|
||||||
<object id="10" name="hangar" x="640" y="128" width="224" height="416"/>
|
<object id="10" name="hangar" x="640" y="96" width="224" height="448"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
@ -44,3 +52,22 @@ menubutton:hover text {
|
|||||||
menubutton:active {
|
menubutton:active {
|
||||||
background: #666;
|
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"); */
|
||||||
|
/* } */
|
||||||
|
@ -8,4 +8,5 @@ You: What happened to the updates from mission control?
|
|||||||
-> Is this even still the same ship?
|
-> Is this even still the same ship?
|
||||||
You: Best not get too philsophical just yet
|
You: Best not get too philsophical just yet
|
||||||
You: Let's have another look around...
|
You: Let's have another look around...
|
||||||
|
<<room quarters>>
|
||||||
===
|
===
|
||||||
|
37
res/text/rooms.yarn
Normal file
37
res/text/rooms.yarn
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
title: Room:quarters
|
||||||
|
---
|
||||||
|
<<declare $roll = 0>>
|
||||||
|
<<declare $hangarKeyFound = false>>
|
||||||
|
<<declare $sleepingMatSetUp = false>>
|
||||||
|
You: It's the crew quarters.
|
||||||
|
You: Well, it will be. Set-up hasn't started yet.
|
||||||
|
You: That was meant to be one of my first jobs after defrost...
|
||||||
|
You: ...but it doesn't exactly seem like a priority now.
|
||||||
|
You: Maybe there's something useful here?
|
||||||
|
-> Search the lockers (perception) <<if not $hangarKeyFound>>
|
||||||
|
<<set $roll to dice(6)>>
|
||||||
|
<<if $roll > 2>>
|
||||||
|
You: Aha! A small piece of paper with the **hangar access code**.
|
||||||
|
<<room hangar>>
|
||||||
|
<<set $hangarKeyFound to true>>
|
||||||
|
<<else>>
|
||||||
|
You: Just some dust bunnies. Guess they stowed away from Earth.
|
||||||
|
<<endif>>
|
||||||
|
-> Set up a sleeping mat (ingenuity) <<if not $sleepingMatSetUp>>
|
||||||
|
<<set $roll to dice(6)>>
|
||||||
|
<<if $roll > 2>>
|
||||||
|
You: Nice, at least I have somewhere to crash now.
|
||||||
|
<<set $sleepingMatSetUp to true>>
|
||||||
|
<<else>>
|
||||||
|
You: Hmm, I was never good at this camping stuff. Maybe I can find somewhere else to rest.
|
||||||
|
<<endif>>
|
||||||
|
-> Leave
|
||||||
|
===
|
||||||
|
title: Room:hangar
|
||||||
|
---
|
||||||
|
You: The **hangar** seems eerily deserted.
|
||||||
|
===
|
||||||
|
title: Room not open
|
||||||
|
---
|
||||||
|
You: Hmm, that part of the ship is still inaccessible. I wonder how to get in?
|
||||||
|
===
|
@ -1,105 +0,0 @@
|
|||||||
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.inst;
|
|
||||||
game.scene.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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,126 +0,0 @@
|
|||||||
import hxyarn.dialogue.Dialogue;
|
|
||||||
import hxyarn.dialogue.VariableStorage.MemoryVariableStore;
|
|
||||||
import hxyarn.dialogue.StringInfo;
|
|
||||||
import hxyarn.dialogue.Line;
|
|
||||||
import hxyarn.dialogue.Command;
|
|
||||||
import hxyarn.dialogue.Option;
|
|
||||||
import hxyarn.dialogue.OptionSet;
|
|
||||||
import hxyarn.compiler.Compiler;
|
|
||||||
import hxyarn.compiler.CompilationJob;
|
|
||||||
|
|
||||||
typedef Option = {
|
|
||||||
text:String,
|
|
||||||
callback:() -> Void
|
|
||||||
};
|
|
||||||
|
|
||||||
class DialogueManager {
|
|
||||||
var storage = new MemoryVariableStore();
|
|
||||||
var dialogue:Dialogue;
|
|
||||||
var stringTable:Map<String, StringInfo>;
|
|
||||||
var dialogueCallback:(DialogueManager, String) -> Void;
|
|
||||||
var optionCallback:(DialogueManager, Array<Option>) -> Void;
|
|
||||||
|
|
||||||
public function new(_dialogueCallback:(DialogueManager, String) -> Void, _optionCallback:(DialogueManager, Array<Option>) -> Void) {
|
|
||||||
dialogue = new Dialogue(new MemoryVariableStore());
|
|
||||||
|
|
||||||
dialogue.logDebugMessage = this.logDebugMessage;
|
|
||||||
dialogue.logErrorMessage = this.logErrorMessage;
|
|
||||||
dialogue.lineHandler = this.lineHandler;
|
|
||||||
dialogue.optionsHandler = this.optionsHandler;
|
|
||||||
dialogue.commandHandler = this.commandHandler;
|
|
||||||
dialogue.nodeCompleteHandler = this.nodeCompleteHandler;
|
|
||||||
dialogue.nodeStartHandler = this.nodeStartHandler;
|
|
||||||
dialogue.dialogueCompleteHandler = this.dialogueCompleteHandler;
|
|
||||||
|
|
||||||
dialogueCallback = _dialogueCallback;
|
|
||||||
optionCallback = _optionCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function load(text:Array<String>, fileNames:Array<String>) {
|
|
||||||
var job = CompilationJob.createFromStrings(text, fileNames, dialogue.library);
|
|
||||||
var compiler = Compiler.compile(job);
|
|
||||||
stringTable = compiler.stringTable;
|
|
||||||
|
|
||||||
dialogue.addProgram(compiler.program);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function runNode(nodeName:String) {
|
|
||||||
dialogue.setNode(nodeName);
|
|
||||||
dialogue.resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function unload() {
|
|
||||||
dialogue.unloadAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resume() {
|
|
||||||
dialogue.resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function logDebugMessage(message:String):Void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function logErrorMessage(message:String):Void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lineHandler(line:Line):HandlerExecutionType {
|
|
||||||
var text = getComposedTextForLine(line);
|
|
||||||
|
|
||||||
dialogueCallback(this, text);
|
|
||||||
|
|
||||||
return HandlerExecutionType.ContinueExecution;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function optionsHandler(options:OptionSet) {
|
|
||||||
var optionCount = options.options.length;
|
|
||||||
var optionChoices = new Array<Option>();
|
|
||||||
|
|
||||||
for (i => option in options.options) {
|
|
||||||
var text = getComposedTextForLine(option.line);
|
|
||||||
optionChoices.push({
|
|
||||||
text: text,
|
|
||||||
callback: function() {
|
|
||||||
dialogue.setSelectedOption(i);
|
|
||||||
dialogue.resume();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
optionCallback(this, optionChoices);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getComposedTextForLine(line:Line):String {
|
|
||||||
var substitutedText = Dialogue.expandSubstitutions(stringTable[line.id].text, line.substitutions);
|
|
||||||
|
|
||||||
var markup = dialogue.parseMarkup(substitutedText);
|
|
||||||
|
|
||||||
return markup.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function commandHandler(command:Command) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function nodeCompleteHandler(nodeName:String) {}
|
|
||||||
|
|
||||||
public function nodeStartHandler(nodeName:String) {}
|
|
||||||
|
|
||||||
public function dialogueCompleteHandler() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNodeNames(?includesTag = "") {
|
|
||||||
var nodeNames = [];
|
|
||||||
for (nodeName in dialogue.allNodes) {
|
|
||||||
if (includesTag == "") {
|
|
||||||
nodeNames.push(nodeName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tags = dialogue.getTagsForNode(nodeName);
|
|
||||||
if (tags.contains(includesTag)) {
|
|
||||||
nodeNames.push(nodeName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nodeNames;
|
|
||||||
}
|
|
||||||
}
|
|
170
src/Game.hx
170
src/Game.hx
@ -1,85 +1,131 @@
|
|||||||
|
import h2d.Layers;
|
||||||
|
import h2d.Console;
|
||||||
|
import h3d.Vector4;
|
||||||
|
import scene.TitleScene;
|
||||||
|
import scene.WorldMapScene;
|
||||||
|
import scene.GameScene;
|
||||||
|
import event.EventBus;
|
||||||
|
import event.ChangeSceneEvent;
|
||||||
import Const;
|
import Const;
|
||||||
import DialogueBox;
|
import listeners.DialogueBoxController;
|
||||||
import DialogueManager;
|
import dialogue.DialogueManager;
|
||||||
import DialogueManager.Option;
|
import dialogue.command.OpenRoomCommand;
|
||||||
|
|
||||||
|
@: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 static var loader = new tiled.Tiled();
|
||||||
|
public static var current:Game; // Current Game (singleton)
|
||||||
|
|
||||||
public var font:h2d.Font;
|
public var font:h2d.Font;
|
||||||
public var world:World;
|
public var options:Array<h2d.ScaleGrid> = [];
|
||||||
public var curDialogue:h2d.Object;
|
|
||||||
public var actions:Array<h2d.ScaleGrid> = [];
|
|
||||||
public var dialogueManager:DialogueManager;
|
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;
|
||||||
|
|
||||||
override function init() {
|
override function init() {
|
||||||
scene = s2d;
|
s2d.scaleMode = Stretch(Const.W, Const.H);
|
||||||
s2d.scaleMode = Stretch(Const.W, Const.H + 12);
|
layer = new Layers(s2d);
|
||||||
world = new World(Res.map, Res.tiles);
|
|
||||||
s2d.add(world.root, 0);
|
#if hl
|
||||||
|
hxd.res.Resource.LIVE_UPDATE = true;
|
||||||
|
hxd.Res.initLocal();
|
||||||
|
#else
|
||||||
|
hxd.Res.initEmbed();
|
||||||
|
#end
|
||||||
|
|
||||||
|
root = new GameContainer();
|
||||||
|
root.horizontalAlign = root.verticalAlign = Middle;
|
||||||
|
layer.addChildAt(root, 1);
|
||||||
|
onResize();
|
||||||
|
|
||||||
|
style = new h2d.domkit.Style();
|
||||||
|
style.load(hxd.Res.style);
|
||||||
|
style.allowInspect = true;
|
||||||
|
style.addObject(root);
|
||||||
|
|
||||||
font = Res.font.minecraftia_regular_6.toFont();
|
font = Res.font.minecraftia_regular_6.toFont();
|
||||||
font.resizeTo(24);
|
font.resizeTo(18);
|
||||||
|
|
||||||
dialogueManager = new DialogueManager(dialogue, renderActions);
|
#if debug
|
||||||
|
console = new Console(font);
|
||||||
|
layer.addChildAt(console, 4);
|
||||||
|
#end
|
||||||
|
|
||||||
var yarnText = [
|
globalEventBus = new EventBus(console);
|
||||||
hxd.Res.text.intro.entry.getText(),
|
globalEventBus.subscribe(ChangeSceneEvent, onChangeScene);
|
||||||
];
|
|
||||||
var yarnFileNames = [
|
dialogueManager = new DialogueManager(globalEventBus);
|
||||||
hxd.Res.text.intro.entry.name,
|
|
||||||
];
|
var yarnText = [hxd.Res.text.intro.entry.getText(), hxd.Res.text.rooms.entry.getText(),];
|
||||||
|
var yarnFileNames = [hxd.Res.text.intro.entry.name, hxd.Res.text.rooms.entry.name,];
|
||||||
dialogueManager.load(yarnText, yarnFileNames);
|
dialogueManager.load(yarnText, yarnFileNames);
|
||||||
dialogueManager.runNode("Intro");
|
|
||||||
|
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
|
||||||
|
setGameScene(new TitleScene(root));
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function newPanel(w, h) {
|
override function update(dt:Float) {
|
||||||
var g = new h2d.ScaleGrid(Res.ui.toTile(), 5, 5);
|
style.sync();
|
||||||
g.width = w;
|
|
||||||
g.height = h;
|
|
||||||
g.colorKey = 0xFF00FF;
|
|
||||||
scene.add(g, 1);
|
|
||||||
return g;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addAction(a: String, callback: () -> Void) {
|
public function onChangeScene(event:ChangeSceneEvent) {
|
||||||
var spr = newPanel(Const.W, 60);
|
setGameScene(event.newScene);
|
||||||
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 setGameScene(gs:GameScene) {
|
||||||
|
#if debug
|
||||||
|
console.resetCommands();
|
||||||
|
#end
|
||||||
|
|
||||||
|
if (root.scene != null) {
|
||||||
|
root.scene.getH2dObject().remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
root.scene = gs;
|
||||||
|
style.addObject(gs.getH2dObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
static function main() {
|
||||||
|
new Game();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
51
src/Main.hx
51
src/Main.hx
@ -1,51 +0,0 @@
|
|||||||
import screens.TitleScreen;
|
|
||||||
|
|
||||||
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() {
|
|
||||||
#if hl
|
|
||||||
hxd.res.Resource.LIVE_UPDATE = true;
|
|
||||||
hxd.Res.initLocal();
|
|
||||||
#else
|
|
||||||
hxd.Res.initEmbed();
|
|
||||||
#end
|
|
||||||
new Main();
|
|
||||||
}
|
|
||||||
}
|
|
229
src/TilemapLayer.hx
Normal file
229
src/TilemapLayer.hx
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
import h2d.col.Point;
|
||||||
|
import h2d.Object;
|
||||||
|
import h2d.SpriteBatch;
|
||||||
|
import tiled.types.TmxLayer;
|
||||||
|
import tiled.types.TmxMap;
|
||||||
|
|
||||||
|
using tiled.TiledTools;
|
||||||
|
|
||||||
|
class TilemapLayer extends h2d.TileGroup {
|
||||||
|
public var map:TmxMap;
|
||||||
|
public var layer:TmxLayer;
|
||||||
|
|
||||||
|
public function new(map:TmxMap, layer:TmxLayer, ?parent:Object) {
|
||||||
|
this.map = map;
|
||||||
|
this.layer = layer;
|
||||||
|
super(parent);
|
||||||
|
for (c in layer.tileChunks) {
|
||||||
|
addChunk(c);
|
||||||
|
}
|
||||||
|
// TODO: Animations
|
||||||
|
}
|
||||||
|
|
||||||
|
// public function gidAt(x:Int, y:Int):Int {
|
||||||
|
// if (x < 0 || x >= layer.width || y < 0 || y >= layer.height) return 0;
|
||||||
|
// return layer.data.tiles[y * layer.width + x].gid;
|
||||||
|
// }
|
||||||
|
public function addChunk(chunk:TileChunk) {
|
||||||
|
var tw = map.tileWidth;
|
||||||
|
var th = map.tileHeight;
|
||||||
|
var ix = 0, iy = 0;
|
||||||
|
var tiles = chunk.tiles, i = 0;
|
||||||
|
var tsets = map.tilesets;
|
||||||
|
switch (map.orientation) {
|
||||||
|
case Orthogonal:
|
||||||
|
var cx = chunk.x * tw + layer.offsetX;
|
||||||
|
var cy = chunk.y * th + layer.offsetY;
|
||||||
|
while (i < tiles.length) {
|
||||||
|
var gid = tiles[i++];
|
||||||
|
if (gid != 0) {
|
||||||
|
var t = tsets.getImage(gid);
|
||||||
|
var x = cx + ix * tw;
|
||||||
|
var y = cy + iy * th + th - t.height;
|
||||||
|
if (gid.flippedHorizontally)
|
||||||
|
addTransform(x + t.width, y, -1, 1, 0, t);
|
||||||
|
else if (gid.flippedVertically)
|
||||||
|
addTransform(x, y + t.height, 1, -1, 0, t);
|
||||||
|
else if (gid.flippedDiagonally)
|
||||||
|
addTransform(x + t.width, y + t.height, -1, -1, 0, t);
|
||||||
|
else
|
||||||
|
add(x, y, t);
|
||||||
|
}
|
||||||
|
if (++ix == chunk.width) {
|
||||||
|
iy++;
|
||||||
|
ix = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Isometric:
|
||||||
|
var isoW = tw >> 1;
|
||||||
|
var isoH = th >> 1;
|
||||||
|
|
||||||
|
var cx = (chunk.x - chunk.y) * isoW + layer.offsetX;
|
||||||
|
var cy = (chunk.x + chunk.y) * isoH + layer.offsetY;
|
||||||
|
while (i < tiles.length) {
|
||||||
|
var gid = tiles[i++];
|
||||||
|
if (gid != 0) {
|
||||||
|
var t = tsets.getImage(gid);
|
||||||
|
var x = cx + (ix - iy) * isoW;
|
||||||
|
var y = cy + (ix + iy) * isoH + th - t.height;
|
||||||
|
if (gid.flippedHorizontally)
|
||||||
|
addTransform(x + t.width, y, -1, 1, 0, t);
|
||||||
|
else if (gid.flippedVertically)
|
||||||
|
addTransform(x, y + t.height, 1, -1, 0, t);
|
||||||
|
else if (gid.flippedDiagonally)
|
||||||
|
addTransform(x + t.width, y + t.height, -1, -1, 0, t);
|
||||||
|
else
|
||||||
|
add(x, y, t);
|
||||||
|
}
|
||||||
|
if (++ix == chunk.width) {
|
||||||
|
iy++;
|
||||||
|
ix = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Staggered(staggerYAxis, staggerIndexOdd):
|
||||||
|
var staggerX = 0,
|
||||||
|
staggerY = 0,
|
||||||
|
stepX = tw >> 1,
|
||||||
|
stepY = th >> 1;
|
||||||
|
var cx = chunk.x * stepX + layer.offsetX;
|
||||||
|
var cy = chunk.y * stepY + layer.offsetY;
|
||||||
|
if (staggerYAxis) {
|
||||||
|
if (staggerIndexOdd) {
|
||||||
|
staggerX = tw >> 1;
|
||||||
|
} else {
|
||||||
|
staggerX = -(tw >> 1);
|
||||||
|
cx -= staggerX;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (staggerIndexOdd) {
|
||||||
|
staggerY = th >> 1;
|
||||||
|
} else {
|
||||||
|
staggerY = -(tw >> 1);
|
||||||
|
cy -= staggerY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cx += (chunk.x % 2) * staggerX;
|
||||||
|
cy += (chunk.y % 2) * staggerY;
|
||||||
|
while (i < tiles.length) {
|
||||||
|
var gid = tiles[i++];
|
||||||
|
if (gid != 0) {
|
||||||
|
var t = tsets.getImage(gid);
|
||||||
|
var x = cx + ix * stepX + staggerX * (ix % 1);
|
||||||
|
var y = cy + iy * stepY + th - t.height;
|
||||||
|
if (gid.flippedHorizontally)
|
||||||
|
addTransform(x + t.width, y, -1, 1, 0, t);
|
||||||
|
else if (gid.flippedVertically)
|
||||||
|
addTransform(x, y + t.height, 1, -1, 0, t);
|
||||||
|
else if (gid.flippedDiagonally)
|
||||||
|
addTransform(x + t.width, y + t.height, -1, -1, 0, t);
|
||||||
|
else
|
||||||
|
add(x, y, t);
|
||||||
|
}
|
||||||
|
if (++ix == chunk.width) {
|
||||||
|
iy++;
|
||||||
|
ix = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Hexagonal(sideLength, staggerYAxis, staggerIndexOdd):
|
||||||
|
// TODO: Fix
|
||||||
|
var staggerX = 0, staggerY = 0, stepX, stepY;
|
||||||
|
var cx, cy;
|
||||||
|
if (staggerYAxis) {
|
||||||
|
stepX = tw;
|
||||||
|
stepY = (th + sideLength) >> 1;
|
||||||
|
cx = chunk.x * stepX + layer.offsetX;
|
||||||
|
cy = chunk.y * stepY + layer.offsetY;
|
||||||
|
if (staggerIndexOdd) {
|
||||||
|
staggerX = tw >> 1;
|
||||||
|
} else {
|
||||||
|
staggerX = -(tw >> 1);
|
||||||
|
cx -= staggerX;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stepX = (tw + sideLength) >> 1;
|
||||||
|
stepY = th;
|
||||||
|
cx = chunk.x * stepX + layer.offsetX;
|
||||||
|
cy = chunk.y * stepY + layer.offsetY;
|
||||||
|
if (staggerIndexOdd) {
|
||||||
|
staggerY = th >> 1;
|
||||||
|
} else {
|
||||||
|
staggerY = -(tw >> 1);
|
||||||
|
cy -= staggerY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (i < tiles.length) {
|
||||||
|
var gid = tiles[i++];
|
||||||
|
if (gid != 0) {
|
||||||
|
var t = tsets.getImage(gid);
|
||||||
|
var x = cx + ix * stepX;
|
||||||
|
var y = cy + iy * stepY + th - t.height;
|
||||||
|
if (gid.flippedHorizontally)
|
||||||
|
addTransform(x + t.width, y, -1, 1, 0, t);
|
||||||
|
else if (gid.flippedVertically)
|
||||||
|
addTransform(x, y + t.height, 1, -1, 0, t);
|
||||||
|
else if (gid.flippedDiagonally)
|
||||||
|
addTransform(x + t.width, y + t.height, -1, -1, 0, t);
|
||||||
|
else
|
||||||
|
add(x, y, t);
|
||||||
|
}
|
||||||
|
if (++ix == chunk.width) {
|
||||||
|
iy++;
|
||||||
|
ix = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addTile(tx:Int, ty:Int, ox:Float, oy:Float, gid:TmxTileIndex) {
|
||||||
|
if (gid == 0)
|
||||||
|
return;
|
||||||
|
var t = map.tilesets.getImage(gid);
|
||||||
|
if (t != null) {
|
||||||
|
var x, y;
|
||||||
|
switch (map.orientation) {
|
||||||
|
case Orthogonal:
|
||||||
|
x = tx * map.tileWidth + ox;
|
||||||
|
y = ty * map.tileHeight + oy;
|
||||||
|
case Isometric:
|
||||||
|
x = (tx - ty) * (map.tileWidth >> 1) + ox;
|
||||||
|
y = (tx + ty) * (map.tileHeight >> 1) + oy;
|
||||||
|
case Staggered(staggerYAxis, staggerIndexOdd):
|
||||||
|
if (staggerYAxis) {
|
||||||
|
y = ty * (map.tileHeight >> 1);
|
||||||
|
if (staggerIndexOdd)
|
||||||
|
x = tx * map.tileWidth + (tx % 2) * (map.tileWidth >> 1);
|
||||||
|
else
|
||||||
|
x = tx * map.tileWidth + ((tx + 1) % 2) * (map.tileWidth >> 1);
|
||||||
|
} else {
|
||||||
|
x = tx * (map.tileWidth >> 1);
|
||||||
|
if (staggerIndexOdd)
|
||||||
|
y = ty * map.tileHeight + (tx % 2) * (map.tileHeight >> 1);
|
||||||
|
else
|
||||||
|
y = ty * map.tileHeight + ((tx + 1) % 2) * (map.tileHeight >> 1);
|
||||||
|
}
|
||||||
|
case Hexagonal(sideLength, staggerYAxis, staggerIndexOdd):
|
||||||
|
if (staggerYAxis) {
|
||||||
|
y = ty * ((map.tileHeight + sideLength) >> 1);
|
||||||
|
if (staggerIndexOdd)
|
||||||
|
x = tx * map.tileWidth + (tx % 2) * (map.tileWidth >> 1);
|
||||||
|
else
|
||||||
|
x = tx * map.tileWidth + ((tx + 1) % 2) * (map.tileWidth >> 1);
|
||||||
|
} else {
|
||||||
|
x = tx * ((map.tileWidth + sideLength) >> 1);
|
||||||
|
if (staggerIndexOdd)
|
||||||
|
y = ty * map.tileHeight + (tx % 2) * (map.tileHeight >> 1);
|
||||||
|
else
|
||||||
|
y = ty * map.tileHeight + ((tx + 1) % 2) * (map.tileHeight >> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gid.flippedHorizontally)
|
||||||
|
addTransform(x + t.width, y, -1, 1, 0, t);
|
||||||
|
else if (gid.flippedVertically)
|
||||||
|
addTransform(x, y + t.height, 1, -1, 0, t);
|
||||||
|
else if (gid.flippedDiagonally)
|
||||||
|
addTransform(x + t.width, y + t.height, -1, -1, 0, t);
|
||||||
|
else
|
||||||
|
add(x, y, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
src/World.hx
65
src/World.hx
@ -1,65 +0,0 @@
|
|||||||
class World {
|
|
||||||
var game:Game;
|
|
||||||
var map:hxd.res.TiledMap.TiledMapData;
|
|
||||||
|
|
||||||
public var root:h2d.Object;
|
|
||||||
|
|
||||||
var layers:Map<String, {
|
|
||||||
name:String,
|
|
||||||
data:Array<Int>,
|
|
||||||
g:h2d.TileGroup,
|
|
||||||
alpha:Float
|
|
||||||
}>;
|
|
||||||
var tiles:Array<h2d.Tile>;
|
|
||||||
|
|
||||||
public var width:Int;
|
|
||||||
public var height:Int;
|
|
||||||
|
|
||||||
public function new(r:hxd.res.TiledMap, tiles:hxd.res.Image) {
|
|
||||||
game = Game.inst;
|
|
||||||
root = new h2d.Object();
|
|
||||||
map = r.toMap();
|
|
||||||
root = new h2d.Object();
|
|
||||||
width = map.width;
|
|
||||||
height = map.height;
|
|
||||||
var t = tiles.toTile();
|
|
||||||
layers = new Map();
|
|
||||||
var font:h2d.Font = hxd.res.DefaultFont.get();
|
|
||||||
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 (ld in map.layers) {
|
|
||||||
if (ld.name == "hotspots")
|
|
||||||
continue;
|
|
||||||
var l = {
|
|
||||||
name: ld.name,
|
|
||||||
data: ld.data,
|
|
||||||
g: new h2d.TileGroup(t, root),
|
|
||||||
alpha: ld.opacity,
|
|
||||||
}
|
|
||||||
// l.g.colorKey = 0x1D8700;
|
|
||||||
l.g.alpha = ld.opacity;
|
|
||||||
layers.set(ld.name, l);
|
|
||||||
rebuildLayer(ld.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function rebuildLayer(name:String) {
|
|
||||||
var l = layers.get(name);
|
|
||||||
if (l == null)
|
|
||||||
return;
|
|
||||||
var pos = 0;
|
|
||||||
var g = l.g;
|
|
||||||
g.clear();
|
|
||||||
while (g.numChildren > 0)
|
|
||||||
g.getChildAt(0).remove();
|
|
||||||
|
|
||||||
for (y in 0...height)
|
|
||||||
for (x in 0...width) {
|
|
||||||
var t = l.data[pos++] - 1;
|
|
||||||
if (t < 0)
|
|
||||||
continue;
|
|
||||||
g.add(x * 32, y * 32, tiles[t]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
135
src/components/DialogueBoxComponent.hx
Normal file
135
src/components/DialogueBoxComponent.hx
Normal file
@ -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 = <dialogue-option>
|
||||||
|
<text text={label} public font={Game.current.font} id="labelTxt" />
|
||||||
|
</dialogue-option>;
|
||||||
|
|
||||||
|
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 = <dialogue-options>
|
||||||
|
${options}
|
||||||
|
</dialogue-options>;
|
||||||
|
|
||||||
|
public var options:Array<DialogueOptionComponent>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@: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 = <dialogue-box>
|
||||||
|
<scale-grid id="dialogueBackground">
|
||||||
|
<text text={displayedText} public font={Game.current.font} id="dialogueText" />
|
||||||
|
</scale-grid>
|
||||||
|
</dialogue-box>
|
||||||
|
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
164
src/dialogue/DialogueManager.hx
Normal file
164
src/dialogue/DialogueManager.hx
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
package dialogue;
|
||||||
|
|
||||||
|
import hxyarn.dialogue.Dialogue;
|
||||||
|
import hxyarn.dialogue.VariableStorage.MemoryVariableStore;
|
||||||
|
import hxyarn.dialogue.StringInfo;
|
||||||
|
import hxyarn.dialogue.Line;
|
||||||
|
import hxyarn.dialogue.Command;
|
||||||
|
import hxyarn.dialogue.Option;
|
||||||
|
import hxyarn.dialogue.OptionSet;
|
||||||
|
import hxyarn.dialogue.markup.MarkupParseResult;
|
||||||
|
import hxyarn.compiler.Compiler;
|
||||||
|
import hxyarn.compiler.CompilationJob;
|
||||||
|
import event.EventBus;
|
||||||
|
import dialogue.command.ICommandHandler;
|
||||||
|
import dialogue.event.LineShown;
|
||||||
|
import dialogue.event.OptionsShown;
|
||||||
|
import dialogue.event.OptionsShown.OptionChoice;
|
||||||
|
import dialogue.event.OptionSelected;
|
||||||
|
import dialogue.event.NextLine;
|
||||||
|
import dialogue.event.StartDialogueNode;
|
||||||
|
import dialogue.event.DialogueComplete;
|
||||||
|
|
||||||
|
class DialogueManager {
|
||||||
|
public var eventBus:EventBus;
|
||||||
|
|
||||||
|
var storage = new MemoryVariableStore();
|
||||||
|
var dialogue:Dialogue;
|
||||||
|
var stringTable:Map<String, StringInfo>;
|
||||||
|
var commandHandlers = new Map<String, ICommandHandler>();
|
||||||
|
|
||||||
|
public var waitingForOption:Bool = false;
|
||||||
|
|
||||||
|
public function new(eventBus:EventBus) {
|
||||||
|
this.eventBus = eventBus;
|
||||||
|
dialogue = new Dialogue(new MemoryVariableStore());
|
||||||
|
|
||||||
|
dialogue.logDebugMessage = this.logDebugMessage;
|
||||||
|
dialogue.logErrorMessage = this.logErrorMessage;
|
||||||
|
dialogue.lineHandler = this.lineHandler;
|
||||||
|
dialogue.optionsHandler = this.optionsHandler;
|
||||||
|
dialogue.commandHandler = this.commandHandler;
|
||||||
|
dialogue.nodeCompleteHandler = this.nodeCompleteHandler;
|
||||||
|
dialogue.nodeStartHandler = this.nodeStartHandler;
|
||||||
|
dialogue.dialogueCompleteHandler = this.dialogueCompleteHandler;
|
||||||
|
|
||||||
|
eventBus.subscribe(NextLine, this.nextLine);
|
||||||
|
eventBus.subscribe(OptionSelected, this.optionSelected);
|
||||||
|
eventBus.subscribe(StartDialogueNode, function(event) {
|
||||||
|
this.runNode(event.node);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function load(text:Array<String>, fileNames:Array<String>) {
|
||||||
|
var job = CompilationJob.createFromStrings(text, fileNames, dialogue.library);
|
||||||
|
var compiler = Compiler.compile(job);
|
||||||
|
stringTable = compiler.stringTable;
|
||||||
|
|
||||||
|
dialogue.addProgram(compiler.program);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runNode(nodeName:String) {
|
||||||
|
dialogue.setNode(nodeName);
|
||||||
|
dialogue.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unload() {
|
||||||
|
dialogue.unloadAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resume() {
|
||||||
|
dialogue.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logDebugMessage(message:String):Void {}
|
||||||
|
|
||||||
|
public function logErrorMessage(message:String):Void {}
|
||||||
|
|
||||||
|
public function nextLine(event:NextLine) {
|
||||||
|
if ((dialogue.isActive()) && (!waitingForOption))
|
||||||
|
dialogue.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function lineHandler(line:Line):Void {
|
||||||
|
var text = getComposedTextForLine(line);
|
||||||
|
eventBus.publishEvent(new LineShown(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function optionSelected(event:OptionSelected) {
|
||||||
|
dialogue.setSelectedOption(event.index);
|
||||||
|
dialogue.resume();
|
||||||
|
waitingForOption = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function optionsHandler(options:OptionSet) {
|
||||||
|
var optionCount = options.options.length;
|
||||||
|
var optionChoices = new Array<OptionChoice>();
|
||||||
|
|
||||||
|
for (i => option in options.options) {
|
||||||
|
var markup = getComposedTextForLine(option.line);
|
||||||
|
optionChoices.push({
|
||||||
|
text: markup.text,
|
||||||
|
index: i,
|
||||||
|
enabled: option.enabled,
|
||||||
|
markup: markup
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
eventBus.publishEvent(new OptionsShown(optionChoices));
|
||||||
|
|
||||||
|
waitingForOption = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getComposedTextForLine(line:Line):MarkupParseResult {
|
||||||
|
var substitutedText = Dialogue.expandSubstitutions(stringTable[line.id].text, line.substitutions);
|
||||||
|
|
||||||
|
return dialogue.parseMarkup(substitutedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function commandHandler(command:Command) {
|
||||||
|
var parts = command.text.split(' ');
|
||||||
|
var key = parts.shift();
|
||||||
|
if (commandHandlers.exists(key)) {
|
||||||
|
if (commandHandlers.get(key).handleCommand(parts)) {
|
||||||
|
resume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addCommandHandler(handler:ICommandHandler) {
|
||||||
|
if (handler.commandName == null || handler.commandName == "") {
|
||||||
|
trace("Command handler has no command name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
commandHandlers.set(handler.commandName, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function nodeCompleteHandler(nodeName:String) {}
|
||||||
|
|
||||||
|
public function nodeStartHandler(nodeName:String) {}
|
||||||
|
|
||||||
|
public function dialogueCompleteHandler() {
|
||||||
|
eventBus.publishEvent(new DialogueComplete(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNodeNames(?includesTag = "") {
|
||||||
|
var nodeNames = [];
|
||||||
|
for (nodeName in dialogue.allNodes) {
|
||||||
|
if (includesTag == "") {
|
||||||
|
nodeNames.push(nodeName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tags = dialogue.getTagsForNode(nodeName);
|
||||||
|
if (tags.contains(includesTag)) {
|
||||||
|
nodeNames.push(nodeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodeNames;
|
||||||
|
}
|
||||||
|
}
|
6
src/dialogue/command/ICommandHandler.hx
Normal file
6
src/dialogue/command/ICommandHandler.hx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package dialogue.command;
|
||||||
|
|
||||||
|
interface ICommandHandler {
|
||||||
|
var commandName:String;
|
||||||
|
function handleCommand(args:Array<String>):Bool;
|
||||||
|
}
|
19
src/dialogue/command/OpenRoomCommand.hx
Normal file
19
src/dialogue/command/OpenRoomCommand.hx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package dialogue.command;
|
||||||
|
|
||||||
|
import event.EventBus;
|
||||||
|
import event.OpenRoomEvent;
|
||||||
|
|
||||||
|
class OpenRoomCommand implements ICommandHandler {
|
||||||
|
public var commandName:String = "room";
|
||||||
|
|
||||||
|
var eventBus:EventBus;
|
||||||
|
|
||||||
|
public function new(eventBus:EventBus) {
|
||||||
|
this.eventBus = eventBus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCommand(args:Array<String>):Bool {
|
||||||
|
eventBus.publishEvent(new OpenRoomEvent(args[0]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
11
src/dialogue/event/DialogueComplete.hx
Normal file
11
src/dialogue/event/DialogueComplete.hx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package dialogue.event;
|
||||||
|
|
||||||
|
import event.IEvent;
|
||||||
|
|
||||||
|
class DialogueComplete implements IEvent {
|
||||||
|
public var nodeName:String;
|
||||||
|
|
||||||
|
public function new(nodeName:String) {
|
||||||
|
this.nodeName = nodeName;
|
||||||
|
}
|
||||||
|
}
|
36
src/dialogue/event/LineShown.hx
Normal file
36
src/dialogue/event/LineShown.hx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package dialogue.event;
|
||||||
|
|
||||||
|
import hxyarn.dialogue.markup.MarkupAttribute;
|
||||||
|
import hxyarn.dialogue.markup.MarkupParseResult;
|
||||||
|
import event.IEvent;
|
||||||
|
|
||||||
|
class LineShown implements IEvent {
|
||||||
|
public var markUpResults:MarkupParseResult;
|
||||||
|
|
||||||
|
public function new(markupParseResults:MarkupParseResult) {
|
||||||
|
this.markUpResults = markupParseResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function line():String {
|
||||||
|
var text = markUpResults.text;
|
||||||
|
var characterAttribute = characterNameAttribute();
|
||||||
|
|
||||||
|
if (characterAttribute != null)
|
||||||
|
text = text.substr(characterAttribute.position + characterAttribute.length);
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function characterName():String {
|
||||||
|
var attribute = characterNameAttribute();
|
||||||
|
|
||||||
|
if (attribute != null)
|
||||||
|
return attribute.properties[0].value.stringValue;
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function characterNameAttribute():MarkupAttribute {
|
||||||
|
return markUpResults.tryGetAttributeWithName("character");
|
||||||
|
}
|
||||||
|
}
|
7
src/dialogue/event/NextLine.hx
Normal file
7
src/dialogue/event/NextLine.hx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package dialogue.event;
|
||||||
|
|
||||||
|
import event.IEvent;
|
||||||
|
|
||||||
|
class NextLine implements IEvent {
|
||||||
|
public function new() {}
|
||||||
|
}
|
11
src/dialogue/event/OptionSelected.hx
Normal file
11
src/dialogue/event/OptionSelected.hx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package dialogue.event;
|
||||||
|
|
||||||
|
import event.IEvent;
|
||||||
|
|
||||||
|
class OptionSelected implements IEvent {
|
||||||
|
public var index:Int;
|
||||||
|
|
||||||
|
public function new(index:Int) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
19
src/dialogue/event/OptionsShown.hx
Normal file
19
src/dialogue/event/OptionsShown.hx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package dialogue.event;
|
||||||
|
|
||||||
|
import hxyarn.dialogue.markup.MarkupParseResult;
|
||||||
|
import event.IEvent;
|
||||||
|
|
||||||
|
typedef OptionChoice = {
|
||||||
|
text:String,
|
||||||
|
index:Int,
|
||||||
|
enabled:Bool,
|
||||||
|
markup:MarkupParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
class OptionsShown implements IEvent {
|
||||||
|
public var options:Array<OptionChoice>;
|
||||||
|
|
||||||
|
public function new(options:Array<OptionChoice>) {
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
}
|
11
src/dialogue/event/StartDialogueNode.hx
Normal file
11
src/dialogue/event/StartDialogueNode.hx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package dialogue.event;
|
||||||
|
|
||||||
|
import event.IEvent;
|
||||||
|
|
||||||
|
class StartDialogueNode implements IEvent {
|
||||||
|
public var node:String;
|
||||||
|
|
||||||
|
public function new(node:String) {
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
}
|
11
src/event/ChangeSceneEvent.hx
Normal file
11
src/event/ChangeSceneEvent.hx
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
48
src/event/EventBus.hx
Normal file
48
src/event/EventBus.hx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
trace('Publishing event $type');
|
||||||
|
|
||||||
|
for (func in listeners.get(type))
|
||||||
|
func(event);
|
||||||
|
}
|
||||||
|
}
|
3
src/event/IEvent.hx
Normal file
3
src/event/IEvent.hx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package event;
|
||||||
|
|
||||||
|
interface IEvent {}
|
9
src/event/OpenRoomEvent.hx
Normal file
9
src/event/OpenRoomEvent.hx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package event;
|
||||||
|
|
||||||
|
class OpenRoomEvent implements IEvent {
|
||||||
|
public var roomName:String;
|
||||||
|
|
||||||
|
public function new(rn:String) {
|
||||||
|
this.roomName = rn;
|
||||||
|
}
|
||||||
|
}
|
125
src/listeners/DialogueBoxController.hx
Normal file
125
src/listeners/DialogueBoxController.hx
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
src/scene/GameScene.hx
Normal file
5
src/scene/GameScene.hx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package scene;
|
||||||
|
|
||||||
|
interface GameScene {
|
||||||
|
function getH2dObject():h2d.Object;
|
||||||
|
}
|
52
src/scene/TitleScene.hx
Normal file
52
src/scene/TitleScene.hx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
76
src/scene/WorldMapScene.hx
Normal file
76
src/scene/WorldMapScene.hx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package scene;
|
||||||
|
|
||||||
|
import dialogue.event.StartDialogueNode;
|
||||||
|
import event.OpenRoomEvent;
|
||||||
|
import TilemapLayer;
|
||||||
|
|
||||||
|
typedef Room = {
|
||||||
|
rect:h2d.Graphics,
|
||||||
|
area:h2d.Interactive,
|
||||||
|
isOpen:Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
@:uiComp("world-map-scene")
|
||||||
|
class WorldMapScene extends h2d.Flow implements GameScene implements h2d.domkit.Object {
|
||||||
|
public var width:Int;
|
||||||
|
public var height:Int;
|
||||||
|
|
||||||
|
var rooms:Map<String, Room> = new Map<String, Room>();
|
||||||
|
|
||||||
|
public function new(?parent) {
|
||||||
|
super(parent);
|
||||||
|
initComponent();
|
||||||
|
|
||||||
|
var root = new h2d.Object(this);
|
||||||
|
|
||||||
|
var map = Game.loader.loadTMX("map.tmx");
|
||||||
|
|
||||||
|
Game.current.globalEventBus.subscribe(OpenRoomEvent, openRoom);
|
||||||
|
|
||||||
|
for (layer in (map.layers)) {
|
||||||
|
switch (layer.kind) {
|
||||||
|
case TTileLayer:
|
||||||
|
var l = new TilemapLayer(map, layer, root);
|
||||||
|
case TObjectGroup:
|
||||||
|
for (obj in layer.objects) {
|
||||||
|
var rect = new h2d.Graphics(root);
|
||||||
|
rect.beginFill(0x333333);
|
||||||
|
rect.alpha = 0.8;
|
||||||
|
rect.drawRect(obj.x, obj.y, obj.width, obj.height);
|
||||||
|
rect.endFill();
|
||||||
|
var area = new h2d.Interactive(obj.width, obj.height, root);
|
||||||
|
area.x = obj.x;
|
||||||
|
area.y = obj.y;
|
||||||
|
area.onClick = function(_) {
|
||||||
|
var room = rooms.get(obj.name);
|
||||||
|
if (room.isOpen) {
|
||||||
|
Game.current.globalEventBus.publishEvent(new StartDialogueNode("Room:" + obj.name));
|
||||||
|
} else {
|
||||||
|
Game.current.globalEventBus.publishEvent(new StartDialogueNode("Room not open"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
rooms.set(obj.name, {rect: rect, area: area, isOpen: false});
|
||||||
|
}
|
||||||
|
case TImageLayer:
|
||||||
|
case TGroup:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if debug
|
||||||
|
trace('skipping intro dialogue');
|
||||||
|
Game.current.globalEventBus.publishEvent(new OpenRoomEvent("quarters"));
|
||||||
|
#else
|
||||||
|
Game.current.globalEventBus.publishEvent(new StartDialogueNode("Intro"));
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
public function openRoom(event:OpenRoomEvent) {
|
||||||
|
var room = rooms.get(event.roomName);
|
||||||
|
room.isOpen = true;
|
||||||
|
room.rect.alpha = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getH2dObject() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user