I'm fairly new to Godot, but I've been programming games for a bit. I understand GDScript, but using it fully still escapes me. So i'm still learning/struggling.
Anyway, I'm working on a sokoban style puzzle game (grid based movement) and I want blocks that have moved next each other to 'combine' and move together. Kinda like legos. I'm currently using raycast2D to detect collision between sprites, and it has been successful, but I receive an error when the sprite being moved collides with a wall (object in tilemap).
This is the error: Invalid get index 'position' (on base: 'Node').
To track the position i'm essentially grabbing colliding sprite and saving it once in a variable. Then I match the collided sprites position to that of the one that is in 'control' or allowed to move, but again I receive the error when the control sprite reaches a collision.
The idea behind control is that ill have multiple instances of a sprite and have the ability to shuffle control between the various sprites in a scene.
Here is the sprite script:
extends Sprite # if the sprite is currently in control, can be rotated with space export var Control = false # make the raycast available to use in the player script onready var ray = $Area2D/RayCast2D onready var rayUP = $Area2D/rayUP onready var rayDOWN = $Area2D/rayDOWN onready var rayLEFT = $Area2D/rayLEFT onready var rayRIGHT = $Area2D/rayRIGHT # detect collision only once with these flags var colUP = false var colDOWN = false var colLEFT = false var colRIGHT = false var UColSprite var DColSprite var LColSprite var RColSprite var speed = 600 # large speed value to determine how fast the sprite will move var tile_size = 64 # size in pixels of the tiles on the grid var last_position = position # last idle position to keep track of var target_position = position # new position to be moved to var movedir = Vector2(0, 0) # the move direction # init function func _ready(): # snap the player to a grid position if misplaced # and update its position trackers to the snapped vector2 position = position.snapped(Vector2(tile_size, tile_size)) last_position = position target_position = position # set move direction based on player input func get_movedir(): # collect the input and store it var LEFT = Input.is_action_pressed("ui_left") var RIGHT = Input.is_action_pressed("ui_right") var UP = Input.is_action_pressed("ui_up") var DOWN = Input.is_action_pressed("ui_down") # process the movement based on each vector movedir.x = -int(LEFT) + int(RIGHT) # is negative one if moving left and vice versa, if both then zero movedir.y = -int(UP) + int(DOWN) # same up with y # prevent diagonal movement if movedir.x !=0 && movedir.y != 0: movedir = Vector2.ZERO # no value # set the end of the ray cast to the edge of the player sprite if movedir != Vector2.ZERO: ray.cast_to = movedir * tile_size / 2 # process movement every frame func _process(delta): if Control == true: # idle if position == target_position: get_movedir() last_position = position # save the players current position target_position += movedir * tile_size # if movement, then calculate new target position # moving else: # make sure not to move the player if they will collide with a wall if ray.is_colliding(): target_position = last_position # set the player back to there original location else: # update the position position += speed * movedir * delta # prevent the player from moving past the target var distance = (position - last_position).abs().length() # how far they moved frem the idle position # track the distance if distance > tile_size - speed * delta: # subtract speed * delta so there's no break/pause in movement position = target_position else: # if the sprite is not being controlled, collect a collision if the controlled sprite moved next to it6 if rayUP.is_colliding(): if colUP == false: colUP = true UColSprite = rayUP.get_collider().get_parent() position = UColSprite.position - Vector2(0, 64) if rayDOWN.is_colliding(): if colDOWN == false: colDOWN = true DColSprite = rayDOWN.get_collider().get_parent() position = DColSprite.position + Vector2(0, 64) if rayLEFT.is_colliding(): if colLEFT == false: colLEFT = true LColSprite = rayLEFT.get_collider().get_parent() position = LColSprite.position + Vector2(64, 0) if rayRIGHT.is_colliding(): if colRIGHT == false: colRIGHT = true RColSprite = rayRIGHT.get_collider().get_parent() position = RColSprite.position - Vector2(64, 0)