Skip to content

FlxMatrixSprite #3427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions flixel/FlxSprite.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

/**
Expand Down
58 changes: 58 additions & 0 deletions flixel/effects/FlxMatrixSprite.hx
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
31 changes: 31 additions & 0 deletions flixel/math/FlxMatrix.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment on lines +25 to +29
Copy link
Member Author

@Geokureli Geokureli Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DetectiveBaldi these are flipped too, right?

Suggested change
b = Math.tan(skewY);
c = Math.tan(skewX);
return this;
b = Math.tan(skewX);
c = Math.tan(skewY);
return this;

Copy link
Contributor

@DetectiveBaldi DetectiveBaldi Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can tell this is intended as intended, the same behavior can be seen in the original FlxSkewedSprite class:

}

/**
* 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);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are flipped

Suggested change
return skewRadians(skewY * FlxAngle.TO_RAD, skewX * FlxAngle.TO_RAD);
return skewRadians(skewX * FlxAngle.TO_RAD, skewY * 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
Expand Down
38 changes: 2 additions & 36 deletions flixel/text/FlxText.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down