test habit puzzle game in CI
This commit is contained in:
1
projects/habit-puzzle-game-flixel-desktop/.gitignore
vendored
Normal file
1
projects/habit-puzzle-game-flixel-desktop/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export
|
5
projects/habit-puzzle-game-flixel-desktop/.vscode/extensions.json
vendored
Normal file
5
projects/habit-puzzle-game-flixel-desktop/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"openfl.lime-vscode-extension"
|
||||
]
|
||||
}
|
21
projects/habit-puzzle-game-flixel-desktop/.vscode/launch.json
vendored
Normal file
21
projects/habit-puzzle-game-flixel-desktop/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Build + Debug",
|
||||
"type": "lime",
|
||||
"request": "launch"
|
||||
},
|
||||
{
|
||||
"name": "Debug",
|
||||
"type": "lime",
|
||||
"request": "launch",
|
||||
"preLaunchTask": null
|
||||
},
|
||||
{
|
||||
"name": "Macro",
|
||||
"type": "haxe-eval",
|
||||
"request": "launch"
|
||||
}
|
||||
]
|
||||
}
|
13
projects/habit-puzzle-game-flixel-desktop/.vscode/settings.json
vendored
Normal file
13
projects/habit-puzzle-game-flixel-desktop/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"search.exclude": {
|
||||
"export/**/*.hx": true
|
||||
},
|
||||
"[haxe]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.sortImports": true
|
||||
}
|
||||
},
|
||||
"haxe.enableExtendedIndentation": true
|
||||
}
|
13
projects/habit-puzzle-game-flixel-desktop/.vscode/tasks.json
vendored
Normal file
13
projects/habit-puzzle-game-flixel-desktop/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "lime",
|
||||
"command": "test",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
90
projects/habit-puzzle-game-flixel-desktop/Project.xml
Normal file
90
projects/habit-puzzle-game-flixel-desktop/Project.xml
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<!-- _________________________ Application Settings _________________________ -->
|
||||
|
||||
<app title="FlxProject" file="FlxProject" main="Main" version="0.0.1" company="HaxeFlixel" />
|
||||
|
||||
<!--The flixel preloader is not accurate in Chrome. You can use it regularly if you embed the swf into a html file
|
||||
or you can set the actual size of your file manually at "FlxPreloaderBase-onUpdate-bytesTotal"-->
|
||||
<app preloader="flixel.system.FlxPreloader" />
|
||||
|
||||
<!--Minimum without FLX_NO_GAMEPAD: 11.8, without FLX_NO_NATIVE_CURSOR: 11.2-->
|
||||
<set name="SWF_VERSION" value="11.8" />
|
||||
|
||||
<!-- ____________________________ Window Settings ___________________________ -->
|
||||
|
||||
<!--These window settings apply to all targets-->
|
||||
<window width="1280" height="720" fps="60" background="#000000" hardware="true" vsync="false" />
|
||||
|
||||
<!--HTML5-specific-->
|
||||
<window if="html5" resizable="false" />
|
||||
|
||||
<!--Desktop-specific-->
|
||||
<window if="desktop" orientation="landscape" fullscreen="false" resizable="true" />
|
||||
|
||||
<!--Mobile-specific-->
|
||||
<window if="mobile" orientation="landscape" fullscreen="true" width="0" height="0" />
|
||||
|
||||
<!-- _____________________________ Path Settings ____________________________ -->
|
||||
|
||||
<set name="BUILD_DIR" value="export" />
|
||||
<classpath name="source" />
|
||||
|
||||
<!-- _______________________________ Libraries ______________________________ -->
|
||||
|
||||
<haxelib name="flixel" />
|
||||
<haxelib name="haxe-strings" />
|
||||
<haxelib name="kiss" />
|
||||
<haxelib name="kiss-tools" />
|
||||
<haxelib name="datetime" />
|
||||
<haxeflag name="--macro" value="kiss.Kiss.setup()" />
|
||||
|
||||
<!--In case you want to use the addons package-->
|
||||
<!--<haxelib name="flixel-addons" />-->
|
||||
|
||||
<!--In case you want to use the ui package-->
|
||||
<!--<haxelib name="flixel-ui" />-->
|
||||
|
||||
<!--In case you want to use nape with flixel-->
|
||||
<!--<haxelib name="nape-haxe4" />-->
|
||||
|
||||
<!-- ______________________________ Haxedefines _____________________________ -->
|
||||
|
||||
<!-- Uncomment these and change the values to pre-compile character frequencies: -->
|
||||
<!--<haxedef name="LEARN_FROM" value="path/to/text/folder"/>-->
|
||||
<!--<haxedef name="LEARN_FROM_EXT" value="txt,markdown,etc"/>-->
|
||||
|
||||
<!--Enable the Flixel core recording system-->
|
||||
<!--<haxedef name="FLX_RECORD" />-->
|
||||
|
||||
<!--Disable the right and middle mouse buttons-->
|
||||
<!--<haxedef name="FLX_NO_MOUSE_ADVANCED" />-->
|
||||
|
||||
<!--Disable the native cursor API on Flash-->
|
||||
<!--<haxedef name="FLX_NO_NATIVE_CURSOR" />-->
|
||||
|
||||
<!--Optimise inputs, be careful you will get null errors if you don't use conditionals in your game-->
|
||||
<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_GAMEPAD" />-->
|
||||
|
||||
<!--Disable the Flixel core sound tray-->
|
||||
<!--<haxedef name="FLX_NO_SOUND_TRAY" />-->
|
||||
|
||||
<!--Disable the Flixel sound management code-->
|
||||
<!--<haxedef name="FLX_NO_SOUND_SYSTEM" />-->
|
||||
|
||||
<!--Disable the Flixel core focus lost screen-->
|
||||
<!--<haxedef name="FLX_NO_FOCUS_LOST_SCREEN" />-->
|
||||
|
||||
<!--Disable the Flixel core debugger. Automatically gets set whenever you compile in release mode!-->
|
||||
<haxedef name="FLX_NO_DEBUG" unless="debug" />
|
||||
|
||||
<!--Enable this for Nape release builds for a serious peformance improvement-->
|
||||
<haxedef name="NAPE_RELEASE_BUILD" unless="debug" />
|
||||
|
||||
<!-- _________________________________ Custom _______________________________ -->
|
||||
|
||||
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
||||
</project>
|
15
projects/habit-puzzle-game-flixel-desktop/hxformat.json
Normal file
15
projects/habit-puzzle-game-flixel-desktop/hxformat.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"lineEnds": {
|
||||
"leftCurly": "both",
|
||||
"rightCurly": "both",
|
||||
"objectLiteralCurly": {
|
||||
"leftCurly": "after"
|
||||
}
|
||||
},
|
||||
"sameLine": {
|
||||
"ifElse": "next",
|
||||
"doWhile": "next",
|
||||
"tryBody": "next",
|
||||
"tryCatch": "next"
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package;
|
||||
|
||||
import kiss.Prelude;
|
||||
import kiss.List;
|
||||
import kiss.Stream;
|
||||
import sys.io.File;
|
||||
import datetime.DateTime;
|
||||
import datetime.DateTimeInterval;
|
||||
|
||||
enum EntryType {
|
||||
Daily(daysOfWeek:Array<Int>, lastDayDone:String);
|
||||
Interval(days:Int, lastDayDone:String);
|
||||
// -1 represents the last day of the month, and so on
|
||||
Monthly(daysOfMonth:Array<Int>, lastDayDone:String);
|
||||
Bonus;
|
||||
Todo;
|
||||
}
|
||||
|
||||
typedef EntryLabel = {
|
||||
label:String,
|
||||
points:Int
|
||||
};
|
||||
|
||||
typedef Entry = {
|
||||
type: EntryType,
|
||||
labels: Array<EntryLabel>,
|
||||
};
|
||||
|
||||
typedef RewardFile = {
|
||||
path: String,
|
||||
startingPoints: Int
|
||||
};
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class HabitModel {}
|
204
projects/habit-puzzle-game-flixel-desktop/source/HabitModel.kiss
Normal file
204
projects/habit-puzzle-game-flixel-desktop/source/HabitModel.kiss
Normal file
@@ -0,0 +1,204 @@
|
||||
(prop :Array<Entry> dailyEntries [])
|
||||
(prop :Array<Entry> monthlyEntries [])
|
||||
(prop :Array<Entry> intervalEntries [])
|
||||
(prop :Array<Entry> bonusEntries [])
|
||||
(prop :Array<Entry> todoEntries [])
|
||||
(prop :Array<RewardFile> rewardFiles [])
|
||||
|
||||
(defNew [&prop :String textFile]
|
||||
(let [s (Stream.fromFile textFile)
|
||||
&mut lastHeader ""]
|
||||
// TODO could be whileLet
|
||||
(loop
|
||||
(case (s.takeLine)
|
||||
((Some "DAILY")
|
||||
(set lastHeader "DAILY"))
|
||||
((Some "MONTHLY")
|
||||
(set lastHeader "MONTHLY"))
|
||||
((Some "INTERVAL")
|
||||
(set lastHeader "INTERVAL"))
|
||||
((Some "BONUS")
|
||||
(set lastHeader "BONUS"))
|
||||
((Some "TODO")
|
||||
(set lastHeader "TODO"))
|
||||
((Some "FILES")
|
||||
(set lastHeader "FILES"))
|
||||
((when (apply = (concat ["-"] (line.split ""))) (Some line))
|
||||
(continue))
|
||||
((Some "") (continue))
|
||||
// Types won't unify with the next case, so this is its own:
|
||||
((when (= lastHeader "FILES") (Some line))
|
||||
(rewardFiles.push
|
||||
(let [parts (line.split " ")
|
||||
startingPoints (Std.parseInt (parts.pop))
|
||||
path (parts.join " ")]
|
||||
(objectWith path startingPoints))))
|
||||
((Some line)
|
||||
(.push
|
||||
(case lastHeader
|
||||
("DAILY" dailyEntries)
|
||||
("MONTHLY" monthlyEntries)
|
||||
("INTERVAL" intervalEntries)
|
||||
("BONUS" bonusEntries)
|
||||
("TODO" todoEntries)
|
||||
(otherwise (throw "bad header")))
|
||||
(object
|
||||
type
|
||||
(case lastHeader
|
||||
("BONUS" Bonus)
|
||||
("TODO" Todo)
|
||||
("DAILY"
|
||||
(case (line.split ":")
|
||||
([noColon]
|
||||
(Daily
|
||||
// all days of week
|
||||
(collect (range 7))
|
||||
// never done before
|
||||
""))
|
||||
([::&mut preColon ...afterColon]
|
||||
(set line (afterColon.join ":"))
|
||||
(Daily
|
||||
// Days of week specified by abbreviation:
|
||||
(sort (filter
|
||||
[
|
||||
// disambiguate Th from T and Su from S:
|
||||
(when (contains preColon "Th") {(set preColon (StringTools.replace preColon "Th" "")) 4})
|
||||
(when (contains preColon "Su") {(set preColon (StringTools.replace preColon "Su" "")) 0})
|
||||
(when (contains preColon "M") 1)
|
||||
(when (contains preColon "T") 2)
|
||||
(when (contains preColon "W") 3)
|
||||
(when (contains preColon "F") 5)
|
||||
(when (contains preColon "S") 6)
|
||||
|
||||
]))
|
||||
// Last date completed after that:
|
||||
(ifLet [[days date] (preColon.split " ")]
|
||||
date
|
||||
"")))
|
||||
(otherwise (throw "bad line"))))
|
||||
("MONTHLY"
|
||||
(case (line.split ": ")
|
||||
([::&mut preColon ...afterColon]
|
||||
(set line (afterColon.join ": "))
|
||||
(Monthly
|
||||
// Days of month can be positive (1-31) or negative (-1 to -31)
|
||||
(map (.split (first (preColon.split " ")) ",") Std.parseInt)
|
||||
// Last date completed after that:
|
||||
(ifLet [[::days ...date] (preColon.split " ")]
|
||||
(date.join " ")
|
||||
"")))
|
||||
(otherwise (throw "bad line"))))
|
||||
("INTERVAL"
|
||||
(case (line.split ": ")
|
||||
([::&mut preColon ...afterColon]
|
||||
(set line (afterColon.join ": "))
|
||||
(case (preColon.split " ")
|
||||
([days]
|
||||
(Interval (Std.parseInt days) ""))
|
||||
([::days ...lastDayDone]
|
||||
(Interval (Std.parseInt days) (lastDayDone.join " ")))
|
||||
(otherwise (throw "bad interval habit: $line"))))
|
||||
(otherwise (throw "bad interval habit: $line"))))
|
||||
(otherwise (throw "bad header: $lastHeader")))
|
||||
labels
|
||||
(for l (line.split "/")
|
||||
(object
|
||||
label (StringTools.trim (StringTools.replace l "|" ""))
|
||||
points (count (l.split "") ->c (= c "|")))))))
|
||||
(otherwise (break))))))
|
||||
|
||||
(method :Int totalPoints []
|
||||
(apply + (for l (flatten (for e (the Array<Entry> (concat dailyEntries monthlyEntries intervalEntries bonusEntries todoEntries)) e.labels)) l.points)))
|
||||
|
||||
(function :String stringify [:Entry e]
|
||||
"$(case e.type
|
||||
((Daily days lastDayDone)
|
||||
(+
|
||||
(.join (for day days
|
||||
(case day
|
||||
(0 "Su")
|
||||
(1 "M")
|
||||
(2 "T")
|
||||
(3 "W")
|
||||
(4 "Th")
|
||||
(5 "F")
|
||||
(6 "S")
|
||||
(otherwise (throw "bad day")))) "")
|
||||
" "
|
||||
lastDayDone
|
||||
": "))
|
||||
((Monthly days lastDayDone)
|
||||
"$(days.join ",") ${lastDayDone}: ")
|
||||
((Interval days lastDayDone)
|
||||
"$days ${lastDayDone}: ")
|
||||
(otherwise ""))$(.join (for label e.labels
|
||||
"${label.label} $(* "|" label.points)") "/")")
|
||||
|
||||
(function :String stringifyRewardFile [:RewardFile rewardFile]
|
||||
"${rewardFile.path} ${rewardFile.startingPoints}")
|
||||
|
||||
(method :Void save []
|
||||
(localVar &mut content "DAILY\n-----\n")
|
||||
(+= content (.join (map dailyEntries stringify) "\n") "\n")
|
||||
(+= content "\nMONTHLY\n--------\n")
|
||||
(+= content (.join (map monthlyEntries stringify) "\n") "\n")
|
||||
(+= content "\nINTERVAL\n--------\n")
|
||||
(+= content (.join (map intervalEntries stringify) "\n") "\n")
|
||||
(+= content "\nBONUS\n-----\n")
|
||||
(+= content (.join (map bonusEntries stringify) "\n") "\n")
|
||||
(+= content "\nTODO\n----\n")
|
||||
(+= content (.join (map todoEntries stringify) "\n") "\n")
|
||||
(+= content "\nFILES\n-----\n")
|
||||
(+= content (.join (map rewardFiles stringifyRewardFile) "\n") "\n")
|
||||
(File.saveContent textFile
|
||||
content))
|
||||
|
||||
// With rotating entries, the active one is the first one with the lowest score:
|
||||
(function :EntryLabel activeLabel [:Entry e]
|
||||
(let [lowScore (apply min (for label e.labels label.points))]
|
||||
(doFor label e.labels (when (= lowScore label.points) (return label)))
|
||||
(throw "no active?!")))
|
||||
|
||||
(function todayString []
|
||||
(let [d (Date.now)] "$(d.getDate)-$(+ 1 (d.getMonth))-$(d.getFullYear)"))
|
||||
|
||||
(function isActive [:Entry e]
|
||||
(case e.type
|
||||
((Daily days lastDayDone)
|
||||
(and !(= lastDayDone (todayString)) (contains days (.getDay (Date.now)))))
|
||||
((Monthly days lastDayDone)
|
||||
// TODO logic
|
||||
(let [&mut nextDay
|
||||
(DateTime.fromDate (Date.now))
|
||||
oneDayInterval (DateTimeInterval.create (DateTime.make null null 1) (DateTime.make null null 2))
|
||||
dayToEndSearch
|
||||
(if lastDayDone
|
||||
(DateTime.fromString lastDayDone)
|
||||
(let [now (DateTime.fromDate (Date.now))]
|
||||
(until (= 1 (now.getDay)) #|now -= oneDayInterval;|#)
|
||||
now))]
|
||||
(until (and (= (nextDay.getDay) (dayToEndSearch.getDay)) (= (nextDay.getMonth) (dayToEndSearch.getMonth)) (= (nextDay.getYear) (dayToEndSearch.getYear)))
|
||||
(let [daysInMonth (DateTime.daysInMonth (nextDay.getMonth) (nextDay.isLeapYear))
|
||||
adjustedDays (for day days (% (+ daysInMonth day) daysInMonth))]
|
||||
(when (contains adjustedDays (nextDay.getDay)) (return true)))
|
||||
#|nextDay -= oneDayInterval|#)
|
||||
(return false)))
|
||||
((Interval days lastDayDone)
|
||||
(or !lastDayDone (<= days #|(DateTime.fromDate(Date.now()) - DateTime.fromString(lastDayDone)).getTotalDays()|#)))
|
||||
(Todo (= 0 .points (activeLabel e)))
|
||||
(otherwise true)))
|
||||
|
||||
(method :Array<Entry> activeDailyEntries []
|
||||
(filter dailyEntries isActive))
|
||||
|
||||
(method :Array<Entry> activeMonthlyEntries []
|
||||
(filter monthlyEntries isActive))
|
||||
|
||||
(method :Array<Entry> activeIntervalEntries []
|
||||
(filter intervalEntries isActive))
|
||||
|
||||
(method :Array<Entry> activeBonusEntries []
|
||||
(filter bonusEntries isActive))
|
||||
|
||||
(method :Array<Entry> activeTodoEntries []
|
||||
(filter todoEntries isActive))
|
@@ -0,0 +1,21 @@
|
||||
package;
|
||||
|
||||
import flash.display.BitmapData;
|
||||
import haxe.io.Path;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxState;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.math.FlxRandom;
|
||||
import flixel.math.FlxPoint;
|
||||
import kiss.Prelude;
|
||||
import kiss.List;
|
||||
import kiss_tools.FlxKeyShortcutHandler;
|
||||
import HabitModel;
|
||||
import hx.strings.Strings;
|
||||
import datetime.DateTime;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class HabitState extends FlxState {}
|
110
projects/habit-puzzle-game-flixel-desktop/source/HabitState.kiss
Normal file
110
projects/habit-puzzle-game-flixel-desktop/source/HabitState.kiss
Normal file
@@ -0,0 +1,110 @@
|
||||
(method &override :Void create [] (super.create))
|
||||
(method &override :Void update [:Float elapsed]
|
||||
(super.update elapsed)
|
||||
// Hold left-click to hide the habit text and see the image clearly:
|
||||
(when entryTexts (if FlxG.mouse.pressed (remove entryTexts) (add entryTexts)))
|
||||
// Handle keyboard input:
|
||||
(when shortcutHandler
|
||||
(shortcutHandler.update)))
|
||||
|
||||
(prop &mut :FlxTypedGroup<FlxText> entryTexts null)
|
||||
(prop &mut :FlxTypedGroup<FlxSprite> rewardBlockers null)
|
||||
(prop &mut :FlxKeyShortcutHandler<Entry> shortcutHandler null)
|
||||
|
||||
(prop &mut :HabitModel model null)
|
||||
|
||||
(var PUZZLE_WIDTH 4)
|
||||
(var PUZZLE_HEIGHT 4)
|
||||
(var TOTAL_PIECES (* PUZZLE_WIDTH PUZZLE_HEIGHT))
|
||||
(prop &mut :FlxSprite rewardSprite null)
|
||||
|
||||
(method setModel [m]
|
||||
(set model m)
|
||||
(set shortcutHandler (new FlxKeyShortcutHandler))
|
||||
|
||||
(let [p (m.totalPoints)
|
||||
&mut i 0
|
||||
&mut currentRewardFile null]
|
||||
// Find, load, and add the current reward image as big as possible:
|
||||
(while (> p .startingPoints (nth m.rewardFiles i))
|
||||
(set currentRewardFile (nth m.rewardFiles i))
|
||||
(if (>= ++i m.rewardFiles.length)
|
||||
(break)))
|
||||
(when rewardSprite
|
||||
(remove rewardSprite))
|
||||
(set rewardSprite (new FlxSprite 0 0 (BitmapData.fromFile (joinPath (Path.directory m.textFile) currentRewardFile.path))))
|
||||
(rewardSprite.setGraphicSize FlxG.width 0)
|
||||
(rewardSprite.updateHitbox)
|
||||
(when (> rewardSprite.height FlxG.height)
|
||||
(rewardSprite.setGraphicSize 0 FlxG.height))
|
||||
(rewardSprite.updateHitbox)
|
||||
(rewardSprite.screenCenter)
|
||||
(add rewardSprite)
|
||||
|
||||
(when rewardBlockers
|
||||
(remove rewardBlockers))
|
||||
(set rewardBlockers (new FlxTypedGroup))
|
||||
(add rewardBlockers)
|
||||
|
||||
(let [PIECE_WIDTH
|
||||
(/ rewardSprite.width PUZZLE_WIDTH)
|
||||
PIECE_HEIGHT
|
||||
(/ rewardSprite.height PUZZLE_HEIGHT)
|
||||
:Array<FlxPoint> blockerPoints []]
|
||||
(doFor x (range PUZZLE_WIDTH)
|
||||
(doFor y (range PUZZLE_HEIGHT)
|
||||
(blockerPoints.push (new FlxPoint (+ rewardSprite.x (* x PIECE_WIDTH)) (+ rewardSprite.y (* y PIECE_HEIGHT))))))
|
||||
// Cover it up with (TOTAL_PIECES - p) black squares placed randomly by choosing and removing from a zipped coordinate list
|
||||
(let [r (new FlxRandom (Strings.hashCode currentRewardFile.path))]
|
||||
(r.shuffle blockerPoints)
|
||||
(doFor i (range (- (+ TOTAL_PIECES currentRewardFile.startingPoints) p))
|
||||
(let [pos (nth blockerPoints i)
|
||||
s (new FlxSprite pos.x pos.y)]
|
||||
(s.makeGraphic (Math.ceil PIECE_WIDTH) (Math.ceil PIECE_HEIGHT) FlxColor.BLACK)
|
||||
(rewardBlockers.add s))))))
|
||||
|
||||
|
||||
(when entryTexts (remove entryTexts))
|
||||
(set entryTexts (new FlxTypedGroup))
|
||||
(set textY 0)
|
||||
(set color FlxColor.ORANGE)
|
||||
(map (m.activeDailyEntries) makeText)
|
||||
(set color FlxColor.GREEN)
|
||||
(map (m.activeMonthlyEntries) makeText)
|
||||
(set color FlxColor.BLUE)
|
||||
(map (m.activeIntervalEntries) makeText)
|
||||
(set color FlxColor.WHITE)
|
||||
(map (m.activeBonusEntries) makeText)
|
||||
(set color FlxColor.YELLOW)
|
||||
(map (m.activeTodoEntries) makeText)
|
||||
(add entryTexts)
|
||||
|
||||
(doFor e (the Array<Entry> (concat m.dailyEntries m.monthlyEntries m.intervalEntries m.bonusEntries m.todoEntries))
|
||||
(when (HabitModel.isActive e)
|
||||
(let [label (HabitModel.activeLabel e)]
|
||||
(shortcutHandler.registerItem label.label e))))
|
||||
|
||||
(set shortcutHandler.onBadKey ->:Void [_ _] {})
|
||||
(set shortcutHandler.onSelectItem ->:Void [:Entry e]
|
||||
(let [label (HabitModel.activeLabel e)]
|
||||
(+= label.points 1)
|
||||
(whenLet [(Daily days lastDayDone) e.type]
|
||||
(set e.type (Daily days (HabitModel.todayString))))
|
||||
(whenLet [(Monthly days lastDayDone) e.type]
|
||||
(set e.type (Monthly days (.toString (DateTime.now)))))
|
||||
(whenLet [(Interval days lastDayDone) e.type]
|
||||
(set e.type (Interval days (.toString (DateTime.now)))))
|
||||
(m.save)
|
||||
(setModel m)
|
||||
(shortcutHandler.start)))
|
||||
(shortcutHandler.start))
|
||||
|
||||
(prop &mut textY 0)
|
||||
(prop &mut :FlxColor color null)
|
||||
|
||||
(method makeText [:Entry e]
|
||||
(let [label (HabitModel.activeLabel e)
|
||||
text (new FlxText 0 textY 0 (+ label.label (* label.points "+")))]
|
||||
(set text.color color)
|
||||
(+= textY text.height)
|
||||
(entryTexts.add text)))
|
17
projects/habit-puzzle-game-flixel-desktop/source/Main.hx
Normal file
17
projects/habit-puzzle-game-flixel-desktop/source/Main.hx
Normal file
@@ -0,0 +1,17 @@
|
||||
package;
|
||||
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxGame;
|
||||
import openfl.display.Sprite;
|
||||
|
||||
class Main extends Sprite
|
||||
{
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
addChild(new FlxGame(0, 0, HabitState, 1, 60, 60, true));
|
||||
var t:HabitState = cast FlxG.state;
|
||||
t.setModel(new HabitModel(Sys.args()[0]));
|
||||
t.model.save();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user