Skip to content
Open
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
1 change: 1 addition & 0 deletions source/funkin/FunkinMemory.hx
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ class FunkinMemory
public static function cacheNoteStyle(style:NoteStyle):Void
{
// TODO: Texture paths should fall back to the default values.
cacheTexture(Paths.image(style.getHealthBarAssetPath(true) ?? "healthBar"));
cacheTexture(Paths.image(style.getNoteAssetPath() ?? "note"));
cacheTexture(style.getHoldNoteAssetPath() ?? "noteHold");
cacheTexture(Paths.image(style.getStrumlineAssetPath() ?? "strumline"));
Expand Down
12 changes: 12 additions & 0 deletions source/funkin/data/notestyle/NoteStyleData.hx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ typedef NoteStyleAssetsData =
@:optional
var holdNoteCover:NoteStyleAssetData<NoteStyleData_HoldNoteCover>;

/**
* The sprites for the healthbar
*/
@:optional
var healthBar:NoteStyleAssetData<NoteStyleData_HealthBar>;

/**
* The THREE sound (and an optional pre-READY graphic).
*/
Expand Down Expand Up @@ -223,6 +229,12 @@ typedef NoteStyleData_HoldNote = {}
typedef NoteStyleData_Judgement = {}
typedef NoteStyleData_ComboNum = {}

typedef NoteStyleData_HealthBar =
{
@:optional
var padding:Null<Array<Float>>;
}

/**
* Data on animations for each direction of the strumline.
*/
Expand Down
62 changes: 13 additions & 49 deletions source/funkin/play/PlayState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import funkin.play.components.Subtitles;
import funkin.play.cutscene.dialogue.Conversation;
import funkin.play.cutscene.VanillaCutscenes;
import funkin.play.cutscene.VideoCutscene;
import funkin.play.notes.HealthBar;
import funkin.play.notes.NoteDirection;
import funkin.play.notes.notekind.NoteKindManager;
import funkin.play.notes.notekind.NoteKind;
Expand Down Expand Up @@ -502,16 +503,10 @@ class PlayState extends MusicBeatSubState
var scoreText:FlxText;

/**
* The bar which displays the player's health.
* Dynamically updated based on the value of `healthLerp` (which is based on `health`).
* The sprite group that displays the player's health.
* Dynamically updated.
*/
public var healthBar:FlxBar;

/**
* The background image used for the health bar.
* Emma says the image is slightly skewed so I'm leaving it as an image instead of a `createGraphic`.
*/
public var healthBarBG:FunkinSprite;
public var healthBar:HealthBar;

/**
* A sprite group for subtitle display.
Expand Down Expand Up @@ -749,8 +744,7 @@ class PlayState extends MusicBeatSubState
opponentStrumline = new Strumline(noteStyle, false, currentChart?.scrollSpeed);

// Healthbar
healthBarBG = FunkinSprite.create(0, 0, 'healthBar');
healthBar = new FlxBar(0, 0, RIGHT_TO_LEFT, Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), null, 0, 2);
healthBar = new HealthBar(noteStyle, isBotPlayMode);
scoreText = new FlxText(0, 0, 0, '', 20);

// Combo & Pop Up
Expand Down Expand Up @@ -980,7 +974,8 @@ class PlayState extends MusicBeatSubState

super.update(elapsed);

updateHealthBar();
healthBar.updateHealthBar(health);

updateScoreText();

// Handle restarting the song when needed (player death or pressing Retry)
Expand Down Expand Up @@ -1387,9 +1382,9 @@ class PlayState extends MusicBeatSubState
updateScoreText();

health = Constants.HEALTH_STARTING;
healthLerp = health;
healthBar.healthLerp = health;

healthBar.value = healthLerp;
healthBar.healthBar.value = healthLerp;

if (!isMinimalMode)
{
Expand Down Expand Up @@ -1896,34 +1891,18 @@ class PlayState extends MusicBeatSubState
&& !ControlsHandler.usingExternalInputDevice)
|| #end Preferences.downscroll;

var healthBarYPos:Float = isDownscroll ? FlxG.height * 0.1 : FlxG.height * 0.9;

healthBarBG.y = healthBarYPos;
healthBarBG.screenCenter(X);
healthBarBG.scrollFactor.set(0, 0);
healthBarBG.zIndex = 800;
add(healthBarBG);

healthBar.x = healthBarBG.x + 4;
healthBar.y = healthBarBG.y + 4;
healthBar.parent = this;
healthBar.parentVariable = 'healthLerp';
healthBar.scrollFactor.set();
healthBar.createFilledBar(Constants.COLOR_HEALTH_BAR_RED, Constants.COLOR_HEALTH_BAR_GREEN);
healthBar.zIndex = 801;
add(healthBar);

// The score text below the health bar.
scoreText.x = healthBarBG.x + healthBarBG.width - 190;
scoreText.y = healthBarBG.y + 30;
scoreText.x = healthBar.healthBar.x + healthBar.healthBar.width - 190;
scoreText.y = healthBar.healthBar.y + 30;
scoreText.setFormat(Paths.font('vcr.ttf'), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
scoreText.scrollFactor.set();
scoreText.zIndex = 802;
add(scoreText);

// Move the health bar to the HUD camera.
healthBar.cameras = [camHUD];
healthBarBG.cameras = [camHUD];
scoreText.cameras = [camHUD];

// Create subtitles if they are enabled.
Expand Down Expand Up @@ -2054,7 +2033,7 @@ class PlayState extends MusicBeatSubState
// OPPONENT HEALTH ICON
//
iconP2 = new HealthIcon('dad', 1);
iconP2.y = healthBar.y - (iconP2.height / 2);
iconP2.y = healthBar.healthBar.y - (iconP2.height / 2);
dad.initHealthIcon(true); // Apply the character ID here
iconP2.zIndex = 850;
add(iconP2);
Expand All @@ -2077,7 +2056,7 @@ class PlayState extends MusicBeatSubState
// PLAYER HEALTH ICON
//
iconP1 = new HealthIcon('bf', 0);
iconP1.y = healthBar.y - (iconP1.height / 2);
iconP1.y = healthBar.healthBar.y - (iconP1.height / 2);
boyfriend.initHealthIcon(false); // Apply the character ID here
iconP1.zIndex = 850;
add(iconP1);
Expand Down Expand Up @@ -2603,21 +2582,6 @@ class PlayState extends MusicBeatSubState
}
}

/**
* Updates the values of the health bar.
*/
function updateHealthBar():Void
{
if (isBotPlayMode)
{
healthLerp = Constants.HEALTH_MAX;
}
else
{
healthLerp = FlxMath.lerp(healthLerp, health, 0.15);
}
}

/**
* Callback executed when one of the note keys is pressed.
*/
Expand Down
11 changes: 6 additions & 5 deletions source/funkin/play/components/HealthIcon.hx
Original file line number Diff line number Diff line change
Expand Up @@ -267,18 +267,19 @@ class HealthIcon extends FunkinSprite
// Update the animation based on the current state.
updateHealthIcon(PlayState.instance.health);
// Update the position to match the health bar.
this.x = PlayState.instance.healthBar.x
+ (PlayState.instance.healthBar.width * (FlxMath.remapToRange(PlayState.instance.healthBar.value, 0, 2, 100, 0) * 0.01) - POSITION_OFFSET);
this.x = PlayState.instance.healthBar.healthBar.x
+ (PlayState.instance.healthBar.healthBar.width * (FlxMath.remapToRange(PlayState.instance.healthBar.healthBar.value, 0, 2, 100, 0) * 0.01)
- POSITION_OFFSET);
case 1: // Dad
// Update the animation based on the current state.
updateHealthIcon(MAXIMUM_HEALTH - PlayState.instance.health);
// Update the position to match the health bar.
this.x = PlayState.instance.healthBar.x
+ (PlayState.instance.healthBar.width * (FlxMath.remapToRange(PlayState.instance.healthBar.value, 0, 2, 100, 0) * 0.01))
this.x = PlayState.instance.healthBar.healthBar.x
+ (PlayState.instance.healthBar.healthBar.width * (FlxMath.remapToRange(PlayState.instance.healthBar.healthBar.value, 0, 2, 100, 0) * 0.01))
- (this.width - POSITION_OFFSET);
}
// Keep the icon centered vertically on the health bar.
this.y = PlayState.instance.healthBar.y - (this.height / 2); // - (PlayState.instance.healthBar.height / 2)
this.y = PlayState.instance.healthBar.healthBar.y - (this.height / 2); // - (PlayState.instance.healthBar.height / 2)
}
}

