├── twinspire ├── render │ ├── StyleType.hx │ ├── Style.hx │ ├── spritesheet │ │ └── SheetData.hx │ ├── tilemap │ │ ├── ts │ │ │ ├── TileMap.hx │ │ │ └── Tileset.hx │ │ └── tiled │ │ │ ├── TileMapLayer.hx │ │ │ ├── Tileset.hx │ │ │ └── TileMap.hx │ ├── SpriteSheet.hx │ ├── Tile.hx │ ├── Tileset.hx │ ├── Object.hx │ └── TileMap.hx ├── gui │ ├── ComboBox.hx │ ├── Container.hx │ ├── CheckBox.hx │ ├── Button.hx │ ├── RadioButton.hx │ └── Label.hx ├── utils │ ├── Flags.hx │ ├── Timer.hx │ └── ExtraMath.hx ├── geom │ ├── Size.hx │ └── Rect.hx ├── events │ ├── EventType.hx │ └── Event.hx ├── Application.hx └── RealColors.hx ├── haxelib.json ├── LICENSE └── README.md /twinspire/render/StyleType.hx: -------------------------------------------------------------------------------- 1 | package twinspire.render; 2 | 3 | @:enum 4 | abstract StyleType(Int) from Int to Int 5 | { 6 | var STYLE_BASIC = 0; 7 | var STYLE_IMAGE = 1; 8 | var STYLE_SPRITESHEET = 2; 9 | } -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Twinspire", 3 | "description": "A video game engine and utility library for Kha.", 4 | "license": "MIT", 5 | "releasenote": "Various bug fixes, simpler flow, and removal of Gui once again.", 6 | "version": "0.2.3-beta", 7 | "url": "https://github.com/twinspire/Twinspire", 8 | "tags": [ 9 | "kha", "utility" 10 | ], 11 | "contributors": [ 12 | "tienery" 13 | ] 14 | } -------------------------------------------------------------------------------- /twinspire/gui/ComboBox.hx: -------------------------------------------------------------------------------- 1 | package twinspire.gui; 2 | 3 | using twinspire.events.EventType; 4 | import twinspire.events.Event; 5 | 6 | import twinspire.render.Object; 7 | 8 | import kha.graphics2.Graphics; 9 | 10 | class ComboBox extends Object 11 | { 12 | 13 | public function new() 14 | { 15 | super(); 16 | } 17 | 18 | public override function update(e:Event) 19 | { 20 | 21 | } 22 | 23 | public override function render(g2:Graphics) 24 | { 25 | 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /twinspire/utils/Flags.hx: -------------------------------------------------------------------------------- 1 | package twinspire.utils; 2 | 3 | class Flags 4 | { 5 | 6 | public static function hasFlag(value:Int, flag:Int) 7 | { 8 | return ((value & flag) != 0); 9 | } 10 | 11 | public static function getAllFlags(value:Int, ?max:Int = 32):Array 12 | { 13 | var current = max - 1; 14 | var results = new Array(); 15 | while (current > 0) 16 | { 17 | if (hasFlag(value, 1 << current)) 18 | results.push(1 << current); 19 | --current; 20 | } 21 | return results; 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /twinspire/render/Style.hx: -------------------------------------------------------------------------------- 1 | package twinspire.render; 2 | 3 | import twinspire.render.SpriteSheet; 4 | 5 | import kha.Color; 6 | import kha.Image; 7 | 8 | class Style 9 | { 10 | 11 | public var backColor:Color; 12 | public var border:Int; 13 | public var borderColor:Color; 14 | public var backState:Image; 15 | public var backSheetState:String; 16 | public var spritesheet:String; 17 | public var type:Int; 18 | 19 | public function new() 20 | { 21 | 22 | } 23 | 24 | 25 | static var _spritesheets:Map; 26 | public static var spritesheets(get, never):Map; 27 | static function get_spritesheets() 28 | { 29 | if (_spritesheets == null) 30 | _spritesheets = new Map(); 31 | 32 | return _spritesheets; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /twinspire/utils/Timer.hx: -------------------------------------------------------------------------------- 1 | package twinspire.utils; 2 | 3 | import kha.System; 4 | 5 | class Timer 6 | { 7 | 8 | private var _lastTime:Float; 9 | private var _dt:Float; 10 | private var _tickValues:Array; 11 | private var _tickValueIndex:Int; 12 | 13 | public function new(timers:Int) 14 | { 15 | _tickValues = []; 16 | 17 | for (i in 0...timers) 18 | _tickValues.push(0); 19 | 20 | _lastTime = System.time; 21 | } 22 | 23 | public function begin() 24 | { 25 | _tickValueIndex = -1; 26 | _dt = System.time - _lastTime; 27 | } 28 | 29 | public function tick(seconds:Float, ?index:Int = -1) 30 | { 31 | var index_in = 0; 32 | if (index > -1) 33 | index_in = index; 34 | else 35 | index_in = ++_tickValueIndex; 36 | 37 | _tickValues[index_in] += _dt; 38 | if (_tickValues[index_in] >= seconds) 39 | { 40 | _tickValues[index_in] = 0.0; 41 | return true; 42 | } 43 | 44 | return false; 45 | } 46 | 47 | public function end() 48 | { 49 | _tickValueIndex = -1; 50 | _lastTime = System.time; 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Twinspire 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /twinspire/render/spritesheet/SheetData.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | package twinspire.render.spritesheet; 11 | 12 | typedef SheetData = 13 | { 14 | var imageName:String; 15 | var data:Dynamic; 16 | } -------------------------------------------------------------------------------- /twinspire/geom/Size.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.geom; 12 | 13 | class Size 14 | { 15 | 16 | public var width:Float; 17 | public var height:Float; 18 | 19 | public inline function new(w:Float, h:Float) 20 | { 21 | width = w; 22 | height = h; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /twinspire/render/tilemap/ts/TileMap.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render.tilemap.ts; 12 | 13 | typedef TileMap = 14 | { 15 | var tileCountX:Int; 16 | var tileCountY:Int; 17 | var tilewidth:Int; 18 | var tileheight:Int; 19 | var layersFromPaths:Array; 20 | var tilesets:Array; 21 | } -------------------------------------------------------------------------------- /twinspire/render/tilemap/tiled/TileMapLayer.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render.tilemap.tiled; 12 | 13 | typedef TileMapLayer = 14 | { 15 | var data:Array; 16 | var height:Int; 17 | var name:String; 18 | var opacity:Float; 19 | var type:String; 20 | var visible:Bool; 21 | var width:Int; 22 | var x:Int; 23 | var y:Int; 24 | } -------------------------------------------------------------------------------- /twinspire/render/tilemap/tiled/Tileset.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render.tilemap.tiled; 12 | 13 | typedef Tileset = 14 | { 15 | var columns:Int; 16 | var firstgid:Int; 17 | var image:String; 18 | var imageheight:Int; 19 | var imagewidth:Int; 20 | var margin:Int; 21 | var name:String; 22 | var spacing:Int; 23 | var tilecount:Int; 24 | var tileheight:Int; 25 | var tilewidth:Int; 26 | } -------------------------------------------------------------------------------- /twinspire/geom/Rect.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.geom; 12 | 13 | class Rect 14 | { 15 | 16 | public var x:Float; 17 | public var y:Float; 18 | public var width:Float; 19 | public var height:Float; 20 | 21 | public inline function new(x:Float, y:Float, width:Float, height:Float) 22 | { 23 | this.x = x; 24 | this.y = y; 25 | this.width = width; 26 | this.height = height; 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /twinspire/render/tilemap/tiled/TileMap.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render.tilemap.tiled; 12 | 13 | typedef TileMap = 14 | { 15 | var layers:Array; 16 | var tilesets:Array; 17 | var tilewidth:Int; 18 | var tileheight:Int; 19 | var version:Int; 20 | var width:Int; 21 | var height:Int; 22 | var nextobjectid:Int; 23 | var orientation:String; 24 | var renderorder:String; 25 | } -------------------------------------------------------------------------------- /twinspire/render/tilemap/ts/Tileset.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render.tilemap.ts; 12 | 13 | typedef Tileset = 14 | { 15 | var assetName:String; 16 | var tilewidth:Float; 17 | var tileheight:Float; 18 | @:optional var canPassThrough:Array; 19 | @:optional var canPassLeft:Array; 20 | @:optional var canPassRight:Array; 21 | @:optional var canPassUp:Array; 22 | @:optional var canPassDown:Array; 23 | } -------------------------------------------------------------------------------- /twinspire/gui/Container.hx: -------------------------------------------------------------------------------- 1 | package twinspire.gui; 2 | 3 | import twinspire.events.Event; 4 | 5 | import twinspire.render.Object; 6 | 7 | import kha.math.FastVector2 in FV2; 8 | import kha.graphics2.Graphics; 9 | 10 | class Container extends Object 11 | { 12 | 13 | public var children:Array; 14 | 15 | public var clipping:Bool; 16 | 17 | public function new() 18 | { 19 | super(); 20 | 21 | children = []; 22 | clipping = true; 23 | } 24 | 25 | public function addObject(obj:Object) 26 | { 27 | obj.parent = this; 28 | children.push(obj); 29 | } 30 | 31 | public override function update(e:Event) 32 | { 33 | for (i in 0...children.length) 34 | { 35 | var child = children[i]; 36 | if ((child.position.x + child.offset.x + child.size.x > position.x && child.position.y + child.offset.y + child.size.y > position.y) || 37 | (child.position.x + child.offset.x < position.x + size.x && child.position.y + child.offset.y < position.y + size.y)) 38 | { 39 | child.update(e); 40 | } 41 | } 42 | } 43 | 44 | public override function render(g2:Graphics) 45 | { 46 | if (clipping) 47 | g2.scissor(cast position.x, cast position.y, cast size.x, cast size.y); 48 | 49 | for (i in 0...children.length) 50 | { 51 | var child = children[i]; 52 | if ((child.position.x + child.offset.x + child.size.x > position.x && child.position.y + child.offset.y + child.size.y > position.y) || 53 | (child.position.x + child.offset.x < position.x + size.x && child.position.y + child.offset.y < position.y + size.y)) 54 | { 55 | child.offset = new FV2(position.x, position.y); 56 | child.render(g2); 57 | } 58 | } 59 | 60 | if (clipping) 61 | g2.disableScissor(); 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /twinspire/render/SpriteSheet.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render; 12 | 13 | import twinspire.geom.Rect; 14 | 15 | import kha.Image; 16 | 17 | /** 18 | * The `SpriteSheet` class provides an easy, compact, collection of images mapped to certain specified rectangles. 19 | */ 20 | class SpriteSheet 21 | { 22 | 23 | /** 24 | * The image to use for this sprite sheet. 25 | */ 26 | public var image:Image; 27 | 28 | /** 29 | * A Map containing an array of rectangles associated with a given key. 30 | * This provides the ability to animate using the array as a sequence. 31 | */ 32 | public var map:Map>; 33 | 34 | public function new(image:Image) 35 | { 36 | this.image = image; 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## NOTICE 2 | This project is no longer in development. For a more up-to-date project, please see [Core](https://github.com/twinspire/Core). 3 | 4 | # Twinspire 5 | Twinspire is a 2D video game engine using the innovative Haxe programming language, built on-top of the low-level framework Kha. 6 | 7 | The main aim of Twinspire is not to be a complete package. It will provide some of the most basic and fundamental utilities required of a game engine, without striving too far into detail. 8 | 9 | Perhaps the one thing to note is that Twinspire will also come with an editor of sorts. GUI plays a major role in the development of this engine, primarily due to the lack of flexibility most other GUI options provide. 10 | 11 | ## Roadmap 12 | 13 | Twinspire, over the past few months, has seen various changes from left-to-right-to-centre. Even the current GUI options that exist may be temporary, but it is currently a prototype for the plan to expand into a fully-customisable `VectorMap`. You may have seen this in a previous iteration of the game engine, but was recently removed. 14 | 15 | Please be aware that the GUI that will eventually exist will be something that just makes so much sense it wouldn't even require thinking about it. But in order to accomplish this, so much consideration into the API needs to be accounted for. 16 | 17 | Other useful utilities will be added as and when they are tested and developed in other non-related projects. 18 | 19 | ## Installation 20 | You can either clone this repository on your computer and make it a haxelib dev directory (may be stable, use with caution). 21 | 22 | haxelib git twinspire https://github.com/twinspire/Twinspire.git 23 | 24 | Or install it directly from Haxelib (stable release): 25 | 26 | haxelib install twinspire 27 | 28 | ## Community and Support 29 | If you find a bug or an issue, please use the issue tracker here. 30 | 31 | You can also find and discuss information, updates and features on our [community forums](http://community.colour-id.co.uk/). -------------------------------------------------------------------------------- /twinspire/render/Tile.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render; 12 | 13 | import kha.math.FastVector2 in FV2; 14 | 15 | /** 16 | * A `Tile` is a simple class containing information useful to TileMap's. 17 | */ 18 | class Tile 19 | { 20 | 21 | /** 22 | * The index identifier used to determine what to draw for this tile. 23 | */ 24 | public var id:Int; 25 | /** 26 | * The `x` position of this tile. 27 | */ 28 | public var x:Float; 29 | /** 30 | * The `y` position of this tile. 31 | */ 32 | public var y:Float; 33 | 34 | /** 35 | * Create a Tile with the given index and position. 36 | * 37 | * @param id The index identifier used to determine what to draw for this tile. 38 | * @param pos The position that this tile will be drawn relative to its TileMap's position. 39 | */ 40 | public function new(id:Int, pos:FV2) 41 | { 42 | this.id = id; 43 | this.x = pos.x; 44 | this.y = pos.y; 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /twinspire/events/EventType.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.events; 12 | 13 | @:enum 14 | abstract EventType(Int) from Int to Int 15 | { 16 | /** 17 | * A mouse button is down. 18 | */ 19 | var EVENT_MOUSE_DOWN = 1; 20 | /** 21 | * A mouse button has released. 22 | */ 23 | var EVENT_MOUSE_UP = 2; 24 | /** 25 | * The mouse has moved. 26 | */ 27 | var EVENT_MOUSE_MOVE = 3; 28 | /** 29 | * The mouse wheel has moved. 30 | */ 31 | var EVENT_MOUSE_WHEEL = 4; 32 | /** 33 | * A keyboard button has been pressed down. 34 | */ 35 | var EVENT_KEY_DOWN = 5; 36 | /** 37 | * A keyboard button has been released. 38 | */ 39 | var EVENT_KEY_UP = 6; 40 | /** 41 | * A keyboard button has been pressed down and released. 42 | **/ 43 | var EVENT_KEY_PRESS = 12; 44 | /** 45 | * A gamepad axis has moved. 46 | */ 47 | var EVENT_GAMEPAD_AXIS = 7; 48 | /** 49 | * A gamepad button has been pressed. 50 | */ 51 | var EVENT_GAMEPAD_BUTTON = 8; 52 | /** 53 | * The game screen has been touched. 54 | */ 55 | var EVENT_TOUCH_START = 9; 56 | /** 57 | * Any or all fingers have been released from the game screen. 58 | */ 59 | var EVENT_TOUCH_END = 10; 60 | /** 61 | * Any or all fingers have moved on the game screen. 62 | */ 63 | var EVENT_TOUCH_MOVE = 11; 64 | } -------------------------------------------------------------------------------- /twinspire/utils/ExtraMath.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.utils; 12 | 13 | /** 14 | * A series of extra mathematical functions. 15 | */ 16 | class ExtraMath 17 | { 18 | 19 | /** 20 | * Round a floating-point number to the nearest integral or decimal number with the given precision. 21 | * 22 | * @param n The floating-point number to round. 23 | * @param prec The precision to round to. 24 | * 25 | * @return Return the resulting rounded value; 26 | */ 27 | public static function froundPrecise(n:Float, prec:Int) 28 | { 29 | var pow = Math.pow(10, prec); 30 | var result = Math.round((n * pow) / pow); 31 | return result; 32 | } 33 | 34 | /** 35 | * Gets the minimum number from a series of values. 36 | * 37 | * @param values The `values` to check. 38 | * 39 | * @return Returns the lowest value from the given array. 40 | */ 41 | public static function min(values:Array) 42 | { 43 | var result:Float = 0; 44 | for (v in values) 45 | { 46 | if (v < result) 47 | result = v; 48 | } 49 | 50 | return result; 51 | } 52 | 53 | /** 54 | * Gets the maximum number from a series of values. 55 | * 56 | * @param values The `values` to check. 57 | * 58 | * @return Returns the highest value from the given array. 59 | */ 60 | public static function max(values:Array) 61 | { 62 | var result:Float = 0; 63 | for (v in values) 64 | { 65 | if (v > result) 66 | result = v; 67 | } 68 | 69 | return result; 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /twinspire/gui/CheckBox.hx: -------------------------------------------------------------------------------- 1 | package twinspire.gui; 2 | 3 | using twinspire.events.EventType; 4 | import twinspire.events.Event; 5 | 6 | import twinspire.render.Object; 7 | import twinspire.render.Style; 8 | using twinspire.render.StyleType; 9 | 10 | import kha.math.FastVector2 in FV2; 11 | import kha.graphics2.Graphics; 12 | import kha.Color; 13 | import kha.Font; 14 | import kha.System; 15 | 16 | class CheckBox extends Object 17 | { 18 | 19 | private var _lblText:Label; 20 | 21 | public var onCheckChanged:Dynamic -> Void; 22 | 23 | public var font(get, set):Font; 24 | function get_font() return _lblText.font; 25 | function set_font(val) return _lblText.font = val; 26 | 27 | public var fontSize(get, set):Int; 28 | function get_fontSize() return _lblText.fontSize; 29 | function set_fontSize(val) return _lblText.fontSize = val; 30 | 31 | public var fontColor(get, set):Color; 32 | function get_fontColor() return _lblText.fontColor; 33 | function set_fontColor(val) return _lblText.fontColor = val; 34 | 35 | public var text(get, set):String; 36 | function get_text() return _lblText.text; 37 | function set_text(val) return _lblText.text = val; 38 | 39 | private var _checked:Bool; 40 | public var checked(get, set):Bool; 41 | function get_checked() return _checked; 42 | function set_checked(val) 43 | { 44 | if (onCheckChanged != null) 45 | onCheckChanged(this); 46 | return _checked = val; 47 | } 48 | 49 | public var padding:Int; 50 | 51 | public function new() 52 | { 53 | super(); 54 | 55 | style = new Style(); 56 | style.type = STYLE_BASIC; 57 | style.backColor = Color.fromFloats(.8, .8, .9); 58 | style.border = 1; 59 | style.borderColor = Color.Black; 60 | 61 | _lblText = new Label(); 62 | _lblText.autoSize = true; 63 | 64 | isInteractive = true; 65 | 66 | size.y = size.x = 24; 67 | 68 | padding = 4; 69 | } 70 | 71 | public override function update(e:Event) 72 | { 73 | super.update(e); 74 | } 75 | 76 | public override function render(g2:Graphics) 77 | { 78 | if (active && _mouseReleased) 79 | { 80 | checked = !checked; 81 | } 82 | 83 | super.render(g2); 84 | 85 | if (offset == null) 86 | offset = new FV2(0, 0); 87 | 88 | _lblText.position.x = position.x + size.x + padding; 89 | _lblText.position.y = ((size.y - _lblText.textHeight) / 2) + position.y; 90 | _lblText.render(g2); 91 | 92 | applyBasicStyle(g2, style); 93 | 94 | if (checked) 95 | { 96 | g2.color = style.borderColor; 97 | g2.drawLine(position.x + style.border / 2, position.y + style.border / 2, position.x + size.x, position.y + size.y, 2); 98 | g2.drawLine(position.y + style.border / 2, position.y + size.y - style.border / 2, position.x + size.x, position.y, 2); 99 | } 100 | } 101 | 102 | } -------------------------------------------------------------------------------- /twinspire/gui/Button.hx: -------------------------------------------------------------------------------- 1 | package twinspire.gui; 2 | 3 | using twinspire.events.EventType; 4 | import twinspire.events.Event; 5 | 6 | import twinspire.render.Object; 7 | using twinspire.render.StyleType; 8 | import twinspire.render.Style; 9 | 10 | import kha.math.FastVector2 in FV2; 11 | import kha.graphics2.Graphics; 12 | import kha.Color; 13 | import kha.Font; 14 | import kha.System; 15 | 16 | class Button extends Object 17 | { 18 | 19 | private var _lblText:Label; 20 | 21 | public var font(get, set):Font; 22 | function get_font() return _lblText.font; 23 | function set_font(val) return _lblText.font = val; 24 | 25 | public var fontSize(get, set):Int; 26 | function get_fontSize() return _lblText.fontSize; 27 | function set_fontSize(val) return _lblText.fontSize = val; 28 | 29 | public var fontColor(get, set):Int; 30 | function get_fontColor() return _lblText.fontColor; 31 | function set_fontColor(val) return _lblText.fontColor = val; 32 | 33 | public var text(get, set):String; 34 | function get_text() return _lblText.text; 35 | function set_text(val) return _lblText.text = val; 36 | 37 | public var padding:Int; 38 | 39 | public var autoSize:Bool; 40 | 41 | public var overStyle:Style; 42 | 43 | public var downStyle:Style; 44 | 45 | public function new() 46 | { 47 | super(); 48 | 49 | isInteractive = true; 50 | 51 | style = new Style(); 52 | style.type = STYLE_BASIC; 53 | style.backColor = Color.fromFloats(0, 0, .5); 54 | style.borderColor = Color.Black; 55 | 56 | overStyle = new Style(); 57 | overStyle.type = STYLE_BASIC; 58 | overStyle.backColor = Color.fromFloats(.3, .3, .6); 59 | overStyle.borderColor = Color.Black; 60 | 61 | downStyle = new Style(); 62 | downStyle.type = STYLE_BASIC; 63 | downStyle.backColor = Color.fromFloats(0, 0, .2); 64 | downStyle.borderColor = Color.Black; 65 | 66 | _lblText = new Label(); 67 | _lblText.autoSize = true; 68 | 69 | autoSize = true; 70 | 71 | padding = 4; 72 | } 73 | 74 | public override function update(e:Event) 75 | { 76 | super.update(e); 77 | } 78 | 79 | public override function render(g2:Graphics) 80 | { 81 | super.render(g2); 82 | 83 | var totalWidth = padding * 2 + style.border * 2 + _lblText.textWidth; 84 | var totalHeight = padding * 2 + style.border * 2 + _lblText.textHeight; 85 | 86 | if (autoSize) 87 | { 88 | size.x = totalWidth; 89 | size.y = totalHeight; 90 | } 91 | 92 | var currentStyle = style; 93 | if (active && _mouseDown) 94 | currentStyle = downStyle; 95 | else if (active || (active && _mouseReleased)) 96 | currentStyle = overStyle; 97 | 98 | if (offset == null) 99 | offset = new FV2(0, 0); 100 | 101 | applyBasicStyle(g2, currentStyle, offset); 102 | 103 | _lblText.position.x = position.x + padding + offset.x; 104 | _lblText.position.y = position.y + padding + offset.y; 105 | _lblText.alpha = alpha; 106 | _lblText.render(g2); 107 | } 108 | 109 | } -------------------------------------------------------------------------------- /twinspire/gui/RadioButton.hx: -------------------------------------------------------------------------------- 1 | package twinspire.gui; 2 | 3 | using twinspire.events.EventType; 4 | import twinspire.events.Event; 5 | 6 | import twinspire.render.Object; 7 | using twinspire.render.StyleType; 8 | import twinspire.render.Style; 9 | 10 | import kha.math.FastVector2 in FV2; 11 | import kha.graphics2.Graphics; 12 | using kha.graphics2.GraphicsExtension; 13 | import kha.Color; 14 | import kha.Font; 15 | import kha.System; 16 | 17 | class RadioButton extends Object 18 | { 19 | 20 | private var _lblText:Label; 21 | 22 | public var onCheckChanged:Dynamic -> Void; 23 | 24 | public var font(get, set):Font; 25 | function get_font() return _lblText.font; 26 | function set_font(val) return _lblText.font = val; 27 | 28 | public var fontSize(get, set):Int; 29 | function get_fontSize() return _lblText.fontSize; 30 | function set_fontSize(val) return _lblText.fontSize = val; 31 | 32 | public var fontColor(get, set):Int; 33 | function get_fontColor() return _lblText.fontColor; 34 | function set_fontColor(val) return _lblText.fontColor = val; 35 | 36 | public var text(get, set):String; 37 | function get_text() return _lblText.text; 38 | function set_text(val) return _lblText.text = val; 39 | 40 | private var _checked:Bool; 41 | public var checked(get, set):Bool; 42 | function get_checked() return _checked; 43 | function set_checked(val) 44 | { 45 | if (onCheckChanged != null) 46 | onCheckChanged(this); 47 | return _checked = val; 48 | } 49 | 50 | public var padding:Int; 51 | 52 | public function new() 53 | { 54 | super(); 55 | 56 | style = new Style(); 57 | style.type = STYLE_BASIC; 58 | style.backColor = Color.fromFloats(.8, .8, .9); 59 | style.border = 1; 60 | style.borderColor = Color.Black; 61 | 62 | _lblText = new Label(); 63 | _lblText.autoSize = true; 64 | 65 | isInteractive = true; 66 | 67 | size.x = size.y = 24; 68 | 69 | padding = 4; 70 | } 71 | 72 | public override function update(e:Event) 73 | { 74 | super.update(e); 75 | } 76 | 77 | public override function render(g2:Graphics) 78 | { 79 | if (active && _mouseReleased) 80 | { 81 | if (!checked) 82 | { 83 | if (parent != null) 84 | { 85 | for (child in parent.children) 86 | { 87 | if (Std.is(child, RadioButton)) 88 | (cast (child, RadioButton)).checked = false; 89 | } 90 | } 91 | 92 | checked = true; 93 | } 94 | } 95 | 96 | super.render(g2); 97 | 98 | if (offset == null) 99 | offset = new FV2(0, 0); 100 | 101 | applyBasicStyle(g2, style, offset); 102 | 103 | if (checked) 104 | { 105 | g2.color = style.borderColor; 106 | g2.fillRect(position.x + 2 + offset.x, position.y + 3 + offset.y, size.x - 5, size.y - 5); 107 | } 108 | 109 | _lblText.position.x = position.x + size.x + padding + offset.x; 110 | _lblText.position.y = ((size.y - _lblText.size.y) / 2) + position.y + offset.y; 111 | _lblText.alpha = alpha; 112 | _lblText.render(g2); 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /twinspire/events/Event.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.events; 12 | 13 | /** 14 | * The `Event` class contains data related to the event handling used internally by the `Game` class. 15 | */ 16 | class Event 17 | { 18 | 19 | /** 20 | * The type of event this is. Use `EventType` to check the types. 21 | */ 22 | public var type:Int; 23 | /** 24 | * The position of the mouse on the `x` axis, relative to the game client. 25 | */ 26 | public var mouseX:Int; 27 | /** 28 | * The position of the mouse on the `y` axis, relative to the game client. 29 | */ 30 | public var mouseY:Int; 31 | /** 32 | * Determines which mouse button was pressed. This value is zero-based. 33 | */ 34 | public var mouseButton:Int; 35 | /** 36 | * Determines by how much the mouse moved since the last event to MouseMove on the `x` axis. 37 | */ 38 | public var mouseMovementX:Int; 39 | /** 40 | * Determines by how much the mouse moved since the last event to MouseMove on the `y` axis. 41 | */ 42 | public var mouseMovementY:Int; 43 | /** 44 | * A value determining which direction the mouse wheel moved. 1 for down, -1 for up. 45 | */ 46 | public var mouseDelta:Int; 47 | /** 48 | * The key that was pressed during a KEY_EVENT. 49 | */ 50 | public var key:Int; 51 | /** 52 | * The key pressed during the EVENT_KEY_PRESS event. 53 | */ 54 | public var char:String; 55 | /** 56 | * The index of the gamepad currently in use. This value is zero-based. 57 | */ 58 | public var gamepadId:Int; 59 | /** 60 | * TODO: What is this? 61 | */ 62 | public var gamepadAxis:Int; 63 | /** 64 | * TODO: What is this? 65 | */ 66 | public var gamepadAxisValue:Float; 67 | /** 68 | * The gamepad button pressed. 69 | */ 70 | public var gamepadButton:Int; 71 | /** 72 | * TODO: What is this? 73 | */ 74 | public var gamepadButtonValue:Float; 75 | /** 76 | * TODO: What is this? 77 | */ 78 | public var touchIndex:Int; 79 | /** 80 | * The x position of the finger in the game. 81 | */ 82 | public var touchX:Int; 83 | /** 84 | * The y position of the finger in the game. 85 | */ 86 | public var touchY:Int; 87 | 88 | public function new() 89 | { 90 | 91 | } 92 | 93 | public function clone() 94 | { 95 | var e = new Event(); 96 | e.type = this.type; 97 | e.mouseX = this.mouseX; 98 | e.mouseY = this.mouseY; 99 | e.mouseButton = this.mouseButton; 100 | e.mouseMovementX = this.mouseMovementX; 101 | e.mouseMovementY = this.mouseMovementY; 102 | e.mouseDelta = this.mouseDelta; 103 | e.key = this.key; 104 | e.char = this.char; 105 | e.gamepadAxis = this.gamepadAxis; 106 | e.gamepadAxisValue = this.gamepadAxisValue; 107 | e.gamepadButton = this.gamepadButton; 108 | e.gamepadButtonValue = this.gamepadButtonValue; 109 | e.touchIndex = this.touchIndex; 110 | e.touchX = this.touchX; 111 | e.touchY = this.touchY; 112 | return e; 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /twinspire/render/Tileset.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render; 12 | 13 | import twinspire.geom.Rect; 14 | 15 | import kha.Image; 16 | 17 | /** 18 | * A `Tileset` is required for `TileMap`'s to enable the drawing of tiles. 19 | * 20 | * Tileset's contain basic data, including the individual `tilewidth` and `tileheight` for each tile in their respective `bitmap` image. 21 | */ 22 | class Tileset 23 | { 24 | 25 | /** 26 | * The width of each tile within the `bitmap`. 27 | */ 28 | public var tilewidth:Float; 29 | /** 30 | * The width of each tile within the `bitmap`. 31 | */ 32 | public var tileheight:Float; 33 | /** 34 | * The amount of tiles that can be found in this Tileset. 35 | * Set in the constructor. It is not recommended to change this value. 36 | */ 37 | public var tilecount:Int; 38 | /** 39 | * The image used for drawing tiles. 40 | */ 41 | public var bitmap:Image; 42 | /** 43 | * An array of boolean values, based on tile index, that determine if 44 | * the tile can be passed through. 45 | */ 46 | public var canPassThrough:Array; 47 | /** 48 | * An array of boolean values, based on tile index, that determine if 49 | * an object or player can pass left from this tile. 50 | */ 51 | public var canPassLeft:Array; 52 | /** 53 | * An array of boolean values, based on tile index, that determine if 54 | * an object or player can pass right from this tile. 55 | */ 56 | public var canPassRight:Array; 57 | /** 58 | * An array of boolean values, based on tile index, that determine if 59 | * an object or player can pass up from this tile. 60 | */ 61 | public var canPassUp:Array; 62 | /** 63 | * An array of boolean values, based on tile index, that determine if 64 | * an object or player can pass down from this tile. 65 | */ 66 | public var canPassDown:Array; 67 | 68 | /** 69 | * Create a `Tileset` with an image, and with its respective width and height for each tile. 70 | * 71 | * @param bitmap The `Image` asset to use as the basis for this Tileset. 72 | * @param tilewidth The width of each tile. 73 | * @param tileheight The height of each tile. 74 | */ 75 | public function new(bitmap:Image, tilewidth:Float, tileheight:Float) 76 | { 77 | this.bitmap = bitmap; 78 | 79 | this.tilewidth = tilewidth; 80 | this.tileheight = tileheight; 81 | 82 | tilecount = Math.floor(bitmap.realWidth / tilewidth) + Math.floor(bitmap.realHeight / tileheight); 83 | } 84 | 85 | /** 86 | * Gets a `Rect` defining the position and size of a given index within `bitmap`. 87 | * 88 | * @param index The index to search for. 89 | * 90 | * @return Returns a `Rect` defining the position and size of the given index. 91 | */ 92 | public function getSourceImageByIndex(index:Int):Rect 93 | { 94 | var tilesX = bitmap.realWidth / tilewidth; 95 | 96 | var col = index % tilesX; 97 | var row = Math.floor(index / tilesX); 98 | 99 | return new Rect(col * tilewidth, row * tileheight, tilewidth, tileheight); 100 | } 101 | 102 | } -------------------------------------------------------------------------------- /twinspire/render/Object.hx: -------------------------------------------------------------------------------- 1 | package twinspire.render; 2 | 3 | using twinspire.events.EventType; 4 | import twinspire.events.Event; 5 | import twinspire.gui.Container; 6 | 7 | import kha.math.FastVector2 in FV2; 8 | import kha.math.FastVector4 in FV4; 9 | import kha.graphics2.Graphics; 10 | import kha.System; 11 | 12 | class Object 13 | { 14 | 15 | private var _lastTime:Float; 16 | private var _mouseDown:Bool; 17 | private var _mouseReleased:Bool; 18 | private var _mouseX:Int; 19 | private var _mouseY:Int; 20 | private var _doubleClickInterval:Float; 21 | private var _doubleClickCurrent:Float; 22 | private var _clickOnce:Bool; 23 | 24 | public var onClick:Dynamic -> Void; 25 | 26 | public var onDoubleClick:Dynamic -> Void; 27 | 28 | public var isInteractive:Bool; 29 | 30 | public var position:FV2; 31 | 32 | public var offset:FV2; 33 | 34 | public var size:FV2; 35 | 36 | public var alpha:Float; 37 | 38 | public var style:Style; 39 | 40 | public var parent:Container; 41 | 42 | private var _active:Bool; 43 | public var active(get, never):Bool; 44 | function get_active() 45 | { 46 | if (_mouseX != null || _mouseY != null) 47 | { 48 | _active = (_mouseX > position.x + offset.x && _mouseX < position.x + size.x + offset.x && 49 | _mouseY > position.y + offset.y && _mouseY < position.y + size.y + offset.y); 50 | } 51 | return _active; 52 | } 53 | 54 | public function new() 55 | { 56 | position = new FV2(0, 0); 57 | size = new FV2(100, 100); 58 | offset = new FV2(0, 0); 59 | alpha = 1; 60 | _clickOnce = false; 61 | isInteractive = false; 62 | 63 | _doubleClickInterval = 0.75; 64 | 65 | _lastTime = System.time; 66 | } 67 | 68 | public function update(e:Event) 69 | { 70 | if (isInteractive) 71 | { 72 | if (e.type == EVENT_MOUSE_MOVE) 73 | { 74 | _mouseX = e.mouseX; 75 | _mouseY = e.mouseY; 76 | } 77 | else if (e.type == EVENT_MOUSE_DOWN) 78 | { 79 | _mouseDown = true; 80 | } 81 | else if (e.type == EVENT_MOUSE_UP) 82 | { 83 | _mouseReleased = true; 84 | _mouseDown = false; 85 | } 86 | } 87 | } 88 | 89 | public function render(g2:Graphics) 90 | { 91 | var dt = System.time - _lastTime; 92 | 93 | _doubleClickCurrent += dt; 94 | if (active && _clickOnce && _doubleClickCurrent >= _doubleClickInterval) 95 | { 96 | _doubleClickCurrent = 0; 97 | _clickOnce = false; 98 | } 99 | 100 | if (active && _mouseReleased) 101 | { 102 | if (onClick != null) 103 | onClick(this); 104 | 105 | if (_clickOnce && _doubleClickCurrent <= _doubleClickInterval) 106 | { 107 | if (onDoubleClick != null) 108 | onDoubleClick(this); 109 | 110 | _doubleClickCurrent = 0; 111 | _clickOnce = false; 112 | } 113 | else 114 | _clickOnce = true; 115 | } 116 | 117 | _lastTime = System.time; 118 | _mouseReleased = false; 119 | } 120 | 121 | public function align(alignment:FV2, ?against:Null = null, ?obj:Null = null) 122 | { 123 | var x = 0.0; 124 | var y = 0.0; 125 | var width = 0.0; 126 | var height = 0.0; 127 | 128 | if (against != null) 129 | { 130 | x = against.x; 131 | y = against.y; 132 | width = against.z; 133 | height = against.w; 134 | } 135 | else if (obj != null) 136 | { 137 | x = obj.position.x; 138 | y = obj.position.y; 139 | width = obj.size.x; 140 | height = obj.size.y; 141 | } 142 | else 143 | { 144 | width = System.windowWidth(); 145 | height = System.windowHeight(); 146 | } 147 | 148 | position.x = ((alignment.x * width) - (alignment.x * size.x)) + x; 149 | position.y = ((alignment.y * height) - (alignment.y * size.y)) + y; 150 | } 151 | 152 | private function applyBasicStyle(g2:Graphics, style:Style, ?offset:FV2 = null) 153 | { 154 | var backColor = style.backColor; 155 | var borderColor = style.borderColor; 156 | 157 | if (offset == null) 158 | offset = new FV2(0, 0); 159 | 160 | if (style.border > 0) 161 | { 162 | borderColor.A = alpha; 163 | g2.color = borderColor; 164 | g2.drawRect(position.x + offset.x, position.y + offset.y, size.x, size.y, style.border); 165 | } 166 | 167 | backColor.A = alpha; 168 | g2.color = backColor; 169 | g2.fillRect(position.x + offset.x + style.border / 2, position.y + offset.y + style.border / 2, size.x - style.border, size.y - style.border / 2); 170 | } 171 | 172 | } -------------------------------------------------------------------------------- /twinspire/gui/Label.hx: -------------------------------------------------------------------------------- 1 | package twinspire.gui; 2 | 3 | import twinspire.events.Event; 4 | import twinspire.render.Object; 5 | 6 | import kha.Image; 7 | import kha.Color; 8 | import kha.Font; 9 | import kha.math.FastVector2 in FV2; 10 | import kha.graphics2.Graphics; 11 | 12 | using StringTools; 13 | 14 | class Label extends Object 15 | { 16 | 17 | private var _lines:Array; 18 | private var _previousText:String; 19 | 20 | /** 21 | * The text to display. 22 | */ 23 | public var text:String; 24 | /** 25 | * The font to use for the text. 26 | */ 27 | public var font:Font; 28 | /** 29 | * The size of the font. 30 | */ 31 | public var fontSize:Int; 32 | /** 33 | * The color of the font. 34 | */ 35 | public var fontColor:Color; 36 | /** 37 | * When set, the text will draw to a maximum width. 38 | */ 39 | public var maxWidth:Float; 40 | /** 41 | * The scroll value of the label, which will move the text up or 42 | * down. 43 | */ 44 | public var scrollV:Int; 45 | /** 46 | * Specifies the number of pixel spacing between each line. Default is 2. 47 | */ 48 | public var lineSpacing:Int; 49 | /** 50 | * The width of the object will be reflected by the total width of the text. 51 | */ 52 | public var autoSize:Bool; 53 | /** 54 | * Determines whether to cast a shadow. 55 | */ 56 | public var shadow:Bool; 57 | /** 58 | * The color of the shadow. 59 | */ 60 | public var shadowColor:Color; 61 | /** 62 | * The x position of the shadow from the text. 63 | */ 64 | public var shadowX:Int; 65 | /** 66 | * The y position of the shadow from the text. 67 | */ 68 | public var shadowY:Int; 69 | 70 | public var textWidth(get, never):Float; 71 | 72 | public var textHeight(get, never):Float; 73 | 74 | public function new() 75 | { 76 | super(); 77 | 78 | fontSize = 15; 79 | fontColor = Color.White; 80 | shadowColor = Color.Black; 81 | shadow = false; 82 | shadowX = 1; 83 | shadowY = 1; 84 | lineSpacing = 2; 85 | _lines = []; 86 | _previousText = ""; 87 | autoSize = false; 88 | 89 | maxWidth = 150; 90 | } 91 | 92 | public override function update(e:Event) 93 | { 94 | 95 | } 96 | 97 | public override function render(g2:Graphics) 98 | { 99 | super.render(g2); 100 | 101 | if (text != null && font != null) 102 | { 103 | if (_previousText != text) 104 | { 105 | _lines = []; 106 | if (maxWidth > -1 && !autoSize) 107 | processLines(); 108 | else 109 | { 110 | var _text = text; 111 | _text = text.replace("\r", ""); 112 | _text = text.replace("\n", ""); 113 | _lines.push(_text); 114 | } 115 | _previousText = text; 116 | } 117 | 118 | var heightLimit = _lines.length * font.height(fontSize) + lineSpacing; 119 | if (size.y > heightLimit) 120 | size.y = heightLimit; 121 | 122 | var maxLinesInLabel = Math.floor(size.y / font.height(fontSize)); 123 | if (scrollV + maxLinesInLabel > _lines.length) 124 | scrollV = _lines.length - maxLinesInLabel; 125 | 126 | if (scrollV < 0) 127 | scrollV = 0; 128 | 129 | var lineIndex:Int = 0 + scrollV; 130 | 131 | g2.font = font; 132 | g2.fontSize = fontSize; 133 | var fontHeight = font.height(fontSize); 134 | 135 | size.x = textWidth; 136 | 137 | if (offset == null) 138 | offset = new FV2(0, 0); 139 | 140 | if (shadow) 141 | { 142 | shadowColor.A = alpha; 143 | g2.color = shadowColor; 144 | g2.font = font; 145 | g2.fontSize = fontSize; 146 | 147 | for (i in 0...maxLinesInLabel) 148 | { 149 | var spaceY = i * fontHeight + lineSpacing * i; 150 | if (i == 0) 151 | spaceY = 0; 152 | if (i < _lines.length) 153 | { 154 | g2.drawString(_lines[i], position.x + shadowX + offset.x, position.y + spaceY + shadowY + offset.y); 155 | } 156 | else 157 | break; 158 | } 159 | 160 | // if (shadowBlurAmount > 0) 161 | // { 162 | // BitmapFilter.blur(bitmapFilter, shadowBlurAmount); 163 | // } 164 | 165 | //g2.drawImage(bitmapFilter, , ); 166 | } 167 | 168 | for (i in 0...maxLinesInLabel) 169 | { 170 | var spaceY = i * fontHeight + lineSpacing * i; 171 | if (i == 0) 172 | spaceY = 0; 173 | if (i < _lines.length) 174 | { 175 | fontColor.A = alpha; 176 | g2.color = fontColor; 177 | g2.drawString(_lines[i], position.x + offset.x, position.y + spaceY + offset.y); 178 | } 179 | else 180 | break; 181 | } 182 | } 183 | } 184 | 185 | private function processLines() 186 | { 187 | if (text == null) 188 | return; 189 | 190 | var lines = text.split('\n'); 191 | var currentLine = ""; 192 | var currentWord = ""; 193 | for (line in lines) 194 | { 195 | var firstWord = false; 196 | for (i in 0...line.length) 197 | { 198 | var char = line.charAt(i); 199 | if (char == "\r") 200 | { 201 | if (currentWord != "") 202 | currentLine += currentWord; 203 | 204 | if (currentLine != "") 205 | _lines.push(currentLine); 206 | 207 | currentLine = ""; 208 | currentWord = ""; 209 | _lines.push("\n"); 210 | } 211 | else if (char == " ") 212 | { 213 | var currentLineWidth = font.width(fontSize, currentLine + " " + currentWord); 214 | if (currentLineWidth < maxWidth) 215 | { 216 | currentLine += currentWord + " "; 217 | currentWord = ""; 218 | continue; 219 | } 220 | else if (currentLineWidth >= maxWidth) 221 | { 222 | _lines.push(currentLine); 223 | firstWord = true; 224 | currentLine = ""; 225 | } 226 | } 227 | else 228 | { 229 | if (firstWord) 230 | { 231 | currentLine += currentWord + " "; 232 | currentWord = ""; 233 | firstWord = false; 234 | } 235 | 236 | var currentLineWidth = font.width(fontSize, currentLine + char); 237 | if (currentLineWidth < maxWidth) 238 | { 239 | currentWord += char; 240 | continue; 241 | } 242 | else if (currentLineWidth >= maxWidth) 243 | { 244 | currentWord += char; 245 | _lines.push(currentLine); 246 | currentLine = ""; 247 | } 248 | } 249 | } 250 | 251 | if (currentWord != "") 252 | currentLine += currentWord; 253 | 254 | if (currentLine != "") 255 | _lines.push(currentLine); 256 | } 257 | } 258 | 259 | private function get_textWidth() 260 | { 261 | var result:Float = 0; 262 | if (autoSize && text != null) 263 | { 264 | var _text = text; 265 | _text = text.replace("\r", ""); 266 | _text = text.replace("\n", ""); 267 | _lines.push(_text); 268 | } 269 | else 270 | { 271 | if (maxWidth > 0) 272 | processLines(); 273 | else 274 | result = size.x; 275 | } 276 | 277 | if (maxWidth > 0) 278 | { 279 | for (i in 0..._lines.length) 280 | if (result < font.width(fontSize, _lines[i])) 281 | result = font.width(fontSize, _lines[i]); 282 | } 283 | 284 | return result; 285 | } 286 | 287 | private function get_textHeight() 288 | { 289 | var result:Float = 0; 290 | 291 | if (autoSize) 292 | result = font.height(fontSize); 293 | else 294 | result = size.y; 295 | 296 | return result; 297 | } 298 | 299 | } -------------------------------------------------------------------------------- /twinspire/Application.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | 10 | */ 11 | 12 | package twinspire; 13 | 14 | import twinspire.events.Event; 15 | 16 | import kha.math.FastVector2 in FV2; 17 | import kha.math.FastVector3 in FV3; 18 | import kha.math.FastVector4 in FV4; 19 | import kha.math.Vector2 in V2; 20 | import kha.math.Vector4 in V4; 21 | import kha.graphics2.Graphics in Graphics2; 22 | import kha.input.Gamepad; 23 | import kha.input.Keyboard; 24 | import kha.input.Mouse; 25 | import kha.input.Surface; 26 | import kha.Font; 27 | import kha.System; 28 | import kha.Assets; 29 | import kha.Framebuffer; 30 | import kha.Image; 31 | import kha.Blob; 32 | 33 | import haxe.Json; 34 | 35 | using twinspire.events.EventType; 36 | using StringTools; 37 | 38 | /** 39 | * The `Application` class handles primarily event handling in a coherent manner. 40 | * 41 | * No rendering is done in the Application class. 42 | */ 43 | class Application 44 | { 45 | 46 | private var g2:Graphics2; 47 | private var _events:Array; 48 | private var _error:String; 49 | 50 | /** 51 | * Gets the currently polled event. 52 | */ 53 | public var currentEvent:Event; 54 | 55 | /** 56 | * Create a `Game`, initialise the system and load all available assets. 57 | * 58 | * @param options The system options used to declare title and size of the game client. 59 | * @param callback The function handler that is called when all assets have been loaded. 60 | */ 61 | public static function create(options:SystemOptions, callback:Void -> Void) 62 | { 63 | System.init(options, function() 64 | { 65 | Assets.loadEverything(function() 66 | { 67 | instance = new Application(); 68 | 69 | callback(); 70 | }); 71 | }); 72 | } 73 | 74 | public function new() 75 | { 76 | initEvents(); 77 | } 78 | 79 | // Event Handling routines 80 | 81 | private function initEvents() 82 | { 83 | _events = []; 84 | 85 | if (Keyboard.get(0) != null) 86 | Keyboard.get(0).notify(_keyboard_onKeyDown, _keyboard_onKeyUp, _keyboard_onKeyPress); 87 | 88 | if (Mouse.get(0) != null) 89 | Mouse.get(0).notify(_mouse_onMouseDown, _mouse_onMouseUp, _mouse_onMouseMove, _mouse_onMouseWheel); 90 | 91 | if (Gamepad.get(0) != null) 92 | Gamepad.get(0).notify(_gamepad_onAxis0, _gamepad_onButton0); 93 | 94 | if (Gamepad.get(1) != null) 95 | Gamepad.get(1).notify(_gamepad_onAxis1, _gamepad_onButton1); 96 | 97 | if (Gamepad.get(2) != null) 98 | Gamepad.get(2).notify(_gamepad_onAxis2, _gamepad_onButton2); 99 | 100 | if (Gamepad.get(3) != null) 101 | Gamepad.get(3).notify(_gamepad_onAxis3, _gamepad_onButton3); 102 | 103 | if (Surface.get(0) != null) 104 | Surface.get(0).notify(_surface_onTouchStart, _surface_onTouchEnd, _surface_onTouchMove); 105 | } 106 | 107 | /** 108 | * Processes all of the events currently waiting in the event queue 109 | * until there is none left. This should be called before any rendering 110 | * takes place. 111 | * 112 | * @return Returns `true` if there are events waiting to be processed. Otherwise `false`. 113 | */ 114 | public function pollEvent():Bool 115 | { 116 | if (_events.length == 0) 117 | { 118 | currentEvent = null; 119 | return false; 120 | } 121 | 122 | currentEvent = _events[0].clone(); 123 | _events.splice(0, 1); 124 | return true; 125 | } 126 | 127 | // Initialisation routines. 128 | 129 | /** 130 | * Begin rendering and reference the buffer. 131 | * 132 | * @param buffer The `Framebuffer` used to draw graphics to the game client. 133 | */ 134 | public function begin(buffer:Framebuffer) 135 | { 136 | g2 = buffer.g2; 137 | } 138 | 139 | /** 140 | * End rendering and set all values to their defaults before the next frame. 141 | */ 142 | public function end() 143 | { 144 | 145 | } 146 | 147 | /** 148 | * Retrieve the most recent error. 149 | * 150 | * @return Returns the `_error` value of the most recently detected error. 151 | */ 152 | public function error() return _error; 153 | 154 | 155 | /** 156 | * Event handling functions 157 | */ 158 | 159 | private function _keyboard_onKeyDown(key:Int) 160 | { 161 | var e = new Event(); 162 | e.type = EVENT_KEY_DOWN; 163 | e.key = key; 164 | _events.push(e); 165 | } 166 | 167 | private function _keyboard_onKeyUp(key:Int) 168 | { 169 | var e = new Event(); 170 | e.type = EVENT_KEY_UP; 171 | e.key = key; 172 | _events.push(e); 173 | } 174 | 175 | private function _keyboard_onKeyPress(char:String) 176 | { 177 | var e = new Event(); 178 | e.type = EVENT_KEY_PRESS; 179 | e.char = char; 180 | _events.push(e); 181 | } 182 | 183 | private function _mouse_onMouseDown(button:Int, x:Int, y:Int) 184 | { 185 | var e = new Event(); 186 | e.type = EVENT_MOUSE_DOWN; 187 | e.mouseButton = button; 188 | e.mouseX = x; 189 | e.mouseY = y; 190 | _events.push(e); 191 | } 192 | 193 | private function _mouse_onMouseUp(button:Int, x:Int, y:Int) 194 | { 195 | var e = new Event(); 196 | e.type = EVENT_MOUSE_UP; 197 | e.mouseButton = button; 198 | e.mouseX = x; 199 | e.mouseY = y; 200 | _events.push(e); 201 | } 202 | 203 | private function _mouse_onMouseMove(x:Int, y:Int, movementX:Int, movementY:Int) 204 | { 205 | var e = new Event(); 206 | e.type = EVENT_MOUSE_MOVE; 207 | e.mouseX = x; 208 | e.mouseY = y; 209 | e.mouseMovementX = movementX; 210 | e.mouseMovementY = movementY; 211 | _events.push(e); 212 | } 213 | 214 | private function _mouse_onMouseWheel(delta:Int) 215 | { 216 | var e = new Event(); 217 | e.type = EVENT_MOUSE_WHEEL; 218 | e.mouseDelta = delta; 219 | _events.push(e); 220 | } 221 | 222 | private function _gamepad_onAxis0(axis:Int, value:Float) 223 | { 224 | var e = new Event(); 225 | e.type = EVENT_GAMEPAD_AXIS; 226 | e.gamepadId = 0; 227 | e.gamepadAxis = axis; 228 | e.gamepadAxisValue = value; 229 | _events.push(e); 230 | } 231 | 232 | private function _gamepad_onButton0(button:Int, value:Float) 233 | { 234 | var e = new Event(); 235 | e.type = EVENT_GAMEPAD_BUTTON; 236 | e.gamepadId = 0; 237 | e.gamepadButton = button; 238 | e.gamepadButtonValue = value; 239 | _events.push(e); 240 | } 241 | 242 | private function _gamepad_onAxis1(axis:Int, value:Float) 243 | { 244 | var e = new Event(); 245 | e.type = EVENT_GAMEPAD_AXIS; 246 | e.gamepadId = 1; 247 | e.gamepadAxis = axis; 248 | e.gamepadAxisValue = value; 249 | _events.push(e); 250 | } 251 | 252 | private function _gamepad_onButton1(button:Int, value:Float) 253 | { 254 | var e = new Event(); 255 | e.type = EVENT_GAMEPAD_BUTTON; 256 | e.gamepadId = 1; 257 | e.gamepadButton = button; 258 | e.gamepadButtonValue = value; 259 | _events.push(e); 260 | } 261 | 262 | private function _gamepad_onAxis2(axis:Int, value:Float) 263 | { 264 | var e = new Event(); 265 | e.type = EVENT_GAMEPAD_AXIS; 266 | e.gamepadId = 2; 267 | e.gamepadAxis = axis; 268 | e.gamepadAxisValue = value; 269 | _events.push(e); 270 | } 271 | 272 | private function _gamepad_onButton2(button:Int, value:Float) 273 | { 274 | var e = new Event(); 275 | e.type = EVENT_GAMEPAD_BUTTON; 276 | e.gamepadId = 2; 277 | e.gamepadButton = button; 278 | e.gamepadButtonValue = value; 279 | _events.push(e); 280 | } 281 | 282 | private function _gamepad_onAxis3(axis:Int, value:Float) 283 | { 284 | var e = new Event(); 285 | e.type = EVENT_GAMEPAD_AXIS; 286 | e.gamepadId = 3; 287 | e.gamepadAxis = axis; 288 | e.gamepadAxisValue = value; 289 | _events.push(e); 290 | } 291 | 292 | private function _gamepad_onButton3(button:Int, value:Float) 293 | { 294 | var e = new Event(); 295 | e.type = EVENT_GAMEPAD_BUTTON; 296 | e.gamepadId = 3; 297 | e.gamepadButton = button; 298 | e.gamepadButtonValue = value; 299 | _events.push(e); 300 | } 301 | 302 | private function _surface_onTouchStart(index:Int, x:Int, y:Int) 303 | { 304 | var e = new Event(); 305 | e.type = EVENT_TOUCH_START; 306 | e.touchIndex = index; 307 | e.touchX = x; 308 | e.touchY = y; 309 | _events.push(e); 310 | } 311 | 312 | private function _surface_onTouchEnd(index:Int, x:Int, y:Int) 313 | { 314 | var e = new Event(); 315 | e.type = EVENT_TOUCH_END; 316 | e.touchIndex = index; 317 | e.touchX = x; 318 | e.touchY = y; 319 | _events.push(e); 320 | } 321 | 322 | private function _surface_onTouchMove(index:Int, x:Int, y:Int) 323 | { 324 | var e = new Event(); 325 | e.type = EVENT_TOUCH_MOVE; 326 | e.touchIndex = index; 327 | e.touchX = x; 328 | e.touchY = y; 329 | _events.push(e); 330 | } 331 | 332 | 333 | public static var instance:Application; 334 | 335 | } -------------------------------------------------------------------------------- /twinspire/render/TileMap.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire.render; 12 | 13 | import twinspire.geom.Rect; 14 | import kha.math.FastVector2 in FV2; 15 | import kha.graphics2.Graphics; 16 | import kha.System; 17 | 18 | /** 19 | * A `TileMap` provides a 2D landscape for drawing levels using tiles. 20 | */ 21 | class TileMap 22 | { 23 | 24 | private var _lastLayerIndex:Int; 25 | private var _lastTileIndex:Int; 26 | private var _tileCountX:Int; 27 | private var _tileCountY:Int; 28 | private var _tiles:Array>; 29 | private var _indexCount:Int; 30 | private var _setMap:Map; 31 | private var _setIndices:Array; 32 | private var _extraData:Map; 33 | 34 | /** 35 | * The width of each tile in the TileMap. 36 | */ 37 | public var tilewidth:Int; 38 | 39 | /** 40 | * The height of each tile in the TileMap. 41 | */ 42 | public var tileheight:Int; 43 | 44 | /** 45 | * Determines if Tilesets are bound to each individual tile layer, or 46 | * if they can be used across all tile layers. 47 | */ 48 | public var isLayerRestricted:Bool; 49 | /** 50 | * Specifies the position of the map and where to draw it. 51 | */ 52 | public var position:FV2; 53 | 54 | /** 55 | * Creates a `TileMap` with the given tile width and height. 56 | * 57 | * @param tilewidth The width of each tile. 58 | * @param tileheight The height of each tile. 59 | */ 60 | public function new(tilecountX:Int, tilecountY:Int, tilewidth:Int, tileheight:Int) 61 | { 62 | _setMap = new Map(); 63 | _tiles = [[]]; 64 | _setIndices = []; 65 | _indexCount = 0; 66 | _extraData = new Map(); 67 | position = new FV2(0, 0); 68 | 69 | this.tilewidth = tilewidth; 70 | this.tileheight = tileheight; 71 | _tileCountX = tilecountX; 72 | _tileCountY = tilecountY; 73 | 74 | isLayerRestricted = true; 75 | 76 | _tiles.splice(0, _tiles.length); 77 | } 78 | 79 | /** 80 | * Set a key/value pair for a given tile index. 81 | * 82 | * @param index The tile index to store the key/value pair in. 83 | * @param name The name of the key to use. 84 | * @param value The value to store for the given name. 85 | */ 86 | public function setExtraData(index:Int, name:String, value:Dynamic) 87 | { 88 | _extraData.set(name + "_" + index, value); 89 | } 90 | 91 | /** 92 | * Gets the value stored for a given tile index with its respective name. 93 | * 94 | * @param index The tile index to look for. 95 | * @param name The name of the extra data to look for. 96 | * 97 | * @return Returns the value associated with the given tile index and name. 98 | */ 99 | public function getExtraData(index:Int, name:String):Dynamic 100 | { 101 | return _extraData.get(name + "_" + index); 102 | } 103 | 104 | /** 105 | * Add a series of tiles onto the next layer. The tiles will not render 106 | * without an available Tileset. 107 | * 108 | * @param tiles An array of tiles. 109 | */ 110 | public function addTilelayer(tiles:Array) 111 | { 112 | _tiles.push(tiles); 113 | } 114 | 115 | /** 116 | * Add a `Tileset` to the `TileMap`. 117 | * 118 | * @param set The Tileset to add. 119 | */ 120 | public function addTileset(set:Tileset) 121 | { 122 | _setIndices.push(_indexCount); 123 | _setMap.set(_indexCount, set); 124 | _indexCount += set.tilecount; 125 | } 126 | 127 | /** 128 | * Add a layer containing an array of tiles with a tileset. 129 | * 130 | * @param tiles An array of tiles. 131 | * @param set The Tileset to add. 132 | */ 133 | public function addLayer(tiles:Array, set:Tileset) 134 | { 135 | _tiles.push(tiles); 136 | _setIndices.push(_indexCount); 137 | _setMap.set(_indexCount, set); 138 | _indexCount += set.tilecount; 139 | } 140 | 141 | /** 142 | * Gets the index of a tile at a given position. 143 | * 144 | * @param pos The position to look for. 145 | * @param layer The layer to search. Default is 0, the first layer. 146 | * 147 | * @return Returns the index of a tile at a given position. If no tile exists for that position, or 148 | * the given layer is out of bounds, -1 is returned. 149 | */ 150 | public function getTileAtPoint(pos:FV2, layer:Int = 0):Tile 151 | { 152 | if (layer >= 0 && layer < _tiles.length) 153 | { 154 | var tileX = Math.floor(pos.x / tilewidth); 155 | var tileY = Math.floor(pos.y / tileheight); 156 | _lastTileIndex = _tileCountX * tileY + tileX; 157 | _lastLayerIndex = layer; 158 | return _tiles[layer][_lastTileIndex]; 159 | } 160 | 161 | return null; 162 | } 163 | 164 | /** 165 | * Gets a boolean value to determine if the tile can be 166 | * passed through; is traversable. 167 | * 168 | * @param t The `Tile` value to check in the Tileset for a given layer. 169 | * @param layer The layer to use for the Tileset. 170 | * 171 | * @return Returns a boolean value determining if the tile can be passed through. 172 | */ 173 | public function canPassThroughTile(t:Tile, ?layer:Int = -1):Bool 174 | { 175 | if (t == null) 176 | return false; 177 | 178 | if (layer == -1) 179 | { 180 | var result = false; 181 | var first = true; 182 | for (i in 0..._tiles.length) 183 | { 184 | var set = getTilesetForIndex(t.id, i); 185 | var index = resolveTilesetIndex(t.id); 186 | result = set.canPassThrough[index]; 187 | if (!first && !result) 188 | break; 189 | first = false; 190 | } 191 | return result; 192 | } 193 | else if (layer >= 0 && layer < _tiles.length) 194 | { 195 | var set = getTilesetForIndex(t.id, layer); 196 | return set.canPassThrough[resolveTilesetIndex(t.id)]; 197 | } 198 | 199 | return false; 200 | } 201 | 202 | /** 203 | * Gets a boolean value to determine if a tile can be 204 | * passed out from the left, given that the tile on its respective left can be passed from 205 | * its right. If neither the tile on the left can be passed into, nor the current tile can 206 | * pass left, then the result is `false`. If checking multiple layers, a boolean value can be `true` 207 | * if the tile on the left is non-existent on higher layers. 208 | * 209 | * @param t The `Tile` value to check in the Tileset for a given layer. 210 | * @param layer The layer to use for the Tileset. If -1, all layers will be scanned. 211 | * 212 | * @return Returns a boolean value determining if the tile can be passed from the left. 213 | */ 214 | public function canPassLeftFromTile(t:Tile, ?layer:Int = -1):Bool 215 | { 216 | if (t == null) 217 | return false; 218 | 219 | if (layer == -1) 220 | { 221 | var result = false; 222 | var first = true; 223 | for (i in 0..._tiles.length) 224 | { 225 | var leftTile = getTileAtPoint(new FV2(t.x - tilewidth, t.y), i); 226 | if (leftTile == null && first) 227 | return false; 228 | 229 | var currentSet = getTilesetForIndex(t.id, i); 230 | var currentIndex = resolveTilesetIndex(t.id); 231 | if (leftTile != null) 232 | { 233 | var leftSet = getTilesetForIndex(leftTile.id, i); 234 | result = (currentSet.canPassLeft[currentIndex] && leftSet.canPassRight[resolveTilesetIndex(leftTile.id)]); 235 | } 236 | else 237 | result = currentSet.canPassLeft[currentIndex]; 238 | 239 | if (!first && !result) 240 | break; 241 | 242 | first = false; 243 | } 244 | return result; 245 | } 246 | else if (layer >= 0 && layer < _tiles.length) 247 | { 248 | var leftTile = getTileAtPoint(new FV2(t.x - tilewidth, t.y), layer); 249 | if (leftTile == null && layer == 0) 250 | return false; 251 | 252 | var set = getTilesetForIndex(t.id, layer); 253 | if (leftTile != null) 254 | { 255 | var leftSet = getTilesetForIndex(leftTile.id, layer); 256 | return (set.canPassLeft[resolveTilesetIndex(t.id)] && leftSet.canPassRight[resolveTilesetIndex(leftTile.id)]); 257 | } 258 | else 259 | return set.canPassLeft[resolveTilesetIndex(t.id)]; 260 | 261 | } 262 | 263 | return false; 264 | } 265 | 266 | /** 267 | * Gets a boolean value to determine if a tile can be 268 | * passed out from the right, given that the tile on its respective right can be passed from 269 | * its left. If neither the tile on the right can be passed into, nor the current tile can 270 | * pass right, then the result is `false`. If checking multiple layers, a boolean value can be `true` 271 | * if the tile on the right is non-existent on higher layers. 272 | * 273 | * @param t The `Tile` value to check in the Tileset for a given layer. 274 | * @param layer The layer to use for the Tileset. If -1, all layers will be scanned. 275 | * 276 | * @return Returns a boolean value determining if the tile can be passed from the right. 277 | */ 278 | public function canPassRightFromTile(t:Tile, ?layer:Int = -1):Bool 279 | { 280 | if (t == null) 281 | return false; 282 | 283 | if (layer == -1) 284 | { 285 | var result = false; 286 | var first = true; 287 | for (i in 0..._tiles.length) 288 | { 289 | var rightTile = getTileAtPoint(new FV2(t.x + tilewidth, t.y), i); 290 | if (rightTile == null && first) 291 | return false; 292 | 293 | var currentSet = getTilesetForIndex(t.id, i); 294 | var currentIndex = resolveTilesetIndex(t.id); 295 | if (rightTile != null) 296 | { 297 | var rightSet = getTilesetForIndex(rightTile.id, i); 298 | result = (currentSet.canPassRight[currentIndex] && rightSet.canPassLeft[resolveTilesetIndex(rightTile.id)]); 299 | } 300 | else 301 | result = currentSet.canPassRight[currentIndex]; 302 | 303 | if (!first && !result) 304 | break; 305 | 306 | first = false; 307 | } 308 | return result; 309 | } 310 | else if (layer >= 0 && layer < _tiles.length) 311 | { 312 | var rightTile = getTileAtPoint(new FV2(t.x + tilewidth, t.y), layer); 313 | if (rightTile == null && layer == 0) 314 | return false; 315 | 316 | var set = getTilesetForIndex(t.id, layer); 317 | if (rightTile != null) 318 | { 319 | var rightSet = getTilesetForIndex(rightTile.id, layer); 320 | return (set.canPassRight[resolveTilesetIndex(t.id)] && rightSet.canPassLeft[resolveTilesetIndex(rightTile.id)]); 321 | } 322 | else 323 | return set.canPassRight[resolveTilesetIndex(t.id)]; 324 | 325 | } 326 | 327 | return false; 328 | } 329 | 330 | /** 331 | * Gets a boolean value to determine if a tile can be 332 | * passed out upward, given that the tile north can be passed from downward. 333 | * If neither the tile northward can be passed into from the current tile, nor the current tile can 334 | * be passed up, then the result is `false`. If checking multiple layers, a boolean value can be `true` 335 | * if the tile north is non-existent on higher layers. 336 | * 337 | * @param t The `Tile` value to check in the Tileset for a given layer. 338 | * @param layer The layer to use for the Tileset. If -1, all layers will be scanned. 339 | * 340 | * @return Returns a boolean value determining if the tile can be passed northward. 341 | */ 342 | public function canPassUpFromTile(t:Tile, ?layer:Int = -1):Bool 343 | { 344 | if (t == null) 345 | return false; 346 | 347 | if (layer == -1) 348 | { 349 | var result = false; 350 | var first = true; 351 | for (i in 0..._tiles.length) 352 | { 353 | var upTile = getTileAtPoint(new FV2(t.x, t.y - tileheight), i); 354 | if (upTile == null && first) 355 | return false; 356 | 357 | var currentSet = getTilesetForIndex(t.id, i); 358 | var currentIndex = resolveTilesetIndex(t.id); 359 | if (upTile != null) 360 | { 361 | var upSet = getTilesetForIndex(upTile.id, i); 362 | result = (currentSet.canPassUp[currentIndex] && upSet.canPassDown[resolveTilesetIndex(upTile.id)]); 363 | } 364 | else 365 | result = currentSet.canPassUp[currentIndex]; 366 | 367 | if (!first && !result) 368 | break; 369 | 370 | first = false; 371 | } 372 | return result; 373 | } 374 | else if (layer >= 0 && layer < _tiles.length) 375 | { 376 | var upTile = getTileAtPoint(new FV2(t.x, t.y - tileheight), layer); 377 | if (upTile == null && layer == 0) 378 | return false; 379 | 380 | var set = getTilesetForIndex(t.id, layer); 381 | if (upTile != null) 382 | { 383 | var upSet = getTilesetForIndex(upTile.id, layer); 384 | return (set.canPassUp[resolveTilesetIndex(t.id)] && upSet.canPassDown[resolveTilesetIndex(upTile.id)]); 385 | } 386 | else 387 | return set.canPassUp[resolveTilesetIndex(t.id)]; 388 | 389 | } 390 | 391 | return false; 392 | } 393 | 394 | /** 395 | * Gets a boolean value to determine if a tile can be 396 | * passed out downward, given that the tile down can be passed from upward. 397 | * If neither the tile downward can be passed into from the current tile, nor the current tile can 398 | * be passed down, then the result is `false`. If checking multiple layers, a boolean value can be `true` 399 | * if the tile south is non-existent on higher layers. 400 | * 401 | * @param t The `Tile` value to check in the Tileset for a given layer. 402 | * @param layer The layer to use for the Tileset. If -1, all layers will be scanned. 403 | * 404 | * @return Returns a boolean value determining if the tile can be passed downward. 405 | */ 406 | public function canPassDownFromTile(t:Tile, ?layer:Int = -1):Bool 407 | { 408 | if (t == null) 409 | return false; 410 | 411 | if (layer == -1) 412 | { 413 | var result = false; 414 | var first = true; 415 | for (i in 0..._tiles.length) 416 | { 417 | var downTile = getTileAtPoint(new FV2(t.x, t.y + tileheight), i); 418 | if (downTile == null && first) 419 | return false; 420 | 421 | var currentSet = getTilesetForIndex(t.id, i); 422 | var currentIndex = resolveTilesetIndex(t.id); 423 | if (downTile != null) 424 | { 425 | var downSet = getTilesetForIndex(downTile.id, i); 426 | result = (currentSet.canPassDown[currentIndex] && downSet.canPassUp[resolveTilesetIndex(downTile.id)]); 427 | } 428 | else 429 | result = currentSet.canPassDown[currentIndex]; 430 | 431 | if (!first && !result) 432 | break; 433 | 434 | first = false; 435 | } 436 | return result; 437 | } 438 | else if (layer >= 0 && layer < _tiles.length) 439 | { 440 | var downTile = getTileAtPoint(new FV2(t.x, t.y + tileheight), layer); 441 | if (downTile == null && layer == 0) 442 | return false; 443 | 444 | var set = getTilesetForIndex(t.id, layer); 445 | if (downTile != null) 446 | { 447 | var downSet = getTilesetForIndex(downTile.id, layer); 448 | return (set.canPassDown[resolveTilesetIndex(t.id)] && downSet.canPassUp[resolveTilesetIndex(downTile.id)]); 449 | } 450 | else 451 | return set.canPassDown[resolveTilesetIndex(t.id)]; 452 | 453 | } 454 | 455 | return false; 456 | } 457 | 458 | /** 459 | * Renders the TileMap to the current buffer at the given position offset and size 460 | * limit. You may optionally change the zoom factor. 461 | * 462 | * @param g2 The `Graphics` component belonging to a 2D buffer on which to render `this` TileMap. 463 | * @param pos The offset used to determine the camera position. 464 | * @param size The size limitation for this TileMap. Tiles will stop rendering after a certain point. 465 | * @param zoom The zoom factor used to determine the scale of each tile as they're drawn. Default value is 1.0. 466 | */ 467 | public function render(g2:Graphics, pos:FV2, size:FV2, zoom:Float = 1.0) 468 | { 469 | var scaleScreen = zoom; 470 | if (zoom < 1) 471 | { 472 | scaleScreen = 1 / zoom; 473 | } 474 | 475 | var zoomWidth = ((size.x <= System.windowWidth() ? size.x : System.windowWidth()) * scaleScreen); 476 | var zoomHeight = ((size.y <= System.windowHeight() ? size.y : System.windowHeight()) * scaleScreen); 477 | 478 | if (size.x != zoomWidth) 479 | size.x = zoomWidth; 480 | 481 | if (size.y != zoomHeight) 482 | size.y = zoomHeight; 483 | 484 | for (i in 0..._tiles.length) 485 | { 486 | for (tile in _tiles[i]) 487 | { 488 | if (tile.id < 0) 489 | continue; 490 | 491 | var set = getTilesetForIndex(tile.id, i); 492 | 493 | var tileX = Math.floor(tile.x / tilewidth); 494 | var tileY = Math.floor(tile.y / tileheight); 495 | 496 | if ((tile.x + (tilewidth * tileX) + position.x >= -pos.x && tile.y + (tileheight * tileY) + position.y >= -pos.y) && 497 | (tile.x + position.x < pos.x + size.x && tile.y + position.y < pos.y + size.y)) 498 | { 499 | var rect = set.getSourceImageByIndex(resolveTilesetIndex(tile.id)); 500 | var extraWidth = rect.width * zoom - rect.width; 501 | var extraHeight = rect.height * zoom - rect.height; 502 | 503 | g2.drawScaledSubImage(set.bitmap, rect.x, rect.y, rect.width, rect.height, tile.x + -pos.x + (extraWidth * tileX), tile.y + -pos.y + (extraHeight * tileY), rect.width * zoom, rect.height * zoom); 504 | } 505 | } 506 | } 507 | } 508 | 509 | private function getTilesetForIndex(index:Int, ?layer:Int = 0):Tileset 510 | { 511 | if (isLayerRestricted) 512 | { 513 | return _setMap.get(_setIndices[layer]); 514 | } 515 | else 516 | { 517 | for (i in 0..._setIndices.length) 518 | { 519 | var setIndex = _setIndices[i]; 520 | if (index < setIndex) 521 | return _setMap.get(setIndex); 522 | } 523 | } 524 | 525 | return null; 526 | } 527 | 528 | private function resolveTilesetIndex(index:Int):Int 529 | { 530 | if (isLayerRestricted) 531 | return index; 532 | 533 | var totalCount = 0; 534 | for (i in 0..._setIndices.length) 535 | { 536 | var setIndex = _setIndices[i]; 537 | if (index < setIndex) 538 | return index - totalCount; 539 | totalCount += setIndex; 540 | } 541 | return -1; 542 | } 543 | 544 | } -------------------------------------------------------------------------------- /twinspire/RealColors.hx: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2017 Colour Multimedia Enterprises, and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | package twinspire; 12 | 13 | import kha.Color; 14 | 15 | /** 16 | * A collection of colors as found on MSDN: https://msdn.microsoft.com/en-us/library/system.drawing.color(v=vs.110).aspx 17 | */ 18 | abstract RealColors(Color) from Int from UInt to Int to UInt 19 | { 20 | /** 21 | * A color value of `#F0F8FF`. 22 | */ 23 | public static var aliceBlue:Color = Color.fromValue(0xFFF0F8FF); 24 | /** 25 | * A color value of `#FAEBD7`. 26 | */ 27 | public static var antiqueWhite:Color = Color.fromValue(0xFFFAEBD7); 28 | /** 29 | * A color value of `#00FFFF`. 30 | */ 31 | public static var aqua:Color = Color.fromValue(0xFF00FFFF); 32 | /** 33 | * A color value of `#7FFFD4`. 34 | */ 35 | public static var aquamarine:Color = Color.fromValue(0xFF7FFFD4); 36 | /** 37 | * A color value of `#F0FFFF`. 38 | */ 39 | public static var azure:Color = Color.fromValue(0xFFF0FFFF); 40 | /** 41 | * A color value of `#F5F5DC`. 42 | */ 43 | public static var beige:Color = Color.fromValue(0xFFF5F5DC); 44 | /** 45 | * A color value of `#FFE4C4`. 46 | */ 47 | public static var bisque:Color = Color.fromValue(0xFFFFE4C4); 48 | /** 49 | * A color value of `#000000`. 50 | */ 51 | public static var black:Color = Color.fromValue(0xFF000000); 52 | /** 53 | * A color value of `#FFEBCD`. 54 | */ 55 | public static var blanchedAlmond:Color = Color.fromValue(0xFFFFEBCD); 56 | /** 57 | * A color value of `#0000FF`. 58 | */ 59 | public static var blue:Color = Color.fromValue(0xFF0000FF); 60 | /** 61 | * A color value of `#8A2BE2`. 62 | */ 63 | public static var blueViolet:Color = Color.fromValue(0xFF8A2BE2); 64 | /** 65 | * A color value of `#A52A2A`. 66 | */ 67 | public static var brown:Color = Color.fromValue(0xFFA52A2A); 68 | /** 69 | * A color value of `#DEB887`. 70 | */ 71 | public static var burlyWood:Color = Color.fromValue(0xFFDEB887); 72 | /** 73 | * A color value of `#5F9EA0`. 74 | */ 75 | public static var cadetBlue:Color = Color.fromValue(0xFF5F9EA0); 76 | /** 77 | * A color value of `#5F9EA0`. 78 | */ 79 | public static var chartreuse:Color = Color.fromValue(0xFF7FFF00); 80 | /** 81 | * A color value of `#D2691E`. 82 | */ 83 | public static var chocolate:Color = Color.fromValue(0xFFD2691E); 84 | /** 85 | * A color value of `#FF7F50`. 86 | */ 87 | public static var coral:Color = Color.fromValue(0xFFFF7F50); 88 | /** 89 | * A color value of `#6495ED`. 90 | */ 91 | public static var cornflowerBlue:Color = Color.fromValue(0xFF6495ED); 92 | /** 93 | * A color value of `#FFF8DC`. 94 | */ 95 | public static var cornsilk:Color = Color.fromValue(0xFFFFF8DC); 96 | /** 97 | * A color value of `#DC143C`. 98 | */ 99 | public static var crimson:Color = Color.fromValue(0xFFDC143C); 100 | /** 101 | * A color value of `#00FFFF`. 102 | */ 103 | public static var cyan:Color = Color.fromValue(0xFF00FFFF); 104 | /** 105 | * A color value of `#00008B`. 106 | */ 107 | public static var darkBlue:Color = Color.fromValue(0xFF00008B); 108 | /** 109 | * A color value of `#008B8B`. 110 | */ 111 | public static var darkCyan:Color = Color.fromValue(0xFF008B8B); 112 | /** 113 | * A color value of `#B8860B`. 114 | */ 115 | public static var darkGoldenrod:Color = Color.fromValue(0xFFB8860B); 116 | /** 117 | * A color value of `#A9A9A9`. 118 | */ 119 | public static var darkGray:Color = Color.fromValue(0xFFA9A9A9); 120 | /** 121 | * A color value of `#006400`. 122 | */ 123 | public static var darkGreen:Color = Color.fromValue(0xFF006400); 124 | /** 125 | * A color value of `#BDB76B`. 126 | */ 127 | public static var darkKhaki:Color = Color.fromValue(0xFFBDB76B); 128 | /** 129 | * A color value of `#8B008B`. 130 | */ 131 | public static var darkMagenta:Color = Color.fromValue(0xFF8B008B); 132 | /** 133 | * A color value of `#556B2F`. 134 | */ 135 | public static var darkOliveGreen:Color = Color.fromValue(0xFF556B2F); 136 | /** 137 | * A color value of `#FF8C00`. 138 | */ 139 | public static var darkOrange:Color = Color.fromValue(0xFFFF8C00); 140 | /** 141 | * A color value of `#9932CC`. 142 | */ 143 | public static var darkOrchid:Color = Color.fromValue(0xFF9932CC); 144 | /** 145 | * A color value of `#8B0000`. 146 | */ 147 | public static var darkRed:Color = Color.fromValue(0xFF8B0000); 148 | /** 149 | * A color value of `#E9967A`. 150 | */ 151 | public static var darkSalmon:Color = Color.fromValue(0xFFE9967A); 152 | /** 153 | * A color value of `#8FBC8F`. 154 | */ 155 | public static var darkSeaGreen:Color = Color.fromValue(0xFF8FBC8F); 156 | /** 157 | * A color value of `#483D8B`. 158 | */ 159 | public static var darkSlateBlue:Color = Color.fromValue(0xFF483D8B); 160 | /** 161 | * A color value of `#2F4F4F`. 162 | */ 163 | public static var darkSlateGray:Color = Color.fromValue(0xFF2F4F4F); 164 | /** 165 | * A color value of `#00CED1`. 166 | */ 167 | public static var darkTurquoise:Color = Color.fromValue(0xFF00CED1); 168 | /** 169 | * A color value of `#9400D3`. 170 | */ 171 | public static var darkViolet:Color = Color.fromValue(0xFF9400D3); 172 | /** 173 | * A color value of `#FF1493`. 174 | */ 175 | public static var deepPink:Color = Color.fromValue(0xFFFF1493); 176 | /** 177 | * A color value of `#00BFFF`. 178 | */ 179 | public static var deepSkyBlue:Color = Color.fromValue(0xFF00BFFF); 180 | /** 181 | * A color value of `#696969`. 182 | */ 183 | public static var dimGray:Color = Color.fromValue(0xFF696969); 184 | /** 185 | * A color value of `#1E90FF`. 186 | */ 187 | public static var dodgerBlue:Color = Color.fromValue(0xFF1E90FF); 188 | /** 189 | * A color value of `#B22222`. 190 | */ 191 | public static var firebrick:Color = Color.fromValue(0xFFB22222); 192 | /** 193 | * A color value of `#FFFAF0`. 194 | */ 195 | public static var floralWhite:Color = Color.fromValue(0xFFFFFAF0); 196 | /** 197 | * A color value of `#228B22`. 198 | */ 199 | public static var forestGreen:Color = Color.fromValue(0xFF228B22); 200 | /** 201 | * A color value of `#FF00FF`. 202 | */ 203 | public static var fuchsia:Color = Color.fromValue(0xFFFF00FF); 204 | /** 205 | * A color value of `#DCDCDC`. 206 | */ 207 | public static var gainsboro:Color = Color.fromValue(0xFFDCDCDC); 208 | /** 209 | * A color value of `#F8F8FF`. 210 | */ 211 | public static var ghostWhite:Color = Color.fromValue(0xFFF8F8FF); 212 | /** 213 | * A color value of `#FFD700`. 214 | */ 215 | public static var gold:Color = Color.fromValue(0xFFFFD700); 216 | /** 217 | * A color value of `#DAA520`. 218 | */ 219 | public static var goldenrod:Color = Color.fromValue(0xFFDAA520); 220 | /** 221 | * A color value of `#808080`. 222 | */ 223 | public static var gray:Color = Color.fromValue(0xFF808080); 224 | /** 225 | * A color value of `#008000`. 226 | */ 227 | public static var green:Color = Color.fromValue(0xFF008000); 228 | /** 229 | * A color value of `#ADFF2F`. 230 | */ 231 | public static var greenYellow:Color = Color.fromValue(0xFFADFF2F); 232 | /** 233 | * A color value of `#F0FFF0`. 234 | */ 235 | public static var honeydew:Color = Color.fromValue(0xFFF0FFF0); 236 | /** 237 | * A color value of `#FF69B4`. 238 | */ 239 | public static var hotPink:Color = Color.fromValue(0xFFFF69B4); 240 | /** 241 | * A color value of `#CD5C5C`. 242 | */ 243 | public static var indianRed:Color = Color.fromValue(0xFFCD5C5C); 244 | /** 245 | * A color value of `#4B0082`. 246 | */ 247 | public static var indigo:Color = Color.fromValue(0xFF4B0082); 248 | /** 249 | * A color value of `#FFFFF0`. 250 | */ 251 | public static var ivory:Color = Color.fromValue(0xFFFFFFF0); 252 | /** 253 | * A color value of `#F0E68C`. 254 | */ 255 | public static var khaki:Color = Color.fromValue(0xFFF0E68C); 256 | /** 257 | * A color value of `#E6E6FA`. 258 | */ 259 | public static var lavender:Color = Color.fromValue(0xFFE6E6FA); 260 | /** 261 | * A color value of `#FFF0F5`. 262 | */ 263 | public static var lavenderBlush:Color = Color.fromValue(0xFFFFF0F5); 264 | /** 265 | * A color value of `#7CFC00`. 266 | */ 267 | public static var lawnGreen:Color = Color.fromValue(0xFF7CFC00); 268 | /** 269 | * A color value of `#FFFACD`. 270 | */ 271 | public static var lemonChiffon:Color = Color.fromValue(0xFFFFFACD); 272 | /** 273 | * A color value of `#ADD8E6`. 274 | */ 275 | public static var lightBlue:Color = Color.fromValue(0xFFADD8E6); 276 | /** 277 | * A color value of `#F08080`. 278 | */ 279 | public static var lightCoral:Color = Color.fromValue(0xFFF08080); 280 | /** 281 | * A color value of `#E0FFFF`. 282 | */ 283 | public static var lightCyan:Color = Color.fromValue(0xFFE0FFFF); 284 | /** 285 | * A color value of `#FAFAD2`. 286 | */ 287 | public static var lightGoldenrodYellow:Color = Color.fromValue(0xFFFAFAD2); 288 | /** 289 | * A color value of `#D3D3D3`. 290 | */ 291 | public static var lightGray:Color = Color.fromValue(0xFFD3D3D3); 292 | /** 293 | * A color value of `#90EE90`. 294 | */ 295 | public static var lightGreen:Color = Color.fromValue(0xFF90EE90); 296 | /** 297 | * A color value of `#FFB6C1`. 298 | */ 299 | public static var lightPink:Color = Color.fromValue(0xFFFFB6C1); 300 | /** 301 | * A color value of `#FFA07A`. 302 | */ 303 | public static var lightSalmon:Color = Color.fromValue(0xFFFFA07A); 304 | /** 305 | * A color value of `#20B2AA`. 306 | */ 307 | public static var lightSeaGreen:Color = Color.fromValue(0xFF20B2AA); 308 | /** 309 | * A color value of `#87CEFA`. 310 | */ 311 | public static var lightSkyBlue:Color = Color.fromValue(0xFF87CEFA); 312 | /** 313 | * A color value of `#778899`. 314 | */ 315 | public static var lightSlateGray:Color = Color.fromValue(0xFF778899); 316 | /** 317 | * A color value of `#B0C4DE`. 318 | */ 319 | public static var lightSteelBlue:Color = Color.fromValue(0xFFB0C4DE); 320 | /** 321 | * A color value of `#FFFFE0`. 322 | */ 323 | public static var lightYellow:Color = Color.fromValue(0xFFFFFFE0); 324 | /** 325 | * A color value of `#00FF00`. 326 | */ 327 | public static var lime:Color = Color.fromValue(0xFF00FF00); 328 | /** 329 | * A color value of `#32CD32`. 330 | */ 331 | public static var limeGreen:Color = Color.fromValue(0xFF32CD32); 332 | /** 333 | * A color value of `#FAF0E6`. 334 | */ 335 | public static var linen:Color = Color.fromValue(0xFFFAF0E6); 336 | /** 337 | * A color value of `#FF00FF`. 338 | */ 339 | public static var magenta:Color = Color.fromValue(0xFFFF00FF); 340 | /** 341 | * A color value of `#800000`. 342 | */ 343 | public static var maroon:Color = Color.fromValue(0xFF800000); 344 | /** 345 | * A color value of `#66CDAA`. 346 | */ 347 | public static var mediumAquamarine:Color = Color.fromValue(0xFF66CDAA); 348 | /** 349 | * A color value of `#0000CD`. 350 | */ 351 | public static var mediumBlue:Color = Color.fromValue(0xFF0000CD); 352 | /** 353 | * A color value of `#BA55D3`. 354 | */ 355 | public static var mediumOrchid:Color = Color.fromValue(0xFFBA55D3); 356 | /** 357 | * A color value of `#9370DB`. 358 | */ 359 | public static var mediumPurple:Color = Color.fromValue(0xFF9370DB); 360 | /** 361 | * A color value of `#3CB371`. 362 | */ 363 | public static var mediumSeaGreen:Color = Color.fromValue(0xFF3CB371); 364 | /** 365 | * A color value of `#7B68EE`. 366 | */ 367 | public static var mediumSlateBlue:Color = Color.fromValue(0xFF7B68EE); 368 | /** 369 | * A color value of `#00FA9A`. 370 | */ 371 | public static var mediumSpringGreen:Color = Color.fromValue(0xFF00FA9A); 372 | /** 373 | * A color value of `#48D1CC`. 374 | */ 375 | public static var mediumTurquoise:Color = Color.fromValue(0xFF48D1CC); 376 | /** 377 | * A color value of `#C71585`. 378 | */ 379 | public static var mediumVioletRed:Color = Color.fromValue(0xFFC71585); 380 | /** 381 | * A color value of `#191970`. 382 | */ 383 | public static var midnightBlue:Color = Color.fromValue(0xFF191970); 384 | /** 385 | * A color value of `#F5FFFA`. 386 | */ 387 | public static var mintCream:Color = Color.fromValue(0xFFF5FFFA); 388 | /** 389 | * A color value of `#FFE4E1`. 390 | */ 391 | public static var mistyRose:Color = Color.fromValue(0xFFFFE4E1); 392 | /** 393 | * A color value of `#FFE4B5`. 394 | */ 395 | public static var moccasin:Color = Color.fromValue(0xFFFFE4B5); 396 | /** 397 | * A color value of `#FFDEAD`. 398 | */ 399 | public static var navajoWhite:Color = Color.fromValue(0xFFFFDEAD); 400 | /** 401 | * A color value of `#000080`. 402 | */ 403 | public static var navy:Color = Color.fromValue(0xFF000080); 404 | /** 405 | * A color value of `#FDF5E6`. 406 | */ 407 | public static var oldLace:Color = Color.fromValue(0xFFFDF5E6); 408 | /** 409 | * A color value of `#808000`. 410 | */ 411 | public static var olive:Color = Color.fromValue(0xFF808000); 412 | /** 413 | * A color value of `#6B8E23`. 414 | */ 415 | public static var oliveDrab:Color = Color.fromValue(0xFF6B8E23); 416 | /** 417 | * A color value of `#FFA500`. 418 | */ 419 | public static var orange:Color = Color.fromValue(0xFFFFA500); 420 | /** 421 | * A color value of `#FF4500`. 422 | */ 423 | public static var orangeRed:Color = Color.fromValue(0xFFFF4500); 424 | /** 425 | * A color value of `#DA70D6`. 426 | */ 427 | public static var orchid:Color = Color.fromValue(0xFFDA70D6); 428 | /** 429 | * A color value of `#EEE8AA`. 430 | */ 431 | public static var paleGoldenrod:Color = Color.fromValue(0xFFEEE8AA); 432 | /** 433 | * A color value of `#98FB98`. 434 | */ 435 | public static var paleGreen:Color = Color.fromValue(0xFF98FB98); 436 | /** 437 | * A color value of `#AFEEEE`. 438 | */ 439 | public static var paleTurquoise:Color = Color.fromValue(0xFFAFEEEE); 440 | /** 441 | * A color value of `#DB7093`. 442 | */ 443 | public static var paleVioletRed:Color = Color.fromValue(0xFFDB7093); 444 | /** 445 | * A color value of `#FFEFD5`. 446 | */ 447 | public static var papayaWhip:Color = Color.fromValue(0xFFFFEFD5); 448 | /** 449 | * A color value of `#FFDAB9`. 450 | */ 451 | public static var peachPuff:Color = Color.fromValue(0xFFFFDAB9); 452 | /** 453 | * A color value of `#CD853F`. 454 | */ 455 | public static var peru:Color = Color.fromValue(0xFFCD853F); 456 | /** 457 | * A color value of `#FFC0CB`. 458 | */ 459 | public static var pink:Color = Color.fromValue(0xFFFFC0CB); 460 | /** 461 | * A color value of `#DDA0DD`. 462 | */ 463 | public static var plum:Color = Color.fromValue(0xFFDDA0DD); 464 | /** 465 | * A color value of `#B0E0E6`. 466 | */ 467 | public static var powderBlue:Color = Color.fromValue(0xFFB0E0E6); 468 | /** 469 | * A color value of `#800080`. 470 | */ 471 | public static var purple:Color = Color.fromValue(0xFF800080); 472 | /** 473 | * A color value of `#FF0000`. 474 | */ 475 | public static var red:Color = Color.fromValue(0xFFFF0000); 476 | /** 477 | * A color value of `#BC8F8F`. 478 | */ 479 | public static var rosyBrown:Color = Color.fromValue(0xFFBC8F8F); 480 | /** 481 | * A color value of `#4169E1`. 482 | */ 483 | public static var royalBlue:Color = Color.fromValue(0xFF4169E1); 484 | /** 485 | * A color value of `#8B4513`. 486 | */ 487 | public static var saddleBrown:Color = Color.fromValue(0xFF8B4513); 488 | /** 489 | * A color value of `#FA8072`. 490 | */ 491 | public static var salmon:Color = Color.fromValue(0xFFFA8072); 492 | /** 493 | * A color value of `#F4A460`. 494 | */ 495 | public static var sandyBrown:Color = Color.fromValue(0xFFF4A460); 496 | /** 497 | * A color value of `#2E8B57`. 498 | */ 499 | public static var seaGreen:Color = Color.fromValue(0xFF2E8B57); 500 | /** 501 | * A color value of `#FFF5EE`. 502 | */ 503 | public static var seaShell:Color = Color.fromValue(0xFFFFF5EE); 504 | /** 505 | * A color value of `#A0522D`. 506 | */ 507 | public static var sienna:Color = Color.fromValue(0xFFA0522D); 508 | /** 509 | * A color value of `#C0C0C0`. 510 | */ 511 | public static var silver:Color = Color.fromValue(0xFFC0C0C0); 512 | /** 513 | * A color value of `#87CEEB`. 514 | */ 515 | public static var skyBlue:Color = Color.fromValue(0xFF87CEEB); 516 | /** 517 | * A color value of `#6A5ACD`. 518 | */ 519 | public static var slateBlue:Color = Color.fromValue(0xFF6A5ACD); 520 | /** 521 | * A color value of `#708090`. 522 | */ 523 | public static var slateGray:Color = Color.fromValue(0xFF708090); 524 | /** 525 | * A color value of `#FFFAFA`. 526 | */ 527 | public static var snow:Color = Color.fromValue(0xFFFFFAFA); 528 | /** 529 | * A color value of `#00FF7F`. 530 | */ 531 | public static var springGreen:Color = Color.fromValue(0xFF00FF7F); 532 | /** 533 | * A color value of `#4682B4`. 534 | */ 535 | public static var steelBlue:Color = Color.fromValue(0xFF4682B4); 536 | /** 537 | * A color value of `#D2B48C`. 538 | */ 539 | public static var tan:Color = Color.fromValue(0xFFD2B48C); 540 | /** 541 | * A color value of `#008080`. 542 | */ 543 | public static var teal:Color = Color.fromValue(0xFF008080); 544 | /** 545 | * A color value of `#D8BFD8`. 546 | */ 547 | public static var thistle:Color = Color.fromValue(0xFFD8BFD8); 548 | /** 549 | * A color value of `#FF6347`. 550 | */ 551 | public static var tomato:Color = Color.fromValue(0xFFFF6347); 552 | /** 553 | * A color value of `#40E0D0`. 554 | */ 555 | public static var turquoise:Color = Color.fromValue(0xFF40E0D0); 556 | /** 557 | * A color value of `#EE82EE`. 558 | */ 559 | public static var violet:Color = Color.fromValue(0xFFEE82EE); 560 | /** 561 | * A color value of `#F5DEB3`. 562 | */ 563 | public static var wheat:Color = Color.fromValue(0xFFF5DEB3); 564 | /** 565 | * A color value of `#FFFFFF`. 566 | */ 567 | public static var white:Color = Color.fromValue(0xFFFFFFFF); 568 | /** 569 | * A color value of `#F5F5F5`. 570 | */ 571 | public static var whiteSmoke:Color = Color.fromValue(0xFFF5F5F5); 572 | /** 573 | * A color value of `#FFFF00`. 574 | */ 575 | public static var yellow:Color = Color.fromValue(0xFFFFFF00); 576 | /** 577 | * A color value of `#9ACD32`. 578 | */ 579 | public static var yellowGreen:Color = Color.fromValue(0xFF9ACD32); 580 | } --------------------------------------------------------------------------------