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
|
-- player = 300 accel, 400 velLimit
local accelLimit = 150
local velLimit = 300
Enemy = Tile:extend {
image = 'data/enemy.png',
maxVelocity = {x=velLimit,y=velLimit},
minVelocity = {x=-velLimit, y=-velLimit},
lastFired = 0,
state = 'patrolling',
onNew = function (self)
self.thrust = Tile:new{image = 'data/thrust.png'}
--the.app.view:add(self.thrust)
self.shield = Shield:new{ship = self}
self:chooseTarget()
end,
onStartFrame = function (self)
local tvec = vector.new(self.target.x - self.x,
self.target.y - self.y)
local tAngle = math.atan2(tvec.y, tvec.x)
local aDiff = self.rotation - tAngle
while aDiff < (-math.pi) do
--print(aDiff .. ' < -π')
aDiff = aDiff + 2 * math.pi
end
while aDiff > math.pi do
--print(aDiff .. ' > π')
aDiff = aDiff - 2 * math.pi
end
if math.abs(aDiff) > 0.1 then
-- rotation really shouldn't be negative. I
-- don't understand why that is. :\
self.velocity.rotation = -2 * util.signOf(aDiff)
else
--print('not rotating')
self.velocity.rotation = 0
end
if self.state == 'combat' and not the.player.active then
self.state = 'patrolling'
end
local pdist2 = vector.new(the.player.x - self.x,
the.player.y - self.y):len2()
if pdist2 < (the.app.width / 2)^2 then
-- if player is roughly on enemy's screen
if self.state == 'patrolling' and the.player.active then
self.state = 'combat'
self.target = the.player
end
elseif pdist2 > (3 * the.app.width)^2 then
if self.state == 'combat' then
self.state = 'patrolling'
self:chooseTarget()
end
end
local tdist2 = tvec:len2()
if tdist2 > 400^2 then
self.acceleration = vector.new(300, 0)
self.acceleration:rotate_inplace(self.rotation)
self.thrust.visible = true
else
self.acceleration = {x=0, y=0}
self.thrust.visible = false
end
if tdist2 < 400^2 then
if self.state == 'patrolling' then
self:chooseTarget()
elseif self.state == 'combat' then
if math.abs(aDiff) < 0.5 * math.pi and
love.timer.getTime() - self.lastFired > 0.25 then
--print('pew')
b = Bullet:new{
x = self.x + self.width / 2,
y = self.y + self.height / 2,
rotation = self.rotation,
source = self
}
self.lastFired = love.timer.getTime()
end
end
end
end,
onUpdate = function(self)
self.thrust.x = self.x - self.width
self.thrust.y = self.y
self.thrust.rotation = self.rotation
end,
onCollide = function (self, other)
if other:instanceOf(Bullet) and other.source ~= self then
if self.shield.strength == 0 then
-- die
the.app.view:add( Boom:new {
x = self.x,
y = self.y,
velocity = { rotation = 5 }
})
self:die()
self.thrust:die()
self.shield:die()
the.enemies:remove(self)
the.app.view:remove(self.thrust)
the.app.view:remove(self.shield)
-- and add a new enemy somewhere else...
local e = Enemy:new{x = math.random(the.bg.width),
y = math.random(the.bg.height)}
the.enemies:add(e)
the.view:add(e.thrust)
the.view:add(e.shield)
else
self.shield:onHit()
end
other:die()
the.bullets:remove(other)
end
end,
chooseTarget = function (self)
self.target = {
x = math.random(the.bg.width),
y = math.random(the.bg.height)
}
end
}
|