Expand Down
78 changes: 78 additions & 0 deletions source/funkin/play/notes/HealthBar.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package funkin.play.notes;

import flixel.group.FlxSpriteGroup;
import flixel.math.FlxMath;
import flixel.ui.FlxBar;
import funkin.graphics.FunkinSprite;
import funkin.play.notes.notestyle.NoteStyle;

class HealthBar extends FlxSpriteGroup
{
final noteStyle:NoteStyle;

public var healthBar:FlxBar;
public var healthBarBG:FunkinSprite;
public var isBotPlayMode:Bool;

final isDownscroll:Bool = #if mobile (Preferences.controlsScheme == FunkinHitboxControlSchemes.Arrows
&& !ControlsHandler.usingExternalInputDevice)
|| #end Preferences.downscroll;

public var healthLerp:Float = Constants.HEALTH_STARTING;

public function new(noteStyle, isBotPlayMode:Bool = false):Void
{
super(0, 0);
this.noteStyle = noteStyle;
this.isBotPlayMode = isBotPlayMode;
var padding = noteStyle.getHealthBarPadding();
trace(noteStyle.getHealthBarAssetPath());
var assetPath = Paths.image(noteStyle.getHealthBarAssetPath() ?? "healthBar");
healthBarBG = FunkinSprite.create(0, 0, assetPath);
healthBar = new FlxBar(0, 0, RIGHT_TO_LEFT, Std.int(healthBarBG.width - padding[0]), Std.int(healthBarBG.height - padding[1]), this, 'healthLerp', 0, 2);
var scale = noteStyle.getHealthBarScale();
if (healthBarBG != null)
{
healthBarBG.scale.set(scale, scale);
healthBarBG.y = isDownscroll ? FlxG.height * 0.1 : FlxG.height * 0.9;
healthBarBG.screenCenter(X);
healthBarBG.scrollFactor.set(0, 0);
healthBarBG.zIndex = 800;
noteStyle.applyHealthBarOffsets(this);
this.add(healthBarBG);
}
else
{
healthBarBG = FunkinSprite.create(0, 0, 'healthBar');
healthBarBG.scale.set(scale, scale);
healthBarBG.y = isDownscroll ? FlxG.height * 0.1 : FlxG.height * 0.9;
healthBarBG.screenCenter(X);
healthBarBG.scrollFactor.set(0, 0);
healthBarBG.zIndex = 800;
noteStyle.applyHealthBarOffsets(this);
this.add(healthBarBG);
}

healthBar.x = healthBarBG.x + padding[0] / 2;
healthBar.y = healthBarBG.y + padding[1] / 2;
healthBar.scrollFactor.set();
healthBar.createFilledBar(Constants.COLOR_HEALTH_BAR_RED, Constants.COLOR_HEALTH_BAR_GREEN);
healthBar.zIndex = 801;
this.add(healthBar);
}

