-
Notifications
You must be signed in to change notification settings - Fork 0
/
actor.lua
157 lines (126 loc) · 3.4 KB
/
actor.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
154
155
156
157
--[[
actor.lua
January 17th, 2013
]]
local Object = (require 'object').Object
require 'drawable'
require 'collidable'
local table
= table
module('objects')
Actor = Object{}
--
-- Actors support the following Events:
--
-- on_begin_X() - will be called when the actor begins an action
-- on_end_X() - will be called when the actor begins an action
--
--
-- Actor constructor
--
function Actor:_clone(values)
local collidable = values._collidable or Collidable(values)
local o = table.merge(
table.merge(collidable, Drawable(values)),
Object._clone(self,values))
o.ACTOR = true
o._lastPosUpdate = values._lastPosUpdate or { 0, 0 }
o._velocity = values._velocity or { 0, 0 }
o._currentAction = values._currentAction or nil
return o
end
--
-- Set or get the velocity
--
function Actor:velocity(x, y)
if not x then
return self._velocity
end
self._velocity[1] = x
self._velocity[2] = y
end
--
-- Update function
--
function Actor:update(dt)
self._latestDt = dt
self._lastPosUpdate[1] = (dt * self._velocity[1])
self._lastPosUpdate[2] = (dt * self._velocity[2])
self._position[1] = self._position[1] + self._lastPosUpdate[1]
self._position[2] = self._position[2] + self._lastPosUpdate[2]
Drawable.update(self, dt)
self:calculateBoundary()
end
--
-- Sets or gets the actors name
--
function Actor:name(n)
if not n then return self._name end
self._name = n
end
--
-- Called when a collidable collides with
-- another object
--
function Actor:collide(other)
-- only adjust positions for blocking items
if not other._nonBlocking then
if self._lastPosUpdate[1] ~= 0 or self._lastPosUpdate[2] ~= 0 then
-- check if reversing the last update moves the
-- actor farther away from the other object
local xdiff = other._position[1] - self._position[1]
local ydiff = other._position[2] - self._position[2]
local currentDist = xdiff * xdiff + ydiff * ydiff
local xdiff = other._position[1] -
(self._position[1] - self._lastPosUpdate[1])
local ydiff = other._position[2] -
(self._position[2] - self._lastPosUpdate[2])
local possibleDist = xdiff * xdiff + ydiff * ydiff
if currentDist < possibleDist then
self._position[1] = self._position[1] - self._lastPosUpdate[1]
self._position[2] = self._position[2] - self._lastPosUpdate[2]
self._lastPosUpdate[1] = 0
self._lastPosUpdate[2] = 0
end
self:calculateBoundary()
end
end
Collidable.collide(self, other)
end
--
-- Do an action
--
function Actor:action(name, cancel)
if not name then return self._currentAction end
-- can only do an action when not doing an action
if self._currentAction and not cancel then
return
end
-- an action is cancelled if
-- on_begin_X returns false
local retval
if self['on_begin_' .. name] then
retval = self['on_begin_' .. name](self)
end
if retval == false then return end
-- set the current action
self._currentAction = name
-- save old animation
local currentAnim
if self._currentAnimation then
currentAnim = self._currentAnimation:name()
end
-- switch to the new animation
self:animation(name, true)
-- set the callback for when the animation ends
self._currentAnimation.done_cb = function()
self._currentAnimation.done_cb = nil
self._currentAction = nil
if currentAnim then
self:animation(currentAnim, true)
end
if self['on_end_' .. name] then
self['on_end_' .. name](self)
end
end
end