diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c1dcd0ff..bbc23ba9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: build: strategy: matrix: - haxe-version: ["4.2.5", "4.3.3"] + haxe-version: ["4.2.5", "4.3.4"] target: [html5, hl, neko, flash, cpp] fail-fast: false runs-on: ubuntu-latest @@ -29,9 +29,8 @@ jobs: haxelib install haxelib 4.0.3 haxelib dev flixel-addons . - - uses: HaxeFlixel/setup-flixel@v1 + - uses: HaxeFlixel/setup-flixel@master with: - haxe-version: current flixel-versions: dev target: ${{matrix.target}} run-tests: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 7937aac6..88123261 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,39 @@ +# 4.0.0 (TBD) +Removed deprecated classes +- `FlxRayCastTilemap`: `FlxBaseTilemap` has an all-around better `ray()` method ([#455](https://github.com/HaxeFlixel/flixel-addons/pull/455)) +- `FlxMouseControl`: Use `FlxMouseEvent`, instead ([#455](https://github.com/HaxeFlixel/flixel-addons/pull/455)) + +## 3.3.2 (January 31, 2025) +------------------------------ +- Fix dox, attempt 2 + +3.3.1 (January 31, 2025) +------------------------------ +- Fix dox + +3.3.0 (December 10, 2024) +------------------------------ +#### New Features: +- `FlxRadialGauge`: Refactor `FlxPieDial` add replacement ([444](https://github.com/HaxeFlixel/flixel-addons/pull/444)) + - `FlxRadialWipeShader`: Shader that masks sprite radially, can be applied to of any static sprite (doesn't work with animations, yet, but neither did FlxPieDial). Shaders only work on non-Flash targets + - `FlxRadialGauge`: Same as `FlxPieDial` but uses less memory, shows more percentages, and performs better + - `FlxPieDialUtils`: Moved all logic from `FlxPieDial` to a shared util + +#### Changes and improvements: +- Compatibility with Flixel 5.9.0 ([431](https://github.com/HaxeFlixel/flixel-addons/pull/431))([432](https://github.com/HaxeFlixel/flixel-addons/pull/432))([433](https://github.com/HaxeFlixel/flixel-addons/pull/433))([436](https://github.com/HaxeFlixel/flixel-addons/pull/436))([437](https://github.com/HaxeFlixel/flixel-addons/pull/437))([440](https://github.com/HaxeFlixel/flixel-addons/pull/440))([441](https://github.com/HaxeFlixel/flixel-addons/pull/441)) + - Deprecated `FlxRayCastTilemap` + - Minor upkeep for `FlxTilemapExt`, `FlxOgmo3Loader`, `FlxOgmo3Loader`, `FlxWeapon`, `FlxNapeTilemap`, `FlxTrail`, `FlxExtendedMouseSprite`, `FlxSlider`, `FlxTransitionSprite` +- `FlxTiledSprite`: Honor `clipRect` ([435](https://github.com/HaxeFlixel/flixel-addons/pull/435)) +- `FlxRuntimeShader`: Refactor and improve readibility ([442](https://github.com/HaxeFlixel/flixel-addons/pull/442)) +- Assets: Ran oxipng on all images ([445](https://github.com/HaxeFlixel/flixel-addons/pull/445)) +- `FlxTrail`: Organize logic into various methods to allow overriding particular behavior ([447](https://github.com/HaxeFlixel/flixel-addons/pull/447)) +- `TiledObject`: Add `POINT` type ([448](https://github.com/HaxeFlixel/flixel-addons/pull/448)) +- `TiledLayer`: Add `parallaxX` and `parallaxY` ([449](https://github.com/HaxeFlixel/flixel-addons/pull/449)) +- Remove all implicit `Int` casts from/to `FlxDirectionFlags` ([451](https://github.com/HaxeFlixel/flixel-addons/pull/451)) + +#### Bugfixes: +- `FlxTypeText`: Honors `prefix` on `reset` calls ([395](https://github.com/HaxeFlixel/flixel-addons/pull/395)) + 3.2.3 (May 15, 2024) ------------------------------ diff --git a/README.md b/README.md index ea60016a..b799cd0a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -![](https://raw.github.com/HaxeFlixel/haxeflixel.com/master/src/files/images/flixel-logos/flixel-addons.png) +![](https://github.com/HaxeFlixel/haxeflixel.com/blob/dev/content/_static/images/flixel-logos/flixel-addons.png?raw=true) -[flixel](https://github.com/HaxeFlixel/flixel) | [addons](https://github.com/HaxeFlixel/flixel-addons) | [ui](https://github.com/HaxeFlixel/flixel-ui) | [demos](https://github.com/HaxeFlixel/flixel-demos) | [tools](https://github.com/HaxeFlixel/flixel-tools) | [templates](https://github.com/HaxeFlixel/flixel-templates) | [docs](https://github.com/HaxeFlixel/flixel-docs) | [haxeflixel.com](https://github.com/HaxeFlixel/haxeflixel.com) +[flixel](https://github.com/HaxeFlixel/flixel) | [addons](https://github.com/HaxeFlixel/flixel-addons) | [ui](https://github.com/HaxeFlixel/flixel-ui) | [demos](https://github.com/HaxeFlixel/flixel-demos) | [tools](https://github.com/HaxeFlixel/flixel-tools) | [templates](https://github.com/HaxeFlixel/flixel-templates) | [docs](https://github.com/HaxeFlixel/flixel-docs) | [haxeflixel.com](https://github.com/HaxeFlixel/haxeflixel.com) | [türkçe](/README_TR.md) [![CI](https://img.shields.io/github/actions/workflow/status/HaxeFlixel/flixel-addons/main.yml?branch=dev&logo=github)](https://github.com/HaxeFlixel/flixel/actions?query=workflow%3ACI) [![Discord](https://img.shields.io/discord/162395145352904705.svg?logo=discord)](https://discordapp.com/invite/rqEBAgF) diff --git a/README_TR.md b/README_TR.md new file mode 100644 index 00000000..2b06d9dd --- /dev/null +++ b/README_TR.md @@ -0,0 +1,28 @@ +![](https://raw.github.com/HaxeFlixel/haxeflixel.com/master/src/files/images/flixel-logos/flixel-addons.png) + +[flixel](https://github.com/HaxeFlixel/flixel) | [uzantılar](https://github.com/HaxeFlixel/flixel-addons) | [ui](https://github.com/HaxeFlixel/flixel-ui) | [demolar](https://github.com/HaxeFlixel/flixel-demos) | [araçlar](https://github.com/HaxeFlixel/flixel-tools) | [şablonlar](https://github.com/HaxeFlixel/flixel-templates) | [dökümanlar](https://github.com/HaxeFlixel/flixel-docs) | [haxeflixel.com](https://github.com/HaxeFlixel/haxeflixel.com) | [english](/README.md) + +[![CI](https://img.shields.io/github/actions/workflow/status/HaxeFlixel/flixel-addons/main.yml?branch=dev&logo=github)](https://github.com/HaxeFlixel/flixel/actions?query=workflow%3ACI) +[![Discord](https://img.shields.io/discord/162395145352904705.svg?logo=discord)](https://discordapp.com/invite/rqEBAgF) +[![Haxelib Version](https://badgen.net/haxelib/v/flixel-addons)](https://lib.haxe.org/p/flixel-addons) +[![Haxelib Downloads](https://badgen.net/haxelib/d/flixel-addons?color=blue)](https://lib.haxe.org/p/flixel-addons) +[![Haxelib License](https://badgen.net/haxelib/license/flixel-addons)](LICENSE.md) +[![Patreon](https://img.shields.io/badge/donate-patreon-blue.svg)](https://www.patreon.com/haxeflixel) + + + +## Hakkında + +[HaxeFlixel](https://github.com/HaxeFlixel/flixel) | [HaxeFlixel](https://github.com/HaxeFlixel/flixel) için kullanışlı ancak isteğe bağlı, topluluk tarafından oluşturulan bir takım sınıf seti. [Flixel Power Tools](https://github.com/photonstorm/Flixel-Power-Tools)'tan bazı sınıflar dahildir. + +## Geliştiriciler için + +Eğer katkıda bulunmak isterseniz, aşağıdaki dökümanları inceleyin (İngilizce): + +- [Kod katkıları](http://haxeflixel.com/documentation/code-contributions) +- [Kod Tarzı](http://haxeflixel.com/documentation/code-style) +- [Geliştirici flixel'i indirin](http://haxeflixel.com/documentation/install-development-flixel/) + +Eğer bir sorunuz varsa veya daha önce hiç Github'dan katkıda bulunmadıysanız, toplulukta [forumlarda](http://haxeflixel.com/documentation/community/) yardım edecek arkadaş canlısı insanlar var. + +Git'i Github ile kullanmak için, değişikliklerinizi yönetebileceğiniz [SourceTree](http://www.sourcetreeapp.com/) gibi bir GUI kullanmanızı öneririz. diff --git a/assets/images/napeDebug.png b/assets/images/napeDebug.png index fd774689..04e12305 100644 Binary files a/assets/images/napeDebug.png and b/assets/images/napeDebug.png differ diff --git a/assets/images/transitions/circle.png b/assets/images/transitions/circle.png index a9645ed8..7d2a5705 100644 Binary files a/assets/images/transitions/circle.png and b/assets/images/transitions/circle.png differ diff --git a/assets/images/transitions/diagonal_gradient.png b/assets/images/transitions/diagonal_gradient.png index 9555ea7d..b14b8fe7 100644 Binary files a/assets/images/transitions/diagonal_gradient.png and b/assets/images/transitions/diagonal_gradient.png differ diff --git a/assets/images/transitions/diamond.png b/assets/images/transitions/diamond.png index 4abb5cc8..87f8100a 100644 Binary files a/assets/images/transitions/diamond.png and b/assets/images/transitions/diamond.png differ diff --git a/assets/images/transitions/square.png b/assets/images/transitions/square.png index a6667f2c..be999720 100644 Binary files a/assets/images/transitions/square.png and b/assets/images/transitions/square.png differ diff --git a/flixel/addons/display/FlxBackdrop.hx b/flixel/addons/display/FlxBackdrop.hx index fa12b5a9..5db02afe 100644 --- a/flixel/addons/display/FlxBackdrop.hx +++ b/flixel/addons/display/FlxBackdrop.hx @@ -115,7 +115,7 @@ class FlxBackdrop extends FlxSprite drawToLargestCamera(); } - #if (flixel >= "5.7.0") + #if (flixel >= version("5.7.0")) final cameras = getCamerasLegacy(); #end for (camera in cameras) @@ -161,7 +161,7 @@ class FlxBackdrop extends FlxSprite { var largest:FlxCamera = null; var largestArea = 0.0; - #if (flixel >= "5.7.0") + #if (flixel >= version("5.7.0")) final cameras = getCamerasLegacy(); // else use this.cameras #end for (camera in cameras) diff --git a/flixel/addons/display/FlxExtendedMouseSprite.hx b/flixel/addons/display/FlxExtendedMouseSprite.hx index b501ff05..eaf5e7b4 100644 --- a/flixel/addons/display/FlxExtendedMouseSprite.hx +++ b/flixel/addons/display/FlxExtendedMouseSprite.hx @@ -183,6 +183,8 @@ class FlxExtendedMouseSprite extends FlxSprite * Returns how many vertical pixels the mouse pointer is inside this sprite from the top left corner. Returns -1 if outside. */ public var mouseY(get, never):Int; + var viewX(get, never):Int; + var viewY(get, never):Int; #end var _snapOnDrag:Bool = false; @@ -453,11 +455,11 @@ class FlxExtendedMouseSprite extends FlxSprite if (acceleration.x < 0) { // Gravity is pulling them left - if ((touching & WALL) != 0) + if (touching.has(WALL)) { drag.y = frictionY; - if ((wasTouching & WALL) == 0) + if (!wasTouching.has(WALL)) { if (velocity.x < toleranceX) { @@ -473,12 +475,12 @@ class FlxExtendedMouseSprite extends FlxSprite else if (acceleration.x > 0) { // Gravity is pulling them right - if ((touching & WALL) != 0) + if (touching.has(WALL)) { // Stop them sliding like on ice drag.y = frictionY; - if ((wasTouching & WALL) == 0) + if (!wasTouching.has(WALL)) { if (velocity.x > -toleranceX) { @@ -499,11 +501,11 @@ class FlxExtendedMouseSprite extends FlxSprite if (acceleration.y < 0) { // Gravity is pulling them up (velocity is negative) - if ((touching & CEILING) != 0) + if (touching.has(CEILING)) { drag.x = frictionX; - if ((wasTouching & CEILING) == 0) + if (!wasTouching.has(CEILING)) { if (velocity.y < toleranceY) { @@ -519,12 +521,12 @@ class FlxExtendedMouseSprite extends FlxSprite else if (acceleration.y > 0) { // Gravity is pulling them down (velocity is positive) - if ((touching & FLOOR) != 0) + if (touching.has(FLOOR)) { // Stop them sliding like on ice drag.x = frictionX; - if ((wasTouching & FLOOR) == 0) + if (!wasTouching.has(FLOOR)) { if (velocity.y > -toleranceY) { @@ -549,14 +551,14 @@ class FlxExtendedMouseSprite extends FlxSprite if (_allowHorizontalDrag) { #if FLX_MOUSE - x = Math.floor(FlxG.mouse.screenX + scrollFactor.x * (FlxG.mouse.x - FlxG.mouse.screenX)) - _dragOffsetX; + x = Math.floor(viewX + scrollFactor.x * (FlxG.mouse.x - viewX)) - _dragOffsetX; #end } if (_allowVerticalDrag) { #if FLX_MOUSE - y = Math.floor(FlxG.mouse.screenY + scrollFactor.y * (FlxG.mouse.y - FlxG.mouse.screenY)) - _dragOffsetY; + y = Math.floor(viewY + scrollFactor.y * (FlxG.mouse.y - viewY)) - _dragOffsetY; #end } @@ -657,8 +659,8 @@ class FlxExtendedMouseSprite extends FlxSprite #if FLX_MOUSE if (_dragFromPoint == false) { - _dragOffsetX = Math.floor(FlxG.mouse.screenX + scrollFactor.x * (FlxG.mouse.x - FlxG.mouse.screenX) - x); - _dragOffsetY = Math.floor(FlxG.mouse.screenY + scrollFactor.y * (FlxG.mouse.y - FlxG.mouse.screenY) - y); + _dragOffsetX = Math.floor(viewX + scrollFactor.x * (FlxG.mouse.x - viewX) - x); + _dragOffsetY = Math.floor(viewY + scrollFactor.y * (FlxG.mouse.y - viewY) - y); } else { @@ -828,8 +830,8 @@ class FlxExtendedMouseSprite extends FlxSprite #if FLX_MOUSE function get_mouseOver():Bool { - return FlxMath.pointInCoordinates(Math.floor(FlxG.mouse.screenX + scrollFactor.x * (FlxG.mouse.x - FlxG.mouse.screenX)), - Math.floor(FlxG.mouse.screenY + scrollFactor.y * (FlxG.mouse.y - FlxG.mouse.screenY)), Math.floor(x), Math.floor(y), Math.floor(width), + return FlxMath.pointInCoordinates(Math.floor(viewX + scrollFactor.x * (FlxG.mouse.x - viewX)), + Math.floor(viewY + scrollFactor.y * (FlxG.mouse.y - viewY)), Math.floor(x), Math.floor(y), Math.floor(width), Math.floor(height)); } @@ -852,6 +854,15 @@ class FlxExtendedMouseSprite extends FlxSprite return -1; } + inline function get_viewX():Int + { + return #if (flixel < version("5.9.0")) FlxG.mouse.screenX #else FlxG.mouse.viewX #end; + } + + inline function get_viewY():Int + { + return #if (flixel < version("5.9.0")) FlxG.mouse.screenY #else FlxG.mouse.viewY #end; + } #end inline function get_rect():FlxRect diff --git a/flixel/addons/display/FlxGridOverlay.hx b/flixel/addons/display/FlxGridOverlay.hx index 949ea9f9..227e46f9 100644 --- a/flixel/addons/display/FlxGridOverlay.hx +++ b/flixel/addons/display/FlxGridOverlay.hx @@ -22,10 +22,10 @@ class FlxGridOverlay * If false each row will be the same colour, creating a striped-pattern effect. * So to create an 8x8 grid you'd call create(8,8) * - * @param CellWidth The grid cell width - * @param CellHeight The grid cell height - * @param Width The width of the FlxSprite. If -1 it will be the size of the game (FlxG.width) - * @param Height The height of the FlxSprite. If -1 it will be the size of the game (FlxG.height) + * @param CellWidth The grid cell width. Must be greater than 0. + * @param CellHeight The grid cell height. Must be greater than 0. + * @param Width The width of the FlxSprite. If -1 it will be the size of the game (FlxG.width). This value cannot be smaller than the `CellWidth` + * @param Height The height of the FlxSprite. If -1 it will be the size of the game (FlxG.height). This value cannot be smaller than the `CellHeight` * @param Alternate Should the pattern alternate on each new row? Default true = checkerboard effect. False = vertical stripes * @param Color1 The first fill colour in 0xAARRGGBB format * @param Color2 The second fill colour in 0xAARRGGBB format @@ -45,9 +45,10 @@ class FlxGridOverlay } if (Width < CellWidth || Height < CellHeight) - { - return null; - } + throw "The width and height of a grid cannot be smaller than the cell's width and height!"; + + if (CellWidth <= 0 || CellHeight <= 0) + throw "Grid cell width/height cannot be less or equal to 0"; var grid:BitmapData = createGrid(CellWidth, CellHeight, Width, Height, Alternate, Color1, Color2); @@ -67,10 +68,10 @@ class FlxGridOverlay * So to create an 8x8 grid you'd call create(8,8, * * @param Sprite The FlxSprite you wish to draw the grid on-top of. This updates its pixels value, not just the current frame (don't use animated sprites!) - * @param CellWidth The grid cell width - * @param CellHeight The grid cell height - * @param Width The width of the FlxSprite. If -1 it will be the size of the game (FlxG.width) - * @param Height The height of the FlxSprite. If -1 it will be the size of the game (FlxG.height) + * @param CellWidth The grid cell width. Must be greater than 0. + * @param CellHeight The grid cell height. Must be greater than 0. + * @param Width The width of the FlxSprite. If -1 it will be the size of the game (FlxG.width). This value cannot be smaller than the `CellWidth` + * @param Height The height of the FlxSprite. If -1 it will be the size of the game (FlxG.height). This value cannot be smaller than the `CellHeight` * @param Alternate Should the pattern alternate on each new row? Default true = checkerboard effect. False = vertical stripes * @param Color1 The first fill colour in 0xAARRGGBB format * @param Color2 The second fill colour in 0xAARRGGBB format @@ -90,9 +91,10 @@ class FlxGridOverlay } if (Width < CellWidth || Height < CellHeight) - { - return null; - } + throw "The width and height of a grid cannot be smaller than the cell's width and height!"; + + if (CellWidth <= 0 || CellHeight <= 0) + throw "Grid cell width/height cannot be less or equal to 0"; var grid:BitmapData = createGrid(CellWidth, CellHeight, Width, Height, Alternate, Color1, Color2); Sprite.pixels.copyPixels(grid, new Rectangle(0, 0, Width, Height), new Point(0, 0), null, null, true); diff --git a/flixel/addons/display/FlxNestedSprite.hx b/flixel/addons/display/FlxNestedSprite.hx index 1d71abb0..16cc988b 100644 --- a/flixel/addons/display/FlxNestedSprite.hx +++ b/flixel/addons/display/FlxNestedSprite.hx @@ -1,6 +1,5 @@ package flixel.addons.display; -import openfl.geom.ColorTransform; import flixel.FlxBasic; import flixel.FlxG; import flixel.FlxSprite; @@ -11,6 +10,8 @@ import flixel.math.FlxVelocity; import flixel.system.FlxAssets.FlxGraphicAsset; import flixel.util.FlxColor; import flixel.util.FlxDestroyUtil; +import flixel.util.FlxDirectionFlags; +import openfl.geom.ColorTransform; using flixel.util.FlxArrayUtil; @@ -296,6 +297,7 @@ class FlxNestedSprite extends FlxSprite var green:Float = (color >> 8 & 0xff) * _parentGreen / 255; var blue:Float = (color & 0xff) * _parentBlue / 255; + #if (flixel < version("6.1.0")) if (colorTransform == null) { colorTransform = new ColorTransform(red, green, blue, alpha); @@ -308,9 +310,16 @@ class FlxNestedSprite extends FlxSprite colorTransform.alphaMultiplier = alpha; } useColorTransform = true; + #else + colorTransform.redMultiplier = red; + colorTransform.greenMultiplier = green; + colorTransform.blueMultiplier = blue; + colorTransform.alphaMultiplier = alpha; + #end } else { + #if (flixel < version("6.1.0")) if (colorTransform != null) { colorTransform.redMultiplier = 1; @@ -319,6 +328,12 @@ class FlxNestedSprite extends FlxSprite colorTransform.alphaMultiplier = 1; } useColorTransform = false; + #else + colorTransform.redMultiplier = 1; + colorTransform.greenMultiplier = 1; + colorTransform.blueMultiplier = 1; + colorTransform.alphaMultiplier = 1; + #end } dirty = true; @@ -333,7 +348,7 @@ class FlxNestedSprite extends FlxSprite override function set_color(Color:FlxColor):FlxColor { - Color = Color.to24Bit(); + Color = Color.rgb; var combinedRed:Float = (Color >> 16) * _parentRed / 255; var combinedGreen:Float = (Color >> 8 & 0xff) * _parentGreen / 255; @@ -347,6 +362,7 @@ class FlxNestedSprite extends FlxSprite color = combinedColor; if ((alpha != 1) || (color != 0x00ffffff)) { + #if (flixel < version("6.1.0")) if (colorTransform == null) { colorTransform = new ColorTransform(combinedRed, combinedGreen, combinedBlue, alpha); @@ -359,9 +375,16 @@ class FlxNestedSprite extends FlxSprite colorTransform.alphaMultiplier = alpha; } useColorTransform = true; + #else + colorTransform.redMultiplier = combinedRed; + colorTransform.greenMultiplier = combinedGreen; + colorTransform.blueMultiplier = combinedBlue; + colorTransform.alphaMultiplier = alpha; + #end } else { + #if (flixel < version("6.1.0")) if (colorTransform != null) { colorTransform.redMultiplier = 1; @@ -370,6 +393,12 @@ class FlxNestedSprite extends FlxSprite colorTransform.alphaMultiplier = 1; } useColorTransform = false; + #else + colorTransform.redMultiplier = 1; + colorTransform.greenMultiplier = 1; + colorTransform.blueMultiplier = 1; + colorTransform.alphaMultiplier = 1; + #end } dirty = true; @@ -401,7 +430,7 @@ class FlxNestedSprite extends FlxSprite return color; } - override function set_facing(Direction:Int):Int + override function set_facing(Direction:FlxDirectionFlags):FlxDirectionFlags { super.set_facing(Direction); if (children != null) diff --git a/flixel/addons/display/FlxPieDial.hx b/flixel/addons/display/FlxPieDial.hx index 0c50c9da..e5e8d382 100644 --- a/flixel/addons/display/FlxPieDial.hx +++ b/flixel/addons/display/FlxPieDial.hx @@ -1,18 +1,23 @@ package flixel.addons.display; import flixel.FlxSprite; +import flixel.graphics.FlxGraphic; +import flixel.graphics.tile.FlxGraphicsShader; import flixel.math.FlxMath; import flixel.math.FlxPoint; +import flixel.util.FlxBitmapDataPool; import flixel.util.FlxColor; +import flixel.util.FlxSpriteUtil; import openfl.display.BitmapData; import openfl.display.BitmapDataChannel; import openfl.display.BlendMode; +import openfl.geom.Point; +import openfl.geom.Rectangle; using flixel.util.FlxSpriteUtil; /** * A dynamic shape that fills up the way a pie chart does. Useful for timers and other things. - * @author larsiusprime */ class FlxPieDial extends FlxSprite { @@ -20,269 +25,356 @@ class FlxPieDial extends FlxSprite * A value between 0.0 (empty) and 1.0 (full) */ public var amount(default, set):Float; - - var pieFrames:Int = 0; - - public function new(X:Float, Y:Float, Radius:Int, Color:FlxColor = FlxColor.WHITE, Frames:Int = 36, ?Shape:FlxPieDialShape, Clockwise:Bool = true, - InnerRadius:Int = 0) + + public function new(x = 0.0, y = 0.0, radius:Int, color = FlxColor.WHITE, frames = 36, ?shape:FlxPieDialShape, clockwise = true, innerRadius = 0) { - if (Shape == null) - Shape = CIRCLE; - super(X, Y); - makePieDialGraphic(Radius, Color, Frames, Shape, Clockwise, InnerRadius); + if (shape == null) + shape = CIRCLE; + + super(x, y); + getPieDialGraphic(radius, color, frames, shape, clockwise, innerRadius); amount = 1.0; } override public function draw():Void { - if (amount == 0) + if (amount * animation.numFrames < 1) return; + super.draw(); } - - function makePieDialGraphic(Radius:Int, Color:FlxColor, Frames:Int, Shape:FlxPieDialShape, Clockwise:Bool, InnerRadius:Int) + + function getPieDialGraphic(radius:Int, color:FlxColor, frames:Int, shape:FlxPieDialShape, clockwise:Bool, innerRadius:Int) { - pieFrames = Frames; - var key:String = "pie_dial_" + Color.toHexString() + "_" + Radius + "_" + Frames + "_" + Shape + "_" + Clockwise + "_" + InnerRadius; - var W = Radius * 2; - var H = Radius * 2; - if (!FlxG.bitmap.checkCache(key)) - { - var bmp = makePieDialGraphicSub(Radius, Color, Frames, Shape, Clockwise, InnerRadius); - FlxG.bitmap.add(bmp, true, key); - } - - loadGraphic(key, true, W, H); + final graphic = FlxPieDialUtils.getPieDialGraphic(radius, color, frames, shape, clockwise, innerRadius); + loadGraphic(graphic, true, radius * 2, radius * 2); } - - function makePieDialGraphicSub(Radius:Int, Color:Int, Frames:Int, Shape:FlxPieDialShape, Clockwise:Bool, InnerRadius):BitmapData + + function set_amount(f:Float):Float { - var W = Radius * 2; - var H = Radius * 2; - - var rows:Int = Math.ceil(Math.sqrt(Frames)); - var cols:Int = Math.ceil((Frames) / rows); - - var back = Clockwise ? FlxColor.BLACK : FlxColor.WHITE; - var fore = Clockwise ? FlxColor.WHITE : FlxColor.BLACK; - - var fullFrame = makeFullFrame(Radius, Color, Frames, Shape, Clockwise, InnerRadius); - var nextFrame = new FlxSprite().makeGraphic(W, H, back, false); - - var bmp:BitmapData = new BitmapData(W * cols, H * rows, false, back); - var i:Int = 0; - _flashPoint.setTo(0, 0); - var p:FlxPoint = FlxPoint.get(0, -1); - var degrees:Float = 360 / (Frames); - if (!Clockwise) + amount = FlxMath.bound(f, 0.0, 1.0); + var frame:Int = Std.int(f * animation.numFrames); + animation.frameIndex = frame; + if (amount == 1.0) { - degrees *= -1; + animation.frameIndex = 0; // special case for full frame } + return amount; + } +} - var sweep:Float = Clockwise ? 0 : 360; - var bmp2 = new BitmapData(bmp.width, bmp.height, true, FlxColor.TRANSPARENT); - var fullBmp:BitmapData = fullFrame.pixels.clone(); +enum FlxPieDialShape +{ + CIRCLE; + SQUARE; +} - var polygon:Array = [FlxPoint.get(), FlxPoint.get(), FlxPoint.get(), FlxPoint.get(), FlxPoint.get()]; - for (r in 0...rows) +/** + * Set of tools for drawing pie dial graphics + * @since 5.9.0 + */ +class FlxPieDialUtils +{ + static final _rect = new Rectangle(); + static final _zero = new Point(); + static final _point = new Point(); + static var flashGfx = FlxSpriteUtil.flashGfx; + + public static function getPieDialGraphic(radius:Int, color:FlxColor, frames:Int, shape:FlxPieDialShape, clockwise:Bool, innerRadius:Int) + { + final key = 'pie_dial_${color.toHexString()}_${radius}_${frames}_${shape}_${clockwise}_$innerRadius'; + + if (!FlxG.bitmap.checkCache(key)) { - for (c in 0...cols) - { - if (i >= Frames) - { - break; - } - - _flashPoint.setTo(c * W, r * H); - bmp2.copyPixels(fullBmp, fullBmp.rect, _flashPoint); - - if (i <= 0) - { - bmp.fillRect(fullBmp.rect, FlxColor.WHITE); - } - else - { - nextFrame.pixels.copyPixels(fullFrame.pixels, fullFrame.pixels.rect, _flashPointZero); - _flashPoint.setTo(c * W, r * H); - drawSweep(sweep, p, nextFrame, polygon, W, H, back, fore); - bmp.copyPixels(nextFrame.pixels, nextFrame.pixels.rect, _flashPoint); - } - - sweep += degrees; - p.rotateByDegrees(degrees); - - i++; - } - - if (i >= Frames) - { - break; - } + final bmp = renderPieDial(shape, radius, innerRadius, frames, clockwise, color); + FlxG.bitmap.add(bmp, true, key); } - - fullBmp.dispose(); - fullFrame.destroy(); - nextFrame.destroy(); - - var shapeChannel = new BitmapData(bmp.width, bmp.height, false); - shapeChannel.copyChannel(bmp2, bmp2.rect, _flashPointZero, BitmapDataChannel.ALPHA, BitmapDataChannel.RED); - shapeChannel.copyChannel(bmp2, bmp2.rect, _flashPointZero, BitmapDataChannel.ALPHA, BitmapDataChannel.GREEN); - shapeChannel.copyChannel(bmp2, bmp2.rect, _flashPointZero, BitmapDataChannel.ALPHA, BitmapDataChannel.BLUE); - - shapeChannel.draw(bmp, null, null, BlendMode.MULTIPLY, null, true); - bmp2.copyChannel(shapeChannel, shapeChannel.rect, _flashPointZero, BitmapDataChannel.RED, BitmapDataChannel.ALPHA); - - shapeChannel.dispose(); - bmp.dispose(); - - return bmp2; + + return FlxG.bitmap.get(key); } - - function makeFullFrame(Radius:Int, Color:Int, Frames:Int, Shape:FlxPieDialShape, Clockwise:Bool, InnerRadius):FlxSprite + + public static function getRadialGaugeGraphic(shape:FlxPieDialShape, radius:Int, innerRadius = 0, color = FlxColor.WHITE) { - var W = Radius * 2; - var H = Radius * 2; - - var fullFrame = new FlxSprite().makeGraphic(W, H, FlxColor.TRANSPARENT, true); - if (InnerRadius > Radius) - { - InnerRadius = 0; - } - - var dR = Radius - InnerRadius; - - if (Shape == SQUARE) + final key = 'radial_gauge_${shape}_${color.toHexString()}_${radius}_$innerRadius'; + + if (!FlxG.bitmap.checkCache(key)) { - fullFrame.pixels.fillRect(fullFrame.pixels.rect, Color); - if (InnerRadius > 0) - { - _flashRect.setTo(dR, dR, InnerRadius * 2, InnerRadius * 2); - fullFrame.pixels.fillRect(_flashRect, FlxColor.TRANSPARENT); - } + final bmp = renderRadialGauge(shape, radius, innerRadius, color); + FlxG.bitmap.add(bmp, true, key); } - else if (Shape == CIRCLE) + + return FlxG.bitmap.get(key); + } + + /** + * Draws an animated pie dial graphic where each frame shows a more full amount, + * however the full gauge frame is on frame 0 + * + * @param radius The radius of the shape + * @param color The color of the shape + * @param shape The shape, Either `SQUARE` or `CIRCLE` + * @param innerRadius The radius of the inner hollow portion, where `0` means completely filled + */ + public static function renderRadialGauge(shape:FlxPieDialShape, radius:Int, innerRadius = 0, color = FlxColor.WHITE):BitmapData + { + return renderPieDial(shape, radius, innerRadius, 1, true, color); + } + + /** + * Draws an animated pie dial graphic where each frame shows a more full amount, + * however the full gauge frame is on frame 0 + * + * @param radius The radius of the shape + * @param color The color of the shape + * @param frames + * @param shape The shape, Either `SQUARE` or `CIRCLE` + * @param clockwise The direction the gauge + * @param innerRadius The radius of the inner hollow portion, where `0` means completely filled + */ + public static function renderPieDial(shape:FlxPieDialShape, radius:Int, innerRadius:Int, frames:Int, clockwise = true, color = FlxColor.WHITE):BitmapData + { + final W = radius * 2; + final H = radius * 2; + + final rows = Math.ceil(Math.sqrt(frames)); + final cols = Math.ceil(frames / rows); + + final maskFrame = FlxBitmapDataPool.get(W, H, true, FlxColor.TRANSPARENT, true); + final fullFrame = FlxBitmapDataPool.get(W, H, true, FlxColor.TRANSPARENT, true); + FlxPieDialUtils.drawShape(fullFrame, radius, color, shape, innerRadius); + + final result = new BitmapData(W * cols, H * rows, true, FlxColor.TRANSPARENT); + final p = FlxPoint.get(); + final degreeInterval = (clockwise ? 1 : -1) * 360 / frames; + + final mask = FlxBitmapDataPool.get(result.width, result.height, result.transparent, FlxColor.TRANSPARENT, true); + + final polygon:Array = [FlxPoint.get(), FlxPoint.get(), FlxPoint.get(), FlxPoint.get(), FlxPoint.get()]; + for (i in 0...frames) { - if (InnerRadius > 0) + _point.setTo((i % cols) * W, Std.int(i / cols) * H); + result.copyPixels(fullFrame, fullFrame.rect, _point);//, null, null, true); + if (i <= 0) { - var alpha = new BitmapData(fullFrame.pixels.width, fullFrame.pixels.height, false, FlxColor.BLACK); - fullFrame.pixels.fillRect(_flashRect, FlxColor.BLACK); - fullFrame.drawCircle(-1, -1, Radius, FlxColor.WHITE, null, {smoothing: true}); - fullFrame.drawCircle(-1, -1, InnerRadius, FlxColor.BLACK, null, {smoothing: true}); - - alpha.copyPixels(fullFrame.pixels, fullFrame.pixels.rect, _flashPointZero, null, null, true); - - fullFrame.pixels.fillRect(fullFrame.pixels.rect, Color); - fullFrame.pixels.copyChannel(alpha, alpha.rect, _flashPointZero, BitmapDataChannel.RED, BitmapDataChannel.ALPHA); - - alpha.dispose(); + mask.fillRect(fullFrame.rect, FlxColor.WHITE); } else { - fullFrame.drawCircle(-1, -1, Radius, Color); + final angle = degreeInterval * i; + maskFrame.fillRect(maskFrame.rect, FlxColor.TRANSPARENT); + FlxPieDialUtils.drawSweep(maskFrame, angle); + mask.copyPixels(maskFrame, maskFrame.rect, _point, null, null, true); } } - return fullFrame; + + result.copyPixels(result, result.rect, _zero, mask); + FlxBitmapDataPool.put(mask); + FlxBitmapDataPool.put(maskFrame); + FlxBitmapDataPool.put(fullFrame); + + return result; } - - function drawSweep(sweep:Float, p:FlxPoint, nextFrame:FlxSprite, polygon:Array, W:Int, H:Int, back:FlxColor, fore:FlxColor) + + /** + * Draws the specified shape onto the bitmap + * + * @param dest The bitmap to draw to + * @param radius The radius of the shape + * @param color The color of the shape + * @param shape The shape, Either `SQUARE` or `CIRCLE` + * @param innerRadius The radius of the inner hollow portion, where `0` means completely filled + */ + public static inline function drawShape(dest:BitmapData, radius:Int, color:FlxColor, shape:FlxPieDialShape, innerRadius = 0):BitmapData { - var halfW = W / 2; - var halfH = H / 2; - - nextFrame.pixels.fillRect(nextFrame.pixels.rect, back); - polygon[0].set(halfW, halfH); - - if (sweep < 45) + final W = radius << 1; + final H = radius << 1; + + switch (shape) { - polygon[1].set(halfW, 0); - polygon[2].set(halfW + W * p.x, halfH + H * p.y); - polygon[3].set(halfW, halfH); + case SQUARE if (innerRadius > 0 && innerRadius < radius): + final thickness = radius - innerRadius; + _rect.setTo(0, 0, W, thickness); + dest.fillRect(_rect, color); + _rect.setTo(0, 0, thickness, H); + dest.fillRect(_rect, color); + _rect.setTo(W - thickness, 0, thickness, H); + dest.fillRect(_rect, color); + _rect.setTo(0, H - thickness, W, thickness); + dest.fillRect(_rect, color); + + case SQUARE: + dest.fillRect(dest.rect, color); + + case CIRCLE if (innerRadius > 0 && innerRadius < radius): + final alpha = FlxBitmapDataPool.get(W, H, false, FlxColor.BLACK, true); + alpha.fillRect(alpha.rect, FlxColor.BLACK); + drawCircle(alpha, radius, FlxColor.WHITE, null, {smoothing: true}); + drawCircle(alpha, innerRadius, FlxColor.BLACK, null, {smoothing: true}); + + alpha.copyPixels(dest, dest.rect, _zero, null, null, true); + + dest.fillRect(dest.rect, color); + dest.copyChannel(alpha, alpha.rect, _zero, BitmapDataChannel.RED, BitmapDataChannel.ALPHA); + + FlxBitmapDataPool.put(alpha); + + case CIRCLE: + drawCircle(dest, radius, color); } - else if (sweep < 90) + return dest; + } + + /** + * Used via `drawSweep` + */ + static final sweepPoints = [for (i in 0...4) FlxPoint.get()]; + + /** + * Draws a wedge section of a bitmap, used in `FlxPieDial` + * @param dest The btimap to draw to + * @param degrees The angle of the wedge + * @param color The color to fill the wedge + */ + public static function drawSweep(dest:BitmapData, degrees:Float, color = FlxColor.WHITE) + { + degrees %= 360; + final p = sweepPoints; + final radius = dest.width >> 1; + final center = p[0].set(radius, radius); + final cornerLength = center.length; + + if (degrees >= 270) { - polygon[1].set(halfW, 0); - polygon[2].set(W, 0); - polygon[3].set(halfW + W * p.x, halfH + H * p.y); + // fill right half + _rect.setTo(radius, 0, radius, dest.height); + dest.fillRect(_rect, color); + // fill bottom-left quadrant + _rect.setTo(0, radius, radius, radius); + dest.fillRect(_rect, color); } - else if (sweep < 135) + else if (degrees >= 180) { - _flashRect.setTo(halfW, 0, halfW, halfH); - nextFrame.pixels.fillRect(_flashRect, fore); - - polygon[1].set(W, halfH); - polygon[2].set(halfW + W * p.x, halfH + H * p.y); - polygon[3].set(halfW, halfH); + // fill right half + _rect.setTo(radius, 0, radius, dest.height); + dest.fillRect(_rect, color); } - else if (sweep < 180) + else if (degrees >= 90) { - _flashRect.setTo(halfW, 0, halfW, halfH); - nextFrame.pixels.fillRect(_flashRect, fore); - - polygon[1].set(W, halfH); - polygon[2].set(W, H); - polygon[3].set(halfW + W * p.x, halfH + H * p.y); + // fill top-right quadrant + _rect.setTo(radius, 0, radius, radius); + dest.fillRect(_rect, color); } - else if (sweep < 225) + else if (degrees <= -270) { - _flashRect.setTo(halfW, 0, halfW, H); - nextFrame.pixels.fillRect(_flashRect, fore); - - polygon[1].set(halfW, H); - polygon[2].set(halfW + W * p.x, halfH + H * p.y); - polygon[3].set(halfW, halfH); + // fill left half + _rect.setTo(0, 0, radius, dest.height); + dest.fillRect(_rect, color); + // fill bottom-right quadrant + _rect.setTo(radius, radius, radius, radius); + dest.fillRect(_rect, color); } - else if (sweep < 270) + else if (degrees <= -180) { - _flashRect.setTo(halfW, 0, halfW, H); - nextFrame.pixels.fillRect(_flashRect, fore); - - polygon[1].set(halfW, H); - polygon[2].set(0, H); - polygon[3].set(halfW + W * p.x, halfH + H * p.y); + // fill left half + _rect.setTo(0, 0, radius, dest.height); + dest.fillRect(_rect, color); } - else if (sweep < 315) + else if (degrees <= -90) { - _flashRect.setTo(halfW, 0, halfW, H); - nextFrame.pixels.fillRect(_flashRect, fore); - _flashRect.setTo(0, halfH, halfW, halfH); - nextFrame.pixels.fillRect(_flashRect, fore); - - polygon[1].set(0, halfH); - polygon[2].set(halfW + W * p.x, halfH + H * p.y); - polygon[3].set(halfW, halfH); + // fill top-left quadrant + _rect.setTo(0, 0, radius, radius); + dest.fillRect(_rect, color); } - else if (sweep < 360) + + // draw the interesting quadrant + if (Math.abs(degrees % 90) < 45) { - _flashRect.setTo(halfW, 0, halfW, H); - nextFrame.pixels.fillRect(_flashRect, fore); - _flashRect.setTo(0, halfH, halfW, halfH); - nextFrame.pixels.fillRect(_flashRect, fore); - - polygon[1].set(0, halfH); - polygon[2].set(0, 0); - polygon[3].set(halfW + W * p.x, halfH + H * p.y); + p[1].setPolarDegrees(radius, -90 + Std.int(degrees / 90) * 90).addPoint(center); + p[2].setPolarDegrees(cornerLength, -90 + degrees).addPoint(center); + p[3].copyFrom(center); } - - polygon[4].set(halfW, halfH); - - nextFrame.drawPolygon(polygon, fore); + else + { + final quadDegreesStart = Std.int(degrees / 90) * 90; + final cornerDegrees = quadDegreesStart + (degrees < 0 ? -45 : 45); + p[1].setPolarDegrees(radius, -90 + quadDegreesStart).addPoint(center); + p[2].setPolarDegrees(cornerLength, -90 + cornerDegrees).addPoint(center); + p[3].setPolarDegrees(cornerLength, -90 + degrees).addPoint(center); + } + + drawPolygon(dest, p, color); } - - function set_amount(f:Float):Float + + /** + * This function draws a circle on a FlxSprite at position X,Y with the specified color. + * + * @param bitmap The BitmapData to manipulate + * @param X X coordinate of the circle's center (automatically centered on the sprite if -1) + * @param Y Y coordinate of the circle's center (automatically centered on the sprite if -1) + * @param radius Radius of the circle (makes sure the circle fully fits on the sprite's graphic if < 1, assuming and and y are centered) + * @param color The ARGB color to fill this circle with. FlxColor.TRANSPARENT (0x0) means no fill. + * @param lineStyle A LineStyle typedef containing the params of Graphics.lineStyle() + * @param drawStyle A DrawStyle typedef containing the params of BitmapData.draw() + * @return The FlxSprite for chaining + */ + public static function drawCircle(bitmap:BitmapData, ?radius:Float, color = FlxColor.WHITE, ?lineStyle:LineStyle, ?drawStyle:DrawStyle):BitmapData { - amount = FlxMath.bound(f, 0.0, 1.0); - var frame:Int = Std.int(f * pieFrames); - animation.frameIndex = frame; - if (amount == 1.0) + final x = bitmap.width * 0.5; + final y = bitmap.height * 0.5; + + if (radius == null) + radius = Math.min(bitmap.width, bitmap.height) * 0.5; + + beginDraw(color, lineStyle); + flashGfx.drawCircle(x, y, radius); + endDraw(bitmap, drawStyle); + return bitmap; + } + + /** + * This function draws a polygon on a FlxSprite. + * + * @param graphic The FlxSprite to manipulate + * @param Vertices Array of Vertices to use for drawing the polygon + * @param FillColor The ARGB color to fill this polygon with. FlxColor.TRANSPARENT (0x0) means no fill. + * @param lineStyle A LineStyle typedef containing the params of Graphics.lineStyle() + * @param drawStyle A DrawStyle typedef containing the params of BitmapData.draw() + * @return The FlxSprite for chaining + */ + public static function drawPolygon(bitmap:BitmapData, vertices:Array, fillColor = FlxColor.WHITE, ?lineStyle:LineStyle, + ?drawStyle:DrawStyle):BitmapData + { + beginDraw(fillColor, lineStyle); + final p:FlxPoint = vertices.shift(); + flashGfx.moveTo(p.x, p.y); + for (p in vertices) { - animation.frameIndex = 0; // special case for full frame + flashGfx.lineTo(p.x, p.y); } - return amount; + endDraw(bitmap, drawStyle); + vertices.unshift(p); + return bitmap; } -} - -enum FlxPieDialShape -{ - CIRCLE; - SQUARE; -} + + static inline function beginDraw(color:FlxColor, ?lineStyle:LineStyle):Void + { + flashGfx.clear(); + FlxSpriteUtil.setLineStyle(lineStyle); + + if (color != FlxColor.TRANSPARENT) + flashGfx.beginFill(color.rgb, color.alphaFloat); + } + + static inline function endDraw(bitmap:BitmapData, ?style:DrawStyle):BitmapData + { + flashGfx.endFill(); + if (style == null) + style = {smoothing: false}; + else if (style.smoothing == null) + style.smoothing = false; + + final sprite = FlxSpriteUtil.flashGfxSprite; + bitmap.draw(sprite, style.matrix, style.colorTransform, style.blendMode, style.clipRect, style.smoothing); + return bitmap; + } +} \ No newline at end of file diff --git a/flixel/addons/display/FlxRadialGauge.hx b/flixel/addons/display/FlxRadialGauge.hx new file mode 100644 index 00000000..8c79c70c --- /dev/null +++ b/flixel/addons/display/FlxRadialGauge.hx @@ -0,0 +1,155 @@ +package flixel.addons.display; + +import flixel.FlxSprite; +import flixel.addons.display.FlxPieDial; +import flixel.util.FlxColor; + +#if !flash +/** + * A dynamic shape that fills up radially (like a pie chart). Useful for timers and other things. + * `FlxRadialGauge` uses `FlxRadialWipeShader` to fill the gauge portion, where `FlxPieDial` + * creates an animation. This also works with any graphic, unlike `FlxPieDial` + * @since 5.9.0 + */ +class FlxRadialGauge extends FlxSprite +{ + /** A value between 0.0 (empty) and 1.0 (full) */ + public var amount(get, set):Float; + inline function get_amount():Float + { + return _sweepShader.amount; + } + inline function set_amount(value:Float):Float + { + return _sweepShader.amount = value; + } + + /** The angle in degrees to start the dial fill */ + public var start(get, set):Float; + inline function get_start():Float + { + return _sweepShader.start; + } + inline function set_start(value:Float):Float + { + return _sweepShader.start = value; + } + + /** The angle in degrees to end the dial fill */ + public var end(get, set):Float; + inline function get_end():Float + { + return _sweepShader.end; + } + inline function set_end(value:Float):Float + { + return _sweepShader.end = value; + } + + var _sweepShader(get, never):FlxRadialWipeShader; + inline function get__sweepShader() return cast shader; + + public function new(x = 0.0, y = 0.0, ?simpleGraphic) + { + super(x, y, simpleGraphic); + + shader = new FlxRadialWipeShader(); + this.amount = 1; + } + + public function makeShapeGraphic(shape:FlxRadialGaugeShape, radius:Int, innerRadius = 0, color = FlxColor.WHITE) + { + final graphic = FlxPieDialUtils.getRadialGaugeGraphic(shape, radius, innerRadius, color); + loadGraphic(graphic, true, radius * 2, radius * 2); + } + + public function setOrientation(start = -90.0, end = 270.0) + { + this.start = start; + this.end = end; + } +} + +typedef FlxRadialGaugeShape = FlxPieDialShape; + +/** + * A shader that masks a static sprite radially, based on the `start` and `end` angles + */ +class FlxRadialWipeShader extends flixel.system.FlxAssets.FlxShader +{ + /** The current fill amount, where `0.0` is empty and `1.0` is full */ + public var amount(get, set):Float; + inline function get_amount():Float return _amount.value[0]; + inline function set_amount(value:Float):Float + { + _amount.value = [value]; + return value; + } + + /** The angle in degrees to start the dial fill */ + public var start(get, set):Float; + inline function get_start():Float return _start.value[0]; + inline function set_start(value:Float):Float + { + _start.value = [value]; + return value; + } + + /** The angle in degrees to end the dial fill */ + public var end(get, set):Float; + inline function get_end():Float return _end.value[0]; + inline function set_end(value:Float):Float + { + _end.value = [value]; + return value; + } + + @:glFragmentSource(' + #pragma header + + const float TAU = 6.2831853072; + + uniform float _amount; + uniform float _start; + uniform float _end; + + float getGradiant(in vec2 dist) + { + float start = _start / 360.0; + float delta = (_end - _start) / 360.0; + float angle = atan(dist.y, dist.x) / TAU; + if (_end > _start) + return mod(angle - start, 1.0) / delta; + else + return mod(start - angle, 1.0) / -delta; + } + + float wedge(in vec2 uv, in float ratio) + { + vec2 dist = uv - vec2(0.5); + float grad = getGradiant(dist); + return step(ratio, grad < 0.0 ? 1.0 : grad); + } + + void main() + { + if (_amount > 0.0) + { + float amount = min(1.0, max(0.0, _amount)); + vec4 bitmap = flixel_texture2D(bitmap, openfl_TextureCoordv); + gl_FragColor = mix(bitmap, vec4(0.0), wedge(openfl_TextureCoordv, amount)); + } + else + gl_FragColor = vec4(0.0); + }') + public function new() + { + super(); + amount = 1.0; + start = -90; + end = 270; + } +} +#elseif (FLX_NO_COVERAGE_TEST && !doc_gen) +#error "FlxRadialGauge is not supported on flash targets" +#end \ No newline at end of file diff --git a/flixel/addons/display/FlxRuntimeShader.hx b/flixel/addons/display/FlxRuntimeShader.hx index bd385e46..edf2e0b2 100644 --- a/flixel/addons/display/FlxRuntimeShader.hx +++ b/flixel/addons/display/FlxRuntimeShader.hx @@ -337,4 +337,4 @@ class FlxRuntimeShader extends FlxGraphicsShader { return 'FlxRuntimeShader'; } -} +} \ No newline at end of file diff --git a/flixel/addons/display/FlxShaderMaskCamera.hx b/flixel/addons/display/FlxShaderMaskCamera.hx index 456895b3..d935be62 100644 --- a/flixel/addons/display/FlxShaderMaskCamera.hx +++ b/flixel/addons/display/FlxShaderMaskCamera.hx @@ -1,6 +1,6 @@ package flixel.addons.display; -#if (openfl >= "8.0.0") +#if (openfl >= version("8.0.0")) import flixel.FlxBasic; import flixel.FlxCamera; import flixel.FlxG; @@ -111,7 +111,7 @@ class FlxShaderMaskCamera extends FlxCamera { // clear our duplicate canvas shaderCanvas.graphics.clear(); - super.fill(bgColor.to24Bit(), useBgAlphaBlending, bgColor.alphaFloat, shaderCanvas.graphics); + super.fill(bgColor.rgb, useBgAlphaBlending, bgColor.alphaFloat, shaderCanvas.graphics); // iterate over draw items, but draw them to both canvases var currItem:FlxDrawBaseItem = _headOfDrawStack; var oldCanvas:Sprite = canvas; diff --git a/flixel/addons/display/FlxTiledSprite.hx b/flixel/addons/display/FlxTiledSprite.hx index da8004fe..2f9f643b 100644 --- a/flixel/addons/display/FlxTiledSprite.hx +++ b/flixel/addons/display/FlxTiledSprite.hx @@ -22,44 +22,44 @@ class FlxTiledSprite extends FlxStrip * The x-offset of the texture */ public var scrollX(default, set):Float = 0; - + /** * The y-offset of the texture. */ public var scrollY(default, set):Float = 0; - + /** * Repeat texture on x axis. Default is true */ public var repeatX(default, set):Bool = true; - + /** * Repeat texture on y axis. Default is true */ public var repeatY(default, set):Bool = true; - + /** * Helper sprite, which does actual rendering in blit render mode. */ var renderSprite:FlxSprite; - + var regen:Bool = true; - + var graphicVisible:Bool = true; - - public function new(?Graphic:FlxGraphicAsset, Width:Float, Height:Float, RepeatX:Bool = true, RepeatY:Bool = true) + + public function new(?graphic:FlxGraphicAsset, width:Float, height:Float, repeatX = true, repeatY = true) { super(); - + repeat = true; - + indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 2; indices[4] = 3; indices[5] = 0; - + uvtData[0] = 0; uvtData[1] = 0; uvtData[2] = 1; @@ -68,66 +68,64 @@ class FlxTiledSprite extends FlxStrip uvtData[5] = 1; uvtData[6] = 0; uvtData[7] = 1; - + vertices[0] = 0; vertices[1] = 0; - vertices[2] = Width; + vertices[2] = width; vertices[3] = 0; - vertices[4] = Width; - vertices[5] = Height; + vertices[4] = width; + vertices[5] = height; vertices[6] = 0; - vertices[7] = Height; - - width = Width; - height = Height; - - repeatX = RepeatX; - repeatY = RepeatY; - - if (Graphic != null) - loadGraphic(Graphic); + vertices[7] = height; + + this.width = width; + this.height = height; + + this.repeatX = repeatX; + this.repeatY = repeatY; + + if (graphic != null) + loadGraphic(graphic); } - - override public function destroy():Void + + override function destroy():Void { renderSprite = FlxDestroyUtil.destroy(renderSprite); super.destroy(); } - - override public function loadGraphic(Graphic:FlxGraphicAsset, Animated:Bool = false, Width:Int = 0, Height:Int = 0, Unique:Bool = false, - ?Key:String):FlxSprite + + override function loadGraphic(graphic, animated = false, width = 0, height = 0, unique = false, ?key:String):FlxSprite { - graphic = FlxG.bitmap.add(Graphic); + this.graphic = FlxG.bitmap.add(graphic); return this; } - - public function loadFrame(Frame:FlxFrame):FlxTiledSprite + + public function loadFrame(frame:FlxFrame):FlxTiledSprite { - graphic = FlxGraphic.fromFrame(Frame); + graphic = FlxGraphic.fromFrame(frame); return this; } - - override function set_clipRect(Value:FlxRect):FlxRect + + override function set_clipRect(value:FlxRect):FlxRect { - if (Value != clipRect) - regen = true; - - return super.set_clipRect(Value); + regen = true; + + return super.set_clipRect(value); } - - override function set_graphic(Value:FlxGraphic):FlxGraphic + + override function set_graphic(value:FlxGraphic):FlxGraphic { - if (graphic != Value) + if (graphic != value) regen = true; - - return super.set_graphic(Value); + + return super.set_graphic(value); } - + function regenGraphic():Void { if (!regen || graphic == null) return; - + if (FlxG.renderBlit) { updateRenderSprite(); @@ -136,69 +134,92 @@ class FlxTiledSprite extends FlxStrip { updateVerticesData(); } - + regen = false; } - - override public function draw():Void + + override function draw():Void { if (regen) regenGraphic(); - - if (!graphicVisible) - return; - - if (FlxG.renderBlit) + + if (graphicVisible) { - renderSprite.x = x; - renderSprite.y = y; - renderSprite.scrollFactor.set(scrollFactor.x, scrollFactor.y); - renderSprite._cameras = _cameras; - renderSprite.draw(); + if (FlxG.renderBlit) + { + renderSprite.x = x; + renderSprite.y = y; + renderSprite.scrollFactor.set(scrollFactor.x, scrollFactor.y); + renderSprite._cameras = _cameras; + renderSprite.draw(); + } + else + { + super.draw(); + } } - else + + #if FLX_DEBUG + if (FlxG.debugger.drawDebug) + drawDebug(); + #end + } + + #if FLX_DEBUG + /** + * Copied exactly from `FlxObject`, to avoid any future changes to `FlxStrip`'s debug drawing + */ + override function drawDebug() + { + if (ignoreDrawDebug) + return; + + final drawPath = path != null && !path.ignoreDrawDebug; + + for (camera in getCamerasLegacy()) { - super.draw(); + drawDebugOnCamera(camera); + + if (drawPath) + { + path.drawDebugOnCamera(camera); + } } } - + #end + function updateRenderSprite():Void { graphicVisible = true; - + if (renderSprite == null) renderSprite = new FlxSprite(); - - var rectX:Float = repeatX ? 0 : scrollX; - var rectWidth:Float = repeatX ? width : graphic.bitmap.width; - - if (!repeatX && (rectX > width || rectX + rectWidth < 0)) + + final drawRect = getDrawRect(); + drawRect.x = Std.int(drawRect.x); + drawRect.y = Std.int(drawRect.y); + drawRect.width = Std.int(drawRect.width); + drawRect.height = Std.int(drawRect.height); + // TODO: rect.int() or smth + + if (drawRect.width * drawRect.height == 0) { graphicVisible = false; + drawRect.put(); return; } - - var rectY:Float = repeatY ? 0 : scrollY; - var rectHeight:Float = repeatY ? height : graphic.bitmap.height; - - if (!repeatY && (rectY > height || rectY + rectHeight < 0)) + + if (renderSprite.width != drawRect.width || renderSprite.height != drawRect.height) { - graphicVisible = false; - return; - } - - if (renderSprite.width != width || renderSprite.height != height) - { - renderSprite.makeGraphic(Std.int(width), Std.int(height), FlxColor.TRANSPARENT, true); + renderSprite.makeGraphic(Std.int(drawRect.width), Std.int(drawRect.height), FlxColor.TRANSPARENT, true); } else { - _flashRect2.setTo(0, 0, width, height); - renderSprite.pixels.fillRect(_flashRect2, FlxColor.TRANSPARENT); + renderSprite.pixels.fillRect(renderSprite.pixels.rect, FlxColor.TRANSPARENT); } - + FlxSpriteUtil.flashGfx.clear(); - + if (scrollX != 0 || scrollY != 0) { _matrix.identity(); @@ -210,115 +231,150 @@ class FlxTiledSprite extends FlxStrip { FlxSpriteUtil.flashGfx.beginBitmapFill(graphic.bitmap); } - - FlxSpriteUtil.flashGfx.drawRect(rectX, rectY, rectWidth, rectHeight); + + FlxSpriteUtil.flashGfx.drawRect(drawRect.x, drawRect.y, drawRect.width, drawRect.height); renderSprite.pixels.draw(FlxSpriteUtil.flashGfxSprite, null, colorTransform); FlxSpriteUtil.flashGfx.clear(); renderSprite.dirty = true; } - + function updateVerticesData():Void { if (graphic == null) return; - - var frame:FlxFrame = graphic.imageFrame.frame; + + final frame:FlxFrame = graphic.imageFrame.frame; graphicVisible = true; - - var rectX:Float = (repeatX ? 0 : scrollX); - rectX = FlxMath.bound(rectX, 0, width); - if (clipRect != null) rectX += clipRect.x; - - var rectWidth:Float = (repeatX ? rectX + width : scrollX + frame.sourceSize.x); - if (clipRect != null) rectWidth = FlxMath.bound(rectWidth, clipRect.x, clipRect.x + clipRect.width); - + + final drawRect = getDrawRect(); + + if (drawRect.width * drawRect.height == 0) + { + graphicVisible = false; + drawRect.put(); + return; + } + // Texture coordinates (UVs) - var rectUX:Float = (rectX - scrollX) / frame.sourceSize.x; - var rectVX:Float = rectUX + (rectWidth-rectX) / frame.sourceSize.x; - - vertices[0] = rectX; - vertices[2] = rectWidth; - vertices[4] = rectWidth; - vertices[6] = rectX; - + final rectUX:Float = (drawRect.x - scrollX) / frame.sourceSize.x; + final rectVX:Float = rectUX + (drawRect.width - drawRect.x) / frame.sourceSize.x; + final rectUY:Float = (drawRect.y - scrollY) / frame.sourceSize.y; + final rectVY:Float = rectUY + (drawRect.height - drawRect.y) / frame.sourceSize.y; + + vertices[0] = drawRect.x; + vertices[2] = drawRect.width; + vertices[4] = drawRect.width; + vertices[6] = drawRect.x; + uvtData[0] = rectUX; uvtData[2] = rectVX; uvtData[4] = rectVX; uvtData[6] = rectUX; - - var rectY:Float = (repeatY ? 0 : scrollY); - rectY = FlxMath.bound(rectY, 0, height); - if (clipRect != null) rectY += clipRect.y; - - var rectHeight:Float = (repeatY ? rectY + height : scrollY + frame.sourceSize.y); - if (clipRect != null) rectHeight = FlxMath.bound(rectHeight, clipRect.y, clipRect.y + clipRect.height); - - // Texture coordinates (UVs) - var rectUY:Float = (rectY - scrollY) / frame.sourceSize.y; - var rectVY:Float = rectUY + (rectHeight-rectY) / frame.sourceSize.y; - - vertices[1] = rectY; - vertices[3] = rectY; - vertices[5] = rectHeight; - vertices[7] = rectHeight; - + + vertices[1] = drawRect.y; + vertices[3] = drawRect.y; + vertices[5] = drawRect.height; + vertices[7] = drawRect.height; + uvtData[1] = rectUY; uvtData[3] = rectUY; uvtData[5] = rectVY; uvtData[7] = rectVY; + + drawRect.put(); } - - override function set_width(Width:Float):Float + + function getDrawRect(?result:FlxRect):FlxRect { - if (Width <= 0) - return Width; - - if (Width != width) + if (result == null) + result = FlxRect.get(); + + final frame:FlxFrame = graphic.imageFrame.frame; + final sourceSizeX = FlxG.renderBlit ? graphic.bitmap.width : frame.sourceSize.x; + final sourceSizeY = FlxG.renderBlit ? graphic.bitmap.height : frame.sourceSize.y; + + result.x = (repeatX ? 0 : scrollX); + if (clipRect != null) + { + result.x += clipRect.x; + } + result.x = FlxMath.bound(result.x, 0, width); + + result.width = (repeatX ? result.x + width : scrollX + sourceSizeX); + if (clipRect != null) + { + result.width = FlxMath.bound(result.width, clipRect.x, clipRect.right); + } + result.width = FlxMath.bound(result.width, 0, width); + + result.y = (repeatY ? 0 : scrollY); + if (clipRect != null) + { + result.y += clipRect.y; + } + result.y = FlxMath.bound(result.y, 0, height); + + result.height = (repeatY ? result.y + height : scrollY + sourceSizeY); + if (clipRect != null) + { + result.height = FlxMath.bound(result.height, clipRect.y, clipRect.bottom); + } + result.height = FlxMath.bound(result.height, 0, height); + + return result; + } + + override function set_width(value:Float):Float + { + if (value <= 0) + return value; + + if (value != width) regen = true; - - return super.set_width(Width); + + return super.set_width(value); } - - override function set_height(Height:Float):Float + + override function set_height(value:Float):Float { - if (Height <= 0) - return Height; - - if (Height != height) + if (value <= 0) + return value; + + if (value != height) regen = true; - - return super.set_height(Height); + + return super.set_height(value); } - - function set_scrollX(Value:Float):Float + + function set_scrollX(value:Float):Float { - if (Value != scrollX) + if (value != scrollX) regen = true; - - return scrollX = Value; + + return scrollX = value; } - - function set_scrollY(Value:Float):Float + + function set_scrollY(value:Float):Float { - if (Value != scrollY) + if (value != scrollY) regen = true; - - return scrollY = Value; + + return scrollY = value; } - - function set_repeatX(Value:Bool):Bool + + function set_repeatX(value:Bool):Bool { - if (Value != repeatX) + if (value != repeatX) regen = true; - - return repeatX = Value; + + return repeatX = value; } - - function set_repeatY(Value:Bool):Bool + + function set_repeatY(value:Bool):Bool { - if (Value != repeatY) + if (value != repeatY) regen = true; - - return repeatY = Value; + + return repeatY = value; } } diff --git a/flixel/addons/editors/ogmo/FlxOgmo3Loader.hx b/flixel/addons/editors/ogmo/FlxOgmo3Loader.hx index 95dd88f5..76152a57 100644 --- a/flixel/addons/editors/ogmo/FlxOgmo3Loader.hx +++ b/flixel/addons/editors/ogmo/FlxOgmo3Loader.hx @@ -284,7 +284,11 @@ class FlxOgmo3Loader for (i in 0...tileFlags.length) { var flag = tileFlags[i]; + #if (flixel 0) specialTile.flipX = true; diff --git a/flixel/addons/editors/spine/FlxSpine.hx b/flixel/addons/editors/spine/FlxSpine.hx index 7851c57c..36310342 100644 --- a/flixel/addons/editors/spine/FlxSpine.hx +++ b/flixel/addons/editors/spine/FlxSpine.hx @@ -270,20 +270,11 @@ class FlxSpine extends FlxSprite wrapper.y = 0; wrapper._cameras = _cameras; - #if (flash || openfl >= "4.0.0") wrapper.vertices.length = verticesLength; for (i in 0...verticesLength) { wrapper.vertices[i] = worldVertices[i]; } - #else - if (worldVertices.length - verticesLength > 0) - { - worldVertices.splice(verticesLength, worldVertices.length - verticesLength); - } - - wrapper.vertices = worldVertices; - #end wrapper.indices = Vector.ofArray(triangles); wrapper.uvtData = Vector.ofArray(uvtData); diff --git a/flixel/addons/editors/tiled/TiledLayer.hx b/flixel/addons/editors/tiled/TiledLayer.hx index ca39fe80..38e07724 100644 --- a/flixel/addons/editors/tiled/TiledLayer.hx +++ b/flixel/addons/editors/tiled/TiledLayer.hx @@ -1,7 +1,7 @@ package flixel.addons.editors.tiled; -import openfl.utils.ByteArray; import haxe.xml.Access; +import openfl.utils.ByteArray; /** * Base class for Tiled object and tile layers @@ -24,6 +24,9 @@ class TiledLayer /** @since 2.1.0 */ public var offsetY:Float; + public var parallaxX:Float; + public var parallaxY:Float; + function new(source:Access, parent:TiledMap) { properties = new TiledPropertySet(); @@ -33,6 +36,8 @@ class TiledLayer opacity = (source.has.opacity) ? Std.parseFloat(source.att.opacity) : 1.0; offsetX = (source.has.offsetx) ? Std.parseFloat(source.att.offsetx) : 0.0; offsetY = (source.has.offsety) ? Std.parseFloat(source.att.offsety) : 0.0; + parallaxX = (source.has.parallaxx) ? Std.parseFloat(source.att.parallaxx) : 1.0; + parallaxY = (source.has.parallaxy) ? Std.parseFloat(source.att.parallaxy) : 1.0; loadProperties(source); } diff --git a/flixel/addons/editors/tiled/TiledObject.hx b/flixel/addons/editors/tiled/TiledObject.hx index d0abac4b..c6e52962 100644 --- a/flixel/addons/editors/tiled/TiledObject.hx +++ b/flixel/addons/editors/tiled/TiledObject.hx @@ -27,6 +27,7 @@ class TiledObject public static inline var POLYGON = 2; public static inline var POLYLINE = 3; public static inline var TILE = 4; + public static inline var POINT = 5; public var x:Int; public var y:Int; @@ -148,6 +149,10 @@ class TiledObject objectType = POLYLINE; getPoints(source.node.polyline); } + else if (source.hasNode.point) + { + objectType = POINT; + } } function getPoints(node:Access):Void diff --git a/flixel/addons/effects/FlxClothSprite.hx b/flixel/addons/effects/FlxClothSprite.hx index 500d1677..28f558ef 100644 --- a/flixel/addons/effects/FlxClothSprite.hx +++ b/flixel/addons/effects/FlxClothSprite.hx @@ -303,10 +303,10 @@ class FlxClothSprite extends FlxSprite y: r * heightInTiles, oldx: c * widthInTiles, oldy: r * heightInTiles, - pinned: ((r == 0 && pinnedSide & UP != 0) - || (r == rows - 1 && pinnedSide & DOWN != 0) - || (c == 0 && pinnedSide & LEFT != 0) - || (c == columns - 1 && pinnedSide & RIGHT != 0)) + pinned: ((r == 0 && pinnedSide.has(UP)) + || (r == rows - 1 && pinnedSide.has(DOWN)) + || (c == 0 && pinnedSide.has(LEFT)) + || (c == columns - 1 && pinnedSide.has(RIGHT))) }); _vertices.push(c * widthInTiles); diff --git a/flixel/addons/effects/FlxTrail.hx b/flixel/addons/effects/FlxTrail.hx index 6f5112b1..e9264e26 100644 --- a/flixel/addons/effects/FlxTrail.hx +++ b/flixel/addons/effects/FlxTrail.hx @@ -17,7 +17,7 @@ import flixel.math.FlxPoint; * Feel free to use this class and adjust it to your needs. * @author Gama11 */ -class FlxTrail extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteContainer #end +class FlxTrail extends #if (flixel < version("5.7.0")) FlxSpriteGroup #else FlxSpriteContainer #end { /** * Stores the FlxSprite the trail is attached to. @@ -95,28 +95,28 @@ class FlxTrail extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteCont /** * Creates a new FlxTrail effect for a specific FlxSprite. * - * @param Target The FlxSprite the trail is attached to. - * @param Graphic The image to use for the trailsprites. Optional, uses the sprite's graphic if null. - * @param Length The amount of trailsprites to create. - * @param Delay How often to update the trail. 0 updates every frame. - * @param Alpha The alpha value for the very first trailsprite. - * @param Diff How much lower the alpha of the next trailsprite is. + * @param target The FlxSprite the trail is attached to. + * @param graphic The image to use for the trailsprites. Optional, uses the sprite's graphic if null. + * @param length The amount of trailsprites to create. + * @param delay How often to update the trail. 0 updates every frame. + * @param alpha The alpha value for the very first trailsprite. + * @param diff How much lower the alpha of the next trailsprite is. */ - public function new(Target:FlxSprite, ?Graphic:FlxGraphicAsset, Length:Int = 10, Delay:Int = 3, Alpha:Float = 0.4, Diff:Float = 0.05):Void + public function new(target:FlxSprite, ?graphic:FlxGraphicAsset, length = 10, delay = 3, alpha = 0.4, diff = 0.05):Void { super(); - _spriteOrigin = FlxPoint.get().copyFrom(Target.origin); + _spriteOrigin = FlxPoint.get().copyFrom(target.origin); // Sync the vars - target = Target; - delay = Delay; - _graphic = Graphic; - _transp = Alpha; - _difference = Diff; + this.target = target; + this.delay = delay; + _graphic = graphic; + _transp = alpha; + _difference = diff; // Create the initial trailsprites - increaseLength(Length); + increaseLength(length); solid = false; } @@ -147,115 +147,110 @@ class FlxTrail extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteCont { // Count the frames _counter++; - + // Update the trail in case the intervall and there actually is one. if (_counter >= delay && _trailLength >= 1) { _counter = 0; - - // Push the current position into the positons array and drop one. - var spritePosition:FlxPoint = null; - if (_recentPositions.length == _trailLength) - { - spritePosition = _recentPositions.pop(); - } - else - { - spritePosition = FlxPoint.get(); - } - - spritePosition.set(target.x - target.offset.x, target.y - target.offset.y); - _recentPositions.unshift(spritePosition); - - // Also do the same thing for the Sprites angle if rotationsEnabled + addTrailFrame(); + + // Now we need to update the all the Trailsprites' values + redrawTrailSprites(); + } + + super.update(elapsed); + } + + inline function recyclePoint(list:Array, x:Float, y:Float) + { + final pos = if (list.length >= _trailLength) + list.pop().set(x, y); + else + FlxPoint.get(x, y); + + list.unshift(pos); + } + + function addTrailFrame() + { + // Push the current position into the positons array and drop one. + recyclePoint(_recentPositions, target.x - target.offset.x, target.y - target.offset.y); + + // Also do the same thing for the Sprites angle if rotationsEnabled + if (rotationsEnabled) + { + cacheValue(_recentAngles, target.angle); + } + + // Again the same thing for Sprites scales if scalesEnabled + if (scalesEnabled) + { + recyclePoint(_recentScales, target.scale.x, target.scale.y); + } + + // Again the same thing for Sprites frames if framesEnabled + if (framesEnabled && _graphic == null) + { + cacheValue(_recentFrames, target.animation.frameIndex); + cacheValue(_recentFlipX, target.flipX); + cacheValue(_recentFlipY, target.flipY); + cacheValue(_recentAnimations, target.animation.curAnim); + } + } + + function redrawTrailSprites() + { + for (i in 0..._recentPositions.length) + { + final trailSprite = members[i]; + trailSprite.x = _recentPositions[i].x; + trailSprite.y = _recentPositions[i].y; + + // And the angle... if (rotationsEnabled) { - cacheValue(_recentAngles, target.angle); + trailSprite.angle = _recentAngles[i]; + trailSprite.origin.x = _spriteOrigin.x; + trailSprite.origin.y = _spriteOrigin.y; } - - // Again the same thing for Sprites scales if scalesEnabled + + // the scale... if (scalesEnabled) { - var spriteScale:FlxPoint = null; // sprite.scale; - if (_recentScales.length == _trailLength) - { - spriteScale = _recentScales.pop(); - } - else - { - spriteScale = FlxPoint.get(); - } - - spriteScale.set(target.scale.x, target.scale.y); - _recentScales.unshift(spriteScale); + trailSprite.scale.copyFrom(_recentScales[i]); } - - // Again the same thing for Sprites frames if framesEnabled + + // and frame... if (framesEnabled && _graphic == null) { - cacheValue(_recentFrames, target.animation.frameIndex); - cacheValue(_recentFlipX, target.flipX); - cacheValue(_recentFlipY, target.flipY); - cacheValue(_recentAnimations, target.animation.curAnim); - } - - // Now we need to update the all the Trailsprites' values - var trailSprite:FlxSprite; - - for (i in 0..._recentPositions.length) - { - trailSprite = members[i]; - trailSprite.x = _recentPositions[i].x; - trailSprite.y = _recentPositions[i].y; - - // And the angle... - if (rotationsEnabled) - { - trailSprite.angle = _recentAngles[i]; - trailSprite.origin.x = _spriteOrigin.x; - trailSprite.origin.y = _spriteOrigin.y; - } - - // the scale... - if (scalesEnabled) - { - trailSprite.scale.x = _recentScales[i].x; - trailSprite.scale.y = _recentScales[i].y; - } - - // and frame... - if (framesEnabled && _graphic == null) - { - trailSprite.animation.frameIndex = _recentFrames[i]; - trailSprite.flipX = _recentFlipX[i]; - trailSprite.flipY = _recentFlipY[i]; - - trailSprite.animation.curAnim = _recentAnimations[i]; - } - - // Is the trailsprite even visible? - trailSprite.exists = true; + trailSprite.animation.frameIndex = _recentFrames[i]; + trailSprite.flipX = _recentFlipX[i]; + trailSprite.flipY = _recentFlipY[i]; + + trailSprite.animation.curAnim = _recentAnimations[i]; } + + // Is the trailsprite even visible? + trailSprite.exists = true; } - - super.update(elapsed); } - + function cacheValue(array:Array, value:T) { array.unshift(value); - FlxArrayUtil.setLength(array, _trailLength); + if (array.length > _trailLength) + array.resize(_trailLength); } public function resetTrail():Void { - _recentPositions.splice(0, _recentPositions.length); - _recentAngles.splice(0, _recentAngles.length); - _recentScales.splice(0, _recentScales.length); - _recentFrames.splice(0, _recentFrames.length); - _recentFlipX.splice(0, _recentFlipX.length); - _recentFlipY.splice(0, _recentFlipY.length); - _recentAnimations.splice(0, _recentAnimations.length); + FlxDestroyUtil.putArray(_recentPositions); + FlxDestroyUtil.putArray(_recentScales); + _recentAngles.resize(0); + _recentFrames.resize(0); + _recentFlipX.resize(0); + _recentFlipY.resize(0); + _recentAnimations.resize(0); for (i in 0...members.length) { @@ -265,27 +260,27 @@ class FlxTrail extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteCont } } } - + /** * A function to add a specific number of sprites to the trail to increase its length. * - * @param Amount The amount of sprites to add to the trail. + * @param amount The amount of sprites to add to the trail. */ - public function increaseLength(Amount:Int):Void + public function increaseLength(amount:Int):Void { // Can't create less than 1 sprite obviously - if (Amount <= 0) + if (amount <= 0) { return; } - - _trailLength += Amount; - + + _trailLength += amount; + // Create the trail sprites - for (i in 0...Amount) + for (i in 0...amount) { - var trailSprite = new FlxSprite(0, 0); - + final trailSprite = new FlxSprite(0, 0); + if (_graphic == null) { trailSprite.loadGraphicFromSprite(target); @@ -300,42 +295,42 @@ class FlxTrail extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteCont trailSprite.alpha = _transp; _transp -= _difference; trailSprite.solid = solid; - + if (trailSprite.alpha <= 0) { trailSprite.kill(); } } } - + /** * In case you want to change the trailsprite image in runtime... * - * @param Image The image the sprites should load + * @param image The image the sprites should load */ - public function changeGraphic(Image:Dynamic):Void + public function changeGraphic(image:Dynamic):Void { - _graphic = Image; - + _graphic = image; + for (i in 0..._trailLength) { - members[i].loadGraphic(Image); + members[i].loadGraphic(image); } } /** * Handy little function to change which events affect the trail. * - * @param Angle Whether the trail reacts to angle changes or not. - * @param X Whether the trail reacts to x changes or not. - * @param Y Whether the trail reacts to y changes or not. - * @param Scale Wheater the trail reacts to scale changes or not. + * @param angle Whether the trail reacts to angle changes or not. + * @param x Whether the trail reacts to x changes or not. + * @param y Whether the trail reacts to y changes or not. + * @param scale Wheater the trail reacts to scale changes or not. */ - public function changeValuesEnabled(Angle:Bool, X:Bool = true, Y:Bool = true, Scale:Bool = true):Void + public function changeValuesEnabled(angle:Bool, x = true, y = true, scale = true):Void { - rotationsEnabled = Angle; - xEnabled = X; - yEnabled = Y; - scalesEnabled = Scale; + rotationsEnabled = angle; + xEnabled = x; + yEnabled = y; + scalesEnabled = scale; } } diff --git a/flixel/addons/effects/chainable/FlxEffectSprite.hx b/flixel/addons/effects/chainable/FlxEffectSprite.hx index cfc87a99..05f4796a 100644 --- a/flixel/addons/effects/chainable/FlxEffectSprite.hx +++ b/flixel/addons/effects/chainable/FlxEffectSprite.hx @@ -2,7 +2,7 @@ package flixel.addons.effects.chainable; // TODO: remove this check when min flixel version is 5.6.0, // So that FlxAddonDefines will handle this -#if (flixel < "5.3.0") +#if (flixel < version("5.3.0")) #error "Flixel-Addons is not compatible with flixel versions older than 5.3.0"; #end diff --git a/flixel/addons/effects/chainable/FlxGlitchEffect.hx b/flixel/addons/effects/chainable/FlxGlitchEffect.hx index c6666780..cfd5789a 100644 --- a/flixel/addons/effects/chainable/FlxGlitchEffect.hx +++ b/flixel/addons/effects/chainable/FlxGlitchEffect.hx @@ -59,7 +59,7 @@ class FlxGlitchEffect implements IFlxEffect var _pixels:BitmapData; /** - * Creates a new FlxGlitchSprite, which applies a Glitch-distortion effect. + * Creates a new FlxGlitchEffect, which applies a Glitch-distortion effect. * This effect is non-destructive to the target's pixels, and can be used on animated FlxSprites. * * @param Strength How strong you want the effect. diff --git a/flixel/addons/effects/chainable/FlxRainbowEffect.hx b/flixel/addons/effects/chainable/FlxRainbowEffect.hx index 4df1d5d4..14d1a819 100644 --- a/flixel/addons/effects/chainable/FlxRainbowEffect.hx +++ b/flixel/addons/effects/chainable/FlxRainbowEffect.hx @@ -54,7 +54,7 @@ class FlxRainbowEffect implements IFlxEffect var _pixels:BitmapData; /** - * Creates a new FlxEffectRainbow, which applies a color-cycling effect, using the target's bitmap as a mask. + * Creates a new FlxRainbowEffect, which applies a color-cycling effect, using the target's bitmap as a mask. * * @param Alpha A number between 0 and 1 to change the opacity of the effect. * @param Brightness A number between 0 and 1, indicating how bright the color should be. diff --git a/flixel/addons/effects/chainable/FlxWaveEffect.hx b/flixel/addons/effects/chainable/FlxWaveEffect.hx index 18d97123..f29a34eb 100644 --- a/flixel/addons/effects/chainable/FlxWaveEffect.hx +++ b/flixel/addons/effects/chainable/FlxWaveEffect.hx @@ -76,7 +76,7 @@ class FlxWaveEffect implements IFlxEffect var _pixels:BitmapData; /** - * Creates a new FlxEffectWave, which applies a wave-distortion effect. + * Creates a new FlxWaveEffect, which applies a wave-distortion effect. * * @param Mode Which Mode you would like to use for the effect. ALL = applies a constant distortion throughout the image, END = makes the effect get stronger towards the bottom of the image, and START = the reverse of END. * @param Strength How strong you want the effect. diff --git a/flixel/addons/nape/FlxNapeSpace.hx b/flixel/addons/nape/FlxNapeSpace.hx index 054aea43..e8f45de1 100644 --- a/flixel/addons/nape/FlxNapeSpace.hx +++ b/flixel/addons/nape/FlxNapeSpace.hx @@ -64,7 +64,7 @@ class FlxNapeSpace extends FlxBasic */ public static function init():Void { - #if (flixel < "5.6.0") + #if (flixel < version("5.6.0")) FlxG.plugins.add(new FlxNapeSpace()); #else FlxG.plugins.addPlugin(new FlxNapeSpace()); diff --git a/flixel/addons/nape/FlxNapeTilemap.hx b/flixel/addons/nape/FlxNapeTilemap.hx index 49122efd..30cf8f96 100644 --- a/flixel/addons/nape/FlxNapeTilemap.hx +++ b/flixel/addons/nape/FlxNapeTilemap.hx @@ -1,13 +1,13 @@ package flixel.addons.nape; -import flixel.addons.nape.FlxNapeSpace; import flixel.FlxG; +import flixel.addons.nape.FlxNapeSpace; import flixel.math.FlxPoint; import flixel.math.FlxRect; +import flixel.system.FlxAssets; +import flixel.tile.FlxBaseTilemap; import flixel.tile.FlxTilemap; import flixel.util.FlxArrayUtil; -import flixel.tile.FlxBaseTilemap; -import flixel.system.FlxAssets; import nape.geom.Vec2; import nape.phys.Body; import nape.phys.BodyType; @@ -42,7 +42,7 @@ class FlxNapeTilemap extends FlxTilemap { super.loadMapFromCSV(MapData, TileGraphic, TileWidth, TileHeight, AutoTile, StartingIndex, DrawIndex, CollideIndex); _binaryData = new Array(); - FlxArrayUtil.setLength(_binaryData, _data.length); + _binaryData.resize(_data.length); return this; } @@ -51,7 +51,7 @@ class FlxNapeTilemap extends FlxTilemap { super.loadMapFromArray(MapData, WidthInTiles, HeightInTiles, TileGraphic, TileWidth, TileHeight, AutoTile, StartingIndex, DrawIndex, CollideIndex); _binaryData = new Array(); - FlxArrayUtil.setLength(_binaryData, _data.length); + _binaryData.resize(_data.length); return this; } @@ -60,7 +60,7 @@ class FlxNapeTilemap extends FlxTilemap { super.loadMapFrom2DArray(MapData, TileGraphic, TileWidth, TileHeight, AutoTile, StartingIndex, DrawIndex, CollideIndex); _binaryData = new Array(); - FlxArrayUtil.setLength(_binaryData, _data.length); + _binaryData.resize(_data.length); return this; } @@ -100,11 +100,12 @@ class FlxNapeTilemap extends FlxTilemap var polygon:Polygon; for (index in tileIndices) { - var coords:Array = getTileCoords(index, false); - if (coords == null) - continue; - - for (point in coords) + #if (flixel >= version("5.9.0")) + final points = getAllTilePos(index); + #else + final points = getTileCoords(index, false); + #end + for (point in points) { polygon = new Polygon(vertices, mat); polygon.translate(Vec2.get(point.x, point.y)); diff --git a/flixel/addons/plugin/FlxMouseControl.hx b/flixel/addons/plugin/FlxMouseControl.hx deleted file mode 100644 index b2604f74..00000000 --- a/flixel/addons/plugin/FlxMouseControl.hx +++ /dev/null @@ -1,274 +0,0 @@ -package flixel.addons.plugin; - -#if FLX_MOUSE -import flixel.addons.display.FlxExtendedMouseSprite; -import flixel.FlxBasic; -import flixel.FlxG; -import flixel.math.FlxMath; -import flixel.math.FlxPoint; -import flixel.math.FlxRect; -import flixel.util.FlxDestroyUtil; - -/** - * FlxMouseControl - * - * @link http://www.photonstorm.com - * @author Richard Davey / Photon Storm - */ -@:deprecated("FlxMouseControl is deprecated, use flixel.input.mouse.FlxMouseEvent") // since 3.1.2 -class FlxMouseControl extends FlxBasic -{ - /** - * Use with sort() to sort in ascending order. - */ - public static inline var ASCENDING:Int = -1; - - /** - * Use with sort() to sort in descending order. - */ - public static inline var DESCENDING:Int = 1; - - /** - * The value that the FlxExtendedMouseSprites are sorted by before deciding which is "on-top" for click select - */ - public static var sortIndex:String = "y"; - - /** - * The sorting order. If the sortIndex is "y" and the order is ASCENDING then a sprite with a Y value of 200 would be "on-top" of one with a Y value of 100. - */ - public static var sortOrder:Int = ASCENDING; - - /** - * Is the mouse currently dragging a sprite? If you have just clicked but NOT yet moved the mouse then this might return false. - */ - public static var isDragging:Bool = false; - - /** - * The FlxExtendedMouseSprite that is currently being dragged, if any. - */ - public static var dragTarget:FlxExtendedMouseSprite; - - public static var clickTarget:FlxExtendedMouseSprite; - - /** - * The speed the mouse is moving on the X axis in pixels per frame - */ - public static var speedX:Int; - - /** - * The speed the mouse is moving on the Y axis in pixels per frame - */ - public static var speedY:Int; - - /** - * The mouse can be set to only be active within a specific FlxRect region of the game world. - * If outside this FlxRect no clicks, drags or throws will be processed. - * If the mouse leaves this region while still dragging then the sprite is automatically dropped and its release handler is called. - * Set the FlxRect to null to disable the zone. - */ - public static var mouseZone:FlxRect; - - /** - * Instead of using a mouseZone (which is calculated in world coordinates) you can limit the mouse to the FlxG.camera.deadzone area instead. - * If set to true the mouse will use the camera deadzone. If false (or the deadzone is null) no check will take place. - * Note that this takes priority over the mouseZone above. If the mouseZone and deadzone are set, the deadzone is used. - */ - public static var linkToDeadZone:Bool = false; - - /** - * The FlxExtendedMouseSprite that currently has the mouse button pressed on it - */ - static var _clickStack:Array = new Array(); - - static var _clickCoords:FlxPoint; - static var _hasClickTarget:Bool = false; - - static var _oldX:Int = 0; - static var _oldY:Int = 0; - - public function new() - { - super(); - - _clickCoords = FlxPoint.get(); - } - - /** - * Adds the given FlxExtendedMouseSprite to the stack of potential sprites that were clicked, the stack is then sorted and the final sprite is selected from that - * - * @param Item The FlxExtendedMouseSprite that was clicked by the mouse - */ - public static function addToStack(Item:FlxExtendedMouseSprite):Void - { - if (mouseZone != null) - { - if (FlxMath.pointInFlxRect(Math.floor(FlxG.mouse.x), Math.floor(FlxG.mouse.y), mouseZone) == true) - { - _clickStack.push(Item); - } - } - else - { - _clickStack.push(Item); - } - } - - /** - * Removes all references to any click / drag targets and resets this class - */ - public static function clear():Void - { - _clickCoords = FlxDestroyUtil.put(_clickCoords); - _hasClickTarget = false; - - if (clickTarget != null) - { - clickTarget.mouseReleasedHandler(); - } - - clickTarget = null; - - isDragging = false; - - if (dragTarget != null) - { - dragTarget.stopDrag(); - } - - speedX = 0; - speedY = 0; - dragTarget = null; - mouseZone = null; - linkToDeadZone = false; - } - - /** - * Main Update Loop - checks mouse status and updates FlxExtendedMouseSprites accordingly - */ - override public function update(elapsed:Float):Void - { - // Update mouse speed - speedX = FlxG.mouse.screenX - _oldX; - speedY = FlxG.mouse.screenY - _oldY; - - _oldX = FlxG.mouse.screenX; - _oldY = FlxG.mouse.screenY; - - // Is the mouse currently pressed down on a target? - if (_hasClickTarget) - { - if (FlxG.mouse.pressed) - { - // Has the mouse moved? If so then we're candidate for a drag - if (isDragging == false - && clickTarget.draggable == true - && (_clickCoords.x != FlxG.mouse.x || _clickCoords.y != FlxG.mouse.y)) - { - // Drag on - isDragging = true; - - dragTarget = clickTarget; - - dragTarget.startDrag(); - } - } - else - { - releaseMouse(); - } - - if (linkToDeadZone == true) - { - if (FlxMath.mouseInFlxRect(false, FlxG.camera.deadzone) == false) - { - releaseMouse(); - } - } - else if (FlxMath.mouseInFlxRect(true, mouseZone) == false) - { - // Is a mouse zone enabled? In which case check if we're still in it - releaseMouse(); - } - } - else - { - // If you are wondering how the brand new array can have anything in it by now, it's because FlxExtendedMouseSprite - // adds itself to the clickStack - if (FlxG.mouse.pressed && _clickStack.length > 0) - { - assignClickedSprite(); - } - } - } - - /** - * Internal function used to release the click / drag targets and reset the mouse state - */ - function releaseMouse():Void - { - // Mouse is no longer down, so tell the click target it's free - this will also stop dragging if happening - clickTarget.mouseReleasedHandler(); - - _hasClickTarget = false; - clickTarget = null; - - isDragging = false; - dragTarget = null; - } - - /** - * Once the clickStack is created this sorts it and then picks the sprite with the highest priority (based on sortIndex and sortOrder) - */ - function assignClickedSprite():Void - { - // If there is more than one potential target then sort them - if (_clickStack.length > 1) - { - _clickStack.sort(sortHandler); - } - - clickTarget = _clickStack.pop(); - - _clickCoords = FlxG.mouse.getWorldPosition(null, _clickCoords); - - _hasClickTarget = true; - - clickTarget.mousePressedHandler(); - - _clickStack = []; - } - - /** - * Helper function for the sort process. - * - * @param Item1 The first object being sorted. - * @param Item2 The second object being sorted. - * - * @return An integer value: -1 (item1 before item2), 0 (same), or 1 (item1 after item2) - */ - function sortHandler(Item1:FlxExtendedMouseSprite, Item2:FlxExtendedMouseSprite):Int - { - var prop1 = Reflect.getProperty(Item1, sortIndex); - var prop2 = Reflect.getProperty(Item2, sortIndex); - - if (prop1 < prop2) - { - return sortOrder; - } - else if (prop1 > prop2) - { - return -sortOrder; - } - - return 0; - } - - /** - * Runs when this plugin is destroyed - */ - override public function destroy():Void - { - clear(); - } -} -#end diff --git a/flixel/addons/plugin/control/FlxControlHandler.hx b/flixel/addons/plugin/control/FlxControlHandler.hx index 8cdb4c42..8a6c0150 100644 --- a/flixel/addons/plugin/control/FlxControlHandler.hx +++ b/flixel/addons/plugin/control/FlxControlHandler.hx @@ -7,11 +7,12 @@ import flixel.FlxSprite; import flixel.math.FlxMath; import flixel.math.FlxPoint; import flixel.math.FlxVelocity; -#if (flixel >= "5.3.0") +#if (flixel >= version("5.3.0")) import flixel.sound.FlxSound; #else import flixel.system.FlxSound; #end +import flixel.util.FlxDirectionFlags; /** * @@ -173,7 +174,7 @@ class FlxControlHandler // Internal time of when they last collided with a valid jumpSurface var _extraSurfaceTime:Int; // The surfaces they can jump from (i.e. FLOOR) - var _jumpSurface:Int; + var _jumpSurface:FlxDirectionFlags; // A function to call every time they jump var _jumpCallback:Void->Void; @@ -612,7 +613,8 @@ class FlxControlHandler * @param callback A user defined function to call when the Sprite jumps * @param altKey Specify an alternative jump key that works AS WELL AS the primary jump key (TODO) */ - public function setJumpButton(key:String, keymode:Int, height:Int, surface:Int, repeatDelay:Int = 250, jumpFromFall:Int = 0, ?callback:Void->Void, + public function setJumpButton(key:String, keymode:Int, height:Int, surface:FlxDirectionFlags, repeatDelay:Int = 250, jumpFromFall:Int = 0, + ?callback:Void->Void, altKey:String = ""):Void { _jumpKey = key; diff --git a/flixel/addons/plugin/screengrab/FlxScreenGrab.hx b/flixel/addons/plugin/screengrab/FlxScreenGrab.hx index 663d9098..2d1eb344 100644 --- a/flixel/addons/plugin/screengrab/FlxScreenGrab.hx +++ b/flixel/addons/plugin/screengrab/FlxScreenGrab.hx @@ -10,11 +10,9 @@ import flixel.addons.util.PNGEncoder; import flixel.FlxG; import flixel.input.keyboard.FlxKey; #if sys -#if (!lime_legacy || lime < "2.9.0") import lime.ui.FileDialog; import lime.ui.FileDialogType; import openfl.display.PNGEncoderOptions; -#end #else import openfl.net.FileReference; #end diff --git a/flixel/addons/system/macros/FlxAddonDefines.hx b/flixel/addons/system/macros/FlxAddonDefines.hx index 8a7f9168..7581d1d4 100644 --- a/flixel/addons/system/macros/FlxAddonDefines.hx +++ b/flixel/addons/system/macros/FlxAddonDefines.hx @@ -41,7 +41,7 @@ class FlxAddonDefines * When the minimum version of flixel is changed to 5.6.0 or greater, remove the above * checks and this comment. */ - #if (flixel < "5.3.0") + #if (flixel < version("5.3.0")) FlxDefines.abortVersion("Flixel", "5.3.0 or newer", "flixel", (macro null).pos); #end } @@ -61,4 +61,4 @@ class FlxAddonDefines Context.fatalError(message, pos); } } -#end \ No newline at end of file +#end diff --git a/flixel/addons/system/macros/FlxRuntimeShaderMacro.hx b/flixel/addons/system/macros/FlxRuntimeShaderMacro.hx new file mode 100644 index 00000000..91c9630b --- /dev/null +++ b/flixel/addons/system/macros/FlxRuntimeShaderMacro.hx @@ -0,0 +1,78 @@ +package flixel.addons.system.macros; + +import haxe.macro.Context; +import haxe.macro.Expr; +import haxe.macro.Type; + +using haxe.macro.ExprTools; + +class FlxRuntimeShaderMacro +{ + /** + * Retrieves the value of a specified metadata tag (only `String` values) from the current class + * or any of its superclasses. The function searches the fields of the class + * for the specified metadata and returns its value as a macro expression. + * If `overwrite` is set to `false`, it will use the first non-null `String` value + * found and ignore any subsequent values. + * + * @param metaName The name of the metadata tag to retrieve. + * @param overwrite If `true`, the metadata value will be concatenated when found; if `false`, only the first non-null value will be used. + * @return The value of the specified metadata as an expression, or `null` if not found. + */ + public static macro function retrieveMetadata(metaName:String, overwrite:Bool = true):Expr + { + var result:String = null; + + final localClass:ClassType = Context.getLocalClass().get(); + + result = checkClassForMetadata(localClass, metaName, overwrite, result); + + var parent:ClassType = localClass.superClass != null ? localClass.superClass.t.get() : null; + + while (parent != null) + { + result = checkClassForMetadata(parent, metaName, overwrite, result); + + parent = parent.superClass != null ? parent.superClass.t.get() : null; + } + + // Context.info('Retrieving $metaName: $result', Context.currentPos()); + + return macro $v{result}; + } + + #if macro + @:noCompletion + private static function checkClassForMetadata(classType:ClassType, metaName:String, overwrite:Bool, currentResult:String):String + { + var result:String = currentResult; + + for (field in [classType.constructor.get()].concat(classType.fields.get())) + { + for (meta in field.meta.get()) + { + if (meta.name == metaName || meta.name == ':' + metaName) + { + final value:Dynamic = meta.params[0].getValue(); + + if (!(value is String)) + continue; + + if (overwrite) + result = result == null ? value : '$value\n$result'; + else if (result == null) + { + result = value; + break; + } + } + } + + if (!overwrite && result != null) + break; + } + + return result; + } + #end +} diff --git a/flixel/addons/text/FlxTypeText.hx b/flixel/addons/text/FlxTypeText.hx index 2774ef5f..3af3592b 100644 --- a/flixel/addons/text/FlxTypeText.hx +++ b/flixel/addons/text/FlxTypeText.hx @@ -2,7 +2,7 @@ package flixel.addons.text; // TODO: remove this check when min flixel version is 5.6.0, // So that FlxAddonDefines will handle this -#if (flixel < "5.3.0") +#if (flixel < version("5.3.0")) #error "Flixel-Addons is not compatible with flixel versions older than 5.3.0"; #end @@ -325,7 +325,7 @@ class FlxTypeText extends FlxText */ public function resetText(Text:String):Void { - text = ""; + text = prefix; _finalText = Text; _typing = false; _erasing = false; diff --git a/flixel/addons/tile/FlxRayCastTilemap.hx b/flixel/addons/tile/FlxRayCastTilemap.hx index 3d5e5b13..7aa55708 100644 --- a/flixel/addons/tile/FlxRayCastTilemap.hx +++ b/flixel/addons/tile/FlxRayCastTilemap.hx @@ -3,9 +3,11 @@ package flixel.addons.tile; import flixel.tile.FlxTilemap; import flixel.math.FlxPoint; +#if (flixel < version("5.9.0")) /** * @author greglieberman */ +@:deprecated("FlxRayCastTilemap is deprecated, use FlxTilemap.ray or rayStep, instead") class FlxRayCastTilemap extends FlxTilemap { /** @@ -73,8 +75,8 @@ class FlxRayCastTilemap extends FlxTilemap } // Find the tile at the start position of the ray - cx = coordsToTileX(Start.x); - cy = coordsToTileY(Start.y); + cx = getColumnAt(Start.x); + cy = getRowAt(Start.y); if (!inTileRange(cx, cy)) { @@ -85,7 +87,7 @@ class FlxRayCastTilemap extends FlxTilemap return false; } - if (getTile(Std.int(cx), Std.int(cy)) > 0) + if (getTileIndex(Std.int(cx), Std.int(cy)) > 0) { // start point is inside a block Result.x = Start.x; @@ -154,7 +156,7 @@ class FlxRayCastTilemap extends FlxTilemap if (tMaxX < tMaxY) { cx = cx + stepX; - if (getTile(Std.int(cx), Std.int(cy)) > 0) + if (getTileIndex(Std.int(cx), Std.int(cy)) > 0) { hitTile = true; break; @@ -172,7 +174,7 @@ class FlxRayCastTilemap extends FlxTilemap { cy = cy + stepY; - if (getTile(Std.int(cx), Std.int(cy)) > 0) + if (getTileIndex(Std.int(cx), Std.int(cy)) > 0) { hitTile = true; break; @@ -209,41 +211,42 @@ class FlxRayCastTilemap extends FlxTilemap return (TileX >= 0 && TileX < widthInTiles && TileY >= 0 && TileY < heightInTiles); } - public function tileAt(CoordX:Float, CoordY:Float):Int + @:deprecated("tileAt is deprecated, use getTileIndexAt, instead") + public function tileAt(worldX:Float, worldY:Float):Int { - return getTile(Std.int((CoordX - x) / scaledTileWidth), Std.int((CoordY - y) / scaledTileHeight)); + return getTileIndexAt(worldX, worldY); } - public function tileIndexAt(CoordX:Float, CoordY:Float):Int + @:deprecated("tileIndexAt is deprecated, use getMapIndexAt, instead") + public function tileIndexAt(worldX:Float, worldY:Float):Int { - var X:Int = Std.int((CoordX - x) / scaledTileWidth); - var Y:Int = Std.int((CoordY - y) / scaledTileHeight); - - return Y * widthInTiles + X; - } - - public function getTileIndex(X:Int, Y:Int):Int - { - return Y * widthInTiles + X; + return getMapIndexAt(worldX, worldY); } - public function coordsToTileX(CoordX:Float):Float + @:deprecated("coordsToTileX is deprecated, use getColumnAt, instead") + public function coordsToTileX(worldX:Float):Float { - return Std.int((CoordX - x) / scaledTileWidth); + return getColumnAt(worldX); } - public function coordsToTileY(CoordY:Float):Float + @:deprecated("coordsToTileY is deprecated, use getRowAt, instead") + public function coordsToTileY(worldY:Float):Float { - return Std.int((CoordY - y) / scaledTileHeight); + return getRowAt(worldY); } - public function indexToCoordX(Index:Int):Float + @:deprecated("indexToCoordX is deprecated, use getColumnPos(getColumn(mapIndex)), instead") + public function indexToCoordX(mapIndex:Int):Float { - return (Index % widthInTiles) * scaledTileWidth + scaledTileWidth / 2; + return getColumnPos(getColumn(mapIndex)); } - public function indexToCoordY(Index:Int):Float + @:deprecated("indexToCoordY is deprecated, use getRowPos(getRow(mapIndex)), instead") + public function indexToCoordY(mapIndex:Int):Float { - return Std.int(Index / widthInTiles) * scaledTileHeight + scaledTileHeight / 2; + return getRowPos(getRow(mapIndex)); } } +#elseif FLX_NO_COVERAGE_TEST +#error "FlxRayCastTilemap has been removed in flixel-addons 4.0.0, use FlxTilemap.ray or rayStep, instead" +#end \ No newline at end of file diff --git a/flixel/addons/tile/FlxTilemapExt.hx b/flixel/addons/tile/FlxTilemapExt.hx index 7973569b..959f0696 100644 --- a/flixel/addons/tile/FlxTilemapExt.hx +++ b/flixel/addons/tile/FlxTilemapExt.hx @@ -139,7 +139,7 @@ class FlxTilemapExt extends FlxTilemap } // Copy tile images into the tile buffer - #if (flixel < "5.2.0") + #if (flixel < version("5.2.0")) _point.x = (camera.scroll.x * scrollFactor.x) - x - offset.x + camera.viewOffsetX; // modified from getScreenPosition() _point.y = (camera.scroll.y * scrollFactor.y) - y - offset.y + camera.viewOffsetY; #else @@ -203,7 +203,7 @@ class FlxTilemapExt extends FlxTilemap { if (tile != null) { - if (tile.allowCollisions <= NONE) + if (tile.allowCollisions == NONE) { debugTile = _debugTileNotSolid; } @@ -322,6 +322,7 @@ class FlxTilemapExt extends FlxTilemap } } + #if (flixel < version("5.9.0")) /** * THIS IS A COPY FROM FlxTilemap BUT IT SOLVES SLOPE COLLISION TOO * Checks if the Object overlaps any tiles with any collision flags set, @@ -334,7 +335,7 @@ class FlxTilemapExt extends FlxTilemap * @param position Optional, specify a custom position for the tilemap (useful for overlapsAt()-type functionality). * @return Whether there were overlaps, or if a callback was specified, whatever the return value of the callback was. */ - override public function overlapsWithCallback(object:FlxObject, ?callback:FlxObject->FlxObject->Bool, flipCallbackParams:Bool = false, + override function overlapsWithCallback(object:FlxObject, ?callback:FlxObject->FlxObject->Bool, flipCallbackParams:Bool = false, ?position:FlxPoint):Bool { var results:Bool = false; @@ -375,8 +376,7 @@ class FlxTilemapExt extends FlxTilemap continue; final tile = _tileObjects[dataIndex]; - - if (tile.allowCollisions != NONE) + if (tile.solid) { var overlapFound = false; @@ -400,7 +400,10 @@ class FlxTilemapExt extends FlxTilemap } else { - overlapFound = (object.x + object.width > tile.x) && (object.x < tile.x + tile.width) && (object.y + object.height > tile.y) + overlapFound + = (object.x + object.width > tile.x) + && (object.x < tile.x + tile.width) + && (object.y + object.height > tile.y) && (object.y < tile.y + tile.height); } @@ -425,6 +428,52 @@ class FlxTilemapExt extends FlxTilemap return results; } + #else + /** + * Hacky fix for `FlxTilemapExt`, with all the new changes to 5.9.0 it's better to perfectly + * recreate the old behavior, here and then make a new tilemap with slopes that uses the new + * features to eventually replace it + */ + override function objectOverlapsTiles(object:TObj, ?callback:(FlxTile, TObj)->Bool, ?position:FlxPoint, isCollision = true):Bool + { + var results = false; + function each(tile:FlxTile) + { + if (tile.solid) + { + var overlapFound = false; + if (callback != null) + { + overlapFound = callback(tile, object); + } + else + { + overlapFound = tile.overlapsObject(object); + } + + // New generalized slope collisions + if (overlapFound || checkArrays(tile.index)) + { + if (tile.callbackFunction != null) + { + tile.callbackFunction(tile, object); + tile.onCollide.dispatch(tile, object); + } + results = true; + } + } + else if ((tile.callbackFunction != null) && ((tile.filter == null) || Std.isOfType(object, tile.filter))) + { + tile.callbackFunction(tile, object); + tile.onCollide.dispatch(tile, object); + } + } + + forEachOverlappingTile(object, each, position); + + return results; + } + #end /** * Set glue to force contact with slopes and a slow down factor while climbing diff --git a/flixel/addons/transition/FlxTransitionSprite.hx b/flixel/addons/transition/FlxTransitionSprite.hx index f75b4120..a70b5901 100644 --- a/flixel/addons/transition/FlxTransitionSprite.hx +++ b/flixel/addons/transition/FlxTransitionSprite.hx @@ -143,7 +143,12 @@ class FlxTransitionSprite extends FlxSprite } animation.play(anim); + #if (flixel < version("5.9.0")) animation.finishCallback = onFinishAnim; + #else + if (!animation.onFinish.has(onFinishAnim)) + animation.onFinish.add(onFinishAnim); + #end status = Status; } diff --git a/flixel/addons/transition/FlxTransitionableState.hx b/flixel/addons/transition/FlxTransitionableState.hx index 3dea1507..3c0a2571 100644 --- a/flixel/addons/transition/FlxTransitionableState.hx +++ b/flixel/addons/transition/FlxTransitionableState.hx @@ -2,7 +2,7 @@ package flixel.addons.transition; // TODO: remove this check when min flixel version is 5.6.0, // So that FlxAddonDefines will handle this -#if (flixel < "5.3.0") +#if (flixel < version("5.3.0")) #error "Flixel-Addons is not compatible with flixel versions older than 5.3.0"; #end diff --git a/flixel/addons/transition/TransitionEffect.hx b/flixel/addons/transition/TransitionEffect.hx index 281d7af7..62b4b5b3 100644 --- a/flixel/addons/transition/TransitionEffect.hx +++ b/flixel/addons/transition/TransitionEffect.hx @@ -10,7 +10,7 @@ import flixel.util.FlxTimer; * @author larsiusprime */ @:allow(flixel.addons.transition.Transition) -class TransitionEffect extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteContainer #end +class TransitionEffect extends #if (flixel < version("5.7.0")) FlxSpriteGroup #else FlxSpriteContainer #end { public var finishCallback:Void->Void; public var finished(default, null):Bool = false; diff --git a/flixel/addons/ui/FlxButtonPlus.hx b/flixel/addons/ui/FlxButtonPlus.hx index a2d2b93c..a35ae40c 100644 --- a/flixel/addons/ui/FlxButtonPlus.hx +++ b/flixel/addons/ui/FlxButtonPlus.hx @@ -24,7 +24,7 @@ import flixel.math.FlxMath; * @link http://www.photonstorm.com * @author Richard Davey / Photon Storm */ -class FlxButtonPlus extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteContainer #end +class FlxButtonPlus extends #if (flixel < version("5.7.0")) FlxSpriteGroup #else FlxSpriteContainer #end { public static inline var NORMAL:Int = 0; public static inline var HIGHLIGHT:Int = 1; diff --git a/flixel/addons/ui/FlxClickArea.hx b/flixel/addons/ui/FlxClickArea.hx index bc18acb1..0736ba7c 100644 --- a/flixel/addons/ui/FlxClickArea.hx +++ b/flixel/addons/ui/FlxClickArea.hx @@ -133,7 +133,7 @@ class FlxClickArea extends FlxObject if (continueUpdate) { var offAll:Bool = true; - #if (flixel >= "5.7.0") + #if (flixel >= version("5.7.0")) final cameras = getCameras(); // else use this.cameras #end for (camera in cameras) diff --git a/flixel/addons/ui/FlxSlider.hx b/flixel/addons/ui/FlxSlider.hx index 9522d8e4..801678e4 100644 --- a/flixel/addons/ui/FlxSlider.hx +++ b/flixel/addons/ui/FlxSlider.hx @@ -16,7 +16,7 @@ import flixel.util.FlxSpriteUtil; * A slider GUI element for float and integer manipulation. * @author Gama11 */ -class FlxSlider extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteContainer #end +class FlxSlider extends #if (flixel < version("5.7.0")) FlxSpriteGroup #else FlxSpriteContainer #end { /** * The horizontal line in the background. @@ -272,10 +272,13 @@ class FlxSlider extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteCon { // Clicking and sound logic #if (flixel >= "5.7.0") - final camera = getCameras()[0];// else use this.camera + final cam = getDefaultCamera(); + #else + final cam = this.camera; #end - final mouse = FlxG.mouse.getScreenPosition(camera); - if (FlxMath.pointInFlxRect(mouse.x, mouse.y, _bounds)) + final mousePosition = FlxG.mouse.getViewPosition(cam); + + if (FlxMath.pointInFlxRect(mousePosition.x, mousePosition.y, _bounds)) { if (hoverAlpha != 1) { @@ -293,7 +296,7 @@ class FlxSlider extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteCon if (FlxG.mouse.pressed) { - handle.x = FlxG.mouse.screenX; + handle.x = mousePosition.x; updateValue(); #if FLX_SOUND_SYSTEM @@ -320,7 +323,7 @@ class FlxSlider extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteCon } // Update the target value whenever the slider is being used - if ((FlxG.mouse.pressed) && (FlxMath.mouseInFlxRect(false, _bounds))) + if ((FlxG.mouse.pressed) && (FlxMath.pointInFlxRect(mousePosition.x, mousePosition.y, _bounds))) { updateValue(); } @@ -340,6 +343,9 @@ class FlxSlider extends #if (flixel < "5.7.0") FlxSpriteGroup #else FlxSpriteCon // Finally, update the valueLabel valueLabel.text = Std.string(FlxMath.roundDecimal(value, decimals)); + mousePosition.put(); + + super.update(elapsed); } diff --git a/flixel/addons/util/FlxScene.hx b/flixel/addons/util/FlxScene.hx index c4e6151b..910726a5 100644 --- a/flixel/addons/util/FlxScene.hx +++ b/flixel/addons/util/FlxScene.hx @@ -10,6 +10,7 @@ import flixel.tile.FlxTilemap; import flixel.ui.FlxButton; import flixel.util.FlxAxes; import flixel.util.FlxColor; +import flixel.util.FlxDirectionFlags; import haxe.xml.Parser; import openfl.Assets; @@ -250,7 +251,7 @@ class FlxScene case "tile": var id = Std.parseInt(element.att.id); - var collision = Std.parseInt(element.att.collision); + var collision:FlxDirectionFlags = cast Std.parseInt(element.att.collision); tilemap.setTileProperties(id, collision); } diff --git a/flixel/addons/weapon/FlxWeapon.hx b/flixel/addons/weapon/FlxWeapon.hx index 0c43dd37..733d386b 100644 --- a/flixel/addons/weapon/FlxWeapon.hx +++ b/flixel/addons/weapon/FlxWeapon.hx @@ -2,7 +2,7 @@ package flixel.addons.weapon; // TODO: remove this check when min flixel version is 5.6.0, // So that FlxAddonDefines will handle this -#if (flixel < "5.3.0") +#if (flixel < version("5.3.0")) #error "Flixel-Addons is not compatible with flixel versions older than 5.3.0"; #end @@ -430,16 +430,20 @@ class FlxTypedWeapon } } - function shouldBulletHit(Object:FlxObject, Bullet:FlxObject):Bool + function shouldBulletHit(object:FlxObject, bullet:FlxObject):Bool { - if (parent == Object && skipParentCollision) + if (parent == object && skipParentCollision) { return false; } - if ((Object is FlxTilemap)) + if ((object is FlxTilemap)) { - return cast(Object, FlxTilemap).overlapsWithCallback(Bullet); + #if (flixel < version("5.9.0")) + return cast(object, FlxTilemap).overlapsWithCallback(bullet); + #else + return cast(object, FlxTilemap).objectOverlapsTiles(bullet); + #end } else { diff --git a/haxelib.json b/haxelib.json index 9cda487a..22cb3177 100644 --- a/haxelib.json +++ b/haxelib.json @@ -4,7 +4,10 @@ "license": "MIT", "tags": ["game", "openfl", "flash", "neko", "cpp", "android", "ios", "cross"], "description": "flixel-addons is a set of useful, additional classes for HaxeFlixel.", - "version": "3.2.3", - "releasenote": "Compatibility with flixel 5.7.0", - "contributors": ["haxeflixel", "Gama11", "GeoKureli"] + "version": "4.0.0", + "releasenote": "Remove deprecated FlxRayCastTilemap and FlxMouseControl", + "contributors": ["haxeflixel", "Gama11", "GeoKureli"], + "dependencies": { + "flixel": "" + } }