1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2025-09-05 05:07:39 +00:00

Compare commits

...

1 commit

Author SHA1 Message Date
Abnormal c1c5c5bcb2 FunkinSprite overhaul 2025-05-04 03:32:11 +00:00
15 changed files with 207 additions and 227 deletions

View file

@ -48,7 +48,8 @@ class FunkTrail extends FlxTrail
{ {
var targ:Bopper = cast target; var targ:Bopper = cast target;
@:privateAccess @:privateAccess
frameOffset.set((targ.animOffsets[0] - targ.globalOffsets[0]) * targ.scale.x, (targ.animOffsets[1] - targ.globalOffsets[1]) * targ.scale.y); frameOffset.set((targ.currentAnimationOffsets[0] - targ.globalOffsets[0]) * targ.scale.x,
(targ.currentAnimationOffsets[1] - targ.globalOffsets[1]) * targ.scale.y);
_recentPositions[0]?.subtract(frameOffset.x, frameOffset.y); _recentPositions[0]?.subtract(frameOffset.x, frameOffset.y);
} }

View file

@ -0,0 +1,30 @@
package funkin.graphics;
import funkin.graphics.FunkinSprite;
import flixel.animation.FlxAnimationController;
/**
* A version of `FlxAnimationController` that has custom offsets support.
*/
class FunkinAnimationController extends FlxAnimationController
{
/**
* The sprite that this animation controller is attached to.
*/
var _parentSprite:FunkinSprite;
public function new(sprite:FunkinSprite)
{
super(sprite);
_parentSprite = sprite;
}
/**
* We override `FlxAnimationController`'s `play` method to account for animation offsets.
*/
public override function play(animName:String, force = false, reversed = false, frame = 0):Void
{
_parentSprite.applyAnimationOffsets(animName);
super.play(animName, force, reversed, frame);
}
}

View file

