Skip to content

Better Health Icons #484

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Apr 20, 2025
Merged
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
3 changes: 0 additions & 3 deletions assets/data/scripts/pixel.hx
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ function postCreate() {
defaultCamZoom /= daPixelZoom;
}

iconP1.antialiasing = false;
iconP2.antialiasing = false;

if (enablePixelGameOver) {
gameOverSong = "pixel/gameOver";
lossSFX = "pixel/gameOverSFX";
Expand Down
File renamed without changes
2 changes: 2 additions & 0 deletions assets/images/icons/bf-pixel/data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE codename-engine-icon>
<icon antialiasing="false" />
File renamed without changes
File renamed without changes
File renamed without changes
2 changes: 2 additions & 0 deletions assets/images/icons/gf-pixel/data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE codename-engine-icon>
<icon antialiasing="false" />
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
2 changes: 2 additions & 0 deletions assets/images/icons/senpai/data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE codename-engine-icon>
<icon antialiasing="false" />
File renamed without changes
2 changes: 2 additions & 0 deletions assets/images/icons/spirit/data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE codename-engine-icon>
<icon antialiasing="false" />
File renamed without changes
File renamed without changes
File renamed without changes
23 changes: 23 additions & 0 deletions source/funkin/backend/assets/Paths.hx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,29 @@ class Paths
return tempFramesCache[key] = loadFrames(assetsPath ? key : Paths.image(key, library, true));
}

/**
* Checks if the images needed for using getFrames() exist.
* @param key Path to the image
* @param checkAtlas Whenever to check for the Animation.json file (used in FlxAnimate)
* @param assetsPath Whenever to use the raw path or to pass it through Paths.image()
* @param library (Additional) library to load the frames from.
* @return True if the images exist, false otherwise.
**/
public static function framesExists(key:String, checkAtlas:Bool = false, checkMulti:Bool = true, assetsPath:Bool = false, ?library:String) {
var path = assetsPath ? key : Paths.image(key, library, true);
var noExt = Path.withoutExtension(path);
if(checkAtlas && Assets.exists('$noExt/Animation.json'))
return true;
if(checkMulti && Assets.exists('$noExt/1.png'))
return true;
if(Assets.exists('$noExt.xml'))
return true;
if(Assets.exists('$noExt.txt'))
return true;
if(Assets.exists('$noExt.json'))
return true;
return false;
}

/**
* Loads frames from a specific image path. Supports Sparrow Atlases, Packer Atlases, and multiple spritesheets.
Expand Down
5 changes: 5 additions & 0 deletions source/funkin/backend/scripting/events/NoteHitEvent.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package funkin.backend.scripting.events;

import funkin.game.Note;
import funkin.game.Character;
import funkin.game.HealthIcon;

final class NoteHitEvent extends CancellableEvent {
@:dox(hide) public var animCancelled:Bool = false;
Expand Down Expand Up @@ -113,6 +114,10 @@ final class NoteHitEvent extends CancellableEvent {
* Whenever the animation should be forced to play (if it's null it will be forced based on the sprite's data xml, if it has one).
*/
public var forceAnim:Null<Bool> = true;
/**
* The attached healthIcon used distinction for icons amongst others
*/
public var healthIcon:HealthIcon;

