I'm mostly concerned about if I'm understanding how Godot does things. I'm coming from Love2D and so messing a lot with the GUI has been a new workflow for me completely. Please disregard the absolute mess that my code is, I'm trying to get through things quickly and not necessarily cleanly. Also, I know I don't need to add 'pass' all the time, I just like the pink visual cue that my function is over, sorta like Lua lol.
extends Node2D
var rng:= RandomNumberGenerator.new()
onready var arrow_left: Node2D = $ArrowLeft
onready var arrow_up: Node2D = $ArrowUp
onready var arrow_right: Node2D = $ArrowRight
onready var score_label: Label = $Control/ScoreLabel
onready var health_label: Label = $Control/HealthLabel
var arrow:PackedScene = preload("res://Arrow.tscn")
var arrows: Array = []
var score: int = 0
var health: float = 100.0
var in_left: bool = false
var in_up: bool = false
var in_right: bool = false
var left_pos: float = 0.0
var up_pos: float = 0.0
var right_pos: float = 0.0
var current_left_arrow: Node2D = null
var current_up_arrow: Node2D = null
var current_right_arrow: Node2D = null
func _ready() -> void:
rng.randomize()
var window_width: float = get_viewport().size.x
var window_height: float = get_viewport().size.y
var left_arrow_pos: float = window_width * 0.3
var up_arrow_pos: float = window_width * 0.5
var right_arrow_pos: float = window_width * 0.7
var arrows_height: float = window_height * 0.9
left_pos = left_arrow_pos
up_pos = up_arrow_pos
right_pos = right_arrow_pos
arrow_left.position.x = left_arrow_pos
arrow_left.position.y = arrows_height
arrow_up.position.x = up_arrow_pos
arrow_up.position.y = arrows_height
arrow_right.position.x = right_arrow_pos
arrow_right.position.y = arrows_height
pass
func _process(delta) -> void:
score_label.text = "Score: " + str(score)
health_label.text = "Health: " + str(health)
if Input.is_action_just_pressed("left") and in_left and current_left_arrow:
increase_score()
arrows.erase(current_left_arrow)
current_left_arrow.queue_free()
current_left_arrow = null
in_left = false
if Input.is_action_just_pressed("up") and in_up and current_up_arrow:
increase_score()
arrows.erase(current_up_arrow)
current_up_arrow.queue_free()
current_up_arrow = null
in_up = false
if Input.is_action_just_pressed("right") and in_right and current_right_arrow:
increase_score()
arrows.erase(current_right_arrow)
current_right_arrow.queue_free()
current_right_arrow = null
in_right = false
for i in arrows.duplicate(): #supposedly safe iteration?
i.position.y += 3
if i.position.y > 540:
health -= 10
arrows.erase(i)
i.queue_free()
if health <= 0:
get_tree().change_scene("res://GameOver.tscn")
if score >= 5:
get_tree().change_scene("res://ChoosePath.tscn")
pass
func _on_CreateArrowTimer_timeout() -> void:
var arrow_instance = arrow.instance()
var arrow_pos = get_rand_arrow_pos()
if arrow_pos == 1:
arrow_instance.position.x = left_pos
elif arrow_pos == 2:
arrow_instance.position.x = up_pos
elif arrow_pos == 3:
arrow_instance.position.x = right_pos
arrows.append(arrow_instance)
arrow_instance.position = Vector2(arrow_instance.position.x, 0)
add_child(arrow_instance)
pass
func increase_score() -> void:
score += 1
pass
func _on_LeftArea2D_area_entered(area: Area2D) -> void:
if area.is_in_group("arrow"):
in_left = true
current_left_arrow = area.get_parent() #get the full arrow Node2D to use for deletion
pass
func _on_LeftArea2D_area_exited(area: Area2D) -> void:
if area.is_in_group("arrow"):
in_left = false
current_left_arrow = null
pass
func _on_UpArea2D_area_entered(area: Area2D) -> void:
if area.is_in_group("arrow"):
in_up = true
current_up_arrow = area.get_parent()
pass
func _on_UpArea2D_area_exited(area: Area2D) -> void:
if area.is_in_group("arrow"):
in_up = false
current_up_arrow = null
pass
func _on_RightArea2D_area_entered(area: Area2D) -> void:
if area.is_in_group("arrow"):
in_right = true
current_right_arrow = area.get_parent()
pass
func _on_RightArea2D_area_exited(area: Area2D) -> void:
if area.is_in_group("arrow"):
in_right = false
current_right_arrow = null
pass
func get_rand_arrow_pos() -> int:
return rng.randi_range(1,3)
pass
I'm not sure if the way I'm doing number randomization is correct and if using duplicate() truly is the right way to remove things from the array. Is it truly deleting the node in the array? Lastly, why can't I seem to get the window size as a script-wide variable? It seems like I can only do so inside the ready function. Thanks!
edit: Code has been properly formatted, sorry!
edit2: From what I can tell this is the right way to remove objects by iterating over the array in reverse
for a in arrows:
a.position.y += 300 * delta
for i in range(arrows.size() - 1, -1, -1): #iterate safely by going backwards
var a = arrows[i]
if a.position.y > 540:
health -= 10
arrows.remove(i)
a.queue_free()
I split up the movement code into its own for loop and then moved the deletion code into the reverse loop.