Mega Man-style Sprite HUD

jorotroid

Member
uzBj7hn.gif


A Small Edit: Here is the link to my post on how to disable the built in HUD, but I also need to update that post. If you follow the instructions there, it will disable the HUD, but there will still be some code elsewhere related to the HUD that is just taking up a little bit of space. So I'll hunt those down at some point and add them to that post.
http://www.nesmakers.com/viewtopic.php?f=3&t=896

I am going to divide this post into 3 sections: The Pros and Cons of doing this, an attempt at a High-Level Explination on what the code does, and finally the code itself and How to Hook it Up. Read them all, or just the ones that are relevant to you.

Pros and Cons
Pros:
-Uses way less memory than the built in HUD to give you more room to work with other things.
-Gives an alternative look.

Cons:
-One less sprite available on the each scanline if you are just doing a health bar. Two less if you are also displaying a weapons bar.
-Less sprites to uses on screen in general. For me, I am using 8 sprites per bar, plus 4 sprites for the caps at the top and bottom which means 20 sprites are going to this health bar. Don't forget that you are limited to 64 sprites at a time. For me, I think that should be fine for what I have planned.
-You have to use some graphical space in either your game objects or each of your monster files. I went with putting the graphics in my game objects.
-Unless you're using also textboxes, the HUD graphics may end up going unused which means that some of your background graphics space will go to waste. I bet there is a way you could re-purpose that space, but I haven't looked into it, so I don't know what would be involved.
-More juggling of your sprite palettes.
-The way I have it written, the health bar goes from 0 to 255, but it only has 32 increments. This means if you are at full health and take 1 point of damage, you will not see a visual change. You need to take about 8 points of damage to see the bar go down 1 step. The easy "fix" to this is to have all enemies give at least 8 points of damage. It wouldn't be difficult modify the code to make the health bar have more divisions, but that would either mean more sprites on screen, more graphic space being used, or both.

Ok, I think you have been sufficiently warned. Now on with the show!


High-Level Explanation

The health bar is made up of 3 sections: Full bar segments, empty bar segments and sometimes one partial bar segment. Each bar segment is a sprite and there are 8 sprites used for the entire health bar. If you are unfamiliar with binary numbers, then here is a quick crash course on finding the value of a binary number. If a bit is equal to one then that adds a certain value to the total of binary number. Using the chart below, you can find out which bits add which value.

Code:
Bit number: 	76543210	Added value:
		|||||||+---	1
		||||||+----	2
		|||||+-----	4
		||||+------	8
		|||+-------	16
		||+--------	32
		|+---------	64
		+----------	128

So this means that if you have 1000 0000, then the only on bit is bit 7 which has a value of 128, so the value of the number is 128. Or to make a more complex example, if you have 1010 1001, you have the bits on for the values 128, 32, 8, and 1 so you add them up to get 169. As I said, the health bar is made up of 8 sprites, each accounting for 32 health points. So if the player's health is 128 or 1000 0000 in binary then I already know that the total health bar is 4 bar segments full (because 128/32 = 4). Or another way you could look at it is that 128 is half of 255ish, so the health bar is half full. So by looking at the last 3 bits (the ones on the left), I can tell how many full bar segments the health bar needs. once I have the number of full bar segments, I can subtract that number from 8 to get the number of empty bar segments. If I have any remaining bits then I can do a check to see what kind of partial bar segment needs to be displayed between the full and empty bar segments. So here is that bit chart again, but this time also showing how much of the health bar each bit represents.

Code:
Bit number: 	76543210	Added value:	Number of Bar Segments:
		|||||||+---	1		\
		||||||+----	2		  > If any of these bits = 1, it displays 1/4 of a Segment
		|||||+-----	4		/
		||||+------	8		1/2 of a Segment
		|||+-------	16		3/4 of a Segment
		||+--------	32		1 Segment
		|+---------	64		2 Segments
		+----------	128		4 Segments

So all of that determines what needs to be displayed. From there we do a loop to display all the full segments, then display a partial segment if we have one, and finally do another loop to display the empty segments. And that's it. I skipped some finer details, but if you made it this far, you should be able to understand the rest from looking at the code.


How to Hook it Up
Step 1:
Open HandleUpdateObjects.asm which is in Routines/System. At line 31 you should see this line of code.
Code:
.include SCR_SPRITE_PREDRAW

