Created
January 17, 2021 15:44
-
-
Save a327ex/2b08ec586b4be736a6e3f56efa4a230f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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