Need Help To Control Speed (Sprite Speed)

Hi everyone,

I have a issue related to the speed of sprite, in the start of my game, sprite moves properly but just after when I tap to kill it, next time when it appears, its speed in more than the speed of previous once.

NOTE: next sprite appears when the existing once is removed or killed.

Any help would be greatly appreciated.

here is my code;

function for sprite creation and sequence
[lua]function spawnCharacter()

    

    local sheetData1 = { width=32, height=32, numFrames=12, sheetContentWidth=96, sheetContentHeight=128 }

    local mySheet1 = graphics.newImageSheet( “bad5.png”, sheetData1 )

    local sequenceData1 = {

                            { name = “front”, frames={ 1,2,3 }, time=1000 },

                            { name = “left”, frames={ 4,5,6 }, time=1000 },

                            { name = “right”, frames={ 7,8,9 }, time=1000 },

                            { name = “back”, frames={ 10,11,12 }, time=1000 }

                        }

    

    enemy = display.newSprite( mySheet1, sequenceData1 )

    

    enemy:setSequence( “right” )

    enemy:play()

    

    enemy.moveX = math.random( 2, 5 )

    enemy.moveY = math.random( 2, 5 )

enemy:addEventListener ( “tap”, kill )

    timer.performWithDelay( 0, moveCharacter, 0 )

end[/lua]

function to kill the bad man (remove the object)

[lua]function kill(event)

    local obj = event.target

    display.remove( obj )

    score = score + 28

    scoreTxt.text = "Score: " … score

    spawnCharacter()

    return true

end[/lua]

function for sprite movement on screen

[lua]local function moveCharacter()

    – let’s make him bounce around the screen

    if enemy.x < 0 or enemy.x > display.contentWidth then 

        enemy.moveX = -enemy.moveX 

    end

    if enemy.y < 0 or enemy.y > display.contentHeight then 

        enemy.moveY = -enemy.moveY 

    end

    enemy.x = enemy.x + enemy.moveX

    enemy.y = enemy.y + enemy.moveY

end[/lua]

Is your enemy variable global?

when removing an object you should do.
 

enemy:removeSelf() enemy = nil

It is done by clearing the variable and releasing it in memory.

If it is still occur. Have you wondered about your math.random(2, 5)? Of course there is a chance it will move faster during next spawn or there is something else. *Just correct me*

Hope this helps =)

Hi lwg-prynce

                    first of all thanks for your reply,

and yes enemy variable is global, I used removeSelf function but problem is still there :frowning:

And math.random() function is called every time when a new enemy is spawn for its movement, I think that when I call this function for new enemy, that random value between 2 and 5 also add up with the previous value in moveX. I also use transition.cancel but it also do not work :frowning:

Then your problem is probably this:
 

"adding this line in your removal" enemy = nil

In this way you can ensure that the table inside enemy variable is removed.

Second I have been wondering, is there a possibility that there are plenty of enemies on screen? And you are just using a single variable? I think the problem is that.

You should put your enemy variable in a table enemies. Refer to this post I just posted here.
http://forums.coronalabs.com/topic/33900-whats-the-best-way-to-create-objects-in-a-table-and-delete-them/#entry175934

thanks lwg-prynce

I used enemy = nil in my code but it does not work for my problem :frowning:

yes there are more than one enemy characters on the screen at a time, And I am using a single variable because right now I used a single enemy for testing, that the code I have written yet works properly or not.

I have a question that if I use more than One enemy characters then what I have to do?

and also thanks for your help (link), I do visit that link and try to understand what is going on that post.

Oh I understand your problem now, why it moves twice fast at the previous one. It is because of your Timer because you didn’t store its handle to a variable so you can also cancel it inside your kill function. It will look like this:

 

"change your timer to this inside your create mob" enemy.timer = timer.performWithDelay( 0, moveCharacter, 0 ) "and your kill" function kill(event) local obj = event.target display.remove( obj ) "add these lines" timer.cancel(enemy.timer) enemy:removeSelf() enemy = nil score = score + 28 scoreTxt.text = "Score: " .. score spawnCharacter() return true end

Your problem is when you continuously create an object by removing it its timer will also multiply. At first you have one then you kill it then create another one but because you didnt cancel your timer what will happen is you create another one that will create 2 timers that moves your enemy and thats the explanation why it moves twice fast.

regarding your question you can have a look at that post. That can answer your question

Hope this helps! 

Is your enemy variable global?

when removing an object you should do.
 

enemy:removeSelf() enemy = nil

It is done by clearing the variable and releasing it in memory.

If it is still occur. Have you wondered about your math.random(2, 5)? Of course there is a chance it will move faster during next spawn or there is something else. *Just correct me*

Hope this helps =)

Hi lwg-prynce

                    first of all thanks for your reply,

and yes enemy variable is global, I used removeSelf function but problem is still there :frowning:

And math.random() function is called every time when a new enemy is spawn for its movement, I think that when I call this function for new enemy, that random value between 2 and 5 also add up with the previous value in moveX. I also use transition.cancel but it also do not work :frowning:

Then your problem is probably this:
 

"adding this line in your removal" enemy = nil

In this way you can ensure that the table inside enemy variable is removed.

Second I have been wondering, is there a possibility that there are plenty of enemies on screen? And you are just using a single variable? I think the problem is that.

You should put your enemy variable in a table enemies. Refer to this post I just posted here.
http://forums.coronalabs.com/topic/33900-whats-the-best-way-to-create-objects-in-a-table-and-delete-them/#entry175934

thanks lwg-prynce

I used enemy = nil in my code but it does not work for my problem :frowning:

yes there are more than one enemy characters on the screen at a time, And I am using a single variable because right now I used a single enemy for testing, that the code I have written yet works properly or not.

I have a question that if I use more than One enemy characters then what I have to do?

and also thanks for your help (link), I do visit that link and try to understand what is going on that post.

Oh I understand your problem now, why it moves twice fast at the previous one. It is because of your Timer because you didn’t store its handle to a variable so you can also cancel it inside your kill function. It will look like this:

 

"change your timer to this inside your create mob" enemy.timer = timer.performWithDelay( 0, moveCharacter, 0 ) "and your kill" function kill(event) local obj = event.target display.remove( obj ) "add these lines" timer.cancel(enemy.timer) enemy:removeSelf() enemy = nil score = score + 28 scoreTxt.text = "Score: " .. score spawnCharacter() return true end

Your problem is when you continuously create an object by removing it its timer will also multiply. At first you have one then you kill it then create another one but because you didnt cancel your timer what will happen is you create another one that will create 2 timers that moves your enemy and thats the explanation why it moves twice fast.

regarding your question you can have a look at that post. That can answer your question

Hope this helps! 

Hi lwg-prynce,

Sorry I was busy in papers,… so i am so late to reply,…

I have done what you have told related to timer but problem is still there :frowning:

and thanks alot for your help so far …!

It appears to me that “enemy” is still a global variable… or if not global, then a local variable declared outside the scope of these functions. I think @lwg-prynce has the correct suggestion: you should associate the timer with the specific display object, not “enemy”.

When you create new enemies, you should try to just create them as local objects (within the spawn function) with all of their own properties, including an attached timer. This will isolate the behavior of a specific enemy to itself, and make cleanup easier.

Brent

Hi lwg-prynce,

Sorry I was busy in papers,… so i am so late to reply,…

I have done what you have told related to timer but problem is still there :frowning:

and thanks alot for your help so far …!

It appears to me that “enemy” is still a global variable… or if not global, then a local variable declared outside the scope of these functions. I think @lwg-prynce has the correct suggestion: you should associate the timer with the specific display object, not “enemy”.

When you create new enemies, you should try to just create them as local objects (within the spawn function) with all of their own properties, including an attached timer. This will isolate the behavior of a specific enemy to itself, and make cleanup easier.

Brent

Hi lwg-prynce and Brent Sorrentino

sorry due to my papers I did not posted any thing related to my game,… lwg-prynce I follow the way you tell me to remove the error (speed of sprite) but it is not working,… the characters are on position 0,0 (x,y) and does not change there position but sprite sheet is working,…

what can i do now to solve this thing,…

Rewrite it.

Sometimes you get a logic error that is ingrained in the way you are doing something - and the only solution is to remove that part of the code and rewrite it.

You should be using a modular approach to your enemies and game logic.

Use a factory class to create new enemies based on the enemy template and add them to an enemies array. That way you can iterate through them properly.

local EnemyTemplate = {} function EnemyTemplate.new(params) local newEnemy = {} newEnemy.speed = math.random(2,5) newEnemy ... return newEnemy end

Create a new lua file named EnemyTemplate.lua and use “requires” to include it:

Local eTemplate = require("EnemyTemplate") ... lots of other code function createAnEnemy(params) local newEnemy = eTemplate.new(params) enemiesList.addEnemy(newEnemy) -- this is however you'll manage your list enemies end function destroyAnEnemy(target) enemiesList.removeEnemy(target) -- however you decide to remove items you can do with your enemies list end

This is just pseudo-code, but you should get the idea.

Keep your work MODULAR. Corona is great for its flexibility, but it can crush you if you use monolithic design practices.

Hi lwg-prynce and Brent Sorrentino

sorry due to my papers I did not posted any thing related to my game,… lwg-prynce I follow the way you tell me to remove the error (speed of sprite) but it is not working,… the characters are on position 0,0 (x,y) and does not change there position but sprite sheet is working,…

what can i do now to solve this thing,…

Rewrite it.

Sometimes you get a logic error that is ingrained in the way you are doing something - and the only solution is to remove that part of the code and rewrite it.

You should be using a modular approach to your enemies and game logic.

Use a factory class to create new enemies based on the enemy template and add them to an enemies array. That way you can iterate through them properly.

local EnemyTemplate = {} function EnemyTemplate.new(params) local newEnemy = {} newEnemy.speed = math.random(2,5) newEnemy ... return newEnemy end

Create a new lua file named EnemyTemplate.lua and use “requires” to include it:

Local eTemplate = require("EnemyTemplate") ... lots of other code function createAnEnemy(params) local newEnemy = eTemplate.new(params) enemiesList.addEnemy(newEnemy) -- this is however you'll manage your list enemies end function destroyAnEnemy(target) enemiesList.removeEnemy(target) -- however you decide to remove items you can do with your enemies list end

This is just pseudo-code, but you should get the idea.

Keep your work MODULAR. Corona is great for its flexibility, but it can crush you if you use monolithic design practices.

I realize this thread is pretty old, but I had a very similar problem today of my enemy movement speeding up more and more each time after they were destroyed and respawned. I googled for a solution and came upon this page, but nothing above seemed to work.

I fixed my code by removing the movement function event listener (removeEventListener) in the destroy function. I guess the fact that the listener is never destroyed means that each time you create new enemies, they will have the previous listener(s) along with the one added each time the spawn/move function is called. This means the move function will have more and more listeners calling it, making each newly spawned character faster and faster.

I’m sure this won’t be helpful to the OP at this point, but maybe it’ll help out anyone else with a similar situation who comes  across this page!