A brief explanation of what we're doing here.
You may recall in the Adventure module that when you get you sword, it will display a little sword sprite in the HUD. This is where that happens in the code, so we're going to use that. But first we need to do some modifications. The code for the sprite HUD bar is pretty long, so we need to set up a trampoline. When you use the JMP command you can only move 128 lines in either direction, and because the code is so long we need to use a JSR to "bookmark" our position so we can find our way back, to put it simply.

Step 2:
Replace line 31 with the following code:
Code:
	JSR drawSpriteHUDTrampoline
	JMP pastDrawSpriteHUDTrampoline
drawSpriteHUDTrampoline:
	JMP checkForSpriteHUDDraw
	.include SCR_SPRITE_PREDRAW
	
pastDrawSpriteHUDTrampoline:

Save that and we are done with HandleUpdateObjects.asm

Step 3:
Go into NESmaker. Go to Project>Project Settings, then click on the Script Settings tab. Find which file is defined for "Handle Sprite Pre-Draw." Here is an image of what it looks like for me, but keep in mind that I have it pointing to a different location than the default. I think the default was in the Adventure module scripts.
qyFOrsV.png


Step 4:
Now that you know which file we're going to be working in, go ahead and open it up. If you're using 4.0.11, then this file is probably all commented out. We can add our code underneath it.

What we are doing here
First we're checking to see if the game is in the main game state. Then if it is, we go on to make draw the 4 sprites for the caps at the top and bottom of the bars. Next we check if the player is still alive because weird things happen after we die. And finally call my macros for drawing a status bar.

Here is the code for this step. The main thing you need to know is on the DrawSprite lines, you need to determine what values you want for your game. In particular, the 3rd argument determines which graphic it will use. If you put #$00, it will use the top left graphic of your game objects sheet. If you use #$FF, I will uses the bottom right graphic whatever monster sheet is currently loaded in game. Just remember the first digit represents the column of the graphic in your sheet, and the second digit represents the row. I had my graphics aroung the lower right of my game objects sheet.
Code:
checkForSpriteHUDDraw:
LDA gameState				; We want only want to make the HUD in the main gameState
BNE drawingSpriteHud
RTS
drawingSpriteHud:

	;; Draws a cap sprite at the top of the health bar.
	DrawSprite #$08, #$10, #$1F, #%00000001, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	
	;; Draws a cap sprite at the top of the magic bar.
	DrawSprite #$10, #$10, #$6E, #%00000000, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
		
	;; Draws a cap sprite at the bottom of the health bar.
	DrawSprite #$08, #$58, #$7E, #%00000001, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	
	;; Draws a cap sprite at the bottom of the magic bar.
	DrawSprite #$10, #$58, #$7F, #%00000001, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset

	
	
	LDX player1_object		; When the player is alive, player1_object == #$00, but 
	BEQ thePlayerIsAlive	; when dead, player1_object == #$FF, so we need to ensure
	LDA #$00				; #$00 gets passed in for the health value when the player	
	STA temp3				; when the player is dead.
	JMP letsGetThisHUDStarted

thePlayerIsAlive:
	LDA Object_health,x
	STA temp3
		
letsGetThisHUDStarted:
	
	;; Draw the Health Bar
	DrawStatusBar #$08, #$18, temp3, #$2F, #$3F, #$4F, #$5F, #$6F, #%00000001
	
	;; Draw the Magic Bar
	DrawStatusBar #$10, #$18, #$6A, #$2F, #$3F, #$4F, #$5F, #$6F, #%00000000
	
	RTS

Final Step:
This is a whopping huge macro, but it makes it easier to draw both a health bar and a magic bar, and any other bars you may feel inclined to include in your game. I left a comment at the top of the macro to explain what each argument does, so check that out. If you want to know how it works, just check out the High-Level Explanation section above. You can either put this code in the Macros.asm file in Routines/System, or do what I did and make my own Macro file. If you do the latter, be sure to include you file in around where Macros.asm gets included in MainASM.asm around line 8.

