Siendo uno de los aspectos más importantes del juego, fue también uno de los más sencillos de desarrolla, al menos a en su nivel más básico.
Esta es la organización de la escena de la nave, llamada dentro del motor “Player”:
voy a ir explicando nodo por nodo y su funcionalidad:
Asi es como se ve la escena general de la nave, en la imagen se indica que hace cada cosa, pero igual explicare un poco como funciona.
Lo primero, notaras que estoy colocando todo lo que es el HUD en la propia nave, eso es porque mientras uno esta jugando, siempre vas a tener la vista puesta en la nave, por lo que colocar información tan critica como cuanto combustible queda o si se puede realizar la habilidad en un HUD aparte en otra punta de la pantalla puede distraer al jugador y hacerle caer en un obstáculo. El HUD consta, de arriba a abajo, de 3 barras: dos semi circulares para el combustible y los puntos, y una recta para la resistencia (con un máximo de 5). Por el momento el juego asume que el jugador es diestro, eso lo cambiaré más adelante, pero por el momento a la izquierda están los indicadores del nivel de la nave y cuando la habilidad está disponible. La Hurtbox es la figura poligonal que se ve dentro del sprite de la nave y la MainArea es la capsula azul que envuelve casi todo.
El script de la nave consta de 14 funciones: las dos primeras siendo funciones por defecto de Godot, las siguientes 8 son funciones creadas por mi para el funcionamiento de la nave y las últimas 4 son funciones asociadas a señales.
Empezando con las creadas por mí:
func motion(d):
# Para el movimiento de la Nave
if Input.is_action_pressed("Touch") and CanMove:
global_position = lerp(global_position, get_global_mouse_position(), 30 * d)
if Input.is_action_just_released("Touch"):
CanMove = false
func margin():
# Para que la nave no salga de la pantalla y se pierda de vista
global_position.x = clamp(global_position.x, MinSide.x + Margin.x, MaxSide.x - Margin.x)
global_position.y = clamp(global_position.y, MinSide.y + Margin.y, MaxSide.y - Margin.y)
func fuel_bar():
# Controla la barra de combustible, indica cuanto se pierde por segundo,
# que colores tomar según la cantidad restante y que hacer cuando se acaba.
FuelBar.value -= ShipStats.FuelCombustion
if FuelBar.value > 50:
FuelBar.tint_progress = Color.GREEN
elif FuelBar.value < 50 and FuelBar.value > 20:
FuelBar.tint_progress = Color.ORANGE
elif FuelBar.value < 20:
FuelBar.tint_progress = Color.RED
elif FuelBar.value == 0:
get_parent().game_over()
func points_bar():
# controla qué ocurre si la barra de puntos llega a 100
if PointsBar.value == 100:
PointsBar.value = 0
Master.velocity += 50
Master.speed_up()
Master.ShipLevel += 1
func kinetic_ability():
# Aqui se evalua si se puede realizar la habilidad de la nave
if round(Difference.y) >= AbilityThreshold and CanMove and CanAbility:
intangibility(true)
CanAbility = false
func intangibility(CanDo):
# Aqui se controla todo con respecto a la habilidad de la nave
if CanDo:
Overlay.visible = true
Hurtbox.monitoring = false
AbilityTimer.start()
else:
Overlay.visible = false
Hurtbox.monitoring = true
func sides():
# Este es para uso estetico. Según la dirección de la nave, el fondo parallax
# cambia su dirección horizontal
if PastPos.x > CurrentPos.x and CanMove:
movin_left.emit()
elif PastPos.x < CurrentPos.x and CanMove:
movin_right.emit()
func get_hurt():
# Aqui se controla qué ocurre al recibir daño
Flash.flash()
Shake.tween_shake()
ShipStats.Resistance-= 1
Las señales, por su parte, son estas:
func _on_main_area_mouse_entered():
# Esta Señal evalua si el mouse ha entrado al MainArea. De ser así,
# vuelve la variable "CanMove" en verdadera y permite a la nave moverse
CanMove = true
func _on_main_area_area_entered(area):
# Aqui se controla la segunda función de la MainArea, que es recolectar los
# coleccionables.
# En este caso los coleccionables no tienen ningun valor por si mismo, solo un tipo.
# Segun el tipo, se adquiere un valor al azar entre 1 y el rango de recolección de ese
# coleccionble segun las estadisticas de la nave.
if area.is_in_group("collectables"):
if area.CollType == 0:
var sum = randi_range(1,ShipStats.FuelRange) * 10
FuelBar.value += sum
elif area.CollType == 1:
var sum = randi_range(1,ShipStats.PointsRange)
PointsBar.value += sum
area.queue_free()
func _on_ability_timer_timeout():
# Cuando la habilidad de la nave es usada, el Ability Timer se activa.
# Cuando se acaba el tiempo, la habilidad se cancela.
intangibility(false)
CanAbility = false
# Esta parte es muy interesante: para evitar que el jugador abuse de la habilidad,
# se hace un pequeño "Cool down" de un segundo utlizando un Timer "desechable" que
# se invoca por medio de codigo. Se le dice al programa que espere a que este Timer
# desechable termine para volver a utilizar la habilidad. Es muy genial y fácil de hacer.
var waitTime = get_tree().create_timer(1)
await waitTime.timeout
CanAbility = true
func _on_hurtbox_area_entered(area):
# Por último, aquí se controla lo que sucede cuando la Hurtbox entra en contacto con un area de tipo "Obstacle" (Obstaculo)
if area.is_in_group("obstacle"):
get_hurt()
Las ultimas dos funciones son la “_ready()” y la “_process(delta)” vienen por defecto en Godot:
func _ready():
# Por el momento uso el _ready solo para hacer que el tiempo del AbilityTimer sea igual
# Al de las estadisticas de la nave.
AbilityTimer.wait_time = ShipStats.AblityTime
func _process(delta):
# En la funcion _process es donde ocurre todo lo que debe ocurrir durante el juego
# Aqui se cambia el texto del Label que indica el nivel de la nave
LevelLabel.text = str(Master.ShipLevel)
# Aqui se reproduce la animación de la nave
SkinShip.play()
# La variable "Difference" se usa para poder activar la habilidad de la nave
Difference = PastPos - CurrentPos
# Esta condicion es para desactivar la función del combustible de la nave cuando se entra
# a una boss fight
if not Master.IsInBoss:
fuel_bar()
# Aqui se controla el color del icono que indica cuando se puede realizar la Habilidad.
if CanAbility:
abilityIcon.color = Color.BLUE
else:
abilityIcon.color = Color.RED
# El valor de la barra de resistencia segun la resistencia que queda
LivesBar.value = ShipStats.Resistance
# Si la resistencia se va a cero, game over
if ShipStats.Resistance == 0:
get_parent().game_over()
# Aqui se llama a todas las funciones anteriormente mencionadas
kinetic_ability()
motion(delta)
sides()
points_bar()
margin()
# De estas variables se saca el valor de la variable "Diferrence".
PastPos = lerp(CurrentPos,global_position, 30 * delta)
CurrentPos = global_position
Me gustaría mostrar las variables, pero esta entrada ya se está haciendo muy larga. La próxima hablaré de los módulos.
Did you like this post? Tell us
Leave a comment
Log in with your itch.io account to leave a comment.