Hi, I'm currently having trouble implementing a mechanic into my first game, which is a Sokoban clone. I want it so that the player can pull boxes when they hold down the z key in addition to pushing boxes naturally.
I've implemented a basic version of the mechanic, however its very buggy, like you are unable to pull boxes if they are in contact with a wall, and the player can also get themselves stuck inside walls when trying to pull.
What I basically want to happen is for the player to pull the box when they press any key that isn't in the box's direction. However, if they do press it in the box's direction, they'll just push it like if they weren't holding down the z key to pull. How can I go about implementing this mechanic?
Here's my player code:
extends KinematicBody2D
onready var ray = $RayCast2D
onready var runTimer = $RunTimer
var grid_size = 8
var runDelay: float = 0.5
var inputs = {
'ui_up' : Vector2(0,-1),
'ui_down' : Vector2(0,1),
'ui_left' : Vector2(-1,0),
'ui_right' : Vector2(1,0)
}
func _unhandled_input(event):
for dir in inputs.keys():
if event.is_action(dir) and runTimer.is_stopped():
runTimer.stop()
if $Tween.is_active() == false:
move(dir)
if event.is_action_pressed(dir):
runTimer.start(runDelay)
if $Tween.is_active() == false:
move(dir)
if event.is_action_pressed("reset"):
get_tree().reload_current_scene()
func move(dir):
var game = get_parent()
var vector_pos = inputs[dir] * grid_size
ray.cast_to = vector_pos
if Input.is_key_pressed(KEY_Z):
ray.cast_to = -vector_pos
ray.force_raycast_update()
$Tween.interpolate_property(self, "position", position, position + vector_pos, 0.1, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
if !ray.is_colliding():
$Tween.start()
game.moves += 1
else:
var collider = ray.get_collider()
if collider.is_in_group('box'):
if collider.move(dir):
$Tween.start()
game.moves += 1
func _on_Tween_tween_all_completed():
get_parent().check_end()
And my box code since the two objects work in tandem to work right (I based my game off of a YouTube tutorial if you couldn't tell already):
extends KinematicBody2D
onready var ray = $RayCast2D
var grid_size = 8
var inputs = {
'ui_up' : Vector2.UP,
'ui_down' : Vector2.DOWN,
'ui_left' : Vector2.LEFT,
'ui_right' : Vector2.RIGHT
}
func move(dir):
var vector_pos = inputs[dir] * grid_size
ray.cast_to = vector_pos
if Input.is_key_pressed(KEY_Z):
ray.cast_to = -vector_pos
ray.force_raycast_update()
$Tween.interpolate_property(
self, "position",
position, position + vector_pos, 0.1,
Tween.TRANS_SINE,
Tween.EASE_IN_OUT
)
if !ray.is_colliding():
$Tween.start()
return true
return false