diff --git a/flixel/FlxSprite.hx b/flixel/FlxSprite.hx index cd4704bfff..125efd6e65 100644 --- a/flixel/FlxSprite.hx +++ b/flixel/FlxSprite.hx @@ -873,9 +873,18 @@ class FlxSprite extends FlxObject drawFrameComplex(_frame, camera); } + @:noCompletion + static final drawComplexMatrix = new FlxMatrix(); function drawFrameComplex(frame:FlxFrame, camera:FlxCamera):Void { - final matrix = this._matrix; // TODO: Just use local? + final matrix = drawComplexMatrix; // TODO: Just use local? + prepareComplexMatrix(matrix, frame, camera); + + camera.drawPixels(frame, framePixels, matrix, colorTransform, blend, antialiasing, shader); + } + + function prepareComplexMatrix(matrix:FlxMatrix, frame:FlxFrame, camera:FlxCamera) + { frame.prepareMatrix(matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY()); matrix.translate(-origin.x, -origin.y); matrix.scale(scale.x, scale.y); @@ -888,17 +897,16 @@ class FlxSprite extends FlxObject matrix.rotateWithTrig(_cosAngle, _sinAngle); } - getScreenPosition(_point, camera).subtract(offset); - _point.add(origin.x, origin.y); - matrix.translate(_point.x, _point.y); + final screenPos = getScreenPosition(camera).subtract(offset); + screenPos.add(origin.x, origin.y); + matrix.translate(screenPos.x, screenPos.y); + screenPos.put(); if (isPixelPerfectRender(camera)) { matrix.tx = Math.floor(matrix.tx); matrix.ty = Math.floor(matrix.ty); } - - camera.drawPixels(frame, framePixels, matrix, colorTransform, blend, antialiasing, shader); } /** diff --git a/flixel/effects/FlxMatrixSprite.hx b/flixel/effects/FlxMatrixSprite.hx new file mode 100644 index 0000000000..946bd63c76 --- /dev/null +++ b/flixel/effects/FlxMatrixSprite.hx @@ -0,0 +1,58 @@ +package flixel.effects; + +import flixel.FlxSprite; +import flixel.graphics.frames.FlxFrame; +import flixel.math.FlxMatrix; + +/** + * A sprite that uses a `renderMatrix` to transform its rendering + */ +class FlxMatrixSprite extends FlxSprite +{ + /** + * The matrix used to transform how this sprite is rendered + * + * @since 6.2.0 + */ + public final renderMatrix:FlxMatrix; + + public function new (x = 0.0, y = 0.0, ?simpleGraphic) + { + renderMatrix = new FlxMatrix(); + + super(x, y, simpleGraphic); + } + + override function isSimpleRenderBlit(?cam) + { + return super.isSimpleRenderBlit(cam) || renderMatrix.isIdentity(); + } + + override function prepareComplexMatrix(matrix:FlxMatrix, frame:FlxFrame, camera:FlxCamera) + { + frame.prepareMatrix(matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY()); + matrix.translate(-origin.x, -origin.y); + matrix.scale(scale.x, scale.y); + + if (bakedRotationAngle <= 0) + { + updateTrig(); + + if (angle != 0) + matrix.rotateWithTrig(_cosAngle, _sinAngle); + } + + matrix.concat(renderMatrix); + + final screenPos = getScreenPosition(camera).subtract(offset); + screenPos.add(origin.x, origin.y); + matrix.translate(screenPos.x, screenPos.y); + screenPos.put(); + + if (isPixelPerfectRender(camera)) + { + matrix.tx = Math.floor(matrix.tx); + matrix.ty = Math.floor(matrix.ty); + } + } +} \ No newline at end of file diff --git a/flixel/math/FlxMatrix.hx b/flixel/math/FlxMatrix.hx index 26c3b7c881..c70d1f6798 100644 --- a/flixel/math/FlxMatrix.hx +++ b/flixel/math/FlxMatrix.hx @@ -9,6 +9,37 @@ import openfl.geom.Matrix; */ class FlxMatrix extends Matrix { + public inline function isIdentity():Bool + { + return a == 1 && b == 0 && c == 0 && d == 1 && tx == 0 && ty == 0; + } + + /** + * Skews `this` matrix, in radians. + * @param skewX Horizontal skew in radians. + * @param skewY Vertical skew in radians. + * @return `this` skewed matrix. + */ + public inline function skewRadians(skewX:Float, skewY:Float):FlxMatrix + { + b = Math.tan(skewY); + + c = Math.tan(skewX); + + return this; + } + + /** + * Skews `this` matrix, in degrees. + * @param skewY Horizontal skew in degrees. + * @param skewX Vertical skew in degrees. + * @return `this` skewed matrix. + */ + public inline function skewDegrees(skewX:Float, skewY:Float):FlxMatrix + { + return skewRadians(skewY * FlxAngle.TO_RAD, skewX * FlxAngle.TO_RAD); + } + /** * Rotates this matrix, but takes the values of sine and cosine, * so it might be useful when you rotate multiple matrices by the same angle diff --git a/flixel/text/FlxText.hx b/flixel/text/FlxText.hx index 8d63c667d6..2b5f570ff6 100644 --- a/flixel/text/FlxText.hx +++ b/flixel/text/FlxText.hx @@ -1023,45 +1023,11 @@ class FlxText extends FlxSprite super.draw(); } - override function drawSimple(camera:FlxCamera):Void + override function getScreenPosition(?result:FlxPoint, ?camera:FlxCamera):FlxPoint { - // same as super but checks _graphicOffset - getScreenPosition(_point, camera).subtract(offset).subtract(_graphicOffset); - if (isPixelPerfectRender(camera)) - _point.floor(); - - _point.copyTo(_flashPoint); - camera.copyPixels(_frame, framePixels, _flashRect, _flashPoint, colorTransform, blend, antialiasing); + return super.getScreenPosition(result, camera).subtract(_graphicOffset); } - override function drawComplex(camera:FlxCamera):Void - { - _frame.prepareMatrix(_matrix, ANGLE_0, checkFlipX(), checkFlipY()); - _matrix.translate(-origin.x, -origin.y); - _matrix.scale(scale.x, scale.y); - - if (bakedRotationAngle <= 0) - { - updateTrig(); - - if (angle != 0) - _matrix.rotateWithTrig(_cosAngle, _sinAngle); - } - - // same as super but checks _graphicOffset - getScreenPosition(_point, camera).subtract(offset).subtract(_graphicOffset); - _point.add(origin.x, origin.y); - _matrix.translate(_point.x, _point.y); - - if (isPixelPerfectRender(camera)) - { - _matrix.tx = Math.floor(_matrix.tx); - _matrix.ty = Math.floor(_matrix.ty); - } - - camera.drawPixels(_frame, framePixels, _matrix, colorTransform, blend, antialiasing, shader); - } - /** * Internal function to update the current animation frame. *