Code:
MACRO DrawStatusBar arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
	;; arg0 x position of bottom bar segment
	;; arg1 y position of bottom bar segment
	;; arg2 value bar is displaying
	;; arg3 location of empty graphic
	;; arg4 location of 1/4 graphic
	;; arg5 location of 1/2 graphic
	;; arg6 location of 3/4 graphic
	;; arg7 location of full graphic
	;; arg8 attribute data (bits 0 and 1 determine which palette is used)
	
		
		LDA #$00		
		STA temp2		;Number of full sprites
		STA temp1		;if there is a partial sprite and what is it
		LDA #$08		
		STA temp		;Number of empty sprites
		
		
		LDA arg2
		BEQ readyToDrawHealthBar
		AND #%11111000
		CMP #%11111000
		BNE checkForHalf
			;; Full
			LDA #$08
			STA temp2
			JMP drawHealthBar
		
	checkForHalf:
		LDA arg2
		AND #%10000000
		BEQ checkForQuarter
			;;;  Half Full
			LDA #$04
			STA temp2
			

	checkForQuarter:
		LDA arg2
		AND #%01000000
		BEQ checkForEighth
			;;; Quarter full
			INC temp2
			INC temp2
			
			
	checkForEighth:
		LDA arg2
		AND #%00100000
		BEQ checkForOneMore
			;;; Eighth full
			INC temp2
			
			
			
	checkForOneMore:
		LDA arg2
		AND #%00011000
		CMP #%00011000
		BNE checkForPartialThreeQuarters
			INC temp2
			JMP drawHealthBar

			
	checkForPartialThreeQuarters:
		LDA arg2
		AND #%00010000
		BEQ checkForPartialHalf
			;; Partial is 3/4 full
			LDA arg6
			STA temp1
			JMP drawHealthBar
			
	checkForPartialHalf:
		LDA arg2
		AND #%00001000
		BEQ checkForPartialQuarter
			;; Partial is half full
			LDA arg5
			STA temp1
			JMP drawHealthBar
			
	checkForPartialQuarter:
		LDA arg2
		AND #%00000111
		BEQ drawHealthBar
			;; Partial is quarter full
			LDA arg4
			STA temp1

		
	drawHealthBar:

		
		LDA temp		
		SEC
		SBC temp2		;Number of full sprites
		STA temp		;Number of empty sprites
		BEQ readyToDrawHealthBar	;If we only have full sprites, then we can go ahead and draw
		LDA temp1
		BEQ readyToDrawHealthBar	;Does an empty sprite need to be replaced with a partial sprite?
			DEC temp
			
	readyToDrawHealthBar:
		LDX temp
		LDA arg1
		STA temp	;Now temp is the y position of drawing from bottom up
	emptySpritesLoop:
		TXA
		BEQ partialSpriteDraw
		DrawSprite arg0, temp, arg3, arg8, spriteOffset
		inc spriteOffset
		inc spriteOffset
		inc spriteOffset
		inc spriteOffset
		
		LDA temp
		CLC
		ADC #$08
		STA temp

		DEX
		JMP emptySpritesLoop
		
	partialSpriteDraw:

		LDA temp1
		BEQ readyToDrawEmptyBars
		DrawSprite arg0, temp, temp1, arg8, spriteOffset
		inc spriteOffset
		inc spriteOffset
		inc spriteOffset
		inc spriteOffset
		
		LDA temp
		CLC
		ADC #$08
		STA temp
		
		
		
	readyToDrawEmptyBars:
	
		LDX temp2		;Loaded into X for iteration
		
		
	fullSpritesLoop:
		TXA				;8
		BEQ doneWithHealthBar
		DrawSprite arg0, temp, arg7, arg8, spriteOffset
		inc spriteOffset
		inc spriteOffset
		inc spriteOffset
		inc spriteOffset
		
		LDA temp
		CLC
		ADC #$08
		STA temp
		
		DEX
		JMP fullSpritesLoop
		
	doneWithHealthBar:

ENDM

And that's it! I hope I didn't make too many typos writing up this post. At some point I will probably modify this macro to have a variable height so that the health bar can be expanded after getting items, but I probably won't make it handle more than 8 segment because I don't want to waste sprites. Instead I will probably make the health bar start short an then work up to 8 sprites tall. But for now I am eager to get back to programming mechanics for my game.
 
I will definitely be using this, and definitely will be trying to make it start small and grow larger(And probably failing a bunch before giving up, then someone else will have the answer, so it all works out in the end).
 

Mihoshi20

Member
I like it a lot. This'll come in handy for a major project of mine down the road. What GPL does this fall under so I can make proper attribution/contribution if I use it.
 
