Tema 23. Godot Engine. Dirección del disparo
Hasta el momento, los disparos solo funcionan en una dirección, pero ¿qué ocurre si el personaje cambia de dirección? El disparo sigue saliendo en dirección derecha.
Por lo tanto, tendremos que tener en cuenta si el personaje se encuentra en dirección izquierda o derecha, y en función de ello, posicionar el disparo a la derecha o izquierda del personaje y además, cambiar la orientación del proyectil según el sentido hacia donde se dirija.
Dependiendo si el personaje se mueva a la izquierda o derecha: Al pulsar la tecla derecha o izquierda comprobamos si $Position2D.position.x es o no negativo. En cada cambio de izquierda a derecha le cambiamos el signo.
func _process(delta): velo1.y += Velocidad1 * delta if Input.is_action_pressed(«Player_Left»): $AnimatedSprite.flip_h = true; $AnimatedSprite.play(«left») if sign($Position2D.position.x) == 1: $Position2D.position.x *= -1 velo1.x = -Velocidad1 if Input.is_action_pressed(«Player_Right»): $AnimatedSprite.play(«right») $AnimatedSprite.flip_h = false; if sign($Position2D.position.x) == -1: $Position2D.position.x *= -1 velo1.x = Velocidad1 if !Input.is_action_pressed(«Player_Left») and !Input.is_action_pressed(«Player_Right»): $AnimatedSprite.play(«idle») velo1.x = 0 if Input.is_action_just_pressed(«Shoot»): print(«disparo») var midisparo = PROYECTIL.instance() get_parent().add_child(midisparo) midisparo.position = $Position2D.global_position move_and_slide(velo1,Vector2(0,-1)) |
Ahora tenemos que saber en cada momento la dirección para establecer la orientación del proyectil.
Accedemos al Nodo Proyectil y modificamos el Script:
var dir_proy = 1 func set_direccion_proyectil(dir): dir_proy = dir if dir == -1: $AnimatedSprite.flip_h = true # Called when the node enters the scene tree for the first time. func _ready(): pass # Replace with function body. # Called every frame. ‘delta’ is the elapsed time since the previous frame. func _process(delta): velocity.x = Speed * delta * dir_proy translate(velocity) $AnimatedSprite.play(«disparo») |
Creamos la variable dir_proy que me dirá en cada momento la dirección del Proyectil
Creamos una función que establezca la dirección del proyectil y me cambia su orientación si el personaje está mirando a la izquierda.
Ahora tendremos que indicarle a la función que haga el cambio de variable según la dirección del personaje. Esto lo haremos cuando pulsemos el botón disparar. Así que debemos ir al Script del Nodo Jugador y añadir el cambio en la condición donde se pulsa el botón Disparo:
Ojo: Recordamos que el if termina con dos puntos y el else también. Además tiene que estar todo bien indentado o dará error.
if Input.is_action_just_pressed(«Shoot»): print(«disparo») var midisparo = PROYECTIL.instance() get_parent().add_child(midisparo) midisparo.position = $Position2D.global_position if sign($Position2D.position.x) == 1: midisparo.set_direccion_proyectil(1) else: midisparo.set_direccion_proyectil(-1) |
Debemos tener cuidado y llamar a la función desde la variable instancia midisparo que hemos creado llamando con el preload desde PROYECTIL.
Si leemos el código al pulsar la tecla disparo, se comprueba el signo $Position2D.position.x (que se cambia en cada pulsación izquierda o derecha)
Si está mirando a la derecha (es positivo) llamamos a la función:
midisparo.set_direccion_proyectil(1) le pasamos un valor positivo y no se hace el flipH
si está mirando a la izquierda llamamos a la función:midisparo.set_direccion_proyectil(-1) le pasamos un valor negativo y se pone flip_H a true
Código del Player2
extends KinematicBody2D export var Velocidad1 = 200 var velo1 = Vector2() var PROYECTIL = preload(«res://Proyectil.tscn») # Declare member variables here. Examples: # var a = 2 # var b = «text» # Called when the node enters the scene tree for the first time. func _ready(): pass # Called every frame. ‘delta’ is the elapsed time since the previous frame. func _process(delta): velo1.y += Velocidad1 * delta if Input.is_action_pressed(«Player_Left»): $AnimatedSprite.flip_h = true; $AnimatedSprite.play(«left») if sign($Position2D.position.x) == 1: $Position2D.position.x *= -1 velo1.x = -Velocidad1 if Input.is_action_pressed(«Player_Right»): $AnimatedSprite.play(«right») $AnimatedSprite.flip_h = false; if sign($Position2D.position.x) == -1: $Position2D.position.x *= -1 velo1.x = Velocidad1 if !Input.is_action_pressed(«Player_Left») and !Input.is_action_pressed(«Player_Right»): $AnimatedSprite.play(«idle») velo1.x = 0 if Input.is_action_just_pressed(«Shoot»): print(«disparo») var midisparo = PROYECTIL.instance() get_parent().add_child(midisparo) midisparo.position = $Position2D.global_position if sign($Position2D.position.x) == 1: midisparo.set_direccion_proyectil(1) else: midisparo.set_direccion_proyectil(-1) move_and_slide(velo1,Vector2(0,-1)) |
Código del Proyectil
extends Area2D export var Speed = 100 var velocity = Vector2() var dir_proy = 1 func set_direccion_proyectil(dir): dir_proy = dir if dir == -1: $AnimatedSprite.flip_h = true # Called when the node enters the scene tree for the first time. func _ready(): pass # Replace with function body. # Called every frame. ‘delta’ is the elapsed time since the previous frame. func _process(delta): velocity.x = Speed * delta * dir_proy translate(velocity) $AnimatedSprite.play(«disparo») func _on_VisibilityNotifier2D_screen_exited(): queue_free() |
Ahora lo único que nos falta por arreglar es eliminar cada disparo que toque cualquier pared que esté situada dentro de la escena.
Para hacer esto iremos al Nodo Proyectil y añadiremos una conexión: body_entered.
Cuando un Cuerpo entre en el Proyectil:
func _on_Proyectil_body_entered(body): pass # Replace with function body. |
Y añadimos el queue_free() ,
Para cualquier cuerpo que entre en el proyectil, se borrar el proyectil. Es decir, si le toca una pared, entonces se borrará.
func _on_Proyectil_body_entered(body): queue_free() |