Moving animated images

Hi all…

I’ve been working on my game for about 3000 hours now and I’m in the process of making it look more professional by making the graphics better.

So far I’ve only been using static images but I want to add some animation and I’ve got stuck on the first attempt.

I want to move spinning coins from the centre of the screen to the score graphic. You see them in lots of games.

I created 10 images of a coin in different aspects and iterate through them in a table which works great but moving that animated coin is another story.

I’ve discovered that using timer.perfromWithDelay is too slow even if you set the delay to 1/1000 of a second.

I’ve looked at sprites but I can’t find any tutorials on how to make sprite sheets, I don’t want to buy third party software if it all possible, I want to do it myself to save money because I don’t have much to spare.

Here’s my attempt at moving an animated coin, it moves at a snails pace and I want to have lots of coins.

Any ideas anyone?

Load the 10 coin graphics into a table…

**coinwidth[1] = 63; coinwidth[2] = 48; coinwidth[3] = 39; coinwidth[4] = 25; coinwidth[5] = 16
    coinwidth[6] = 5; coinwidth[7] = 16; coinwidth[8] = 25; coinwidth[9] = 39; coinwidth[10] = 48

    for i = 1, 10 do
        coin[i] = display.newImageRect(“images/goldcoin”…i…".png", coinwidth[i], 66)
        coin[i].x = (_W*0.5); coin[i].y = (_H*0.64)
        coin[i].isVisible = false
    end**

Create a table to hold 10 coins ( each has 10 images )…

**local coinVar = {}

    for n = 1, 10 do

        coinVar[n] = {}

        for i = 1, 10 do

            coinVar[n][i] = coin[i]
            mainGroup:insert(coinVar[n][i])
            
        end
    end**

And make a function to iterate through the coin(s) so they appear to spin…

**    local rotateCoins = function()

        if i > 1 then
        coinVar[m][i-1].isVisible = false
        end

        if i == 1 then
        coinVar[m][10].isVisible = false
        end

        coinVar[m][i].isVisible = true

            i = i + 1

            if i == 11 then
                i = 1
            end
    end**

And my attepmt at moving the animated coin(s) across the screen using another function…

l**ocal moveCoins = function()

        coinVar[m][i].x = coinVar[m][i].x +1
        coinVar[m][i].y = coinVar[m][i].y -1

    end

    local controlCoins = function()

    myTimer = timer.performWithDelay( 5, rotateCoins , 1 )
    myTimer = timer.performWithDelay( 5, moveCoins , 1 )

    end

    myTimer = timer.performWithDelay( 5, controlCoins , 400 )**

In the above code I have the possibilty to have 10 coins on the screen but I’m only moving one for now which moves really really slow across the screen. The spinning animation works great at any speed but it’s the movement that’s the problem.

Any help would be greatly appreciated.

Wow, you made it really, really difficult for yourself. You basically implemented a sprite engine of your own. The good news is that Corona already has a sprite engine, and there are tutorials to help you do this the right way :slight_smile:

Read this on making sprites http://coronalabs.com/blog/2012/10/02/animated-sprites-and-methods/

And this on making image sheets: http://coronalabs.com/blog/2013/05/14/sprites-and-image-sheets-for-beginners/

Have fun!

Here’s an example from one of my own projects, it’s an animated bird based on a sprite sheet with 8 images:

local birdSheetData = {width = 128, height = 128, numFrames = 8, sheetContentWidth = 1024, sheetContentHeight = 128} local birdSheet = graphics.newImageSheet("img/bird-sheet.png", birdSheetData) local birdSequenceData = {{name = "fly", start = 1, count = 8, loopDirection = "bounce", time = 300}} local bird = display.newSprite(birdSheet, birdSequenceData) bird:play()

… as you see, just a few lines of code :slight_smile:

Also, don’t forget you can use math.sin to create the illusion of a spinning coin like this

myCoin.width = 50 \* math.abs(math.sin(event.time/100))

if you put something like the above pseudocode in your enterFrame event.

Thanks so much for taking the time to reply Thomas & Memo

Thomas, I will play around with that code snippet, it’s looks interesting.

Memo, I must have been looking in the wrong places, I couldn’t find the “sprites and image sheets for beginners”, I’ve just read it and started working with it, thanks very much!

More help needed I’m affraid.

I’ve successfully created my coin sprite and I can transition it with the desired effect but I have hit another brick wall and can’t find the answer after searching for over an hour again.

I want multiple coins so I’ve tried making a table like this…

local coinSprite = {}

**for i = 1, 20 do

          local coinSprite[i] = display.newSprite( coinSheet, sequenceData )
            coinSprite[i].x = _W*0.5
            coinSprite[i].y = _H*0.64
            coinGroup:insert( coinSprite[i] )
            coinSprite[i]:setSequence( “coin” … 12 )**

end

But Corona doesn’t like the brackets on the end of coinSprite, so I tried this…

local coinSprite = display.newSprite( coinSheet, sequenceData )
            coinSprite.x = _W*0.5
            coinSprite.y = _H*0.64
            coinGroup:insert( coinSprite )
            coinSprite:setSequence( “coin” … 12 )

local coinBat = {}

for i = 1, 20 do
        coinBat[i] = coinSprite
    end

But when I iterate through the coinBat table and add a different transition to each instance I end up with just one sprite on the screen…

**for i = 1, 20 do

            local av = math.random(60, 360)
            local tm = math.random(4000, 8000)
            local x = coinBat[i].x
            local y = coinBat[i].y

            coinBat[i].angularVelocity = av

            coinBat[i]:play()

        local myTransition = transition.to( coinBat[i], { time=tm, alpha=0, x=x+av, y=y-av } )

    end**

