Skip to content

Revamp tutorial #329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Tutorials/TurnBasedRPG/Project.xml
Original file line number Diff line number Diff line change
@@ -62,6 +62,7 @@
<haxedef name="FLX_NO_MOUSE" if="mobile" />
<haxedef name="FLX_NO_KEYBOARD" if="mobile" />
<haxedef name="FLX_NO_TOUCH" if="desktop" />
<haxedef name="FLX_NO_HEALTH"/>
<!--<haxedef name="FLX_NO_GAMEPAD" />-->

<!--Disable the Flixel core sound tray-->
52 changes: 27 additions & 25 deletions Tutorials/TurnBasedRPG/assets/data/room-001.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"ogmoVersion": "3.3.0",
"ogmoVersion": "3.4.0",
"width": 640,
"height": 480,
"offsetX": 0,
@@ -16,41 +16,43 @@
"gridCellsY": 30,
"entities": [
{"name": "player", "id": 0, "_eid": "40117707", "x": 128, "y": 144, "originX": 0, "originY": 0},
{"name": "coin", "id": 1, "_eid": "40304284", "x": 320, "y": 96, "originX": 0, "originY": 0},
{"name": "coin", "id": 2, "_eid": "40304284", "x": 352, "y": 80, "originX": 0, "originY": 0},
{"name": "coin", "id": 3, "_eid": "40304284", "x": 192, "y": 144, "originX": 0, "originY": 0},
{"name": "coin", "id": 4, "_eid": "40304284", "x": 224, "y": 144, "originX": 0, "originY": 0},
{"name": "coin", "id": 5, "_eid": "40304284", "x": 256, "y": 144, "originX": 0, "originY": 0},
{"name": "coin", "id": 6, "_eid": "40304284", "x": 288, "y": 144, "originX": 0, "originY": 0},
{"name": "coin", "id": 7, "_eid": "40304284", "x": 304, "y": 160, "originX": 0, "originY": 0},
{"name": "coin", "id": 8, "_eid": "40304284", "x": 304, "y": 192, "originX": 0, "originY": 0},
{"name": "coin", "id": 9, "_eid": "40304284", "x": 304, "y": 224, "originX": 0, "originY": 0},
{"name": "coin", "id": 10, "_eid": "40304284", "x": 304, "y": 256, "originX": 0, "originY": 0},
{"name": "coin", "id": 11, "_eid": "40304284", "x": 304, "y": 304, "originX": 0, "originY": 0},
{"name": "coin", "id": 12, "_eid": "40304284", "x": 320, "y": 288, "originX": 0, "originY": 0},
{"name": "coin", "id": 13, "_eid": "40304284", "x": 336, "y": 304, "originX": 0, "originY": 0},
{"name": "coin", "id": 14, "_eid": "40304284", "x": 288, "y": 288, "originX": 0, "originY": 0},
{"name": "coin", "id": 15, "_eid": "40304284", "x": 272, "y": 304, "originX": 0, "originY": 0},
{"name": "coin", "id": 16, "_eid": "40304284", "x": 256, "y": 224, "originX": 0, "originY": 0},
{"name": "coin", "id": 17, "_eid": "40304284", "x": 256, "y": 192, "originX": 0, "originY": 0},
{"name": "coin", "id": 18, "_eid": "40304284", "x": 208, "y": 192, "originX": 0, "originY": 0},
{"name": "coin", "id": 19, "_eid": "40304284", "x": 208, "y": 224, "originX": 0, "originY": 0},
{"name": "enemy", "id": 20, "_eid": "40444291", "x": 304, "y": 112, "originX": 0, "originY": 0},
{"name": "enemy", "id": 21, "_eid": "40444291", "x": 272, "y": 208, "originX": 0, "originY": 0},
{"name": "boss", "id": 22, "_eid": "40444462", "x": 304, "y": 288, "originX": 0, "originY": 0}
{"name": "coin", "id": 1, "_eid": "40304284", "x": 416, "y": 48, "originX": 0, "originY": 0},
{"name": "coin", "id": 2, "_eid": "40304284", "x": 496, "y": 48, "originX": 0, "originY": 0},
{"name": "coin", "id": 3, "_eid": "40304284", "x": 192, "y": 136, "originX": 0, "originY": 0},
{"name": "coin", "id": 4, "_eid": "40304284", "x": 240, "y": 136, "originX": 0, "originY": 0},
{"name": "coin", "id": 5, "_eid": "40304284", "x": 288, "y": 136, "originX": 0, "originY": 0},
{"name": "coin", "id": 6, "_eid": "40304284", "x": 336, "y": 136, "originX": 0, "originY": 0},
{"name": "coin", "id": 7, "_eid": "40304284", "x": 392, "y": 176, "originX": 0, "originY": 0},
{"name": "coin", "id": 8, "_eid": "40304284", "x": 392, "y": 224, "originX": 0, "originY": 0},
{"name": "coin", "id": 9, "_eid": "40304284", "x": 392, "y": 272, "originX": 0, "originY": 0},
{"name": "coin", "id": 10, "_eid": "40304284", "x": 392, "y": 320, "originX": 0, "originY": 0},
{"name": "coin", "id": 11, "_eid": "40304284", "x": 336, "y": 400, "originX": 0, "originY": 0},
{"name": "coin", "id": 12, "_eid": "40304284", "x": 368, "y": 368, "originX": 0, "originY": 0},
{"name": "coin", "id": 13, "_eid": "40304284", "x": 400, "y": 400, "originX": 0, "originY": 0},
{"name": "coin", "id": 14, "_eid": "40304284", "x": 304, "y": 368, "originX": 0, "originY": 0},
{"name": "coin", "id": 15, "_eid": "40304284", "x": 272, "y": 400, "originX": 0, "originY": 0},
{"name": "coin", "id": 16, "_eid": "40304284", "x": 304, "y": 256, "originX": 0, "originY": 0},
{"name": "coin", "id": 17, "_eid": "40304284", "x": 304, "y": 224, "originX": 0, "originY": 0},
{"name": "coin", "id": 18, "_eid": "40304284", "x": 240, "y": 224, "originX": 0, "originY": 0},
{"name": "coin", "id": 19, "_eid": "40304284", "x": 240, "y": 256, "originX": 0, "originY": 0},
{"name": "enemy", "id": 20, "_eid": "40444291", "x": 464, "y": 64, "originX": 0, "originY": 0},
{"name": "enemy", "id": 21, "_eid": "40444291", "x": 272, "y": 240, "originX": 0, "originY": 0},
{"name": "boss", "id": 22, "_eid": "40444462", "x": 336, "y": 384, "originX": 0, "originY": 0},
{"name": "coin", "id": 23, "_eid": "40304284", "x": 496, "y": 80, "originX": 0, "originY": 0},
{"name": "coin", "id": 24, "_eid": "40304284", "x": 416, "y": 80, "originX": 0, "originY": 0}
]
},
{
"name": "walls",
"_eid": "40116503",
"_eid": "02788814",
"offsetX": 0,
"offsetY": 0,
"gridCellWidth": 16,
"gridCellHeight": 16,
"gridCellsX": 40,
"gridCellsY": 30,
"tileset": "tiles",
"data": [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
"data": [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 20, 16, 16, 16, 16, 16, 21, 28, 28, 22, 28, 22, 22, 28, 22, 22, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 4, 9, 9, 9, 9, 9, 9, 9, 5, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 20, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, 16, 16, 21, 7, 3, 1, 1, 1, 2, 1, 1, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 3, 1, 1, 1, 1, 1, 1, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 28, 28, 28, 28, 22, 22, 28, 23, 16, 16, 16, 20, 16, 16, 16, 16, 16, 16, 24, 21, 7, 1, 1, 1, 2, 1, 1, 1, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 4, 5, 9, 9, 9, 9, 9, 34, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 35, 7, 1, 1, 1, 1, 3, 1, 1, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 1, 1, 1, 1, 1, 1, 32, 28, 28, 28, 22, 28, 28, 28, 28, 22, 28, 28, 33, 7, 1, 30, 26, 26, 26, 26, 26, 26, 27, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 1, 1, 1, 1, 1, 1, 9, 9, 5, 9, 9, 9, 9, 9, 9, 9, 5, 9, 9, 8, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 12, 13, 13, 13, 13, 13, 14, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 10, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 1, 1, 1, 2, 1, 1, 23, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 21, 11, 1, 23, 24, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 1, 1, 1, 2, 1, 1, 23, 21, 28, 28, 28, 28, 28, 28, 28, 22, 22, 34, 35, 7, 1, 23, 16, 16, 16, 16, 20, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 3, 1, 1, 1, 1, 1, 23, 21, 4, 9, 9, 9, 9, 9, 9, 9, 9, 32, 33, 7, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 25, 26, 26, 26, 26, 26, 26, 26, 27, 21, 7, 1, 1, 1, 2, 1, 1, 1, 1, 9, 9, 8, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, 21, 7, 2, 1, 1, 1, 1, 1, 1, 1, 30, 31, 10, 1, 23, 16, 20, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 20, 16, 16, 16, 21, 7, 1, 1, 1, 1, 1, 1, 2, 1, 23, 21, 12, 14, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 21, 12, 14, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 20, 17, 18, 18, 18, 18, 18, 18, 18, 35, 12, 14, 34, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 22, 22, 22, 22, 29, 28, 28, 33, 12, 14, 32, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 20, 21, 22, 22, 29, 28, 28, 28, 28, 33, 12, 14, 32, 23, 16, 24, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 20, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 4, 9, 5, 9, 9, 9, 9, 9, 8, 1, 9, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 1, 1, 1, 1, 3, 1, 1, 1, 2, 1, 23, 20, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 20, 16, 16, 16, 16, 16, 16, 21, 11, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 21, 7, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 23, 20, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, 16, 21, 7, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16],
"exportMode": 0,
"arrayMode": 0
}
10 changes: 5 additions & 5 deletions Tutorials/TurnBasedRPG/assets/data/turnBasedRPG.ogmo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "HaxeFlixel Tutorial",
"ogmoVersion": "3.3.0",
"ogmoVersion": "3.4.0",
"levelPaths": ["."],
"backgroundColor": "#282c34ff",
"gridColor": "#3c4049cc",
@@ -29,7 +29,7 @@
"definition": "tile",
"name": "walls",
"gridSize": {"x": 16, "y": 16},
"exportID": "40116503",
"exportID": "02788814",
"exportMode": 0,
"arrayMode": 0,
"defaultTileset": "tiles"
@@ -54,7 +54,7 @@
{"x": 1, "y": 1}
]
},
"color": "#ff0000ff",
"color": "#00e3ffff",
"tileX": false,
"tileY": false,
"tileSize": {"x": 16, "y": 16},
@@ -162,7 +162,7 @@
{"x": 1, "y": 1}
]
},
"color": "#00e3ffff",
"color": "#ff0000ff",
"tileX": false,
"tileY": false,
"tileSize": {"x": 16, "y": 16},
@@ -182,6 +182,6 @@
}
],
"tilesets": [
{"label": "tiles", "path": "../images/tiles.png", "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAQCAYAAABQrvyxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODRBQjNDODZENDhCMTFFMzk5N0RDMzAxQTc5NEM5RkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODRBQjNDODdENDhCMTFFMzk5N0RDMzAxQTc5NEM5RkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4NEFCM0M4NEQ0OEIxMUUzOTk3REMzMDFBNzk0QzlGQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4NEFCM0M4NUQ0OEIxMUUzOTk3REMzMDFBNzk0QzlGQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrOLMN8AAACUSURBVHja7JWhDoAgEEBPRrERbVYCX+If8Z8Eqo2IyYi7wOYYTncYuI3XD94bDKaUErSwWZtWY0izu3NAnc3zEhpBAVyIQvAeWuKPEEAAQ7I8IjjLswso5RHZq2iNUp7lFRoBI2AEQN+vEL5A+EM/MSvV7wm8ySNnjH0GfJGvRQhu8mWE/GPz2g/5hUVrkvw94hJgALO2Vr1s43dIAAAAAElFTkSuQmCC", "tileWidth": 16, "tileHeight": 16, "tileSeparationX": 0, "tileSeparationY": 0}
{"label": "tiles", "path": "../images/tiles.png", "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAACQCAMAAACPiZ3DAAAABGdBTUEAALGOfPtRkwAAAFRQTFRFAAAAqrfM/udh/q40/smc5O35af/UdeP/0XbQAJnbWmmIm0yj/3BtJZVq4Zpl6EU3Q+Gz////98KCz4JUvWxKUmB8wMvcJitEdjs26qVsi5u0PyYxhk+Z/gAAABx0Uk5TAP///////////////////////////////////6l3rVEAAAMZSURBVGiB7ZdbcusgDED90R0QkwTvf5+XNxKSLMBJm2mvpmMHDAch9KDb1slzUvr5bwB8fb0CYFCXtTY+wmtpC7MAvLwxKxoYA3+a0FwGgH0s2iDPNCYqsg7Isg4ID6/CFMBcBRANprZQPTpbz6STmdOACYuFLXQAo0i/gDHYqX4bIPeh1jiAGjjmolFA6zH1IQIMBaCVzRNkoRVA3sAMgJk/p8GPA07mvweAvn8eoA+mHviZADJABYBLB1vOxfgYBJwK2cIKIBCKDsuAqxq0hLMGaDr82BbGAayjzdiAc3XYXgRMGFHV4H63bljs/Y7G+3YBIEqPtGACA3Dh1hUfRVADtl0AgK8uAvYJCQDcfpkN5gC2tTe0J02KDVxrf7YNqG8ggFVtQH0D+YH7PBsM2OIkFpgIYGzxllh4XJT/gL8COIpMAw5RxgB1eHZ8nnAKcCiWWnkZBlgeYCcBew7+fQUQJxZAySLfCjiOPqWkXgZAfSUNTYsXcU4CMC4yC3jcbg8R0MwgA25eGMCQDXyHCLBg+eQDBHAkgLgFfIwLRlQBaaJ0jLoNxGwBATkuBUCyXviTAa74wymA00D3gwI43cIFG4z4gZBx5/zgfYDns6bi+A/GKcDfhgiACgG0EPA24gBdXeCjUdBgJK2XRf3qNJhm6oIHoB3UykTqAqlMaZ7vJYDej7PwACrHzgP2wershb9toiFbsL2t1r9JqLg092GLp08MCCVk2wy40QVGAaJUwONBUwolsYBqAw0gaSDfwAYB12Tjj7pJnw/69gbznQPpu6TzNp6VBsBeC+8D5J6I2gIA1oE+nOHbAzQbqIC281oAuzrQ5wPYTluQ9Y+xz/en9ysAug3OvxI/yMdXzZHTeBzV/C800hdyjOX82zECQAjHkh4kQP/uC0lLDxmg26ACunyQAbofdBr0AP0Y3w0Ir91xuw++SquxBMD5ILYnAUj79GMU4HYJsLtxAGuDQUCJ8OwHwBEmbED1/26A5geweuEL34AfxNTOyqAflCxM60JMabofKGld9wMVoPmBUhf0Y1TS+lXAP2vxLx2XEutMAAAAAElFTkSuQmCC", "tileWidth": 16, "tileHeight": 16, "tileSeparationX": 0, "tileSeparationY": 0, "tileMarginX": 0, "tileMarginY": 0}
]
}
Binary file added Tutorials/TurnBasedRPG/assets/images/bar_empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tutorials/TurnBasedRPG/assets/images/bar_filled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/images/boss.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/images/button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/images/coin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/images/enemy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tutorials/TurnBasedRPG/assets/images/font.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/images/health.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/images/player.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/images/pointer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/images/tiles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tutorials/TurnBasedRPG/assets/images/ui_section.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tutorials/TurnBasedRPG/assets/images/uiback.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tutorials/TurnBasedRPG/assets/sounds/coin.wav
Binary file not shown.
Binary file modified Tutorials/TurnBasedRPG/assets/sounds/combat.wav
Binary file not shown.
Binary file modified Tutorials/TurnBasedRPG/assets/sounds/fled.wav
Binary file not shown.
Binary file modified Tutorials/TurnBasedRPG/assets/sounds/hurt.wav
Binary file not shown.
Binary file modified Tutorials/TurnBasedRPG/assets/sounds/lose.wav
Binary file not shown.
Binary file modified Tutorials/TurnBasedRPG/assets/sounds/miss.wav
Binary file not shown.
Binary file modified Tutorials/TurnBasedRPG/assets/sounds/select.wav
Binary file not shown.
Binary file modified Tutorials/TurnBasedRPG/assets/sounds/win.wav
Binary file not shown.
507 changes: 0 additions & 507 deletions Tutorials/TurnBasedRPG/source/CombatHUD.hx

