Touch and drop

I’ve been looking around and I can’t find an example of a touch and drop object . I have a grenade in my game. When I touch the grenade I want it to fall to the bottom of the screen and blow up . I have some sprite sheets for the explosion . Can someone help me with this ?

My current relevant code:

 grenade1 = display.newImage("grenade.png") grenade1.x = 350 grenade1.y = 50 grenade1:scale( 0.3, 0.3 ) grenade2 = display.newImage("grenade.png") grenade2.x = 390 grenade2.y = 50 grenade2:scale( 0.3, 0.3 ) grenade3 = display.newImage("grenade.png") grenade3.x = 430 grenade3.y = 50 grenade3:scale( 0.3, 0.3 ) local function grenadeDrop( event ) if event.phase == "ended" then end end function game.start( ) -- Game is already started, just exit if( isRunning ) then return end -- Mark game as running isRunning = true gun:addEventListener( "touch", shootBullet ) Runtime:addEventListener( "collision", onCollision ) grenade1:addEventListener( "touch", grenadeDrop ) grenade2:addEventListener( "touch", grenadeDrop ) grenade3:addEventListener( "touch", grenadeDrop ) end

The phrase you’re looking for is drag and drop.

SSK2 comes with a helper that you can use OR steal the code from:

https://roaminggamer.github.io/RGDocs/pages/SSK2/libraries/misc/#addsmartdrag

Code is here (lines 407 …465):

https://raw.githubusercontent.com/roaminggamer/SSK2/master/ssk2/misc.lua

If you grab the code, you’ll need to remove some parts if you’re not using SSK:

This should do it (may still have issues as I’m not going to test it, but I removed the parts that made it dependent upon SSK):

local function addSmartDrag( obj, params ) params = params or {} obj.touch = function( self, event ) local phase = event.phase local id = event.id if( phase == "began" ) then self.isFocus = true display.currentStage:setFocus( self, id ) self.x0 = self.x self.y0 = self.y if( params.toFront ) then self:toFront() end if( self.onDragged ) then self:onDragged( { obj = self, phase = event.phase, x = event.x, y = event.y, dx = 0, dy = 0, time = getTimer(), target = self } ) end target = self } ) if( params.listener ) then return params.listener( self, event ) or fnn(params.retval,false) end elseif( self.isFocus ) then local dx = event.x - event.xStart local dy = event.y - event.yStart self.x = self.x0 + dx self.y = self.y0 + dy event.dx = dx event.dy = dy if( phase == "ended" or phase == "cancelled" ) then self.isFocus = false display.currentStage:setFocus( self, nil ) if( self.onDragged ) then self:onDragged( { obj = self, phase = event.phase, x = event.x, y = event.y, dx = dx, dy = dy, time = getTimer(), target = self } ) end if( self.onDropped ) then self:onDropped( { obj = self, phase = event.phase, x = event.x, y = event.y, dx = dx, dy = dy, time = getTimer(), target = self } ) end getTimer(), target = self } ) getTimer(), target = self } ) else if( self.onDragged ) then self:onDragged( { obj = self, phase = event.phase, x = event.x, y = event.y, dx = dx, dy = dy, time = getTimer(), target = self } ) end getTimer(), target = self } ) end if( params.listener ) then return params.listener( self, event ) or fnn(params.retval,false) end end if( params.listener ) then return params.listener( self, event ) or fnn(params.retval,false) else return fnn(params.retval,false) end end; obj:addEventListener("touch") end

You could use it like this:

-- Define addSmartDrag above this line local obj = display.newCirlce( 100, 100, 10 ) function obj.onDropped( self ) self:setFillColor(1,0,0) end addSmartDrag( obj )

Now, when you drag the circle it will move and when you release/drop it, it will turn red.

That should be plenty of a starting point to do what you need.

Finally, there is also a physics dragger in SSK (see same docs page)

I’ll try to be clearer . The grenade is just there on the right corner of my screen . I have three of them . When the user touches them, I want them to fall to the bottom of the screen . They won’t be able to drag them just drop them .

Sounds like you just need to add a body to the grenade when you touch it.  

Just add a body once and only during one of the touch phases.