This will bring the Megaman X Style if I mod this to use 8-bit styles of the Megaman X HUD and my game be somewhat megaman styled - if I do it right.
 

jorotroid

Member
Thanks everyone!

Mihoshi20 said:
I like it a lot. This'll come in handy for a major project of mine down the road. What GPL does this fall under so I can make proper attribution/contribution if I use it.
Oh, I totally did not think that far ahead. Basically if you feel this warrants crediting, I'd be honored to be mentioned and you can list me as Joe Rossi. But I'm also not going to comb through your credits to make sure you credited me.


Convoy_Avenger said:
I will definitely be using this, and definitely will be trying to make it start small and grow larger(And probably failing a bunch before giving up, then someone else will have the answer, so it all works out in the end).
Awesome! I'll definitely be interested to see what you come up with. I have some ideas about how I'll go about it, but I'm very anxious to get back to programming mechanics and the health bar can be a later issue for me. Especially considering I barely have enemies at the moment.
 
I'm having the hardest time making this work....I want to make a copy of the HandleUpdateObjects.asm and replace what's needed and create a copy of it so it doesn't clash with the other games of mine and when exported it threw out label already defined error..... I'm like what!?!

I feel I need copies of these so it works as I tried to follow this code.
 

jorotroid

Member
"Label already defined" means that you have made two or more labels with the same name. The console will tell you which line the error happened on, so you can find out with label it was and then search for where it has been repeated.
 

Mugi

Member
i instantly got a "PC out of range" with this on routines/system/valuecounters.asm
is there other code you cleaned up to free space aside the hud code you linked at the beginning ?
what i have on my game is quite barebones atm, and can't really imagine i already ran out of space.

at any rate, i tried getting this to work with no luck, and same with the icarus hud that was posted here, that just made the game go full gray screen and print tons of garbage for almost a minute before showing up a corrupt game screen. not good.
i think i pretty much destroyed my codebase already by messing with the huds, time to clean up and restart. ^^;
 

jorotroid

Member
Huh. I don't think I have seen "PC out of range" before. Usually it's "Value out of range" that I see when a bank is maxed out in memory. I'm not sure what the distinction is. What have you done so far with your game? Also what line does it say the error is on?
 

MistSonata

Moderator
If you're getting "PC out of range" errors at valuecounters, then something has gone terribly wrong, because from what I understand that means that one of the scripts that's being included before valuecounters is so big that it's knocking several hundreds of lines of code out of the limits of what a bank can hold. You're not going to be able to remove enough stuff to fit whatever got added to your code without breaking the functionality of your game.

My recommendation would be to go back and try to find what you did before getting the error, you might've placed a chunk of code in the wrong place or maybe an error with the tool is causing a bunch of garbage code to be created. If you need further help, it might help us a lot if you put the demo.txt from your attempted export into a zip file and post it here so we can better see what might've happened.
 

Mugi

Member
edit: im sorry, im an idiot. I left the original post i wrote below, but here's what was wrong;
in my modified code i removed the quarter checks, but i didn't patch out the checkForHalf to move into drawHealthBar, instead it was still looking for "checkfor quarter"

Code:
checkForHalf:
	LDA arg2
	AND #%10000000
	BEQ drawHealthBar ; <---- this was originally checkForQuarter
		;;;  Half Full
		LDA #$04
		STA temp2


now it does things, and drew lots of heads of my sprite to the screen. There is still the mystery of why the vanilla code doesnt fit into my rom, but i will deal with that if i ever need to. For now it appears to function.

-----------------------------------------------------------------------------------



I followed the instructions here to the spot for installing this, and tested it multiple times.

that said, i was able to get it to load and behave by removing the original hud code as was indicated on the opening post,
combined with toning this HUD code down to my own use (i removed the draw caps for bars, and checks for everything except full, half and empty bar.) I made it draw sideways and only display 2 bars of HP per sprite (as it was on shatterhand)
now it compiles just fine, aside that it's giving me a "unknown label" for DrawStatusBar now. but i dont really have hurt mechanics or player HP set up, yet so maybe it's that ?

the game was functioning as normally before i attempted to install this code, and reverting the changes described to install this will result in the game working again, so there is that.
i also tested both ways of installing this, by setting the macro in macros.asm, and by making my own macro, both ways function identically and do indicate that the macro is found and acnowledged (nothing of this works if the macro is not there.)

