-
Notifications
You must be signed in to change notification settings - Fork 4
/
isomap.lua
113 lines (93 loc) · 2.77 KB
/
isomap.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
local PREALLOCATE_SB_SIZE = 256
local path = (...):match('^.+[%.\\/]') or ''
local grid = require (path..'grid')
local map = require (path..'map')
local ceil = math.ceil
local sqrt = math.sqrt
local floor = math.floor
local max = math.max
local lg = love.graphics
-- 0.9/0.8 compatibility
local sbadd = love.graphics.drawq and 'addq' or 'add'
local sbset = love.graphics.drawq and 'setq' or 'set'
local dummyquad = lg.newQuad(0,0,1,1,1,1)
local getSBrange = function(tx,ty,tx2,ty2,sw,sh)
local sbx,sby = ceil(tx/sw),ceil(ty/sh)
local sbx2,sby2= ceil(tx2/sw),ceil(ty2/sh)
return sbx,sby,sbx2,sby2
end
local isoToScreen = function(ix,iy,tw,th)
local x = (ix-1)*tw/2 - (iy-1)*tw/2
local y = (ix-1)*th/2 + (iy-1)*th/2
return x,y
end
local setQuad = function(self,t)
t.sb[sbset](t.sb, t.id,t.quad, t.x+self.hw,t.y+self.hh, t.angle, t.sx,t.sy, self.hw,self.hh)
end
local preallocateSB = function(self,sbx,sby)
local sb = lg.newSpriteBatch(self.image,PREALLOCATE_SB_SIZE)
sb:bind()
grid.set(self,sbx,sby,sb)
local qw,qh = self.atlas:getqSize()
local tox,toy = self.SBwidth*(sbx-1),self.SBheight*(sby-1)
for y = 1,self.SBheight do
for x = 1,self.SBwidth do
local rx,ry = isoToScreen(x+tox,y+toy,self.tw,self.th)
local tiledata= {
quad = nil,
index = nil,
property= nil,
sb = sb,
id = sb[sbadd](sb,dummyquad,0,0,0,0),
x = rx,
y = ry,
angle = 0,
sx = 1,
sy = 1,
}
grid.set(self.tilegrid,tox+x,toy+y,tiledata)
end
end
sb:unbind()
end
local getQuad = function(self,index)
local atlas = self.atlas
local qx,qy = atlas:getqViewport(index)
local qi = qx..','..qy
local qw,qh = atlas:getqSize()
local quad = self.quads[qi] or lg.newQuad(qx,qy,qw,qh,atlas:getImageSize())
self.quads[qi]= quad
return quad
end
local isomap = setmetatable({},{__call = function(self,...) return self.new(...) end,__index = map})
isomap.__index = isomap
function isomap.new(image,atlas, tw,th)
local self = map.new(image,atlas,tw,th)
return setmetatable(self,isomap)
end
function isomap:setTile(tx,ty,index, angle,flipx,flipy)
local t = grid.get(self.tilegrid,tx,ty)
if not t then
local sbx,sby = getSBrange(tx,ty,tx,ty,self.SBwidth,self.SBheight)
preallocateSB(self,sbx,sby)
t = grid.get(self.tilegrid,tx,ty)
end
if not index then
t.quad = nil
t.index = nil
t.angle = nil
t.sx = nil
t.sy = nil
t.property= nil
t.sb[sbset](t.sb, t.id, dummyquad, 0,0,0,0)
return
end
local quad= getQuad(self,index)
t.quad = quad
t.index = type(index)== 'table' and ( self.atlas:getColumns()*(index[2]-1) + index[1] ) or index
t.angle = angle or 0
t.sx = flipx and -1 or 1
t.sy = flipy and -1 or 1
setQuad(self,t)
end
return isomap