167 lines
8.1 KiB
Plaintext
167 lines
8.1 KiB
Plaintext
// Calculate where to draw the given stamp sprite on the given canvas sprite, as percentages or pixels from edge
|
|
(function :Array<Int> positionOn [:FlxSprite stamp :FlxSprite canvas :RelativePosition pos &opt :Bool allowOutOfRange]
|
|
(unless pos.anchorX (set pos.anchorX (Percent 0.5)))
|
|
(unless pos.anchorY (set pos.anchorY (Percent 0.5)))
|
|
(let [&mut x (coordIn pos.x (/ canvas.width canvas.scale.x) pos.offsetX allowOutOfRange)
|
|
&mut y (coordIn pos.y (/ canvas.height canvas.scale.y) pos.offsetY allowOutOfRange)]
|
|
(-= x (coordIn pos.anchorX stamp.width))
|
|
(-= y (coordIn pos.anchorY stamp.height))
|
|
[x y]))
|
|
|
|
(function :Int coordIn [:RelativeCoordinate coord :Float range &opt :Int offset &opt :Bool allowOutOfRange]
|
|
(+ (or offset 0)
|
|
(Math.round
|
|
(case coord
|
|
((when (and (or allowOutOfRange (>= p -1)) (< p 0)) (Percent p))
|
|
(+ range (* p range)))
|
|
((when (and (or allowOutOfRange (>= p -range)) (< p 0)) (Pixels p))
|
|
(+ range p))
|
|
((when (or allowOutOfRange (<= p 1)) (Percent p))
|
|
(* range p))
|
|
((when (or allowOutOfRange (<= p range)) (Pixels p))
|
|
p)
|
|
(otherwise (throw "$coord is out of range $range"))))))
|
|
|
|
(function :Void scaleStampOn [:FlxSprite stamp :FlxSprite canvas :RelativePosition pos]
|
|
(let [&mut x 0 &mut y 0]
|
|
(when pos.sizeX
|
|
(set x (coordIn pos.sizeX canvas.frameWidth)))
|
|
(when pos.sizeY
|
|
(set y (coordIn pos.sizeY canvas.frameHeight)))
|
|
(stamp.setGraphicSize x y)
|
|
(stamp.updateHitbox)))
|
|
|
|
(function :Void drawOnSprite [:FlxSprite stamp :FlxSprite canvas :RelativePosition pos]
|
|
(scaleStampOn stamp canvas pos)
|
|
(let [[x y] (positionOn stamp canvas pos)]
|
|
(let [oX stamp.origin.x
|
|
oY stamp.origin.y]
|
|
(stamp.origin.set 0 0)
|
|
(canvas.stamp stamp x y)
|
|
(stamp.origin.set oX oY))))
|
|
|
|
// TODO allow specifying size relative to canvas
|
|
(function :Void writeOnSprite [:String text :Int size :FlxSprite canvas :RelativePosition pos &opt :FlxColor color :String fontPath]
|
|
(let [lines (text.split "\n")
|
|
&mut offsetY (/ (* size lines.length) -2)]
|
|
(doFor text lines
|
|
(set pos.offsetY offsetY)
|
|
(+= offsetY size)
|
|
(let [text (new FlxText 0 0 0 text size)]
|
|
(when fontPath
|
|
(text.setFormat fontPath size color))
|
|
(when color
|
|
(set text.color color))
|
|
(drawOnSprite text canvas pos)))))
|
|
|
|
// Source: https://gist.github.com/miltoncandelero/0c452f832fa924bfdd60fe9d507bc581
|
|
(#when sys
|
|
(function :Void saveToPNG [:FlxSprite sprite :String file]
|
|
(let [bitmapData sprite.pixels
|
|
&mut bytes (new ByteArray)]
|
|
(set bytes (bitmapData.encode bitmapData.rect (new PNGEncoderOptions true) bytes))
|
|
(File.saveBytes file bytes))))
|
|
|
|
(function :FlxSprite textPlate [:String text :Int size :Int margin &opt :FlxColor textColor :FlxColor bgColor :FlxText->FlxText applyFormat :String fontPath]
|
|
(unless applyFormat (set applyFormat ->text text))
|
|
(unless textColor (set textColor FlxColor.WHITE))
|
|
(unless bgColor (set bgColor FlxColor.BLACK))
|
|
(let [flxText (new FlxText 0 0 0 text size)
|
|
flxText (if fontPath
|
|
(flxText.setFormat fontPath size textColor)
|
|
flxText)
|
|
flxText (applyFormat flxText)
|
|
textWidth flxText.width
|
|
textHeight flxText.height
|
|
plate (new FlxSprite)]
|
|
(set flxText.color textColor)
|
|
(plate.makeGraphic (+ (* 2 margin) textWidth) (+ (* 2 margin) textHeight) bgColor true)
|
|
(plate.stamp flxText margin margin)
|
|
plate))
|
|
|
|
(function :FlxSprite cloneUnique [:FlxSprite sprite]
|
|
(let [s (sprite.clone)]
|
|
(s.loadGraphic s.graphic false 0 0 true)))
|
|
|
|
(var &mut _idx 0)
|
|
(var &mut doPrint true)
|
|
(var :Map<flixel.FlxBasic,Bool> ignoreObjects (new Map))
|
|
(function :String logSprites [&opt :flixel.FlxCamera _camera :FlxGroup group :String tab :StringBuf buf]
|
|
(unless buf
|
|
(set buf (new StringBuf)))
|
|
(localFunction _print [:String text]
|
|
(when doPrint
|
|
(print text))
|
|
(buf.add "${text}\n"))
|
|
(unless _camera
|
|
(_print "Logging Sprites")
|
|
(_print "###############")
|
|
(let [cameras (enumerate (filter FlxG.cameras.list))]
|
|
(doFor [idx camera] cameras
|
|
(_print "Camera #${idx} (${camera.x}, ${camera.y}, ${camera.width}x${camera.height})")
|
|
(_print "bgColor: ${camera.bgColor}")
|
|
(_print "--------------")
|
|
(logSprites camera null "" buf))
|
|
(return (buf.toString))))
|
|
(unless group
|
|
(set _idx 0)
|
|
(set group FlxG.state)
|
|
(set tab ""))
|
|
(group.forEach
|
|
->:Void obj
|
|
(cond
|
|
((ignoreObjects.exists obj) null)
|
|
((let [cameras (or obj.cameras (Reflect.field FlxG.cameras "defaults"))]
|
|
(cameras.contains _camera))
|
|
|
|
(typeCase [obj]
|
|
([:FlxText text]
|
|
(_print "${tab}${_idx++}. ${text.text} $(spriteToString text)"))
|
|
([:SimpleWindow window]
|
|
(_print "${tab}${_idx++}. SimpleWindow '${window.title}': $(spriteToString window)"))
|
|
([:FlxSprite sprite]
|
|
(_print "${tab}${_idx++}. $(spriteToString sprite)"))
|
|
([:DebugLayer innerGroup]
|
|
(_print "${tab}${_idx++}. DebugLayer:")
|
|
(logSprites _camera (cast innerGroup) "${tab}| " buf))
|
|
([:FlxTypedGroup<FlxBasic> innerGroup]
|
|
(logSprites _camera innerGroup "${tab}| " buf))
|
|
(otherwise
|
|
(_print "${tab}${_idx++}. Unhandled type $(Type.getClassName (Type.getClass obj))"))))
|
|
(true
|
|
null)))
|
|
(_print "${tab}---------------")
|
|
"")
|
|
|
|
(var FLIPPED_X ", flipped horizontally")
|
|
(var FLIPPED_Y ", flipped vertically")
|
|
(function :String spriteToString [:FlxSprite sprite]
|
|
(localVar flipInfo "$?(when sprite.flipX FLIPPED_X)$?(when sprite.flipY FLIPPED_Y)")
|
|
"{${sprite.graphic.assetsKey} at (${sprite.x},${sprite.y}) with origin ${sprite.origin}, angle ${sprite.angle}, scale ${sprite.scale}, size ${sprite.width}x${sprite.height}, alpha ${sprite.alpha}, frame ${sprite.animation?.frameIndex}}$flipInfo")
|
|
|
|
(#when sys
|
|
(function :Void warnLogSprites [:String logFile]
|
|
(assertLogSprites logFile true))
|
|
|
|
// Successive runs of this program will assert that the layout and order of sprites stays the same. Must pass in a unique constant logFile path
|
|
(function :Void assertLogSprites [:String logFile &opt :Bool warnOnly]
|
|
(set doPrint false)
|
|
(if (sys.FileSystem.exists logFile)
|
|
(let [expectedLog (StringTools.trim (StringTools.replace (sys.io.File.getContent logFile) "\r" ""))
|
|
actualLog (StringTools.trim (logSprites))]
|
|
(unless (= expectedLog actualLog)
|
|
(#when (and linux debug)
|
|
(sys.io.File.saveContent "${logFile}.actual" actualLog)
|
|
(tryProcess "delta" [logFile "${logFile}.actual"] Prelude.printStr)
|
|
(sys.FileSystem.deleteFile "${logFile}.actual"))
|
|
(if warnOnly
|
|
{
|
|
(print "Warning! Expected and actual sprite logs are not the same. Install delta for a readable diff")
|
|
(print "expected:")
|
|
(print expectedLog)
|
|
(print "actual:")
|
|
(print actualLog)
|
|
}
|
|
(assertEquals expectedLog actualLog))))
|
|
(sys.io.File.saveContent logFile (logSprites)))
|
|
(set doPrint true))) |