u/Aggressive-Site-2184

▲ 2 r/CreandoConGodot+1 crossposts

Bugs con las fisicas de mi personage

acabo de hacer que en mi juego de lucha el jugador pueda embestir al enemigo, y al hacerlo el enemigo se desliza ligeramente, pero por algún motivo no funciona, le pedí ayuda a chat gpt y lo único que hace es decirme que haga 500 cambios inútiles en mi código, los cuales no arreglan nada.

uso una var llamada u/export var fuerza_empuje = 600

la parte que se encarga de detectar el daño es esta.

func recibir_daño(cantidad, tipo_golpe, atacante = null):

Life -= cantidad

$vida.text = str(Life)



if estado == "bloquear":

	golpes\_bloqueados += 1

	

	var reduccion = 0.95 - (golpes\_bloqueados \* 0.15)

	reduccion = clamp(reduccion, 0.2, 0.95)

	

	cantidad \*= (1.0 - reduccion)

	Life -= cantidad

	$vida.text = str(Life)

	return



golpes\_bloqueados = 0



dañado = true

ocupado = true

atacando = false

match tipo_golpe:

"embestida":

		empujado = true

		ocupado = true

		atacando = false

		

		if atacante != null:

var dir = sign(global_position.x - atacante.global_position.x)

velocity.x = dir * fuerza_empuje

		$AnimationPlayer.play("daño2")

y creo que el fallo podría estar aquí.

if dañado and not empujado:

	velocity.x = 0

	move\_and\_slide()

	return

aunque yo lo borre y seguia sin funcionar, pero el fallo tambien podria estar aqui.

if empujado:

	

	velocity.x = lerp(velocity.x, 0.0, 0.1)

	

	move\_and\_slide()

	

	if abs(velocity.x) < 10:

		empujado = false

		dañado = false

		ocupado = false

	return  
reddit.com
u/Aggressive-Site-2184 — 15 days ago
▲ 1 r/CreandoConGodot+1 crossposts

e estado programando una IA para mi juego de peleas para godot 4.6, y funcionaba de forma decente, pero cuando le añadí el código que le permite hacer daño al jugador el enemigo cambio por completo, ahora se queda quieto casi siempre, y cuando no lo hace se pone a caminar a ningun lado, o salta y bloquea por todas partes, necesito arreglarlo.

class_name Soldado_Draco

extends CharacterBody2D

const ataque_ki = preload("res://juego/ki/ataque_ki.tscn")

var obgetivo = null

var distancia_obgetivo = 0

var tiempo_decision = 0

var intervalo_decision = randf_range(0.05, 0.3)

var ocupado = false

var puede_combo = true

var agresividad = randf_range(0.3, 0.9)

var defensa = randf_range(0.2, 0.8)

var locura = randf_range(0.0, 1.0)

var embistiendo = false

var embestida_direccion = 0

u/export var enegia_embestida_coste = 10

u/export var cooldown_combo = 0.3

var estado = "idle"

var ultimo_estado = ""

var repeticiones = 0

var en_aire_por_golpe = false

var empujado = false

u/export var fuerza_uppercut = 800

u/export var fuerza_empuje = 600

u/export var nivel = 1

u/export var Life = 100

u/export var Energy = 100

u/export var Max_energy = 100

u/export var gravity = 20

u/export var jump_speed = 1000

u/export var speed = 200

u/export var spring_speed = 1000

u/export var damage_embestida = 5

u/export var damage = 10

var puede_bloquear = true

var puede_embestir = true

u/export var cooldown_embestida = 2.0

var dañado = false

var atacando = false

var mirar_izquierda = false

var grupo_enemigo = ""

func _ready() -> void:

add\_to\_group("P\_jugables2")

randomize()

$AnimationPlayer.play("por defecto")

$vida.text = str(Life)

func _physics_process(delta):

var current\_time = Time.get\_ticks\_msec() / 1000.0

tiempo\_decision -= delta

obgetivo = obtener\_enemigo\_mas\_cercano()



if obgetivo != null:

	distancia\_obgetivo = global\_position.distance\_to(obgetivo.global\_position)

	mirar\_izquierda = obgetivo.global\_position.x < global\_position.x



if not is\_on\_floor():

	velocity.y += gravity



if empujado:

	move\_and\_slide()

	

	velocity.x = lerp(velocity.x, 0.0, 0.1)

	

	if abs(velocity.x) < 10:

		empujado = false

		ocupado = false

	return