i can try and revert this back to the state of vanilla install to see if i can still reproduce the error at hand, or if you'd like jorotroid, i could send you the whole project base so you could see for yourself, if you're interested of seeing what broke.
i honest to god can't see any any error in backtracking my install steps here, and i did attempt it multiple times, always with identical results.

for reference, here's my modified macro, and predraw code:

Code:
checkForSpriteHUDDraw:
LDA gameState				; We want only want to make the HUD in the main gameState
BNE drawingSpriteHud
RTS

drawingSpriteHud:
	LDX player1_object			; When the player is alive, player1_object == #$00, but 
	BEQ thePlayerIsAlive			; when dead, player1_object == #$FF, so we need to ensure
	LDA #$00				; #$00 gets passed in for the health value when the player	
	STA temp3				; when the player is dead.
	JMP letsGetThisHUDStarted

thePlayerIsAlive:
	LDA Object_health,x
	STA temp3
		
letsGetThisHUDStarted:
	;; Draw the Health Bar
	;DrawStatusBar #$08, #$18, temp3, #$2F, #$3F, #$4F, #$5F, #$6F, #%00000001

	RTS

the "DrawStatusBar" is commented out here for the health bar because like i said, now it compiles and works as it was, but uncommenting it will give me an "unknown label" error, so that's not good.

Code:
MACRO DrawStatusBar arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
	;; arg0 x position of bottom bar segment
	;; arg1 y position of bottom bar segment
	;; arg2 value bar is displaying
	;; arg3 location of empty graphic
	;; arg4 location of 1/4 graphic
	;; arg5 location of 1/2 graphic
	;; arg6 location of 3/4 graphic
	;; arg7 location of full graphic
	;; arg8 attribute data (bits 0 and 1 determine which palette is used)
	
		
	LDA #$00		
	STA temp2		;Number of full sprites
	STA temp1		;if there is a partial sprite and what is it
	LDA #$08		
	STA temp		;Number of empty sprites
		
		
	LDA arg2
	BEQ readyToDrawHealthBar
	AND #%11111000
	CMP #%11111000
	BNE checkForHalf
		;; Full
		LDA #$08
		STA temp2
		JMP drawHealthBar
		
checkForHalf:
	LDA arg2
	AND #%10000000
	BEQ checkForQuarter
		;;;  Half Full
		LDA #$04
		STA temp2
			

drawHealthBar:

		
	LDA temp		
	SEC
	SBC temp2		;Number of full sprites
	STA temp		;Number of empty sprites
	BEQ readyToDrawHealthBar	;If we only have full sprites, then we can go ahead and draw
	LDA temp1
	BEQ readyToDrawHealthBar	;Does an empty sprite need to be replaced with a partial sprite?
		DEC temp
			
readyToDrawHealthBar:
	LDX temp
	LDA arg0
	STA temp	;Now temp is the x position of drawing from bottom up
emptySpritesLoop:
	TXA
	BEQ partialSpriteDraw
	DrawSprite arg0, temp, arg3, arg8, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
		
	LDA temp
	CLC
	ADC #$08
	STA temp

	DEX
	JMP emptySpritesLoop
		
partialSpriteDraw:

	LDA temp1
	BEQ readyToDrawEmptyBars
	DrawSprite arg0, temp, temp1, arg8, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
		
	LDA temp
	CLC
	ADC #$08
	STA temp
		
		
		
readyToDrawEmptyBars:
	
	LDX temp2		;Loaded into X for iteration
		
		
fullSpritesLoop:
	TXA				;8
	BEQ doneWithHealthBar
	DrawSprite arg0, temp, arg7, arg8, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
		
	LDA temp
	CLC
	ADC #$08
	STA temp
		
	DEX
	JMP fullSpritesLoop
		
doneWithHealthBar:

ENDM
 

Mugi

Member
im not really sure either, but with a tiny bit of external help, i made everything work, and finished up the modifications.
i wont spam the thread any further with this, but i'll just throw a mention here if someone is interested of a variation.

what i created is a variation of this hud, that;

1) draws horizontally
2) counts up to 8 HP (first 4bits) instead of 256 HP by holding 2 HP per sprite and will draw full and half sprites accordingly (i made it after shatterhand, where you have 8 HP, and everything does 1 damage.)

