Skip to content
Draft
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
13 changes: 10 additions & 3 deletions flixel/FlxSprite.hx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package flixel;

import flixel.FlxBasic.IFlxBasic;
import flixel.FlxBasic;
import flixel.animation.FlxAnimationController;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxFrame;
Expand All @@ -16,6 +16,7 @@ import flixel.util.FlxBitmapDataUtil;
import flixel.util.FlxColor;
import flixel.util.FlxDestroyUtil;
import flixel.util.FlxDirectionFlags;
import flixel.util.FlxSignal;
import openfl.display.BitmapData;
import openfl.display.BlendMode;
import openfl.geom.ColorTransform;
Expand Down Expand Up @@ -286,14 +287,16 @@ class FlxSprite extends FlxObject
* applied after the frame is clipped. Use `clipToWorldBounds` or `clipToViewBounds` to convert
*/
public var clipRect(default, set):FlxRect;
var _lastClipRect = FlxRect.get(Math.NaN);
var _lastClipRect:FlxRect;

/**
* GLSL shader for this sprite. Avoid changing it frequently as this is a costly operation.
* @since 4.1.0
*/
public var shader:FlxShader;


public final onFrameChange = new FlxSignal();

/**
* The actual frame used for sprite rendering
*/
Expand Down Expand Up @@ -406,6 +409,7 @@ class FlxSprite extends FlxObject
_halfSize = FlxPoint.get();
_matrix = new FlxMatrix();
_scaledOrigin = new FlxPoint();
_lastClipRect = FlxRect.get(Math.NaN);
}

/**
Expand All @@ -430,6 +434,7 @@ class FlxSprite extends FlxObject
_halfSize = FlxDestroyUtil.put(_halfSize);
_scaledOrigin = FlxDestroyUtil.put(_scaledOrigin);
_lastClipRect = FlxDestroyUtil.put(_lastClipRect);
onFrameChange.removeAll();

framePixels = FlxDestroyUtil.dispose(framePixels);

Expand Down Expand Up @@ -1855,6 +1860,8 @@ class FlxSprite extends FlxObject
if (clipRect != null)
_frame.clip(clipRect);

onFrameChange.dispatch();

return frame;
}

Expand Down
123 changes: 123 additions & 0 deletions flixel/graphics/FlxSliceSprite.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package flixel.graphics;

import flixel.graphics.frames.FlxFrame;
import flixel.graphics.frames.slice.FlxSpriteSlicer;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.util.FlxDestroyUtil;

/**
* A `FlxSprite` with a 9-slice scaling. The `sliceRect` determines how to divide the 9 sections,
* and `displayWidth` and `displayHeight` determine how much the frame is stretched when drawn.
* If `sliceRect` is null, and the curret frame's `slice` is non-null, that slice rect is used
*
* **Note:** All of the slicing functionality is done via `FlxSpriteSlicer`, making it easy to
* add to any other class that extends FlxSprite
*
* @since 6.2.0
*/
class FlxSliceSprite extends flixel.FlxSprite
{
/**
* Controls the slicing of this sprite, `null` means no slicing
*/
public var sliceRect(get, set):Null<FlxRect>;
inline function get_sliceRect() { return slicer.rect; }
inline function set_sliceRect(value) { return slicer.rect = value; }

/**
* How large to draw the sliced sprite, relative to the `frameWidth`.
* If the value is `0` or less, the frameWidth is used
*/
public var displayWidth(get, set):Float;
inline function get_displayWidth() { return slicer.displayWidth; }
inline function set_displayWidth(value)
{
frameWidth = Std.int(value);
return slicer.displayWidth = value;
}

/**
* How large to draw the sliced sprite, relative to the `frameHeight`
* If the value is `0` or less, the frameWidth is used
*/
public var displayHeight(get, set):Float;
inline function get_displayHeight() { return slicer.displayHeight; }
inline function set_displayHeight(value)
{
frameHeight = Std.int(value);
return slicer.displayHeight = value;
}

/**
* The sprite's 9-slicing data
*/
var slicer(default, null):FlxSpriteSlicer;

override function initVars():Void
{
super.initVars();

slicer = new FlxSpriteSlicer(this);
}

override function destroy():Void
{
super.destroy();

slicer = FlxDestroyUtil.destroy(slicer);
}

override function updateHitbox()
{
return slicer.hasValidSlicing() ? slicer.updateTargetHitbox() : super.updateHitbox();
}

override function getGraphicBounds(?rect:FlxRect):FlxRect
{
return slicer.hasValidSlicing() ? slicer.getTargetGraphicBounds(rect) : super.getGraphicBounds(rect);
}

override function drawComplex(camera:FlxCamera):Void
{
if (slicer.hasValidSlicing())
slicer.drawComplex(camera);
else
super.drawComplex(camera);
}

override function viewToFrameHelper(viewX:Float, viewY:Float, ?camera:FlxCamera, ?result:FlxPoint):FlxPoint
{
result = super.viewToFrameHelper(viewX, viewY, camera, result);

if (slicer.hasValidSlicing())
slicer.displayToFrame(result, result);

return result;
}

override function worldToFrameSimpleHelper(worldX:Float, worldY:Float, ?result:FlxPoint):FlxPoint
{
result = super.worldToFrameSimpleHelper(worldX, worldY, result);

if (slicer.hasValidSlicing())
slicer.displayToFrame(result, result);

return result;
}

// override function getScreenBounds(?newRect:FlxRect, ?camera:FlxCamera):FlxRect
// {
// newRect = super.getScreenBounds(newRect, camera);

// // if (slicer.hasValidSlicing())
// // {
// // newRect.x = slicer.displayToFrameX(newRect.x);
// // newRect.y = slicer.displayToFrameX(newRect.y);
// // newRect.width = slicer.displayToFrameX(newRect.width);
// // newRect.height = slicer.displayToFrameX(newRect.height);
// // }

// return newRect;
// }
}
17 changes: 16 additions & 1 deletion flixel/graphics/atlas/AtlasBase.hx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,22 @@ typedef AtlasPos =
/**
* Rectangle struct use for atlas json parsing, { x:Float, y:Float, w:Float, h:Float }
*/
typedef AtlasRect = AtlasPos & AtlasSize;
@:forward
abstract AtlasRect(AtlasPos & AtlasSize) from AtlasPos & AtlasSize
{
public var l(get, never):Float; inline function get_l() return this.x;
public var r(get, never):Float; inline function get_r() return this.x + this.w;
public var t(get, never):Float; inline function get_t() return this.y;
public var b(get, never):Float; inline function get_b() return this.y + this.h;

public function toFlxRect(?rect)
{
if (rect == null)
rect = flixel.math.FlxRect.get();

return rect.set(this.x, this.y, this.w, this.h);
}
}

typedef AtlasFrame =
{
Expand Down
58 changes: 53 additions & 5 deletions flixel/graphics/frames/FlxFrame.hx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package flixel.graphics.frames;

import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.slice.FlxFrameSlices;
import flixel.graphics.frames.slice.FlxSliceSection;
import flixel.math.FlxMath;
import flixel.math.FlxMatrix;
import flixel.math.FlxPoint;
Expand Down Expand Up @@ -145,6 +147,16 @@ class FlxFrame implements IFlxDestroyable
/** Internal cache used to draw this frame **/
var blitMatrix:MatrixVector;

/**
* The 9-slice rect of this frame
*/
public var slice:FlxRect;

/**
* Internal helper for this frame's 9-slicing
*/
var sliceData:FlxFrameSlices;

public function new(parent:FlxGraphic, angle = FlxFrameAngle.ANGLE_0, flipX = false, flipY = false, duration = 0.0)
{
this.parent = parent;
Expand All @@ -161,11 +173,42 @@ class FlxFrame implements IFlxDestroyable
blitMatrix = new MatrixVector();
if (FlxG.renderTile)
tileMatrix = new MatrixVector();

sliceData = new FlxFrameSlices(this);
}

@:allow(flixel.graphics.frames.FlxFramesCollection)
@:allow(flixel.graphics.frames.FlxBitmapFont)
function cacheFrameMatrix():Void

/**
* Updates the internal helpers to prepare this frame for rendering.
* Called automaticaly in `copyTo`.
*/
public function updateCache()
{
if (slice == null && sliceData.rect != null)
sliceData.clear();
else if (slice != null && (sliceData.rect == null || sliceData.rect.equals(slice)))
sliceData.set(slice);

// TODO: Defer matrix stuff?
}

/**
* Fills the target frame sections with this frame's slice data, for rendering
* @param list
*/
public function initSliceSections(frames:FlxSectionList<FlxFrame>)
{
if (slice != null)
{
for (section=>frame in frames)
sliceData.initSectionFrame(section, frame);
}
}

/**
* initializes internal data, used for rendering, usually called after creation
* @since 6.1.0
*/
public function cacheFrameMatrix():Void
{
blitMatrix.copyFrom(this, true);

Expand Down Expand Up @@ -768,7 +811,8 @@ class FlxFrame implements IFlxDestroyable
clone.angle = angle;
clone.frame = FlxDestroyUtil.put(clone.frame);
}


updateCache();
clone.offset.copyFrom(offset);
clone.flipX = flipX;
clone.flipY = flipY;
Expand All @@ -778,6 +822,9 @@ class FlxFrame implements IFlxDestroyable
clone.name = name;
clone.duration = duration;
clone.cacheFrameMatrix();
clone.slice = slice;
clone.sliceData.copyFrom(sliceData);

return clone;
}

Expand All @@ -789,6 +836,7 @@ class FlxFrame implements IFlxDestroyable
offset = FlxDestroyUtil.put(offset);
frame = FlxDestroyUtil.put(frame);
uv = FlxDestroyUtil.put(uv);
sliceData = FlxDestroyUtil.destroy(sliceData);
blitMatrix = null;
tileMatrix = null;
}
Expand Down
Loading
Loading