Search code examples
luaspritecoronasdklua-table

How to use an id to load sprite sheets and img files in Corona SDK?


The title sounds confusing, but what I am looking for is something like this: https://www.youtube.com/watch?v=GhI98-HJk6o

Just watch the first minute, notice when the player taps the bottom squares the appropriate unit is spawned. I am trying to achieve this in Corona SDK, but I have been getting stuck a lot recently and I hope you guys can help.

What I tried to do was this:

local m = {} -- characters.lua

m.units = {
   {img = "sprites/girl.png", timeBetweenAtk = 2350, name = girl, cost = 75, respawnTime = 3750, state = active}
}

m.girl = {}
m.girl.walking = {}
local data = {width = 309, height = 494, numFrames = 10, sheetContentWidth = 1545, sheetContentHeight = 988}
m.girl.walking.sheet = graphics.newImageSheet("sprites/walking-girl.png", data )
m.girl.walking.seq = {name = "walking", start = 1, count = 10, loopCount = 0, loopDirection = "forward"}

m.girl.primaryAtk = {}
local data = {width = 385, height = 477, numFrames = 10, sheetContentWidth = 1925, sheetContentHeight = 954}
m.girl.primaryAtk.sheet = graphics.newImageSheet("sprites/melee-girl.png", data)
m.girl.primaryAtk.seq = {name = "melee", start = 1, count = 10, loopCount = 0, loopDirection = "forward"}

m.girl.idle = {}
local data = {width = 271, height = 473, numFrames = 10, sheetContentWidth = 813, sheetContentHeight = 1892}
m.girl.idle.sheet = graphics.newImageSheet("sprites/idle-girl.png", data)
m.girl.idle.seq = {name = "idle", start = 1, count = 10, loopCount = 0, loopDirection = "forward"}

return m

And then I made a function in main.lua, to call the correct sprite:

local characters = require "characters"

for k = 1, #imgSet do
  local function spawnCharacter(event)
     local identifier = characters.units[k].name
     if event.phase == "began" then
       if moneyCount < characters.units[k].cost then
          print("insufficient funds")
       else
          moneyCount = moneyCount - characters.units[k].cost
          moneyText.text = moneyCount .. " / " .. moneyWallet
          local unit = display.newSprite(characters.identifier.walking.sheet, characters.identifier.walking.seq)
       end
     end
     return true
  end
  imgSet[k]:addEventListener("touch", spawnCharacter)
end

But now I know that it is not possible to concatenate display objects, so does anyone know if there is another way to do this.


Solution

  • I think you want to use string as identifier. In your setup:

    m.units = {
     {
       img = "sprites/girl.png", 
       timeBetweenAtk = 2350, 
       name = "girl", --seems like girl variable not declared so in your code you got nil
       cost = 75, 
       respawnTime = 3750, 
       state = active -- probably same issue - use string here or some pre-defined variable
      }
    }
    

    So with my code you got m.units[1].name == "girl"

    Now you can use it in spawn function:

    local function spawnCharacter(event)
      local charToSpawn = characters.units[k]
      local identifier = charToSpawn.name
      if event.phase == "began" then
        if moneyCount < charToSpawn.cost then
          print("insufficient funds")
        else
          moneyCount = moneyCount - charToSpawn.cost
          moneyText.text = moneyCount .. " / " .. moneyWallet
    
          local charWalkingData = characters[identifier].walking -- proper use of string identifier here
          local unit = display.newSprite(charWalkingData.sheet, charWalkingData.seq)
        end
      end
      return true
    end
    

    Put attention on this line: characters[identifier] If your identifier variable contains string, i.e. "girl" this calls are simular:

    characters[identifier]
    characters["girl"] -- assuming identifier = "girl" in this example
    characters.girl