Enemy that runs away from you

Started by Max, October 24, 2018, 02:02:18 AM

Previous topic - Next topic
October 24, 2018, 02:02:18 AM Last Edit: October 24, 2018, 02:13:03 AM by Max
I don't know if this'd be handy for anyone else, but I'd been messing with getting an enemy that runs away from you to be fun, and I think I've finally got it.

This enemy will wader randomly until you get within its detection_distance, then it'll run in the opposite direction of the player. When it hits a wall, it will dash in a random direction for its dash_distance, then go back to running from the player.

I think it's pretty fun to chase, the random dashing when it hits a wall makes it pretty unpredictable and it a pretty good compromise to keep it from getting stuck in corners. There's also an element of danger to trying to corner it, because it very well might just dash through you and damage you. In my testing, it works best and a kind of joke-ier enemy that doesn't do much damage, because whenever it bumps into a wall it careens wildly and is going to smack into the player at some point.

Also, here's a gif of the behavior. It's more fun that it might look, haha:


Code (lua) Select

local enemy = ...
local game = enemy:get_game()
local map = enemy:get_map()
local hero = map:get_hero()
local sprite
local movement
local dashing
--adjustable stats
local hp = 30
local damage = 1
local detection_distance = 65
local walking_speed = 45
local running_speed = 82
local dash_distance = 80
local dash_speed = 140


function enemy:on_created()
  sprite = enemy:create_sprite("enemies/" .. enemy:get_breed())
  enemy:set_life(hp)
  enemy:set_damage(damage)
end

function enemy:on_movement_changed(movement)
  local direction4 = movement:get_direction4()
  sprite = self:get_sprite()
  sprite:set_direction(direction4)
end

function enemy:on_restarted()
  if moement ~= nil then movement:stop() end
  dashing = false
  enemy:go_random()
  enemy:check_hero()
end

function enemy:check_hero()
  local dist_hero = enemy:get_distance(hero)
  local _,_,hero_layer = hero:get_position()
  local _,_,enemy_layer = enemy:get_position()
  if enemy_layer == hero_layer and dist_hero < detection_distance and not dashing then
    enemy:run_away()
  elseif not dashing then
    enemy:go_random()
  end

  sol.timer.start(enemy, 100, function() enemy:check_hero() end)

end

function enemy:run_away()
  local angle = enemy:get_angle(hero)
  angle = angle + math.pi
  movement = sol.movement.create("straight")
  movement:set_angle(angle)
  movement:set_speed(running_speed)
  movement:start(enemy) 
end

function enemy:go_random()
  movement = sol.movement.create("random_path")
  movement:set_speed(walking_speed)
  movement:start(enemy)
end

function enemy:on_obstacle_reached()
  enemy:dash()
end

function enemy:dash()
  dashing = true
  movement = sol.movement.create("straight")
  movement:set_angle(math.random(2*math.pi))
  movement:set_speed(dash_speed)
  movement:set_max_distance(dash_distance)
  movement:start(enemy, function()
    dashing = false
    enemy:go_random()
  end)
end



Nice one!

Looks like you have a typo on line 31: "moement"

Haha this is awesome!
RIP Aaron Swartz