/**
* Updates the values of the health bar.
*/
public function updateHealthBar(health:Float):Void
{
if (isBotPlayMode)
{
healthLerp = Constants.HEALTH_MAX;
}
else
{
healthLerp = FlxMath.lerp(healthLerp, health, 0.15);
}
}
}
37 changes: 37 additions & 0 deletions source/funkin/play/notes/notestyle/NoteStyle.hx
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,43 @@ class NoteStyle implements IRegistryEntry<NoteStyleData>
return _data?.assets?.holdNoteCover?.offsets ?? fallback?.getHoldCoverOffsets() ?? [0.0, 0.0];
}

public function getHealthBarAssetPath(raw:Bool = false):Null<String>
{
if (raw)
{
var rawPath:Null<String> = _data?.assets?.healthBar?.assetPath;
if (rawPath == null) return fallback?.getHealthBarAssetPath(true);
return rawPath;
}
// library:path
var parts = getHealthBarAssetPath(true)?.split(Constants.LIBRARY_SEPARATOR) ?? [];
if (parts.length == 0) return null;
if (parts.length == 1) return getHealthBarAssetPath(true);
return parts[1];
}

public function getHealthBarOffsets():Array<Float>
{
return _data?.assets?.healthBar?.offsets ?? fallback?.getHealthBarOffsets() ?? [0.0, 0.0];
}

public function applyHealthBarOffsets(target:HealthBar):Void
{
var offsets = getHealthBarOffsets();
target.x += offsets[0];
target.y += offsets[1];
}

public function getHealthBarScale():Float
{
return _data.assets?.healthBar?.scale ?? fallback?.getHealthBarScale() ?? 1.0;
}

public function getHealthBarPadding():Array<Float>
{
return _data?.assets?.healthBar?.data?.padding ?? fallback?.getHealthBarPadding() ?? [8.0, 8.0];
}

public function destroy():Void {}

/**
Expand Down
Loading