Swapping Image For Image Or Sprite

Following on from a query I had in another post Iam having to ask for help/suggestions once again.

I have a grid of objects (think space invader layout), I have a different image on each row.

I need to swap these images for sprites.

Sprites because I wouldnt have to alter my movement code then.

Iam familar with sprite sheets and use an external module for all sequences etc which I call into the main.lua.

Below is my stripped down code for the image call and for loops etc.

Any help would be most welacome, I have tried a number of things all to no avail.

[lua]-- enemys.lua –

function enemys:init(xloc, yloc, row )

    self.image = display.newImage(“images/enemy”…row…".png" )
    self.image:setReferencePoint( CenterReferencePoint )
    self.image.x = xloc
    self.image.y = yloc
    self.image.name = “enemy”
   
end [/lua]

[lua] – main.lua –

local enemys = require(“modules.enemy”)
        for j = 1, 5 do
        for i = 1, 11 do
        allEnemys[#allEnemys + 1] = enemys:new()
        allEnemys[#allEnemys]:init(i * 60, j* 70 +70,j )
        allEnemys[#allEnemys]:start()
        end

     end[/lua]

this is how I import my sprite data

[lua]display.newSprite(sprites.sheets.object,sprites.sequences.object)[/lua]

I was hoping it would be a simple method altering  “images/enemy”…row…“png”

thank you

You can’t swap images, per se - once you declare display.newImage(), that’s the image you get. To swap you would want to write a function that basically removes that object, nil’s it out, and replaces it with the new display.newImage() or display.newSprite() call. (But if your images are sprites to begin with, you can just :setFrame() to change its appearance!)

Just keep in mind that with sprites you construct them differently - you have to point at the sprite sheet (imageSheet) and frame sequence table. You can’t just load a raw image.

Please vote for the ability to switch display object images in Feedback.  I’ve been asking about this for a while now.  Spoke to Walter at length about it, and we might actually get it.

http://feedback.coronalabs.com/forums/188732-corona-sdk-feature-requests-feedback/suggestions/3814545-be-able-to-change-a-display-object-s-image-as-easy

@richard9, yes I see, however I apologise I may not have made myself clear enough.

I need to  implement a sprite sheet in  the code instead of an image.

For instance, I have a grid 5 rows by 11 columns  with a different image on each row, the code above will produce this.

Now I require a different sprite on each row and not an image. So I am trying to establish how to go about loading a sprite into each row.

Does that make sense?

and yes the image swapping would be useful BTT :slight_smile:

I guess it depends what you mean by “sprite”.

In Corona SDK, a sprite is just an image hooked up to an imageSheet (an image with multiple images in it). Apart from the fact that you have to initialize the sheet first (and can change frames) it behaves identically to .newImage.

So you have a few options:

  1. Make it a newSprite to begin with.

i. Create the imageSheet when you launch the program

ii. Make newSprite() instead of newImage()

iii. Change frames using :setFrame()

  1. Make a function to fake the switch.

i. Create the imageSheet when you launch the program

ii. Function step 1: Record the position and image name of the newImage()

iii. Create a new sprite using the imageSheet and the details you recorded

iv. display.remove() the newImage()

The actual method of making a sprite works like this:

-- 1. Make the imageSheet. It can be a single image if you want; it's just any png local options = {} -- this has to be details describing what's in the image, like number of frames, image size, etc local mySheet = graphics.newImageSheet( "myImage.png", options )   -- 2. Now, anywhere that the imagesheet can be "seen" by the code, you can make sprites from it. local sequence = {} -- this describes the frame order local coolSprite = display.newSprite(mySheet, sequence)

If you need any help with sequences or options, it’s easy for us to help, just need to know the exact issue. :slight_smile:

You can’t swap images, per se - once you declare display.newImage(), that’s the image you get. To swap you would want to write a function that basically removes that object, nil’s it out, and replaces it with the new display.newImage() or display.newSprite() call. (But if your images are sprites to begin with, you can just :setFrame() to change its appearance!)

Just keep in mind that with sprites you construct them differently - you have to point at the sprite sheet (imageSheet) and frame sequence table. You can’t just load a raw image.

Please vote for the ability to switch display object images in Feedback.  I’ve been asking about this for a while now.  Spoke to Walter at length about it, and we might actually get it.

http://feedback.coronalabs.com/forums/188732-corona-sdk-feature-requests-feedback/suggestions/3814545-be-able-to-change-a-display-object-s-image-as-easy

@richard9, yes I see, however I apologise I may not have made myself clear enough.

I need to  implement a sprite sheet in  the code instead of an image.

For instance, I have a grid 5 rows by 11 columns  with a different image on each row, the code above will produce this.

Now I require a different sprite on each row and not an image. So I am trying to establish how to go about loading a sprite into each row.

Does that make sense?

and yes the image swapping would be useful BTT :slight_smile:

I guess it depends what you mean by “sprite”.

In Corona SDK, a sprite is just an image hooked up to an imageSheet (an image with multiple images in it). Apart from the fact that you have to initialize the sheet first (and can change frames) it behaves identically to .newImage.

So you have a few options:

  1. Make it a newSprite to begin with.

i. Create the imageSheet when you launch the program

ii. Make newSprite() instead of newImage()

iii. Change frames using :setFrame()

  1. Make a function to fake the switch.

i. Create the imageSheet when you launch the program

ii. Function step 1: Record the position and image name of the newImage()

iii. Create a new sprite using the imageSheet and the details you recorded

iv. display.remove() the newImage()

The actual method of making a sprite works like this:

-- 1. Make the imageSheet. It can be a single image if you want; it's just any png local options = {} -- this has to be details describing what's in the image, like number of frames, image size, etc local mySheet = graphics.newImageSheet( "myImage.png", options )   -- 2. Now, anywhere that the imagesheet can be "seen" by the code, you can make sprites from it. local sequence = {} -- this describes the frame order local coolSprite = display.newSprite(mySheet, sequence)

If you need any help with sequences or options, it’s easy for us to help, just need to know the exact issue. :slight_smile:

Please can you give more info on setFrame as i cannot see anywhere in the docs about set Frame when you are not animating.

The use of sprite sheets for a simple image swap is fine (if time consuming to prepare) … but there is no documentation on this when its a 2 image swap.

What is in “sequence”… when it is just a 2 image sprite sheet?

Thanks,

(setFrameAPI page)

Think of a sequence as two things:

  1. A list of frames to play, and

  2. A pool of frames to choose from.

Even if you don’t want to play an animation, you’re best off creating a simple sequence that holds all the frames, so that you can choose from any one of them.  The most basic sequence looks like this:

local sequence = { name = "default", -- not sure if required, but helpful start = 1, -- whatever the first frame in the sheet is end = 8, -- whatever the last frame in the sheet is }

There are other options for things like timing, looping, etc. but if you’re just setting frames you just need this.

Typically sheets are a bit more complicated because you can do more efficient things like, say, include all of your UI elements in a sheet and then just use different sequences for different pieces. Some games put their entire art set into a single 2048x2048 sheet.

Thanks, i am trying this and it is not working.

Shouldn’t “end” be “count”?

Also when i try and do it i get an error.

Here is my code.

 local sequenceData = { name="select", start = 1, count = 2 } bgButtons[1] = display.newSprite( myButtonImageSheet , sequenceData ) bgButtons[1].x = display.contentWidth - 40 bgButtons[1].y = 120

then the eventlistener is 

local function setView(event) print("currentView " .. currentView) currentView = view for i=0, 4 do if currentView == i then bgButtons[i]:setFrame(1) else bgButtons[i]:setFrame(2) end end end

But every time it fails on setFrame(2).

I am simply trying to have buttons that show their state … 4 of them.

You’re right, it’s “count”. Whoops. What is the error message on :setFrame, by the way?

Your code seems reasonable from what little I can tell (you’re missing parts of the structure) but I do want to know what the 0-4 stuff is; by default in lua tables do not have a [0] entry unless you make one.

Doh!

I do normally start from 1, but too many years of coding other languages maybe distracted me on this one… 

It is working now that the loop starts from 1… 

Easy mistakes eh… 

Thanks very much for taking the time to help me out here !!!

Jez

Please can you give more info on setFrame as i cannot see anywhere in the docs about set Frame when you are not animating.

The use of sprite sheets for a simple image swap is fine (if time consuming to prepare) … but there is no documentation on this when its a 2 image swap.

What is in “sequence”… when it is just a 2 image sprite sheet?

Thanks,

(setFrameAPI page)

Think of a sequence as two things:

  1. A list of frames to play, and

  2. A pool of frames to choose from.

Even if you don’t want to play an animation, you’re best off creating a simple sequence that holds all the frames, so that you can choose from any one of them.  The most basic sequence looks like this:

local sequence = { name = "default", -- not sure if required, but helpful start = 1, -- whatever the first frame in the sheet is end = 8, -- whatever the last frame in the sheet is }

There are other options for things like timing, looping, etc. but if you’re just setting frames you just need this.

Typically sheets are a bit more complicated because you can do more efficient things like, say, include all of your UI elements in a sheet and then just use different sequences for different pieces. Some games put their entire art set into a single 2048x2048 sheet.

Thanks, i am trying this and it is not working.

Shouldn’t “end” be “count”?

Also when i try and do it i get an error.

Here is my code.

 local sequenceData = { name="select", start = 1, count = 2 } bgButtons[1] = display.newSprite( myButtonImageSheet , sequenceData ) bgButtons[1].x = display.contentWidth - 40 bgButtons[1].y = 120

then the eventlistener is 

local function setView(event) print("currentView " .. currentView) currentView = view for i=0, 4 do if currentView == i then bgButtons[i]:setFrame(1) else bgButtons[i]:setFrame(2) end end end

But every time it fails on setFrame(2).

I am simply trying to have buttons that show their state … 4 of them.

You’re right, it’s “count”. Whoops. What is the error message on :setFrame, by the way?

Your code seems reasonable from what little I can tell (you’re missing parts of the structure) but I do want to know what the 0-4 stuff is; by default in lua tables do not have a [0] entry unless you make one.

Doh!

I do normally start from 1, but too many years of coding other languages maybe distracted me on this one… 

It is working now that the loop starts from 1… 

Easy mistakes eh… 

Thanks very much for taking the time to help me out here !!!

Jez

Swapping out images would be good to have mainly because that’s how it’s done in the other environments, allowing for easier migration to Corona SDK both of apps and coders :wink:

It also allows keeping all the settings of the image, including the z-index (determined by order of creation). Re-creating the image (and usually also re-inserting it into some scrollView, overlay or other parent view) would put it frontmost.

Certainly you could create a sprite frame sheet, if you have a Photoshop license or the equivalent, and that gives better performance.

But it would be one of those handy things for the one-off image swaps that don’t need performance. It might also save a bit on the GC?