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.

    • SeeFerns@programming.devOP
      link
      fedilink
      English
      arrow-up
      8
      ·
      17 天前

      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!

  • Arkouda@lemmy.ca
    link
    fedilink
    arrow-up
    8
    ·
    17 天前

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

      • Arkouda@lemmy.ca
        link
        fedilink
        arrow-up
        5
        ·
        17 天前

        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.

        • SeeFerns@programming.devOP
          link
          fedilink
          English
          arrow-up
          4
          ·
          17 天前

          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

          • Arkouda@lemmy.ca
            link
            fedilink
            arrow-up
            4
            ·
            17 天前

            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.

            • SeeFerns@programming.devOP
              link
              fedilink
              English
              arrow-up
              4
              ·
              17 天前

              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

              • Arkouda@lemmy.ca
                link
                fedilink
                arrow-up
                4
                ·
                17 天前

                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!

  • Gamma@beehaw.org
    link
    fedilink
    English
    arrow-up
    6
    ·
    17 天前

    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

  • erytau@programming.dev
    link
    fedilink
    English
    arrow-up
    4
    ·
    edit-2
    11 天前

    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.

    • SeeFerns@programming.devOP
      link
      fedilink
      English
      arrow-up
      4
      ·
      17 天前

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