specify whether flixel projects need to pass html5/c++ compilation

This commit is contained in:
2021-09-18 19:16:27 -06:00
parent fe84da9ad4
commit 64902bbe3b
24 changed files with 13 additions and 5 deletions

View File

@@ -0,0 +1,4 @@
package;
@:build(flixel.system.FlxAssets.buildFileReferences("assets", true))
class AssetPaths {}

View File

@@ -0,0 +1,14 @@
package;
import kiss.Prelude;
import kiss.List;
import flash.display.BitmapData;
import flixel.addons.display.FlxExtendedSprite;
import nat.Entry;
import nat.Archive;
import nat.BoolExpInterp;
import nat.components.Images;
import nat.components.Positions;
@:build(kiss.Kiss.build())
class EntrySprite extends FlxExtendedSprite {}

View File

@@ -0,0 +1,19 @@
(loadFrom "nat-archive-tool" "src/nat/Lib.kiss")
(defNew [:String positionKey
&prop :Archive archive
&prop :Entry e]
(let [images (readComponent archive e Images)]
(case (dictGet (readComponent archive e Positions) positionKey)
((object x x y y z z)
(super x y)))
(.onComplete (BitmapData.loadFromFile (joinPath archive.archiveDir "files" (nth images.imageFiles images.pinnedImageIndex)))
->bitmapData {
(loadGraphic bitmapData)
(enableMouseClicks false)
(enableMouseDrag)
}))
(set mouseStopDragCallback
->[self _dx _dy]
(withWritableComponents archive e [positions Positions]
(dictSet positions positionKey (object x (cast this.x Float) y (cast this.y Float) z 0.0)))))

View File

@@ -0,0 +1,10 @@
package;
import kiss.Prelude;
import kiss.List;
import nat.System;
import nat.BoolExpInterp;
import nat.components.Positions;
@:build(kiss.Kiss.build())
class EntrySpriteSystem extends System {}

View File

@@ -0,0 +1,27 @@
(loadFrom "nat-archive-tool" "src/nat/Lib.kiss")
(prop :Map<String,EntrySprite> sprites (new Map))
(defNew [:String tagFilterString :String positionKey :PlayState playState]
(super
->[archive e]
?(and (tagsMatch archive e tagFilterString) (hasComponent e Images))
->[archive e]
{
(when !(hasComponent e Positions)
(withWritableEntry archive e
(addComponent archive e Positions (new Map))))
(withWritableComponents archive e [positions Positions]
(when !(positions.exists positionKey)
(dictSet positions positionKey (object x 0.0 y 0.0 z 0.0))))
(let [sprite (new EntrySprite positionKey archive e)]
(playState.entryGroup.add sprite)
(dictSet sprites e.id sprite))
})
(set onRemoveEntry
->[archive e]
{
(.kill (dictGet sprites e.id))
(sprites.remove e.id)
}))

View File

@@ -0,0 +1,4 @@
package;
@:build(kiss.Kiss.build())
class Main extends Sprite {}

View File

@@ -0,0 +1,3 @@
(method new []
(super)
(addChild (new FlxGame 320 240 PlayState 1 60 60 true false)))

View File

@@ -0,0 +1,22 @@
package;
import kiss.Prelude;
import kiss.List;
import sys.FileSystem;
import nat.Entry;
import nat.BoolExpInterp;
import nat.Archive;
import nat.ArchiveUI;
import nat.ArchiveController;
import flixel.addons.ui.FlxInputText;
import flixel.addons.ui.FlxUIPopup;
import flixel.text.FlxText;
import flixel.util.FlxColor;
import flixel.FlxCamera;
import flixel.math.FlxVector;
import flixel.addons.plugin.FlxMouseControl;
using StringTools;
@:build(kiss.Kiss.build())
class PlayState extends FlxState implements ArchiveUI {}

View File

