0 votes

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
in Engine by (197 points)

1 Answer

+1 vote
Best answer

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

by (1,440 points)
selected by

Thanks.

Though, I'm rather new to Godot, so how would I use lookAt in this?

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.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.