@ -10,6 +10,7 @@ import openfl.display.BitmapData;
import flixel.math.FlxRect; import flixel.math.FlxRect;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.graphics.frames.FlxFrame.FlxFrameAngle; import flixel.graphics.frames.FlxFrame.FlxFrameAngle;
import funkin.graphics.FunkinAnimationController;
import flixel.FlxCamera; import flixel.FlxCamera;
/** /**
@ -31,6 +32,46 @@ class FunkinSprite extends FlxSprite
*/ */
static var previousCachedTextures:Map<String, FlxGraphic> = []; static var previousCachedTextures:Map<String, FlxGraphic> = [];
/**
* A map of offsets for each animation.
*/
public var animationOffsets:Map<String, Array<Float>> = new Map<String, Array<Float>>();
/**
* The current animation offset being used.
*/
public var currentAnimationOffsets(default, set):Array<Float> = [0, 0];
/**
* Sets the current animation offset.
* Override this in your class if you want to handle animation offsets differently.
*/
function set_currentAnimationOffsets(value:Array<Float>):Array<Float>
{
if (currentAnimationOffsets == null) currentAnimationOffsets = [0, 0];
if (value == null) value = [0, 0];
if ((currentAnimationOffsets[0] == value[0]) && (currentAnimationOffsets[1] == value[1])) return value;
return currentAnimationOffsets = value;
}
/**
* The offset of the sprite overall.
*/
public var globalOffsets(default, set):Array<Float> = [0, 0];
/**
* Sets the global offset.
* Override this in your class if you want to handle global offsets differently.
*/
function set_globalOffsets(value:Array<Float>):Array<Float>
{
if (globalOffsets == null) globalOffsets = [0, 0];
if (globalOffsets == value) return value;
return globalOffsets = value;
}
/** /**
* @param x Starting X position * @param x Starting X position
* @param y Starting Y position * @param y Starting Y position
@ -38,6 +79,16 @@ class FunkinSprite extends FlxSprite
public function new(?x:Float = 0, ?y:Float = 0) public function new(?x:Float = 0, ?y:Float = 0)
{ {
super(x, y); super(x, y);
globalOffsets = [x, y];
}
override function initVars():Void
{
super.initVars();
// We replace `FlxSprite`'s default animation controller with our own to handle offsets.
animation.destroy();
animation = new FunkinAnimationController(this);
} }
/** /**
@ -237,17 +288,59 @@ class FunkinSprite extends FlxSprite
} }
} }
/**
* Ensures the sparrow atlas with the given key is cached.
* @param key The key of the sparrow atlas to cache.
*/
public static function cacheSparrow(key:String):Void public static function cacheSparrow(key:String):Void
{ {
cacheTexture(Paths.image(key)); cacheTexture(Paths.image(key));
} }
/**
* Ensures the packer atlas with the given key is cached.
* @param key The key of the packer atlas to cache.
*/
public static function cachePacker(key:String):Void public static function cachePacker(key:String):Void
{ {
cacheTexture(Paths.image(key)); cacheTexture(Paths.image(key));
} }
/** /**
* Applies the offsets for a specific animation.
* @param animName The animation name.
*/
public function applyAnimationOffsets(animName:String):Void
{
var offsets = animationOffsets.get(animName);
this.currentAnimationOffsets = offsets;
}
/**
* Define the animation offsets for a specific animation.
* @param name The animation name.
* @param xOffset The x offset.
* @param yOffset The y offset.
*/
public function setAnimationOffsets(name:String, xOffset:Float, yOffset:Float):Void
{
animationOffsets.set(name, [xOffset, yOffset]);
}
/**
* Set the sprite scale to the appropriate value.
* @param scale
*/
public function setScale(scale:Null<Float>):Void
{
if (scale == null) scale = 1.0;
this.scale.x = scale;
this.scale.y = scale;
this.updateHitbox();
}
/**
* Prepares the sprite cache for purging.
* Call this, then `cacheTexture` to keep the textures we still need, then `purgeCache` to remove the textures that we won't be using anymore. * Call this, then `cacheTexture` to keep the textures we still need, then `purgeCache` to remove the textures that we won't be using anymore.
*/ */
public static function preparePurgeCache():Void public static function preparePurgeCache():Void
@ -256,6 +349,9 @@ class FunkinSprite extends FlxSprite
currentCachedTextures = []; currentCachedTextures = [];
} }
/**
* Purges the old sprite cache.
*/
public static function purgeCache():Void public static function purgeCache():Void
{ {
// Everything that is in previousCachedTextures but not in currentCachedTextures should be destroyed. // Everything that is in previousCachedTextures but not in currentCachedTextures should be destroyed.
@ -269,6 +365,11 @@ class FunkinSprite extends FlxSprite
} }
} }
/**
* Whether or not the given graphic is cached.
* @param graphic The graphic to check.
* @return Bool
*/
static function isGraphicCached(graphic:FlxGraphic):Bool static function isGraphicCached(graphic:FlxGraphic):Bool
{ {
if (graphic == null) return false; if (graphic == null) return false;
@ -283,6 +384,7 @@ class FunkinSprite extends FlxSprite
} }
/** /**
* Whether or not the given animation is dynamic (has multiple frames).
* @param id The animation ID to check. * @param id The animation ID to check.
* @return Whether the animation is dynamic (has multiple frames). `false` for static, one-frame animations. * @return Whether the animation is dynamic (has multiple frames). `false` for static, one-frame animations.
*/ */
@ -294,6 +396,37 @@ class FunkinSprite extends FlxSprite
return animData.numFrames > 1; return animData.numFrames > 1;
} }
/**
* Checks whether or not the given animation exists for this sprite.
* @param id The name of the animation to check for.
* @return Whether this sprite posesses the given animation.
* Only true if the animation was successfully loaded from the XML.
*/
public function hasAnimation(id:String):Bool
{
if (this.animation == null) return false;
return this.animation.getByName(id) != null;
}
/**
* Returns the name of the animation that is currently playing.
* If no animation is playing (usually this means the sprite is BROKEN!),
* returns an empty string to prevent NPEs.
*/
public function getCurrentAnimation():String
{
return this.animation?.curAnim?.name ?? "";
}
/**
* Whether the current animation has finished playing.
*/
public function isAnimationFinished():Bool
{
return this.animation?.finished ?? false;
}
/** /**
* Acts similarly to `makeGraphic`, but with improved memory usage, * Acts similarly to `makeGraphic`, but with improved memory usage,
* at the expense of not being able to paint onto the resulting sprite. * at the expense of not being able to paint onto the resulting sprite.
@ -367,6 +500,10 @@ class FunkinSprite extends FlxSprite
if (camera == null) camera = FlxG.camera; if (camera == null) camera = FlxG.camera;
result.set(x, y); result.set(x, y);
result.x -= currentAnimationOffsets[0];
result.y -= currentAnimationOffsets[1];
if (pixelPerfectPosition) if (pixelPerfectPosition)
{ {
_rect.width = _rect.width / this.scale.x; _rect.width = _rect.width / this.scale.x;

View file

@ -250,14 +250,10 @@ class BaseCharacter extends Bopper
* Set the character's sprite scale to the appropriate value. * Set the character's sprite scale to the appropriate value.
* @param scale The desired scale. * @param scale The desired scale.
*/ */
public function setScale(scale:Null<Float>):Void public override function setScale(scale:Null<Float>):Void
{ {
if (scale == null) scale = 1.0; super.setScale(scale);
var feetPos:FlxPoint = feetPosition; var feetPos:FlxPoint = feetPosition;
this.scale.x = scale;
this.scale.y = scale;
this.updateHitbox();
// Reposition with newly scaled sprite. // Reposition with newly scaled sprite.
this.x = feetPos.x - characterOrigin.x + globalOffsets[0]; this.x = feetPos.x - characterOrigin.x + globalOffsets[0];
this.y = feetPos.y - characterOrigin.y + globalOffsets[1]; this.y = feetPos.y - characterOrigin.y + globalOffsets[1];

View file

@ -114,7 +114,7 @@ class MultiSparrowCharacter extends BaseCharacter
if (anim.offsets == null) if (anim.offsets == null)
{ {
setAnimationOffsets(anim.name, 0, 0); setAnimationOffsets(anim.name, 0.0, 0.0);
} }
else else
{ {

View file

@ -71,7 +71,7 @@ class SparrowCharacter extends BaseCharacter
{ {
if (anim.offsets == null) if (anim.offsets == null)
{ {
setAnimationOffsets(anim.name, 0, 0); setAnimationOffsets(anim.name, 0.0, 0.0);
} }
else else
{ {

View file

@ -450,35 +450,6 @@ class HealthIcon extends FunkinSprite
this.antialiasing = !isPixel; this.antialiasing = !isPixel;
} }
/**
* @return Name of the current animation being played by this health icon.
*/
public function getCurrentAnimation():String
{
if (this.animation == null || this.animation.curAnim == null) return "";
return this.animation.curAnim.name;
}
/**
* @param id The name of the animation to check for.
* @return Whether this sprite posesses the given animation.
* Only true if the animation was successfully loaded from the XML.
*/
public function hasAnimation(id:String):Bool
{
if (this.animation == null) return false;
return this.animation.getByName(id) != null;
}
/**
* @return Whether the current animation is in the finished state.
*/
public function isAnimationFinished():Bool
{
return this.animation.finished;
}
/** /**
* Plays the animation with the given name. * Plays the animation with the given name.
* @param name The name of the animation to play. * @param name The name of the animation to play.

View file

@ -122,7 +122,7 @@ class DialogueBox extends FlxSpriteGroup implements IDialogueScriptedClass imple
this.boxSprite = null; this.boxSprite = null;
} }
this.boxSprite = new FunkinSprite(0, 0); this.boxSprite = new FlxSprite(0, 0);
trace('[DIALOGUE BOX] Loading spritesheet ${_data.assetPath} for ${id}'); trace('[DIALOGUE BOX] Loading spritesheet ${_data.assetPath} for ${id}');

View file

@ -1,6 +1,6 @@
package funkin.play.cutscene.dialogue; package funkin.play.cutscene.dialogue;
import flixel.FlxSprite; import funkin.graphics.FunkinSprite;
import funkin.data.IRegistryEntry; import funkin.data.IRegistryEntry;
import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEvent;
import flixel.graphics.frames.FlxFramesCollection; import flixel.graphics.frames.FlxFramesCollection;
@ -14,7 +14,7 @@ import funkin.data.dialogue.speaker.SpeakerRegistry;
* *
* Most conversations have two speakers, with one being flipped. * Most conversations have two speakers, with one being flipped.
*/ */
class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRegistryEntry<SpeakerData> class Speaker extends FunkinSprite implements IDialogueScriptedClass implements IRegistryEntry<SpeakerData>
{ {
/** /**
* A readable name for this speaker. * A readable name for this speaker.
@ -26,36 +26,21 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
return _data.name; return _data.name;
} }
/** override function set_currentAnimationOffsets(value:Array<Float>):Array<Float>
* Offset the speaker's sprite by this much when playing each animation.
*/
var animationOffsets:Map<String, Array<Float>> = new Map<String, Array<Float>>();
/**
* The current animation offset being used.
*/
var animOffsets(default, set):Array<Float> = [0, 0];
function set_animOffsets(value:Array<Float>):Array<Float>
{ {
if (animOffsets == null) animOffsets = [0, 0]; if (currentAnimationOffsets == null) currentAnimationOffsets = [0, 0];
if ((animOffsets[0] == value[0]) && (animOffsets[1] == value[1])) return value; if ((currentAnimationOffsets[0] == value[0]) && (currentAnimationOffsets[1] == value[1])) return value;
var xDiff:Float = value[0] - animOffsets[0]; var xDiff:Float = value[0] - currentAnimationOffsets[0];
var yDiff:Float = value[1] - animOffsets[1]; var yDiff:Float = value[1] - currentAnimationOffsets[1];
this.x += xDiff; this.x += xDiff;
this.y += yDiff; this.y += yDiff;
return animOffsets = value; return currentAnimationOffsets = value;
} }
/** override function set_globalOffsets(value:Array<Float>):Array<Float>
* The offset of the speaker overall.
*/
public var globalOffsets(default, set):Array<Float> = [0, 0];
function set_globalOffsets(value:Array<Float>):Array<Float>
{ {
if (globalOffsets == null) globalOffsets = [0, 0]; if (globalOffsets == null) globalOffsets = [0, 0];
if (globalOffsets == value) return value; if (globalOffsets == value) return value;
@ -144,18 +129,6 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
this.setScale(_data.scale); this.setScale(_data.scale);
} }
/**
* Set the sprite scale to the appropriate value.
* @param scale
*/
public function setScale(scale:Null<Float>):Void
{
if (scale == null) scale = 1.0;
this.scale.x = scale;
this.scale.y = scale;
this.updateHitbox();
}
function loadAnimations():Void function loadAnimations():Void
{ {
trace('[SPEAKER] Loading ${_data.animations.length} animations for ${id}'); trace('[SPEAKER] Loading ${_data.animations.length} animations for ${id}');
@ -166,7 +139,7 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
{ {
if (anim.offsets == null) if (anim.offsets == null)
{ {
setAnimationOffsets(anim.name, 0, 0); setAnimationOffsets(anim.name, 0.0, 0.0);
} }
else else
{ {
@ -188,14 +161,6 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
if (correctName == null) return; if (correctName == null) return;
this.animation.play(correctName, restart, false, 0); this.animation.play(correctName, restart, false, 0);
applyAnimationOffsets(correctName);
}
public function getCurrentAnimation():String
{
if (this.animation == null || this.animation.curAnim == null) return "";
return this.animation.curAnim.name;
} }
/** /**
@ -232,37 +197,6 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
} }
} }
public function hasAnimation(id:String):Bool
{
if (this.animation == null) return false;
return this.animation.getByName(id) != null;
}
/**
* Define the animation offsets for a specific animation.
*/
public function setAnimationOffsets(name:String, xOffset:Float, yOffset:Float):Void
{
animationOffsets.set(name, [xOffset, yOffset]);
}
/**
* Retrieve an apply the animation offsets for a specific animation.
*/
function applyAnimationOffsets(name:String):Void
{
var offsets:Array<Float> = animationOffsets.get(name);
if (offsets != null && !(offsets[0] == 0 && offsets[1] == 0))
{
this.animOffsets = offsets;
}
else
{
this.animOffsets = [0, 0];
}
}
public function onDialogueStart(event:DialogueScriptEvent):Void {} public function onDialogueStart(event:DialogueScriptEvent):Void {}
public function onDialogueCompleteLine(event:DialogueScriptEvent):Void {} public function onDialogueCompleteLine(event:DialogueScriptEvent):Void {}

View file

@ -172,22 +172,6 @@ class StrumlineNote extends FunkinSprite
} }
} }
/**
* Returns the name of the animation that is currently playing.
* If no animation is playing (usually this means the sprite is BROKEN!),
* returns an empty string to prevent NPEs.
*/
public function getCurrentAnimation():String
{
if (this.animation == null || this.animation.curAnim == null) return "";
return this.animation.curAnim.name;
}
public function isAnimationFinished():Bool
{
return this.animation.finished;
}
static final DEFAULT_OFFSET:Int = 13; static final DEFAULT_OFFSET:Int = 13;
/** /**

View file

@ -32,11 +32,6 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
*/ */
public var shouldAlternate:Null<Bool> = null; public var shouldAlternate:Null<Bool> = null;
/**
* Offset the character's sprite by this much when playing each animation.
*/
public var animationOffsets:Map<String, Array<Float>> = new Map<String, Array<Float>>();
/** /**
* Add a suffix to the `idle` animation (or `danceLeft` and `danceRight` animations) * Add a suffix to the `idle` animation (or `danceLeft` and `danceRight` animations)
* that this bopper will play. * that this bopper will play.
@ -68,32 +63,8 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
return value; return value;
} }
/**
* The offset of the character relative to the position specified by the stage.
*/
public var globalOffsets(default, set):Array<Float> = [0, 0];
function set_globalOffsets(value:Array<Float>):Array<Float>
{
if (globalOffsets == null) globalOffsets = [0, 0];
if (globalOffsets == value) return value;
return globalOffsets = value;
}
@:allow(funkin.ui.debug.anim.DebugBoundingState)
var animOffsets(default, set):Array<Float> = [0, 0];
public var originalPosition:FlxPoint = new FlxPoint(0, 0); public var originalPosition:FlxPoint = new FlxPoint(0, 0);
function set_animOffsets(value:Array<Float>):Array<Float>
{
if (animOffsets == null) animOffsets = [0, 0];
if ((animOffsets[0] == value[0]) && (animOffsets[1] == value[1])) return value;
return animOffsets = value;
}
/** /**
* Whether to play `danceRight` next iteration. * Whether to play `danceRight` next iteration.
* Only used when `shouldAlternate` is true. * Only used when `shouldAlternate` is true.
@ -203,13 +174,6 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
} }
} }
public function hasAnimation(id:String):Bool
{
if (this.animation == null) return false;
return this.animation.getByName(id) != null;
}
/** /**
* Ensure that a given animation exists before playing it. * Ensure that a given animation exists before playing it.
* Will gracefully check for name, then name with stripped suffixes, then fail to play. * Will gracefully check for name, then name with stripped suffixes, then fail to play.
@ -293,8 +257,6 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
{ {
canPlayOtherAnims = false; canPlayOtherAnims = false;
} }
applyAnimationOffsets(correctName);
} }
var forceAnimationTimer:FlxTimer = new FlxTimer(); var forceAnimationTimer:FlxTimer = new FlxTimer();
@ -313,7 +275,6 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
if (correctName == null) return; if (correctName == null) return;
this.animation.play(correctName, false, false); this.animation.play(correctName, false, false);
applyAnimationOffsets(correctName);
canPlayOtherAnims = false; canPlayOtherAnims = false;
forceAnimationTimer.start(duration, (timer) -> { forceAnimationTimer.start(duration, (timer) -> {
@ -321,40 +282,18 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
}, 1); }, 1);
} }
function applyAnimationOffsets(name:String):Void
{
var offsets = animationOffsets.get(name);
this.animOffsets = offsets;
}
public function isAnimationFinished():Bool
{
return this.animation?.finished ?? false;
}
public function setAnimationOffsets(name:String, xOffset:Float, yOffset:Float):Void
{
animationOffsets.set(name, [xOffset, yOffset]);
}
/**
* Returns the name of the animation that is currently playing.
* If no animation is playing (usually this means the character is BROKEN!),
* returns an empty string to prevent NPEs.
*/
public function getCurrentAnimation():String
{
if (this.animation == null || this.animation.curAnim == null) return "";
return this.animation.curAnim.name;
}
// override getScreenPosition (used by FlxSprite's draw method) to account for animation offsets. // override getScreenPosition (used by FlxSprite's draw method) to account for animation offsets.
override function getScreenPosition(?result:FlxPoint, ?camera:FlxCamera):FlxPoint override function getScreenPosition(?result:FlxPoint, ?camera:FlxCamera):FlxPoint
{ {
var output:FlxPoint = super.getScreenPosition(result, camera); if (result == null) result = FlxPoint.get();
output.x -= (animOffsets[0] - globalOffsets[0]) * this.scale.x;
output.y -= (animOffsets[1] - globalOffsets[1]) * this.scale.y; if (camera == null) camera = getDefaultCamera();
return output;
result.set(x, y);
result.x -= (currentAnimationOffsets[0] - globalOffsets[0]) * this.scale.x;
result.y -= (currentAnimationOffsets[1] - globalOffsets[1]) * this.scale.y;
return result.subtract(camera.scroll.x * scrollFactor.x, camera.scroll.y * scrollFactor.y);
} }
public function onPause(event:PauseScriptEvent) {} public function onPause(event:PauseScriptEvent) {}

View file

@ -214,18 +214,18 @@ class DebugBoundingState extends FlxState
if (FlxG.mouse.justPressed && !haxeUIFocused) if (FlxG.mouse.justPressed && !haxeUIFocused)
{ {
movingCharacter = true; movingCharacter = true;
mouseOffset.set(FlxG.mouse.x - -swagChar.animOffsets[0], FlxG.mouse.y - -swagChar.animOffsets[1]); mouseOffset.set(FlxG.mouse.x - -swagChar.currentAnimationOffsets[0], FlxG.mouse.y - -swagChar.currentAnimationOffsets[1]);
} }
if (!movingCharacter) return; if (!movingCharacter) return;
if (FlxG.mouse.pressed) if (FlxG.mouse.pressed)
{ {
swagChar.animOffsets = [(FlxG.mouse.x - mouseOffset.x) * -1, (FlxG.mouse.y - mouseOffset.y) * -1]; swagChar.currentAnimationOffsets = [(FlxG.mouse.x - mouseOffset.x) * -1, (FlxG.mouse.y - mouseOffset.y) * -1];
swagChar.animationOffsets.set(offsetAnimationDropdown.value.id, swagChar.animOffsets); swagChar.animationOffsets.set(offsetAnimationDropdown.value.id, swagChar.currentAnimationOffsets);
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets; txtOffsetShit.text = 'Offset: ' + swagChar.currentAnimationOffsets;
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height; txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
} }
@ -535,7 +535,7 @@ class DebugBoundingState extends FlxState
} }
} }
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets; txtOffsetShit.text = 'Offset: ' + swagChar.currentAnimationOffsets;
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height; txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
dropDownSetup = true; dropDownSetup = true;
} }
@ -558,7 +558,7 @@ class DebugBoundingState extends FlxState
swagChar.playAnimation(animName, true); // trace(); swagChar.playAnimation(animName, true); // trace();
trace(swagChar.animationOffsets.get(animName)); trace(swagChar.animationOffsets.get(animName));
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets; txtOffsetShit.text = 'Offset: ' + swagChar.currentAnimationOffsets;
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height; txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
} }

