I BROKE THE OFFSETS FUCK

.
This commit is contained in:
Yoshman29
2026-01-18 21:43:47 +01:00
parent 246014af60
commit 0c8b766b19
17 changed files with 96 additions and 531 deletions
+1
View File
@@ -131,6 +131,7 @@
<haxelib name="away3d" if="THREE_D_SUPPORT" />
<haxelib name="format" />
<haxelib name="flxanimate" />
<haxelib name="flixel-animate" />
<haxelib name="nape-haxe4" if="NAPE_ENABLED"/>
<haxelib name="hscript-improved" />
-92
View File
@@ -1,92 +0,0 @@
package funkin.backend;
import flixel.graphics.frames.FlxFrame;
import flixel.math.FlxAngle;
import flixel.math.FlxMatrix;
import openfl.display.BlendMode;
import openfl.geom.ColorTransform;
class FlxAnimate extends flxanimate.FlxAnimate {
static var rMatrix = new FlxMatrix();
override function drawLimb(limb:FlxFrame, _rMatrix:FlxMatrix, ?colorTransform:ColorTransform, ?blendMode:BlendMode)
{
if (alpha == 0 || colorTransform != null && (colorTransform.alphaMultiplier == 0 || colorTransform.alphaOffset == -255) || limb == null || limb.type == EMPTY)
return;
if (blendMode == null)
blendMode = BlendMode.NORMAL;
for (camera in cameras)
{
rMatrix.identity();
limb.prepareMatrix(rMatrix, FlxFrameAngle.ANGLE_0, _checkFlipX() != camera.flipX, _checkFlipY() != camera.flipY);
rMatrix.concat(_rMatrix);
if (!camera.visible || !camera.exists || !limbOnScreen(limb, _rMatrix, camera))
return;
getScreenPosition(_point, camera).subtractPoint(offset);
rMatrix.translate(-origin.x, -origin.y);
if (limb != _pivot) {
if (frameOffsetAngle != null && frameOffsetAngle != angle)
{
var angleOff = (frameOffsetAngle - angle) * FlxAngle.TO_RAD;
var cos = Math.cos(angleOff);
var sin = Math.sin(angleOff);
// cos doesn't need to be negated
rMatrix.rotateWithTrig(cos, -sin);
rMatrix.translate(-frameOffset.x, -frameOffset.y);
rMatrix.rotateWithTrig(cos, sin);
}
else
{
rMatrix.translate(-frameOffset.x, -frameOffset.y);
}
rMatrix.scale(scale.x, scale.y);
if (!matrixExposed && bakedRotationAngle <= 0)
{
updateTrig();
if (angle != 0)
rMatrix.rotateWithTrig(_cosAngle, _sinAngle);
}
}
else
rMatrix.a = rMatrix.d = 0.7 / camera.zoom;
if (matrixExposed)
{
rMatrix.concat(transformMatrix);
}
else
{
rMatrix.concat(@:privateAccess flxanimate.FlxAnimate._skewMatrix);
}
_point.addPoint(origin);
if (isPixelPerfectRender(camera))
{
_point.floor();
}
rMatrix.translate(_point.x, _point.y);
camera.drawPixels(limb, null, rMatrix, colorTransform, blendMode, antialiasing, shaderEnabled ? shader : null);
#if FLX_DEBUG
FlxBasic.visibleCount++;
#end
}
// doesn't work, needs to be remade
// #if FLX_DEBUG
// if (FlxG.debugger.drawDebug)
// drawDebug();
// #end
}
override function limbOnScreen(limb:FlxFrame, m:FlxMatrix, ?Camera:FlxCamera)
{
// TODO: ACTUAL OPTIMIZATION
return true;
}
}
+27 -109
View File
@@ -1,5 +1,7 @@
package funkin.backend;
import animate.FlxAnimate;
import animate.FlxAnimateController.FlxAnimateAnimation;
import flixel.addons.effects.FlxSkewedSprite;
import flixel.animation.FlxAnimation;
import flixel.math.FlxMatrix;
@@ -43,7 +45,7 @@ enum abstract XMLAnimType(Int)
}
}
class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements IOffsetCompatible implements IXMLEvents
class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffsetCompatible implements IXMLEvents
{
public var extra:Map<String, Dynamic> = [];
@@ -66,10 +68,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
public var beatOffset:Int = 0;
public var skipNegativeBeats:Bool = false;
public var animateAtlas:FlxAnimate;
@:noCompletion public var atlasPlayingAnim:String;
@:noCompletion public var atlasPath:String;
var _rect2:FlxRect;
public function new(?X:Float = 0, ?Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset)
@@ -85,6 +83,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
}
moves = false;
applyStageMatrix = true;
}
/**
@@ -100,8 +99,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
@:privateAccess {
spr.setPosition(source.x, source.y);
spr.frames = source.frames;
if (casted != null && casted.animateAtlas != null && casted.atlasPath != null)
spr.loadSprite(casted.atlasPath);
spr.animation.copyFrom(source.animation);
spr.visible = source.visible;
spr.alpha = source.alpha;
@@ -111,8 +108,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
if (casted != null) {
spr.skew.set(casted.skew.x, casted.skew.y);
spr.transformMatrix = casted.transformMatrix;
spr.matrixExposed = casted.matrixExposed;
spr.animOffsets = casted.animOffsets.copy();
spr.zoomFactor = casted.zoomFactor;
}
@@ -123,8 +118,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
public override function update(elapsed:Float)
{
super.update(elapsed);
if (animateAtlas != null)
animateAtlas.update(elapsed);
// hate how it looks like but hey at least its optimized and fast - Nex
if (!debugMode && isAnimFinished()) {
@@ -142,15 +135,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
public function loadSprite(path:String, Unique:Bool = false, Key:String = null)
{
var noExt = Path.withoutExtension(path);
if (Assets.exists('$noExt/Animation.json'))
{
atlasPath = noExt;
animateAtlas = new FlxAnimate(x, y, noExt);
}
else
{
frames = Paths.getFrames(path, true);
}
frames = Paths.getFrames(path, true);
return this;
}
@@ -182,48 +167,9 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
// ANIMATE ATLAS DRAWING
#if REGION
public override function draw()
{
if (animateAtlas != null)
{
copyAtlasValues();
animateAtlas.draw();
}
else
{
super.draw();
}
}
public function copyAtlasValues()
{
@:privateAccess {
animateAtlas.cameras = cameras; // investigate if we can use _cameras
animateAtlas.scrollFactor = scrollFactor;
animateAtlas.scale = scale;
animateAtlas.offset = offset;
animateAtlas.frameOffset = frameOffset;
animateAtlas.x = x;
animateAtlas.y = y;
animateAtlas.angle = angle;
animateAtlas.alpha = alpha;
animateAtlas.visible = visible;
animateAtlas.flipX = flipX;
animateAtlas.flipY = flipY;
animateAtlas.shader = shader;
animateAtlas.shaderEnabled = shaderEnabled;
animateAtlas.antialiasing = antialiasing;
animateAtlas.skew = skew;
animateAtlas.transformMatrix = transformMatrix;
animateAtlas.matrixExposed = matrixExposed;
animateAtlas.colorTransform = colorTransform;
}
}
public override function destroy()
{
animateAtlas = FlxDestroyUtil.destroy(animateAtlas);
if (animOffsets != null) {
for (key in animOffsets.keys()) {
final point = animOffsets[key];
@@ -340,13 +286,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
Force = anim != null && anim.forced;
}
if (animateAtlas != null)
{
@:privateAccess
animateAtlas.anim.play(AnimName, Force, Reversed, Frame);
atlasPlayingAnim = AnimName;
}
else animation.play(AnimName, Force, Reversed, Frame);
animation.play(AnimName, Force, Reversed, Frame);
var daOffset = getAnimOffset(AnimName);
frameOffset.set(daOffset.x, daOffset.y);
@@ -370,18 +310,11 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
});
}
public inline function removeAnim(name:String)
{
if (animateAtlas != null)
@:privateAccess animateAtlas.anim.animsMap.remove(name);
else
animation.remove(name);
public inline function removeAnim(name:String) {
animation.remove(name);
}
public function getAnim(name:String):OneOfTwo<FlxAnimation, FlxSymbolAnimation>
{
if(animateAtlas != null)
return animateAtlas.anim.getByName(name);
public function getAnim(name:String):OneOfTwo<FlxAnimation, FlxAnimateAnimation> {
return animation.getByName(name);
}
@@ -392,40 +325,26 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
return FlxPoint.weak(0, 0);
}
public inline function hasAnim(AnimName:String):Bool @:privateAccess
return animateAtlas != null ? (animateAtlas.anim.animsMap.exists(AnimName)
|| animateAtlas.anim.symbolDictionary.exists(AnimName)) : animation.exists(AnimName);
public inline function hasAnim(AnimName:String):Bool
return animation.exists(AnimName);
public inline function getAnimName() {
return (animateAtlas != null) ? atlasPlayingAnim : animation.name;
}
public inline function getAnimName()
return animation.name;
public inline function isAnimReversed():Bool {
return animateAtlas != null ? animateAtlas.anim.reversed : animation.curAnim != null ? animation.curAnim.reversed : false;
}
public inline function isAnimReversed():Bool
return animation.curAnim?.reversed ?? false;
public inline function getNameList():Array<String> {
if (animateAtlas != null)
return [for (name in @:privateAccess animateAtlas.anim.animsMap.keys()) name];
else
return animation.getNameList();
}
public inline function getNameList():Array<String>
return animation.getNameList();
public inline function stopAnim()
{
if (animateAtlas != null)
animateAtlas.anim.pause();
else
animation.stop();
}
animation.stop();
public inline function isAnimFinished() {
return animateAtlas != null ? animateAtlas.anim.finished : (animation.curAnim != null ? animation.curAnim.finished : true);
}
public inline function isAnimFinished()
return animation.curAnim?.finished ?? true;
public inline function isAnimAtEnd() {
return animateAtlas != null ? animateAtlas.anim.isAtEnd : (animation.curAnim != null ? animation.curAnim.isAtEnd : false);
}
public inline function isAnimAtEnd()
return animation.curAnim?.isAtEnd ?? false;
override function updateAnimation(elapsed:Float) {
if (animEnabled)
@@ -447,10 +366,9 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
return beatInterval = v;
}
@:noCompletion private inline function get_globalCurFrame() {
return animateAtlas != null ? (animateAtlas.anim.curFrame) : (animation.curAnim != null ? animation.curAnim.curFrame : 0);
}
@:noCompletion private inline function set_globalCurFrame(val:Int) {
return animateAtlas != null ? (animateAtlas.anim.curFrame = val) : (animation.curAnim != null ? animation.curAnim.curFrame = val : val);
}
@:noCompletion private inline function get_globalCurFrame()
return animation.curAnim?.curFrame ?? 0;
@:noCompletion private inline function set_globalCurFrame(val:Int)
return animation.curAnim?.curFrame ?? 0;
}
+2 -6
View File
@@ -114,12 +114,8 @@ class MusicBeatTransition extends MusicBeatSubstate {
}
if (transitionSprite != null) {
if (transitionSprite.animateAtlas == null) {
transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height);
transitionSprite.updateHitbox();
} else {
transitionSprite.screenCenter();
}
transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height);
transitionSprite.updateHitbox();
}
}
+6
View File
@@ -8,6 +8,7 @@ import funkin.backend.scripting.Script;
import haxe.io.Path;
import lime.utils.AssetLibrary;
import openfl.utils.Assets as OpenFlAssets;
import animate.FlxAnimateFrames;
using StringTools;
@@ -174,6 +175,9 @@ class Paths
inline static public function getSparrowAtlas(key:String, ?library:String, ?ext:String)
return FlxAtlasFrames.fromSparrow(image(key, library, ext), file('images/$key.xml', library));
inline static public function getAnimateAtlasAlt(key:String)
return FlxAnimateFrames.fromAnimate(key);
inline static public function getSparrowAtlasAlt(key:String, ?ext:String)
return FlxAtlasFrames.fromSparrow('$key.${ext != null ? ext : Flags.IMAGE_EXT}', '$key.xml');
@@ -263,6 +267,8 @@ class Paths
cur++;
}
return finalFrames;
} else if (Assets.exists('$noExt/Animation.json')) {
return Paths.getAnimateAtlasAlt(noExt);
} else if (Assets.exists('$noExt.xml')) {
return Paths.getSparrowAtlasAlt(noExt, ext);
} else if (Assets.exists('$noExt.txt')) {
+1 -1
View File
@@ -91,7 +91,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
"FunkinShader" => funkin.backend.shaders.FunkinShader,
"CustomShader" => funkin.backend.shaders.CustomShader,
"FunkinText" => funkin.backend.FunkinText,
"FlxAnimate" => funkin.backend.FlxAnimate,
"FlxAnimate" => animate.FlxAnimate,
"FunkinSprite" => funkin.backend.FunkinSprite,
"Alphabet" => funkin.menus.ui.Alphabet,
"Flags" => funkin.backend.system.Flags,
@@ -23,7 +23,7 @@ class Macros {
#if VIDEO_CUTSCENES "hxvlc.flixel", "hxvlc.openfl", #end
#if NAPE_ENABLED "nape", "flixel.addons.nape", #end
// BASE HAXE
"DateTools", "EReg", "Lambda", "StringBuf", "haxe.crypto", "haxe.display", "haxe.exceptions", "haxe.extern", "scripting"
"DateTools", "EReg", "Lambda", "StringBuf", "haxe.crypto", "haxe.display", "haxe.exceptions", "haxe.extern", "scripting", "animate"
])
Compiler.include(inc);
+1 -4
View File
@@ -1265,10 +1265,7 @@ final class CoolUtil
}
public static function getAnimsListFromSprite(spr:FunkinSprite):Array<String> {
if (spr.animateAtlas != null) {
return [for (symbol => timeline in spr.animateAtlas.anim.symbolDictionary) symbol];
} else
return getAnimsListFromFrames(spr.frames);
return getAnimsListFromFrames(spr.frames);
}
// TODO: check this for bugs
+8 -136
View File
@@ -34,151 +34,23 @@ final class MatrixUtil {
//if(_height == -1) _height = sprite.height;
if(camera == null) camera = sprite.camera;
if(points is FlxBasePoint) points = [points];
var isFunkinSprite = sprite is FunkinSprite;
var funkinSprite:FunkinSprite = null;
if(isFunkinSprite) funkinSprite = cast sprite;
var isAnimateAtlas = isFunkinSprite && funkinSprite.animateAtlas != null;
var nc:FakeCamera = isAnimateAtlas ? FakeCallCamera.instance : FakeCamera.instance;
var nc:FakeCamera = FakeCamera.instance;
nc.zoom = camera.zoom;
nc.scroll.set(camera.scroll.x, camera.scroll.y);
nc.pixelPerfectRender = camera.pixelPerfectRender;
var points:Array<FlxPoint> = cast points;
if(isAnimateAtlas) {
var cnc = FakeCallCamera.instance;
var sprite = funkinSprite;
var oldOnDraw = cnc.onDraw;
// TODO: fix rotation
// TODO: fix skew
var boundsTopLeft = new FlxPoint(Math.POSITIVE_INFINITY, Math.POSITIVE_INFINITY);
var boundsTopRight = new FlxPoint(Math.NEGATIVE_INFINITY, Math.POSITIVE_INFINITY);
var boundsBottomLeft = new FlxPoint(Math.POSITIVE_INFINITY, Math.NEGATIVE_INFINITY);
var boundsBottomRight = new FlxPoint(Math.NEGATIVE_INFINITY, Math.NEGATIVE_INFINITY);
cnc.onDraw = function(?frame:FlxFrame, ?pixels:BitmapData, matrix:FlxMatrix, ?transform:ColorTransform, ?blend:BlendMode, ?smoothing:Bool = false, ?shader:FlxShader) {
// cnc is already perfect rn
// so we need to manually process the limb
var points = [
// corners
FlxPoint.get(0, 0),
FlxPoint.get(1, 0),
FlxPoint.get(0, 1),
FlxPoint.get(1, 1)
];
rawTransformPoints(points, matrix, frame.sourceSize.x, frame.sourceSize.y);
// sort the points, incase like they were transformed with a scale -1 matrix
var topLeft:FlxPoint = points[0];
var topRight:FlxPoint = points[1];
var bottomLeft:FlxPoint = points[2];
var bottomRight:FlxPoint = points[3];
if (points[0].y > points[1].y) {
topLeft = points[1];
topRight = points[0];
}
if (points[2].y > points[3].y) {
bottomLeft = points[3];
bottomRight = points[2];
}
if (topLeft.x > topRight.x) {
var temp = topLeft;
topLeft = topRight;
topRight = temp;
}
if (bottomLeft.x > bottomRight.x) {
var temp = bottomLeft;
bottomLeft = bottomRight;
bottomRight = temp;
}
// points should now contain the corners of the limb
// trace("Corners of limb: " + points);
// set the max bounds of each corner of the limb
if(topLeft.x < boundsTopLeft.x) boundsTopLeft.x = topLeft.x;
if(topLeft.y < boundsTopLeft.y) boundsTopLeft.y = topLeft.y;
if(topRight.x > boundsTopRight.x) boundsTopRight.x = topRight.x;
if(topRight.y < boundsTopRight.y) boundsTopRight.y = topRight.y;
if(bottomLeft.x < boundsBottomLeft.x) boundsBottomLeft.x = bottomLeft.x;
if(bottomLeft.y > boundsBottomLeft.y) boundsBottomLeft.y = bottomLeft.y;
if(bottomRight.x > boundsBottomRight.x) boundsBottomRight.x = bottomRight.x;
if(bottomRight.y > boundsBottomRight.y) boundsBottomRight.y = bottomRight.y;
// recycle the points
for(point in points) point.put();
}
var cameras = sprite._cameras;
var oldVisible = cnc.visible;
cnc.visible = true;
sprite._cameras = [cnc];
sprite.draw();
sprite._cameras = cameras;
cnc.visible = oldVisible;
cnc.onDraw = oldOnDraw;
// fake transform
//trace("");
//trace("topLeft: " + boundsTopLeft);
//trace("topRight: " + boundsTopRight);
//trace("bottomLeft: " + boundsBottomLeft);
//trace("bottomRight: " + boundsBottomRight);
//trace("Before transform");
//trace(points);
for(point in points) {
//var x = matrix.__transformX(point.x * _width, point.y * _height);
//var y = matrix.__transformY(point.x * _width, point.y * _height);
// apply using boundsTopLeft, boundsTopRight, boundsBottomLeft, boundsBottomRight
// matrix doesnt work for this
var x = FlxMath.lerp(
FlxMath.lerp(boundsTopLeft.x, boundsTopRight.x, point.x),
FlxMath.lerp(boundsBottomLeft.x, boundsBottomRight.x, point.x),
point.y
);
var y = FlxMath.lerp(
FlxMath.lerp(boundsTopLeft.y, boundsTopRight.y, point.x),
FlxMath.lerp(boundsBottomLeft.y, boundsBottomRight.y, point.x),
point.y
);
//trace("(" + point.x + ", " + point.y + ") -> (" + x + ", " + y + ")");
// reset to ingame coords
x += camera.scroll.x;
y += camera.scroll.y;
if(isFunkinSprite) {
var ratio = 1 - FlxMath.lerp(1 / camera.zoom, 1, funkinSprite.zoomFactor);
x += camera.width / 2 * ratio;
y += camera.height / 2 * ratio;
}
point.set(x, y);
}
//trace("After transform");
//trace(points);
if(sprite is IPrePostDraw) {
var postDraw = cast(sprite, IPrePostDraw);
postDraw.preDraw();
sprite.drawComplex(nc);
postDraw.postDraw();
} else {
if(sprite is IPrePostDraw) {
var postDraw = cast(sprite, IPrePostDraw);
postDraw.preDraw();
sprite.drawComplex(nc);
postDraw.postDraw();
} else {
sprite.drawComplex(nc);
}
transformPoints(sprite, points, sprite._matrix, camera, _width, _height);
sprite.drawComplex(nc);
}
transformPoints(sprite, points, sprite._matrix, camera, _width, _height);
return points;
}
+8 -2
View File
@@ -14,6 +14,7 @@ import funkin.backend.scripting.ScriptPack;
import flixel.util.typeLimit.OneOfTwo;
import funkin.backend.system.interfaces.IOffsetCompatible;
import haxe.xml.Access;
import animate.FlxAnimateFrames;
using StringTools;
@@ -127,6 +128,10 @@ final class XMLUtil {
spr.spriteAnimType = XMLAnimType.fromString(node.att.type, spr.spriteAnimType);
}
if (node.has.applyStageMatrix) {
spr.applyStageMatrix = node.att.applyStageMatrix == "true";
}
if(node.has.x) {
var x:Null<Float> = Std.parseFloat(node.att.x);
if (x.isNotNull()) spr.x = x;
@@ -299,11 +304,12 @@ final class XMLUtil {
if (animData.name != null) {
if (animData.fps <= 0 #if web || animData.fps == null #end) animData.fps = 24;
if (sprite is FunkinSprite && cast(sprite, FunkinSprite).animateAtlas != null) {
var animateAnim = cast(sprite, FunkinSprite).animateAtlas.anim;
if (sprite.frames is FlxAnimateFrames) {
if(animData.anim == null)
return MISSING_PROPERTY;
var animateAnim = cast(sprite, FunkinSprite).anim;
if (animData.indices != null && animData.indices.length > 0)
animateAnim.addBySymbolIndices(animData.name, animData.anim, animData.indices, animData.fps, animData.loop);
else
@@ -231,18 +231,12 @@ class CharacterAnimButton extends UIButton {
}
var oldName:String = anim;
if (parent.character.animateAtlas != null) {
var animSymbol:FlxSymbolAnimation = __getAnimationSymbol();
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.name = newName;
parent.character.animateAtlas.anim.animsMap.remove(anim);
parent.character.animateAtlas.anim.animsMap.set(newName, animSymbol);
} else {
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.name = newName;
parent.character.animation._animations.remove(anim);
parent.character.animation._animations.set(newName, flxAnimation);
}
parent.character.animation._animations.remove(anim);
parent.character.animation._animations.set(newName, flxAnimation);
var animData:AnimData = parent.character.animDatas[anim];
animData.name = newName;
@@ -276,22 +270,7 @@ class CharacterAnimButton extends UIButton {
var oldAnim:String = animData.anim;
animData.anim = newAnim;
if (parent.character.animateAtlas != null)
__refreshAnimation();
else {
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.prefix = newAnim;
refreshFlxAnimationFrames(flxAnimation, animData);
if (valid) {
parent.buildAnimDisplay(anim, data);
animationDisplayBG.alpha = 1;
} else {
parent.removeAnimDisplay(anim);
animationDisplayBG.alpha = 0.4;
}
}
__refreshAnimation();
if (parent.character.getAnimName() == anim)
CharacterEditor.instance.playAnimation(anim);
@@ -330,13 +309,8 @@ class CharacterAnimButton extends UIButton {
var oldFPS:Float = animData.fps;
animData.fps = newFPS;
if (parent.character.animateAtlas != null) {
var animSymbol:FlxSymbolAnimation = __getAnimationSymbol();
animSymbol.frameRate = newFPS;
} else {
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.frameRate = newFPS;
}
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.frameRate = newFPS;
if (parent.character.getAnimName() == anim)
CharacterEditor.instance.playAnimation(anim);
@@ -351,13 +325,8 @@ class CharacterAnimButton extends UIButton {
animData.loop = newLooping;
if (parent.character.animateAtlas != null) {
var animSymbol:FlxSymbolAnimation = __getAnimationSymbol();
animSymbol.instance.symbol.loop = animData.loop ? Loop : PlayOnce;
} else {
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.looped = animData.loop;
}
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.looped = animData.loop;
if (parent.character.getAnimName() == anim)
CharacterEditor.instance.playAnimation(anim);
@@ -429,24 +398,6 @@ class CharacterAnimButton extends UIButton {
}
}
public inline function refreshSymbolKeyFrames(symbol:FlxSymbolAnimation, animData:AnimData) @:privateAccess {
var wasRefreshed:Bool = false;
try {
parent.character.animateAtlas.anim.animsMap.remove(animData.name);
if (animData.indices.length > 0)
parent.character.animateAtlas.anim.addBySymbolIndices(animData.name, animData.anim, animData.indices, animData.fps, animData.loop);
else
parent.character.animateAtlas.anim.addBySymbol(animData.name, animData.anim, animData.fps, animData.loop);
wasRefreshed = parent.character.animateAtlas.anim.animsMap.exists(animData.name);
if (!wasRefreshed) __getAnimationSymbol();
} catch (e) {
trace('ERROR REFRESHING SYMBOL FRAMES: $e');
}
validate(wasRefreshed);
}
public function toggleGhost() {
if (valid && parent.ghosts.indexOf(anim) == -1) {
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARACTER_GHOSTENABLE_SOUND));
@@ -521,16 +472,8 @@ class CharacterAnimButton extends UIButton {
return parent.character.animation._animations[anim];
}
public inline function __getAnimationSymbol():Null<FlxSymbolAnimation> @:privateAccess {
if (!parent.character.animateAtlas.anim.animsMap.exists(anim))
XMLUtil.addAnimToSprite(parent.character, data);
return parent.character.animateAtlas.anim.animsMap[anim];
}
@:noCompletion function __refreshAnimation() @:privateAccess {
if (parent.character.animateAtlas != null) refreshSymbolKeyFrames(__getAnimationSymbol(), data);
else refreshFlxAnimationFrames(__getFlxAnimation(), data);
refreshFlxAnimationFrames(__getFlxAnimation(), data);
if (valid) {
parent.buildAnimDisplay(anim, data);
@@ -30,7 +30,7 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
buttonCameras.pixelPerfectRender = true;
if (Assets.exists(Paths.image('characters/${character.sprite}')) && character.animateAtlas == null)
if (Assets.exists(Paths.image('characters/${character.sprite}')))
displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false));
displayWindowSprite = new FlxSprite();
@@ -69,30 +69,16 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
}
public function buildAnimDisplay(name:String, anim:AnimData) @:privateAccess {
if (character.animateAtlas == null) {
var anim:FlxAnimation = character.animation._animations[anim.name];
if (anim == null || anim.frames.length <= 0) return;
var anim:FlxAnimation = character.animation._animations[anim.name];
if (anim == null || anim.frames.length <= 0) return;
var frameIndex:Int = anim.frames.getDefault([0])[0];
var frame:FlxFrame = displayWindowSprite.frames.frames[frameIndex];
var frameIndex:Int = anim.frames.getDefault([0])[0];
var frame:FlxFrame = displayWindowSprite.frames.frames[frameIndex];
var frameRect:Rectangle = new Rectangle(frame.offset.x, frame.offset.y, frame.sourceSize.x, frame.sourceSize.y);
var animBounds:Rectangle = displayWindowGraphic != null ? displayWindowGraphic.bitmap.bounds(frameRect) : frameRect;
var frameRect:Rectangle = new Rectangle(frame.offset.x, frame.offset.y, frame.sourceSize.x, frame.sourceSize.y);
var animBounds:Rectangle = displayWindowGraphic != null ? displayWindowGraphic.bitmap.bounds(frameRect) : frameRect;
displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/Math.max(animBounds.width, animBounds.height), animBounds: animBounds});
} else {
character.storeAtlasState();
/*
character.animateAtlas.anim.play(anim.name, true, false, 0);
character.animateAtlas.anim.stop();
var animBounds:Rectangle = MatrixUtil.getBounds(character).copyToFlash();
displayAnimsFramesList.set(name, {frame: anim.anim, scale: 104/animBounds.height, animBounds: animBounds});
*/
character.restoreAtlasState();
}
displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/Math.max(animBounds.width, animBounds.height), animBounds: animBounds});
}
public function removeAnimDisplay(name:String)
@@ -20,33 +20,19 @@ class CharacterGhost extends Character {
var wasInvalidFrame:Bool = !colorTransform.__isDefault(false);
colorTransform.__identity();
if (animateAtlas != null) {
storeAtlasState();
for (anim in ghosts) {
animateAtlas.anim.play(anim, true, false, 0);
setAnimOffset(anim);
for (anim in ghosts) @:privateAccess {
alpha = 0.4; color = 0xFFAEAEAE;
alpha = 0.4; color = 0xFFAEAEAE;
super.draw();
}
var flxanim:FlxAnimation = animation._animations.get(anim);
var frameIndex:Int = flxanim.frames.getDefault([0])[flxanim.frames.length - 1];
frame = frames.frames[frameIndex];
if (ghosts.length > 0) restoreAtlasState();
setAnimOffset(anim);
super.draw();
}
else {
for (anim in ghosts) @:privateAccess {
alpha = 0.4; color = 0xFFAEAEAE;
var flxanim:FlxAnimation = animation._animations.get(anim);
var frameIndex:Int = flxanim.frames.getDefault([0])[flxanim.frames.length - 1];
frame = frames.frames[frameIndex];
setAnimOffset(anim);
super.draw();
}
if (ghosts.length > 0)
frame = frames.frames[animation.frameIndex];
}
if (ghosts.length > 0)
frame = frames.frames[animation.frameIndex];
ghostDraw = FakeCallCamera.instance.ignoreDraws = false;
alpha = 1; color = 0xFFFFFFFF;
@@ -55,7 +41,7 @@ class CharacterGhost extends Character {
offset.set(globalOffset.x * (isPlayer != playerOffsets ? 1 : -1), -globalOffset.y);
colorTransform.color = 0xFFEF0202;
} else
setAnimOffset(animateAtlas != null ? atlasPlayingAnim : animation.name);
setAnimOffset(animation.name);
super.draw();
}
@@ -71,21 +57,5 @@ class CharacterGhost extends Character {
}
// This gets annoying lmao -lunar
private var atlasState:AtlasState = null;
public function storeAtlasState():AtlasState @:privateAccess {
return atlasState = {
oldAnim: atlasPlayingAnim,
oldFrame: animateAtlas.anim.curFrame,
oldTick: animateAtlas.anim._tick,
oldPlaying: animateAtlas.anim.isPlaying,
};
}
public function restoreAtlasState(state:AtlasState = null) @:privateAccess {
if (state == null) state = atlasState;
animateAtlas.anim.play(state.oldAnim, true, false, state.oldFrame);
animateAtlas.anim._tick = state.oldTick;
animateAtlas.anim.isPlaying = state.oldPlaying;
}
// it's gone now <3 -yosh
}
@@ -1,7 +1,6 @@
package funkin.editors.character;
import funkin.backend.FlxAnimate;
import haxe.io.Path;
import funkin.editors.character.CharacterInfoScreen.CharacterExtraInfo;
import funkin.game.Character;
@@ -188,27 +187,11 @@ class CharacterPropertiesWindow extends UISliceSprite {
if (animsWindow.displayWindowGraphic != null)
animsWindow.displayWindowGraphic.destroy();
if (Assets.exists('$noExt/Animation.json')) {
if (character.animateAtlas == null) {
character.animation.reset();
character.animateAtlas = new FlxAnimate(character.x, character.y);
} else
character.animateAtlas.anim.stop();
character.frames = Paths.getFrames(path, true);
character.atlasPath = noExt;
character.animateAtlas.loadAtlas(noExt);
} else {
if (character.animateAtlas != null) {
character.animateAtlas.destroy();
character.animateAtlas = null;
character.atlasPlayingAnim = character.atlasPath = null;
}
character.frames = Paths.getFrames(path, true);
animsWindow.displayWindowSprite.loadGraphicFromSprite(character);
if (Assets.exists(Paths.image('characters/${character.sprite}')))
animsWindow.displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false));
}
animsWindow.displayWindowSprite.loadGraphicFromSprite(character);
if (Assets.exists(Paths.image('characters/${character.sprite}')))
animsWindow.displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false));
character.animDatas.clear();
for (anim in animsWindow.buttons) anim.checkValid(); // Re-add all animations
+2 -6
View File
@@ -377,9 +377,7 @@ class StageEditor extends UIState {
// Play first anim, and make it the last frame
var animToPlay = char.getAnimOrder()[0];
char.playAnim(animToPlay, true, NONE);
var lastIndx = (char.animateAtlas != null) ?
char.animateAtlas.anim.length - 1 :
char.animation.curAnim.numFrames - 1;
var lastIndx = char.animation.curAnim.numFrames - 1;
char.playAnim(animToPlay, true, NONE, false, lastIndx);
char.stopAnimation();
@@ -565,9 +563,7 @@ class StageEditor extends UIState {
// Play first anim, and make it the last frame
var animToPlay = char.getAnimOrder()[0];
char.playAnim(animToPlay, true, NONE);
var lastIndx = (char.animateAtlas != null) ?
char.animateAtlas.anim.length - 1 :
char.animation.curAnim.numFrames - 1;
var lastIndx = char.animation.curAnim.numFrames - 1;
char.playAnim(animToPlay, true, NONE, false, lastIndx);
char.stopAnimation();
+5 -18
View File
@@ -161,7 +161,6 @@ class HealthIcon extends FunkinSprite
var iconSize:Int = 0;
var iconIsPlayer = xmlValid ? xmlData.get("facing").getDefault("right").toLowerCase() == "left" : false;
animateAtlas = null; // reset
if (this.animated)
loadSprite(Paths.image(newIconPath));
else {
@@ -184,8 +183,6 @@ class HealthIcon extends FunkinSprite
if(!animation.onFinishEnd.has(animFinishCallback))
animation.onFinishEnd.add(animFinishCallback);
if(animateAtlas != null && !animateAtlas.anim.onFinishEnd.has(animFinishCallback))
animateAtlas.anim.onFinishEnd.add(animFinishCallback);
var parsedSteps:Map<Int, String> = [];
@@ -233,10 +230,10 @@ class HealthIcon extends FunkinSprite
offsetY = Std.parseFloat(node.get("offsety")).getDefault(0);
addAnim(animName, node.get("anim"), Std.parseInt(node.get("fps")).getDefault(24), false, null, null, offsetX, offsetY); // don't allow looping for transitions
if (animateAtlas == null && animation.exists(animName))
if (animation.exists(animName))
animation.getByName(animName).flipX = isPlayer != iconIsPlayer;
case "anim":
if (this.animated == false) {
if (!this.animated) {
Logs.trace('Icon ${char} data <anim> is not allowed when not animated', WARNING);
continue;
}
@@ -270,7 +267,7 @@ class HealthIcon extends FunkinSprite
looped = node.get("loop").toLowerCase() == "true";
addAnim(animName, node.get("anim"), Std.parseInt(node.get("fps")).getDefault(24), looped, null, null, offsetX, offsetY);
if (animateAtlas == null && animation.exists(animName))
if (animation.exists(animName))
animation.getByName(animName).flipX = isPlayer != iconIsPlayer;
case "step":
if (!node.exists("percent")) {
@@ -314,18 +311,8 @@ class HealthIcon extends FunkinSprite
curAnimState = data.animState;
}
if (animateAtlas != null) {
@:bypassAccessor
frameWidth = 150;
@:bypassAccessor
frameHeight = 150;
extraOffsets.x -= frameWidth / 2;
extraOffsets.y -= frameHeight / 2;
updateHitbox();
} else {
setGraphicSize(150);
updateHitbox();
}
setGraphicSize(150);
updateHitbox();
defaultScale = (xmlValid && xmlData.exists("scale")) ? Std.parseFloat(xmlData.get("scale")).getDefault(scale.x) : scale.x;
scale.set(defaultScale, defaultScale);
-4
View File
@@ -20,8 +20,6 @@ class Splash extends FunkinSprite
@:privateAccess {
spr.setPosition(source.x, source.y);
spr.frames = source.frames;
if (source.animateAtlas != null && source.atlasPath != null)
spr.loadSprite(source.atlasPath);
spr.animation.copyFrom(source.animation);
spr.visible = source.visible;
spr.alpha = source.alpha;
@@ -29,8 +27,6 @@ class Splash extends FunkinSprite
spr.scale.set(source.scale.x, source.scale.y);
spr.scrollFactor.set(source.scrollFactor.x, source.scrollFactor.y);
spr.skew.set(source.skew.x, source.skew.y);
spr.transformMatrix = source.transformMatrix;
spr.matrixExposed = source.matrixExposed;
spr.zoomFactor = source.zoomFactor;
spr.animOffsets = source.animOffsets.copy();
}