Skip to content

Commit

Permalink
allow changes to cliprect to take effect without setter
Browse files Browse the repository at this point in the history
  • Loading branch information
Geokureli committed Feb 27, 2025
1 parent a2295f2 commit 4ad99fa
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 82 deletions.
74 changes: 47 additions & 27 deletions flixel/FlxSprite.hx
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ class FlxSprite extends FlxObject
* Set to `null` to discard graphic frame clipping.
*/
public var clipRect(default, set):FlxRect;
var lastClipRect = FlxRect.get(Math.NaN);

/**
* GLSL shader for this sprite. Avoid changing it frequently as this is a costly operation.
Expand Down Expand Up @@ -420,6 +421,7 @@ class FlxSprite extends FlxObject
scale = FlxDestroyUtil.put(scale);
_halfSize = FlxDestroyUtil.put(_halfSize);
_scaledOrigin = FlxDestroyUtil.put(_scaledOrigin);
lastClipRect = FlxDestroyUtil.put(lastClipRect);

framePixels = FlxDestroyUtil.dispose(framePixels);

Expand Down Expand Up @@ -808,7 +810,9 @@ class FlxSprite extends FlxObject

if (dirty) // rarely
calcFrame(useFramePixels);


checkClipRect();

for (camera in getCamerasLegacy())
{
if (!camera.visible || !camera.exists || !isOnScreen(camera))
Expand All @@ -829,6 +833,24 @@ class FlxSprite extends FlxObject
drawDebug();
#end
}

/**
* Checks the previous frame's clipRect compared to the current. If there's changes, apply them
*/
function checkClipRect()
{
if ((clipRect == null && Math.isNaN(lastClipRect.x))
|| (clipRect != null && clipRect.equals(lastClipRect)))
return;

// redraw frame
frame = frames.frames[animation.frameIndex];

if (clipRect == null)
lastClipRect.set(Math.NaN);
else
lastClipRect.copyFrom(clipRect);
}

@:noCompletion
function drawSimple(camera:FlxCamera):Void
Expand All @@ -844,29 +866,35 @@ class FlxSprite extends FlxObject
@:noCompletion
function drawComplex(camera:FlxCamera):Void
{
_frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY());
_matrix.translate(-origin.x, -origin.y);
_matrix.scale(scale.x, scale.y);

drawFrameComplex(_frame, camera);
}

function drawFrameComplex(frame:FlxFrame, camera:FlxCamera):Void
{
final matrix = this._matrix; // TODO: Just use local?
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.rotateWithTrig(_cosAngle, _sinAngle);
}

getScreenPosition(_point, camera).subtract(offset);
_point.add(origin.x, origin.y);
_matrix.translate(_point.x, _point.y);

matrix.translate(_point.x, _point.y);
if (isPixelPerfectRender(camera))
{
_matrix.tx = Math.floor(_matrix.tx);
_matrix.ty = Math.floor(_matrix.ty);
matrix.tx = Math.floor(matrix.tx);
matrix.ty = Math.floor(matrix.ty);
}

camera.drawPixels(_frame, framePixels, _matrix, colorTransform, blend, antialiasing, shader);
camera.drawPixels(frame, framePixels, matrix, colorTransform, blend, antialiasing, shader);
}

