This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
0 votes

hi, i'm doing a game candy-crush like for a school project. And i have gotten this error:
Invalid call. Nonexistent function 'take_damege' in base 'Node2D'.

Apparently i have a function that my script is not reading. They are separated in two scripts but i don't think thats the problem. the two codes:

 func _on_Grid_damage_ice(board_position):
    if ice_pieces[board_position.x][board_position.y] != null:
        ice_pieces[board_position.x][board_position.y].take_damage(1)
        if ice_pieces[board_position.x][board_position.y].health <= 0:
            ice_pieces[board_position.x][board_position.y].queue_free()
            ice_pieces[board_position.x][board_position.y] = null

and

export (int) var health

func _ready():
    pass # Replace with function body.

func take_damage(damage):
    health <= damage

So the "take_damage" is been call invalid for some reason
anything that can help i would be grateful.

Edit: heres the principal script:

#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();

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()

Pieces script:

    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
Godot version godot 64x
in Engine by (18 points)
edited by

1 Answer

+2 votes

Pretex

Computers are not very good at understanding human speech Alpha-Numeric Languages similar to most people not being able to understand machine code binary.

Program Languages are a way to mediate this gap by translating one to the other however what is typed must conform strictly to the guidelines or your intentions will get lost in translation.

Problems

  1. The most common problems while programming are caused by user error of sometimes simply misspelling a word
  2. Which based on your title is the most likely candidate for your error.
  3. This line health <= damage does not do anything
  4. You've offset critical info outside of the function
  5. Global variable misuse [avoid when possible the use of global vars and never manipulate them outside of their class directly]

Semi - Solution

export (int) var health

func _ready():
    pass # Replace with function body.

func take_damage(damage):
    health -= damage

    if health <= 0:
        queue_free()

    return health

Nothing is wrong with your use case however you can use Vector2 in lieu of multiple Arrays

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
by (6,942 points)
ice_pieces[board_position.x][board_position.y] = null

No need for that line

Also double check that your "res://Cenarioo/Gelo.tscn" has the pieces script attached to the top most node in that scene

Add this function check as well

func _on_Grid_damage_ice(board_position):
    if ice_pieces[board_position.x][board_position.y] != null:
    if ice_pieces[board_position.x][board_position.y].has_method("take_damage"):
        ice_pieces[board_position.x][board_position.y].take_damage(1) 

fix the error, but i don't do what it supose todo... do you know something that i can put to make the sprite disappear?

You already have with queue_free()

Will try your code and see if it works and get back to you

any progress? i know its late to say now. But this code is from a tutorial. if you need more information about the code i think you can find is this video:
https://www.youtube.com/watch?v=ThINCQcEOYs

Figured as much.

And with that knowledge provided there was never ever any reason for me to help you in the first place because all the code for your project is right here and all of the steps are equally located here

After downloading that code if you don't already have one you should download a versioning diff tool like Meld then compare your project to the one above and it will show exactly where you misstep.

Additionally if you intend to do coding continually you could get familiar with version control software such as Git to properly manage your future projects

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.