The above code works if I create 20 coinSprites like this…

local coinSprite1 = display.newSprite( coinSheet, sequenceData )
            coinSprite1.x = _W*0.5
            coinSprite1.y = _H*0.64
            coinGroup:insert( coinSprite1 )
            coinSprite1:setSequence( “coin” … 12 )

local coinSprite2 = display.newSprite( coinSheet, sequenceData )

local coinSprite3 = display.newSprite( coinSheet, sequenceData )

and add them to the coinBat[i] table but this creates hundreds of lines of code.

Is there a way to make multiple (individual) sprites from 1 sprite, like space invaders for example?

local coinSprite = {}

 

**for i = 1, 20 do

          local coinSprite[i] = display.newSprite( coinSheet, sequenceData )
            coinSprite[i].x = _W*0.5
            coinSprite[i].y = _H*0.64
            coinGroup:insert( coinSprite[i] )
            coinSprite[i]:setSequence( “coin” … 12 )**

end
 

local coinSprite[i] is wrong. You must remove “local” in this case, as you’ve already declared the table outside of the loop.
You also must use this loop, as going the other route, with just coinSprite, will create only a single coin (that’s why you see only one sprite moving).

OMG!

Well spotted Ragdog, I removed the local and it worked, the problem was that the error was saying “unexpected […” which focused my attention on the bracket and not spotting the local inside a loop.

Thanks very much for your help.

Wow, you made it really, really difficult for yourself. You basically implemented a sprite engine of your own. The good news is that Corona already has a sprite engine, and there are tutorials to help you do this the right way :slight_smile:

Read this on making sprites http://coronalabs.com/blog/2012/10/02/animated-sprites-and-methods/

And this on making image sheets: http://coronalabs.com/blog/2013/05/14/sprites-and-image-sheets-for-beginners/

Have fun!

Here’s an example from one of my own projects, it’s an animated bird based on a sprite sheet with 8 images:

local birdSheetData = {width = 128, height = 128, numFrames = 8, sheetContentWidth = 1024, sheetContentHeight = 128} local birdSheet = graphics.newImageSheet("img/bird-sheet.png", birdSheetData) local birdSequenceData = {{name = "fly", start = 1, count = 8, loopDirection = "bounce", time = 300}} local bird = display.newSprite(birdSheet, birdSequenceData) bird:play()

… as you see, just a few lines of code :slight_smile:

Also, don’t forget you can use math.sin to create the illusion of a spinning coin like this

myCoin.width = 50 \* math.abs(math.sin(event.time/100))

if you put something like the above pseudocode in your enterFrame event.

Thanks so much for taking the time to reply Thomas & Memo

Thomas, I will play around with that code snippet, it’s looks interesting.

Memo, I must have been looking in the wrong places, I couldn’t find the “sprites and image sheets for beginners”, I’ve just read it and started working with it, thanks very much!

More help needed I’m affraid.

I’ve successfully created my coin sprite and I can transition it with the desired effect but I have hit another brick wall and can’t find the answer after searching for over an hour again.

I want multiple coins so I’ve tried making a table like this…

local coinSprite = {}

**for i = 1, 20 do

          local coinSprite[i] = display.newSprite( coinSheet, sequenceData )
            coinSprite[i].x = _W*0.5
            coinSprite[i].y = _H*0.64
            coinGroup:insert( coinSprite[i] )
            coinSprite[i]:setSequence( “coin” … 12 )**

end

But Corona doesn’t like the brackets on the end of coinSprite, so I tried this…

local coinSprite = display.newSprite( coinSheet, sequenceData )
            coinSprite.x = _W*0.5
            coinSprite.y = _H*0.64
            coinGroup:insert( coinSprite )
            coinSprite:setSequence( “coin” … 12 )

local coinBat = {}

for i = 1, 20 do
        coinBat[i] = coinSprite
    end

But when I iterate through the coinBat table and add a different transition to each instance I end up with just one sprite on the screen…

**for i = 1, 20 do

            local av = math.random(60, 360)
            local tm = math.random(4000, 8000)
            local x = coinBat[i].x
            local y = coinBat[i].y

            coinBat[i].angularVelocity = av

            coinBat[i]:play()

        local myTransition = transition.to( coinBat[i], { time=tm, alpha=0, x=x+av, y=y-av } )

    end**

The above code works if I create 20 coinSprites like this…

local coinSprite1 = display.newSprite( coinSheet, sequenceData )
            coinSprite1.x = _W*0.5
            coinSprite1.y = _H*0.64
            coinGroup:insert( coinSprite1 )
            coinSprite1:setSequence( “coin” … 12 )

local coinSprite2 = display.newSprite( coinSheet, sequenceData )

local coinSprite3 = display.newSprite( coinSheet, sequenceData )

and add them to the coinBat[i] table but this creates hundreds of lines of code.

Is there a way to make multiple (individual) sprites from 1 sprite, like space invaders for example?

local coinSprite = {}

 

**for i = 1, 20 do

          local coinSprite[i] = display.newSprite( coinSheet, sequenceData )
            coinSprite[i].x = _W*0.5
            coinSprite[i].y = _H*0.64
            coinGroup:insert( coinSprite[i] )
            coinSprite[i]:setSequence( “coin” … 12 )**

end
 

local coinSprite[i] is wrong. You must remove “local” in this case, as you’ve already declared the table outside of the loop.
You also must use this loop, as going the other route, with just coinSprite, will create only a single coin (that’s why you see only one sprite moving).

OMG!

Well spotted Ragdog, I removed the local and it worked, the problem was that the error was saying “unexpected […” which focused my attention on the bracket and not spotting the local inside a loop.

Thanks very much for your help.