_slashing_timer_sec = .12 _slash_animation_distance = 3 function slashing_particle(following) SlashingParticleBuilder = EntityBuilder:new(World) :b_type(Entities.Particle) :b_render_order(-1) :b_live_for(_slashing_timer_sec) :b_position(vec2(following.position)) :b_sprite_position(vec2(following.sprite_position)) :b_line_of_sight(vec2(following.line_of_sight)) :b_add_state( States.Active, { animation = { pos_y = { sequence = { 115, 116, 117 }, dt = _slashing_timer_sec / 3, reflect = vec2(true, true) }, neg_y = { sequence = { 115, 116, 117 }, dt = _slashing_timer_sec / 3 }, pos_x = { sequence = { 112, 113, 114 }, dt = _slashing_timer_sec / 3 }, neg_x = { sequence = { 112, 113, 114 }, dt = _slashing_timer_sec / 3, reflect = vec2(true, false) } } } ) :b_state(States.Active) function SlashingParticleBuilder:transition_state() end return SlashingParticleBuilder:build() end function enemy() EnemyBuilder = EntityBuilder:new(World) function EnemyBuilder:transition_state() end EnemyBuilder:b_type(Entities.Enemy) :b_health(10) :b_position(vec2(30, 40)) :b_sprite_position(vec2(30, 40)) :b_line_of_sight(vec2(1, 0)) :b_render_order(1) :b_collidable() :b_add_state( States.Idle, { animation = { pos_y = { sequence = { 32, 33 }, dt = 1 }, neg_y = { sequence = { 32, 33 }, dt = 1 }, pos_x = { sequence = { 32, 33 }, dt = 1 }, neg_x = { sequence = { 32, 33 }, dt = 1, reflect = vec2(true, false) } } } ) :b_add_state( States.Walk, { animation = { pos_x = { sequence = { 32, 34 }, dt = 0.20 }, neg_x = { sequence = { 32, 34 }, dt = 0.20, reflect = vec2(true, false) }, pos_y = { sequence = { 32, 34 }, dt = 0.20 }, neg_y = { sequence = { 32, 34 }, dt = 0.20 } } } ) :b_state(States.Idle) return EnemyBuilder:build() end function wife() WifeBuilder = EntityBuilder:new(World) function WifeBuilder:transition_state() end WifeBuilder:b_type(Entities.Wife) :b_line_of_sight(vec2(1, 0)) :b_render_order(2) :b_collidable() :b_position(vec2(50, 50)) :b_sprite_position(vec2(30, 30)) :b_add_state( States.Idle, { animation = { pos_y = { sequence = { 16, 17 }, dt = 1 }, neg_y = { sequence = { 16, 17 }, dt = 1 }, pos_x = { sequence = { 16, 17 }, dt = 1 }, neg_x = { sequence = { 16, 17 }, dt = 1, reflect = vec2(true, false) } } } ) :b_state(States.Idle) return WifeBuilder:build() end function bow() BowBuilder = EntityBuilder:new(World) function BowBuilder:transition_state() end BowBuilder:b_type(Entities.Bow) :b_position(vec2(0, 0)) :b_sprite_position(vec2(0, 0)) :b_line_of_sight(vec2(1, 0)) :b_render_order(1) :b_collidable() :b_add_state( States.Equipped, { animation = { pos_y = { sequence = { 96 }, dt = 1, reflect = vec2(false, true) }, neg_y = { sequence = { 96 }, dt = 1 }, pos_x = { sequence = { 80 }, dt = 1 }, neg_x = { sequence = { 80 }, dt = 1, reflect = vec2(true, false) } } } ) :b_add_state( States.Drawn, { animation = { pos_y = { sequence = { 81 }, dt = 1, reflect = vec2(false, true) }, neg_y = { sequence = { 81 }, dt = 1 }, pos_x = { sequence = { 81 }, dt = 1 }, neg_x = { sequence = { 81 }, dt = 1, reflect = vec2(true, false) } } } ) :b_add_state( States.Drawing, { animation = BowBuilder.states[States.Equipped] } ) :b_state(States.Equipped) return BowBuilder:build() end function sword() _particle_distance = 4 _attack_burst_sec = 0.200 _sword_damage = { amount = 2, knockback = { magnitude = 300, time = 0.080 } } SwordBuilder = EntityBuilder:new(World) function SwordBuilder:transition_state() if button_just_pressed(5) and self.state == States.Equipped and self.state_stopwatch > _attack_burst_sec then self:transition_to(States.Slashing) self:equip(slashing_particle(self), _particle_distance) self.damage = _sword_damage elseif self.state == States.Slashing then self.damage = nil if (self.state_stopwatch > _slashing_timer_sec) then self:transition_to(States.Equipped) end end end SwordBuilder:b_type(Entities.Sword) :b_line_of_sight(vec2(1, 0)) :b_position(vec2(0, 0)) :b_sprite_position(vec2(0, 0)) :b_render_order(0) :b_collidable() :b_add_state( States.Equipped, { animation = { pos_y = { sequence = { 99 }, dt = 1, reflect = vec2(false, true) }, neg_y = { sequence = { 99 }, dt = 1, reflect = vec2(true, false) }, pos_x = { sequence = { 98 }, dt = 1 }, neg_x = { sequence = { 98 }, dt = 1, reflect = vec2(true, false) } } } ) :b_add_state( States.Slashing, { animation = { pos_y = { sequence = { 82, 98 }, dt = _slashing_timer_sec / 2, reflect = vec2(false, true) }, neg_y = { sequence = { 82, 98 }, dt = _slashing_timer_sec / 2, reflect = vec2(true, false) }, pos_x = { sequence = { 82, 99 }, dt = _slashing_timer_sec / 2, reflect = vec2(false, false)}, neg_x = { sequence = { 82, 99 }, dt = _slashing_timer_sec / 2, reflect = vec2(true, false) } } } ) :b_state(States.Equipped) return SwordBuilder:build() end _enemy = enemy() _sword = sword() _wife = wife() _bow = bow() function player() PlayerBuilder = EntityBuilder:new(World) function PlayerBuilder:transition_state() if (self.velocity.x == 0 and self.velocity.y == 0) then self:transition_to(States.Idle) else self:transition_to(States.Walk) end end PlayerBuilder :b_type(Entities.Player) :b_line_of_sight(vec2(1, 0)) :b_render_order(2) :b_collidable() :b_position(vec2(30, 30)) :b_sprite_position(vec2(30, 30)) :b_add_state( States.Idle, { animation = { pos_y = { sequence = { 3, 19 }, dt = 1 }, neg_y = { sequence = { 6, 22 }, dt = 1 }, pos_x = { sequence = { 0, 1 }, dt = 1 }, neg_x = { sequence = { 0, 1 }, dt = 1, reflect = vec2(true, false) } } } ) :b_add_state( States.Walk, { animation = { pos_x = { sequence = { 2, 0 }, dt = 0.20 }, neg_x = { sequence = { 2, 0 }, dt = 0.20, reflect = vec2(true, false) }, pos_y = { sequence = { 4, 5 }, dt = 0.20 }, neg_y = { sequence = { 7, 8 }, dt = 0.20 } } } ) :b_state(States.Idle) return PlayerBuilder:build() end _player = player() _player:equip(_sword) _walk_speed = 35 -- powerup increase? function handle_input() dpos = vec2(0, 0) if btn(0) then dpos.x -= 1 end if btn(1) then dpos.x += 1 end if btn(3) then dpos.y += 1 end if btn(2) then dpos.y -= 1 end _player.velocity = dpos:normal() * _walk_speed end function _init() end _camera = Camera:new(_player) _step_t = time() _continue = true function pause() _continue = false end function resume() _continue = true _step_t = time() end function _update60() -- clear here in case we want to print to screen outside of _draw cls(0) old_step = _step_t _step_t = time() step_dt = _step_t - old_step foreach(update_hooks, function(f) f(step_dt) end) handle_input() if not _continue then return end World.foreach(function(e) e:update(step_dt) end) run_collisions() World.cull_the_dead() end function _draw() -- TODO: FIX THIS -- World.sort(function(a, b) -- return b.render_order < a.render_order -- end) World.foreach(function(e) _camera:render(e) end) end