The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

Sooo. i did a questin 4 days ago, it solve my problem, but it creted another problem...
i'm doing a game like candy-crush, for a school project. got it in a totorial in youtube but i video is kinda old (4 years ago) and i think some codes are wrong or something, now i'm trying to do a ice piece.

The problem is when i match any 3 pieces in the grid. got this error of invalid index '(x, y)' (x and y are number of the grid. is a random number).

the code that is gettin the error:

func _on_Grid_damage_ice(board_position : Vector2):
    *if ice_pieces[board_position] != null:*
        ice_pieces[board_position].take_damage(1)
        if ice_pieces[board_position].health <= 0:
            ice_pieces[board_position] = null

The error mark the second line with the error. but i think is all the func have a problem.

i have separeted codes to the grid and this code

this is the main code:

extends Node2D

#state machine
enum {wait, move}
var state

# Grid Variaveis
export (int) var width;
export (int) var height;
export (int) var x_start;
export (int) var y_start;
export (int) var offset;
export (int) var y_offset;

# obstacle Stuff
export (PoolVector2Array) var empty_spaces
export (PoolVector2Array) var ice_spaces

#obstacle signals
signal damage_ice
signal make_ice

#The piece array
var possible_pieces = [
preload("res://Cenario peças/banana.tscn"),
preload("res://Cenario peças/dragao.tscn"),
preload("res://Cenario peças/melancia.tscn"),
preload("res://Cenario peças/tomato.tscn"),
preload("res://Cenario peças/maça.tscn"),
preload("res://Cenario peças/uva.tscn") 
];

# the current  pieces in the scene
var all_pieces =[];

#swap back variable
var piece_one = null
var piece_two = null
var last_place = Vector2(0,0)
var last_direction = Vector2(0, 0)
var move_checked = false
# Touch variable
var first_touch  = Vector2(0, 0);
var final_touch  = Vector2(0, 0);
var controlling = false;

func _ready():
    state = move
    randomize();
    all_pieces  = make_2d_array();
    spawn_pieces();
    spawn_ice();
    print(possible_pieces)

func restricted_fill(place):
    #check thepty pieces
    if is_in_array(empty_spaces, place):
        return true
    return false    



func is_in_array(array, item):
    for i in array.size():
        if array[i] == item:
            return true
    return false            

func make_2d_array():
    var array = [];
    for i in width:
           array.append([]);
           for j in height:
               array[i].append(null)
    return array;

func spawn_pieces():
    for i in width:
        for j in height:
            if !restricted_fill(Vector2(i, j)):
            #choose a random number and store it
                var rand = floor(rand_range(0, possible_pieces.size()));
                var piece = possible_pieces[rand].instance();
                var loops = 0
                while(match_at(i, j, piece.color) && loops < 100):
                    rand = floor(rand_range(0, possible_pieces.size()));
                    loops += 1;
                    piece = possible_pieces[rand].instance();
            #instance that piece from the array
                add_child(piece);
                piece.position = grid_to_pixel(i, j);
                all_pieces[i][j] = piece;
                print (possible_pieces[rand])

func spawn_ice():
    for i in ice_spaces.size():
        emit_signal("make_ice", ice_spaces[i])


func match_at(i, j, color):

    if i > 1:
        if all_pieces[i - 1][j] != null && all_pieces[i - 2][j] != null:
            if all_pieces[i - 1][j].color == color && all_pieces[i - 2][j].color == color:
                return true;
    if j > 1:
        if all_pieces[i][j - 1] != null && all_pieces[i][j - 2] != null:
            if all_pieces[i][j - 1].color == color && all_pieces[i][j - 2].color == color:
                return true;


func grid_to_pixel(column, row):
    var new_x = x_start + offset * column;
    var new_y = y_start + -offset * row;
    return Vector2(new_x, new_y);

func pixel_to_grid(pixel_x, pixel_y):
    var new_x = round((pixel_x - x_start) / offset);
    var new_y = round((pixel_y - y_start) / -offset);
    return Vector2(new_x, new_y);
    pass;   

func is_in_grid(grid_position):
    if grid_position.x >= 0 && grid_position.x < width:
        if grid_position.y >= 0 && grid_position.y < height:
            return true;
    return false;           

func touch_input():

    if Input.is_action_just_pressed("ui_touch"):        
        if is_in_grid(pixel_to_grid(get_global_mouse_position().x, get_global_mouse_position().y)):
            first_touch = pixel_to_grid(get_global_mouse_position().x, get_global_mouse_position().y);
            controlling = true
    if Input.is_action_just_released("ui_touch"):
        if is_in_grid(pixel_to_grid(get_global_mouse_position().x, get_global_mouse_position().y)) && controlling:
            controlling = false;
            final_touch= pixel_to_grid(get_global_mouse_position().x, get_global_mouse_position().y)
            touch_difference(first_touch, final_touch);

func swap_pieces(column, row, direction):           
    var first_piece = all_pieces[column][row];
    var other_piece = all_pieces[column + direction.x][row + direction.y];
    if first_piece != null && other_piece != null:
        store_info(first_piece, other_piece, Vector2(column, row), direction)
        state = wait
        all_pieces[column][row] = other_piece;
        all_pieces[column + direction.x][row + direction.y] = first_piece;
        first_piece.move(grid_to_pixel(column + direction.x, row + direction.y));
        other_piece.move(grid_to_pixel(column, row));
        if !move_checked:
            find_matches()

func store_info(first_piece, other_piece, place, direction):
    piece_one = first_piece
    piece_two = other_piece
    last_place = place
    last_direction = direction
    pass
func swap_back():
    #LOL
    if piece_one != null && piece_two != null:
        swap_pieces(last_place.x, last_place.y, last_direction)
    state = move
    move_checked = false
    pass

