Overhaul hollywoo & hollywoo-flixel. Close #178
This commit is contained in:
@@ -5,6 +5,7 @@ import kiss.List;
|
||||
import kiss.FuzzyMap;
|
||||
import flixel.FlxSprite;
|
||||
import hollywoo_flixel.FlxMovie;
|
||||
import hollywoo.Director;
|
||||
|
||||
typedef AnimationArgs = {
|
||||
frames:Array<Int>,
|
||||
|
@@ -1,11 +1,15 @@
|
||||
(prop :FlxStageFacing defaultFacing)
|
||||
(loadFrom "hollywoo-flixel" "src/hollywoo_flixel/Aliases.kiss")
|
||||
|
||||
(prop :StageFacing defaultFacing)
|
||||
|
||||
(prop :FuzzyMap<String> animationNames (new FuzzyMap<String>))
|
||||
|
||||
(defNew [&prop :String assetPath &opt frameWidth frameHeight :FlxStageFacing defaultFacing :Map<String,AnimationArgs> animations]
|
||||
(prop :Float z 0)
|
||||
|
||||
(defNew [&prop :String assetPath &opt frameWidth frameHeight :StageFacing defaultFacing :Map<String,AnimationArgs> animations]
|
||||
(super)
|
||||
|
||||
(set this.defaultFacing (or defaultFacing Right))
|
||||
(set this.defaultFacing (or defaultFacing FacingRight))
|
||||
|
||||
(if (and frameWidth frameHeight)
|
||||
(loadGraphic assetPath true frameWidth frameHeight)
|
||||
|
@@ -0,0 +1,6 @@
|
||||
(defAlias &ident Left "Left")
|
||||
(defAlias &ident LeftBehind "Left2")
|
||||
(defAlias &ident Right "Right")
|
||||
(defAlias &ident RightBehind "Right2")
|
||||
(defAlias &ident FacingLeft (TowardsPosition "OffScreenLeft"))
|
||||
(defAlias &ident FacingRight (TowardsPosition "OffScreenRight"))
|
@@ -7,6 +7,7 @@ import flixel.FlxSprite;
|
||||
import flixel.input.actions.FlxAction;
|
||||
import flixel.input.actions.FlxActionManager;
|
||||
import flixel.input.mouse.FlxMouseButton;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.tweens.FlxTween;
|
||||
import hollywoo.Movie;
|
||||
import hollywoo.Scene;
|
||||
@@ -18,6 +19,7 @@ import flixel.system.FlxSound;
|
||||
import flixel.util.FlxTimer;
|
||||
import haxe.Constraints;
|
||||
import kiss_flixel.SpriteTools;
|
||||
import haxe.ds.Option;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class FlxDirector implements Director<String, FlxStagePosition, FlxStageFacing, FlxScreenPosition, ActorFlxSprite, FlxSound, String, FlxSprite, FlxSound> {}
|
||||
class FlxDirector implements Director<FlxSprite, FlxScreenPosition, ActorFlxSprite, FlxSound, String, FlxSprite, FlxSound> {}
|
||||
|
@@ -1,6 +1,10 @@
|
||||
(prop :FlxActionDigital continueAction)
|
||||
(prop actionManager (new FlxActionManager))
|
||||
(prop &mut :Movie<String,FlxStagePosition,FlxStageFacing,FlxScreenPosition,ActorFlxSprite,FlxSound,String,FlxSprite,FlxSound> movie)
|
||||
(prop &mut :Movie<FlxSprite,FlxScreenPosition,ActorFlxSprite,FlxSound,String,FlxSprite,FlxSound> movie)
|
||||
(loadFrom "hollywoo-flixel" "src/hollywoo_flixel/Aliases.kiss")
|
||||
|
||||
(prop :Array<FlxTypedGroup<FlxSprite>> spriteLayers [])
|
||||
(var LAYER_MAX 5)
|
||||
|
||||
(defNew []
|
||||
(set continueAction (new FlxActionDigital "Continue" onContinue))
|
||||
@@ -9,111 +13,62 @@
|
||||
(continueAction.addMouse LEFT JUST_PRESSED)
|
||||
(actionManager.addAction continueAction)
|
||||
(FlxG.inputs.add actionManager)
|
||||
(set actionManager.resetOnStateSwitch NONE))
|
||||
(set actionManager.resetOnStateSwitch NONE)
|
||||
|
||||
(prop &mut :SceneFlxState currentState)
|
||||
(method :Void showScene [:Scene<String,FlxStagePosition,FlxStageFacing,FlxScreenPosition,ActorFlxSprite,FlxSprite> scene :Appearance appearance :Continuation cc]
|
||||
// Close the last scene state
|
||||
(when currentState
|
||||
(currentState.close))
|
||||
// TODO on the first appearance, give a super (for some scenes but probably not others... hm....)
|
||||
(set currentState (cast scene SceneFlxState))
|
||||
(set currentState.parent FlxG.state)
|
||||
(FlxG.state.openSubState currentState)
|
||||
// Re-show characters in case their actor sprites were moved in different scenes:
|
||||
(doFor =>name character currentState.characters
|
||||
(showCharacter character ReAppearance ->:Void {}))
|
||||
// TODO characters will be in front of every prop layer -- characters need their own group layer
|
||||
(doFor i (range LAYER_MAX)
|
||||
(let [g (new FlxTypedGroup<FlxSprite>)]
|
||||
(spriteLayers.push g)
|
||||
(FlxG.state.add g))))
|
||||
|
||||
(method :Void showSet [:FlxSprite setSprite :SceneTime time :ScenePerspective perspective :Appearance appearance :Continuation cc]
|
||||
(setSprite.setGraphicSize FlxG.width)
|
||||
(when (> setSprite.height FlxG.height)
|
||||
(setSprite.setGraphicSize 0 FlxG.height))
|
||||
(setSprite.updateHitbox)
|
||||
(setSprite.screenCenter)
|
||||
(FlxG.state.add setSprite)
|
||||
(cc))
|
||||
|
||||
(method :Void cleanup []
|
||||
(FlxG.state.openSubState null))
|
||||
(method :Void hideSet [:FlxSprite set :Continuation cc]
|
||||
(FlxG.state.remove set)
|
||||
(cc))
|
||||
|
||||
(var STAGE_LEFT_X 150)
|
||||
(var STAGE_RIGHT_X (- 1280 150))
|
||||
(var STAGE_BEHIND_DY -250)
|
||||
(var ACTOR_Y 500)
|
||||
(method :Void cleanup [] 0)
|
||||
|
||||
(var STAGE_LEFT_X 150.0)
|
||||
(var STAGE_RIGHT_X (- FlxG.width STAGE_LEFT_X))
|
||||
(var STAGE_BEHIND_DY 250.0)
|
||||
|
||||
(prop :Option<AutoZConfig> autoZConfig (Some (object zPerLayer STAGE_BEHIND_DY frontLayer 0)))
|
||||
|
||||
(var ACTOR_Y 500.0)
|
||||
(var ACTOR_WIDTH 300)
|
||||
|
||||
(method :Void showCharacter [:Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite> character :Appearance appearance :Continuation cc]
|
||||
(method :Void showCharacter [:Character<ActorFlxSprite> 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 on clothing doesn't mirror
|
||||
(set character.actor.flipX ?!(= character.stageFacing character.actor.defaultFacing))
|
||||
// All actors same width, display centered on x
|
||||
(character.actor.setGraphicSize ACTOR_WIDTH)
|
||||
(character.actor.updateHitbox)
|
||||
(ifLet [(FullControl layer rpos) character.stagePosition]
|
||||
{
|
||||
(assert (<= 0 layer SceneFlxState.LAYER_MAX) "Layer $layer is out of range 0-$SceneFlxState.LAYER_MAX")
|
||||
(SpriteTools.scaleStampOn character.actor (canvas) rpos)
|
||||
(let [[x y] (SpriteTools.positionOn character.actor (canvas) rpos)]
|
||||
(set character.actor.x x)
|
||||
(set character.actor.y y)
|
||||
(if (= layer SceneFlxState.LAYER_MAX)
|
||||
// In front of everything:
|
||||
(currentState.add character.actor)
|
||||
(.add (nth currentState.spriteLayers layer) character.actor)))
|
||||
}
|
||||
{
|
||||
(set character.actor.x
|
||||
(- (case character.stagePosition
|
||||
(Left
|
||||
(set currentState.actorOnLeft character.actor)
|
||||
(set currentState.characterOnLeft character)
|
||||
STAGE_LEFT_X)
|
||||
(LeftBehind
|
||||
STAGE_LEFT_X)
|
||||
(Right
|
||||
(set currentState.actorOnRight character.actor)
|
||||
(set currentState.characterOnRight character)
|
||||
STAGE_RIGHT_X)
|
||||
(RightBehind
|
||||
STAGE_RIGHT_X)
|
||||
(otherwise (throw "unsupported stage position")))
|
||||
(/ character.actor.width 2)))
|
||||
(set character.actor.y ACTOR_Y)
|
||||
(let [bottom (+ character.actor.y character.actor.height)]
|
||||
(when (> bottom 720)
|
||||
(-= character.actor.y (- bottom 720))))
|
||||
(let [&mut reAddFront false]
|
||||
(case character.stagePosition
|
||||
((or LeftBehind RightBehind)
|
||||
(set reAddFront true)
|
||||
(+= character.actor.y STAGE_BEHIND_DY))
|
||||
(otherwise))
|
||||
(when reAddFront
|
||||
(when currentState.actorOnLeft (currentState.remove currentState.actorOnLeft))
|
||||
(when currentState.actorOnRight (currentState.remove currentState.actorOnRight)))
|
||||
(currentState.add character.actor)
|
||||
(when reAddFront
|
||||
(when currentState.actorOnLeft (currentState.add currentState.actorOnLeft))
|
||||
(when currentState.actorOnRight (currentState.add currentState.actorOnRight))))
|
||||
})
|
||||
(set character.actor.x
|
||||
(- character.stagePosition.x
|
||||
(/ character.actor.width 2)))
|
||||
(set character.actor.y character.stagePosition.y)
|
||||
// Bump sprites up from the bottom if they're too tall
|
||||
(let [bottom (+ character.actor.y character.actor.height)]
|
||||
(when (> bottom FlxG.height)
|
||||
(-= character.actor.y (- bottom FlxG.height))))
|
||||
// Display with y adjusted by z:
|
||||
(-= character.actor.y character.stagePosition.z)
|
||||
(FlxG.state.add character.actor)
|
||||
(cc))
|
||||
|
||||
(method :Void hideCharacter [:Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite> character :Continuation cc]
|
||||
(when (= currentState.actorOnLeft character.actor)
|
||||
(set currentState.actorOnLeft null)
|
||||
(set currentState.characterOnLeft null))
|
||||
(when (= currentState.actorOnRight character.actor)
|
||||
(set currentState.actorOnRight null)
|
||||
(set currentState.characterOnRight null))
|
||||
(currentState.remove character.actor)
|
||||
(method :Void hideCharacter [:Character<ActorFlxSprite> character :Continuation cc]
|
||||
(FlxG.state.remove character.actor)
|
||||
(cc))
|
||||
|
||||
(method :Void moveCharacter [:Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite> character toPos toFacing :Continuation cc]
|
||||
// Directors don't have to change the character, but FlxDirector does because that state determines
|
||||
// where actors are drawn in showCharacter:
|
||||
(set character.stagePosition toPos)
|
||||
(set character.stageFacing toFacing)
|
||||
(hideCharacter character
|
||||
->:Void (showCharacter character ReAppearance cc)))
|
||||
|
||||
(method :Void swapCharacters [:Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite> a :Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite> b :Continuation cc]
|
||||
(let [noCC ->:Void {}
|
||||
tempStagePos a.stagePosition
|
||||
tempStageFacing a.stageFacing]
|
||||
(moveCharacter a b.stagePosition b.stageFacing noCC)
|
||||
(moveCharacter b tempStagePos tempStageFacing cc)))
|
||||
|
||||
(prop &mut :Null<Continuation> nextCC)
|
||||
(method onContinue [:FlxActionDigital continueAction]
|
||||
(whenLet [cc nextCC]
|
||||
@@ -134,23 +89,24 @@
|
||||
(prop &mut :FlxSprite titleCard null)
|
||||
(method :Void showTitleCard [:Array<String> text :Continuation cc]
|
||||
(set titleCard (new FlxSprite))
|
||||
(titleCard.makeGraphic 1280 720 FlxColor.BLACK true)
|
||||
(titleCard.makeGraphic FlxG.width FlxG.height FlxColor.BLACK true)
|
||||
(SpriteTools.writeOnSprite (text.shift) TITLE_SIZE titleCard (object x (Percent 0.5) y (Pixels TITLE_Y)))
|
||||
(localVar &mut subtitleY (+ TITLE_Y TITLE_SIZE TITLE_MARGIN))
|
||||
(doFor subtitle text
|
||||
(SpriteTools.writeOnSprite subtitle SUBTITLES_SIZE titleCard (object x (Percent 0.5) y (Pixels subtitleY)))
|
||||
(+= subtitleY SUBTITLES_SIZE SUBTITLES_MARGIN))
|
||||
(currentState.add titleCard)
|
||||
(FlxG.state.add titleCard)
|
||||
// Allow skipping
|
||||
(startWaitForInput cc))
|
||||
|
||||
(method :Void hideTitleCard []
|
||||
(currentState.remove titleCard))
|
||||
(FlxG.state.remove titleCard))
|
||||
|
||||
(var DIALOG_X 300)
|
||||
(var DIALOG_WIDTH (- 1280 ACTOR_WIDTH ACTOR_WIDTH))
|
||||
(var DIALOG_Y 500)
|
||||
(var DIALOG_HEIGHT (- 720 DIALOG_Y))
|
||||
// Make these aliases so they get FlxG.width's current value when queried (not 0 at start time)
|
||||
(defAlias &ident DIALOG_WIDTH (- FlxG.width ACTOR_WIDTH ACTOR_WIDTH))
|
||||
(defAlias &ident DIALOG_HEIGHT (- FlxG.height DIALOG_Y))
|
||||
// TODO these could be customizable to the Actor, wrylies, etc.
|
||||
(var DIALOG_BOX_COLOR FlxColor.BLACK)
|
||||
(var DIALOG_COLOR FlxColor.WHITE)
|
||||
@@ -160,29 +116,17 @@
|
||||
(var &mut :FlxText dialogText)
|
||||
(var &mut :FlxText speakerNameText)
|
||||
|
||||
(method showDialog [:String speakerName :SpeechType<FlxStagePosition,FlxStageFacing,ActorFlxSprite> type :String wryly :String text :Continuation cc]
|
||||
(method showDialog [:String speakerName :SpeechType<ActorFlxSprite> 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
|
||||
|
||||
// When an actor is associated with the line, check for an animation matching the wryly
|
||||
// TODO allow sounds for wrylies, like the dispatch click
|
||||
(localVar &mut nameOnRight false)
|
||||
(case type
|
||||
((OnScreen character)
|
||||
(case character.stagePosition
|
||||
((or Right RightBehind) (set nameOnRight true))
|
||||
(otherwise))
|
||||
// If the character is behind another character, swap them so the speaker is front
|
||||
(case character.stagePosition
|
||||
(LeftBehind
|
||||
(if currentState.characterOnLeft
|
||||
(swapCharacters character currentState.characterOnLeft ->:Void {}))
|
||||
(moveCharacter character Left character.stageFacing ->:Void {}))
|
||||
(RightBehind
|
||||
(if currentState.characterOnRight
|
||||
(swapCharacters character currentState.characterOnRight ->:Void {}))
|
||||
(moveCharacter character Right character.stageFacing ->:Void {}))
|
||||
(otherwise))
|
||||
(when (> character.stagePosition.x (/ FlxG.width 2))
|
||||
(set nameOnRight true))
|
||||
// When an actor is associated with the line, check for an animation matching the wryly
|
||||
(let [actor (the ActorFlxSprite character.actor)]
|
||||
(if wryly
|
||||
(actor.playAnimation wryly)
|
||||
@@ -198,23 +142,23 @@
|
||||
(set dialogBox (new FlxSprite DIALOG_X DIALOG_Y))
|
||||
(dialogBox.makeGraphic DIALOG_WIDTH DIALOG_HEIGHT DIALOG_BOX_COLOR))
|
||||
|
||||
(currentState.add dialogBox)
|
||||
(FlxG.state.add dialogBox)
|
||||
(dialogBox.revive)
|
||||
// show the dialog
|
||||
(unless dialogText
|
||||
(set dialogText (new FlxText DIALOG_X DIALOG_Y DIALOG_WIDTH "" DIALOG_SIZE)))
|
||||
(currentState.add dialogText)
|
||||
(FlxG.state.add dialogText)
|
||||
(set dialogText.text text)
|
||||
// TODO actually page through the dialog instead of sizing it down?
|
||||
// ^ though that doesn't work automatically with VO unless individual word times are kept in the json
|
||||
// (which would be really clunky)
|
||||
(set dialogText.size DIALOG_SIZE)
|
||||
(while (< 720 (+ dialogText.y dialogText.height))
|
||||
(while (< FlxG.height (+ dialogText.y dialogText.height))
|
||||
(-= dialogText.size 6))
|
||||
// show the speaker name
|
||||
(unless speakerNameText
|
||||
(set speakerNameText (new FlxText DIALOG_X DIALOG_Y 0 "" DIALOG_SIZE)))
|
||||
(currentState.add speakerNameText)
|
||||
(FlxG.state.add speakerNameText)
|
||||
(if speakerName
|
||||
{
|
||||
(set speakerNameText.text "${speakerName}:")
|
||||
@@ -277,12 +221,12 @@
|
||||
(var PROP_MAX_WIDTH 500)
|
||||
|
||||
(method :Void quickShowPropOnScreen [:FlxSprite prop :FlxScreenPosition position :Continuation cc]
|
||||
(let [left (/ 1280 6)
|
||||
right (- 1280 left)
|
||||
upper (/ 720 6)
|
||||
lower (- 720 upper)
|
||||
centerX (/ 1280 2)
|
||||
centerY (/ 720 2)
|
||||
(let [left (/ FlxG.width 6)
|
||||
right (- FlxG.width left)
|
||||
upper (/ FlxG.height 6)
|
||||
lower (- FlxG.height upper)
|
||||
centerX (/ FlxG.width 2)
|
||||
centerY (/ FlxG.height 2)
|
||||
[x y]
|
||||
(case position
|
||||
(Center [centerX centerY])
|
||||
@@ -317,7 +261,7 @@
|
||||
(-= prop.y (- propBottom FlxG.height))))
|
||||
(otherwise)))
|
||||
|
||||
(currentState.add prop)))
|
||||
(FlxG.state.add prop)))
|
||||
(cc))
|
||||
|
||||
(prop &mut :FlxSprite _canvas null)
|
||||
@@ -328,15 +272,15 @@
|
||||
_canvas)
|
||||
|
||||
(method :Void smartShowPropOnScreen [:FlxSprite prop :Int layer :RelativePosition rpos :Continuation cc]
|
||||
(assert (<= 0 layer SceneFlxState.LAYER_MAX) "Layer $layer is out of range 0-$SceneFlxState.LAYER_MAX")
|
||||
(assert (<= 0 layer LAYER_MAX) "Layer $layer is out of range 0-$LAYER_MAX")
|
||||
(SpriteTools.scaleStampOn prop (canvas) rpos)
|
||||
(let [[x y] (SpriteTools.positionOn prop (canvas) rpos)]
|
||||
(set prop.x x)
|
||||
(set prop.y y)
|
||||
(if (= layer SceneFlxState.LAYER_MAX)
|
||||
(if (= layer LAYER_MAX)
|
||||
// In front of everything:
|
||||
(currentState.add prop)
|
||||
(.add (nth currentState.spriteLayers layer) prop)))
|
||||
(FlxG.state.add prop)
|
||||
(.add (nth spriteLayers layer) prop)))
|
||||
(cc))
|
||||
|
||||
(method :Void showPropOnScreen [:FlxSprite prop :FlxScreenPosition position :Continuation cc]
|
||||
@@ -346,8 +290,8 @@
|
||||
(quickShowPropOnScreen prop position cc)))
|
||||
|
||||
(method :Void hideProp [:FlxSprite prop cc]
|
||||
(currentState.remove prop)
|
||||
(doFor layer currentState.spriteLayers
|
||||
(FlxG.state.remove prop)
|
||||
(doFor layer spriteLayers
|
||||
(layer.remove prop))
|
||||
(cc))
|
||||
|
||||
@@ -360,19 +304,19 @@
|
||||
(prop &mut :FlxSprite blackBG null)
|
||||
(method :Void showBlackScreen []
|
||||
(set blackBG (new FlxSprite))
|
||||
(blackBG.makeGraphic 1280 720 FlxColor.BLACK true)
|
||||
(currentState.add blackBG))
|
||||
(blackBG.makeGraphic FlxG.width FlxG.height FlxColor.BLACK true)
|
||||
(FlxG.state.add blackBG))
|
||||
|
||||
(method :Void hideBlackScreen []
|
||||
(currentState.remove blackBG))
|
||||
(FlxG.state.remove blackBG))
|
||||
|
||||
// TODO maybe credits need their own substate so an after-credits scene could be done.
|
||||
// currently the bg will cover whatever the final scene was.
|
||||
(method :Void rollCredits [:Array<CreditsLine> credits cc]
|
||||
(localVar bg (new FlxSprite))
|
||||
(bg.makeGraphic 1280 720 FlxColor.BLACK true)
|
||||
(currentState.add bg)
|
||||
(localVar &mut textY 720)
|
||||
(bg.makeGraphic FlxG.width FlxG.height FlxColor.BLACK true)
|
||||
(FlxG.state.add bg)
|
||||
(localVar &mut textY FlxG.height)
|
||||
(var oneColSize 64)
|
||||
(var twoColSize 48)
|
||||
(var threeColSize 32)
|
||||
@@ -392,9 +336,9 @@
|
||||
((TwoColumn col1 col2)
|
||||
(let [t1 (_ctext col1 twoColSize)
|
||||
t2 (_ctext col2 twoColSize)]
|
||||
(set t1.x (- (* 1280 0.3) t1.width (/ twoColumnGap 2)))
|
||||
(set t1.x (- (* FlxG.width 0.3) t1.width (/ twoColumnGap 2)))
|
||||
(set t1.y textY)
|
||||
(set t2.x (+ (* 1280 0.3) (/ twoColumnGap 2)))
|
||||
(set t2.x (+ (* FlxG.width 0.3) (/ twoColumnGap 2)))
|
||||
(set t2.y textY))
|
||||
(+= textY twoColSize creditMargin))
|
||||
// Left-justified, centered, right-justified three column lines
|
||||
@@ -406,11 +350,11 @@
|
||||
(set t1.y textY)
|
||||
(t2.screenCenter)
|
||||
(set t2.y textY)
|
||||
(set t3.x (- 1280 creditMargin t3.width))
|
||||
(set t3.x (- FlxG.width creditMargin t3.width))
|
||||
(set t3.y textY))
|
||||
(+= textY threeColSize creditMargin))
|
||||
(otherwise)))
|
||||
|
||||
(doFor text creditsText
|
||||
(currentState.add text)
|
||||
(FlxG.state.add text)
|
||||
(FlxTween.linearMotion text text.x text.y text.x (- text.y textY) 200 false (object onComplete ->:Void _ (cc)))))
|
@@ -3,12 +3,13 @@ package hollywoo_flixel;
|
||||
import flixel.FlxState;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.system.FlxSound;
|
||||
import hollywoo.Director;
|
||||
import hollywoo.Movie;
|
||||
import hollywoo_flixel.ActorFlxSprite;
|
||||
import hollywoo_flixel.SceneFlxState;
|
||||
import kiss_flixel.SpriteTools;
|
||||
import openfl.Assets;
|
||||
|
||||
/*
|
||||
enum FlxStagePosition {
|
||||
Left;
|
||||
Right;
|
||||
@@ -19,11 +20,7 @@ enum FlxStagePosition {
|
||||
// AND don't move the object automatically for any reason
|
||||
FullControl(layer:Int, pos:RelativePosition);
|
||||
}
|
||||
|
||||
enum FlxStageFacing {
|
||||
Left;
|
||||
Right;
|
||||
}
|
||||
*/
|
||||
|
||||
enum FlxScreenPosition {
|
||||
// Shortcuts
|
||||
@@ -42,7 +39,7 @@ enum FlxScreenPosition {
|
||||
/**
|
||||
* Model/controller of a Hollywoo-Flixel film, and main execution script
|
||||
*/
|
||||
class FlxMovie extends Movie<String, FlxStagePosition, FlxStageFacing, FlxScreenPosition, ActorFlxSprite, FlxSound, String, FlxSprite, FlxSound> {
|
||||
class FlxMovie extends Movie<FlxSprite, FlxScreenPosition, ActorFlxSprite, FlxSound, String, FlxSprite, FlxSound> {
|
||||
// Think of HollywooFlixelDSL.kiss as the corresponding Kiss file for this class!
|
||||
|
||||
public function new(director:FlxDirector, ?voiceLinesAssetPath:String) {
|
||||
@@ -50,6 +47,28 @@ class FlxMovie extends Movie<String, FlxStagePosition, FlxStageFacing, FlxScreen
|
||||
if (voiceLinesAssetPath != null) {
|
||||
voiceLinesJson = Assets.getText(voiceLinesAssetPath);
|
||||
}
|
||||
|
||||
super(director, voiceLinesJson);
|
||||
|
||||
stagePositions["Left"] = {
|
||||
x: FlxDirector.STAGE_LEFT_X,
|
||||
y: FlxDirector.ACTOR_Y,
|
||||
z: 0.0
|
||||
};
|
||||
stagePositions["Right"] = {
|
||||
x: FlxDirector.STAGE_RIGHT_X,
|
||||
y: FlxDirector.ACTOR_Y,
|
||||
z: 0.0
|
||||
};
|
||||
stagePositions["Left2"] = {
|
||||
x: FlxDirector.STAGE_LEFT_X,
|
||||
y: FlxDirector.ACTOR_Y,
|
||||
z: FlxDirector.STAGE_BEHIND_DY
|
||||
};
|
||||
stagePositions["Right2"] = {
|
||||
x: FlxDirector.STAGE_RIGHT_X,
|
||||
y: FlxDirector.ACTOR_Y,
|
||||
z: FlxDirector.STAGE_BEHIND_DY
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -2,16 +2,12 @@
|
||||
|
||||
(defMacroVar subclass true)
|
||||
(loadFrom "hollywoo" "src/hollywoo/Movie.kiss")
|
||||
(loadFrom "hollywoo-flixel" "src/hollywoo_flixel/Aliases.kiss")
|
||||
|
||||
(method newFlxScene [name set time perspective]
|
||||
(method newFlxSet [name assetPath]
|
||||
(let [setSprite (new FlxSprite 0 0)]
|
||||
(setSprite.loadGraphic (dictGet sets set) false 0 0 true) // Load uniquely so we can draw on sets for specific scenes
|
||||
(newScene name (cast (new SceneFlxState setSprite time perspective)))))
|
||||
|
||||
// Destroy substates when the movie end is reached:
|
||||
(cleanup
|
||||
(doFor =>name scene scenes
|
||||
(.destroy (cast scene SceneFlxState))))
|
||||
(setSprite.loadGraphic assetPath false 0 0 true) // Load uniquely so we can draw on sets for specific scenes
|
||||
(newSet name setSprite)))
|
||||
|
||||
(method newFlxSound [name path &opt :Float volume]
|
||||
(set volume (or volume 1))
|
||||
@@ -56,41 +52,11 @@
|
||||
(localVar buttonsPerColumn 25)
|
||||
(doFor [num label] (enumerate (sort (collect (runners.keys))))
|
||||
(let [runner (dictGet runners label)
|
||||
b (new flixel.ui.FlxButton 0 buttonY label ->{(.remove (cast (_currentScene) SceneFlxState) buttons)(runner)})]
|
||||
b (new flixel.ui.FlxButton 0 buttonY label ->{(FlxG.state.remove buttons)(runner)})]
|
||||
(let [column (Std.int (/ num buttonsPerColumn))]
|
||||
(set b.x (* b.width column)))
|
||||
(buttons.add b))
|
||||
(+= buttonY 20)
|
||||
(when (= (- buttonsPerColumn 1) (% num buttonsPerColumn))
|
||||
(set buttonY 0)))
|
||||
(.add (cast (_currentScene) SceneFlxState) buttons)))
|
||||
|
||||
(defMacro withProp [propKey name &body body]
|
||||
`(let [,name (dictGet props ,propKey)]
|
||||
,@body
|
||||
(cc)))
|
||||
|
||||
// like withProp, but you promise to call CC yourself in the body:
|
||||
(defMacro withPropCC [propKey name &body body]
|
||||
`(let [,name (dictGet props ,propKey)]
|
||||
,@body))
|
||||
|
||||
(defMacro withActor [actorKey name &body body]
|
||||
`(let [,name (dictGet actors ,actorKey)]
|
||||
,@body
|
||||
(cc)))
|
||||
|
||||
// like withActor, but you promise to call CC yourself in the body:
|
||||
(defMacro withActorCC [actorKey name &body body]
|
||||
`(let [,name (dictGet actors ,actorKey)]
|
||||
,@body))
|
||||
|
||||
(defMacro withSet [sceneKey name &body body]
|
||||
`(let [,name .setSprite (cast (dictGet scenes ,sceneKey) SceneFlxState)]
|
||||
,@body
|
||||
(cc)))
|
||||
|
||||
// like withSet, but you promise to call CC yourself in the body:
|
||||
(defMacro withSetCC [sceneKey name &body body]
|
||||
`(let [,name .setSprite (cast (dictGet scenes ,sceneKey) SceneFlxState)]
|
||||
,@body))
|
||||
(FlxG.state.add buttons)))
|
@@ -1,15 +0,0 @@
|
||||
package hollywoo_flixel;
|
||||
|
||||
import kiss.Prelude;
|
||||
import kiss.List;
|
||||
import kiss.FuzzyMap;
|
||||
import flixel.FlxSubState;
|
||||
import flixel.FlxState;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.FlxG;
|
||||
import hollywoo.Scene;
|
||||
import hollywoo_flixel.FlxMovie;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class SceneFlxState extends FlxSubState {}
|
@@ -1,36 +0,0 @@
|
||||
// Track which actors are in FRONT of the stage so actors can appear behind them
|
||||
(prop &mut :ActorFlxSprite actorOnLeft null)
|
||||
(prop &mut :Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite> characterOnLeft null)
|
||||
(prop &mut :ActorFlxSprite actorOnRight null)
|
||||
(prop &mut :Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite> characterOnRight null)
|
||||
|
||||
// Track props in an arbitrary number of layers
|
||||
(prop :Array<FlxTypedGroup<FlxSprite>> spriteLayers [])
|
||||
(var LAYER_MAX 5)
|
||||
|
||||
(defNew [&prop :FlxSprite setSprite &prop :SceneTime time &prop :ScenePerspective perspective]
|
||||
[
|
||||
&mut :FlxState parent null
|
||||
:FuzzyMap<Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite>> characters (new FuzzyMap<Character<FlxStagePosition,FlxStageFacing,ActorFlxSprite>>)
|
||||
:Map<FlxSprite,FlxScreenPosition> propsOnScreen (new Map)
|
||||
]
|
||||
(super)
|
||||
(add setSprite)
|
||||
// TODO characters will be in front of every prop layer -- characters need their own group layer
|
||||
(doFor i (range LAYER_MAX)
|
||||
(let [g (new FlxTypedGroup<FlxSprite>)]
|
||||
(spriteLayers.push g)
|
||||
(add g))))
|
||||
|
||||
(method &override :Void create []
|
||||
(super.create)
|
||||
(setSprite.setGraphicSize FlxG.width)
|
||||
(when (> setSprite.height FlxG.height)
|
||||
(setSprite.setGraphicSize 0 FlxG.height))
|
||||
(setSprite.updateHitbox)
|
||||
(setSprite.screenCenter))
|
||||
|
||||
(method &override :Void update [:Float elapsed]
|
||||
(when parent
|
||||
(parent.update elapsed))
|
||||
(super.update elapsed))
|
@@ -2,6 +2,7 @@ package hollywoo;
|
||||
|
||||
import hollywoo.Scene;
|
||||
import hollywoo.Movie;
|
||||
import haxe.ds.Option;
|
||||
|
||||
enum Appearance {
|
||||
FirstAppearance;
|
||||
@@ -10,13 +11,31 @@ enum Appearance {
|
||||
|
||||
typedef Continuation = Void -> Void;
|
||||
|
||||
interface Director<Set, StagePosition, StageFacing, ScreenPosition, Actor, Sound, Song, Prop, VoiceTrack> {
|
||||
var movie(default, default):Movie<Set, StagePosition, StageFacing, ScreenPosition, Actor, Sound, Song, Prop, VoiceTrack>;
|
||||
function showScene(scene:Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor, Prop>, appearance:Appearance, cc:Continuation):Void;
|
||||
function showCharacter(character:Character<StagePosition, StageFacing, Actor>, appearance:Appearance, cc:Continuation):Void;
|
||||
function hideCharacter(character:Character<StagePosition, StageFacing, Actor>, cc:Continuation):Void;
|
||||
function moveCharacter(character:Character<StagePosition, StageFacing, Actor>, toPos:StagePosition, toFacing:StageFacing, cc:Continuation):Void;
|
||||
function swapCharacters(a:Character<StagePosition, StageFacing, Actor>, b:Character<StagePosition, StageFacing, Actor>, cc:Continuation):Void;
|
||||
typedef StagePosition = {
|
||||
x:Float,
|
||||
y:Float,
|
||||
z:Float,
|
||||
};
|
||||
|
||||
enum StageFacing {
|
||||
TowardsCharacter(name:String);
|
||||
AwayFromCharacter(name:String);
|
||||
TowardsPosition(name:String);
|
||||
AwayFromPosition(name:String);
|
||||
}
|
||||
|
||||
typedef AutoZConfig = {
|
||||
zPerLayer:Float,
|
||||
frontLayer:Int
|
||||
};
|
||||
|
||||
interface Director<Set:Cloneable<Set>, ScreenPosition, Actor, Sound, Song, Prop, VoiceTrack> {
|
||||
var movie(default, default):Movie<Set, ScreenPosition, Actor, Sound, Song, Prop, VoiceTrack>;
|
||||
var autoZConfig(default,null):Option<AutoZConfig>;
|
||||
function showSet(set:Set, time:SceneTime, perspective:ScenePerspective, appearance:Appearance, cc:Continuation):Void;
|
||||
function hideSet(set:Set, cc:Continuation):Void;
|
||||
function showCharacter(character:Character<Actor>, appearance:Appearance, cc:Continuation):Void;
|
||||
function hideCharacter(character:Character<Actor>, cc:Continuation):Void;
|
||||
function playSound(sound:Sound, volumeMod:Float, waitForEnd:Bool, cc:Continuation):Void;
|
||||
function stopSound(sound:Sound):Void;
|
||||
function playSong(song:Song, volumeMod:Float, loop:Bool, waitForEnd:Bool, cc:Continuation):Void;
|
||||
@@ -25,7 +44,7 @@ interface Director<Set, StagePosition, StageFacing, ScreenPosition, Actor, Sound
|
||||
function stopVoiceTrack(track:VoiceTrack):Void;
|
||||
function startWaitForInput(cc:Continuation):Void;
|
||||
function stopWaitForInput():Void;
|
||||
function showDialog(speakerName:String, type:SpeechType<StagePosition, StageFacing, Actor>, wryly:String, dialog:String, cc:Continuation):Void;
|
||||
function showDialog(speakerName:String, type:SpeechType<Actor>, wryly:String, dialog:String, cc:Continuation):Void;
|
||||
function hideDialog():Void;
|
||||
function showTitleCard(text:Array<String>, cc:Continuation):Void;
|
||||
function hideTitleCard():Void;
|
||||
|
@@ -1,3 +1,34 @@
|
||||
(defMacro withProp [propKey name &body body]
|
||||
`(let [,name (dictGet props ,propKey)]
|
||||
,@body
|
||||
(cc)))
|
||||
|
||||
// like withProp, but you promise to call CC yourself in the body:
|
||||
(defMacro withPropCC [propKey name &body body]
|
||||
`(let [,name (dictGet props ,propKey)]
|
||||
,@body))
|
||||
|
||||
(defMacro withActor [actorKey name &body body]
|
||||
`(let [,name (dictGet actors ,actorKey)]
|
||||
,@body
|
||||
(cc)))
|
||||
|
||||
// like withActor, but you promise to call CC yourself in the body:
|
||||
(defMacro withActorCC [actorKey name &body body]
|
||||
`(let [,name (dictGet actors ,actorKey)]
|
||||
,@body))
|
||||
|
||||
// Do something with the given scene's instance of its set
|
||||
(defMacro withSceneSet [sceneKey name &body body]
|
||||
`(let [,name .set (dictGet scenes ,sceneKey)]
|
||||
,@body
|
||||
(cc)))
|
||||
|
||||
// like withSceneSet, but you promise to call CC yourself in the body:
|
||||
(defMacro withSceneSetCC [sceneKey name &body body]
|
||||
`(let [,name .set (dictGet scenes ,sceneKey)]
|
||||
,@body))
|
||||
|
||||
// When this file is loaded, all expressions in (preload <...>) will be collected. When (end) is called, they will
|
||||
// be injected into a method called (doPreload).
|
||||
// This allows assets to be declared in Hollywoo files where they first appear, but still loaded before execution starts.
|
||||
|
@@ -13,6 +13,10 @@ import uuid.Uuid;
|
||||
|
||||
using kiss.FuzzyMapTools;
|
||||
|
||||
typedef Cloneable<T> = {
|
||||
function clone():T;
|
||||
}
|
||||
|
||||
enum DelayHandling {
|
||||
Auto;
|
||||
AutoWithSkip;
|
||||
@@ -37,8 +41,4 @@ enum CreditsLine {
|
||||
* Model/controller of a Hollywoo film, and main execution script
|
||||
*/
|
||||
@:build(kiss.Kiss.build())
|
||||
class Movie<Set, StagePosition, StageFacing, ScreenPosition, Actor, Sound, Song, Prop, VoiceTrack> extends AsyncEmbeddedScript {
|
||||
// TODO for some reason this wasn't working when declared in Movie.kiss:
|
||||
// Mutable representation of frames in time:
|
||||
var scenes:FuzzyMap<Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor, Prop>> = new FuzzyMap<Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor, Prop>>();
|
||||
}
|
||||
class Movie<Set:Cloneable<Set>, ScreenPosition, Actor, Sound, Song, Prop, VoiceTrack> extends AsyncEmbeddedScript {}
|
||||
|
@@ -1,3 +1,6 @@
|
||||
(defMacro makeCC [&body b]
|
||||
`->:Void {,@b})
|
||||
|
||||
// This file is designed to be loaded again by subclasses, with macroVar "subclass" set
|
||||
(#unless subclass
|
||||
|
||||
@@ -14,9 +17,8 @@
|
||||
|
||||
(prop &mut :DelayHandling delayHandling AutoWithSkip)
|
||||
|
||||
// TODO for some reason this won't work when declared in Kiss syntax:
|
||||
// Mutable representation of frames in time:
|
||||
// var scenes:Map<String, Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor>> = [];
|
||||
(prop :FuzzyMap<Scene<Set,ScreenPosition,Actor,Prop>> scenes (new FuzzyMap<Scene<Set,ScreenPosition,Actor,Prop>>))
|
||||
|
||||
(prop :FuzzyMap<Bool> shownScenes (new FuzzyMap<Bool>))
|
||||
(prop :FuzzyMap<Bool> shownCharacters (new FuzzyMap<Bool>))
|
||||
@@ -40,7 +42,8 @@
|
||||
(method :Void showDialog [actorName dialogType wryly text cc]
|
||||
(when intercutMap
|
||||
(whenLet [sceneForActor (try (dictGet intercutMap actorName) (catch [e] null))]
|
||||
(setScene sceneForActor ->{})))
|
||||
(unless (= sceneForActor sceneKey)
|
||||
(setScene sceneForActor ->{}))))
|
||||
|
||||
(let [cc ->:Void {(director.hideDialog) (cc)}
|
||||
&mut skipCC cc]
|
||||
@@ -83,11 +86,66 @@
|
||||
[])]
|
||||
(dictSet voiceLines "$actorName $key" (objectWith [start line.start end line.end] trackKey alts))))))
|
||||
|
||||
(method _ccForEach <>[T] [:Iterable<T> collection :(T,Continuation)->Void do_ :Continuation finalCC]
|
||||
(let [:Iterator<T> iter (collection.iterator)]
|
||||
(withFunctions
|
||||
[
|
||||
(:Void doNext []
|
||||
(if (iter.hasNext)
|
||||
(do_ (iter.next) doNext)
|
||||
(finalCC)))
|
||||
]
|
||||
(doNext))))
|
||||
|
||||
(method _hideCurrentScene [:Continuation cc]
|
||||
(if sceneKey
|
||||
// hide current scene background
|
||||
(let [currentScene (dictGet scenes sceneKey)]
|
||||
(director.hideSet currentScene.set
|
||||
(makeCC
|
||||
// hide current scene characters
|
||||
(_ccForEach
|
||||
currentScene.characters
|
||||
->[:Character<Actor> c :Continuation cc]
|
||||
(director.hideCharacter c cc)
|
||||
(makeCC
|
||||
// hide current scene props, etc.
|
||||
(_ccForEach
|
||||
currentScene.propsOnScreen
|
||||
->[:ScreenProp<ScreenPosition,Prop> p :Continuation cc]
|
||||
(director.hideProp p.prop cc)
|
||||
cc))))))
|
||||
(cc)))
|
||||
|
||||
(method _showScene [:Scene<Set,ScreenPosition,Actor,Prop> scene :Appearance appearance :Continuation cc]
|
||||
// Show current scene background
|
||||
(director.showSet scene.set scene.time scene.perspective appearance
|
||||
(makeCC
|
||||
// Show current scene characters
|
||||
(_ccForEach
|
||||
(object iterator ->(scene.characters.keys))
|
||||
->[:String key :Continuation cc]
|
||||
(director.showCharacter (dictGet scene.characters key) (appearanceFlag shownCharacters key) cc)
|
||||
(makeCC
|
||||
// hide current scene props, etc.
|
||||
(_ccForEach
|
||||
scene.propsOnScreen
|
||||
->[:ScreenProp<ScreenPosition,Prop> p :Continuation cc]
|
||||
(director.showPropOnScreen p.prop p.screenPosition cc)
|
||||
cc))))))
|
||||
|
||||
(defNew
|
||||
[
|
||||
// "View" in the Model-View-Controller architecture:
|
||||
&prop :Director<Set,StagePosition,StageFacing,ScreenPosition,Actor,Sound,Song,Prop,VoiceTrack> director
|
||||
&prop :Director<Set,ScreenPosition,Actor,Sound,Song,Prop,VoiceTrack> director
|
||||
&opt :String voiceLinesJson
|
||||
&opt :String positionsJson
|
||||
]
|
||||
[
|
||||
:Map<String,StagePosition> stagePositions
|
||||
(if positionsJson
|
||||
(haxe.Json.parse (sys.io.File.getContent positionsJson))
|
||||
(new Map))
|
||||
]
|
||||
|
||||
(set director.movie this)
|
||||
@@ -99,7 +157,7 @@
|
||||
|
||||
// Some real magic happens here. This macro defines a method, AND a reader macro
|
||||
// for calling it with cc passed automatically if cc is an argument.
|
||||
|
||||
// GOTCHA: DO NOT use (method) directly in this file!!
|
||||
(defMacro hollywooMethod [nameAndType canSkip argList &builder b &body body]
|
||||
(let [args (expList argList)
|
||||
numArgs args.length
|
||||
@@ -162,25 +220,24 @@
|
||||
(dictSet scenes name (objectWith
|
||||
[
|
||||
set
|
||||
(dictGet sets setKey)
|
||||
(.clone (dictGet sets setKey))
|
||||
characters
|
||||
(new FuzzyMap<Character<StagePosition,StageFacing,Actor>>)
|
||||
(new FuzzyMap<Character<Actor>>)
|
||||
propsOnScreen
|
||||
(new FuzzyMap<Prop>)
|
||||
(new FuzzyMap<ScreenProp<ScreenPosition,Prop>>)
|
||||
]
|
||||
time
|
||||
perspective)))
|
||||
|
||||
(hollywooMethod newScene true [name :Scene<Set,StagePosition,StageFacing,ScreenPosition,Actor,Prop> scene]
|
||||
(assert isLoading)
|
||||
(dictSet scenes name scene))
|
||||
|
||||
(hollywooMethod setScene false [name :Continuation cc]
|
||||
(set sceneKey name)
|
||||
(director.showScene
|
||||
(dictGet scenes name)
|
||||
(appearanceFlag shownScenes name)
|
||||
cc))
|
||||
(_hideCurrentScene
|
||||
(makeCC
|
||||
(set sceneKey name)
|
||||
(_showScene
|
||||
(dictGet scenes name)
|
||||
(appearanceFlag shownScenes name)
|
||||
cc))))
|
||||
|
||||
|
||||
(hollywooMethod newSound true [name :Sound s]
|
||||
(assert isLoading)
|
||||
@@ -221,38 +278,62 @@
|
||||
(assert isLoading)
|
||||
(dictSet actors name actor))
|
||||
|
||||
(hollywooMethod addCharacter false [actorName :StagePosition position :StageFacing facing :Continuation cc]
|
||||
(let [character (object stagePosition position stageFacing facing actor (dictGet actors actorName))]
|
||||
(dictSet .characters (_currentScene) actorName character)
|
||||
(director.showCharacter
|
||||
character
|
||||
(appearanceFlag shownCharacters actorName)
|
||||
cc)))
|
||||
(hollywooMethod autoZProcess false [:StagePosition position :Continuation cc]
|
||||
// handle auto z recursively
|
||||
(ifLet [(Some (objectWith zPerLayer frontLayer)) director.autoZConfig]
|
||||
{
|
||||
(doFor =>name otherCharacter .characters (_currentScene)
|
||||
(when (and (= position.x otherCharacter.stagePosition.x) (= position.y otherCharacter.stagePosition.y) (= position.z otherCharacter.stagePosition.z))
|
||||
(moveCharacter name (object x position.x y position.y z (+ otherCharacter.stagePosition.z zPerLayer)) otherCharacter.stageFacing cc)
|
||||
(return)))
|
||||
(cc)
|
||||
}
|
||||
(cc)))
|
||||
|
||||
(hollywooMethod addCharacter false [actorName :Dynamic position :StageFacing facing :Continuation cc]
|
||||
(let [position (typeCase [position]
|
||||
([:String pKey] (dictGet stagePositions pKey))
|
||||
(otherwise position))
|
||||
character (object stagePosition position stageFacing facing actor (dictGet actors actorName))]
|
||||
(autoZProcess position
|
||||
(makeCC
|
||||
(dictSet .characters (_currentScene) actorName character)
|
||||
(director.showCharacter
|
||||
character
|
||||
(appearanceFlag shownCharacters actorName)
|
||||
cc)))))
|
||||
|
||||
(hollywooMethod removeCharacter false [actorName :Continuation cc]
|
||||
(let [c (dictGet .characters (_currentScene) actorName)]
|
||||
(.remove .characters (_currentScene) actorName)
|
||||
(director.hideCharacter c cc)))
|
||||
|
||||
(hollywooMethod moveCharacter false [actorName :StagePosition newPosition :StageFacing newFacing :Continuation cc]
|
||||
(let [c (dictGet .characters (_currentScene) actorName)]
|
||||
(director.moveCharacter c newPosition newFacing ->:Void {
|
||||
(set c.stagePosition newPosition)
|
||||
(set c.stageFacing newFacing)
|
||||
(cc)
|
||||
})))
|
||||
// INSTANTLY move a character:
|
||||
(hollywooMethod moveCharacter false [actorName :Dynamic newPosition :StageFacing newFacing :Continuation cc]
|
||||
(let [newPosition (typeCase [newPosition]
|
||||
([:String pKey] (dictGet stagePositions pKey))
|
||||
(otherwise newPosition))]
|
||||
(removeCharacter actorName
|
||||
(makeCC
|
||||
(addCharacter actorName newPosition newFacing cc)))))
|
||||
|
||||
// INSTANTLY swap characters
|
||||
(hollywooMethod swapCharacters false [actorNameA actorNameB :Continuation cc]
|
||||
// remove both, then re-add both, so they don't trigger
|
||||
// cascading auto z adjustments on top of each other:
|
||||
(let [a (dictGet .characters (_currentScene) actorNameA)
|
||||
b (dictGet .characters (_currentScene) actorNameB)]
|
||||
(director.swapCharacters a b ->:Void
|
||||
(let [tempStagePos a.stagePosition
|
||||
tempStageFacing a.stageFacing]
|
||||
(set a.stagePosition b.stagePosition)
|
||||
(set a.stageFacing b.stageFacing)
|
||||
(set b.stagePosition tempStagePos)
|
||||
(set b.stageFacing tempStageFacing)
|
||||
(cc)))))
|
||||
asp a.stagePosition
|
||||
asf a.stageFacing
|
||||
b (dictGet .characters (_currentScene) actorNameB)
|
||||
bsp b.stagePosition
|
||||
bsf b.stageFacing]
|
||||
(removeCharacter actorNameA
|
||||
(makeCC
|
||||
(removeCharacter actorNameB
|
||||
(makeCC
|
||||
(addCharacter actorNameA bsp bsf
|
||||
(makeCC
|
||||
(addCharacter actorNameB asp asf cc)))))))))
|
||||
|
||||
// TODO moveCharacter remove them, add them to another scene
|
||||
// TODO moveCharacterAndFollow remove them, add them to another scene, set that the scene
|
||||
@@ -262,10 +343,13 @@
|
||||
(dictSet props name prop))
|
||||
|
||||
(hollywooMethod addPropToScreen false [name :ScreenPosition position :Continuation cc]
|
||||
(dictSet .propsOnScreen (_currentScene) name (dictGet props name))
|
||||
(director.showPropOnScreen (dictGet props name) position cc))
|
||||
(let [prop (dictGet props name)]
|
||||
(dictSet .propsOnScreen (_currentScene) name (object screenPosition position prop prop))
|
||||
(director.showPropOnScreen prop position cc)))
|
||||
|
||||
(hollywooMethod removeProp false [name :Continuation cc]
|
||||
(.remove .propsOnScreen (_currentScene) name)
|
||||
// TODO (propsOnStage.remove name)
|
||||
(director.hideProp (dictGet props name) cc))
|
||||
|
||||
// Dialogue:
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package hollywoo;
|
||||
|
||||
import kiss.FuzzyMap;
|
||||
import hollywoo.Director;
|
||||
import hollywoo.Movie;
|
||||
|
||||
enum SceneTime {
|
||||
Morning;
|
||||
@@ -15,26 +17,31 @@ enum ScenePerspective {
|
||||
Mixed;
|
||||
}
|
||||
|
||||
typedef Character<StagePosition, StageFacing, Actor> = {
|
||||
typedef Character<Actor> = {
|
||||
stagePosition:StagePosition,
|
||||
stageFacing:StageFacing,
|
||||
actor:Actor
|
||||
};
|
||||
|
||||
enum SpeechType<StagePosition, StageFacing, Actor> {
|
||||
enum SpeechType<Actor> {
|
||||
Super;
|
||||
OffScreen(actor:Actor);
|
||||
VoiceOver(actor:Actor);
|
||||
TextMessage(actor:Actor);
|
||||
FromPhone(actor:Actor);
|
||||
OnScreen(character:Character<StagePosition, StageFacing, Actor>);
|
||||
OnScreen(character:Character<Actor>);
|
||||
Custom(type:String, actor:Actor, args:Dynamic);
|
||||
}
|
||||
|
||||
typedef Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor, Prop> = {
|
||||
typedef ScreenProp<ScreenPosition,Prop> = {
|
||||
screenPosition:ScreenPosition,
|
||||
prop:Prop
|
||||
};
|
||||
|
||||
typedef Scene<Set:Cloneable<Set>, ScreenPosition, Actor, Prop> = {
|
||||
set:Set,
|
||||
characters:FuzzyMap<Character<StagePosition, StageFacing, Actor>>,
|
||||
propsOnScreen:FuzzyMap<Prop>,
|
||||
characters:FuzzyMap<Character<Actor>>,
|
||||
propsOnScreen:FuzzyMap<ScreenProp<ScreenPosition,Prop>>,
|
||||
// TODO props on stage
|
||||
time:SceneTime,
|
||||
perspective:ScenePerspective
|
||||
|
Reference in New Issue
Block a user