-
Notifications
You must be signed in to change notification settings - Fork 1
/
objman.lua
153 lines (141 loc) · 4.84 KB
/
objman.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
ObjMan = class(function(o)
o.objects = {}
o.not_objects = {}
for idx, kind in ipairs(object_kinds) do
o.objects[kind] = {}
o.not_objects[kind] = {}
end
o.age = 0
o.routines = {}
o:add(Object({x=400, y=300, direction=facing_up, kind="player"}))
end)
function ObjMan.draw(self)
for i,kind in ipairs(object_kinds) do
local objects = self.objects[kind]
--set_color(unpack(default_colors[kind]))
for j=1, #objects do
objects[j]:draw()
end
end
end
function ObjMan.run(self)
local player = self.objects["player"][1]
if player then
local pdx=0
local pdy=0
if keys["up"] then pdy = pdy - 1 end
if keys["down"] then pdy = pdy + 1 end
if keys["left"] then pdx = pdx - 1 end
if keys["right"] then pdx = pdx + 1 end
local pspeed, pdirection = get_polar(pdx, pdy)
pspeed = min(1, pspeed)
pspeed = pspeed * 7
if keys["lshift"] then pspeed = pspeed * 0.5 end
player.speed=pspeed
if pspeed ~= 0 then player.direction = pdirection end
end
-- Move all the objects
for kind, objects in pairs(self.objects) do
for j=1, #objects do
objects[j]:run()
end
end
-- Move the player back onto the screen...
if player then
player.x = min(player.x, 800-5)
player.x = max(player.x, 5)
player.y = min(player.y, 600-5)
player.y = max(player.y, 5)
end
-- Run all of their scripts
local routines = self.routines[self.age] or {}
for i=1, #routines do
local blob = routines[i]
local routine, args = blob[1], blob[2]
local status = nil
local result = nil
if args then
status, result = coroutine.resume(routine, unpack(args))
else
status, result = coroutine.resume(routine)
end
if not status then
error(result..'\n'..debug.traceback(routine))
end
if result and type(result) == "number" and result > 0 then
result = result + self.age
if not self.routines[result] then
self.routines[result] = {}
end
local later_r = self.routines[result]
later_r[#later_r + 1] = {routine}
end
end
-- don't leave references to dead routines lying around...
self.routines[self.age] = nil
-- Make them crash into each other
self:collision("enemy_bullet", "player")
-- Get rid of the ones that died
for kind, objects in pairs(self.objects) do
local not_objects = {}
for j=1, #objects do
local object = objects[j]
if object.dead then
if kind=="player" or kind=="enemy_bullet" then
object.dead = false
local r, theta = v_add_polar({3, facing_right},
{object.speed, object.direction})
object:fire({speed=r, direction=theta, kind="top_fade"},
{later, 10, Object.vanish})
r, theta = v_add_polar({3, facing_left},
{object.speed, object.direction})
object:fire({speed=r, direction=theta, kind="bot_fade"},
{later, 10, Object.vanish})
object.dead = true
end
else
not_objects[#not_objects + 1] = object
end
end
self.not_objects[kind] = not_objects
end
self.objects, self.not_objects = self.not_objects, self.objects
self.age = self.age + 1
end
function ObjMan.collision(self, kind_a, kind_b)
local objs_a = self.objects[kind_a]
local objs_b = self.objects[kind_b]
for i=1, #objs_a do
local a = objs_a[i]
for j=1, #objs_b do
local b = objs_b[j]
local dx = abs(a.x - b.x)
local dy = abs(a.y - b.y)
-- TODO: lol, square collision detection with hard-coded radius
if dx < 8 and dy < 8 then
local damage = max(min(a.health, b.health), 0)
a.health = a.health - damage
b.health = b.health - damage
if a.health <= 0 then a:core_vanish() end
if b.health <= 0 then b:core_vanish() end
end
end
end
end
function ObjMan.add(self, obj)
--if not obj then return end
local objects = self.objects[obj.kind]
objects[#objects + 1] = obj
end
function ObjMan.register(self, obj, args)
if not self.routines[self.age+1] then
self.routines[self.age+1] = {}
end
local routines = self.routines[self.age+1]
if type(args) == "function" then
args = {args}
end
local func = args[1]
args[1] = obj
routines[#routines + 1] = {coroutine.create(func), args}
end