Funkin/source/funkin/play/notes/StrumlineNote.hx

212 lines
5.6 KiB
Haxe
Raw Normal View History

2023-06-22 01:41:01 -04:00
package funkin.play.notes;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.FlxSprite;
import funkin.play.notes.NoteSprite;
/**
* The actual receptor that you see on screen.
*/
class StrumlineNote extends FlxSprite
{
public var isPlayer(default, null):Bool;
public var direction(default, set):NoteDirection;
var confirmHoldTimer:Float = -1;
static final CONFIRM_HOLD_TIME:Float = 0.1;
2023-06-22 01:41:01 -04:00
public function updatePosition(parentNote:NoteSprite)
{
this.x = parentNote.x;
this.x += parentNote.width / 2;
this.x -= this.width / 2;
this.y = parentNote.y;
this.y += parentNote.height / 2;
}
function set_direction(value:NoteDirection):NoteDirection
{
this.direction = value;
setup();
return this.direction;
}
public function new(isPlayer:Bool, direction:NoteDirection)
{
super(0, 0);
this.isPlayer = isPlayer;
this.direction = direction;
this.animation.callback = onAnimationFrame;
this.animation.finishCallback = onAnimationFinished;
2023-06-27 17:22:51 -04:00
// Must be true for animations to play.
2023-06-22 01:41:01 -04:00
this.active = true;
}
function onAnimationFrame(name:String, frameNumber:Int, frameIndex:Int):Void {}
function onAnimationFinished(name:String):Void
{
// Run a timer before we stop playing the confirm animation.
// On opponent, this prevent issues with hold notes.
// On player, this allows holding the confirm key to fall back to press.
if (name == 'confirm')
2023-06-22 01:41:01 -04:00
{
confirmHoldTimer = 0;
2023-06-22 01:41:01 -04:00
}
}
override function update(elapsed:Float)
{
super.update(elapsed);
centerOrigin();
if (confirmHoldTimer >= 0)
{
confirmHoldTimer += elapsed;
// Ensure the opponent stops holding the key after a certain amount of time.
if (confirmHoldTimer >= CONFIRM_HOLD_TIME)
{
confirmHoldTimer = -1;
playStatic();
}
}
2023-06-22 01:41:01 -04:00
}
function setup():Void
{
this.frames = Paths.getSparrowAtlas('noteStrumline');
2023-06-22 01:41:01 -04:00
switch (this.direction)
{
case NoteDirection.LEFT:
this.animation.addByPrefix('static', 'staticLeft0', 24, false, false, false);
this.animation.addByPrefix('press', 'pressLeft0', 24, false, false, false);
this.animation.addByPrefix('confirm', 'confirmLeft0', 24, false, false, false);
this.animation.addByPrefix('confirm-hold', 'confirmHoldLeft0', 24, true, false, false);
2023-06-22 01:41:01 -04:00
case NoteDirection.DOWN:
this.animation.addByPrefix('static', 'staticDown0', 24, false, false, false);
this.animation.addByPrefix('press', 'pressDown0', 24, false, false, false);
this.animation.addByPrefix('confirm', 'confirmDown0', 24, false, false, false);
this.animation.addByPrefix('confirm-hold', 'confirmHoldDown0', 24, true, false, false);
2023-06-22 01:41:01 -04:00
case NoteDirection.UP:
this.animation.addByPrefix('static', 'staticUp0', 24, false, false, false);
this.animation.addByPrefix('press', 'pressUp0', 24, false, false, false);
this.animation.addByPrefix('confirm', 'confirmUp0', 24, false, false, false);
this.animation.addByPrefix('confirm-hold', 'confirmHoldUp0', 24, true, false, false);
2023-06-22 01:41:01 -04:00
case NoteDirection.RIGHT:
this.animation.addByPrefix('static', 'staticRight0', 24, false, false, false);
this.animation.addByPrefix('press', 'pressRight0', 24, false, false, false);
this.animation.addByPrefix('confirm', 'confirmRight0', 24, false, false, false);
this.animation.addByPrefix('confirm-hold', 'confirmHoldRight0', 24, true, false, false);
2023-06-22 01:41:01 -04:00
}
this.setGraphicSize(Std.int(Strumline.STRUMLINE_SIZE * 1.55));
this.updateHitbox();
this.playStatic();
}
public function playAnimation(name:String = 'static', force:Bool = false, reversed:Bool = false, startFrame:Int = 0):Void
{
this.animation.play(name, force, reversed, startFrame);
centerOffsets();
centerOrigin();
}
public function playStatic():Void
{
this.active = false;
this.playAnimation('static', true);
}
public function playPress():Void
{
this.active = true;
this.playAnimation('press', true);
}
public function playConfirm():Void
{
this.active = true;
this.playAnimation('confirm', true);
}
public function isConfirm():Bool
{
return getCurrentAnimation().startsWith('confirm');
}
public function holdConfirm():Void
{
this.active = true;
if (getCurrentAnimation() == "confirm-hold")
{
return;
}
else if (getCurrentAnimation() == "confirm")
2023-06-22 01:41:01 -04:00
{
if (isAnimationFinished())
{
this.confirmHoldTimer = -1;
this.playAnimation('confirm-hold', false, false);
2023-06-22 01:41:01 -04:00
}
}
else
{
this.playAnimation('confirm', false, false);
}
2023-06-22 01:41:01 -04:00
}
/**
* 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;
/**
* Adjusts the position of the sprite's graphic relative to the hitbox.
*/
function fixOffsets():Void
{
// Automatically center the bounding box within the graphic.
this.centerOffsets();
if (getCurrentAnimation() == "confirm")
{
// Move the graphic down and to the right to compensate for
// the "glow" effect on the strumline note.
this.offset.x -= DEFAULT_OFFSET;
this.offset.y -= DEFAULT_OFFSET;
}
else
{
this.centerOrigin();
}
}
}