Skip to content

Commit 8c252bb

Browse files
FuroYTNeeEooNexIsDumb
authored
Better Health Icons (#484)
* Better Health Icons - Add Animated Icons Support - Switch to Funkin Sprite - Customizable Icon Bumps With HScript * Moved icons * Improve code and features for Health Icons V2 * Small fixes * fix icons in editors * Remove that not needed code * Use better onFinish callback * Animate Atlas icons * Cleanup * Small change * sing anim nodes on icons and updateIconPos can be overitten on hscript * remove sing nodes since its useless * fix potential null function pointer * remove that lines * fixing compiling errors * hawk tuah * ORGANIZE THEM >:D * mlem imports are organized based on the func in vsc smh * bruh --------- Co-authored-by: Ne_Eo <[email protected]> Co-authored-by: ⍚~Nex <[email protected]>
1 parent 2a700b6 commit 8c252bb

File tree

30 files changed

+446
-118
lines changed

30 files changed

+446
-118
lines changed

assets/data/scripts/pixel.hx

-3
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,6 @@ function postCreate() {
9797
defaultCamZoom /= daPixelZoom;
9898
}
9999

100-
iconP1.antialiasing = false;
101-
iconP2.antialiasing = false;
102-
103100
if (enablePixelGameOver) {
104101
gameOverSong = "pixel/gameOver";
105102
lossSFX = "pixel/gameOverSFX";
File renamed without changes.

assets/images/icons/bf-pixel/data.xml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<!DOCTYPE codename-engine-icon>
2+
<icon antialiasing="false" />
File renamed without changes.
File renamed without changes.
File renamed without changes.

assets/images/icons/gf-pixel/data.xml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<!DOCTYPE codename-engine-icon>
2+
<icon antialiasing="false" />
File renamed without changes.
File renamed without changes.
File renamed without changes.

assets/images/icons/senpai/data.xml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<!DOCTYPE codename-engine-icon>
2+
<icon antialiasing="false" />
File renamed without changes.

assets/images/icons/spirit/data.xml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<!DOCTYPE codename-engine-icon>
2+
<icon antialiasing="false" />
File renamed without changes.
File renamed without changes.

source/funkin/backend/assets/Paths.hx

+23
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,29 @@ class Paths
200200
return tempFramesCache[key] = loadFrames(assetsPath ? key : Paths.image(key, library, true));
201201
}
202202

203+
/**
204+
* Checks if the images needed for using getFrames() exist.
205+
* @param key Path to the image
206+
* @param checkAtlas Whenever to check for the Animation.json file (used in FlxAnimate)
207+
* @param assetsPath Whenever to use the raw path or to pass it through Paths.image()
208+
* @param library (Additional) library to load the frames from.
209+
* @return True if the images exist, false otherwise.
210+
**/
211+
public static function framesExists(key:String, checkAtlas:Bool = false, checkMulti:Bool = true, assetsPath:Bool = false, ?library:String) {
212+
var path = assetsPath ? key : Paths.image(key, library, true);
213+
var noExt = Path.withoutExtension(path);
214+
if(checkAtlas && Assets.exists('$noExt/Animation.json'))
215+
return true;
216+
if(checkMulti && Assets.exists('$noExt/1.png'))
217+
return true;
218+
if(Assets.exists('$noExt.xml'))
219+
return true;
220+
if(Assets.exists('$noExt.txt'))
221+
return true;
222+
if(Assets.exists('$noExt.json'))
223+
return true;
224+
return false;
225+
}
203226

204227
/**
205228
* Loads frames from a specific image path. Supports Sparrow Atlases, Packer Atlases, and multiple spritesheets.

source/funkin/backend/scripting/events/NoteHitEvent.hx

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package funkin.backend.scripting.events;
22

33
import funkin.game.Note;
44
import funkin.game.Character;
5+
import funkin.game.HealthIcon;
56

67
final class NoteHitEvent extends CancellableEvent {
78
@:dox(hide) public var animCancelled:Bool = false;
@@ -113,6 +114,10 @@ final class NoteHitEvent extends CancellableEvent {
113114
* 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).
114115
*/
115116
public var forceAnim:Null<Bool> = true;
117+
/**
118+
* The attached healthIcon used distinction for icons amongst others
119+
*/
120+
public var healthIcon:HealthIcon;
116121

117122
/**
118123
* Prevents the default sing animation from being played.

source/funkin/editors/character/CharacterInfoScreen.hx

+5-14
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ import flixel.math.FlxPoint;
44
import haxe.xml.Access;
55
import funkin.game.Character;
66
import funkin.editors.extra.PropertyButton;
7+
import funkin.game.HealthIcon;
78

89
class CharacterInfoScreen extends UISubstateWindow {
910
public var character:Character;
1011

1112
public var spriteTextBox:UITextBox;
1213
public var iconTextBox:UITextBox;
13-
public var iconSprite:FlxSprite;
14+
public var iconSprite:HealthIcon;
1415
public var gameOverCharTextBox:UITextBox;
1516
public var antialiasingCheckbox:UICheckbox;
1617
public var flipXCheckbox:UICheckbox;
@@ -147,20 +148,10 @@ class CharacterInfoScreen extends UISubstateWindow {
147148
}
148149

149150
function updateIcon(icon:String) {
150-
if (iconSprite == null) add(iconSprite = new FlxSprite());
151+
if (iconSprite == null) add(iconSprite = new HealthIcon());
151152

152-
if (iconSprite.animation.exists(icon)) return;
153-
@:privateAccess iconSprite.animation.clearAnimations();
154-
155-
var path:String = Paths.image('icons/$icon');
156-
if (!Assets.exists(path)) path = Paths.image('icons/face');
157-
158-
iconSprite.loadGraphic(path, true, 150, 150);
159-
iconSprite.animation.add(icon, [0], 0, false);
160-
iconSprite.antialiasing = true;
161-
iconSprite.animation.play(icon);
162-
163-
iconSprite.scale.set(0.5, 0.5);
153+
iconSprite.setIcon(icon);
154+
iconSprite.scale.set(iconSprite.defaultScale * 0.5, iconSprite.defaultScale * 0.5);
164155
iconSprite.updateHitbox();
165156
iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
166157
}

source/funkin/editors/charter/ChartCreationScreen.hx

+4-5
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ class CompactCharacterButton extends UIButton {
320320
autoAlpha = false;
321321

322322
charIcon = new HealthIcon(funkin.game.Character.getIconFromCharName(char));
323-
charIcon.scale.set(0.2, 0.2);
323+
charIcon.scale.set(charIcon.defaultScale * 0.2, charIcon.defaultScale * 0.2);
324324
charIcon.updateHitbox();
325325
charIcon.setPosition(10, bHeight/2 - charIcon.height / 2);
326326
charIcon.scrollFactor.set(1,1);
@@ -332,11 +332,10 @@ class CompactCharacterButton extends UIButton {
332332
textBox.antialiasing = true;
333333
textBox.onChange = function(char:String) {
334334
char = funkin.game.Character.getIconFromCharName(char);
335-
var image = Paths.image("icons/" + char);
336-
if(!Assets.exists(image))
337-
image = Paths.image("icons/face");
338-
charIcon.loadGraphic(image, true, 150, 150);
335+
charIcon.setIcon(char);
336+
charIcon.scale.set(charIcon.defaultScale * 0.2, charIcon.defaultScale * 0.2);
339337
charIcon.updateHitbox();
338+
charIcon.setPosition(10, bHeight/2 - charIcon.height / 2);
340339
}
341340

342341
deleteButton = new UIButton(textBox.x + 115 + 16, bHeight/2 - (32/2), "", function () {

source/funkin/editors/charter/CharterMetaDataScreen.hx

+5-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package funkin.editors.charter;
33
import flixel.math.FlxPoint;
44
import funkin.backend.chart.ChartData.ChartMetaData;
55
import funkin.editors.extra.PropertyButton;
6+
import funkin.game.HealthIcon;
67

78
using StringTools;
89

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

2122
public var displayNameTextBox:UITextBox;
2223
public var iconTextBox:UITextBox;
23-
public var iconSprite:FlxSprite;
24+
public var iconSprite:HealthIcon;
2425
public var opponentModeCheckbox:UICheckbox;
2526
public var coopAllowedCheckbox:UICheckbox;
2627
public var colorWheel:UIColorwheel;
@@ -130,20 +131,10 @@ class CharterMetaDataScreen extends UISubstateWindow {
130131
}
131132

132133
function updateIcon(icon:String) {
133-
if (iconSprite == null) add(iconSprite = new FlxSprite());
134+
if (iconSprite == null) add(iconSprite = new HealthIcon());
134135

135-
if (iconSprite.animation.exists(icon)) return;
136-
@:privateAccess iconSprite.animation.clearAnimations();
137-
138-
var path:String = Paths.image('icons/$icon');
139-
if (!Assets.exists(path)) path = Paths.image('icons/face');
140-
141-
iconSprite.loadGraphic(path, true, 150, 150);
142-
iconSprite.animation.add(icon, [0], 0, false);
143-
iconSprite.antialiasing = true;
144-
iconSprite.animation.play(icon);
145-
146-
iconSprite.scale.set(0.5, 0.5);
136+
iconSprite.setIcon(icon);
137+
iconSprite.scale.set(iconSprite.defaultScale * 0.5, iconSprite.defaultScale * 0.5);
147138
iconSprite.updateHitbox();
148139
iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
149140
}

source/funkin/editors/charter/CharterStrumline.hx

+4-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class CharterStrumline extends UISprite {
4949

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

107108
for (i=>icon in icons) {
108109
var healthIcon = new HealthIcon(Character.getIconFromCharName(icon));
109-
healthIcon.scale.x = healthIcon.scale.y = 0.6 - (icons.length / 20);
110+
var newScale = 0.6 - (icons.length / 20);
111+
healthIcon.scale.x = healthIcon.scale.y = healthIcon.defaultScale * newScale;
110112
healthIcon.updateHitbox();
111113
healthIcon.x = FlxMath.lerp(0, icons.length * 20, (icons.length-1 != 0 ? i / (icons.length-1) : 0));
112114
healthIcon.y = draggable ? 14 : 7;

source/funkin/editors/charter/CharterStrumlineScreen.hx

+4-5
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ class CharacterButton extends UIButton {
194194
super(x, y, "", null, 250, 54);
195195

196196
charIcon = new HealthIcon(Character.getIconFromCharName(char));
197-
charIcon.scale.set(0.3, 0.3);
197+
charIcon.scale.set(charIcon.defaultScale * 0.3, charIcon.defaultScale * 0.3);
198198
charIcon.updateHitbox();
199199
charIcon.setPosition(x + 10, bHeight/2 - charIcon.height / 2);
200200
charIcon.scrollFactor.set(1,1);
@@ -206,11 +206,10 @@ class CharacterButton extends UIButton {
206206
textBox.antialiasing = true;
207207
textBox.onChange = function(char:String) {
208208
char = Character.getIconFromCharName(char);
209-
var image = Paths.image("icons/" + char);
210-
if(!Assets.exists(image))
211-
image = Paths.image("icons/face");
212-
charIcon.loadGraphic(image, true, 150, 150);
209+
charIcon.setIcon(char);
210+
charIcon.scale.set(charIcon.defaultScale * 0.3, charIcon.defaultScale * 0.3);
213211
charIcon.updateHitbox();
212+
charIcon.setPosition(x + 10, bHeight/2 - charIcon.height / 2);
214213
}
215214

216215
deleteButton = new UIButton(textBox.x + 115 + 16, bHeight/2 - (32/2), "", function () {

source/funkin/editors/charter/SongCreationScreen.hx

+5-14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import flixel.text.FlxText.FlxTextFormatMarkerPair;
55
import flixel.group.FlxGroup;
66
import funkin.backend.chart.ChartData.ChartMetaData;
77
import haxe.io.Bytes;
8+
import funkin.game.HealthIcon;
89

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

2627
public var displayNameTextBox:UITextBox;
2728
public var iconTextBox:UITextBox;
28-
public var iconSprite:FlxSprite;
29+
public var iconSprite:HealthIcon;
2930
public var opponentModeCheckbox:UICheckbox;
3031
public var coopAllowedCheckbox:UICheckbox;
3132
public var colorWheel:UIColorwheel;
@@ -231,20 +232,10 @@ class SongCreationScreen extends UISubstateWindow {
231232
}
232233

233234
function updateIcon(icon:String) {
234-
if (iconSprite == null) menuDataGroup.add(iconSprite = new FlxSprite());
235+
if (iconSprite == null) add(iconSprite = new HealthIcon());
235236

236-
if (iconSprite.animation.exists(icon)) return;
237-
@:privateAccess iconSprite.animation.clearAnimations();
238-
239-
var path:String = Paths.image('icons/$icon');
240-
if (!Assets.exists(path)) path = Paths.image('icons/face');
241-
242-
iconSprite.loadGraphic(path, true, 150, 150);
243-
iconSprite.animation.add(icon, [0], 0, false);
244-
iconSprite.antialiasing = true;
245-
iconSprite.animation.play(icon);
246-
247-
iconSprite.scale.set(0.5, 0.5);
237+
iconSprite.setIcon(icon);
238+
iconSprite.scale.set(iconSprite.defaultScale * 0.5, iconSprite.defaultScale * 0.5);
248239
iconSprite.updateHitbox();
249240
iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
250241
}

0 commit comments

Comments
 (0)