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.
Totally fair point. Idk I’m conflicted because I worry that Godot 4 doesn’t have amazing performance for lower end hardware.
I mess with portmaster on some anbernic devices that I’d love to play my game on. However, using v4 to make games for them doesn’t seem feasible.
I’m sure some people could get it running well some how, maybe using some unique export templates to really strip things down too, but I don’t know if I’m savvy enough to figure it out lol
I have a low end ASUS laptop ($450 range) that I bought about 5ish years ago and it runs Godot 4 perfectly for me. My partner has an older Lenovo Ideapad and she cannot run the game I made. Your worry is justified. lol But I don't think it would hurt to test it out. Worst case, you delete and go back to 3, best case is 4 is pretty awesome and has a lot more functionality than 3.
I am not the one to speak to about export templates unfortunately, as I have only ever exported once to be compatible with my system. It was incredibly easy to choose which template I wanted though, so you shouldn't need to be to savvy to figure it out! :)
Also, if you haven't found it yet, I would recommend Pixelorama if you are into making pixel art games. It was made with Godot, and it is awesome. I animated my entire game with it, and it is super user friendly.
Good idea, I can probably finish this prototype and spend like a few hours just porting it over to v4.4 for a quick test. I haven''t noticed a ton of differences so far for something so simple, and this prototype is going to be very very small and simple.
Oh that is good to hear! I haven't messed with the exporting process yet but I've heard its pretty darn simple. Love2D's process was pretty straightforward for most platforms but had a few quirks for sure.
Pixelorama is my jam! Lol I didn't love the UI of libresprite so I poked around a few months ago and found it and immediately fell in love haha. Unforunately, this will be the first project where I want to try and dip my toe into vector art so I'm going to test out gimp soon once I feel like I have a game idea worth pursuing. Hopefully this prototype is the one
Just be sure to keep a back up copy of the original v3 version. There is no going back once you switch it over!
It is such a great program! I even got my partner working with it and she loves it. haha
Good luck with vector art! And with your project!
Thanks friend :D