Skip to content

Instantly share code, notes, and snippets.

Created June 2, 2015 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/a1adcd640706e7ddb80e to your computer and use it in GitHub Desktop.
Save anonymous/a1adcd640706e7ddb80e to your computer and use it in GitHub Desktop.
--# Main
function setup()
Layer = Layer()
--Layer.debug = true
--ui = UI()
end
function draw()
--Layer:draw()
--ui:draw()
end
local touches
function touched(touch)
-- Register touches
touches = touches or {}
local register, uid = true
for i, t in ipairs(touches) do
if t.id == touch.id then
uid = i
touches[uid] = touch
end
-- lock to active gesture!
if t.state ~= BEGAN then
register = false
end
end
if register and not uid and touch.state == BEGAN then
table.insert(touches, touch)
uid = #touches
end
-- Handle multitouch
if #touches > 0 then
--if not ui:touched(touches[1]) then
--Layer:touched(touches)
--end
end
-- Unregister touches
if uid and touches[uid].state == ENDED then
touches = nil -- cancel current gesture!
end
end
--# Zoom
-- (c) Zoom library v1.2 by Herwig Van Marck
-- Modified by jack0088@me.com from kennstewayne.de
--
-- USAGE:
--
--[[
function setup()
zoom = Zoom(WIDTH/2, HEIGHT/2)
end
function draw()
zoom:draw()
end
function touched(touch)
zoom:touched(touch)
end
--]]
Zoom = class()
function Zoom:init(id, x, y)
self.id = id or 1
self.initAnchor = vec2(x, y)
self:reset()
self:read()
end
function Zoom:read()
self.anchor = readLocalData("Zoom_"..self.id.."_anchor", self.anchor)
self.offset = readLocalData("Zoom_"..self.id.."_offset", self.offset)
self.zoom = readLocalData("Zoom_"..self.id.."_zoom", self.zoom)
end
function Zoom:save()
saveLocalData("Zoom_"..self.id.."_anchor", self.anchor)
saveLocalData("Zoom_"..self.id.."_offset", self.offset)
saveLocalData("Zoom_"..self.id.."_zoom", self.zoom)
end
function Zoom:clear()
saveLocalData("Zoom_"..self.id.."_anchor", nil)
saveLocalData("Zoom_"..self.id.."_offset", nil)
saveLocalData("Zoom_"..self.id.."_zoom", nil)
end
function Zoom:reset()
self.anchor = self.initAnchor
self.offset = vec2(0, 0)
self.zoom = 1
self.lastPinchDist = 0
self.pinchDelta = 1.0
end
function Zoom:getWorldPoint(pt)
return vec2(self.offset.x-(self.anchor.x-pt.x)/self.zoom, self.offset.y-(self.anchor.y-pt.y)/self.zoom)
end
function Zoom:getLocalPoint(pt)
return vec2(pt.x*self.zoom+self.anchor.x-self.offset.x*self.zoom, pt.y*self.zoom+self.anchor.y-self.offset.y*self.zoom)
end
function Zoom:draw()
if self.touch1 and self.touch2 then
local t1 = vec2(self.touch1.x, self.touch1.y)
local t2 = vec2(self.touch2.x, self.touch2.y)
local tc = (t1 + t2)/2
local dist = t1:dist(t2)
if self.lastPinchDist > 0 then
if dist > 150 then -- for smooth pan!
self.pinchDelta = dist / self.lastPinchDist
end
else
self.offset = self.offset + (tc-self.anchor)/self.zoom
end
self.anchor = tc
self.lastPinchDist = dist
else
self.pinchDelta = 1.0
self.lastPinchDist = 0
end
self.zoom = self.zoom * self.pinchDelta
local x = self.anchor.x - self.offset.x * self.zoom
local y = self.anchor.y - self.offset.y * self.zoom
self.translation = vec2(x, y)
translate(x, y)
scale(self.zoom)
self.pinchDelta = 1.0
end
function Zoom:touched(touch)
if touch.state == BEGAN then
self.touch1 = self.touch1 or touch
self.touch2 = self.touch2 or (touch.id ~= self.touch1.id and touch or nil)
end
if self.touch1 and self.touch1.id == touch.id then self.touch1 = touch end
if self.touch2 and self.touch2.id == touch.id then self.touch2 = touch end
if touch.state == ENDED then
if self.touch1 and self.touch2 then
if ((self.touch1.tapCount+self.touch2.tapCount)/2) > 1 then
self:reset()
end
end
if (self.touch1 and self.touch1.state == ENDED) or (self.touch2 and self.touch2.state == ENDED) then
self.touch1 = nil
self.touch2 = nil
self:save()
end
end
end
--# UI
UI = class()
function UI:init()
end
function UI:draw()
end
function UI:touched(touch)
end
--# Canvas
Canvas = class()
function Canvas:init()
self.layers = {
[1] = {
[1] = {x, y},
[2] = {self.layers[1]}
}
}
end
function Canvas:loadSession()
end
function Canvas:saveSession()
end
function Canvas:draw()
end
function Canvas:touched(touches)
end
--# Layers
Layer = class()
function Layer:init(id)
self.id = id or 1
--self:reset()
--self:read()
("-54x-67_1"):gsub("(%w+)x(%w+)_(%w+)", function(x, y, id)
print(x, y, id)
end)
end
function Layer:read()
local function import(tiles)
local list = {}
tiles:gsub("(%w+)x(%w+)_(%w+)", function(x, y, id)
print()
end)
return list
end
self.translation = readLocalData("Layer_"..self.id.."_translation", self.translation)
self.tiles = readLocalData("Layer_"..self.id.."_tiles", self.tiles)
end
function Layer:save()
local function export(tiles)
local values = {}
for _, tile in ipairs(tiles) do
table.insert(values, tile.x.."x"..tile.y.."_"..self.id)
end
return table.concat(values, ",")
end
saveLocalData("Layer_"..self.id.."_translation", self.translation)
saveLocalData("Layer_"..self.id.."_tiles", export(self.tiles))
end
function Layer:clear()
saveLocalData("Layer_"..self.id.."_translation", nil)
saveLocalData("Layer_"..self.id.."_tiles", nil)
end
function Layer:reset()
self.translation = vec2(0, 0)
self.tiles = {}
self.visibleTiles = {}
end
function Layer:addScratchpad(x, y)
local pos = self:getTilePositionFromPoint(x, y)
local size = vec2(WIDTH, HEIGHT)
local subd = vec2(1, 1)
if self.visibleTiles and #self.visibleTiles > 0 then
local tiles = self.visibleTiles
local bottomLeft = vec2(0, 0)
local topRight = vec2(0, 0)
if #tiles > 0 then -- define bounding-box
table.sort(tiles, function(min, max) return min.x < max.x end)
bottomLeft.x = tiles[1].x
table.sort(tiles, function(min, max) return min.y < max.y end)
bottomLeft.y = tiles[1].y
table.sort(tiles, function(min, max) return min.x > max.x end)
topRight.x = tiles[1].x
table.sort(tiles, function(min, max) return min.y > max.y end)
topRight.y = tiles[1].y
topRight = topRight + vec2(self.tileSize, self.tileSize)
end
size = topRight - bottomLeft
subd = vec2(size.x / self.tileSize, size.y / self.tileSize)
else
--create a Scratchpad
--propose width and height based on: zoom * tileSize
end
self.scratchpads = self.scratchpads or {}
table.insert(self.scratchpads, Scratchpad(pos.x, pos.y, size.x, size.y, subd.x, subd.y))
if self.debug then self.scratchpads[#self.scratchpads].debug = true end
print("+scratchpad: "..size.x.."x"..size.y.."\n".."scratchpads: "..#self.scratchpads)
end
function Layer:removeScratchpad(id)
table.remove(self.scratchpads, id)
end
function Layer:updateScratchpads()
for id, scratchpad in ipairs(self.scratchpads) do
if scratchpad.state == "dead" then
self:removeScratchpad(id)
else
scratchpad:draw()
end
end
end
function Layer:getTilePositionFromPoint(x, y)
local point = vec2(x, y)
local Layer = vec2(self.x, self.y)
local shifts = (point - Layer) / self.tileSize
local pos = shifts * self.tileSize
return pos
end
function Layer:updateVisibleTiles()
self.visibleTiles = {}
for _, tile in ipairs(self.tiles) do
local size = self.zoom * vec2(self.tileSize, self.tileSize)
local pos = self.zoom * (vec2(tile.x, tile.y) + vec2(self.x, self.y))
local edges = { -- bounding-box (bb)
vec2(pos.x, pos.y),
vec2(pos.x + size.x, pos.y),
vec2(pos.x + size.x, pos.y + size.y),
vec2(pos.x, pos.y + size.y)
}
for _, vert in ipairs(edges) do
if vert.x > 0 and vert.x < WIDTH and vert.y > 0 and vert.y < HEIGHT then
table.insert(self.visibleTiles, tile)
break
end
end
end
print("visibleTiles: "..#self.visibleTiles.."/"..#self.tiles)
end
function Layer:draw()
background(176, 169, 158, 255)
self.zoomlib:draw()
self.zoom = self.zoomlib.zoom
self.x = self.zoomlib.x
self.y = self.zoomlib.y
pushStyle()
for _, tile in ipairs(self.visibleTiles) do
spriteMode(CORNER)
sprite("Project:"..tile.x.."x"..tile.y, tile.x, tile.y, self.tileSize, self.tileSize)
if self.debug then
noFill()
strokeWidth(2)
stroke(0, 154, 255, 255)
rect(tile.x, tile.y, self.tileSize)
end
end
popStyle()
self:updateScratchpads()
end
function Layer:touched(touches)
-- Draw
if #touches == 1 then
if touches[1].state ~= BEGAN then
self.scratchpads[#self.scratchpads].touched(touches[1])
end
end
-- Pinch
if #touches == 2 then
self.zoomlib:touched(CurrentTouch)
if touches[1].state == ENDED or touches[2].state == ENDED then
self:updateVisibleTiles()
self:addScratchpad()
end
end
end
--# Scratchpads
Scratchpad = class()
function Scratchpad:init(x, y, width, height, subdX, subdY)
self.debug = false
self.x = x or 0
self.y = y or 0
self.width = width
self.height = height
self.subdX = subdX
self.subdY = subdY
self.image = image(self.width, self.height)
self.autosave = coroutine.create(function()
for i=1,5 do
print("saved "..i)
coroutine.yield()
end
end)
end
function Scratchpad:draw()
pushStyle()
spriteMode(CORNER)
sprite(self.image, self.x, self.y, self.width, self.height)
if self.debug then
noFill()
strokeWidth(2)
stroke(34, 138, 28, 255)
rect(self.x, self.y, self.width, self.height)
end
popStyle()
self.state = coroutine.status(self.autosave)
end
function Scratchpad:touched(touch)
do
print(touch)
return
end
do
pushStyle()
noFill()
strokeWidth(2)
stroke(0)
--[[
if Color.a == 0 then
stroke(0,0,0,255)
blendMode(ZERO, ONE_MINUS_SRC_ALPHA)
end
--]]
setContext(self.image)
line(touch.prevX, touch.prevY, touch.x, touch.y)
setContext()
blendMode(NORMAL)
popStyle()
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment