Checking the sprite of a colliding object.

F

fireair

Guest
Hey there I'm currently working on a tetris like game and i want the score gained when you clear a line to multiply based on the number of blocks with the most occurring sprite in the cleared line. However the only way I can think to do this is by checking the sprite of each block in the line, getting the number of each sprites occurrence, finding the highest number, then multiplying that number by 50 and adding it to the score. I'm not sure how to check the sprites in the line, so if anyone knows how to do whats said in the title please tell me.
 

jo-thijs

Member
Hey there I'm currently working on a tetris like game and i want the score gained when you clear a line to multiply based on the number of blocks with the most occurring sprite in the cleared line. However the only way I can think to do this is by checking the sprite of each block in the line, getting the number of each sprites occurrence, finding the highest number, then multiplying that number by 50 and adding it to the score. I'm not sure how to check the sprites in the line, so if anyone knows how to do whats said in the title please tell me.
Hi and welcome to the GMC!

The way you described to tackle your problem sounds good to me.
In order for us to tell how to get the sprite of a certain block, we need to know how you represent blocks.
In case you represent blocks as object instances, you could probably do something like this:
Code:
var counts, tetromino_amount = 7;
counts[tetromino_amount - 1] = 0;

var cy = line_y;
for(var cx = leftmost_x; cx < rightmost_x; cx += cell_width) {
    with instance_position(cx, cy, obj_tetromino) {
        var index = -1;
        switch sprite_index {
        case spr_tetromino_I:
            index = 0;
            break;
        case spr_tetromino_O:
            index = 1;
            break;
        ...
        }
        counts[index]++;
    }
}

var maxcount = 0;
for(var i = 0; i < tetromino_amount; ++i) {
    maxcount = max(maxcount, counts[i]);
}

var score_bonus = maxcount * 50;
where leftmost_x is the x coordinate of the leftmost cell in the tetris field,
righmost_x is the x coordinate of the right edge of the field,
line_y is the y coordinate of the blocks on the line you're checking,
obj_tetromino is a parent object of all block objects,
spr_tetromino_* is a sprite of a tetromino,
tetromino_amount is the amount of tetromino sprites
and score_bonus is the score you get for completing the line.
 
F

fireair

Guest
Hi and welcome to the GMC!

The way you described to tackle your problem sounds good to me.
In order for us to tell how to get the sprite of a certain block, we need to know how you represent blocks.
In case you represent blocks as object instances, you could probably do something like this:
Code:
var counts, tetromino_amount = 7;
counts[tetromino_amount - 1] = 0;

var cy = line_y;
for(var cx = leftmost_x; cx < rightmost_x; cx += cell_width) {
    with instance_position(cx, cy, obj_tetromino) {
        var index = -1;
        switch sprite_index {
        case spr_tetromino_I:
            index = 0;
            break;
        case spr_tetromino_O:
            index = 1;
            break;
        ...
        }
        counts[index]++;
    }
}

var maxcount = 0;
for(var i = 0; i < tetromino_amount; ++i) {
    maxcount = max(maxcount, counts[i]);
}

var score_bonus = maxcount * 50;
where leftmost_x is the x coordinate of the leftmost cell in the tetris field,
righmost_x is the x coordinate of the right edge of the field,
line_y is the y coordinate of the blocks on the line you're checking,
obj_tetromino is a parent object of all block objects,
spr_tetromino_* is a sprite of a tetromino,
tetromino_amount is the amount of tetromino sprites
and score_bonus is the score you get for completing the line.

Actually I just realized that it always adds 700 to the score when i clear 1 line

heres my code:

/// @description destroy the block and add it to game grid
var gg, bw, bh, bx, by, r, c, clear_this_line, cleared_lines = 0

gg = global.game_grid

bw = grid_width
bh = grid_height
bx = block_x
by = block_y
var counts, obj_block_parent_amount = 7;
counts[obj_block_parent_amount - 1] = 0;


ds_grid_add_grid_region(gg, grid, 0, 0, bw - 1, bh - 1, bx , by)

/// clear completed lines, if necessary
for (r = 1; r < GAME_HEIGHT; r++) {
clear_this_line = true
for (c = 0; c < GAME_WIDTH; c++) {
if (ds_grid_get(gg, c, r) == 0) {
clear_this_line = false
break
}
}

if (clear_this_line) {
ds_grid_remove_line(gg, r)
cleared_lines++
}
}

var cy = r;

for(var cx = 0; cx < 288; cx += 32) {
with instance_position(cx, cy, obj_block_parent) {
var index = -1;
switch sprite_index {
case spr_block_red:
index = 0;
break;
case spr_block_blue:
index = 1;
break;
case spr_block_green:
index = 2;
break;
case spr_block_purple:
index = 3;
break;
case spr_block_yellow:
index = 4;
break;
}
counts[index]++;
}
}


