Most optimal way to update life bar?

So to make it easer I have a life bar sprite with 10 frames.
A persons life is 100.

In an enemy collision function, the sprite is updated with:
bar = display.NewImage(sprite_data,life/10)

However this seems to be slowing down my code (collision taking longer than expected or slows down).

When I remove the life bar, collisions and everything go smooth.

Does anyone have any examples on how they implemented the life bar?

I did this with another game I made and the same thing is happening.

Make it a sprite instead, then you just change the frame depending on the amount of life left. This way you won’t get stuttering as the game loads in a brand new texture each time.

https://docs.coronalabs.com/api/library/display/newSprite.html

https://docs.coronalabs.com/guide/media/spriteAnimation/index.html

What does your bar look like? If it’s not particularly fancy, you could just use a newRect, anchored centerLeft, and change the width depending on the amount of life left. You could even overlay a fancy graphic over the top of the rect to make it look prettier.

Your code does not update the image, it seems: you are not replacing the old image with a new one, you are just adding a new one (while still keeping the old one). Or at least it looks that way in your code. Make sure you do the following:

  1. Make sure you only call the ‘update image’ code once for every collision. I don’t know how you call your update-life-bar code, but sometimes code gets called every frame (instead of just once), while one object is inside a specific collision area. Make sure your code includes an “if branch” or conditional statement that specifies "IF you haven’t update the life bar for this collision, then update it. If it has already been updated, don’t do anything.

  2. As Nick says, use sprites, and set setFrame command.

  3. Or, also as Nick mentions, you can make great life bars by scaling a rectangle placed instead a fancy graphics frame. This has the benefit of not create extra geometry or textures, which takes more of a hit on the processor. That being said, switching sprites should not affect your game speed that much, unless the resolution of the images is very high.

Please supply some links to images of ‘lifebars’ that you like. There are so many ways to do this, it will help give us a starting point.

This is the simplest life bar I can think of:

local function newPercentBar( group, x, y, width, height, fill, intitialPercent ) group = group or display.currentStage local bar = newRect( group, x - width/2, y, width, height ) bar:setFillColor( unpack(fill) ) bar.anchorX = 0 -- function bar:setPercent( percent ) percent = percent \< 0 and 0 or percent percent = percet \> 100 and 100 or percent self.alpha = (percent == 0) and 0 or 1 self.xScale = (percent \> 0 ) and (percent/100) or 1 self.percent = percent end function bar:getPercent() return self.percent end bar:setPercent( initialPercent ) end

Now use it like this:

local bar1 = newPercentBar( nil, display.contentCenterX, display.contentCenterY, 200, 40, {1,1,0}, 80 ) bar1:setPercent( 50 )

You can modify that to add an overlay or a frame quite easily.

You can also extend it to animate/change bar fill and/or color over time.

Ok well here is my code.

I realised my code is not causing it to lag…there is actually no lag at all.

Its a  problem with my collisions.

Anyways here is my health bar update code:

Critique it as you like:

local bar\_data = { width=122, height=382, numFrames=16, sheetContentWidth=1952, sheetContentHeight=382, filename="healthbar.png"} local bar\_sheet = graphics.newImageSheet( "healthbar.png", bar\_data ) local bar = display.newImage(GUIGroup,bar\_sheet,16) bar.x=display.contentCenterX+125 bar.y=display.contentCenterY-10 bar:scale(0.7,0.7) local function bar\_update() if life~=0 then display.remove(bar) bar = display.newImage(GUIGroup,bar\_sheet,life/6.25) bar.x=display.contentCenterX+125 bar.y=display.contentCenterY-10 bar:scale(0.7,0.7) end end Runtime:addEventListener("enterFrame",bar\_update)

There’s a few working life bars in the Ponywolf template games…

https://marketplace.coronalabs.com/vendor/ponywolf

This code looks nice and clean but it throws an error when you run it as is:

attempt to call global ‘newRect’ (a nil value)

stack.traceback:

main.lua:92: in function ‘newPercentBar’

main.lua:124: in main chunk

I would guess that’s because @roaminggamer normally creates a ‘shortcut’ such as

local newRect = display.newRect

which saves on the amount of typing needed in a large project.

if you change this line

local bar = newRect( group, x - width/2, y, width, height )

to

local bar = display.newRect( group, x - width/2, y, width, height )

then it should work.

you can improve your code a bit.

