Hi everyone.
I have just started learning Godot, and I'm trying to implement a "zip to point" ability in my 2D platformer, that when the mouse is clicked, the player shoots a grappling hook towards the direction of the mouse, pulls themselves towards it, and once the player reaches the hook, you regain control. (Like something from Spider-Man games but in 2D?)
Currently, I have it so a Raycast2D is cast from the player, and if it collides with something, the player is teleported to the collision point. However, with this, the player teleports into the floor and through walls (I'm not sure why) and can teleport through small gaps.
How would I better implement this mechanic?
Here is my code:
extends KinematicBody2D
# physics
const speed = 150
const acc = 13
var jumpForce : int = 300
var gravity : int = 800
onready var sprite = $Sprite
onready var animation_tree = $AnimationTree
onready var state_machine = animation_tree.get("parameters/playback")
#zip to point
onready var raycast2d = $RayCast2D
const MAX_LENGTH = 200
onready var end = $Position2D
onready var player = $Player
var vel = Vector2()
const UP = Vector2(0, -1)
func _physics_process(delta):
# movement inputs
if Input.is_action_pressed("move_left"):
state_machine.travel("run")
vel.x = max(vel.x - acc, -speed)
print(vel.x)
elif Input.is_action_pressed("move_right"):
state_machine.travel("run")
vel.x = min(vel.x + acc, speed)
print(vel.x)
else:
vel.x = lerp(vel.x, 0, 0.2)
state_machine.travel("idle")
#zip to point
if Input.is_action_pressed("right_click"):
var mouse_position = get_local_mouse_position()
var max_cast_to = mouse_position.normalized() * MAX_LENGTH
raycast2d.cast_to = max_cast_to
if raycast2d.is_colliding():
end.global_position = raycast2d.get_collision_point()
print(end.global_position - position)
var direction = mouse_position.normalized()
self.position = end.global_position
else:
end.global_position = raycast2d.cast_to
# applying the velocity
vel = move_and_slide(vel, UP)
#terminal velocity
if vel.y > 300:
vel.y =300
# gravity
vel.y += gravity * delta
# jump input
if Input.is_action_pressed("jump") and is_on_floor():
vel.y -= jumpForce
if !is_on_floor():
if vel.y < 0:
state_machine.travel("jump")
elif vel.y > 0:
state_machine.travel("fall")
# sprite direction
if vel.x < 0:
sprite.flip_h = false
elif vel.x > 0:
sprite.flip_h = true
I am still very new to Godot, so detailed explanations would be super helpful.
Thanks