Topic was automatically imported from the old Question2Answer platform.
Asked By
System_Error
Hi all, just had a question for my game. I have a ship-based weapon being used to fend off hordes of enemies, but the standard pulse-laser isn’t enough in some situations, and the starship gets overwhelmed. What I’d like is a charge-up, secondary fire for my gun that generates a laser beam that the player can use to wipe the screen clean, and have a cooldown time for the beam after about five seconds of use. What would be a good way to make this happen?
LazerGun.gd
extends KinematicBody2D
const LAZER = preload("res://player-side/EnergyShot.tscn")
const ROTATION_SPEED = 0.5
signal fire
var playing = false
var rotation_Direction
var gun_temp = 0.0
var max_temp = 10.0
var heat_per_shot = 2.0
var cooling_power = 1.5
var can_fire = true
var can_fire_beam = true
func _process(delta):
gun_temp -= cooling_power * delta
if gun_temp < 0:
gun_temp = 0
can_fire = true
func get_input():
rotation_Direction = 0.0
if playing == true:
if Input.is_action_pressed('test_up'):
rotation_Direction -= 1.25
elif Input.is_action_pressed('test_down'):
rotation_Direction += 1.25
if Input.is_action_just_pressed('test_fire'):
fire()
if Input.is_action_pressed('test_fire'): # Supposed to hold for a couple seconds.
beam_fire()
func fire():
if can_fire and gun_temp < max_temp:
var lazershot = LAZER.instance()
gun_temp += heat_per_shot
if gun_temp > max_temp:
can_fire = false
lazershot.start($LazerSpawn.global_position, rotation)
get_parent().add_child(lazershot)
func beam_fire(): # This is where I want most of the laser beam's code to be.
pass
func _physics_process(delta):
get_input()
rotation += rotation_Direction * ROTATION_SPEED * delta
rotation = clamp(rotation, deg2rad(-60), deg2rad(60))
func _on_game_over():
playing = false
func _on_HUD_play_game():
playing = true
Use a line2D for graphics and RayCast for collision.
Something like this:
func beam_fire(InDelta): # This is where I want most of the laser beam's code to be.
$Line2D.position = $LazerSpawn.global_position
$Line2D.points[0] = Vector2.ZERO
#So it only sets the position once
if ($Line2D.points[1] == Vector2.ZERO):
$Line2D.points[1] = Vector2(self.get_viewport_rect().size.x +16, 0)
$Line2D/RayCast2D.cast_to = $Line2D.points[1]
$Line2D.rotate(1 * InDelta)
func _process(delta):
beam_fire(delta)
This makes a laser that spins around the start point. Use lookAt or the offset to aim the laser
Thanks.
Though, I’m rather new to Godot, so how would I use lookAt in this?
System_Error | 2019-01-11 07:38
I was tired, when I posted that so my mind defaulted to the standard way. There is actually a easier way to aim at the mouse:
func beam_fire(InDelta): # This is where I want most of the laser beam’s code to be.
$Line2D.position = $LazerSpawn.global_position
$Line2D.points[0] = Vector2.ZERO
#Just get the mouse position and subtract our own position from it
$Line2D.points[1] = get_global_mouse_position() - self.global_position
$Line2D/RayCast2D.cast_to = $Line2D.points[1]
The more advanced way uses a distance calculation to impose a limit on the beam:
func beam_fire(): # This is where I want most of the laser beam's code to be.
$Line2D.global_position = $LazerSpawn.global_position
$Line2D.points[0] = Vector2.ZERO
var Offset = get_global_mouse_position() - $Line2D.global_position
var DistanceToMouse = Offset.length()
var Rotation = Offset / DistanceToMouse #Optimal same as Offset.normalized()
var LimitedLazer = 300
if DistanceToMouse > LimitedLazer:
$Line2D.points[1] = Rotation* LimitedLazer
else:
$Line2D.points[1] = Offset
$Line2D/RayCast2D.cast_to = $Line2D.points[1]
I recommend that if you have some time, learn the basis of linear algebra. It is fundamental to game design; or learn it as you go.