Godot 4.3
Hey there, this is my first time posting in the forums so please forgive me if there’s any structural errors in how I’ve presented my question or if there’s mistakes in my grammar or terminology, and please let me know if there is. I’m fairly new to game programming, having made a couple of very simple games in unity and I’m brand new to godot.
Basically I’m creating a top down 2d game, where the player slides along some ice. The game uses grid based movement. At the moment I have constructed a small arena where there are 2 areas of land or “snow” on which the player can move around freely, 1 tile at a time and collides with any walls or obstacles.
What I’m struggling with is having the player slide along the ice. For that I need some conditions:
- The player travels continuously in the direction that they have entered the ice from until they either hit an wall/obstacle.
- Movement inputs are disabled while the player is sliding.
- Movement inputs are enabled if the player has stopped or is now off the ice.
I’m using custom data in the tile map named on_ice, which I’ve painted onto the ice tiles. This is called in a script that I’ve attached to my “world” and the player script calls it from there. So I have gone as far as the player being able to understand that it is on an ice tile. I’ve been trying different things for about 3 days, but I’m at a loss.
Here is my player script as it stands at the moment(I’ve deleted anything from the slide() function that hasn’t helped):
extends CharacterBody2D
#variables
@onready var ray = $RayCast2D
@onready var collider = $CollisionShape2D
const tile_size = 32
var moving = false
var sliding = false
var speed = 0.1
var input_dir
var speed_modifier := 1.0
#movement
func _physics_process(delta: float) -> void:
var on_ice = false
on_ice = World.get_custom_data_at(position, "is_ice")
if on_ice == true:
slide()
if on_ice == false: # snow movement
input_dir = Vector2.ZERO
if Input.is_action_pressed("ui_down"):
input_dir = Vector2(0,1)
move()
elif Input.is_action_pressed("ui_up"):
input_dir = Vector2(0,-1)
move()
elif Input.is_action_pressed("ui_right"):
input_dir = Vector2(1,0)
move()
elif Input.is_action_pressed("ui_left"):
input_dir = Vector2(-1,0)
move()
move_and_slide()
func move():
speed_modifier = World.get_custom_data_at(position, "speed_modifier")
var move_speed = speed*speed_modifier
var angle_dir = input_dir.angle() #raycast direction
ray.rotation = angle_dir + PI/2
ray.force_raycast_update()
if !ray.is_colliding():
if input_dir:
if moving == false:
moving = true
var tween = create_tween()
tween.tween_property(self, "position", position + input_dir*tile_size, move_speed)
tween.tween_callback(move_false)
func slide():
sliding = true
func move_false():
moving = false