-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlevel.lua
126 lines (115 loc) · 3.48 KB
/
level.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
114
115
116
117
118
119
120
121
122
123
124
125
126
require 'ball'
require 'class'
require 'player'
local DEBUG_VIEW = false
local tileW, tileH = 32, 32
local function imageTile(name)
return function(world, x, y)
local obj = {}
obj.graphics = love.graphics.newImage(name)
obj.body = love.physics.newBody(world, x, y)
obj.shape = love.physics.newRectangleShape(tileW, tileH)
obj.fixture = love.physics.newFixture(obj.body, obj.shape)
return obj
end
end
local function objTile(cls, dir)
return function(world, x, y)
return cls:create(world, x, y + tileH/2*dir, dir)
end
end
local legend = {
B = imageTile('brick.png'),
G = imageTile('grass.png'),
R = imageTile('grass2.png'),
P = objTile(Player, 1),
Q = objTile(Player, -1),
O = objTile(Ball, 1),
['.'] = function() return {} end,
}
Level = class {}
function Level:fromString(str)
love.physics.setMeter(tileH)
local world = love.physics.newWorld(0, 9.8*tileH, true)
local row, objects, collisions = {}, {}, {}
local grid = { row }
for i = 1, #str do
local c = str:sub(i, i)
if c == '\n' then
row = {}
grid[#grid + 1] = row
else
local x, y = (#row+0.5) * tileW, (#grid-0.5) * tileH
local obj = legend[c](world, x, y)
if obj.update then
objects[#objects + 1] = obj
if obj.collideOn then
for _, fixt in pairs(obj.collideOn) do
collisions[fixt] = obj
end
end
obj = {}
end
row[#row + 1] = obj
end
end
local function onContact(fixt1, fixt2, contact)
if collisions[fixt1] then
collisions[fixt1]:collide(fixt2, contact)
end
if collisions[fixt2] then
collisions[fixt2]:collide(fixt1, contact)
end
end
world:setCallbacks(onContact, onContact)
love.window.setMode(#grid[1] * tileW, #grid * tileH)
return self:new {
world = world,
grid = grid,
objects = objects,
}
end
function Level:update(dt)
for _, obj in pairs(self.objects) do
obj:update(dt)
end
self.world:update(dt)
end
function Level:draw()
for y, row in ipairs(self.grid) do
for x, t in ipairs(row) do
if t.graphics then
love.graphics.draw(t.graphics, (x-1) * tileW, (y-1) * tileH)
end
end
end
for i, obj in pairs(self.objects) do
love.graphics.draw(obj.graphics, obj:getX(), obj:getY())
end
end
if DEBUG_VIEW then
local function drawShapes(obj)
for _, val in pairs(obj) do
if type(val) == 'userdata' and val.typeOf and val:typeOf('Fixture') then
local body, shape = val:getBody(), val:getShape()
if shape:typeOf('PolygonShape') then
love.graphics.polygon('line', body:getWorldPoints(shape:getPoints()))
elseif shape:typeOf('CircleShape') then
love.graphics.circle('line', body:getX(), body:getY(), shape:getRadius())
end
end
end
end
function Level:draw()
love.graphics.setColor(250, 250, 250)
for y, row in ipairs(self.grid) do
for x, t in ipairs(row) do
drawShapes(t)
end
end
love.graphics.setColor(250, 0, 0)
for i, obj in pairs(self.objects) do
drawShapes(obj)
end
end
end