Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | lucasfazzi |
I was wondering a way to make a enemy that “ambushes” the player. Is not a real ambush that make a lot of decisions based on player behavior to proper tricks him, just a AI that follows the player by the back besides the front or global position.
I already have a default enemy that follows player with this basic AI:
extends KinematicBody2D
var ENEMY_1_LIFE = 100
var RAND_SPEED = 0
onready var player = get_parent().get_node("player")
onready var enemy_1_FOV = false
func _ready():
get_node("fov_enemy_1").add_to_group("fov_enemies")
get_node("enemy_1_hit").add_to_group("enemy_1_hit")
RAND_SPEED = randi()%320+100
func _on_fov_enemy_1_body_entered(body):
if body == player:
enemy_1_FOV = true
else:
null
func _physics_process(delta):
if enemy_1_FOV == true:
var vec_to_player = player.global_position - global_position
vec_to_player = vec_to_player.normalized()
move_and_collide(vec_to_player * RAND_SPEED * delta)
else:
null
func _on_enemy_1_hit_area_entered(area):
if area.is_in_group("bullet_1_hit_group"):
ENEMY_1_LIFE -= 50
else:
null
if ENEMY_1_LIFE == 0:
destroy_enemy_1()
func destroy_enemy_1():
queue_free()
You can see that enemy follows player with a global position in relation with player. I was wondering if it’s possible to adapt this to make enemy following the player by the back when it approachs by certain distance.
I make some sketch to exemplify:
thanks guys
I make some tests, it’s a bit amateur but it works.
I will put here to share, so anybody can test or refine.
- I put two areas attached to player on a triangular angle:
- then i re-write the code with two behaviors: first step, when player go to enemy FOV, enemy walks with one of this areas (randi); second when enemy colides with this areas, then the movement changes and he start to follow player by global position; code:
extends KinematicBody2D
onready var player = get_parent().get_node("player")
onready var player_ambush_1 = get_parent().get_node("player/player_catch1")
onready var player_ambush_2 = get_parent().get_node("player/player_catch2")
var ENEMY_4_LIFE = 150
var RAND_SPEED = 0
var vec_to_player_ambush_1
var vec_to_player_ambush_2
var randi_ambush = 0
var enemy_4_FOV = false
var enemy_4_get_position = false
func _ready():
global.enemy_4 = self
get_node("enemy_4_fov").add_to_group("fov_enemies")
get_node("enemy_4_hit").add_to_group("enemy_4_hit")
RAND_SPEED = randi()%280+200
func _on_enemy_4_fov_body_entered(body):
if body == player:
enemy_4_get_position = true
randi_ambush = randi()%2+1
else:
null
func _physics_process(delta):
if randi_ambush == 1 and enemy_4_get_position == true:
vec_to_player_ambush_1 = player_ambush_1.global_position - global_position
vec_to_player_ambush_1 = vec_to_player_ambush_1.normalized()
move_and_collide(vec_to_player_ambush_1 * RAND_SPEED * delta)
if randi_ambush == 2 and enemy_4_get_position == true:
vec_to_player_ambush_2 = player_ambush_2.global_position - global_position
vec_to_player_ambush_2 = vec_to_player_ambush_2.normalized()
move_and_collide(vec_to_player_ambush_2 * RAND_SPEED * delta)
else:
null
if randi_ambush == 1 and enemy_4_get_position == false:
var vec_to_player = player.global_position - global_position
vec_to_player = vec_to_player.normalized()
move_and_collide(vec_to_player * RAND_SPEED * delta)
if randi_ambush == 2 and enemy_4_get_position == false:
var vec_to_player = player.global_position - global_position
vec_to_player = vec_to_player.normalized()
move_and_collide(vec_to_player * RAND_SPEED * delta)
func _on_enemy_4_area_entered_player_position_area_entered(area):
if area.is_in_group("player_catches"):
enemy_4_get_position = false
else:
null
func _on_enemy_4_fov_body_exited(body):
if body == player:
enemy_4_get_position = true
randi_ambush = randi()%2+1
else:
null
func _on_enemy_4_hit_area_entered(area):
if area.is_in_group("bullet_1_hit_group"):
ENEMY_4_LIFE -= 50
check_enemy_4_life()
if area.is_in_group("player_hit"):
enemy_4_get_position = true
randi_ambush = randi()%2+1
else:
null
func check_enemy_4_life():
if ENEMY_4_LIFE == 0:
destroy_enemy_4()
else:
null
func destroy_enemy_4():
queue_free()
With this way, the enemy can make something like this:
I’m still have problems when enemy hit player by the front and get stuck, but is a huge progress.
lucasfazzi | 2019-02-09 16:57