the code is slightly more compact than jorotroids original, so if you dont have a need for a 256 HP and such, the variation consumes slightly less program space.

game_015.png
 

dale_coop

Moderator
Staff member
Sounds great Mugi, congrats! I am interested in your version of the code, if you don't mind to share it (or in a new post).
 

Mugi

Member
sure thing, here you go.

predraw
Code:
checkForSpriteHUDDraw:
LDA gameState				; We want only want to make the HUD in the main gameState
BNE drawingSpriteHud
RTS

drawingSpriteHud:

	;; Draws the health symbol at the left side of the bar
	DrawSprite #$08, #$E0, #$7C, #%00000001, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset

	LDX player1_object			; When the player is alive, player1_object == #$00, but 
	BEQ thePlayerIsAlive			; when dead, player1_object == #$FF, so we need to ensure
	LDA #$00				; #$00 gets passed in for the health value when the player	
	STA temp3				; when the player is dead.
	JMP letsGetThisHUDStarted

thePlayerIsAlive:
	LDA Object_health,x
	STA temp3
		
letsGetThisHUDStarted:
	;; Draw the Health Bar
	DrawStatusBar #$18, #$E0, temp3, #$7F, #$11, #$7E, #$11, #$7D, #%00000001

	RTS

macro:
Code:
MACRO DrawStatusBar arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
	;; arg0 x position of bottom bar segment
	;; arg1 y position of bottom bar segment
	;; arg2 value bar is displaying
	;; arg3 location of empty graphic
	;; arg4 location of 1/4 graphic
	;; arg5 location of 1/2 graphic
	;; arg6 location of 3/4 graphic
	;; arg7 location of full graphic
	;; arg8 attribute data (bits 0 and 1 determine which palette is used)

	LDA #$00		
	STA temp2		;Number of full sprites
	STA temp1		;if there is a partial sprite and what is it
	LDA #$04		
	STA temp		;Number of empty sprites

	LDA arg2
	;see if health empty
	AND #%00001111
	BEQ readyToDrawHealthBar
	; store full sprite number
	LSR a
	STA temp2
	; no bit was left over
	BCC drawHealthBar
	; bit left over, our half sprite
	LDA arg5
	STA temp1

drawHealthBar:
	LDA temp		
	SEC
	SBC temp2		;Number of full sprites
	STA temp		;Number of empty sprites
	BEQ readyToDrawHealthBar	;If we only have full sprites, then we can go ahead and draw
	LDA temp1
	BEQ readyToDrawHealthBar	;Does an empty sprite need to be replaced with a partial sprite?
	DEC temp ;remove 1 empty sprite for partial

readyToDrawHealthBar:
	LDX temp2
	LDA arg0
	STA temp2	;Now temp2 is the x position of drawing from left to right

fullSpritesLoop:
	TXA
	BEQ partialSpriteDraw
	DrawSprite temp2, arg1, arg7, arg8, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset

	LDA temp2
	CLC
	ADC #$08
	STA temp2

	DEX
	JMP fullSpritesLoop

partialSpriteDraw:
	LDA temp1
	BEQ readyToDrawEmptyBars
	DrawSprite temp2, arg1, temp1, arg8, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
		
	LDA temp2
	CLC
	ADC #$08
	STA temp2

readyToDrawEmptyBars:
	LDX temp		;Loaded into X for iteration
emptySpritesLoop:
	TXA
	BEQ doneWithHealthBar
	DrawSprite temp2, arg1, arg3, arg8, spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
	inc spriteOffset
		
	LDA temp2
	CLC
	ADC #$08
	STA temp2

	DEX
	JMP emptySpritesLoop

doneWithHealthBar:

ENDM

how you use them is the same as jorotroid's original, you will have to set the macro as instructed.

it's not really that much different, aside that the predraw has less things as it only draws the life indicator (one sprite) as opposed to the 4 "caps" of the bars.
on the macro, the calculation to determine what to draw is much shorter due to simplified logic.

for tiles, you will need a life indicator sprite (8x8), and full, half and empty life bar tiles, i drew mine as 4x8 so that 2 blibs of HP displays in one sprite. this is what the script expects.


it is recommended to set the bar to the very top or very bottom of the screen due to the fact that it draws 5 sprites horizontally, so if it sits in an area of the screen where other sprites move, it will cause issues.
 
Top Bottom