var maxcount = 0;
for(var i = 0; i < obj_block_parent_amount; ++i) {
maxcount = max(maxcount, counts);

if (cleared_lines > 0) {
var score_bonus = maxcount * 50;
global.gscore += score_bonus + (cleared_lines * 100)
if (cleared_lines > 1) global.gscore += cleared_lines * 50
}
}
instance_destroy()
global.current_block = -1
any Idea what i can do to fix this?
 

jo-thijs

Member
Actually I just realized that it always adds 700 to the score when i clear 1 line

heres my code:

/// @description destroy the block and add it to game grid
var gg, bw, bh, bx, by, r, c, clear_this_line, cleared_lines = 0

gg = global.game_grid

bw = grid_width
bh = grid_height
bx = block_x
by = block_y
var counts, obj_block_parent_amount = 7;
counts[obj_block_parent_amount - 1] = 0;


ds_grid_add_grid_region(gg, grid, 0, 0, bw - 1, bh - 1, bx , by)

/// clear completed lines, if necessary
for (r = 1; r < GAME_HEIGHT; r++) {
clear_this_line = true
for (c = 0; c < GAME_WIDTH; c++) {
if (ds_grid_get(gg, c, r) == 0) {
clear_this_line = false
break
}
}

if (clear_this_line) {
ds_grid_remove_line(gg, r)
cleared_lines++
}
}

var cy = r;

for(var cx = 0; cx < 288; cx += 32) {
with instance_position(cx, cy, obj_block_parent) {
var index = -1;
switch sprite_index {
case spr_block_red:
index = 0;
break;
case spr_block_blue:
index = 1;
break;
case spr_block_green:
index = 2;
break;
case spr_block_purple:
index = 3;
break;
case spr_block_yellow:
index = 4;
break;
}
counts[index]++;
}
}


var maxcount = 0;
for(var i = 0; i < obj_block_parent_amount; ++i) {
maxcount = max(maxcount, counts);

if (cleared_lines > 0) {
var score_bonus = maxcount * 50;
global.gscore += score_bonus + (cleared_lines * 100)
if (cleared_lines > 1) global.gscore += cleared_lines * 50
}
}
instance_destroy()
global.current_block = -1
any Idea what i can do to fix this?
1) If you only use 5 colors, you should set obj_block_parent_amount to 5, not 7 in this line:
Code:
var counts, obj_block_parent_amount = 7;
2) This line:
Code:
ds_grid_add_grid_region(gg, grid, 0, 0, bw - 1, bh - 1, bx , by)
doesn't make a lot of sense to me.
Why are you adding the values of the regions together?
It also seems to suggest you're not using object instances to represent your blocks, but you're using grids instead.
Is this correct?
If so, you can work more efficiently.

3) When you reach this line:
Code:
var cy = r;
you're already outside the loop and r will just be GAME_HEIGHT.
This represents the row below the bottom row, which does not exist.
On top of that, r is a row index whereas cy is a vertical coordinate in the room.
To convert between them, you'd need to multiply r with (presumably) 32 and add an offset (presumably 0).
Because you don't do this conversion, you're (presumably) always checking the top row of your field, where there will (presumably) almost never be any block.
As a result, all counts will be 0.

4) This:
Code:
var maxcount = 0;
for(var i = 0; i < obj_block_parent_amount; ++i) {
    maxcount = max(maxcount, counts[i]);
    
    if (cleared_lines > 0) {
        var score_bonus = maxcount * 50;
        global.gscore += score_bonus + (cleared_lines * 100)
        if (cleared_lines > 1) global.gscore += cleared_lines * 50
    }
}
should be this:
Code:
var maxcount = 0;
for(var i = 0; i < obj_block_parent_amount; ++i) {
    maxcount = max(maxcount, counts[i]);
}

if cleared_lines > 0 {
    global.gscore += cleared_lines * 150 + maxcount * 50;
}
PS: You should use "Insert... > Code" to insert code in your comments on the GMC.
 
F

fireair

Guest
the game height is actually the number of cells in a column of the grid (16) the width is 10, yes i am doing it with grids, and yes thats whats happening the cleared line is all thats added to the score. So where do I actually add the conversion to the code, and what should it look like? I'm not the greatest at code so I really appreciate the help.:)
 

jo-thijs

Member
the game height is actually the number of cells in a column of the grid (16) the width is 10, yes i am doing it with grids, and yes thats whats happening the cleared line is all thats added to the score. So where do I actually add the conversion to the code, and what should it look like? I'm not the greatest at code so I really appreciate the help.:)
For an optimal solution, can you explain what global.game_grid and grid are?
What are the values of their cells?
What do they represent?
 
Top