Magnetic Drop for a puzzle game

Dear contributers,

I’m working to build a simple puzzle game… For the moment, i’m a beginner, and read some tutorials to understand the LUA language.

I’m able to drag “images” but cannot find the LUA code to “have a magnetic drop” in the good “cases”. This is my code :

local storyboard = require "storyboard" local scene = storyboard.newScene()  storyboard.purgeOnSceneChange = true local physics = require("physics") physics.start() physics.setGravity(0,0) --physics.setDrawMode("hybrid")   -- forward declarations function scene:createScene( event ) local ROWS=1 local COLS=1 local SLOT\_SIZE=95   local board local blue local yellow   local collidedWith -- slot that we collide with  local cube                                  = display.newImage("module.png")         cube.x                                      =display.contentWidth/2         cube.y                                      =display.contentHeight/2 local timeLimit = 5 timeLeft = display.newText(timeLimit, 160, 20, native.systemFontBold, 14) timeLeft:setTextColor(255,0,0) local function timerDown()    timeLimit = timeLimit-1    timeLeft.text = timeLimit      if(timeLimit==0)then                          storyboard.gotoScene( "endtime")      end   end timer.performWithDelay(1000,timerDown,timeLimit) timer.performWithDelay(1000,decreaseTime,60)        -- A basic function for dragging physics objects local function startDrag( event )         local t = event.target           local phase = event.phase         if "began" == phase then                 display.getCurrentStage():setFocus( t )                 t.isFocus = true                   -- Store initial position                 t.x0 = event.x - t.x                 t.y0 = event.y - t.y                          elseif t.isFocus then                 if "moved" == phase then                         t.x = event.x - t.x0                         t.y = event.y - t.y0                   elseif "ended" == phase or "cancelled" == phase then                         display.getCurrentStage():setFocus( nil )                         t.isFocus = false                                            -- if we have collided with a slot,                         -- move the blue to the slot                         if(collidedWith ~= nil) then                                                          blue.x = collidedWith.x                                 blue.y = collidedWith.y                                  --local alert = native.showAlert( "You are in scene1!", "Congratulations!", { "OK" })                                  physics.removeBody(blue)                                  blue:removeEventListener( "touch", startDrag )                                                                                                    -- move smoothly to slot                                 transition.to(blue,                                 {                                   time=10,                                   x = collidedWith.x,                                   y=collidedWith.y                                 })                         end                                                          end         end           -- Stop further propagation of touch event!         return true end     function onblueCollision(self,event)           if(event.phase=="began") then                 if(event.other.type=="slot") then                         collidedWith=event.other                 end           elseif(event.phase=="ended" or event.phase=="cancelled") then                            if(event.other==collidedWith) then                         collidedWith=nil                 end         end   end   local function makeSlot()           local slot = display.newImageRect( "blue\_hidden2.png", 1,1 )         --slot:setFillColor(255,0,0,200)         --slot:setReferencePoint(display.CenterReferencePoint)         physics.addBody(slot, "static")         slot.x=display.contentWidth/2-47         slot.y=display.contentHeight/2-96                  slot.isSensor=true         slot.type="slot"         return slot   end     local function makeBoard()           board=display.newGroup()           local counter=0           for y=1, ROWS, 1 do                 for x=1, COLS, 1 do                           counter = counter + 1                           local slot = makeSlot()                         --slot.x = (x-1) \* SLOT\_SIZE                         --slot.y = (y-1) \* SLOT\_SIZE                         slot.id = counter                         board:insert(slot)                   end           end           board.x = SLOT\_SIZE/2         board.y = SLOT\_SIZE/2   end   local function makeblue()                  blue = display.newImageRect("blue.png", 150,100)         blue.x  =display.contentWidth/2         blue.y  =100                             blue.type="blue"           physics.addBody(blue,"dynamic", {density=1, bounce=0.1})         blue.isFixedRotation=true           blue.collision = onblueCollision         blue:addEventListener( "collision", blue)                                          board:insert(blue)   end local function makeyellow()                  yellow = display.newImageRect("yellow.png", 100,150)         yellow.x  =display.contentWidth/2         yellow.y  =100         yellow.rotation=-90                         yellow.type="yellow"           physics.addBody(yellow,"dynamic", {density=1, bounce=0.1})         yellow.isFixedRotation=true           yellow.collision = onblueCollision         yellow:addEventListener( "collision", yellow)                                          board:insert(yellow)   end     --   makeBoard() makeblue() makeyellow()   blue:addEventListener( "touch", startDrag ) yellow:addEventListener( "touch", startDrag ) end function scene:exitScene( event ) end scene:addEventListener( "createScene", scene ) scene:addEventListener( "exitScene", scene ) return scene 

So, this code let me drag the element named “Yellow” into the screen, but I would like to have a magnetic drop once the image is “dropped” (means the finger is off) in the good case (look at the enclosed file).

Maybe i’ll need to identify each elements (yellow, blue, etc…) and put a listenner on the “drop” event.

Any information will be appreciate :slight_smile: Thanks dude !

Well the code you posted has only one line, you oshould edit and fix that.

The way to go abouto this would be to check on the touch ended phase if the object is close enough for the snap (magnet) to happen and then just transition it to the right position. Check the transition API.

Dear,

My code is working for the transition & drag’n drop with magnetic drop. Whereas, how can I check if it’s the correct place ? I mean, if the user dropped the correct “lego” in the correct place ? Should i use “ID” check ? Thanks

Well you can set a property on the display object to identify them or even set the correct position values on it that you can check in the touch listeners.

obj = display.new…

obj.destX = 100

obj.destY = 100

then in touch end phase

if math.abs(obj.y - obj.destY) < snapTreshold and math.abs(obj.x - obj.destY) < snapTreshold then

–snap to destX and destY

Well the code you posted has only one line, you oshould edit and fix that.

The way to go abouto this would be to check on the touch ended phase if the object is close enough for the snap (magnet) to happen and then just transition it to the right position. Check the transition API.

Dear,

My code is working for the transition & drag’n drop with magnetic drop. Whereas, how can I check if it’s the correct place ? I mean, if the user dropped the correct “lego” in the correct place ? Should i use “ID” check ? Thanks

Well you can set a property on the display object to identify them or even set the correct position values on it that you can check in the touch listeners.

obj = display.new…

obj.destX = 100

obj.destY = 100

then in touch end phase

if math.abs(obj.y - obj.destY) < snapTreshold and math.abs(obj.x - obj.destY) < snapTreshold then

–snap to destX and destY