Assets, code organization, and draw vs update

Context: I like to organize my assets into their own file. Such as HUD assets go into the HUD file. The HUD file contains things like fuel gauge, health gauge and stuff. They to our their own file and are imported into HUD. This way on my main.lua file I can just do import HUD and it brings everything with it.

The Problem: I want to pass information back and forth between files but they're not working.

As in the HUD class, I have fuel which uses draw something like fuel:draw() it only draws once. What I want is for my car class which has like car.fueltank to pass it's fuel to the HUD so it can show the remaining fuel on screen.

I like the simplicity of this setup


import "coreLibs/object"
import "coreLibs/graphics"
import "coreLibs/sprites"

local pd <const> = playdate
local gfx <const> = pd.graphics


class('Fuel').extends(playdate.graphics.sprite)

local fuel = Fuel()
fuel:setZIndex(1000)
fuel:setSize(100, 50)
fuel:setCollideRect(0,0,100,20)
fuel:moveTo(100, 100)
fuel:addSprite()
fuel.percentage = 100

local Test = 10000
function fuel:draw(p)
    Test-=1
    print("Fuel draw ",tst)
	local cx, cy, width, height = self:getCollideBounds()
    gfx.setColor(playdate.graphics.kColorBlack)
	gfx.fillRect(cx, cy, Test, height)
    gfx.drawText("Fuel",cx,cy)
end

I really like this way because it's easy and works very well. But I don't know how to update the width of the fuel gauge, seems to draw once then it's done.

If I do something like this in my main.lua file

local function initalize()
	car = Car(277,0,1,1)
	car ()

 	 local backgroundImage = gfx.image.new("images/background")
	gfx.sprite.setBackgroundDrawingCallback(
		function(x,y,width,height)
			gfx.setClipRect(x,y,width,height)
			backgroundImage:draw(0,0)
	        gfx.clearClipRect()

			gfx.fillRect(5, 210, car:getRemainingFuel(), 25)
			gfx.setImageDrawMode(playdate.graphics.kColorXOR)
			gfx.drawText("Fuel",50,215)
			
		end
	)
end

It' works well, but it removes my background (because in my car class I'm doing gfx.sprite.redrawBackground() and I guess the setBackgroundDrawingCallback doesn't like that). It also seems way to complicated. I'm going to have a few more assets on screen and hate to have to continue this messy code.

I've tried putting the gfx.fillRect directly inside the playdate:update, but it doesn't seem to work.

My Inital thought on how it should work is.

  • I have my Car class
    -- car class holds properties like : gassTank,efficiency,remaining gass
  • On button press or something fuel is taken out of the tank
  • On Main which imports Hud I could pass car.remainingFuel to Hud HUD then passes that to fuel. Then when fuel updates via draw or playdate.Update the UI updates and I see it on screen. Yet I can't seem to get that right without over complicating it like above.

I COULD just write everything inside of main, but that gets real messy real quick. I'd prefer to just keep everything isolated.

How do some of the rest of you manage your files? Do you typically use draw and pickup updated properties a different way? or use a sprite class and use playdate.update?

I think your organisational structure is sensible and will work. I organise my games similarly.

Your drawing technique is currently too complicated and not well organised.

I think you should use sprites (draw your fuel gauge to an image that is set to a sprite, or in the sprite draw callback) and let the sprite system take care of the dirty details!

Take a look at SDK/Examples/FlippyFish

This darn fuel gauge/progress bar is going to kill me >...<

Great to hear you're with me. I defiantly prefer the structure. I was just wondering if I was fighting the system or perhaps making it harder just to keep coding structure.

Update!
I really like FlippyFish's structure. I guess I'm confused on how one sprite class and use values from another. The FlippyFish example doesn't seem to do that.

For example, I need my Car class to pass the remaining fuel to the UI Class so it can be shown on screen.

Unless you're suggesting scrap all that, and just have the Car class also draw the remaining fuel on screen itself.

For me that goes against separation of duties. The Car class should only care about itself. And the UI should only care about UI stuff (besides using data from car to drive the data on UI)

As you can see I'm.... being pulled in many direction and just looking to see how other people (looking at you matt ^...^) solved this problem.

Let's do it your way.

Please create a minimal example on GitHub, invite me, and we can make it work together in public!

Here how I would approach it.

I tend to have a game object (usually just a table, it's not even a class) that hold references to all the important object in the game. If the project is small, I don't even bother and put everything as a global.

I would have a Car object and a fuelUI object.

The fuelUI object would have have a playdate.graphics.image object and a playdate.graphics.sprite (you could inherit the fuelUI object from a sprite but I tend to avoid inheritance to avoid over-architecture). The sprite would use the image of course.
The fuelUI object can have a function setRemainingFuel( level ) that would save the fuel level in the object and redraw the image if the level changed.

So the Car object in their update can set the remaining fuel by calling game.fuelUI.setRemainingFuel( some_number )

I am not sure if this is helpful but this is how I tend to do it. A big game object that have reference to all the important other objects so everything is accessible from anywhere.