28
submitted 4 days ago* (last edited 4 days ago) by [email protected] to c/[email protected]

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.

top 15 comments
sorted by: hot top new old
[-] [email protected] 17 points 4 days ago

Im curious why did you pick 3.6 over 4.4 or 4.x?

[-] [email protected] 8 points 4 days ago

Hey there, I wanted open gl 2 support.

I have and like to use some pretty old and low powered stuff so its nice to have that. Also, its a smaller export which I also like. Idk, I might be being stupid here but whatever its just a quick prototype!

[-] [email protected] 8 points 4 days ago

Can you fix the formatting of your OP? Some parts didn't get properly formatted.

[-] [email protected] 6 points 4 days ago

Done, thanks for letting me know about that.

[-] [email protected] 5 points 4 days ago

No problem! It seems others have already answered your questions better than I could, so good luck using Godot!

The only recommendation I would make is to update to a newer version if you are able to. 3 is fine, I started on it myself, but a lot of what you will find online for help is being more and more tailored to 4 and higher so it may be harder over time to get help with issues in the future.

[-] [email protected] 4 points 4 days ago

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

[-] [email protected] 4 points 4 days ago

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.

[-] [email protected] 4 points 4 days ago

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

[-] [email protected] 4 points 4 days ago

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!

[-] [email protected] 3 points 4 days ago

Thanks friend :D

[-] [email protected] 6 points 4 days ago

You can only get the window size after the window is ready, if you were on godot 4 that’d be with an @onready var but I don’t remember how to do that in 3

[-] [email protected] 6 points 4 days ago

Oh hey, this works lol in godot 3, its just 'onready' instead of '@onready' thanks!

[-] [email protected] 4 points 4 days ago

Nice, glad it was easy!

[-] [email protected] 4 points 4 days ago

You can simplify your rng by using global randomize(). Then you won't have to remember to create a new random generator, and you can generate random stuff with randi_range() instead of rng.randi_range(). That is, if you don't need several differently-seeded random generators.

Couldn't read through the whole code because of messed up formatting.

[-] [email protected] 4 points 4 days ago

Oh, good idea. I probably won't need several differently-seeded rngs. I can't imagine in this project when I'd need that.

this post was submitted on 19 Jul 2025
28 points (100.0% liked)

Godot

6894 readers
38 users here now

Welcome to the programming.dev Godot community!

This is a place where you can discuss about anything relating to the Godot game engine. Feel free to ask questions, post tutorials, show off your godot game, etc.

Make sure to follow the Godot CoC while chatting

We have a matrix room that can be used for chatting with other members of the community here

Links

Other Communities

Rules

We have a four strike system in this community where you get warned the first time you break a rule, then given a week ban, then given a year ban, then a permanent ban. Certain actions may bypass this and go straight to permanent ban if severe enough and done with malicious intent

Wormhole

[email protected]

Credits

founded 2 years ago
MODERATORS