Ok . Now I only have one that falls . I tried to add code for all three of the grenades . Here is all the code I tried :

(current code):

local function grenadeTouch( event ) if event.phase == "ended" then physics.addBody( grenade1, "dynamic", {density=3.0, friction=0.5, bounce=0.3, radius=12.5} ) elseif event.phase == "ended" then physics.addBody( grenade2, "dynamic", {density=3.0, friction=0.5, bounce=0.3, radius=12.5} ) end end

local function grenadeTouch( event ) if event.phase == "ended" then physics.addBody( grenade1, "dynamic", {density=3.0, friction=0.5, bounce=0.3, radius=12.5} ) physics.addBody( grenade2, "dynamic", {density=3.0, friction=0.5, bounce=0.3, radius=12.5} ) physics.addBody( grenade3, "dynamic", {density=3.0, friction=0.5, bounce=0.3, radius=12.5} ) end end

When I did the second block of code all three of the grenades fell down .

With the first block of code, whichever grenade I touch the first one is the only one that falls . Should I make a separate  function for all of them ?

I fixed the grenades but now my problem is with the floor . I added some floor code so when the grenades fall down, they fall on the floor and blow up .

 theFloor = display.newImage("invisibleTile.png") theFloor.x = 0 theFloor.y = 350 physics.addBody(theFloor, layers.underlay, "static", {density=.1, bounce=0.2, friction=.2})

I tried moving the floor along the y axis and nothing changed . I also tried this :

 theFloor = display.newImage(layers.underlay, "invisibleTile.png") theFloor.x = 0 theFloor.y = 350 physics.addBody(theFloor, "static", {density=.1, bounce=0.2, friction=.2})

make the body ‘kinematic’ if you intend to move it.  Also, I don’t think that argument list is right:

 physics.addBody(theFloor, "kinematic", {density=.1, bounce=0.2, friction=.2})

Note, updating the position manually will move the image and it’s body, but that will not move objects resting on the ground.

Only objects with a velocity will move other physics objects.

I have this code :

 theFloor = display.newImage(layers.overlay, "invisibleTile.png") theFloor.x = 0 theFloor.y = 350 physics.addBody(theFloor, "kinematic", {density=.1, bounce=0.2, friction=.2})

And the same thing is happening . The grenades are falling off of the screen

If you want to see how to make moving platforms, take a look at this thread:

https://forums.coronalabs.com/topic/67141-how-to-implement-a-conveyor-belt/#entry347337

I don’t want to move the floor . I want it to stay still and as soon as the grenade drops on the floor it blows up.

Try to be more clear please.   You clearly said:

I tried moving the floor along the y axis and nothing changed …

From this I assumed you tried to make the floor move.

I assume now that the issue is GRENADES not colliding with FLOOR?

I so, please show your current addBody calls for both the GRENADES and the FLOOR.

Also, are you you making any these bodies a sensor?  Sensors do not exhibit collision responses.  i.e. They don’t bounce off other objects.

Hey.  Just wanted to point out this code won’t work because you’re testing for the same condition twice:

local function grenadeTouch( event ) if event.phase == "ended" then -- ONLY THIS CONDITION WILL EXECUTE elseif event.phase == "ended" then -- SAME AS LAST CONDITION end end

How ‘thick’ is the floor.  If it is very thin you could be tunneling.

when you add the bodies to the grenades, set ‘isBullet’ to true.

Your code should look like this:

physics.addBody( grenade1, "dynamic", {density=3.0, friction=0.5, bounce=0.3, radius=12.5} ) grenade1.isBullet = true

 physics.addBody(theFloor, "kinematic", {density=.1, bounce=0.2, friction=.2})

Finally, be sure you’re NOT changing the x or y position of any groups.

Bodies in misaligned groups will not work as expected.

If this doesn’t work you’ll need someone to look at your entire game.

Thanks I fixed that already .

The floor is an image . It’s an invisible tile . I tried putting theFloor to kinematic but that didn’t change anything

have you turned on hybrid drawMode() to verify the bodies visually.

also, you’re not understanding.  What is the dimension of the floor object (width and height)

480 x 25

No I didn’t try to turn that mode on .

I have it on an example project and it works just fine