func touch_difference(grid_1, grid_2):
    var difference = grid_2 - grid_1;
    if abs(difference.x) > abs(difference.y):
        if difference.x > 0:
            swap_pieces(grid_1.x, grid_1.y, Vector2(1, 0));
        elif difference.x < 0:
            swap_pieces(grid_1.x, grid_1.y, Vector2(-1, 0));
    elif abs(difference.y) > abs(difference.x):
        if difference.y > 0:
            swap_pieces(grid_1.x, grid_1.y, Vector2(0, 1));
        elif difference.y < 0:
            swap_pieces(grid_1.x, grid_1.y, Vector2(0, -1));
        pass;

func _process(delta):
    if state == move:
        touch_input();


func find_matches():
    for i in width:
        for j in height:
            if all_pieces[i][j] != null:
                var current_color = all_pieces[i][j].color
                if i > 0 && i < width - 1:
                    if !is_piece_null(i - 1, j) && all_pieces[i + 1][j] != null:
                        if all_pieces[i - 1][j].color == current_color && all_pieces[i + 1][j].color == current_color:
                            match_and_dim(all_pieces[i - 1][j])
                            match_and_dim(all_pieces[i][j])
                            match_and_dim(all_pieces[i + 1][j])
                            all_pieces[i][j].matched = true;
                            all_pieces[i][j].dim();
                            all_pieces[i + 1][j].matched = true;
                            all_pieces[i + 1][j].dim();
                if j > 0 && j < height - 1:
                    if all_pieces[i][j - 1] != null && all_pieces[i][j + 1] != null:
                        if all_pieces[i][j - 1].color == current_color && all_pieces[i][j + 1].color == current_color:
                            match_and_dim(all_pieces[i][j - 1])
                            match_and_dim(all_pieces[i][j])
                            match_and_dim(all_pieces[i][j + 1])
                            all_pieces[i][j].matched = true;
                            all_pieces[i][j].dim();
                            all_pieces[i][j + 1].matched = true;
                            all_pieces[i][j + 1].dim();
    get_parent()    .get_node("destroy_timer").start()  


func is_piece_null(column, row):
    if all_pieces[column][row] == null:
        return true
    return false    


func match_and_dim(item):
    item.matched = true
    item.dim()


func destroy_matched():
    var was_matched = false
    for i in width:
        for j in height:
            if all_pieces[i][j] != null:
                if all_pieces[i][j].matched:
                    emit_signal("damage_ice", Vector2(i,j))
                    was_matched = true
                    all_pieces[i][j].queue_free()
                    all_pieces[i][j] = null
    move_checked = true
    if was_matched:
        get_parent().get_node("Collapse_timer").start()
    else:   
        swap_back()
func collapse_collums():
    for i in width:
        for j in height:
            if all_pieces[i][j] == null && !restricted_fill(Vector2(i, j)):
                for k in range(j + 1, height):
                    if all_pieces[i][k] != null:
                        all_pieces[i][k].move(grid_to_pixel(i, j))
                        all_pieces[i][j] = all_pieces[i][k]
                        all_pieces[i][k] = null
                        break
    get_parent().get_node("refil_timer").start()                        
func refill_columns():
    for i in width:
        for j in height:
            if all_pieces[i][j] == null && !restricted_fill(Vector2(i, j)):
                var rand = floor(rand_range(0, possible_pieces.size()));
                var piece = possible_pieces[rand].instance();
                var loops = 0
                while(match_at(i, j, piece.color) && loops < 100):
                    rand = floor(rand_range(0, possible_pieces.size()));
                    loops += 1;
                    piece = possible_pieces[rand].instance();
                #instance that piece from the array
                add_child(piece);
                piece.position = grid_to_pixel(i, j - y_offset);
                piece.move(grid_to_pixel(i, j));
                all_pieces[i][j] = piece;
    after_refil()

func after_refil():
    for i in width:
        for j in height:
            if all_pieces[i][j] != null:
                if match_at(i, j, all_pieces[i][j].color):
                    find_matches()
                    get_parent().get_node("destroy_timer").start()
                    return
    state = move
    move_checked = false

func _on_destroy_timer_timeout():
    destroy_matched()

func _on_Collapse_timer_timeout():
    collapse_collums()

func _on_refil_timer_timeout():
    refill_columns()

and i got a script for the pieces in the grid:

    extends Node2D

export (String) var color;
var move_tween;
var matched = false


func _ready():
    move_tween = get_node("Sprite/move_tween")

    pass # Replace with function body.

func move(target):
    move_tween.interpolate_property(self, "position", position, target, .3,
                                   Tween.TRANS_BOUNCE, Tween.EASE_OUT);
    move_tween.start();
    pass;

# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#   pass

func dim():
    var sprite = get_node("Sprite")
    sprite.modulate = Color(1, 1, 1, .5);
    pass

By interest the video i'm referring is this link:
https://www.youtube.com/watch?v=ThINCQcEOYs&list=PL4vbr3u7UKWqwQlvwvgNcgDL1p_3hcNn2&index=19

any questions is just ask.

Godot version godot 64x standart
in Engine by (18 points)

1 Answer

0 votes

Getting a value from an array like this ice_pieces[board_position], requires the corresponding value to actually exist in the array. Otherwise you'll get that error.

What I believe you want to do is to use array.get(..), like this:

if ice_pieces.get(board_position) != null:

The get function will return null if the value is not found in the array, while array[key] will cause an error.

Alternatively, make sure your array is initialized properly and the data you are trying to get already exists in it.

by (1,122 points)
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 Frequently asked questions and 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 [email protected] with your username.