Задать вопрос
@Fiiry

Как оптимизировать скрипт для передвижения врагов и атаки персонажа врагами?

В скрипте у мобов есть два состояния: они бродят или атакуют персонажа, когда он находится в заданных пределах.
Любые переменные игрока, такие как хп и позиция на карте берутся из автолод скрипта global. Я не уверен, что такая архитектура в принципе является удачной, если я прав, был бы рад, если вы предложите новую.

extends KinematicBody2D


var player_is_attacked = false
var staying = true
var speed = 45
var speed_atack = 1
var range_atack = 40
var damage = 1
var detection_area = 200
var velocity = Vector2()
var destination = Vector2()
var prev_pos = Vector2()
var player_pos = Vector2()
export var x_zone = 0
export var y_zone = 0


func _ready():
	$AnimatedSprite.speed_scale = speed_atack

func _process(delta):
	if velocity:
		prev_pos = position
		select_walk_animation()
		move_and_slide(velocity)
	generate_destination()
	if global.player_health != 0:
		search_player()
	else:
		player_is_attacked = false

func generate_destination():	
	if staying:
		randomize()
		var x = rand_range(x_zone - 90, x_zone + 90) #x_zone и y_zone присваиваются в сцене карты
		var y = rand_range(y_zone - 90, y_zone + 90)
		get_destination(Vector2(x, y))
		
	elif velocity != Vector2():
		if not player_is_attacked:
			if position.distance_to(destination) <= speed:
				cancel_moving()
				$NotMovTimer.start(1.5)
			elif prev_pos.distance_to(position) <= 0.6:
				cancel_moving()
				$NotMovTimer.start(0.5)


func get_destination(dest):
	destination = dest
	velocity = (destination - position).normalized() * speed
	staying = false


func search_player():
	var pl_pos = Vector2(global.player_pos.x, global.player_pos.y)
	if pl_pos.distance_to(position) <= detection_area: #игрок в заданой области
		get_destination(pl_pos)
	if pl_pos.distance_to(position) <= range_atack: #если до точки остался путь в range_atack
		velocity = Vector2()
		destination = Vector2()
		select_attack_animation()
		player_is_attacked = true
	else:
		player_is_attacked = false


func cancel_moving():
	$AnimatedSprite.stop()
	$AnimatedSprite.set_frame(0) # анимация в 0(спокойствии) и сохраняет свое направление после .stop()
	velocity = Vector2()
	destination = Vector2()

func select_walk_animation():
	if abs(velocity.x) > abs(velocity.y):
		if velocity.x < 0:
			$AnimatedSprite.play("left")
		else:
			$AnimatedSprite.play("right")
	elif abs(velocity.x) < abs(velocity.y):
		if velocity.y < 0:
			$AnimatedSprite.play("up")
		else:
			$AnimatedSprite.play("down")

func select_attack_animation():
	if "atack" in $AnimatedSprite.animation: #анимации удара называются attack_направление
		return 								 #анимации передвижения left, right, up, down
	else:
		$AnimatedSprite.play("atack_" + $AnimatedSprite.animation)
		
func _on_NotMovTimer_timeout():
	staying = true


func _on_AnimatedSprite_animation_finished():
	if player_is_attacked and global.player_health >= 0:
		global.player_health -= damage
  • Вопрос задан
  • 83 просмотра
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы