Lua-Corona : Changing image of an object on touch event

Hello everybodies,

I would like to change an image once the user has touch the screen. My touch handler is flyUp. My image was created in the CreateScene(). I would like to do a kind of swiping image on touch event.

player = display.newImageRect("ballon.png", 150,170 ) player.anchorX = 0.5 player.anchorY = 0.5 player.x = display.contentCenterX - 450 player.y = display.contentCenterY+100 physics.addBody(player, "static", {density=0.1, bounce=0.1, friction=0.1}) screenGroup:insert(player) player.myName="player" player.isFixedRotation = true 

Now, I would like to change the picture when the user clic on the screen :

player = display.newImageRect("ballon\_2.png", 150,170 ) player.anchorX = 0.5 player.anchorY = 0.5 player.x = display.contentCenterX - 450 player.y = display.contentCenterY+100 physics.addBody(player, "static", {density=0.1, bounce=0.1, friction=0.1}) screenGroup:insert(player) player.myName="player" player.isFixedRotation = true

So, i’ve tried to handle this :

function flyUp(event) if event.phase == "began" then player.bodyType = "dynamic" player:applyForce(0, -200, player.x, player.y) elseif event.phase=="ended" then player = display.newImageRect("ballon\_2.png", 150,170 ) player.anchorX = 0.5 player.anchorY = 0.5 player.x = display.contentCenterX - 450 player.y = display.contentCenterY+100 physics.addBody(player, "static", {density=0.1, bounce=0.1, friction=0.1}) screenGroup:insert(player) player.myName="player" player.isFixedRotation = true end end end

Unfortunatly, it doesn’t work. Do you have an ideal ? Thank you

You can’t change an image once it’s already created. The simplest method (if you only have a few images to switch between) is:

  1. Make all of them at once

  2. Add them all to a display group

  3. Turn them on/off as needed (object.isVisible = false)

If you need more images, you would want to use an imageSheet and change frames, but that’s a fair bit more to setup.

Oh great ! I found the solution thanks to ImageSpreadSheet. Here is my code :

sheetData\_player = { width=120, height=153, numFrames=2, sheetContentWidth=240, sheetContentHeight=153 } mySheet\_player = graphics.newImageSheet( "ballon\_action.png", sheetData\_player ) sequenceData\_player = { { name = "off", start=1, count=1, time=800 }, { name = "on", frames={2,2}, loopCount=0, time=1000 } } player = display.newSprite( mySheet\_player, sequenceData\_player) player.x = display.contentCenterX - 450 --center the sprite horizontally player.y = display.contentCenterY+100 --center the sprite vertically screenGroup:insert(player) player.myName="player" physics.addBody(player, "static", {density=0.159, bounce=0, friction=0, isSensor=false})

Then, in my function (on touch event), i put this :

 if event.phase == "began" then if gameStarted == false then Runtime:addEventListener("enterFrame",scrollGrasses) player:setSequence("on") player:play() player.bodyType="dynamic" player:applyForce(0, -300, player.x,player.y) (..)

Now, it’s okay, when i touch the screen, the image “changed”. I have another question : I use gravity to “fall the object” :

physics.setGravity( 0,1)

And the function below permit to move up the object in the air, the gravity is making a pressuire on the object to fall.

 player:applyForce(0, -300, player.x,player.y)  

What i’m looking now, is to change the sequence of my SpreadSheet, once the object is going to fall :

 --if player is going to fall, then : player:setSequence("off")  

Is there any “listenner” or other to use for this ? 

Thank you in advance.

If you have an enterFrame listener, what I would recommend is to check the object’s Y velocity.

If it’s positive (moving down) then change its sequence.

For example, in your “enterFrame” listener :

local function myUpdateListener( e ) local vx,vy = player:getLinearVelocity() if vy \> 0 and player.sequence ~= "off" then player:setSequence("off"); end end

That’s okay Thank you :slight_smile:

I added this for the up movement

if vy \< 0 and player.sequence ~= "on" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;player:setSequence("on"); &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;player:play( ) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;

I don’t know why it doesn’t react when you touch the screen. Add two print(“touch 1”) and print(“touch 2”) in both “if gameStarted == false then” -> “else” and “else” -> “end” blocks. Not sure if it’s really clear…