This file was deleted.

100 changes: 0 additions & 100 deletions Tutorials/TurnBasedRPG/source/GameOverState.hx

This file was deleted.

46 changes: 0 additions & 46 deletions Tutorials/TurnBasedRPG/source/HUD.hx

This file was deleted.

1 change: 1 addition & 0 deletions Tutorials/TurnBasedRPG/source/Main.hx
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import flixel.FlxG;
import flixel.FlxGame;
import flixel.util.FlxSave;
import openfl.display.Sprite;
import states.MenuState;

class Main extends Sprite
{
78 changes: 0 additions & 78 deletions Tutorials/TurnBasedRPG/source/MenuState.hx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package;
package objects;

import flixel.FlxSprite;
import flixel.tweens.FlxEase;
@@ -9,7 +9,9 @@ class Coin extends FlxSprite
public function new(x:Float, y:Float)
{
super(x, y);
loadGraphic(AssetPaths.coin__png, false, 8, 8);
loadGraphic(AssetPaths.coin__png, true, 12, 12);
animation.add("idle", [0, 1], 4);
animation.play("idle");
}

override function kill()
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package;
package objects;

import flixel.FlxG;
import flixel.FlxSprite;
import flixel.math.FlxPoint;
import flixel.math.FlxVelocity;
import flixel.tile.FlxTilemap;
import flixel.sound.FlxSound;

using flixel.util.FlxSpriteUtil;
@@ -16,8 +17,8 @@ enum EnemyType

class Enemy extends FlxSprite
{
static inline var WALK_SPEED:Float = 40;
static inline var CHASE_SPEED:Float = 70;
static inline var WALK_SPEED:Float = 50;
static inline var CHASE_SPEED:Float = 90;

var brain:FSM;
var idleTimer:Float;
@@ -27,25 +28,28 @@ class Enemy extends FlxSprite
public var type(default, null):EnemyType;
public var seesPlayer:Bool;
public var playerPosition:FlxPoint;
public var maxHP:Int;
public var hp:Int;

public function new(x:Float, y:Float, type:EnemyType)
{
super(x, y);
this.type = type;
var graphic = if (type == BOSS) AssetPaths.boss__png else AssetPaths.enemy__png;
loadGraphic(graphic, true, 16, 16);
setFacingFlip(LEFT, false, false);
setFacingFlip(RIGHT, true, false);

changeType(type);
maxHP = type == REGULAR ? 2 : 4;
hp = maxHP;

setFacingFlip(LEFT, true, false);
setFacingFlip(RIGHT, false, false);
animation.add("d_idle", [0]);
animation.add("lr_idle", [3]);
animation.add("u_idle", [6]);
animation.add("d_walk", [0, 1, 0, 2], 6);
animation.add("lr_walk", [3, 4, 3, 5], 6);
animation.add("u_walk", [6, 7, 6, 8], 6);
drag.x = drag.y = 10;
setSize(8, 8);
offset.x = 4;
offset.y = 8;
setSize(12, 12);
offset.set(6, 12);

brain = new FSM(idle);
idleTimer = 0;
@@ -55,49 +59,50 @@ class Enemy extends FlxSprite
stepSound = FlxG.sound.load(AssetPaths.step__wav, 0.4);
stepSound.proximity(x, y, FlxG.camera.target, FlxG.width * 0.6);
}

public function hurt(damage:Int)
{
hp -= damage;
}

override public function update(elapsed:Float)
override function update(elapsed:Float)
{
if (this.isFlickering())
{
return;
}

var action = "idle";
if (velocity.x != 0 || velocity.y != 0)
{
action = "walk";
if (Math.abs(velocity.x) > Math.abs(velocity.y))
{
if (velocity.x < 0)
facing = LEFT;
else
facing = RIGHT;
facing = (velocity.x < 0) ? LEFT : RIGHT;
}
else
{
if (velocity.y < 0)
facing = UP;
else
facing = DOWN;
facing = (velocity.y < 0) ? UP : DOWN;
}

stepSound.setPosition(x + frameWidth / 2, y + height);
stepSound.setPosition(x + width / 2, y + height);
stepSound.play();
}

switch (facing)
{
case LEFT, RIGHT:
animation.play("lr_" + action);

case UP:
animation.play("u_" + action);

case DOWN:
animation.play("d_" + action);

case _:
}

brain.update(elapsed);
super.update(elapsed);
}
@@ -125,7 +130,9 @@ class Enemy extends FlxSprite
idleTimer = FlxG.random.int(1, 4);
}
else
{
idleTimer -= elapsed;
}
}

function chase(elapsed:Float)
@@ -139,14 +146,22 @@ class Enemy extends FlxSprite
FlxVelocity.moveTowardsPoint(this, playerPosition, CHASE_SPEED);
}
}

public function checkVision(player:Player, walls:FlxTilemap)
{
// Store the player position
player.getMidpoint(playerPosition);
// Cast a ray from here to the player and see if a wall is blocking
seesPlayer = walls.ray(getMidpoint(FlxPoint.weak()), playerPosition);
}

public function changeType(type:EnemyType)
{
if (this.type != type)
{
this.type = type;
var graphic = if (type == BOSS) AssetPaths.boss__png else AssetPaths.enemy__png;
loadGraphic(graphic, true, 16, 16);
loadGraphic(graphic, true, 24, 24);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package objects;

class FSM
{
public var activeState:Float->Void;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package;
package objects;

import flixel.FlxG;
import flixel.FlxSprite;
@@ -7,16 +7,21 @@ import flixel.sound.FlxSound;

class Player extends FlxSprite
{
static inline var SPEED:Float = 100;
static inline var SPEED:Float = 110;
/** Reaches top speed in 0.15 seconds */
static inline var ACCEL:Float = SPEED / 0.15;

var stepSound:FlxSound;
public final maxHP:Int = 3;
public var hp:Int;

public function new(x:Float = 0, y:Float = 0)
{
hp = maxHP;
super(x, y);
loadGraphic(AssetPaths.player__png, true, 16, 16);
setFacingFlip(LEFT, false, false);
setFacingFlip(RIGHT, true, false);

loadGraphic(AssetPaths.player__png, true, 24, 24);
setFacingFlip(LEFT, true, false);
setFacingFlip(RIGHT, false, false);
animation.add("d_idle", [0]);
animation.add("lr_idle", [3]);
animation.add("u_idle", [6]);
@@ -25,20 +30,44 @@ class Player extends FlxSprite
animation.add("u_walk", [6, 7, 6, 8], 6);

drag.x = drag.y = 800;
setSize(8, 8);
offset.set(4, 8);

stepSound = FlxG.sound.load(AssetPaths.step__wav);
maxVelocity.x = maxVelocity.y = SPEED;
setSize(12, 12);
offset.set(6, 12);
}

public function hurt(damage:Int)
{
hp -= damage;
}

override function update(elapsed:Float)
{
updateMovement();
super.update(elapsed);

updateMovement();
}

function updateMovement()
{
var action = "idle";
// check if the player is moving, and not walking into walls
if (velocity.x != 0 || velocity.y != 0)
{
// FlxG.sound.play(AssetPaths.step__wav)
action = "walk";
}

switch (facing)
{
case LEFT, RIGHT:
animation.play("lr_" + action);
case UP:
animation.play("u_" + action);
case DOWN:
animation.play("d_" + action);
case _:
}

var up:Bool = false;
var down:Bool = false;
var left:Bool = false;
@@ -58,65 +87,48 @@ class Player extends FlxSprite
left = left || virtualPad.buttonLeft.pressed;
right = right || virtualPad.buttonRight.pressed;
#end


// Cancel out opposing directions
if (up && down)
{
up = down = false;
}

if (left && right)
{
left = right = false;

if (up || down || left || right)
}

acceleration.set(0, 0);
if (right)
{
var newAngle:Float = 0;
if (up)
{
newAngle = -90;
if (left)
newAngle -= 45;
else if (right)
newAngle += 45;
facing = UP;
}
else if (down)
{
newAngle = 90;
if (left)
newAngle += 45;
else if (right)
newAngle -= 45;
facing = DOWN;
}
else if (left)
{
newAngle = 180;
facing = LEFT;
}
else if (right)
{
newAngle = 0;
facing = RIGHT;
}

// determine our velocity based on angle and speed
velocity.setPolarDegrees(SPEED, newAngle);
facing = RIGHT;
acceleration.x = ACCEL;
}

var action = "idle";
// check if the player is moving, and not walking into walls
if ((velocity.x != 0 || velocity.y != 0) && touching == NONE)
else if (left)
{
stepSound.play();
action = "walk";
facing = LEFT;
acceleration.x = -ACCEL;
}

switch (facing)
if (down)
{
case LEFT, RIGHT:
animation.play("lr_" + action);
case UP:
animation.play("u_" + action);
case DOWN:
animation.play("d_" + action);
case _:
facing = DOWN;
acceleration.y = ACCEL;
}
else if (up)
{
facing = UP;
acceleration.y = -ACCEL;
}

// Prevent faster speeds on diagonal movement
var magnitude = velocity.length;
if (magnitude > SPEED)
{
// Reduce speed to SPEED but maintain direction
velocity.x *= SPEED / magnitude;
velocity.y *= SPEED / magnitude;
}
}
}
106 changes: 106 additions & 0 deletions Tutorials/TurnBasedRPG/source/states/GameOverState.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package states;

import flixel.util.FlxTimer;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.text.FlxBitmapText;
import flixel.text.FlxText;
import flixel.ui.FlxButton;
import flixel.util.FlxAxes;
import flixel.util.FlxColor;
import ui.LargeText;

class GameOverState extends FlxState
{
/**
* Called from PlayState, this will set our win and score variables
* @param win Whether the player beat the boss, or died
* @param score The number of coins collected
*/
public function new(win:Bool, score:Int)
{
super();

#if FLX_MOUSE
FlxG.mouse.visible = true;
#end

// create and add each of our items

var titleText = new LargeText(0, 20, if (win) "You Win!" else "Game Over!");
titleText.screenCenter(FlxAxes.X);
add(titleText);

var messageText = new FlxText(0, (FlxG.height / 2) - 18, 0, "Final Score: 0", 8);
messageText.screenCenter(FlxAxes.X);
add(messageText);

// Fade the camera from black
FlxG.camera.fade(FlxColor.BLACK, 0.33, true);

// Count up the points for dramatic effect
FlxTween.num(0, score, 1.0, // from 0 to score in 1.0 second
{
startDelay: 0.33,// wait for the fade to complete
ease: FlxEase.circOut,
onComplete: function (tween:FlxTween)
{
// Wait 1 second and then show the highscore
new FlxTimer().start(0.5, (_)->showHighscore(score));
}
},
function updateText(tweenedScore)
{
messageText.text = "Final Score: " + Math.floor(tweenedScore);
}
);
}

function showHighscore(score:Int)
{
// Get previous highscore
var highscore = 0;
if (FlxG.save.data.highscore != null)
{
highscore = FlxG.save.data.highscore;
}

var highscoreText = new FlxText(0, (FlxG.height / 2) + 10, 0, "Highscore: " + highscore, 8);
add(highscoreText);

// New high score
if (score > highscore)
{
FlxG.save.data.highscore = score;
highscoreText.text = "New Highscore!";
}

highscoreText.screenCenter(FlxAxes.XY);

// Wait a second then show the
new FlxTimer().start(1.0, (_)->showButton());
}

function showButton()
{
var mainMenuButton = new FlxButton(0, FlxG.height - 32, "Main Menu", switchToMainMenu);
mainMenuButton.loadGraphic(AssetPaths.button__png, true, 80, 20);
mainMenuButton.screenCenter(FlxAxes.X);
mainMenuButton.onUp.sound = FlxG.sound.load(AssetPaths.select__wav);
add(mainMenuButton);
}

/**
* When the user hits the main menu button, it should fade out and then take them back to the MenuState
*/
function switchToMainMenu():Void
{
FlxG.camera.fade(FlxColor.BLACK, 0.33, false, function()
{
FlxG.switchState(MenuState.new);
});
}
}
111 changes: 111 additions & 0 deletions Tutorials/TurnBasedRPG/source/states/MenuState.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package states;

import ui.OptionsSubState;
import ui.LargeText;
import flixel.FlxG;
import flixel.FlxState;
import flixel.text.FlxBitmapText;
import flixel.text.FlxText;
import flixel.ui.FlxButton;
import flixel.util.FlxColor;
import flixel.addons.editors.ogmo.FlxOgmo3Loader;

class MenuState extends FlxState
{
override public function create()
{
// NOTE: differs from tutorial!
var map = new FlxOgmo3Loader(AssetPaths.turnBasedRPG__ogmo, AssetPaths.room_001__json);
var walls = map.loadTilemap(AssetPaths.tiles__png, "walls");
walls.x -= 123;
walls.y -= 10;
add(walls);

// Use FlxBitmapText for crisper edges on large text
var titleText = new LargeText(0, 16, "DUNGEON\nCRAWLER");
titleText.alignment = CENTER;
titleText.setBorderStyle(OUTLINE, 0xFF3f2631);
titleText.screenCenter(X);
add(titleText);

// TUTORIAL VERSION:
// var titleText = new FlxText(0, 16, 0, "DUNGEON\nCRAWLER", 32);
// titleText.alignment = CENTER;
// titleText.screenCenter(X);
// add(titleText);

var playButton = new FlxButton(0, 0, "Play", clickPlay);
playButton.loadGraphic(AssetPaths.button__png, true, 80, 20);
playButton.onUp.sound = FlxG.sound.load(AssetPaths.select__wav);
playButton.x = (FlxG.width / 2) - 10 - playButton.width;
playButton.y = FlxG.height - playButton.height - 10;
add(playButton);

var optionsButton = new FlxButton(0, 0, "Options", clickOptions);
optionsButton.loadGraphic(AssetPaths.button__png, true, 80, 20);
optionsButton.x = (FlxG.width / 2) + 10;
optionsButton.y = FlxG.height - optionsButton.height - 10;
add(optionsButton);

#if desktop
var exitButton = new FlxButton(FlxG.width - 28, 8, "X", clickExit);
exitButton.loadGraphic(AssetPaths.small_button__png, true, 20, 20);
add(exitButton);
#end

if (FlxG.sound.music == null) // don't restart the music if it's already playing
{
initSound();
}

FlxG.camera.fade(FlxColor.BLACK, 0.33, true);

super.create();
}

function initSound()
{
var volumes:{ music:Float, sound:Float } = null;
if (FlxG.save.data.volumes != null)
{
volumes = FlxG.save.data.volumes;
}
else
{
volumes = { music:0.5, sound:1.0 };
}

FlxG.sound.defaultMusicGroup.volume = volumes.music;
FlxG.sound.defaultSoundGroup.volume = volumes.sound;

#if flash
FlxG.sound.playMusic(AssetPaths.HaxeFlixel_Tutorial_Game__mp3, 1.0, true);
#else
FlxG.sound.playMusic(AssetPaths.HaxeFlixel_Tutorial_Game__ogg, 1.0, true);
#end
}

function clickPlay()
{
FlxG.camera.fade(FlxColor.BLACK, 0.33, false, function()
{
FlxG.switchState(PlayState.new);
});
}

function clickOptions()
{
openSubState(new OptionsSubState());
// FlxG.camera.fade(FlxColor.BLACK, 0.33, false, function()
// {
// FlxG.switchState(OptionsState.new);
// });
}

#if desktop
function clickExit()
{
Sys.exit(0);
}
#end
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package;
package states;

import flixel.FlxG;
import flixel.FlxState;
import flixel.text.FlxText;
import flixel.text.FlxBitmapText;
import flixel.ui.FlxBar;
import flixel.ui.FlxButton;
import flixel.util.FlxAxes;
@@ -11,73 +12,67 @@ import flixel.util.FlxColor;
class OptionsState extends FlxState
{
// define our screen elements
var titleText:FlxText;
var volumeBar:FlxBar;
var volumeText:FlxText;
var volumeAmountText:FlxText;
var volumeDownButton:FlxButton;
var volumeUpButton:FlxButton;
var clearDataButton:FlxButton;
var backButton:FlxButton;
#if desktop
var fullscreenButton:FlxButton;
#end

override public function create():Void
{
// setup and add our objects to the screen
titleText = new FlxText(0, 20, 0, "Options", 22);
titleText.alignment = CENTER;
titleText.screenCenter(FlxAxes.X);
var titleText = new LargeText(0, 32, "Options");
titleText.screenCenter(X);
add(titleText);

volumeText = new FlxText(0, titleText.y + titleText.height + 10, 0, "Volume", 8);
var volumeText = new FlxText(0, titleText.y + titleText.height + 10, 0, "Volume", 8);
volumeText.alignment = CENTER;
volumeText.screenCenter(FlxAxes.X);
volumeText.screenCenter(X);
add(volumeText);

// the volume buttons will be smaller than 'default' buttons
volumeDownButton = new FlxButton(8, volumeText.y + volumeText.height + 2, "-",
clickVolumeDown);
volumeDownButton.loadGraphic(AssetPaths.button__png, true, 20, 20);
var volumeDownButton = new FlxButton(8, volumeText.y + volumeText.height + 2, "-", clickVolumeDown);
volumeDownButton.loadGraphic(AssetPaths.small_button__png, true, 20, 20);
volumeDownButton.onUp.sound = FlxG.sound.load(AssetPaths.select__wav);
add(volumeDownButton);

volumeUpButton = new FlxButton(FlxG.width - 28, volumeDownButton.y, "+", clickVolumeUp);
volumeUpButton.loadGraphic(AssetPaths.button__png, true, 20, 20);
var volumeUpButton = new FlxButton(FlxG.width - 28, volumeDownButton.y, "+", clickVolumeUp);
volumeUpButton.loadGraphic(AssetPaths.small_button__png, true, 20, 20);
volumeUpButton.onUp.sound = FlxG.sound.load(AssetPaths.select__wav);
add(volumeUpButton);

volumeBar = new FlxBar(volumeDownButton.x + volumeDownButton.width + 4,
volumeDownButton.y, LEFT_TO_RIGHT, Std.int(FlxG.width - 64),
Std.int(volumeUpButton.height));
volumeBar.createFilledBar(0xff464646, FlxColor.WHITE, true, FlxColor.WHITE);
add(volumeBar);

volumeAmountText = new FlxText(0, 0, 200, (FlxG.sound.volume * 100) + "%", 8);
volumeAmountText.alignment = CENTER;
volumeAmountText.borderStyle = FlxTextBorderStyle.OUTLINE;
volumeAmountText.borderColor = 0xff464646;
volumeAmountText.y = volumeBar.y + (volumeBar.height / 2) - (volumeAmountText.height / 2);
volumeAmountText.screenCenter(FlxAxes.X);
add(volumeAmountText);

#if desktop
fullscreenButton = new FlxButton(0, volumeBar.y + volumeBar.height + 8,
FlxG.fullscreen ? "FULLSCREEN" : "WINDOWED", clickFullscreen);
fullscreenButton.loadGraphic(AssetPaths.button__png, true, 80, 20);
fullscreenButton.screenCenter(FlxAxes.X);
add(fullscreenButton);
#end

clearDataButton = new FlxButton((FlxG.width / 2) - 90, FlxG.height - 28, "Clear Data",
clickClearData);
var clearDataButton = new FlxButton((FlxG.width / 2) - 90, FlxG.height - 28, "Clear Data", clickClearData);
clearDataButton.loadGraphic(AssetPaths.button__png, true, 80, 20);
clearDataButton.onUp.sound = FlxG.sound.load(AssetPaths.select__wav);
add(clearDataButton);

backButton = new FlxButton((FlxG.width / 2) + 10, FlxG.height - 28, "Back", clickBack);

var backButton = new FlxButton((FlxG.width / 2) + 10, FlxG.height - 28, "Back", clickBack);
backButton.loadGraphic(AssetPaths.button__png, true, 80, 20);
backButton.onUp.sound = FlxG.sound.load(AssetPaths.select__wav);
add(backButton);

// update our bar to show the current volume level
updateVolume();

Original file line number Diff line number Diff line change
@@ -1,101 +1,91 @@
package;
package states;

import flixel.FlxG;
import flixel.FlxState;
import flixel.addons.editors.ogmo.FlxOgmo3Loader;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.group.FlxGroup;
import flixel.sound.FlxSound;
import flixel.tile.FlxTilemap;
import flixel.util.FlxColor;
#if mobile
import flixel.ui.FlxVirtualPad;
#end
import objects.Coin;
import objects.Enemy;
import objects.Player;
import ui.CombatSubState;
import ui.HUD;

using flixel.util.FlxSpriteUtil;

class PlayState extends FlxState
{
var player:Player;
var map:FlxOgmo3Loader;
var walls:FlxTilemap;
var coins:FlxTypedGroup<Coin>;
var enemies:FlxTypedGroup<Enemy>;

var hud:HUD;
var money:Int = 0;
var health:Int = 3;

var inCombat:Bool = false;
var combatHud:CombatHUD;

var ending:Bool;
var won:Bool;

var coinSound:FlxSound;


#if mobile
public static var virtualPad:FlxVirtualPad;
#end

override public function create()
{
#if FLX_MOUSE
FlxG.mouse.visible = false;
#end

map = new FlxOgmo3Loader(AssetPaths.turnBasedRPG__ogmo, AssetPaths.room_001__json);
var map = new FlxOgmo3Loader(AssetPaths.turnBasedRPG__ogmo, AssetPaths.room_001__json);
walls = map.loadTilemap(AssetPaths.tiles__png, "walls");
walls.follow();
walls.setTileProperties(1, NONE);
walls.setTileProperties(2, ANY);
walls.setTileProperties(0, NONE, null, null, 16);
walls.setTileProperties(16, ANY, null, null, 20);
add(walls);

coins = new FlxTypedGroup<Coin>();
add(coins);

enemies = new FlxTypedGroup<Enemy>();
add(enemies);

player = new Player();
map.loadEntities(placeEntities, "entities");
add(player);

FlxG.camera.follow(player, TOPDOWN, 1);

hud = new HUD();
add(hud);

combatHud = new CombatHUD();
add(combatHud);

coinSound = FlxG.sound.load(AssetPaths.coin__wav);


#if mobile
virtualPad = new FlxVirtualPad(FULL, NONE);
add(virtualPad);
#end

FlxG.camera.fade(FlxColor.BLACK, 0.33, true);

super.create();
}

function placeEntities(entity:EntityData)
{
var x = entity.x;
var y = entity.y;

switch (entity.name)
{
case "player":
player.setPosition(x, y);

case "coin":
coins.add(new Coin(x + 4, y + 4));

case "enemy":
enemies.add(new Enemy(x + 4, y, REGULAR));

case "boss":
enemies.add(new Enemy(x + 4, y, BOSS));
}
@@ -104,62 +94,12 @@ class PlayState extends FlxState
override public function update(elapsed:Float)
{
super.update(elapsed);

if (ending)
{
return;
}

if (inCombat)
{
if (!combatHud.visible)
{
health = combatHud.playerHealth;
hud.updateHUD(health, money);
if (combatHud.outcome == DEFEAT)
{
ending = true;
FlxG.camera.fade(FlxColor.BLACK, 0.33, false, doneFadeOut);
}
else
{
if (combatHud.outcome == VICTORY)
{
combatHud.enemy.kill();
if (combatHud.enemy.type == BOSS)
{
won = true;
ending = true;
FlxG.camera.fade(FlxColor.BLACK, 0.33, false, doneFadeOut);
}
}
else
{
combatHud.enemy.flicker();
}
inCombat = false;
player.active = true;
enemies.active = true;

#if mobile
virtualPad.visible = true;
#end
}
}
}
else
{
FlxG.collide(player, walls);
FlxG.overlap(player, coins, playerTouchCoin);
FlxG.collide(enemies, walls);
enemies.forEachAlive(checkEnemyVision);
FlxG.overlap(player, enemies, playerTouchEnemy);
}
}

function doneFadeOut()
{
FlxG.switchState(() -> new GameOverState(won, money));

FlxG.collide(player, walls);
FlxG.overlap(player, coins, playerTouchCoin);
FlxG.collide(enemies, walls);
enemies.forEachAlive(checkEnemyVision);
FlxG.overlap(player, enemies, playerTouchEnemy);
}

function playerTouchCoin(player:Player, coin:Coin)
@@ -168,22 +108,14 @@ class PlayState extends FlxState
{
coin.kill();
money++;
hud.updateHUD(health, money);
coinSound.play(true);
hud.updateMoney(money);
FlxG.sound.play(AssetPaths.coin__wav);
}
}

function checkEnemyVision(enemy:Enemy)
{
if (walls.ray(enemy.getMidpoint(), player.getMidpoint()))
{
enemy.seesPlayer = true;
enemy.playerPosition = player.getMidpoint();
}
else
{
enemy.seesPlayer = false;
}
enemy.checkVision(player, walls);
}

function playerTouchEnemy(player:Player, enemy:Enemy)
@@ -196,13 +128,40 @@ class PlayState extends FlxState

function startCombat(enemy:Enemy)
{
inCombat = true;
player.active = false;
enemies.active = false;
combatHud.initCombat(health, enemy);

#if mobile
virtualPad.visible = false;
#end

FlxG.sound.play(AssetPaths.combat__wav);
openSubState(new CombatSubState(player, enemy, (outcome)->handleCombatOutcome(outcome, enemy)));
}

function handleCombatOutcome(outcome:CombatOutcome, enemy:Enemy)
{
hud.updateHealth(player.hp);
switch(outcome)
{
case VICTORY:
enemy.kill();
if (enemy.type == BOSS)
{
fadeToGameOver(true);
}
case ESCAPED:
enemy.flicker();
case DEFEAT:
player.alive = false;

fadeToGameOver(false);
}
}

function fadeToGameOver(won:Bool)
{
function onComplete()
{
FlxG.switchState(()->new GameOverState(won, money));
}
FlxG.camera.fade(FlxColor.BLACK, 0.33, false, onComplete);
}
}
528 changes: 528 additions & 0 deletions Tutorials/TurnBasedRPG/source/ui/CombatSubState.hx

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions Tutorials/TurnBasedRPG/source/ui/HUD.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package ui;

import flixel.FlxG;
import flixel.FlxSprite;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.text.FlxText;
import flixel.util.FlxColor;
import objects.Coin;

using flixel.util.FlxSpriteUtil;

class HUD extends FlxTypedGroup<FlxSprite>
{
var healthCounter:FlxText;
var moneyCounter:FlxText;

public function new()
{
super();

var healthIcon = new FlxSprite(4, 4, AssetPaths.health__png);
healthCounter = new FlxText(0, 0, 0, "3 / 3", 8);
healthCounter.setBorderStyle(SHADOW, FlxColor.GRAY, 1, 1);
healthCounter.x = healthIcon.x + healthIcon.width;
healthCounter.y = healthIcon.y + (healthIcon.height - healthCounter.height) / 2;
add(healthIcon);
add(healthCounter);

var moneyIcon = new Coin(0, 4);
moneyIcon.solid = false;
moneyCounter = new FlxText(0, 0, 0, "00", 8);
moneyCounter.setBorderStyle(SHADOW, FlxColor.GRAY, 1, 1);
moneyIcon.x = FlxG.width - 4 - moneyIcon.width - moneyCounter.width;
moneyCounter.x = moneyIcon.x + moneyIcon.width;
moneyCounter.y = moneyIcon.y + (moneyIcon.height - moneyCounter.height) / 2;
moneyCounter.text = "0";
add(moneyIcon);
add(moneyCounter);

forEach(function(sprite) sprite.scrollFactor.set(0, 0));
}

public function updateHealth(health:Int)
{
healthCounter.text = health + " / 3";
}

public function updateMoney(money:Int)
{
moneyCounter.text = Std.string(money);
}
}
64 changes: 64 additions & 0 deletions Tutorials/TurnBasedRPG/source/ui/LargeText.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package ui;

import flixel.FlxG;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.text.FlxBitmapFont;
import flixel.text.FlxBitmapText;

/**
* Note: This is not in the tutorial, the tutorial uses FlxText everywhere, which is easier to teach.
* Feel free to use this in your games
* Font created by Rick Hoppmann: https://tinyworlds.itch.io/free-pixel-font-thaleah
*/
@:forward
abstract LargeText(FlxBitmapText) to FlxBitmapText
{
static function getDefaultFont()
{
final graphic = FlxG.bitmap.add(AssetPaths.font__png);
final font = FlxBitmapFont.findFont(graphic.imageFrame.frame);
if (font != null)
{
return font;
}

final chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!";
final widths = ['I'.code=>3, '!'.code=>3, 'T'.code=>7];
final defaultWidth = 8;
final defaultHeight = 8;
final font = FlxBitmapFont.fromMonospace(graphic, "", new FlxPoint(defaultWidth, defaultHeight));

var x:Int = 0;
for (i in 0...chars.length)
{
final charCode = chars.charCodeAt(i);
final width = if (widths.exists(charCode)) widths[charCode] else defaultWidth;
final frame = FlxRect.get(x, 0, width, defaultHeight);
@:privateAccess
font.addCharFrame(charCode, frame, FlxPoint.weak(), width);
x += width;
}
return font;
}

public function new (x = 0.0, y = 0.0, text = "", scale = 4)
{
this = new FlxBitmapText(x, y, text, getDefaultFont());
this.text = text;
this.autoUpperCase = true;
setScale(scale);
}

function setScale(scale:Int)
{
this.scale.set(scale, scale);
this.updateHitbox();
}

inline public function setBorderStyle(style, color = 0x0, size = 1, quality = 1)
{
this.setBorderStyle(style, color, size, quality);
this.updateHitbox();
}
}
272 changes: 272 additions & 0 deletions Tutorials/TurnBasedRPG/source/ui/OptionsSubState.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
package ui;

import flixel.FlxSprite;
import flixel.FlxG;
import flixel.addons.display.FlxSliceSprite;
import flixel.group.FlxGroup;
import flixel.group.FlxSpriteGroup;
import flixel.math.FlxRect;
import flixel.text.FlxText;
import flixel.ui.FlxBar;
import flixel.ui.FlxButton;
import flixel.util.FlxColor;

/**
* A SubState that pauses the main menu to show the options UI
*/
class OptionsSubState extends flixel.FlxSubState
{
public function new ()
{
super();

// black-out the main menu
var back = new FlxSprite();
back.makeGraphic(1, 1, 0x80000000);
back.setGraphicSize(FlxG.width, FlxG.height);
back.updateHitbox();
add(back);

// add the UI
var ui = new OptionsUI(()->close());
add(ui);
}
}

/**
* The UI that controls options, extends `FlxSpriteGroup` which changes its members
* when certain properties are changed, namely `x`, `y`, `alpha` and `scrollFactor`.
*/
class OptionsUI extends FlxGroup
{

// define our screen elements
var musicBar:VolumeBar;
var soundBar:VolumeBar;
var fullscreenButton:FlxButton;

public function new (onClose:()->Void)
{
super();

if (FlxG.save.data.volumes == null)
{
initSave();
}

// Make a background to visially separate the ui from the game underneath
var bg = new FlxSliceSprite(AssetPaths.uiback__png, new FlxRect(16, 16, 16, 16), 200, 160);
// Stretch the sections rather than tiling them for better performance
bg.stretchTop
= bg.stretchRight
= bg.stretchLeft
= bg.stretchBottom
= bg.stretchCenter
= true;
bg.screenCenter(XY);
add(bg);

// place the group in the screen center, this will move the bg, and anything added later

var titleText = new LargeText(bg.x, bg.y + 4, "Options", 2);
titleText.screenCenter(X);
add(titleText);

var gap = 8;
var barX = bg.x + gap;
var barY = titleText.y + titleText.height + gap;
var barWidth = bg.width - gap * 2;

musicBar = new VolumeBar(barX, barY, barWidth, "Music", FlxG.sound.defaultMusicGroup.volume, updateMusic);
add(musicBar);
barY += musicBar.height + gap;

soundBar = new VolumeBar(barX, barY, barWidth, "Sound", FlxG.sound.defaultSoundGroup.volume, updateSound);
add(soundBar);
// barY += soundBar.height + gap;

fullscreenButton = new Button(0, soundBar.y + soundBar.height + 8, FlxG.fullscreen ? "Windowed" : "Fullscreen", clickFullscreen);
fullscreenButton.screenCenter(X);
add(fullscreenButton);

var clearDataButton = new Button(bg.x + 10, 0, "Clear Data", clickClearData);
clearDataButton.y = bg.y + bg.height - clearDataButton.height - 10;
add(clearDataButton);

var backButton = new Button(0, clearDataButton.y, "Back", onClose);
backButton.x = bg.x + bg.width - backButton.width - 10;
add(backButton);
}

function clickFullscreen()
{
fullscreenButton.text = FlxG.fullscreen ? "Windowed" : "Fullscreen";
FlxG.fullscreen = !FlxG.fullscreen;
FlxG.save.data.fullscreen = FlxG.fullscreen;
FlxG.save.flush();
}

function initSave()
{
FlxG.save.data.volumes =
{
music: FlxG.sound.defaultMusicGroup.volume,
sound: FlxG.sound.defaultSoundGroup.volume
};
FlxG.sound.muted = false;
FlxG.sound.volume = 1.0;
FlxG.save.data.fullscreen = FlxG.fullscreen;
FlxG.save.flush();
trace(FlxG.save.data);
}

/**
* The user wants to clear the saved data - we just call erase on our save object and then reset the volume to .5
*/
function clickClearData()
{
FlxG.save.erase();
initSave();
musicBar.setVolume(0.5, true);
soundBar.setVolume(1.0, true);
}

/**
* Whenever we want to show the value of volume, we call this to change the bar and the amount text
*/
function updateMusic(volume:Float)
{
FlxG.sound.defaultMusicGroup.volume = volume;
FlxG.save.data.volumes.music = volume;
FlxG.save.flush();
}

/**
* Whenever we want to show the value of volume, we call this to change the bar and the amount text
*/
function updateSound(volume:Float)
{
FlxG.sound.defaultSoundGroup.volume = volume;
FlxG.save.data.volumes.sound = volume;
FlxG.save.flush();
}
}

class VolumeBar extends FlxSpriteGroup
{
var bar:FlxBar;
var amountText:FlxText;
var label:String;
var onChange:(amount:Float)->Void;

/**
*
* @param x
* @param y
* @param width
* @param label
* @param onChange
* @return
*/
public function new (x:Float, y:Float, width:Float, label:String, volume:Float, onChange:(amount:Float)->Void)
{
this.label = label;
this.onChange = onChange;
super();

// var label = new FlxText(0, 0, 0, label, 8);
// label.x = (width - label.width) / 2;
// add(label);

// the volume buttons will be smaller than 'default' buttons
var downButton = new SmallButton(0, 0, "-", clickDown);
add(downButton);

var upButton = new SmallButton(0, downButton.y, "+", clickUp);
upButton.x = width - upButton.width;
add(upButton);

var barWidth = Std.int(width - (4 + upButton.width) * 2);
var barHeight = Std.int(upButton.height);
bar = new FlxBar(downButton.x + downButton.width + 4, downButton.y, LEFT_TO_RIGHT, barWidth, barHeight);
bar.createFilledBar(0xff464646, FlxColor.WHITE, true, FlxColor.WHITE);
add(bar);

amountText = new FlxText(0, 0, 200, "100%", 8);
amountText.alignment = CENTER;
amountText.setBorderStyle(OUTLINE, 0xff464646);
amountText.x = bar.x + (bar.width - amountText.width) / 2;
amountText.y = bar.y + (bar.height - amountText.height) / 2;
add(amountText);

//
this.x = x;
this.y = y;
setVolume(volume);
}

function clickDown()
{
setVolumeHelper(bar.value - 10);
}

function clickUp()
{
setVolumeHelper(bar.value + 10);
}

function setVolumeHelper(volume:Float, dispatch = true)
{
bar.value = Math.round(volume); // Note: bar.value is automatically clamped between 0 and 100
amountText.text = label + " " + bar.value + "%";

if (dispatch)
{
onChange(bar.value / 100);
}
}

public function setVolume(volume:Float, dispatch = false)
{
setVolumeHelper(volume * 100, dispatch);
}

override function destroy()
{
// remove references but do not destroy
bar = null;
amountText = null;
onChange = null;

// this will actually destroy them
super.destroy();
}
}

/**
* Helper class for creating an 80x20 button with a custom graphic
*/
class Button extends FlxButton
{
public function new (x, y, label, onClick)
{
super(x, y, label, onClick);

loadGraphic(AssetPaths.button__png, true, 80, 20);
onUp.sound = FlxG.sound.load(AssetPaths.select__wav);
}
}

/**
* Helper class for creating small 20x20 buttons
*/
class SmallButton extends FlxButton
{
public function new (x, y, label, onClick)
{
super(x, y, label, onClick);

loadGraphic(AssetPaths.small_button__png, true, 20, 20);
onUp.sound = FlxG.sound.load(AssetPaths.select__wav);
}
}