0 votes

Hi all.

I'm trying to get a game I've been working on ready for mobile, and needed to replace the movement system. What I decided on was a simple, on-screen joystick, that the player would use to make the ship move forward/back, and turn left/right.

I've had the ship done for a while, but now that I'm refactoring the movement system to use the joystick instead of WASD, I'm a little bit lost. The ship is instanced, capable of being destroyed, and, if it has been destroyed, will be re-spawned when the player starts the level again. (I'll get that last little bit done when I get to it, as right now I just want to get the movement system working again.)

Player.gd

extends RigidBody2D 

const MAX_DURABILITY = 70
const MIN = -0.1
const MAX = 0.1

var thrust = Vector2(200,0)
var torque = 11250
var tele_ready = false
var damage_taken = 0
var explosion_scene = preload("res://resources/resource_scenes/Explosion.tscn")
var control_active = true
var can_teleport = true

func _ready():
    self.set_contact_monitor(true)


func _integrate_forces(state):
    if Input.is_action_pressed("forwards") and control_active == true:
        $Thruster.set_emitting(true)
        set_applied_force(thrust.rotated(rotation))
    elif Input.is_action_pressed("backwards") and control_active == true:
        set_applied_force(thrust.rotated(rotation)*-0.25)
    else:
        set_applied_force(Vector2())
        $Thruster.set_emitting(false)
    var rotation_dir = 0
    if Input.is_action_pressed("turn_left") and control_active == true:
        rotation_dir -= 1
    if Input.is_action_pressed("turn_right") and control_active == true:
        rotation_dir += 1
    set_applied_torque(rotation_dir * torque)


func _input(event):
    var destination = $TeleporterObjects/TeleportDestination.global_position


    if Input.is_action_just_pressed("warp") == true:
        if self.linear_velocity > Vector2(MAX,MAX) or self.linear_velocity < Vector2(MIN,MIN):
            can_teleport = false
            self.set_angular_damp(2)
            self.set_linear_damp(3)
        elif self.linear_velocity <= Vector2(MAX,MAX) or self.linear_velocity >= Vector2(MIN,MIN):
            can_teleport = true
            self.set_angular_damp(-1)
            self.set_linear_damp(-1)

    if Input.is_action_just_pressed("warp") and control_active == true and can_teleport == true:
        mode = RigidBody2D.MODE_STATIC
        $TeleporterObjects/TeleportTimer.start()
        $TeleporterObjects/TeleChargeEffect.emitting = true
        $TeleporterObjects/TeleportDestination/TeleportEffect.emitting = true

    if tele_ready == false and Input.is_action_just_released("warp") and control_active == true and can_teleport == true:
        $TeleporterObjects/TeleportTimer.stop()
        mode = RigidBody2D.MODE_RIGID
        sleeping = false
        $TeleporterObjects/TeleChargeEffect.emitting = false
        $TeleporterObjects/TeleportDestination/TeleportEffect.emitting = false

    if tele_ready == true and Input.is_action_just_released("warp") and control_active == true and can_teleport == true:
        self.global_position = destination
        mode = RigidBody2D.MODE_RIGID
        sleeping = false
        $TeleporterObjects/TeleChargeEffect.emitting = false
        $TeleporterObjects/TeleportDestination/TeleportEffect.emitting = false
        $TeleporterObjects/TeleFullCharge.emitting = false
        $TeleporterObjects/TeleportComplete.emitting = true
        tele_ready = false

...

(There might also be a better way of doing the teleport/warp thing, but this is what I've got.)

joystick.gd

extends TouchScreenButton

var radius = Vector2(16,16)
var limit = 32

var ongoing_drag = -1
var return_accel = 15
var threshold = 10

func _process(delta):
    if ongoing_drag == -1:
        var pos_diff = (Vector2(0,0) - radius) - position
        position += pos_diff * return_accel * delta

func get_button_pos():
    return position + radius

func _input(event):
    if event is InputEventScreenDrag or (event is InputEventScreenTouch and event.is_pressed()):
        var event_dist_from_mid = (event.position - get_parent().global_position).length()

        if event_dist_from_mid <= limit * global_scale.x or event.get_index() == ongoing_drag:
            set_global_position(event.position - radius)

            if get_button_pos().length() > limit:
                set_position(get_button_pos().normalized() * limit - radius)

            ongoing_drag = event.get_index()

    if event is InputEventScreenTouch and !event.is_pressed() and event.get_index() == ongoing_drag:
        ongoing_drag = -1

func get_value():
    if get_button_pos().length() > threshold:
        return get_button_pos().normalized()/16
    return Vector2(0,0)

(I followed Gonkee's joystick tutorial for this one.)

Again, I'm trying to re-do the movement section of my player-ship, replacing the keyboard-reliant WASD with an on-screen, in-game joystick. W and S will be replaced with the joystick's Y input. A and D will, likewise, be replaced with the joystick's X inputs. Or something like that.

Scene structure would have Joystick as a child node of HUD. HUD would be a sibling node to Player.

in Engine by (197 points)

1 Answer

–1 vote

System Problem

by (12 points)

Eh? What's that supposed to mean?

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.