(prop :FlxActionDigital continueAction) (prop actionManager (new FlxActionManager)) (prop &mut :Movie movie) (defNew [] (set continueAction (new FlxActionDigital "Continue" onContinue)) // TODO allow configuring continue keys -- any key, specifically mapped keys, etc. (continueAction.addKey SPACE JUST_PRESSED) (continueAction.addMouse LEFT JUST_PRESSED) (actionManager.addAction continueAction) (FlxG.inputs.add actionManager) (set actionManager.resetOnStateSwitch NONE)) (prop &mut :SceneFlxState currentState) (method :Void showScene [:Scene scene :Appearance appearance :Continuation cc] // TODO on the first appearance, give a super (for some scenes but probably not others... hm....) (set currentState (cast scene SceneFlxState)) (FlxG.switchState currentState) (cc)) (var STAGE_LEFT_X 150) (var STAGE_RIGHT_X (- 1280 150)) (var ACTOR_Y 500) (var ACTOR_WIDTH 300) (method :Void showCharacter [:Character character :Appearance appearance :Continuation cc] // TODO on the first appearance, show name and description (maybe? also probably not for all?) // TODO also allow for manually defined flipped frames so text doesn't mirror (set character.actor.flipX ?!(= character.stageFacing character.actor.defaultFacing)) (character.actor.setGraphicSize ACTOR_WIDTH) (set character.actor.x (- (case character.stagePosition (Left STAGE_LEFT_X) (Right STAGE_RIGHT_X)) (/ character.actor.width 2))) (set character.actor.y ACTOR_Y) (currentState.add character.actor) (cc)) (prop &mut :Null nextCC) (method onContinue [:FlxActionDigital continueAction] (whenLet [cc nextCC] (set nextCC null) (cc))) (method :Void startWaitForInput [:Continuation cc] (set nextCC cc)) (method :Void stopWaitForInput [] (set nextCC null)) (var DIALOG_X 300) (var DIALOG_WIDTH (- 1280 ACTOR_WIDTH ACTOR_WIDTH)) (var DIALOG_Y 500) (var DIALOG_HEIGHT (- 720 DIALOG_Y)) // TODO these could be customizable to the Actor (var DIALOG_BOX_COLOR FlxColor.BLACK) (var DIALOG_COLOR FlxColor.WHITE) (var DIALOG_SIZE 24) (var &mut :FlxSprite dialogBox) (var &mut :FlxText dialogText) (var &mut :FlxText speakerNameText) (method showDialog [:String speakerName :SpeechType type :String wryly :String text :Continuation cc] // TODO handle text messages, wrylies, off-screen, from-phone, etc. via (case type) // TODO attribute on-screen dialogue to the character's stageposition // Make a dialog box (unless dialogBox (set dialogBox (new FlxSprite DIALOG_X DIALOG_Y)) (dialogBox.makeGraphic DIALOG_WIDTH DIALOG_HEIGHT DIALOG_BOX_COLOR) (currentState.add dialogBox)) (dialogBox.revive) // show the dialog (unless dialogText // TODO use FlxTypeText to reveal dialog gradually (set dialogText (new FlxText DIALOG_X DIALOG_Y DIALOG_WIDTH "" DIALOG_SIZE)) (currentState.add dialogText)) (set dialogText.text text) // show the speaker name (unless speakerNameText (set speakerNameText (new FlxText DIALOG_X DIALOG_Y DIALOG_WIDTH "" DIALOG_SIZE)) (currentState.add speakerNameText)) (if speakerName { (set speakerNameText.text "${speakerName}:") (speakerNameText.revive) (set dialogText.y (+ DIALOG_Y speakerNameText.height)) } (set dialogText.y DIALOG_Y)) (dialogText.revive) // wait for input or delay // TODO customize the delay in a more sophisticated way to the dialog length or voice-over length, // or rely on FlxTypeText to add breathing room (movie.delay .length (text.split " ") ->{ (dialogText.kill) (speakerNameText.kill) (dialogBox.kill) (cc) })) (method :Void playSound [:FlxSound sound :Float volumeMod :Bool waitForEnd :Continuation cc] (let [originalVolume sound.volume restoreOriginalVolume ->(set sound.volume originalVolume)] (*= sound.volume volumeMod) (set sound.onComplete (if waitForEnd ->{(restoreOriginalVolume) (cc)} restoreOriginalVolume))) (sound.play) (unless waitForEnd (cc))) (prop &mut :FlxSound music) (prop MUSIC_FADE_SEC 1) (prop MUSIC_FADE_STEPS 10) (method :Void playSong [:String song :Float volumeMod :Bool loop :Bool waitForEnd :Continuation cc] (set music (FlxG.sound.play song 0 loop null true (if waitForEnd cc ->{}))) (.start (new FlxTimer) (/ MUSIC_FADE_SEC MUSIC_FADE_STEPS) ->:Void _ (+= music.volume (/ volumeMod MUSIC_FADE_STEPS)) MUSIC_FADE_STEPS) (set music.persist true) (unless waitForEnd (cc))) (method :Void stopSong [] (when music (music.stop)))