mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2025-04-12 06:54:41 -04:00
FunkinSprite
overhaul
This commit is contained in:
parent
d31ef12363
commit
b7d132151f
15 changed files with 207 additions and 227 deletions
source/funkin
effects
graphics
play
character
components
cutscene/dialogue
notes
stage
ui
debug/anim
haxeui/components
options
|
@ -47,7 +47,8 @@ class FunkTrail extends FlxTrail
|
|||
{
|
||||
var targ:Bopper = cast target;
|
||||
@: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);
|
||||
}
|
||||
|
|
30
source/funkin/graphics/FunkinAnimationController.hx
Normal file
30
source/funkin/graphics/FunkinAnimationController.hx
Normal 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);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import openfl.display.BitmapData;
|
|||
import flixel.math.FlxRect;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.graphics.frames.FlxFrame.FlxFrameAngle;
|
||||
import funkin.graphics.FunkinAnimationController;
|
||||
import flixel.FlxCamera;
|
||||
|
||||
/**
|
||||
|
@ -31,6 +32,46 @@ class FunkinSprite extends FlxSprite
|
|||
*/
|
||||
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 y Starting Y position
|
||||
|
@ -38,6 +79,16 @@ class FunkinSprite extends FlxSprite
|
|||
public function new(?x:Float = 0, ?y:Float = 0)
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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.
|
||||
*/
|
||||
public static function preparePurgeCache():Void
|
||||
|
@ -256,6 +349,9 @@ class FunkinSprite extends FlxSprite
|
|||
currentCachedTextures = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges the old sprite cache.
|
||||
*/
|
||||
public static function purgeCache():Void
|
||||
{
|
||||
// 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
|
||||
{
|
||||
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.
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
* 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;
|
||||
|
||||
result.set(x, y);
|
||||
|
||||
result.x -= currentAnimationOffsets[0];
|
||||
result.y -= currentAnimationOffsets[1];
|
||||
|
||||
if (pixelPerfectPosition)
|
||||
{
|
||||
_rect.width = _rect.width / this.scale.x;
|
||||
|
|
|
@ -250,14 +250,10 @@ class BaseCharacter extends Bopper
|
|||
* Set the character's sprite scale to the appropriate value.
|
||||
* @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;
|
||||
this.scale.x = scale;
|
||||
this.scale.y = scale;
|
||||
this.updateHitbox();
|
||||
// Reposition with newly scaled sprite.
|
||||
this.x = feetPos.x - characterOrigin.x + globalOffsets[0];
|
||||
this.y = feetPos.y - characterOrigin.y + globalOffsets[1];
|
||||
|
|
|
@ -114,7 +114,7 @@ class MultiSparrowCharacter extends BaseCharacter
|
|||
|
||||
if (anim.offsets == null)
|
||||
{
|
||||
setAnimationOffsets(anim.name, 0, 0);
|
||||
setAnimationOffsets(anim.name, 0.0, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -71,7 +71,7 @@ class SparrowCharacter extends BaseCharacter
|
|||
{
|
||||
if (anim.offsets == null)
|
||||
{
|
||||
setAnimationOffsets(anim.name, 0, 0);
|
||||
setAnimationOffsets(anim.name, 0.0, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -450,35 +450,6 @@ class HealthIcon extends FunkinSprite
|
|||
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.
|
||||
* @param name The name of the animation to play.
|
||||
|
|
|
@ -126,7 +126,7 @@ class DialogueBox extends FlxSpriteGroup implements IDialogueScriptedClass imple
|
|||
this.boxSprite = null;
|
||||
}
|
||||
|
||||
this.boxSprite = new FunkinSprite(0, 0);
|
||||
this.boxSprite = new FlxSprite(0, 0);
|
||||
|
||||
trace('[DIALOGUE BOX] Loading spritesheet ${_data.assetPath} for ${id}');
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package funkin.play.cutscene.dialogue;
|
||||
|
||||
import flixel.FlxSprite;
|
||||
import funkin.graphics.FunkinSprite;
|
||||
import funkin.data.IRegistryEntry;
|
||||
import funkin.modding.events.ScriptEvent;
|
||||
import flixel.graphics.frames.FlxFramesCollection;
|
||||
|
@ -14,7 +14,7 @@ import funkin.data.dialogue.speaker.SpeakerRegistry;
|
|||
*
|
||||
* 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>
|
||||
{
|
||||
/**
|
||||
* The internal ID for this speaker.
|
||||
|
@ -36,36 +36,21 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
|
|||
return _data.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
override function set_currentAnimationOffsets(value:Array<Float>):Array<Float>
|
||||
{
|
||||
if (animOffsets == null) animOffsets = [0, 0];
|
||||
if ((animOffsets[0] == value[0]) && (animOffsets[1] == value[1])) return value;
|
||||
if (currentAnimationOffsets == null) currentAnimationOffsets = [0, 0];
|
||||
if ((currentAnimationOffsets[0] == value[0]) && (currentAnimationOffsets[1] == value[1])) return value;
|
||||
|
||||
var xDiff:Float = value[0] - animOffsets[0];
|
||||
var yDiff:Float = value[1] - animOffsets[1];
|
||||
var xDiff:Float = value[0] - currentAnimationOffsets[0];
|
||||
var yDiff:Float = value[1] - currentAnimationOffsets[1];
|
||||
|
||||
this.x += xDiff;
|
||||
this.y += yDiff;
|
||||
|
||||
return animOffsets = value;
|
||||
return currentAnimationOffsets = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The offset of the speaker overall.
|
||||
*/
|
||||
public var globalOffsets(default, set):Array<Float> = [0, 0];
|
||||
|
||||
function set_globalOffsets(value:Array<Float>):Array<Float>
|
||||
override function set_globalOffsets(value:Array<Float>):Array<Float>
|
||||
{
|
||||
if (globalOffsets == null) globalOffsets = [0, 0];
|
||||
if (globalOffsets == value) return value;
|
||||
|
@ -154,18 +139,6 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
|
|||
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
|
||||
{
|
||||
trace('[SPEAKER] Loading ${_data.animations.length} animations for ${id}');
|
||||
|
@ -176,7 +149,7 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
|
|||
{
|
||||
if (anim.offsets == null)
|
||||
{
|
||||
setAnimationOffsets(anim.name, 0, 0);
|
||||
setAnimationOffsets(anim.name, 0.0, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -198,14 +171,6 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe
|
|||
if (correctName == null) return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,37 +207,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 onDialogueCompleteLine(event:DialogueScriptEvent):Void {}
|
||||
|
|
|
@ -167,22 +167,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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,11 +32,6 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
|
|||
*/
|
||||
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)
|
||||
* that this bopper will play.
|
||||
|
@ -68,32 +63,8 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
|
|||
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);
|
||||
|
||||
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.
|
||||
* 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.
|
||||
* 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;
|
||||
}
|
||||
|
||||
applyAnimationOffsets(correctName);
|
||||
}
|
||||
|
||||
var forceAnimationTimer:FlxTimer = new FlxTimer();
|
||||
|
@ -313,7 +275,6 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
|
|||
if (correctName == null) return;
|
||||
|
||||
this.animation.play(correctName, false, false);
|
||||
applyAnimationOffsets(correctName);
|
||||
|
||||
canPlayOtherAnims = false;
|
||||
forceAnimationTimer.start(duration, (timer) -> {
|
||||
|
@ -321,40 +282,18 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
|
|||
}, 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 function getScreenPosition(?result:FlxPoint, ?camera:FlxCamera):FlxPoint
|
||||
{
|
||||
var output:FlxPoint = super.getScreenPosition(result, camera);
|
||||
output.x -= (animOffsets[0] - globalOffsets[0]) * this.scale.x;
|
||||
output.y -= (animOffsets[1] - globalOffsets[1]) * this.scale.y;
|
||||
return output;
|
||||
if (result == null) result = FlxPoint.get();
|
||||
|
||||
if (camera == null) camera = getDefaultCamera();
|
||||
|
||||
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) {}
|
||||
|
|
|
@ -214,18 +214,18 @@ class DebugBoundingState extends FlxState
|
|||
if (FlxG.mouse.justPressed && !haxeUIFocused)
|
||||
{
|
||||
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 (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;
|
||||
}
|
||||
|
||||
|
@ -532,7 +532,7 @@ class DebugBoundingState extends FlxState
|
|||
playCharacterAnimation(event.data.id, true);
|
||||
}
|
||||
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets;
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.currentAnimationOffsets;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
dropDownSetup = true;
|
||||
}
|
||||
|
@ -555,7 +555,7 @@ class DebugBoundingState extends FlxState
|
|||
swagChar.playAnimation(animName, true); // trace();
|
||||
trace(swagChar.animationOffsets.get(animName));
|
||||
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets;
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.currentAnimationOffsets;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
}
|
||||
|
||||
|
|
|
@ -180,10 +180,10 @@ class CharacterPlayer extends Box
|
|||
character.y = this.cachedScreenY;
|
||||
|
||||
// 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.y -= animOffsets[1] * targetScale;
|
||||
character.x -= currentAnimationOffsets[0] * targetScale * (flip ? -1 : 1);
|
||||
character.y -= currentAnimationOffsets[1] * targetScale;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -187,7 +187,7 @@ class PreferencesMenu extends Page<OptionsState.OptionsMenuPageName>
|
|||
*/
|
||||
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() {
|
||||
var value = !checkbox.currentValue;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
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;
|
||||
|
||||
|
@ -10,9 +10,10 @@ class CheckboxPreferenceItem extends FlxSprite
|
|||
{
|
||||
super(x, y);
|
||||
|
||||
frames = Paths.getSparrowAtlas('checkboxThingie');
|
||||
loadSparrow('checkboxThingie');
|
||||
animation.addByPrefix('static', 'Check Box unselected', 24, false);
|
||||
animation.addByPrefix('checked', 'Check Box selecting animation', 24, false);
|
||||
setAnimationOffsets('checked', 17, 70);
|
||||
|
||||
setGraphicSize(Std.int(width * 0.7));
|
||||
updateHitbox();
|
||||
|
@ -20,19 +21,6 @@ class CheckboxPreferenceItem extends FlxSprite
|
|||
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
|
||||
{
|
||||
if (value)
|
||||
|
|
Loading…
Add table
Reference in a new issue