/**
Expand Down Expand Up @@ -1450,21 +1478,16 @@ class FlxSprite extends FlxObject
{
return null;
}

if (FlxG.renderTile)
{
_frameGraphic = FlxDestroyUtil.destroy(_frameGraphic);
}


_frame = frame.copyTo(_frame);
if (clipRect != null)
{
_frame = frame.clipTo(clipRect, _frame);
}
else
{
_frame = frame.copyTo(_frame);
}

_frame.clip(clipRect);

return frame;
}

Expand Down Expand Up @@ -1567,9 +1590,6 @@ class FlxSprite extends FlxObject
else
clipRect = null;

if (frames != null)
frame = frames.frames[animation.frameIndex];

return rect;
}

Expand Down
106 changes: 51 additions & 55 deletions flixel/graphics/frames/FlxFrame.hx
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package flixel.graphics.frames;

import openfl.display.BitmapData;
import openfl.geom.Point;
import openfl.geom.Rectangle;
import flixel.graphics.FlxGraphic;
import flixel.math.FlxMath;
import flixel.math.FlxMatrix;
Expand All @@ -13,6 +10,9 @@ import flixel.util.FlxDestroyUtil;
import flixel.util.FlxStringUtil;
import haxe.ds.ArraySort;
import haxe.ds.Vector;
import openfl.display.BitmapData;
import openfl.geom.Point;
import openfl.geom.Rectangle;

/**
* Base class for all frame types
Expand Down Expand Up @@ -576,83 +576,79 @@ class FlxFrame implements IFlxDestroyable
* If `null`, a new frame will be created.
* @return Result of applying frame clipping
*/
public function clipTo(clip:FlxRect, ?clippedFrame:FlxFrame):FlxFrame
public function clipTo(rect:FlxRect, ?clippedFrame:FlxFrame):FlxFrame
{
if (clippedFrame == null)
{
clippedFrame = new FlxFrame(parent, angle);
}
else
{
clippedFrame.parent = parent;
clippedFrame.angle = angle;
clippedFrame.frame = FlxDestroyUtil.put(clippedFrame.frame);
}

clippedFrame.sourceSize.copyFrom(sourceSize);
clippedFrame.name = name;
copyTo(clippedFrame);
return clippedFrame.clip(rect);
}

/**
* Clips this frame to the desired rect
*
* @param rect Clipping rectangle to apply
*/
public function clip(rect:FlxRect)
{
// no need to make all calculations if original frame is empty...
if (type == FlxFrameType.EMPTY)
{
clippedFrame.type = FlxFrameType.EMPTY;
clippedFrame.offset.set(0, 0);
return clippedFrame;
}

final clippedRect:FlxRect = FlxRect.get(0, 0).setSize(frame.width, frame.height);
return this;

final clippedRect = FlxRect.get(0, 0, frame.width, frame.height);
if (angle != FlxFrameAngle.ANGLE_0)
{
clippedRect.width = frame.height;
clippedRect.height = frame.width;
}

clip.offset(-offset.x, -offset.y);
var frameRect:FlxRect = clippedRect.intersection(clip);

rect.offset(-offset.x, -offset.y);
final frameRect:FlxRect = clippedRect.intersection(rect);
rect.offset(offset.x, offset.y);
clippedRect.put();

if (frameRect.isEmpty)
{
clippedFrame.type = FlxFrameType.EMPTY;
frameRect.set(0, 0, 0, 0);
clippedFrame.frame = frameRect;
clippedFrame.offset.set(0, 0);
type = FlxFrameType.EMPTY;
frame.set(0, 0, 0, 0);
offset.set(0, 0);
}
else
{
clippedFrame.type = FlxFrameType.REGULAR;
clippedFrame.offset.set(frameRect.x, frameRect.y).add(offset);

var p1 = FlxPoint.weak(frameRect.x, frameRect.y);
var p2 = FlxPoint.weak(frameRect.right, frameRect.bottom);

_matrix.identity();

if (angle == FlxFrameAngle.ANGLE_NEG_90)
{
_matrix.rotateByPositive90();
_matrix.translate(frame.width, 0);
}
else if (angle == FlxFrameAngle.ANGLE_90)
{
_matrix.rotateByNegative90();
_matrix.translate(0, frame.height);
}

type = FlxFrameType.REGULAR;
offset.add(frameRect.x, frameRect.y);

if (angle != FlxFrameAngle.ANGLE_0)
{
final p1 = FlxPoint.weak(frameRect.x, frameRect.y);
final p2 = FlxPoint.weak(frameRect.right, frameRect.bottom);

_matrix.identity();

if (angle == FlxFrameAngle.ANGLE_NEG_90)
{
_matrix.rotateByPositive90();
_matrix.translate(frame.width, 0);
}
else if (angle == FlxFrameAngle.ANGLE_90)
{
_matrix.rotateByNegative90();
_matrix.translate(0, frame.height);
}

p1.transform(_matrix);
p2.transform(_matrix);
frameRect.fromTwoPoints(p1, p2);
}

frameRect.fromTwoPoints(p1, p2);

frameRect.offset(frame.x, frame.y);
clippedFrame.frame = frameRect;
clippedFrame.cacheFrameMatrix();
frame.copyFrom(frameRect);
cacheFrameMatrix();
}

clip.offset(offset.x, offset.y);
return clippedFrame;
frameRect.put();
return this;
}

/**
Expand Down

0 comments on commit 4ad99fa

Please sign in to comment.