Game Development Reference
In-Depth Information
@closest_powerup
=
nil
if
now
-
(
@powerup_cache_updated_at
||= 0
)
>
POWERUP_CACHE_TIMEOUT
@closest_powerup
=
nil
@powerup_cache_updated_at
=
now
end
@closest_powerup
||=
find_closest_powerup(
*
suitable)
end
private
def
find_closest_powerup
(
*
suitable)
if
suitable
.
empty?
suitable
= [
FireRatePowerup
,
HealthPowerup
,
RepairPowerup
,
TankSpeedPowerup
]
end
@in_sight
.
select
do
|
o
|
suitable
.
include?(o
.
class)
end
.
sort
do
|
a, b
|
x, y
=
@viewer
.
x,
@viewer
.
y
d1
=
Utils
.
distance_between(x, y, a
.
x, a
.
y)
d2
=
Utils
.
distance_between(x, y, b
.
x, b
.
y)
d1
<=>
d2
end
.
first
end
# ...
end
It is very similar to
AiVision#closest_tank
, and parts should probably be extracted
to keep the code dry, but we will not bother.
Seeking Powerups While Roaming
Roaming is when most picking should happen, because Tank sees no enemies in sight and
needs to prepare for upcoming battles. Let's see how can we implement this behavior while
leveraging the newly made
AiVision#closest_powerup
:
class
TankRoamingState
<
TankMotionState
# ...
def
required_powerups
required
= []
health
=
@object
.
health
.
health
if
@object
.
fire_rate_modifier
< 2 &&
health
> 50
required
<<
FireRatePowerup