When I run this code (which is based on the “DragMe” sample app) I get very unexpected results in very particular circumstances.
My “snapToGrid” function sets x and y to the nearest round 100 value for each new tile or after a drag.
If a tile is placed in row 5 (so y = 500) and then rotated the y value changes from 500 to 499.99996948242
(In every other row the y value stays the same before and after rotation).
How can this be explained? I notice this only happens if the tile has a physics body.
This code will run stand alone i.e. does not require use any image/sound assets etc.
[lua]
local function snapToGrid(t)
modHalf = t.x % t.width
if modHalf > t.width/2 then
t.x = t.x + (t.width-modHalf)
end
if modHalf < t.width/2 then
t.x = t.x - modHalf
end
modHalfY = t.y % t.height
if modHalfY > t.height/2 then
t.y = t.y + (t.height-modHalfY)
end
if modHalfY < t.height/2 then
t.y = t.y - modHalfY
end
display.getCurrentStage():setFocus( nil )
t.isFocus = false
return true
end
function rotatePiece(target)
if target.rotation == 270 then
target.rotation = 0
else
target.rotation = target.rotation + 90
end
end
local function dragBody(event)
local target = event.target
local phase = event.phase
local halfWidth = target.width/2
local halfHeight = target.height/2
--get tileX and tileY relative to tile centre
local tileX = event.x-target.x
local tileY = event.y-target.y
local modHalf = ""
if phase == “began” then
– Make target the top-most object
display.getCurrentStage():setFocus( target )
– Spurious events can be sent to the target, e.g. the user presses
– elsewhere on the screen and then moves the finger over the target.
– To prevent this, we add this flag. Only when it’s true will "move"
– events be sent to the target.
target.isFocus = true
– Store initial position
target.x0 = event.x - target.x
target.y0 = event.y - target.y
elseif target.isFocus then
if phase == “moved” then
– Make object move (we subtract target.x0,target.y0 so that moves are
– relative to initial grab point, rather than object “snapping”).
target.x = event.x - target.x0
target.y = event.y - target.y0
if target.x > display.contentWidth - (target.width/2) then target.x = display.contentWidth - (target.width/2) end
if target.y > display.contentHeight - (target.height/2) then target.y = display.contentHeight - (target.height/2) end
if target.x < 0 + (target.width/2) then target.x = 0 + (target.width/2) end
if target.y < 0 + (target.height/2) then target.y = 0 + (target.height/2) end
hasMoved = true
return true
elseif phase == “ended” then
if hasMoved then
hasMoved = false
snapToGrid(target)
--tile has moved
examine(target)
return true
else
--rotate piece
rotatePiece(target)
display.getCurrentStage():setFocus( nil )
target.isFocus = false
--tile has rotated
examine(target)
return true
end
end
end
– Important to return true. This tells the system that the event
– should not be propagated to listeners of any objects underneath.
return true
end
local onTouch = function(event)
if event.phase == “began” then
local tile = {}
img = display.newRect(event.x,event.y,100,100)
img:addEventListener( “touch”, dragBody )
snapToGrid(img)
physics.addBody( img, “static” )
--new tile created
examine(img)
return true
end
end
function examine(img)
print("--------------------------------------------------")
if img ~= nil then
print("X: “…img.x…”, Y: "…img.y)
end
print("--------------------------------------------------")
end
local img
local physics = require( “physics” )
–draw gridlines
for i = 49, display.contentHeight, 100 do
local line = display.newLine(0,i,display.contentWidth,i)
end
for i = 49, display.contentWidth, 100 do
local line = display.newLine(i,0,i,display.contentHeight )
end
physics.start()
Runtime:addEventListener(“touch”, onTouch)
[/lua]