Another solution would be that it reacts to your touch, but as it’s falling down, you don’t really see the force applied to the player.

I would recommend using setLinearVelocity instead of applyForce, because setLinearVelocity sets exactly the force you provided. applyForce only applies a force to the player, while it is receiving other forces (player falling down for example), so sometimes it may only slow down the falling movement but not doing anything other.

Thank you for your help :slight_smile: In fact, i’ll try to use setLinearVelocity() function…

By the way, i solved my problem by adding this in my enterFrame function :

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if vy \< 0 and player.sequence ~= "on" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;player:setSequence("on"); &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;player:play( ) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;

It works very well now ! Thank you in advance for your help dude :slight_smile:

If you’r interested, i’m actually looking for solution for the scoring module (http://forums.coronalabs.com/topic/47117-adding-a-score-function-with-images/) :slight_smile:

You can’t change an image once it’s already created. The simplest method (if you only have a few images to switch between) is:

  1. Make all of them at once

  2. Add them all to a display group

  3. Turn them on/off as needed (object.isVisible = false)

If you need more images, you would want to use an imageSheet and change frames, but that’s a fair bit more to setup.

Oh great ! I found the solution thanks to ImageSpreadSheet. Here is my code :

sheetData\_player = { width=120, height=153, numFrames=2, sheetContentWidth=240, sheetContentHeight=153 } mySheet\_player = graphics.newImageSheet( "ballon\_action.png", sheetData\_player ) sequenceData\_player = { { name = "off", start=1, count=1, time=800 }, { name = "on", frames={2,2}, loopCount=0, time=1000 } } player = display.newSprite( mySheet\_player, sequenceData\_player) player.x = display.contentCenterX - 450 --center the sprite horizontally player.y = display.contentCenterY+100 --center the sprite vertically screenGroup:insert(player) player.myName="player" physics.addBody(player, "static", {density=0.159, bounce=0, friction=0, isSensor=false})

Then, in my function (on touch event), i put this :

 if event.phase == "began" then if gameStarted == false then Runtime:addEventListener("enterFrame",scrollGrasses) player:setSequence("on") player:play() player.bodyType="dynamic" player:applyForce(0, -300, player.x,player.y) (..)

Now, it’s okay, when i touch the screen, the image “changed”. I have another question : I use gravity to “fall the object” :

physics.setGravity( 0,1)

And the function below permit to move up the object in the air, the gravity is making a pressuire on the object to fall.

 player:applyForce(0, -300, player.x,player.y) &nbsp;

What i’m looking now, is to change the sequence of my SpreadSheet, once the object is going to fall :

 --if player is going to fall, then : player:setSequence("off") &nbsp;

Is there any “listenner” or other to use for this ? 

Thank you in advance.

If you have an enterFrame listener, what I would recommend is to check the object’s Y velocity.

If it’s positive (moving down) then change its sequence.

For example, in your “enterFrame” listener :

local function myUpdateListener( e ) local vx,vy = player:getLinearVelocity() if vy \> 0 and player.sequence ~= "off" then player:setSequence("off"); end end

That’s okay Thank you :slight_smile:

I added this for the up movement

if vy \< 0 and player.sequence ~= "on" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;player:setSequence("on"); &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;player:play( ) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;

I don’t know why it doesn’t react when you touch the screen. Add two print(“touch 1”) and print(“touch 2”) in both “if gameStarted == false then” -> “else” and “else” -> “end” blocks. Not sure if it’s really clear…

Another solution would be that it reacts to your touch, but as it’s falling down, you don’t really see the force applied to the player.

I would recommend using setLinearVelocity instead of applyForce, because setLinearVelocity sets exactly the force you provided. applyForce only applies a force to the player, while it is receiving other forces (player falling down for example), so sometimes it may only slow down the falling movement but not doing anything other.

Thank you for your help :slight_smile: In fact, i’ll try to use setLinearVelocity() function…

By the way, i solved my problem by adding this in my enterFrame function :

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if vy \< 0 and player.sequence ~= "on" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;player:setSequence("on"); &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;player:play( ) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;

It works very well now ! Thank you in advance for your help dude :slight_smile:

If you’r interested, i’m actually looking for solution for the scoring module (http://forums.coronalabs.com/topic/47117-adding-a-score-function-with-images/) :slight_smile: