Domanda: qual'è il modo più performante e corretto per disegnare più rettangoli di diverse dimensioni, secondo voi?
(uso Game maker studio 2 v2.3)
Qui di seguito vi elenco alcuni metodi che ho usato:
Inizialmente ho semplicemente optato per il modo più classico:
Codice: Seleziona tutto
draw_rectangle_color( object.x - 25, object.y -25, object.x + 25, object.y + 25, c_yellow, c_yellow, c_yellow, c_yellow, true ); //Rettangolo A
draw_rectangle_color( object.x - 45, object.y -45, object.x + 45, object.y + 45, c_red, c_red, c_red, c_red, true ); //Rettangolo B
draw_rectangle_color( object.x - 75, object.y -75, object.x + 75, object.y + 75, c_blue, c_blue, c_blue, c_blue, true ); //Rettangolo C
Poi ho pensato di usare un array 2d (sto cominciando a conoscerlo) e ad usare un ciclo for per disegnare i rettangoli, in questo modo:
Codice: Seleziona tutto
///Draw Event
//Array 2d [ colonna A (Rettangolo A, Rettangolo B, Rettangolo C), colonna B (x1,y1,x2,y2,colore) ]
var array_2d;
//Rettangolo A
array_2d[2, 4] = -25; // x1
array_2d[2, 3] = -25; // y1
array_2d[2, 2] = 25; // x2
array_2d[2, 1] = 25; // y2
array_2d[2, 0] = c_yellow; // colore
//Rettangolo B
array_2d[1, 4] = -45; // x1
array_2d[1, 3] = -45; // y1
array_2d[1, 2] = 45; // x2
array_2d[1, 1] = 45; // y2
array_2d[1, 0] = c_red; // colore
//Rettangolo C
array_2d[0, 4] = -75; // x1
array_2d[0, 3] = -75; // y1
array_2d[0, 2] = 75; // x2
array_2d[0, 1] = 75; // y2
array_2d[0, 0] = c_blue; // colore
size = array_length(array_2d) - 1;
for (var i = size; i >= 0; --i)
{
draw_rectangle_color(
object.x + array_2d[i, 4], object.y + array_2d[i, 3], //x1 y1
object.x + array_2d[i, 2], object.y + array_2d[i, 1], //x2 y2
array_2d[i, 0], array_2d[i, 0], array_2d[i, 0], array_2d[i, 0], //colore
true);
}
Allora ho pensato di usare le Data Structures (sto iniziando a conoscerle solo ora), e in particolar modo di usare una ds_grid, visto che ho letto che è praticamente un array 2d con la possibilità di gestire l'ordine numerico al suo interno e senza preoccuparmi di numerare ciascuna colonna per ogni nuova aggiunta (sennò non capisco il senso di usare una ds_grid). Ho fantasticato di poterla usare come una ds_map, con la possibilità di usare 2 chiavi dichiarate in stringhe invece di una, più il valore. In questo modo:
Codice: Seleziona tutto
var grid = ds_grid_create();
//Rettangolo A
ds_grid_add (grid , "rettangolo_A", "x1", -25)
ds_grid_add (grid , "rettangolo_A", " y1", -25)
ds_grid_add (grid , "rettangolo_A", "x2", 25)
ds_grid_add (grid , "rettangolo_A", "y2", 25)
ds_grid_add (grid , "rettangolo_A", "colore", c_yellow)
//Rettangolo B
ds_grid_add (grid , "rettangolo_B", "x1", -45)
ds_grid_add (grid , "rettangolo_B", " y1", -45)
ds_grid_add (grid , "rettangolo_B", "x2", 45)
ds_grid_add (grid , "rettangolo_B", "y2", 45)
ds_grid_add (grid , "rettangolo_B", "colore", c_red)
//Rettangolo C
ds_grid_add (grid , "rettangolo_C", "x1", -75)
ds_grid_add (grid , "rettangolo_C", " y1", -75)
ds_grid_add (grid , "rettangolo_C", "x2", 75)
ds_grid_add (grid , "rettangolo_C", "y2", 75)
ds_grid_add (grid , "rettangolo_C", "colore", c_blue)
Codice: Seleziona tutto
size = ds_grid_width (grid);
for (var i = 0; i < size; i++)
{
draw_rectangle_color(
object.x + grid [# i, "x1"], object.y + grid [# i, "y1"], //x1 y1
object.x + grid [# i, "x2"], object.y + grid [# i, "y2"], //x2 y2
grid[# i, "colore"], grid [# i, "colore"], grid [# i, "colore"], grid [# i, "colore"], //colore
true);
}
ds_grid_clear(grid);
ds_grid_destroy(grid);
Quindi,
Certo, potrei usare "enum" nell'evento create e inizializzare per nome le costanti da importare poi nella griglia, senza dovermi preoccupare dell'ordine numerico, ma vorrei evitarlo visto che queste costanti mi servirebbero soltanto per disegnare questi rettangoli che rapresentano le aree interessate delle funzioni "collision_in_rectangle" utilizzate da un oggetto. Preferirei quindi che tutto fosse eseguito e poi cancellato nell' evento Draw.
Mi chiedo se non ci fosse un altro modo per dichiarare il valore in una stringa, senza stare a numerare l'ordine, perchè sennò potrei farlo tranquillamente con un array 2d, ma allora siamo punto e a capo. L'ideale sarebbe farlo con chiavi in stringhe come una ds_map, ma poterle usare in un ciclo for come se fossero costanti.
La mia attuale soluzione è questa, per ora.
Ho creato due liste, in una ci ho messo l'elenco dei rettangoli, nell'altra invece le statistiche, e nella ds grid attribuisco il valore, relativo al rettangolo e alla statistica che ho stabilito, per poi scorrere l'elenco dei rettangoli nel ciclo for, ma non penso che questo sia il metodo più breve e performante, mi sembra troppo complicato per quello che devo fare, e inoltre non ha molto senso l'utilizzo di una ds_grid a questo punto.
Codice: Seleziona tutto
/// EVENTO DRAW
//LISTA RETTANGOLI
var rL = ds_list_create();
ds_list_add (rL, "collision_x");
ds_list_add (rL, "collision_y");
ds_list_add (rL, "collision_y_line");
ds_list_add (rL, "ladder_up_layer_doors");
ds_list_add (rL, "ladder_down");
ds_list_add (rL, "shadowfloor");
ds_list_add (rL, "collide_uphill");
ds_list_add (rL, "collide_ball");
//LISTA STATISTICHE
var sL = ds_list_create();
ds_list_add (sL, "x1");
ds_list_add (sL, "y1");
ds_list_add (sL, "x2");
ds_list_add (sL, "y2");
ds_list_add (sL, "color");
//CREAZIONE DELLA GRIGLIA
var b_Dung = ds_grid_create (ds_list_size(rL), ds_list_size(sL));
//STATISTICHE INDICIZZATE
var _x1 = ds_list_find_index (sL, "x1");
var _y1 = ds_list_find_index (sL, "y1");
var _x2 = ds_list_find_index (sL, "x2");
var _y2 = ds_list_find_index (sL, "y2");
var _color = ds_list_find_index (sL, "color");
//ASSEGNA POSIZIONE E RELATIVI VALORI ALLA GRIGLIA
//collision_x
var _collision_x = ds_list_find_index(rL,"collision_x"); //Rettangolo Indicizzato
b_Dung[# _collision_x, _x1] = -25;
b_Dung[# _collision_x, _y1] = -5 + oDung.ypos_sprite;
b_Dung[# _collision_x, _x2] = 25;
b_Dung[# _collision_x, _y2] = 25 + oDung.ypos_sprite;
b_Dung[# _collision_x, _color] = c_silver;
//collision_y
var _collision_y = ds_list_find_index(rL,"collision_y");
b_Dung[# _collision_y, _x1] = -50*oDung.scale;
b_Dung[# _collision_y, _y1] = -90*oDung.scale + oDung.ypos_sprite;
b_Dung[# _collision_y, _x2] = 50*oDung.scale;
b_Dung[# _collision_y, _y2] = -40*oDung.scale + oDung.ypos_sprite;
b_Dung[# _collision_y, _color] = c_silver;
//collision_y_line
var _collision_y_line = ds_list_find_index(rL,"collision_y_line");
b_Dung[# _collision_y_line, _x1] = 0;
b_Dung[# _collision_y_line, _y1] = -40*oDung.scale;
b_Dung[# _collision_y_line, _x2] = 0;
b_Dung[# _collision_y_line, _y2] = -10*oDung.scale;
b_Dung[# _collision_y_line, _color] = c_fuchsia;
//ladder_up e layer_doors
var _ladder_up_layer_doors = ds_list_find_index(rL,"ladder_up_layer_doors");
b_Dung[# _ladder_up_layer_doors, _x1] = -18*oDung.scale;
b_Dung[# _ladder_up_layer_doors, _y1] = -50*oDung.scale + oDung.ypos_sprite;
b_Dung[# _ladder_up_layer_doors, _x2] = 18*oDung.scale;
b_Dung[# _ladder_up_layer_doors, _y2] = -40*oDung.scale + oDung.ypos_sprite;
b_Dung[# _ladder_up_layer_doors, _color] = c_lime;
//ladder_down
var _ladder_down = ds_list_find_index(rL,"ladder_down");
b_Dung[# _ladder_down, _x1] = -18*oDung.scale;
b_Dung[# _ladder_down, _y1] = 40*oDung.scale;
b_Dung[# _ladder_down, _x2] = 18*oDung.scale;
b_Dung[# _ladder_down, _y2] = 50*oDung.scale;
b_Dung[# _ladder_down, _color] = c_lime;
//shadowfloor
var _shadowfloor = ds_list_find_index(rL,"shadowfloor");
b_Dung[# _shadowfloor, _x1] = -15*oDung.scale;
b_Dung[# _shadowfloor, _y1] = -10*oDung.scale;
b_Dung[# _shadowfloor, _x2] = 15*oDung.scale;
b_Dung[# _shadowfloor, _y2] = 200*oDung.scale;
b_Dung[# _shadowfloor, _color] = c_black;
//collide_uphill
var _collide_uphill = ds_list_find_index(rL,"collide_uphill");
b_Dung[# _collide_uphill, _x1] = -5*oDung.spr_scale;
b_Dung[# _collide_uphill, _y1] = -15*oDung.scale;
b_Dung[# _collide_uphill, _x2] = 108*oDung.spr_scale;
b_Dung[# _collide_uphill, _y2] = -25*oDung.scale;
b_Dung[# _collide_uphill, _color] = c_red;
//collide_ball
var _collide_ball = ds_list_find_index(rL,"collide_ball");
b_Dung[# _collide_ball, _x1] = 70*oDung.spr_scale;
b_Dung[# _collide_ball, _y1] = -50*oDung.scale;
b_Dung[# _collide_ball, _x2] = 70*oDung.spr_scale;
b_Dung[# _collide_ball, _y2] = -50*oDung.scale;
b_Dung[# _collide_ball, _color] = c_red;
var grid_w = ds_grid_width(b_Dung); //il numero totale della lista dei rettangoli
for (var grid_y = 0; grid_y < grid_w; grid_y++)
{
draw_rectangle_color(
oDung.x + b_Dung[# grid_y, _x1], oDung.y + b_Dung[# grid_y, _y1], //x1 y1
oDung.x + b_Dung[# grid_y, _x2], oDung.y + b_Dung[# grid_y, _y2], //x2 y2
b_Dung[# grid_y, _color], b_Dung[# grid_y, _color], b_Dung[# grid_y, _color], b_Dung[# grid_y, _color], //color
true);
}
ds_list_clear(rL);
ds_list_clear(sL);
ds_grid_clear(b_Dung,-1);
ds_list_destroy(rL);
ds_list_destroy(sL);
ds_grid_destroy(b_Dung);
A questo punto non so se è meglio scrivere per tante volte di fila draw_rectangle_color, oppure scrivere tutto questo mazzo di codice che, ricapitolando, comprende 2 liste 1 griglia e 15 variabili locali.
Secondo voi qual'è il modo più breve e performante per disegnare tanti rettangoli di dimensioni diverse? Illuminatemi, please!