/**
* Prevents the default sing animation from being played.
Expand Down
19 changes: 5 additions & 14 deletions source/funkin/editors/character/CharacterInfoScreen.hx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import flixel.math.FlxPoint;
import haxe.xml.Access;
import funkin.game.Character;
import funkin.editors.extra.PropertyButton;
import funkin.game.HealthIcon;

class CharacterInfoScreen extends UISubstateWindow {
public var character:Character;

public var spriteTextBox:UITextBox;
public var iconTextBox:UITextBox;
public var iconSprite:FlxSprite;
public var iconSprite:HealthIcon;
public var gameOverCharTextBox:UITextBox;
public var antialiasingCheckbox:UICheckbox;
public var flipXCheckbox:UICheckbox;
Expand Down Expand Up @@ -147,20 +148,10 @@ class CharacterInfoScreen extends UISubstateWindow {
}

function updateIcon(icon:String) {
if (iconSprite == null) add(iconSprite = new FlxSprite());
if (iconSprite == null) add(iconSprite = new HealthIcon());

if (iconSprite.animation.exists(icon)) return;
@:privateAccess iconSprite.animation.clearAnimations();

var path:String = Paths.image('icons/$icon');
if (!Assets.exists(path)) path = Paths.image('icons/face');

iconSprite.loadGraphic(path, true, 150, 150);
iconSprite.animation.add(icon, [0], 0, false);
iconSprite.antialiasing = true;
iconSprite.animation.play(icon);

iconSprite.scale.set(0.5, 0.5);
iconSprite.setIcon(icon);
iconSprite.scale.set(iconSprite.defaultScale * 0.5, iconSprite.defaultScale * 0.5);
iconSprite.updateHitbox();
iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
}
Expand Down
9 changes: 4 additions & 5 deletions source/funkin/editors/charter/ChartCreationScreen.hx
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ class CompactCharacterButton extends UIButton {
autoAlpha = false;

charIcon = new HealthIcon(funkin.game.Character.getIconFromCharName(char));
charIcon.scale.set(0.2, 0.2);
charIcon.scale.set(charIcon.defaultScale * 0.2, charIcon.defaultScale * 0.2);
charIcon.updateHitbox();
charIcon.setPosition(10, bHeight/2 - charIcon.height / 2);
charIcon.scrollFactor.set(1,1);
Expand All @@ -332,11 +332,10 @@ class CompactCharacterButton extends UIButton {
textBox.antialiasing = true;
textBox.onChange = function(char:String) {
char = funkin.game.Character.getIconFromCharName(char);
var image = Paths.image("icons/" + char);
if(!Assets.exists(image))
image = Paths.image("icons/face");
charIcon.loadGraphic(image, true, 150, 150);
charIcon.setIcon(char);
charIcon.scale.set(charIcon.defaultScale * 0.2, charIcon.defaultScale * 0.2);
charIcon.updateHitbox();
charIcon.setPosition(10, bHeight/2 - charIcon.height / 2);
}

deleteButton = new UIButton(textBox.x + 115 + 16, bHeight/2 - (32/2), "", function () {
Expand Down
19 changes: 5 additions & 14 deletions source/funkin/editors/charter/CharterMetaDataScreen.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package funkin.editors.charter;
import flixel.math.FlxPoint;
import funkin.backend.chart.ChartData.ChartMetaData;
import funkin.editors.extra.PropertyButton;
import funkin.game.HealthIcon;

using StringTools;

Expand All @@ -20,7 +21,7 @@ class CharterMetaDataScreen extends UISubstateWindow {

public var displayNameTextBox:UITextBox;
public var iconTextBox:UITextBox;
public var iconSprite:FlxSprite;
public var iconSprite:HealthIcon;
public var opponentModeCheckbox:UICheckbox;
public var coopAllowedCheckbox:UICheckbox;
public var colorWheel:UIColorwheel;
Expand Down Expand Up @@ -130,20 +131,10 @@ class CharterMetaDataScreen extends UISubstateWindow {
}

function updateIcon(icon:String) {
if (iconSprite == null) add(iconSprite = new FlxSprite());
if (iconSprite == null) add(iconSprite = new HealthIcon());

if (iconSprite.animation.exists(icon)) return;
@:privateAccess iconSprite.animation.clearAnimations();

var path:String = Paths.image('icons/$icon');
if (!Assets.exists(path)) path = Paths.image('icons/face');

iconSprite.loadGraphic(path, true, 150, 150);
iconSprite.animation.add(icon, [0], 0, false);
iconSprite.antialiasing = true;
iconSprite.animation.play(icon);

iconSprite.scale.set(0.5, 0.5);
iconSprite.setIcon(icon);
iconSprite.scale.set(iconSprite.defaultScale * 0.5, iconSprite.defaultScale * 0.5);
iconSprite.updateHitbox();
iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
}
Expand Down
6 changes: 4 additions & 2 deletions source/funkin/editors/charter/CharterStrumline.hx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class CharterStrumline extends UISprite {

for (i=>icon in icons) {
var healthIcon = new HealthIcon(Character.getIconFromCharName(icon));
healthIcon.scale.x = healthIcon.scale.y = 0.6 - (icons.length / 20);
var newScale = 0.6 - (icons.length / 20);
healthIcon.scale.x = healthIcon.scale.y = healthIcon.defaultScale * newScale;
healthIcon.updateHitbox();
healthIcon.x = FlxMath.lerp(0, icons.length * 20, (icons.length-1 != 0 ? i / (icons.length-1) : 0));
healthIcon.y = draggable ? 29 : 7;
Expand Down Expand Up @@ -106,7 +107,8 @@ class CharterStrumline extends UISprite {

for (i=>icon in icons) {
var healthIcon = new HealthIcon(Character.getIconFromCharName(icon));
healthIcon.scale.x = healthIcon.scale.y = 0.6 - (icons.length / 20);
var newScale = 0.6 - (icons.length / 20);
healthIcon.scale.x = healthIcon.scale.y = healthIcon.defaultScale * newScale;
healthIcon.updateHitbox();
healthIcon.x = FlxMath.lerp(0, icons.length * 20, (icons.length-1 != 0 ? i / (icons.length-1) : 0));
healthIcon.y = draggable ? 14 : 7;
Expand Down
9 changes: 4 additions & 5 deletions source/funkin/editors/charter/CharterStrumlineScreen.hx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ class CharacterButton extends UIButton {
super(x, y, "", null, 250, 54);

charIcon = new HealthIcon(Character.getIconFromCharName(char));
charIcon.scale.set(0.3, 0.3);
charIcon.scale.set(charIcon.defaultScale * 0.3, charIcon.defaultScale * 0.3);
charIcon.updateHitbox();
charIcon.setPosition(x + 10, bHeight/2 - charIcon.height / 2);
charIcon.scrollFactor.set(1,1);
Expand All @@ -206,11 +206,10 @@ class CharacterButton extends UIButton {
textBox.antialiasing = true;
textBox.onChange = function(char:String) {
char = Character.getIconFromCharName(char);
var image = Paths.image("icons/" + char);
if(!Assets.exists(image))
image = Paths.image("icons/face");
charIcon.loadGraphic(image, true, 150, 150);
charIcon.setIcon(char);
charIcon.scale.set(charIcon.defaultScale * 0.3, charIcon.defaultScale * 0.3);
charIcon.updateHitbox();
charIcon.setPosition(x + 10, bHeight/2 - charIcon.height / 2);
}

deleteButton = new UIButton(textBox.x + 115 + 16, bHeight/2 - (32/2), "", function () {
Expand Down
19 changes: 5 additions & 14 deletions source/funkin/editors/charter/SongCreationScreen.hx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import flixel.text.FlxText.FlxTextFormatMarkerPair;
import flixel.group.FlxGroup;
import funkin.backend.chart.ChartData.ChartMetaData;
import haxe.io.Bytes;
import funkin.game.HealthIcon;

typedef SongCreationData = {
var meta:ChartMetaData;
Expand All @@ -25,7 +26,7 @@ class SongCreationScreen extends UISubstateWindow {

public var displayNameTextBox:UITextBox;
public var iconTextBox:UITextBox;
public var iconSprite:FlxSprite;
public var iconSprite:HealthIcon;
public var opponentModeCheckbox:UICheckbox;
public var coopAllowedCheckbox:UICheckbox;
public var colorWheel:UIColorwheel;
Expand Down Expand Up @@ -231,20 +232,10 @@ class SongCreationScreen extends UISubstateWindow {
}

function updateIcon(icon:String) {
if (iconSprite == null) menuDataGroup.add(iconSprite = new FlxSprite());
if (iconSprite == null) add(iconSprite = new HealthIcon());

if (iconSprite.animation.exists(icon)) return;
@:privateAccess iconSprite.animation.clearAnimations();

var path:String = Paths.image('icons/$icon');
if (!Assets.exists(path)) path = Paths.image('icons/face');

iconSprite.loadGraphic(path, true, 150, 150);
iconSprite.animation.add(icon, [0], 0, false);
iconSprite.antialiasing = true;
iconSprite.animation.play(icon);

iconSprite.scale.set(0.5, 0.5);
iconSprite.setIcon(icon);
iconSprite.scale.set(iconSprite.defaultScale * 0.5, iconSprite.defaultScale * 0.5);
iconSprite.updateHitbox();
iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
}
Expand Down
Loading