Qual'è il modo migliore per disegnare più rettangoli di diverse dimensioni?

Hai una curiosità o un problema con Game Maker? Domanda e ti sarà risposto!
Rispondi
Avatar utente
celeste orsa
Newbie
Messaggi: 10
Iscritto il: 02/11/2018, 17:11
Specialità: Grafico Compositore
Uso: GM:Studio 2
Contatta:

Qual'è il modo migliore per disegnare più rettangoli di diverse dimensioni?

Messaggio da celeste orsa »

Salve a tutti,
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
ma per quanto il codice sia il più breve fra tutti i metodi che conosco, non so se sia necessariamente il più performante, visto che se volessi aggiungere 20 o 30 rettangoli in più, dovrei ripetere per la medesima quantità la stessa funzione, e credo che non sia il modo più corretto.

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);
}
Ma ho trovato che fosse un metodo molto macchinoso, in quanto non so la quantità esatta degli elementi che in futuro potrei aggiungere alle 2 colonne di dati, se ad esempio volessi aggiungere un rettangolo o una statistica in più, sarei costretto a cambiare l'ordine numerico della colonna interessata e questo sarebbe veramente frustrante.

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) 
e poi di utilizzarla nel ciclo for come ho fatto per l'array 2d:

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

Ma ovviamente tutto ciò non ha funzionato, perchè, a quanto pare, la ds_grid non può contenere chiavi dichiarate in stringhe al suo interno (correggetemi se sbaglio) e funziona solo con valori numerici o costanti, proprio come un array 2d.

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.
Spoiler
L'unico motivo perchè sto utilizzando una ds_grid al momento, è perchè ho notato un problema quando utilizzo gli array 2d con un ciclo for. Quando sono dentro il gioco e premo il tasto per mostrare i rettangoli su schermo, il debug a volte mi mostra una lunga linea grigia (ho letto sul manuale che rappresenta il tempo di elaborazione dell'evento draw), in quel momento mi si abbassano i framerate da 6000 a 50 circa, per un secondo, questo è strano visto che con la ds_grid non mi succede, forse è un bug della nuova versione 2.3, o c'è qualcosa che non so degli array 2d, ma questa e un'altra storia...
Comunque, questo è quello che sto facendo ora:

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

Come potete vedere, è un sacco di codice, non so se questo sia il modo corretto di usare una ds_grid, e il modo più performante per disegnare 8 diversi rettangoli su schermo... e visto che ancora sono un dilettante, sicuramente mi sfugge qualcosa, e sono sicuro che ci sia qualcosa di più semplice e performante.
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!

Avatar utente
Simsure
Membro
Messaggi: 223
Iscritto il: 13/09/2013, 21:54
Specialità: Programmazione
Uso: GM:Studio 2
Località: dietro di te...
Contatta:

Re: Qual'è il modo migliore per disegnare più rettangoli di diverse dimensioni?

Messaggio da Simsure »

Ciao Celeste, allora, il primo metodo che hai provato non ha fondamentalmente nessun problema, le performance non sono una cosa di cui devi preoccuparti a certi livelli e chiamare anche 10000 volte draw_rectangle nell'evento draw non è minimamente un problema per Game Maker neanche su computer poco potenti.
L'unico difetto è che potrebbe essere un pelo scomodo per te tenere visivamente in ordine tutti questi rettangoli.

Non riesco a capire bene a quale scopo ti serva avere dei rettangoli e dover avere cosi tante informazioni su di loro, quindi spero di darti comunque un suggerimento che faccia al caso tuo.
In game maker studio 2.3 c'è una novità estremamente utile, le struct, sono come dei mini oggetti senza eventi, per immagazzinare dati, se hai familiarità con altri linguaggi forse le hai gia sentite, si dichiarano cosi:

Codice: Seleziona tutto

var nome_struct = 
{
   xx : 50,
   yy : 100,
   nome : "giorgino"
}
E come per gli oggetti i valori interni si richiamano come le variabili, quindi

Codice: Seleziona tutto

var nome = nome_struct.nome 
nome_struct.nome = "filiberto"
Ecco la documentazione per saperne di piu : https://manual.yoyogames.com/#t=GameMak ... s%20struct

Per imagazinarli potresti usare una ds_map, un'altra data structure, che è fondamentalmente una list con delle stringhe come indici, cosi come indice puoi usare qualsiasi nome tu voglia e come valore della map ci metti una struct al cui interno metti tutti i dati necessari al rettangolo.
Nel draw ti giri la map e per ogni struct disegni il rettangolo prendendone i dati per nome.
Una cosa del genere

Codice: Seleziona tutto

//NELL'EVENTO CREATE
lista_rettangoli = ds_map_create()
ds_map_add( lista_rettangoli , "rettangolo_1", {xx: 100, yy:200, ww:50, hh:50} )
Documentazione delle map : https://manual.yoyogames.com/#t=GameMak ... maps%20map

Nel tuo ultimo esempio hai scritto che tutto quel blocco di codice lo esegui nell'evento draw, ma in questo modo stai anche dichiarando le liste e tutto il loro contenuto nel draw, l'evento draw non si definisce una volta sola, è come se lo schermo si pulisse ad ogni frame e ciò che è scritto nel draw venisse rieseguito ad ogni frame di gioco, forse è questo a causare il lag di cui parlavi, tutto ciò che riguarda il "definire" i dati va nel create, mentre nel draw vanno solo comandi che appunto iniziano con draw, come draw_rectangle().
Immagine
Spoiler
Immagine

Avatar utente
celeste orsa
Newbie
Messaggi: 10
Iscritto il: 02/11/2018, 17:11
Specialità: Grafico Compositore
Uso: GM:Studio 2
Contatta:

Re: Qual'è il modo migliore per disegnare più rettangoli di diverse dimensioni?

Messaggio da celeste orsa »

Simsure ha scritto:
14/10/2020, 22:01
Ciao Celeste, allora, il primo metodo che hai provato non ha fondamentalmente nessun problema, le performance non sono una cosa di cui devi preoccuparti a certi livelli e chiamare anche 10000 volte draw_rectangle nell'evento draw non è minimamente un problema per Game Maker neanche su computer poco potenti.
L'unico difetto è che potrebbe essere un pelo scomodo per te tenere visivamente in ordine tutti questi rettangoli.

Non riesco a capire bene a quale scopo ti serva avere dei rettangoli e dover avere cosi tante informazioni su di loro, quindi spero di darti comunque un suggerimento che faccia al caso tuo.
Grazie Simsure per aver risposto,
Dunque alla fin fine penso che userò il primo metodo, se come dici tu non è minimamente un problema per le performance. Comunque non ho una grande esigenza per utilizzare altri metodi, ma questo esercizio mi sta aiutando a capire come utilizzare gli array, le ds e, adesso che me le hai citate, anche le structs (sì, le conoscevo ma non le avevo ancora sperimentate). Ma mi interessa soprattutto come utilizzarle all'interno di un ciclo for (che sto cominciando ad utilizzare giusto da una settimana), senza però stare lì a numerare ogni singolo rettangolo o statistica, in modo da non preoccuparmi di cambiare l'ordine ogni qualvolta volessi aggiungere un nuovo dato o elemento.
Simsure ha scritto:
14/10/2020, 22:01
In game maker studio 2.3 c'è una novità estremamente utile, le struct, sono come dei mini oggetti senza eventi, per immagazzinare dati, se hai familiarità con altri linguaggi forse le hai gia sentite, si dichiarano cosi:

Codice: Seleziona tutto

var nome_struct = 
{
   xx : 50,
   yy : 100,
   nome : "giorgino"
}
E come per gli oggetti i valori interni si richiamano come le variabili, quindi

Codice: Seleziona tutto

var nome = nome_struct.nome 
nome_struct.nome = "filiberto"
Ecco la documentazione per saperne di piu : https://manual.yoyogames.com/#t=GameMak ... s%20struct

Per imagazinarli potresti usare una ds_map, un'altra data structure, che è fondamentalmente una list con delle stringhe come indici, cosi come indice puoi usare qualsiasi nome tu voglia e come valore della map ci metti una struct al cui interno metti tutti i dati necessari al rettangolo.
Nel draw ti giri la map e per ogni struct disegni il rettangolo prendendone i dati per nome.
Una cosa del genere

Codice: Seleziona tutto

//NELL'EVENTO CREATE
lista_rettangoli = ds_map_create()
ds_map_add( lista_rettangoli , "rettangolo_1", {xx: 100, yy:200, ww:50, hh:50} )
Documentazione delle map : https://manual.yoyogames.com/#t=GameMak ... maps%20map

Ho provato ad usare le struct per immagazzinare i dati all'interno di una ds_map come mi hai detto, ma non capisco bene come riportare quei dati all'interno di un ciclo for, questo mi ha dato un errore:

Codice: Seleziona tutto

var rect_List = ds_map_create();
ds_map_add( rect_List  , "collision_x", { X1: - 100, Y1: -100, X2: 100, Y2: 100, COLOR: c_red } );
ds_map_add( rect_List  , "collision_y", { X1: - 50, Y1: -50, X2: 50, Y2: 50, COLOR: c_blue } );
				
				
var list_size = ds_map_size (rect_List );						          					

for (var i = 0; i < list_size; i++) 
{
	draw_rectangle_color(
	oDung.x + rect_List [? i, i.X1], oDung.y + rect_List [? i, i.Y1], //x1 y1
	oDung.x + rect_List [? i, i.X2], oDung.y + rect_List [? i, i.Y2], //x2 y2									 
	rect_List [? i, i.COLOR], rect_List [? i, i.COLOR], rect_List [? i, i.COLOR], rect_List [? i, i.COLOR], //color									 
	true);
}
Simsure ha scritto:
14/10/2020, 22:01
Nel tuo ultimo esempio hai scritto che tutto quel blocco di codice lo esegui nell'evento draw, ma in questo modo stai anche dichiarando le liste e tutto il loro contenuto nel draw, l'evento draw non si definisce una volta sola, è come se lo schermo si pulisse ad ogni frame e ciò che è scritto nel draw venisse rieseguito ad ogni frame di gioco, forse è questo a causare il lag di cui parlavi, tutto ciò che riguarda il "definire" i dati va nel create, mentre nel draw vanno solo comandi che appunto iniziano con draw, come draw_rectangle().
Sì, so esattamente che l'evento Draw si ripete in continuazione come un evento Step, ma questo non sembrava causare problemi di prestazioni, quindi per comodità preferivo avere tutto insieme, ma il lag di cui stavo parlando succede solo quando uso gli array, e non sempre, né in continuazione, accade sporadicamente per 1 secondo o 2 solo la prima volta che mostro i rettangoli su schermo, poi non accade più durante il gioco. Inoltre mi è successo anche se inizializzavo l'array in Create usando il ciclo for in Draw. Con le ds invece non ho avuto alcun problema, quindi è strano, per questo ho pensato che fosse un bug...

Avatar utente
Simsure
Membro
Messaggi: 223
Iscritto il: 13/09/2013, 21:54
Specialità: Programmazione
Uso: GM:Studio 2
Località: dietro di te...
Contatta:

Re: Qual'è il modo migliore per disegnare più rettangoli di diverse dimensioni?

Messaggio da Simsure »

celeste orsa ha scritto:
15/10/2020, 14:39
Ma mi interessa soprattutto come utilizzarle all'interno di un ciclo for (che sto cominciando ad utilizzare giusto da una settimana), senza però stare lì a numerare ogni singolo rettangolo o statistica, in modo da non preoccuparmi di cambiare l'ordine ogni qualvolta volessi aggiungere un nuovo dato o elemento.
Posso chiederti a cosa ti serve questa lista di rettangoli? Forse ci sono modi alternativi e piu diretti di ottenere il risultato che ti serve senza definire cosi ciascun rettangolo, in ogni caso se non ti serve "dare un nome" a ciascun rettangolo puoi sempre usare una ds_list invece di una ds_map, cosi li metti dentro semplicemente in fila senza curarti di chi siano.
celeste orsa ha scritto:
15/10/2020, 14:39
Ho provato ad usare le struct per immagazzinare i dati all'interno di una ds_map come mi hai detto, ma non capisco bene come riportare quei dati all'interno di un ciclo for, questo mi ha dato un errore:
Perche le map si scorrono in modo diverso, nella documentazione c'è un esempio.

Codice: Seleziona tutto

var size = ds_map_size(inventory) ;
var key = ds_map_find_first(inventory);
for (var i = 0; i < size; i++;)
{
     //la struct
     var rettangolo = ds_map_find_value(inventory, key)
     
     key = ds_map_find_next(inventory, key);
}
Al contrario delle list non scorri gli elementi col for, ma le chiavi, ossia i nomi che hai dato ai rettangoli, e con quelli accedi poi ai singoli rettangoli, e prima di terminare un ciclo for aggiorni la chiave prendendo la prossima, in modo che il prossimo ciclo prenda l'elemento successivo.
celeste orsa ha scritto:
15/10/2020, 14:39
Sì, so esattamente che l'evento Draw si ripete in continuazione come un evento Step, ma questo non sembrava causare problemi di prestazioni, quindi per comodità preferivo avere tutto insieme, ma il lag di cui stavo parlando succede solo quando uso gli array, e non sempre, né in continuazione, accade sporadicamente per 1 secondo o 2 solo la prima volta che mostro i rettangoli su schermo, poi non accade più durante il gioco. Inoltre mi è successo anche se inizializzavo l'array in Create usando il ciclo for in Draw. Con le ds invece non ho avuto alcun problema, quindi è strano, per questo ho pensato che fosse un bug...
Ma è molto sbagliato comunque e romperà qualsiasi cosa tu debba fare in futuro, ogni frame di gioco stai inserendo dati inutili che gia esistono in una lista.
Se dovessi andare a modificarli durante il gioco non potresti perche a ogni frame tornerebbero quelli originali, ed in ogni caso aggiungendone sempre di piu incorreresti sicuramente in problemi di prestazioni.
Eccetto variabili temporanee non si dichiara mai nulla nel draw, va sempre tutto nel create.
Immagine
Spoiler
Immagine

Avatar utente
celeste orsa
Newbie
Messaggi: 10
Iscritto il: 02/11/2018, 17:11
Specialità: Grafico Compositore
Uso: GM:Studio 2
Contatta:

Re: Qual'è il modo migliore per disegnare più rettangoli di diverse dimensioni?

Messaggio da celeste orsa »

Simsure ha scritto:
16/10/2020, 14:58
Posso chiederti a cosa ti serve questa lista di rettangoli? Forse ci sono modi alternativi e piu diretti di ottenere il risultato che ti serve senza definire cosi ciascun rettangolo, in ogni caso se non ti serve "dare un nome" a ciascun rettangolo puoi sempre usare una ds_list invece di una ds_map, cosi li metti dentro semplicemente in fila senza curarti di chi siano.
I rettangoli rappresentano visivamente le funzioni collision_in_rectangle che sto utilizzando per un oggetto. Sono dei sensori che mi servono per rilevare altri oggetti, tutto qui.
Comunque, questi rettangoli disegnati non saranno mai visibili all'interno del gioco, e una volta sviluppato il gioco, li eliminerò totalmente dal codice. Quindi sono solo punti di riferimento momentanei che visualizzo premendo un tasto on/off. Per quello non voglio riempire il mio evento create con del codice che tanto non esisterà mai nella versione finale del gioco. Ovviamente se usassi le ds per altre ragioni, le inizializzerei in create e poi le ripescherei dove mi serve, ma non è questo il caso.
Non è importante quindi come disegnarli, ma è semplicemente un esercizio per capire bene come utilizzare le ds_map all'interno di un ciclo for. Sarebbe interessante capire come scorrere le "key" come se fossero un array all'interno di un ciclo, senza dovermi però preoccupare di numerare un l'elenco, o di inizializzare un sacco di variabili locali in una ds_list.
Ti ringrazio tantissimo per avermi suggerito di utilizzare le structs... sono eccezionali e credo che le userò spesso! In questo esempio le ho utilizzate per disegnare i rettangoli, numerando un array:

Codice: Seleziona tutto

var rectangle;
					
	rectangle[0] = { X1: - 100, Y1: -100, X2: 100, Y2: 100, COLOR: c_yellow };
	rectangle[1] = { X1: - 20, Y1: -20, X2: 20, Y2: 20, COLOR: c_red };
	rectangle[2] = { X1: - 70, Y1: -70, X2: 70, Y2: 70, COLOR: c_blue };
	rectangle[3] = { X1: - 50, Y1: -50, X2: 50, Y2: 50, COLOR: c_green };
				
var list_size = array_length(rectangle);
				
for (var i = 0; i < list_size; i++) 
{
	draw_rectangle_color(
	oDung.x + rectangle[i].X1, oDung.y + rectangle[i].Y1, //x1 y1
	oDung.x + rectangle[i].X2, oDung.y + rectangle[i].Y2, //x2 y2									 
	rectangle[i].COLOR, rectangle[i].COLOR, rectangle[i].COLOR, rectangle[i].COLOR, //color									 
	true);
}
Però Non sono soddisfatto, perchè sto comunque numerando un array, invece sarebbe grandioso poter fare qualcosa del genere:

Codice: Seleziona tutto

	rectangle["A"] = { X1: - 100, Y1: -100, X2: 100, Y2: 100, COLOR: c_yellow };
	rectangle["B"] = { X1: - 20, Y1: -20, X2: 20, Y2: 20, COLOR: c_red };
	rectangle["C"] = { X1: - 70, Y1: -70, X2: 70, Y2: 70, COLOR: c_blue };
	rectangle["D"] = { X1: - 50, Y1: -50, X2: 50, Y2: 50, COLOR: c_green };
Come vedi, ho semplicemente scritto qualcosa invece di numerarlo, senza neanche inizializzare altre variabili locali.

Simsure ha scritto:
16/10/2020, 14:58
Perche le map si scorrono in modo diverso, nella documentazione c'è un esempio.

Codice: Seleziona tutto

var size = ds_map_size(inventory) ;
var key = ds_map_find_first(inventory);
for (var i = 0; i < size; i++;)
{
     //la struct
     var rettangolo = ds_map_find_value(inventory, key)
     
     key = ds_map_find_next(inventory, key);
}
Sì ho visto il manuale, e stavo cercando di applicare lo stesso metodo, ma non capisco come applicarlo usando una struct. Come faresti a mettere quest'insieme di dati pescandoli da una struct come ho fatto qui?

Codice: Seleziona tutto

for (var i = 0; i < list_size; i++) 
{
	draw_rectangle_color(
	oDung.x + rectangle[i].X1, oDung.y + rectangle[i].Y1, //x1 y1
	oDung.x + rectangle[i].X2, oDung.y + rectangle[i].Y2, //x2 y2									 
	rectangle[i].COLOR, rectangle[i].COLOR, rectangle[i].COLOR, rectangle[i].COLOR, //color									 
	true);
}

Avatar utente
celeste orsa
Newbie
Messaggi: 10
Iscritto il: 02/11/2018, 17:11
Specialità: Grafico Compositore
Uso: GM:Studio 2
Contatta:

Re: Qual'è il modo migliore per disegnare più rettangoli di diverse dimensioni?

Messaggio da celeste orsa »

Simsure ha scritto:
16/10/2020, 14:58
Al contrario delle list non scorri gli elementi col for, ma le chiavi, ossia i nomi che hai dato ai rettangoli, e con quelli accedi poi ai singoli rettangoli, e prima di terminare un ciclo for aggiorni la chiave prendendo la prossima, in modo che il prossimo ciclo prenda l'elemento successivo.
Sono riuscito a trovare una soluzione scorrendo le key della ds map in un ciclo for, il metodo è un po' diverso dall' esempio che ho visto nel manuale, ma è praticamente lo stesso e ho inserito l'operazione che avrei dovuto fare con "if" direttamente tra le parentesi tonde del ciclo, in questo modo:

Codice: Seleziona tutto

var rectangle = ds_map_create();

rectangle[? "A"] = { X1: - 20, Y1: -20, X2: 20, Y2: 20, COLOR: c_yellow };
rectangle[? "B"] = { X1: - 50, Y1: -50, X2: 50, Y2: 50, COLOR: c_red };
rectangle[? "C"] = { X1: - 70, Y1: -70, X2: 70, Y2: 70, COLOR: c_blue };
rectangle[? "D"] = { X1: - 100, Y1: -100, X2: 100, Y2: 100, COLOR: c_green };
rectangle[? ""] = { X1: 0, Y1: 0, X2: 0, Y2: 0, COLOR: 0 };

var last = ds_map_find_last (rectangle);
for (var key = ds_map_find_first(rectangle); key != last; key = ds_map_find_next(rectangle, key))
{
	draw_rectangle_color(
	oDung.x + rectangle[?key].X1, oDung.y + rectangle[?key].Y1, //x1 y1
	oDung.x + rectangle[?key].X2, oDung.y + rectangle[?key].Y2, //x2 y2									 
	rectangle[?key].COLOR, rectangle[?key].COLOR, rectangle[?key].COLOR, rectangle[?key].COLOR, //color									 
	true);
}
Invece di basarmi sul numero totale dell'elenco, ho confrontato le chiavi, il ciclo parte dalla prima chiave e finchè è diversa dall'ultima all'interno dell'elenco, passa a quella successiva.
Ho dovuto aggiungere una chiave vuota alla fine, perchè non poteva disegnare l'ultimo rettangolo della lista.
Dunque, era quello che volevo, e ora l'ordine non è più un numero o una costante in un array, ma un elenco di chiavi che non ho bisogno di numerare.
GRAZIE ancora Simsure, il tuo aiuto è stato fondamentale.

Ultimo aggiornamento:
Il lag che si generava ogni tanto quando usavo gli array, lo faceva perchè stupidamente non avevo inizializzato tutte le voci in create, pensavo di averlo già testato, invece mi sbagliavo... Me lo fa solo se inizializzo un array locale in un evento draw o step o qualsiasi altro evento che viene eseguito in continuazione. Ho fatto lo stesso per la ds_map... ora vorrei capire come funziona il buffer, ma questa è un'altra storia.

Rispondi

Chi c’è in linea

Visitano il forum: Bing [Bot], Google [Bot] e 38 ospiti