Skip to content

Instantly share code, notes, and snippets.

@a327ex
Created January 17, 2021 15:44
Show Gist options
  • Save a327ex/2b08ec586b4be736a6e3f56efa4a230f to your computer and use it in GitHub Desktop.
Save a327ex/2b08ec586b4be736a6e3f56efa4a230f to your computer and use it in GitHub Desktop.
class Outlier extends GameObject
new: (group, x, y, opts) =>
super group, x, y, opts
@\set_as_rectangle 18, 10, 'dynamic', 'enemy'
@\set_fixed_rotation true
@color = red[0]
@max_hp = (2000 + node.level*100)
@hp = @max_hp
@\set_as_steerable 65, 2000, 4*math.pi, 4
mixin @, Enemy
@done = true
update: (dt) =>
@\update_game_object dt
if @done
@next_attack = random\table {'rotate_cone', 'rotate_quad', 'chase'}
switch @next_attack
when 'rotate_cone'
@arg = random\table {{x: node.x1 + gw/12, y: gh/2}, {x: node.x2 - gw/12, y: gh/2}}
when 'rotate_quad'
@arg = {x: gw/2, y: gh/2}
when 'chase'
@arg = nil
@done = false
@[@next_attack] @, @arg, dt
if not @pre_shooting and not @rotating
@\rotate_towards_velocity 0.5
@r = @\get_angle!
rotate_cone: (p) =>
@\seek_point p.x, p.y
@\wander 50, 100, 20
if @\distance_to_point(p.x, p.y) <= 5 and not @pre_shooting
@pre_shooting = true
@timer\cancel 'sides'
@timer\after 0.2, (->
@shooting = true
n = math.remap node.level, 0, 20, 1, 0.25
@timer\every 0.25*n, (->
@\shoot @r + random\float -n*math.pi/12, n*math.pi/12
), nil, nil, 'shooting'
@timer\after {6, 8}, (->
@timer\cancel 'shooting'
@shooting = false
@pre_shooting = false
@done = true
@\sides!
)
)
if @shooting
EnemyProjectile main, @x + 1.25*@shape.w*math.cos(@r - math.pi/8), @y + 1.25*@shape.w*math.sin(@r - math.pi/8), {v: 250, r: @r - math.pi/8, color: @color}
EnemyProjectile main, @x + 1.25*@shape.w*math.cos(@r + math.pi/8), @y + 1.25*@shape.w*math.sin(@r + math.pi/8), {v: 250, r: @r + math.pi/8, color: @color}
if @pre_shooting
@\rotate_towards_object node.player, 0.2
@r = @\get_angle!
rotate_quad: (p, dt) =>
@\seek_point p.x, p.y
@\wander 50, 100, 20
if @\distance_to_point(p.x, p.y) <= 5 and not @rotating
@rotating = true
@timer\cancel 'sides'
@timer\after 0.2, (->
@rotating_shooting = true
@timer\after {6, 8}, (->
@rotating = false
@rotating_shooting = false
@done = true
@\sides!
)
)
if @rotating_shooting
EnemyProjectile main, @x + 1.25*@shape.w*math.cos(@r - math.pi/4), @y + 1.25*@shape.w*math.sin(@r - math.pi/4), {v: 250, r: @r - math.pi/4, color: @color}
EnemyProjectile main, @x + 1.25*@shape.w*math.cos(@r + math.pi/4), @y + 1.25*@shape.w*math.sin(@r + math.pi/4), {v: 250, r: @r + math.pi/4, color: @color}
EnemyProjectile main, @x + 1.25*@shape.w*math.cos(@r - 3*math.pi/4), @y + 1.25*@shape.w*math.sin(@r - 3*math.pi/4), {v: 250, r: @r - 3*math.pi/4, color: @color}
EnemyProjectile main, @x + 1.25*@shape.w*math.cos(@r + 3*math.pi/4), @y + 1.25*@shape.w*math.sin(@r + 3*math.pi/4), {v: 250, r: @r + 3*math.pi/4, color: @color}
if @rotating
n = math.remap node.level, 0, 20, 1, 4
@r += n*0.25*math.pi*dt
@\set_angle @r
chase: =>
@\seek_object node.player
@\wander 50, 100, 20
@\rotate_towards_velocity 0.5
@r = @\get_angle!
if not @chase_shooting
@chase_shooting = true
@timer\cancel 'sides'
@timer\every {2, 3}, (->
@spring\pull 0.375
@hit_flash = true
@timer\after 0.15, (-> @hit_flash = false), 'shoot_hit_flash'
n = math.remap node.level, 0, 20, 1, 4
for i = 1, math.ceil(4*n)
@timer\after (i-1)*0.1, (->
n = math.remap node.level, 0, 20, 1, 6
d = random\float -2*n, 2*n
x, y = @x + 12*math.cos(@r + math.pi) + d*math.cos(@r + math.pi + math.pi/2), @y + 12*math.sin(@r + math.pi) + d*math.sin(@r + math.pi + math.pi/2)
HitCircle effects, x, y, {rs: 6}
n = math.remap node.level, 0, 20, 1, 2
EnemyProjectile main, x, y, {r: @r + math.pi, v: n*random\float(150, 200), color: @color, ricochet: 3}
)
), nil, nil, 'chase_shooting'
@timer\after {8, 10}, (->
@timer\cancel 'chase_shooting'
@chase_shooting = false
@done = true
@\sides!
)
sides: =>
n = math.remap node.level, 0, 20, 1, 0.25
@timer\every 0.4*n, (->
HitCircle effects, @x + 0.8*@shape.h*math.cos(@r - math.pi/2), @y + 0.8*@shape.h*math.sin(@r - math.pi/2), {rs: 6}
HitCircle effects, @x + 0.8*@shape.h*math.cos(@r + math.pi/2), @y + 0.8*@shape.h*math.sin(@r + math.pi/2), {rs: 6}
EnemyProjectile main, @x + 1.25*@shape.h*math.cos(@r - math.pi/2), @y + 1.25*@shape.h*math.sin(@r - math.pi/2), {v: 250, r: @r - math.pi/2, color: @color}
EnemyProjectile main, @x + 1.25*@shape.h*math.cos(@r + math.pi/2), @y + 1.25*@shape.h*math.sin(@r + math.pi/2), {v: 250, r: @r + math.pi/2, color: @color}
), nil, nil, 'sides'
shoot: (r) =>
@hit_flash = true
@timer\after 0.15, (-> @hit_flash = false), 'shoot_hit_flash'
@spring\pull 0.15, 200, 10
HitCircle effects, @x + 0.8*@shape.w*math.cos(r), @y + 0.8*@shape.w*math.sin(r), {rs: 6}
EnemyProjectile main, @x + 1.6*@shape.w*math.cos(r), @y + 1.6*@shape.w*math.sin(r), {v: 175, r: r, color: @color}
draw: =>
color = @color
if @hit_flash then color = fg[0]
graphics.push @x, @y, @r, @spring.x, @spring.x
graphics.rectangle @x, @y, @shape.w, @shape.h, 4, 4, color
graphics.pop!
@\draw_enemy_ui!
on_collision_enter: (other, contact) =>
if other.__class == Solid
nx, ny = contact\getNormal!
x, y = contact\getPositions!
r = 0
if nx == 0 and ny == -1 then r = -math.pi/2
elseif nx == 0 and ny == 1 then r = math.pi/2
elseif nx == -1 and ny == 0 then r = math.pi
else r = 0
@hit_flash = true
@timer\after 0.15, (-> @hit_flash = false), 'hit_flash'
@spring\pull 0.25, 200, 10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment