Ok, this is as simple as I could get it. You don’t need any assets to run it except a image for the player named player.png. I suggest using your smart phone to take a picture of your head facing to the right and then name it player.png and use that.
tileSize = 40
relDelta = {}
relDelta.mapRotate0 = function(dX, dY) return dX, dY end
relDelta.mapRotate90 = function(dX, dY) return dY, -dX end
relDelta.mapRotate180 = function(dX, dY) return -dX, -dY end
relDelta.mapRotate270 = function(dX, dY) return -dY, dX end
function centerOnPlayer(playerGroup, n)
mapTiles.xReference = playerGroup.x
mapTiles.yReference = playerGroup.y
local newX, newY = 20, display.contentCenterY\* 141/240 -- home position
if n then mapTiles.x = newX; mapTiles.y = newY; return end -- moves player instantly
transition.to(mapTiles, {time = 500, x = newX, y=newY })
end
function correctRotation(object)
object.rotation = object.rotation % 360
if object.rotation \< 0 then object.rotation = 360 + object.rotation end
end
function newCoordsFromDelta(startX, startY, moveDeltaX, moveDeltaY)
local mapRotation = "mapRotate" .. mapTiles.rotation
local relDeltaX, relDeltaY = relDelta[mapRotation](moveDeltaX, moveDeltaY)
local x
local y
--checking relative to 0 is so that you get rounding that is relative to the original location
if relDeltaX \> 0 then
x = (relDeltaX + startX) - (relDeltaX % tileSize)
elseif relDeltaX == 0 then
x = startX
else
x = (relDeltaX + startX) + (tileSize-(relDeltaX % tileSize))
end
if relDeltaY \> 0 then
y = (relDeltaY + startY) - (relDeltaY % tileSize)
elseif relDeltaY == 0 then
y = startY
else
y = (relDeltaY + startY) + (tileSize-(relDeltaY % tileSize))
end
return x, y
end
function createTurnButton(playerGroup)
local turnButton = display.newRect( display.contentCenterX - 25, display.contentCenterY + 175, 50, 50 )
turnButton.rotation = player.rotation
function turnButton:tap(event)
local newPlayerAngle = playerGroup.rotation - 90
local newMapAngle = mapTiles.rotation + 90
transition.to( playerGroup, { time=150, rotation=newPlayerAngle, onComplete = correctRotation })
mapTiles.xReference = playerGroup.x
mapTiles.yReference = playerGroup.y
transition.to( mapTiles, { time= 200, rotation = newMapAngle, onComplete = correctRotation })
return true
end
turnButton:addEventListener("tap")
return turnButton
end
function createPlayer()
local newPlayer = display.newImageRect( "player.png", 40, 40 )
-- player drag event
function newPlayer:touch(event)
if event.phase == "began" then
--set touch focus
display.getCurrentStage():setFocus(self)
self.isFocus = true
self.markX = self.x -- store x location of object
self.markY = self.y -- store y location of object
elseif self.isFocus then
local moveDeltaX = event.x - event.xStart
local moveDeltaY = event.y - event.yStart
local x, y = newCoordsFromDelta(self.markX, self.markY, moveDeltaX, moveDeltaY)
if event.phase == "moved" then
self.x, self.y = x, y
elseif event.phase == "ended" or event.phase == "cancelled" then
-- reset touch focus
display.getCurrentStage():setFocus(nil)
self.isFocus = nil
centerOnPlayer(player)
end
end
return true
end
newPlayer:addEventListener( "touch", playerGroup)
return newPlayer
end
function createMap()
-- create a display group
local floorTiles = display.newGroup()
local gradient1 = graphics.newGradient({100, 0, 0}, {100, 100, 100})
local gradient2 = graphics.newGradient({0, 0, 100}, {100, 100, 100})
local startX, finishX, deltaX = 0, 2560, 40
local startY, finishY, deltaY = 0, 2560, 40
local color = 0
for i=startX, finishX, deltaX do
for j=startY, finishY, deltaY do
local thisTile = display.newRect( i,j, 40, 40 ) -- initialize to stone
if color == 0 then thisTile:setFillColor(gradient1) else thisTile:setFillColor(gradient2) end
floorTiles:insert(thisTile)
if color == 0 then color = 1 else color = 0 end -- checkerboard so we can see what is going on
end
end
function dragMap(event)
local self = event.target
local screenOrientation = system.orientation
if event.phase == "began" then
--set touch focus
display.getCurrentStage():setFocus(self)
self.isFocus = true
self.markX = self.x -- store x location of object
self.markY = self.y -- store y location of object
elseif self.isFocus then
local deltaX = event.x - event.xStart
local deltaY = event.y - event.yStart
local relDeltaX, relDeltaY = relDelta["mapRotate0"](deltaX, deltaY)
local x = self.markX + relDeltaX
local y = self.markY + relDeltaY
if event.phase == "moved" then
self.x, self.y = x,y
elseif event.phase == "ended" or event.phase == "cancelled" then
self.x, self.y = x,y
-- reset touch focus
display.getCurrentStage():setFocus(nil)
self.isFocus = nil
centerOnPlayer(player) -- put the player back in the home position
end
end
return true
end
floorTiles:addEventListener( "touch", dragMap)
return floorTiles
end
display.setDefault("background", 0, 0, 0)
mapTiles = createMap()
player = createPlayer()
player.x, player.y = 20, 20 + 4 \* tileSize
mapTiles:insert(player) -- note that the player is in the same group as the map
turnLeft = createTurnButton(player)
centerOnPlayer(player, true)
try dragging the player or the map and then let go and the map will go back to the home position.
click the white square at the bottom of the screen to turn. Now drag the board and you will see that it returns as expected. Now drag the player and you will see that it starts getting messed up. If you drag the board after it gets messed up, it just kind of gets worse.
However, if you click turn it snaps him back to the correct position. This makes me suspect a bug because the turn function doesn’t call the function centerOnPlayer. [import]uid: 191108 topic_id: 33432 reply_id: 133322[/import]