View file

@ -177,10 +177,10 @@ class CharacterPlayer extends Box
character.y = this.cachedScreenY; character.y = this.cachedScreenY;
// Apply animation offsets, so the character is positioned correctly based on the animation. // Apply animation offsets, so the character is positioned correctly based on the animation.
@:privateAccess var animOffsets:Array<Float> = character.animOffsets; @:privateAccess var currentAnimationOffsets:Array<Float> = character.currentAnimationOffsets;
character.x -= animOffsets[0] * targetScale * (flip ? -1 : 1); character.x -= currentAnimationOffsets[0] * targetScale * (flip ? -1 : 1);
character.y -= animOffsets[1] * targetScale; character.y -= currentAnimationOffsets[1] * targetScale;
} }
/** /**

View file

@ -211,7 +211,7 @@ class PreferencesMenu extends Page<OptionsState.OptionsMenuPageName>
*/ */
function createPrefItemCheckbox(prefName:String, prefDesc:String, onChange:Bool->Void, defaultValue:Bool):Void function createPrefItemCheckbox(prefName:String, prefDesc:String, onChange:Bool->Void, defaultValue:Bool):Void
{ {
var checkbox:CheckboxPreferenceItem = new CheckboxPreferenceItem(0, 120 * (items.length - 1 + 1), defaultValue); var checkbox:CheckboxPreferenceItem = new CheckboxPreferenceItem(25, (120 * (items.length - 1 + 1)) + 35, defaultValue);
items.createItem(0, (120 * items.length) + 30, prefName, AtlasFont.BOLD, function() { items.createItem(0, (120 * items.length) + 30, prefName, AtlasFont.BOLD, function() {
var value = !checkbox.currentValue; var value = !checkbox.currentValue;

View file

@ -1,8 +1,8 @@
package funkin.ui.options.items; package funkin.ui.options.items;
import flixel.FlxSprite.FlxSprite; import funkin.graphics.FunkinSprite;
class CheckboxPreferenceItem extends FlxSprite class CheckboxPreferenceItem extends FunkinSprite
{ {
public var currentValue(default, set):Bool; public var currentValue(default, set):Bool;
@ -10,9 +10,10 @@ class CheckboxPreferenceItem extends FlxSprite
{ {
super(x, y); super(x, y);
frames = Paths.getSparrowAtlas('checkboxThingie'); loadSparrow('checkboxThingie');
animation.addByPrefix('static', 'Check Box unselected', 24, false); animation.addByPrefix('static', 'Check Box unselected', 24, false);
animation.addByPrefix('checked', 'Check Box selecting animation', 24, false); animation.addByPrefix('checked', 'Check Box selecting animation', 24, false);
setAnimationOffsets('checked', 17, 70);
setGraphicSize(Std.int(width * 0.7)); setGraphicSize(Std.int(width * 0.7));
updateHitbox(); updateHitbox();
@ -20,19 +21,6 @@ class CheckboxPreferenceItem extends FlxSprite
this.currentValue = defaultValue; this.currentValue = defaultValue;
} }
override function update(elapsed:Float):Void
{
super.update(elapsed);
switch (animation.curAnim.name)
{
case 'static':
offset.set();
case 'checked':
offset.set(17, 70);
}
}
function set_currentValue(value:Bool):Bool function set_currentValue(value:Bool):Bool
{ {
if (value) if (value)