for loop running an extra time

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Surtarso

Hi, these are the methods I use to shoot. when I shoot thru a single hole, all calcs are correct, I can shoot 1, 2 or 3 bullets thru the same hole and it will account shots fire correctly. but when I shoot trhu multiple holes, it always add an extra bullet (on the same position as another, since visually it shoots correctly), but it always accounts for an extra shot (ex. shooting 3 bullets trhu 3 holes should account 9 bullets, but it accounts 12)

onready var bullet_holes:Array = [
	$Sprite/Position2DFront,$Sprite/Position2DLeft,$Sprite/Position2DRight,
	$Sprite/Position2DBack,$Sprite/Position2DBackLeft,$Sprite/Position2DBackRight]

func _shoot(): ## LMB
	print("shoot")
	can_shoot = false #disables shooting
	if multi_gun: _add_bullet(3) #add bullets to 3 bullet holes[0,1,2]
	if star_gun: _add_bullet(6) #add bullets to all bullet holes [0...5]
	else: _add_bullet(1) #add bullet to front bullet hole[0]
	$ShootTimer.wait_time = PlayerData.shoot_rate #check/set current shoot_rate
	$ShootTimer.start() #start shoot cooldown
	yield($ShootTimer,"timeout") #wait cooldown to finish
	can_shoot = true #re-enables shooting

func _add_bullet(holes):
	for hole in holes: #add a bullet to each hole
		var bullet = bullets_array[bullet_type].instance() #pick right bullet
		bullet.transform = bullet_holes[hole].global_transform #orient bullet to proper hole
		#account shots fired (for accuracy calcs):
		if bullet_type == 0 or bullet_type == 3: PlayerData.shots_fired += 1 # single bullets
		if bullet_type == 1: PlayerData.shots_fired += 2 #dual bullets
		if bullet_type == 2: PlayerData.shots_fired += 3 #triple bullets
		#add bullet:
		Globals.stage.add_child(bullet)
		print(bullet)

The print results from shooting a single bullet (1 bullet 1 hole) and right after shooting once with 3 bullets in 3 holes (9 total)

shoot #single shot (1 bullet, 1 hole)
[Area2D:1758]

shoot #multi shot (3 bullets in 3 holes)
[Node2D:2080]
[Node2D:2102]
[Node2D:2124]
[Node2D:2146] ← extra bullet is added, not shown on screen (so same position as another) and accounts as “12” shots (3x4)

What is going on? why does my for loop, loops an extra time???

:bust_in_silhouette: Reply From: Surtarso

I don’t know why… but changing

if star_gun: _add_bullet(6) #add bullets to all bullet holes [0...5]

to:

elif star_gun: _add_bullet(6) #add bullets to all bullet holes [0...5]

Fixed it… Still would love if someone could explain to me why it happened and why this fix worked… or I wont learn a thing… lol thx :slight_smile:

:bust_in_silhouette: Reply From: Inces

It is because the line :

else: _add_bullet(1) #add bullet to front bullet hole[0]

was resolved every time star gun was false. ELSE statement was connected to only this one IF statement above it. Now when You changed stargun check into ELIF, ELSE statement is connected to both IF and ELIF statements. This is what ELIF is used for : it works as continuation of one big IF check, finishing ELSE is resolved when none of those IF checks are true.

ahhhh ok, so:

if a
if b
if c
if d
elif e
else f

the ELSE would be connected to only IF D, ELIF E and not the other top IFs?
and IF A happened it would also execute the ELSE?

Surtarso | 2021-03-27 16:56

Exactly : a, b and c are checked independently from each other and indepenedently from cluster check d,e,f :slight_smile:

Generally ELIF comes from ELSE+IF = ELIF

Inces | 2021-03-27 17:34

very clarifying, thank you!

Surtarso | 2021-03-27 17:49