if en\_aire\_por\_golpe:

	move\_and\_slide()

	if en\_aire\_por\_golpe and is\_on\_floor():

		en\_aire\_por\_golpe = false

		ocupado = false

		velocity.y = 0

		$AnimationPlayer.play("por defecto")

	return



if is\_on\_floor() and estado == "saltar":

	ocupado = false

	tomar\_decision()



if tiempo\_decision <= 0 and not en\_aire\_por\_golpe:

	tomar\_decision()

	

	intervalo\_decision = randf\_range(0.05, 0.4)

	tiempo\_decision = intervalo\_decision



if dañado:

	velocity.x = 0

	move\_and\_slide()

	return



if embistiendo:

	velocity.x = spring\_speed \* embestida\_direccion

	

	Energy -= 20 \* delta

	if Energy <= 0:

		Energy = 0

		terminar\_embestida()

	move\_and\_slide()

	return



if mirar\_izquierda:

	$Visual.scale.x = -1

else:

	$Visual.scale.x = 1



match estado:

	"idle":

		velocity.x = 0

		$AnimationPlayer.play("por defecto")

	"acercarse":

		mover\_hacia\_obgetivo()

	"embestida":

		embestida\_ia()

	"saltar":

		saltar\_ia()

	"atacar":

		ataque\_cuerpo()

	"combo":

		ataque\_combo()

	"ataque\_distancia":

		ataque\_ki\_ia()

	"bloquear":

		bloquear\_ia()

	"recargar":

		recargar\_ia()

move\_and\_slide()

func cambiar_estado(nuevo):

if atacando or ocupado:

	return



if nuevo == ultimo\_estado:

	repeticiones += 1

else:

	repeticiones = 0



if repeticiones > 2:

	var alternativas = \["saltar", "bloquear", "acercarse"\]

	nuevo = alternativas.pick\_random()

	repeticiones = 0

estado = nuevo

ultimo\_estado = nuevo

func tomar_decision():

if randf() < 0.1:

	cambiar\_estado("idle")

	return



if obgetivo == null:

	cambiar\_estado("idle") 

	return



var opciones = \[\]



if Energy < 20:

	opciones.append("recargar")



if distancia\_obgetivo > 300:

	opciones += \["acercarse", "ataque\_distancia"\]



if distancia\_obgetivo < 185:

	if randf() < agresividad:

		opciones += \["combo"\]

	if randf() < defensa:

		opciones.append("bloquear")



if distancia\_obgetivo > 185 and distancia\_obgetivo < 300:

	opciones += \["acercarse", "saltar"\]



if Energy > enegia\_embestida\_coste and randf() < 0.3 and puede\_embestir:

	opciones.append("embestida")



if randf() < locura:

	

	var caos = \["bloquear", "acercarse"\]

	

	if distancia\_obgetivo >= 185:

		caos.append("combo")

	opciones.append(caos.pick\_random())

	

	var decision = opciones.pick\_random()

	cambiar\_estado(decision)

func obtener_enemigo_mas_cercano():

var enemigos = get\_tree().get\_nodes\_in\_group("P\_Jugables")



var mas\_cercano = null

var distancia\_min = INF



for enemigo in enemigos:

	var distancia = global\_position.distance\_to(enemigo.global\_position)

	

	if distancia < distancia\_min:

		distancia\_min = distancia

		mas\_cercano = enemigo

return mas\_cercano

func mover_hacia_obgetivo():

if obgetivo == null:

	return



var dir = sign(obgetivo.global\_position.x - global\_position.x)

var distancia\_minima = 185



if distancia\_obgetivo > distancia\_minima:

	var variacion = randf\_range(0.9, 1.1)

	velocity.x = dir \* speed \* variacion

	$AnimationPlayer.play("caminar")

else:

	velocity.x = 0



if not ocupado and not atacando:

	if randf() < agresividad:

		estado = \["atacar", "combo"\].pick\_random()

	else:

		cambiar\_estado("bloquear")



mirar\_izquierda = dir < 0

func saltar_ia():

if not is\_on\_floor():

	return

ocupado = true



var dir = sign(obgetivo.global\_position.x -global\_position.x)

velocity.x = dir \* speed

velocity.y = - jump\_speed

$AnimationPlayer.play("saltar1")

func embestida_ia():