@@ -0,0 +1,198 @@
(loadFrom "nat-archive-tool" "src/nat/Lib.kiss")
// TODO store a map of Entry IDs -> EntrySprites.
// TODO handleChanges() will need to kill every changed Entry's sprite and make a new one
// TODO make the EntrySprite constructor assign the entry a serialized position component
// maybe by writing a Map<String, Point> positions component so there can be multiple?
(method &override :Void create []
(super.create)
(FlxG.plugins.add (new FlxMouseControl))
// TODO find a better way to pass the archiveDir to a HaxeFlixel game
(let [archiveDir
(or (Sys.getEnv "NAT_DIR") (throw "NAT_DIR environment variable must be set"))
archive
(new Archive archiveDir)]
(set this.archive archive)
(new ArchiveController
archive
this))
(prop &mut :FlxGroup uiGroup (new FlxGroup))
(add uiGroup)
(prop :FlxGroup entryGroup (new FlxGroup))
(add entryGroup)
(prop uiCamera (new FlxCamera 0 0 FlxG.width FlxG.height))
(set uiCamera.bgColor FlxColor.TRANSPARENT)
(FlxG.cameras.add uiCamera false)
(set uiGroup.cameras [uiCamera])
// TODO make a button that can be clicked to run typeCommand()
// make interactible sprites for entries that have images
// TODO allow configuring the tags at runtime and erasing/re-creating sprites later
// TODO allow using other position keys and erasing/re-creating sprites later
(prop &mut :EntrySpriteSystem spriteSystem)
(set spriteSystem (new EntrySpriteSystem "!done" "Playground-MAIN" this))
(archive.addSystem spriteSystem)
(spriteSystem.process archive))
(method &override :Void update [:Float elapsed]
(super.update elapsed)
// Press ENTER to type a command to run
(when (and !textInput FlxG.keys.justPressed.ENTER)
(typeCommand))
(when (and textInput !textInput.alive)
(set textInput null))
// Press ESCAPE to clear the UI and cancel any input
(when FlxG.keys.justPressed.ESCAPE
(clearUI))
// Scroll the UI with the mouse:
(var UI_SCROLL_FACTOR 2)
(+= uiCamera.y (* FlxG.mouse.wheel UI_SCROLL_FACTOR))
// TODO allow changing the a scroll factor
// Control the UI camera with the arrow keys, and the playground camera with wasd:
(var KEYBOARD_SCROLL_SPEED 200)
(method cameraKeyControl [:FlxCamera camera :Void->Bool leftKey :Void->Bool rightKey :Void->Bool upKey :Void->Bool downKey]
// but not when textInput is focused
(unless (and textInput textInput.hasFocus)
(let [scrollPerSec (/ KEYBOARD_SCROLL_SPEED 60)
&mut :FlxVector movement (new FlxPoint)]
(when (leftKey) (-= movement.x 1))
(when (rightKey) (+= movement.x 1))
(when (upKey) (-= movement.y 1))
(when (downKey) (+= movement.y 1))
(when (< 0 movement.length)
(set movement (movement.normalize)))
(movement.scale scrollPerSec)
(+= camera.scroll.x movement.x)
(+= camera.scroll.y movement.y))))
// don't move the ui camera before ui has been placed -- new UI elements could appear offscreen
(when (> uiGroup.length 0)
(cameraKeyControl uiCamera
->{FlxG.keys.pressed.LEFT}
->{FlxG.keys.pressed.RIGHT}
->{FlxG.keys.pressed.UP}
->{FlxG.keys.pressed.DOWN}))
(cameraKeyControl FlxG.camera
->{FlxG.keys.pressed.A}
->{FlxG.keys.pressed.D}
->{FlxG.keys.pressed.W}
->{FlxG.keys.pressed.S}))
(method :Void typeCommand []
(enterText
"command to run:"
->commandName (controller.tryRunCommand commandName)
Math.POSITIVE_INFINITY))
(prop &mut :ArchiveController controller)
(prop &mut :Archive archive)
(method :Void setController [controller]
(set this.controller controller))
(prop &mut :FlxText textInputLabel null)
(prop &mut :FlxInputText textInput null)
(method :Void enterText [prompt resolve maxLength]
(set textInputLabel (new FlxText 0 0 300 prompt))
(showUI textInputLabel)
(set textInput (new FlxInputText 0 0 300 ""))
(set textInput.hasFocus true)
(set textInput.callback
->:Void [text action]
(case [text action]
([text FlxInputText.ENTER_ACTION]
(set textInput.callback null)
(hideUI textInput)
// This part is hacky...
(set lastUI textInputLabel)
(hideUI textInputLabel)
(resolve text))
//([_ FlxInputText.])
(otherwise {})))
(showUI textInput))
(method :Void enterNumber [prompt resolve min max &opt inStepsOf]
(resolve 0))
(method :Void chooseEntry [prompt :Archive archive resolve]
(resolve null))
(method :Void chooseEntries [prompt archive resolve min max]
(_chooseEntries prompt archive resolve min max []))
// TODO is it possible to resolve with less than max?
(method :Void _chooseEntries [prompt archive resolve min max :Array<Entry> collectedEntries]
(let [&mut :Void->Void chooseNextEntry
null
_chooseNextEntry
->:Void {(chooseEntry
prompt
archive
->:Void e {(collectedEntries.push e)
// If the maximum is reached, return it
(if (= max collectedEntries.length)
(resolve collectedEntries)
// Otherwise, recurse
(chooseNextEntry))})}]
(set chooseNextEntry _chooseNextEntry)
(_chooseNextEntry)))
(method handleChanges [:Archive archive :ChangeSet changeSet]
(doFor e changeSet
// refresh the sprites for entries that changed data.
// Entries whose data changed to remove them from the sprite pool will already have been removed
// by refreshEntry()
(when (spriteSystem.entries.exists e.id)
(when (spriteSystem.sprites.exists e.id)
(spriteSystem.onRemoveEntry archive e))
(spriteSystem.processEntry archive e))))
(prop &mut :Int uiY 0)
(prop &mut :FlxSprite lastUI null)
(method :Void showUI [:FlxSprite ui]
(set ui.y uiY)
(uiGroup.add ui)
(set lastUI ui)
(+= uiY ui.height)
(when (> uiY FlxG.height) (+= uiCamera.scroll.y ui.height)))
(method :Void hideUI [:FlxSprite ui]
(uiGroup.remove ui)
(ui.kill)
(when (= lastUI ui) (-= uiY ui.height)))
(method :Void displayMessage [:String message]
(let [messageText (new FlxText 0 0 0 (message.replace "\n" "|"))]
(showUI messageText)))
(method :Void clearUI []
(uiGroup.kill)
(set uiGroup (new FlxGroup))
(set uiGroup.cameras [uiCamera])
(add uiGroup)
(set uiY 0)
(set uiCamera.scroll.x 0)
(set uiCamera.scroll.y 0))
(method :Void reportError [:String error]
(let [text (new FlxText 0 0 0 (error.replace "\n" "|"))]
(text.setFormat null 8 FlxColor.RED)
(showUI text)))

View File

@@ -0,0 +1,16 @@
import flixel.FlxGame;
import openfl.display.Sprite;
import flixel.FlxState;
import flixel.ui.FlxButton;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.util.FlxColor;
import flixel.input.keyboard.FlxKey;
import flixel.math.FlxPoint;
import flixel.math.FlxVelocity;
import flixel.FlxObject;
import flixel.tile.FlxTilemap;
import flixel.group.FlxGroup;
import flixel.tweens.FlxTween;
import flixel.tweens.FlxEase;
import kiss.Prelude;