Why won't my laser fire to the left of screen? (game design)

  • Thread starter Thread starter Darkmisc
  • Start date Start date
  • Tags Tags
    Laser
Click For Summary
SUMMARY

The issue of the laser not firing correctly in the game design discussion was identified as a problem with the logic controlling the player's facing direction. The player character, implemented using Godot's KinematicBody2D, was only firing the right-facing laser regardless of the direction faced. The solution involved removing unnecessary lines of code that incorrectly set the Global.face_right variable, specifically lines 20-23, which caused the logic to always evaluate to true. After this adjustment, the laser firing functionality worked as intended.

PREREQUISITES
  • Understanding of Godot Engine 3.x scripting
  • Familiarity with KinematicBody2D node functionality
  • Knowledge of signal handling and input actions in Godot
  • Basic debugging techniques in game development
NEXT STEPS
  • Explore Godot's Input Map for handling multiple input actions
  • Learn about Godot's scene instancing for dynamic object creation
  • Investigate debugging techniques specific to Godot scripting
  • Study the use of global variables in Godot for managing game state
USEFUL FOR

Game developers, particularly those using Godot Engine, and anyone interested in troubleshooting character control and shooting mechanics in 2D games.

Darkmisc
Messages
222
Reaction score
31
TL;DR
I'm making a game where the player can face either left or right. I want them to fire a laser in the direction they face. I'm using an if-statement to determine which laser to fire (based on whether the player sprite is flipped). I suspect the if-statement is not working.
Hi everyone

I'm making a shoot 'em up like Fantasy Zone, i.e. the player can face either left or right (as opposed to only facing one direction while moving forwards and backwards).

I've made separate scenes for the laser that fires left and the laser that fires right.

The player should fire the lasers based on which way they are facing.

However, the player only fires the laser that is instanced at line 61. I've tried both LASER and RLASER in that position and they both work.
The problem is that the player will only fire one type of laser. They won't fire the laser instanced after the else-statement.

I made a label to check when Global.face_right==true and Global.face_right==false, and the label always displays the correct value.
It seems the program knows which way the player is facing, but won't fire the appropriate laser.

Does anyone know what I've done wrong? Thanks[CODE title="Player.gd" highlight="18, 22, 24-27, 60"]extends KinematicBody2Dvar speed = 300
var LASER = preload("res://Laser/Laser.tscn")
var RLASER = preload("res://Laser/Rev_Laser.tscn")
export var normalFireDelay: float = 0.12
export var rapidFireDelay: float = 0.08
var fireDelay: float = normalFireDelay
var vel := Vector2(0, 0)
var laser_parent = Node2D.new()
var laser_parent2 = Node2D.new()
func _physics_process(delta):
var dirVec := Vector2(0, 0)
$Label.text=str(Global.face_right)

move_and_slide(Global.move_vector * speed)

$AnimatedSprite.flip_h = Global.move_vector.x < 0

if $AnimatedSprite.flip_h:
Global.face_right=false
else:
Global.face_right=true if Input.is_action_pressed("shoot"):
shoot_laser()

# if Input.is_action_pressed("shoot") and Global.face_right==false:
#
# shoot_R_laser()

if Input.is_action_pressed("move_left"):
dirVec.x = -1
Global.face_right=false
$AnimatedSprite.set_flip_h(true)
elif Input.is_action_pressed("move_right"):
dirVec.x = 1
Global.face_right=true
$AnimatedSprite.set_flip_h(false)
if Input.is_action_pressed("move_up"):
dirVec.y = -1
elif Input.is_action_pressed("move_down"):
dirVec.y = 1

vel = dirVec.normalized() * speed
position += vel * delta

var viewRect := get_viewport_rect()
position.x = clamp(position.x, 0, viewRect.size.x)
position.y = clamp(position.y, 0, viewRect.size.y)
func shoot_laser():
if Global.face_right:
var new_laser = LASER.instance()
get_parent().add_child(laser_parent)
laser_parent.add_child(new_laser)
new_laser.global_position = Vector2(global_position.x+53, global_position.y)
else:
var new_laser2 = RLASER.instance()
get_parent().add_child(laser_parent2)
laser_parent2.add_child(new_laser2)
new_laser2.global_position = Vector2(global_position.x-53, global_position.y)

func shoot_R_laser():
var new_laser = RLASER.instance()
get_parent().add_child(laser_parent)
laser_parent.add_child(new_laser)
new_laser.global_position = Vector2(global_position.x-53, global_position.y)
[/CODE]
 
Technology news on Phys.org
One of my techniques for debugging a block like this is to systematically eliminate variables and functions until I have the mere skeleton of the function that is misbehaving. This is also a really good way to present your code to readers to debug, so we don't have to understand every aspect of your game, such as movement and firing delay. (Although I guarantee it won't come to that. By the time you eliminate well-behaved extraneous code, the error will jump out at you.)

Also, are lines 33-35 supposed to be commented out? That calls shoot_R_laser()
 
Last edited:
I've deleted all the unnecessary stuff.

The parts I commented out could have been omitted. I've tried putting the if-statement in different places. I originally had shoot_R_laser() as a separate function, but ended up copying its contents into the shoot() function.

This code is slightly different. At line 42, I have:
if Global.face_right==false:

Now the code is only executing the line after the else statement.

I'm sure this is significant, I just can't work out how :s

[CODE title="Player.gd" highlight="42-51, 26-27, 20-23, 4-5"]extends KinematicBody2D

var speed = 300
var LASER = preload("res://Laser/Laser.tscn")
var RLASER = preload("res://Laser/Rev_Laser.tscn")
var vel := Vector2(0, 0)
var laser_parent = Node2D.new()
var laser_parent2 = Node2D.new()
func _physics_process(delta):
var dirVec := Vector2(0, 0)
$Label.text=str(Global.face_right)

move_and_slide(Global.move_vector * speed)

$AnimatedSprite.flip_h = Global.move_vector.x < 0

if $AnimatedSprite.flip_h:
Global.face_right=false
else:
Global.face_right=true if Input.is_action_pressed("shoot"):
shoot_laser()

if Input.is_action_pressed("move_left"):
dirVec.x = -1
Global.face_right=false
$AnimatedSprite.set_flip_h(true)
elif Input.is_action_pressed("move_right"):
dirVec.x = 1
Global.face_right=true
$AnimatedSprite.set_flip_h(false)

vel = dirVec.normalized() * speed
position += vel * delta

func shoot_laser():
if Global.face_right==false:
var new_laser = RLASER.instance()
get_parent().add_child(laser_parent)
laser_parent.add_child(new_laser)
new_laser.global_position = Vector2(global_position.x+53, global_position.y)
else:
var new_laser2 = LASER.instance()
get_parent().add_child(laser_parent2)
laser_parent2.add_child(new_laser2)
new_laser2.global_position = Vector2(global_position.x-53, global_position.y)



[/CODE]
 
I think I found the problem. It's lines 20-23.

I changed them to this
[CODE title="problem"] if $AnimatedSprite.flip_h:
Global.face_right=false
$Label2.text="false"
else:
Global.face_right=true
$Label2.text="true"[/CODE]

And Label2 always reads true.
 
I deleted lines 20-23, and it works now.
 
  • Like
Likes   Reactions: DaveC426913

Similar threads

Replies
5
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
Replies
10
Views
2K