if embistiendo or ocupado or Energy <= enegia\_embestida\_coste or not puede\_embestir:

	return



embistiendo = true

ocupado = true

atacando = true



embestida\_direccion = -1 if mirar\_izquierda else 1



$AnimationPlayer.play("embestida")

func terminar_embestida():

if not embistiendo:

	return



embistiendo = false

ocupado = false

atacando = false

velocity.x = 0



puede\_embestir = false



$AnimationPlayer.play("por defecto")



await get\_tree().create\_timer(2.0).timeout

puede\_embestir = true

func ataque_cuerpo():

if obgetivo == null or ocupado:

	return



if distancia\_obgetivo < 182:

	ocupado = true

	atacando = true

	velocity.x = 0

	$AnimationPlayer.play("ataque1")

func ataque_combo():

if obgetivo == null or ocupado or not puede\_combo:

	return



puede\_combo = false



if distancia\_obgetivo < 185:

	ocupado = true

	atacando = true

	$AnimationPlayer.play("ataque1")

	await get\_tree().create\_timer(0.2).timeout

	if obgetivo != null and distancia\_obgetivo < 185:

		$AnimationPlayer.play("ataque2")

		await get\_tree().create\_timer(0.2).timeout

		if obgetivo != null and distancia\_obgetivo < 185:

$AnimationPlayer.play("patada_tierra")

func ataque_ki_ia():

pass

func bloquear_ia():

if not puede\_bloquear or ocupado:

	return



ocupado = true

puede\_bloquear = false



velocity.x = 0

$AnimationPlayer.play("bloqueo")

await get\_tree().create\_timer(0.5).timeout



ocupado = false



await get\_tree().create\_timer(1.5).timeout

puede\_bloquear = true

func recargar_ia():

if ocupado:

	return



ocupado = true



$AnimationPlayer.play("recarga1")

await get\_tree().create\_timer(0.1).timeout

$AnimationPlayer.play("recarga2")



await get\_tree().create\_timer(1.5).timeout



if Energy < Max\_energy:

	Energy += 30

	if Energy > Max\_energy:

		Energy = Max\_energy

ocupado = false

func recibir_daño(cantidad, tipo_golpe):

Life -= cantidad

$vida.text = str(Life)



dañado = true

ocupado = true

atacando = false



match tipo\_golpe:

	"ataque\_1":

		$AnimationPlayer.play("daño1")

	"ataque2":

		$AnimationPlayer.play("daño2")

	"patada\_tierra":

		$AnimationPlayer.play("daño1")

	"patada\_aire":

		$AnimationPlayer.play("daño1")

	"uppercut":

		en\_aire\_por\_golpe = true

		ocupado = true

		atacando = false

		

		velocity.y = -fuerza\_uppercut

		$AnimationPlayer.play("daño1")

	"embestida":

		empujado = true

		ocupado = true

		atacando = false

		

		var dir = sign(global\_position.x - get\_tree().get\_first\_node\_in\_group("P\_Jugables").global\_position.x)

		velocity.x = dir \* fuerza\_empuje

		

		$AnimationPlayer.play("daño2")

if Life <= 0:

	queue\_free()

func _on_animation_player_animation_finished(anim_name: StringName) -> void:

match anim\_name:

	"caminar":

		$AnimationPlayer.play("por defecto")

	"embestida":

		terminar\_embestida()

	"ataque1":

		$AnimationPlayer.play("por defecto")

		ocupado = false

		atacando = false

	"ataque2":

		$AnimationPlayer.play("por defecto")

		ocupado = false

		atacando = false

	"patada\_tierra":

		$AnimationPlayer.play("por defecto")

		ocupado = false

		atacando = false

		await get\_tree().create\_timer(cooldown\_combo).timeout

		puede\_combo = true

	"daño1":

		$AnimationPlayer.play("por defecto")

		await get\_tree().create\_timer(0.2).timeout

		dañado = false

		ocupado = false

	"daño2":

		$AnimationPlayer.play("por defecto")

		await get\_tree().create\_timer(0.2).timeout

		dañado = false

		ocupado = false

func _on_hurtboxes_body_entered(body: Node2D) -> void:

if body.has\_method("recibir\_daño"):

	print("enemigo golpe")



	match $AnimationPlayer.current\_animation:

		"embestida":

await get_tree().create_timer(0.1).timeout

terminar_embestida()

reddit.com
u/Aggressive-Site-2184 — 27 days ago