first dont use bar.x = whateverX, use translate(whateverX, whateverY). it’s faster.

second don’t use scale to reduce your bar. just reduce the imagesheet 30%.

third, your creating 30/60 images per second depending on your config.lua. i would never use this approach. I would only update the function if anything will happen to the value directly linked to the bar. I don’t think a runtime is needed for a health progress bar.

forth, i would never create 30/60 images per second for a progress bar. i would prefer a method of filling or creating a custom bar using rectangle with a mask if you want that “custom” feel. @roaminggamer was a better approach regarding of speed.

Make it a sprite instead, then you just change the frame depending on the amount of life left. This way you won’t get stuttering as the game loads in a brand new texture each time.

https://docs.coronalabs.com/api/library/display/newSprite.html

https://docs.coronalabs.com/guide/media/spriteAnimation/index.html

What does your bar look like? If it’s not particularly fancy, you could just use a newRect, anchored centerLeft, and change the width depending on the amount of life left. You could even overlay a fancy graphic over the top of the rect to make it look prettier.

Your code does not update the image, it seems: you are not replacing the old image with a new one, you are just adding a new one (while still keeping the old one). Or at least it looks that way in your code. Make sure you do the following:

  1. Make sure you only call the ‘update image’ code once for every collision. I don’t know how you call your update-life-bar code, but sometimes code gets called every frame (instead of just once), while one object is inside a specific collision area. Make sure your code includes an “if branch” or conditional statement that specifies "IF you haven’t update the life bar for this collision, then update it. If it has already been updated, don’t do anything.

  2. As Nick says, use sprites, and set setFrame command.

  3. Or, also as Nick mentions, you can make great life bars by scaling a rectangle placed instead a fancy graphics frame. This has the benefit of not create extra geometry or textures, which takes more of a hit on the processor. That being said, switching sprites should not affect your game speed that much, unless the resolution of the images is very high.

Please supply some links to images of ‘lifebars’ that you like. There are so many ways to do this, it will help give us a starting point.

This is the simplest life bar I can think of:

local function newPercentBar( group, x, y, width, height, fill, intitialPercent ) group = group or display.currentStage local bar = newRect( group, x - width/2, y, width, height ) bar:setFillColor( unpack(fill) ) bar.anchorX = 0 -- function bar:setPercent( percent ) percent = percent \< 0 and 0 or percent percent = percet \> 100 and 100 or percent self.alpha = (percent == 0) and 0 or 1 self.xScale = (percent \> 0 ) and (percent/100) or 1 self.percent = percent end function bar:getPercent() return self.percent end bar:setPercent( initialPercent ) end

Now use it like this:

local bar1 = newPercentBar( nil, display.contentCenterX, display.contentCenterY, 200, 40, {1,1,0}, 80 ) bar1:setPercent( 50 )

You can modify that to add an overlay or a frame quite easily.

You can also extend it to animate/change bar fill and/or color over time.

Ok well here is my code.

I realised my code is not causing it to lag…there is actually no lag at all.

Its a  problem with my collisions.

Anyways here is my health bar update code:

Critique it as you like:

local bar\_data = { width=122, height=382, numFrames=16, sheetContentWidth=1952, sheetContentHeight=382, filename="healthbar.png"} local bar\_sheet = graphics.newImageSheet( "healthbar.png", bar\_data ) local bar = display.newImage(GUIGroup,bar\_sheet,16) bar.x=display.contentCenterX+125 bar.y=display.contentCenterY-10 bar:scale(0.7,0.7) local function bar\_update() if life~=0 then display.remove(bar) bar = display.newImage(GUIGroup,bar\_sheet,life/6.25) bar.x=display.contentCenterX+125 bar.y=display.contentCenterY-10 bar:scale(0.7,0.7) end end Runtime:addEventListener("enterFrame",bar\_update)

There’s a few working life bars in the Ponywolf template games…

https://marketplace.coronalabs.com/vendor/ponywolf

This code looks nice and clean but it throws an error when you run it as is:

attempt to call global ‘newRect’ (a nil value)

stack.traceback:

main.lua:92: in function ‘newPercentBar’

main.lua:124: in main chunk

I would guess that’s because @roaminggamer normally creates a ‘shortcut’ such as

local newRect = display.newRect

which saves on the amount of typing needed in a large project.

if you change this line

local bar = newRect( group, x - width/2, y, width, height )

to

local bar = display.newRect( group, x - width/2, y, width, height )

then it should work.