move asciilib2 -> asciilib for naming clarity
This commit is contained in:
8
projects/asciilib/src/Main.hx
Normal file
8
projects/asciilib/src/Main.hx
Normal file
@@ -0,0 +1,8 @@
|
||||
package;
|
||||
|
||||
import kiss.Kiss;
|
||||
import kiss.Prelude;
|
||||
import asciilib.Surface;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class Main {}
|
||||
1
projects/asciilib/src/Main.kiss
Normal file
1
projects/asciilib/src/Main.kiss
Normal file
@@ -0,0 +1 @@
|
||||
(print "Hello world!")
|
||||
4
projects/asciilib/src/asciilib/Assets.hx
Normal file
4
projects/asciilib/src/asciilib/Assets.hx
Normal file
@@ -0,0 +1,4 @@
|
||||
package asciilib;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class Assets {}
|
||||
12
projects/asciilib/src/asciilib/Assets.kiss
Normal file
12
projects/asciilib/src/asciilib/Assets.kiss
Normal file
@@ -0,0 +1,12 @@
|
||||
(defNew [&prop :AssetsBackend backend]
|
||||
[:Map<String,Surface> _surfaces (new Map)])
|
||||
|
||||
// TODO don't allow overriding a key -- use a macro so all load___() calls check their maps first
|
||||
(method loadSurface [key path]
|
||||
(dictSet _surfaces key (Surface.fromString (backend.loadText path))))
|
||||
|
||||
// TODO runtime-assert that the key exists. Use a macro so all get___() calls check their maps first
|
||||
(method getSurface [key]
|
||||
(dictGet _surfaces key))
|
||||
|
||||
// TODO freeSurface() etc.
|
||||
5
projects/asciilib/src/asciilib/AssetsBackend.hx
Normal file
5
projects/asciilib/src/asciilib/AssetsBackend.hx
Normal file
@@ -0,0 +1,5 @@
|
||||
package asciilib;
|
||||
|
||||
interface AssetsBackend {
|
||||
function loadText(filePath:String):String;
|
||||
}
|
||||
15
projects/asciilib/src/asciilib/Colors.hx
Normal file
15
projects/asciilib/src/asciilib/Colors.hx
Normal file
@@ -0,0 +1,15 @@
|
||||
package asciilib;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
|
||||
typedef Color = {
|
||||
r:Int,
|
||||
g:Int,
|
||||
b:Int,
|
||||
}
|
||||
|
||||
/**
|
||||
* The Colors class represents a 2D grid of colors. Under the hood, it's byte channels
|
||||
*/
|
||||
@:build(kiss.Kiss.build())
|
||||
class Colors {}
|
||||
40
projects/asciilib/src/asciilib/Colors.kiss
Normal file
40
projects/asciilib/src/asciilib/Colors.kiss
Normal file
@@ -0,0 +1,40 @@
|
||||
(defNew [_width _height &opt :Color fillColor]
|
||||
[:Int width _width
|
||||
:Int height _height
|
||||
:Int area (* width height)
|
||||
:Bytes red (Bytes.alloc area)
|
||||
:Bytes green (Bytes.alloc area)
|
||||
:Bytes blue (Bytes.alloc area)]
|
||||
|
||||
(fill (or fillColor Black)))
|
||||
|
||||
(method fill [:Color color]
|
||||
(red.fill 0 area color.r)
|
||||
(green.fill 0 area color.g)
|
||||
(blue.fill 0 area color.b))
|
||||
|
||||
(method _index [x y]
|
||||
(+ x (* y width)))
|
||||
|
||||
(defmacro withIndex [idxName xName yName &body body]
|
||||
`(let [,idxName (_index ,xName ,yName)]
|
||||
,@body))
|
||||
|
||||
(method getPixel [x y]
|
||||
(withIndex idx x y
|
||||
(object r (red.get idx) g (green.get idx) b (blue.get idx))))
|
||||
|
||||
(method setPixel [x y color]
|
||||
(withIndex idx x y
|
||||
(red.set idx color.r)
|
||||
(green.set idx color.g)
|
||||
(blue.set idx color.b)))
|
||||
|
||||
(function equal [c1 c2]
|
||||
(and (= c1.r c2.r) (= c1.g c2.g) (= c1.b c2.b)))
|
||||
|
||||
(var Black (object r 0 g 0 b 0))
|
||||
(var Red (object r 255 g 0 b 0))
|
||||
(var Green (object r 0 g 255 b 0))
|
||||
(var Blue (object r 0 g 0 b 255))
|
||||
(var White (object r 255 g 255 b 255))
|
||||
4
projects/asciilib/src/asciilib/Game.hx
Normal file
4
projects/asciilib/src/asciilib/Game.hx
Normal file
@@ -0,0 +1,4 @@
|
||||
package asciilib;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class Game {}
|
||||
25
projects/asciilib/src/asciilib/Game.kiss
Normal file
25
projects/asciilib/src/asciilib/Game.kiss
Normal file
@@ -0,0 +1,25 @@
|
||||
(defNew [title
|
||||
width
|
||||
height
|
||||
letterWidth
|
||||
letterHeight
|
||||
_gameLogic
|
||||
assetsBackend
|
||||
_graphicsBackend]
|
||||
|
||||
// TODO the type annotation on this line feels like a bit much, but is necessary:
|
||||
[:Graphics graphics (new Graphics width height)
|
||||
:GameLogic gameLogic _gameLogic
|
||||
:Assets assets (new Assets assetsBackend)
|
||||
:GraphicsBackend graphicsBackend _graphicsBackend]
|
||||
|
||||
(graphicsBackend.initialize title width height letterWidth letterHeight)
|
||||
(gameLogic.initialize assets))
|
||||
|
||||
(method update [:Float deltaSeconds]
|
||||
(gameLogic.update this deltaSeconds))
|
||||
|
||||
(method draw []
|
||||
(let [&mut changedGraphics false]
|
||||
(gameLogic.draw (lambda [] (set changedGraphics true) graphics) assets)
|
||||
(when changedGraphics (graphicsBackend.draw graphics))))
|
||||
10
projects/asciilib/src/asciilib/GameLogic.hx
Normal file
10
projects/asciilib/src/asciilib/GameLogic.hx
Normal file
@@ -0,0 +1,10 @@
|
||||
package asciilib;
|
||||
|
||||
// Your game's logic is an interface contained in Game instead of a class that extends Game.
|
||||
// This allows ASCIILib to support libraries like HaxeFlixel where your main class is expected
|
||||
// to extend another class already.
|
||||
interface GameLogic {
|
||||
public function initialize(assets:Assets):Void;
|
||||
public function update(game:Game, deltaSeconds:Float):Void;
|
||||
public function draw(graphicsHandle:() -> Graphics, assets:Assets):Void;
|
||||
}
|
||||
4
projects/asciilib/src/asciilib/Graphics.hx
Normal file
4
projects/asciilib/src/asciilib/Graphics.hx
Normal file
@@ -0,0 +1,4 @@
|
||||
package asciilib;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class Graphics extends Surface {}
|
||||
2
projects/asciilib/src/asciilib/Graphics.kiss
Normal file
2
projects/asciilib/src/asciilib/Graphics.kiss
Normal file
@@ -0,0 +1,2 @@
|
||||
(method new [width height]
|
||||
(super width height))
|
||||
6
projects/asciilib/src/asciilib/GraphicsBackend.hx
Normal file
6
projects/asciilib/src/asciilib/GraphicsBackend.hx
Normal file
@@ -0,0 +1,6 @@
|
||||
package asciilib;
|
||||
|
||||
interface GraphicsBackend {
|
||||
function initialize(title:String, width:Int, height:Int, letterWidth:Int, letterHeight:Int):Void;
|
||||
function draw(graphics:Graphics):Void;
|
||||
}
|
||||
4
projects/asciilib/src/asciilib/Grid.hx
Normal file
4
projects/asciilib/src/asciilib/Grid.hx
Normal file
@@ -0,0 +1,4 @@
|
||||
package asciilib;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class Grid<T> {}
|
||||
7
projects/asciilib/src/asciilib/Grid.kiss
Normal file
7
projects/asciilib/src/asciilib/Grid.kiss
Normal file
@@ -0,0 +1,7 @@
|
||||
(defNew [_width _height :T defaultValue]
|
||||
[:Int width _width
|
||||
:Int height _height
|
||||
:Array<Array<T>> rows (for _ (range height) (for _ (range width) defaultValue))])
|
||||
|
||||
(method getCell [x y] (nth (nth rows y) x))
|
||||
(method setCell [x y value] (setNth (nth rows y) x value))
|
||||
4
projects/asciilib/src/asciilib/Letters.hx
Normal file
4
projects/asciilib/src/asciilib/Letters.hx
Normal file
@@ -0,0 +1,4 @@
|
||||
package asciilib;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class Letters {}
|
||||
13
projects/asciilib/src/asciilib/Letters.kiss
Normal file
13
projects/asciilib/src/asciilib/Letters.kiss
Normal file
@@ -0,0 +1,13 @@
|
||||
(defNew [_width _height &opt :String letter]
|
||||
[:Int width _width
|
||||
:Int height _height
|
||||
:Array<String> rows (for _ (range height) (* (or letter " ") width))])
|
||||
|
||||
(method getChar [x y]
|
||||
(.charAt (nth rows y) x))
|
||||
|
||||
(method setChar [x y char]
|
||||
(let [row (nth rows y)
|
||||
left (row.substr 0 x)
|
||||
right (row.substr (+ x 1))]
|
||||
(setNth rows y "${left}${char}${right}")))
|
||||
13
projects/asciilib/src/asciilib/Surface.hx
Normal file
13
projects/asciilib/src/asciilib/Surface.hx
Normal file
@@ -0,0 +1,13 @@
|
||||
package asciilib;
|
||||
|
||||
import asciilib.Colors;
|
||||
import kiss.Stream;
|
||||
import haxe.ds.Option;
|
||||
|
||||
typedef Letter = {
|
||||
char:String,
|
||||
color:Color
|
||||
};
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class Surface {}
|
||||
98
projects/asciilib/src/asciilib/Surface.kiss
Normal file
98
projects/asciilib/src/asciilib/Surface.kiss
Normal file
@@ -0,0 +1,98 @@
|
||||
(defNew [_width _height &opt :Color backgroundColor :String letter :Color letterColor]
|
||||
[:Int width _width
|
||||
:Int height _height
|
||||
:Colors backgroundColors (new Colors width height (or backgroundColor Colors.Black))
|
||||
:Letters letters (new Letters width height (or letter " "))
|
||||
:Colors letterColors (new Colors width height (or letterColor Colors.White))
|
||||
:Grid<Bool> opacity (new Grid width height true)
|
||||
:Grid<String> specialInfo (new Grid width height "")])
|
||||
|
||||
(method getBackgroundColor [x y]
|
||||
(backgroundColors.getPixel x y))
|
||||
|
||||
(method setBackgroundColor [x y color]
|
||||
(backgroundColors.setPixel x y color))
|
||||
|
||||
(method getLetter [x y]
|
||||
(object char (letters.getChar x y) color (letterColors.getPixel x y)))
|
||||
|
||||
(method setLetter [x y letter]
|
||||
(letters.setChar x y letter.char)
|
||||
(letterColors.setPixel x y letter.color))
|
||||
|
||||
(method isCellOpaque [x y]
|
||||
(opacity.getCell x y))
|
||||
|
||||
(method setCellOpacity [x y value]
|
||||
(opacity.setCell x y value))
|
||||
|
||||
(method getSpecialInfo [x y]
|
||||
(specialInfo.getCell x y))
|
||||
|
||||
(method setSpecialInfo [x y value]
|
||||
(specialInfo.setCell x y value))
|
||||
|
||||
// TODO rectangle type
|
||||
// TODO optional source rectangle argument
|
||||
(method blitSurface [:Surface surface x y]
|
||||
(doFor [srcX destX] (the kiss.List<kiss.List<Int>> (zipDrop (range surface.width) (range x (+ x surface.width))))
|
||||
(when (< -1 destX width)
|
||||
(doFor [srcY destY] (the kiss.List<kiss.List<Int>> (zipDrop (range 0 surface.height) (range y (+ y surface.height))))
|
||||
(when (< -1 destY height)
|
||||
(when (surface.isCellOpaque srcX srcY)
|
||||
(setBackgroundColor destX destY (surface.getBackgroundColor srcX srcY))
|
||||
(setLetter destX destY (surface.getLetter srcX srcY))
|
||||
(setSpecialInfo destX destY (surface.getSpecialInfo srcX srcY))
|
||||
// Cover transparent cells in the lower surface with opaque ones
|
||||
(setCellOpacity destX destY true)))))))
|
||||
|
||||
(function fromString [text]
|
||||
(let [stream (Stream.fromString text)
|
||||
:Map<String,Color> colors (new Map)
|
||||
:Map<String,String> infoCodes (new Map)
|
||||
:Map<String,Bool> opacityCodes [=>"0" false =>"1" true]]
|
||||
|
||||
(stream.dropString "COLORS\n")
|
||||
(loop
|
||||
(case (stream.takeLine)
|
||||
((Some "INFO CODES") (break))
|
||||
((Some colorLine)
|
||||
(let [[symbol _r _g _b] (colorLine.split " ")]
|
||||
(dictSet colors symbol (object r (Std.parseInt _r) g (Std.parseInt _g) b (Std.parseInt _b)))))
|
||||
(None (throw "Expected INFO CODES in Surface"))))
|
||||
(loop
|
||||
(case (stream.takeLine)
|
||||
((Some "SIZE") (break))
|
||||
((Some infoLine)
|
||||
(let [infoTokens (infoLine.split " ")]
|
||||
(dictSet infoCodes (infoTokens.shift) (infoTokens.join " "))))
|
||||
(None (throw "Expected SIZE in Surface"))))
|
||||
(case (stream.takeLine)
|
||||
(None (throw "expected [width] [height] in Surface"))
|
||||
((Some sizeLine)
|
||||
(let [[width height] (.map (sizeLine.split " ") Std.parseInt)
|
||||
surface (new Surface width height)]
|
||||
(stream.dropString "CHARACTERS\n")
|
||||
(doFor row (range height)
|
||||
(setNth surface.letters.rows row (stream.expect "line of characters" ->{(stream.takeLine)})))
|
||||
(stream.dropString "BACKGROUND COLORS\n")
|
||||
(doFor y (range height)
|
||||
(doFor x (range width)
|
||||
(surface.setBackgroundColor x y (dictGet colors (stream.expect "a color code" ->{(stream.takeChars 1)}))))
|
||||
(stream.dropString "\n"))
|
||||
(stream.dropString "CHARACTER COLORS\n")
|
||||
(doFor y (range height)
|
||||
(doFor x (range width)
|
||||
(surface.letterColors.setPixel x y (dictGet colors (stream.expect "a color code" ->{(stream.takeChars 1)}))))
|
||||
(stream.dropString "\n"))
|
||||
(stream.dropString "OPACITY\n")
|
||||
(doFor y (range height)
|
||||
(doFor x (range width)
|
||||
(surface.opacity.setCell x y (dictGet opacityCodes (stream.expect "0 or 1" ->{(stream.takeChars 1)}))))
|
||||
(stream.dropString "\n"))
|
||||
(stream.dropString "SPECIAL INFO\n")
|
||||
(doFor y (range height)
|
||||
(doFor x (range width)
|
||||
(surface.specialInfo.setCell x y (dictGet infoCodes (stream.expect "a special info code" ->{(stream.takeChars 1)}))))
|
||||
(stream.dropString "\n"))
|
||||
surface)))))
|
||||
@@ -0,0 +1,7 @@
|
||||
package asciilib.backends.flixel;
|
||||
|
||||
import asciilib.AssetsBackend;
|
||||
import openfl.Assets;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class FlxAssetsBackend implements AssetsBackend {}
|
||||
@@ -0,0 +1,3 @@
|
||||
(defNew [])
|
||||
|
||||
(method loadText [filePath] (Assets.getText filePath))
|
||||
@@ -0,0 +1,16 @@
|
||||
package asciilib.backends.flixel;
|
||||
|
||||
import asciilib.GraphicsBackend;
|
||||
import asciilib.Graphics;
|
||||
import flixel.FlxState;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.system.FlxAssets;
|
||||
import flixel.graphics.frames.FlxBitmapFont;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.text.FlxBitmapText;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class FlxGraphicsBackend implements GraphicsBackend {}
|
||||
@@ -0,0 +1,45 @@
|
||||
(prop &mut :FlxGroup backgroundColors null)
|
||||
(prop &mut :FlxGroup letters null)
|
||||
(prop &mut :Int letterWidth 0)
|
||||
(prop &mut :Int letterHeight 0)
|
||||
(prop &mut :FlxBitmapFont font null)
|
||||
|
||||
(defNew [_state
|
||||
_fontAsset
|
||||
&opt _letters _region _spacing]
|
||||
[:FlxState state _state
|
||||
:FlxBitmapFontGraphicAsset fontAsset _fontAsset
|
||||
:String fontLetters _letters
|
||||
:FlxRect region _region
|
||||
:FlxPoint spacing _spacing])
|
||||
|
||||
(method :Void initialize [:String title :Int width :Int height :Int _letterWidth :Int _letterHeight]
|
||||
(set letterWidth _letterWidth)
|
||||
(set letterHeight _letterHeight)
|
||||
(set font (FlxBitmapFont.fromMonospace fontAsset fontLetters (new FlxPoint letterWidth letterHeight) region spacing))
|
||||
(set backgroundColors (new FlxGroup))
|
||||
(set letters (new FlxGroup)))
|
||||
|
||||
(method :Void draw [:Graphics graphics]
|
||||
(backgroundColors.kill)
|
||||
(set backgroundColors (new FlxGroup))
|
||||
(letters.kill)
|
||||
(set letters (new FlxGroup))
|
||||
(for x (range graphics.width)
|
||||
(for y (range graphics.height)
|
||||
(let [bgc (graphics.getBackgroundColor x y)]
|
||||
(unless (Colors.equal bgc Colors.Black)
|
||||
(let [sprite (new FlxSprite (* letterWidth x) (* letterHeight y))]
|
||||
(backgroundColors.add (sprite.makeGraphic letterWidth letterHeight (FlxColor.fromRGB bgc.r bgc.g bgc.b))))))
|
||||
(let [letter (graphics.getLetter x y)]
|
||||
(unless (= letter.char " ")
|
||||
(let [color letter.color
|
||||
text (new FlxBitmapText font)]
|
||||
(set text.text letter.char)
|
||||
(set text.x (* letterWidth x))
|
||||
(set text.y (* letterHeight y))
|
||||
(set text.useTextColor true)
|
||||
(set text.textColor (FlxColor.fromRGB color.r color.g color.b))
|
||||
(letters.add text))))))
|
||||
(state.add backgroundColors)
|
||||
(state.add letters))
|
||||
@@ -0,0 +1,7 @@
|
||||
package asciilib.backends.test;
|
||||
|
||||
import asciilib.AssetsBackend;
|
||||
import sys.io.File;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class TestAssetsBackend implements AssetsBackend {}
|
||||
@@ -0,0 +1,3 @@
|
||||
(defNew [])
|
||||
|
||||
(method loadText [filePath] (File.getContent filePath))
|
||||
@@ -0,0 +1,7 @@
|
||||
package asciilib.backends.test;
|
||||
|
||||
import asciilib.GraphicsBackend;
|
||||
import asciilib.Graphics;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class TestGraphicsBackend implements GraphicsBackend {}
|
||||
@@ -0,0 +1,12 @@
|
||||
(prop &mut :Int letterWidth 0)
|
||||
(prop &mut :Int letterHeight 0)
|
||||
(prop &mut :Int drawCalled 0)
|
||||
|
||||
(defNew [])
|
||||
|
||||
(method :Void initialize [:String title :Int width :Int height :Int _letterWidth :Int _letterHeight]
|
||||
(set letterWidth _letterWidth)
|
||||
(set letterHeight _letterHeight))
|
||||
|
||||
(method :Void draw [:Graphics graphics]
|
||||
(+= drawCalled 1))
|
||||
1
projects/asciilib/src/asciilib/import.hx
Normal file
1
projects/asciilib/src/asciilib/import.hx
Normal file
@@ -0,0 +1 @@
|
||||
import kiss.Prelude;
|
||||
Reference in New Issue
Block a user