-
Notifications
You must be signed in to change notification settings - Fork 2
/
entity.lua
151 lines (116 loc) · 3.96 KB
/
entity.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
-------------------------------------------------------------------------
-- [entity.lua]
-- entity
-------------------------------------------------------------------------
local _M = {_NAME = "entity", _TYPE = 'module'}
local _MT = {__index = _M}
-------------------------------------------------------------------------
local count = 0
local SFX_Explosion = love.audio.newSource("sfx/Explosion.wav", "static")
-------------------------------------------------------------------------
-- Handles some texture properties
function _M.set_texture(self, texture)
self.texture = texture
self.width = texture:getWidth()
self.height = texture:getHeight()
end
local generic_icon = love.graphics.newImage("gfx/AutoTurret.png")
-------------------------------------------------------------------------
function _M.new(t)
t = t or {}
local e = {}
e._TYPE = 'entity'
e.kind = t.kind or 'thing'
e.name = t.name or string.format('entity#%d', count)
e.id = count
e.pos_x = t.pos_x or 0
e.pos_y = t.pos_y or 0
e.dir_x = t.dir_x or 0
e.dir_y = t.dir_y or 0
e.speed = t.speed or 0
e.facing = t.facing or 0
e.scale = t.scale or 1
-- Handles the texture, width, and height fields
_M.set_texture(e, t.texture or generic_icon)
e.state = t.state or 'alive'
e.shieldmax = t.shieldmax or 100
e.shield = t.shield or e.shieldmax
e.damage = t.damage or e.shieldmax *.3
e.radius = t.radius or (e.height + e.width)/3
count = count + 1
return setmetatable(e, _MT)
end
-------------------------------------------------------------------------
function _M:think(dt)
end
-------------------------------------------------------------------------
function _M:update(dt)
local dv = self.speed * dt
self.pos_x = self.pos_x + (self.dir_x * dv)
self.pos_y = self.pos_y + (self.dir_y * dv)
self:think(dt)
end
-- returns the distance between this entity, and the given entity.
function _M:distance(e)
local a = math.abs(self.pos_x - e.pos_x)^2
local b = math.abs(self.pos_y - e.pos_y)^2
return math.sqrt(a+b)
end
-- tests if this entity, and the given entity, have collided.
function _M:testcollision(e)
return self:distance(e) <= self.radius+e.radius
end
function _M:draw()
assert(self, "We have no self, so I really don't know how you expect this to work.")
local tau = math.pi*2
local hpratio = self.shield / self.shieldmax
local lg = love.graphics
lg.push()
-- draw health-indicators
lg.setColor(0,0, 127)
lg.circle('line', self.pos_x, self.pos_y, self.radius)
lg.setColor(255-(255*hpratio), 255*hpratio, 0)
lg.arc('line', self.pos_x, self.pos_y, self.radius, 0, hpratio*tau)
-- draw the actual sprite
lg.setColor(255, 255, 255)
lg.draw(self.texture, self.pos_x, self.pos_y, self.facing, self.scale, self.scale, self.width/2, self.height/2)
lg.pop()
end
-- damages the entity according to the given number,
-- and tests / triggers death if appropriate
function _M:dohit(n)
n = n or 1
assert(n > 0, "Cannot hurt for negative damage")
local shield = self.shield - n
shield = shield >= 0 and shield or 0
shield = shield <= self.shieldmax and shield or self.shieldmax
self.shield = shield
love.audio.play(SFX_Explosion) -- shouldn't this be using the soundmanager?
if shield == 0 and self.state ~= 'dead'then
self:die()
end
return shield
end
-- handles the death of the entity.
function _M:die()
self.state = 'dead'
self.shooting = false
self.dir_x = 0
self.dir_y = 0
end
function _M:heal(n)
n = n or 1
assert(n > 0, "Cannot heal for negative health")
local shield = self.shield
shield = shield + n
shield = shield >= 0 and shield or 0
shield = shield <= self.shieldmax and shield or self.shieldmax
self.shield = shield
end
function _M:collidewith(e, dt)
assert(e and e._TYPE == 'entity', string.format("Expected 'entity', got '%s' instead.", e and e.type or type(e)))
e:dohit(self.damage*dt)
end
-------------------------------------------------------------------------
if _VERSION == "Lua 5.1" then _G[_M._NAME] = _M end
return _M