PDA

View Full Version : { Corso: Introduzione alla grafica 2D } by Banglit


Nuitari
01-09-2002, 00:58
In questo primo "tutorial" sulla programmazione grafica non stenderete neanche una linea di codice ma stenderete le basi per programmare una qualsiasi applicazione che faccia uso di grafica 2D o 3D. Innanzitutto occorre conoscere approfonditamente un linguaggio di programmazione, in questi tutorial mi concentro sul C, e avere dimestichezza con il proprio compilatore, sotto sistemi targati microsoft consiglio vivamente Visual C++. Esistono diverse librerie grafiche, alcune potenti altre meno, alcune facili da usare altre mooolto diffcili, alcune portabili su molti sistemi altre no. Un introduzione alle librerie grafiche la farò nel prossimo "capitoletto".

Ora iniziamo con un po' di sanissima teoria.

Immaginate lo schermo come se fosse diviso in tante piccole "caselle". Ognuna di queste caselle è identificata da due valori X ed Y (nella grafica 2D). Questi valori sono come gli assi cartesiani con la differenza che l'asse delle Y è rivolto verso il basso. Così:

------------------------------------> asse x
|
|
|
|
|
|
|
|
^
asse Y.

Ora tutti voi conoscerete quasi sicuramente le "modalità grafiche". Ad esempio: 320x200, 640x480, 800x600, 1024x768 etc. Bene cosa sono questi numeri apparentemente senza senso? Bene immaginate di applicare queste coordiante alle assi cartesiani di prima, cosa ne risulta? Che il valore massimo di X è di 320 e il massimo di Y è di 200 (320x200). Dunque se volessimo "blittare" cioè "disegnare" o stampare un pixel sullo schermo useremo una coordinata X compresa fra 0 e 320 e una coordinata Y compresa fra 0 e 200. Cosa è un pixel? Un pixel è l'entità minima nella grafica 2D. (Un pixel è per capirci un puntino luminoso sullo schermo). Ora sorge spontanea un'osservazione:
come mai nel mio videogioco preferito se "setto" la grafica a 1024x768 vedo tutto al rallentatore?

La risposta è che il gioco richiede più potenza da parte del tuo computer in quanto deve gestire molti più pixel!(1024*768=786432)

Ogni pixel poi ha una cosidetta profondità di colore. La profondità di colore cosa è? Sostanzialmente è "quanti colori può assumere dato pixel". Ad esempio la risoluzione grafica 640x480x256 usa un massimo di 640x480 pixel alla profondità di colore 256. In questa modalità ogni pixel può variare fra 256 "stati" diversi. Ogni stato corrisponde ad un colore differente. Come primo capitoletto direi che può bastare... nel prossimo vi introdurrò ai pregi e ai difetti delle varie librerie grafiche.

Nuitari
01-09-2002, 17:59
Le librerie grafiche, By Banglit

Bene se avete seguito con sufficiente attenzione il primo tutorial non dovreste avere problemi con questo =) Anche in questo tutorial non stenderemo manco una linea di codice... bello eh?

Dunque in ordine cronologico abbiamo la modalità graficha mode 13h. Il mode 13h permetteva di coniugare "prestazioni" e bellezza visiva. Consisteva in una risoluzione di 320x200 a 256 colori visibili contermporaneamente. Il mode 13h è strettamente legato all'hardware della scheda video. Infatti all'epoca (parlo di quasi 10 anni fa) non esisteva uno standard ben preciso e le varie schede video supportavano differenti modalità grafiche. Il mode 13h viene mappato inil mode 13 è mappato in memoria di sistema a partire dall'indirizzo A000:0000 tutti gli altri modi non anno nulla in comune col mode 13. (questo per chi conosce come funziona la RAM di sistema etc.). Molti "newbies" iniziano proprio col mode 13 in quanto consente di accedere "linearmente" alla memoria video.

Per tornare più vicini a noi parliamo delle OpenGL.
OpenGL è nata come base per le applicazioni di computer grafica,inizialmente non godeva di un pieno supporto di tutte le schede video ma solo delle più costose. Le OpenGl (o OGL) sono sempre state molto al passo coi tempi e molte volte hanno anticipato la tecnologia disponibile. Un buon punto di riferimento è il "reedbook" delle OGL un manuale che spiega perfettamente il loro utilizzo. Lo potete trovare su: www.opengl.com
C'è da dire che nonostante la loro tecnologia molto avanzata le OGL sono una sicurezza per il programmatore. Infatti le nuove "release" escono molto lentamente. Magari a distanza di parecchi mesi. C'è inoltre da dire che le OGL sono nate per sistemi UNIX e poi sono migrate sotto i sistemi x86.


Directx.
Le Directx sono un insieme di librerie atte a svolgere ogni compito di un applicazione multimediale. C'è da dire però che le Directx funzionano solo piattaforme Microsoft. Dunque portabilità 0.
Le librerie Directx sono composte da:
Direct3D, è l'API per le funzioni 3D, similmente a OpenGL possiede l'accesso alle funzionalità hardware delle shede;
DirectMusic, consente la riproduzione di brani in formato MIDI;
DirectSound, permette di acquisire/riprodurre campioni audio;
joystick ed altre periferiche;
DirectPlay, supporta lo scambio di dati tra computer (via ethernet, internet, ecc) per il gioco multiplayer;
DirectInput, permette la gestione dell'input dalla tastiera, dal
DirectShow, è l'API che consente l'acquisizione/riproduzione di file multimediali, come video e brani musicali (non MIDI…).

Ultime sono le Allegro.
Le librerie Allegro sono ottime per il principiante in quanto offrono una buona infarinatura per la programmazione con le Directx. Le Allegro coprono tutti gli eventi di un possibile Videogames. Le Allegro possono "wrappare" cioè "interfacciare" anche le modalità grafiche OpenGl e Direct3D. Però sono sconsigliabili se volete realizzare qualche cosa in 3D che debba girare fluido su molti sistemi in quanto sono "precotte". Cioè le funzioni di base della libreria è impossibile modificarle (se non riscrivendone i sorgenti). In questo corso farò particolare riferimento alle Allegro e alle Directx. Inizieremo progettando un giochino con le Allegro ed eseguiremo il suo porting sotto Directx. Le allegro inoltre sono portabili su molte piattaforme (pure sotto UNIX) in quanto esistono diverse versioni della libreria, per tutte le piattaforme. Lo sviluppatore si trova così avantaggiato in caso di porting, basta fare attenzione a dei particolari di programmazione e il porting è bello che fatto =). www.allegro.cc per saperne di più e per scaricare queste librerie.

Con questo è tutto. Nel prossimo tutorial vi spiegherò come si installano le Allegro e come si utlizzano sotto Visual C++ 6.0.

Nuitari
02-09-2002, 14:48
Inizializzazione Allegro, By Banglit

Dunque questo breve tutorial vi spiegherà come utilizzare le librerie Allegro. Bene dopo aver scaricato l'ultima versione delle Allegro da qua:
www.allegro.cc

Unzippatele in una cartella a vostra scelta (consiglio c:\allegro). Dopo aver fatto ciò andate nella cartella dove le avete unzippate e selezionate Vcvars.exe. Dopo aver fatto ciò aprite il Visual C++. Create una nuova "win 32 application" ed aggiungete un file .c. A questo punto clikkate su Projects e poi "settings". Dopo aver fatto ciò selezionate la sezione C/C++ e scegliete "Category Code Generation" e selezionate Debug Multithread Dll (modalità debug) e Multithread Dll (modalità release). Infine andate sulla sezione "link" e sotto "Object/Library Modules" aggiungete prima di qualsiasi altra libreria "alleg.lib". (NB! Aggiungete alleb.lib sia in modalità debug che in modalità release). Dopo aver fatto ciò dal menu build selezionate "Set Active Configuration" e scegliete la modalità Release. Questo perchè avrete il file .exe di dimensioni ridotte e privo di codice praticamente inutile. Benissimo abbiamo installato correttamente le allegro. Ora possiamo passare a un po' di sanissimo codice =)

Prima però dobbiamo creare una immagine bitmap. Aprite paint e disegnate qualche cosa e salvatela nella stessa cartella in cui viene compilato il vostro progetto (non in release non in debug nella cartella principale) poi dovrete modificare il codice e dove c'è scritto tuabmp.bmp dovrete mettere il nome che avete usato voi =) Ricordate l'estensione!!! E' importante!!!!

#include <allegro.h>
#include <winalleg.h>

main()
{

PALETTE pal;
BITMAP *prova;

allegro_init(); //Inizializza Allegro
install_keyboard(); //Inizializza tastiera

//Modalità grafiche
set_color_depth(16);
set_gfx_mode(GFX_DIRECTX, 640, 480, 0, 0);

prova=load_bitmap("tuabmp.bmp", pal);

masked_blit(prova, screen, 0,0, 10, 20, prova->w, prova->h);
readkey(); //Attende pressione di un tasto

destroy_bitmap(prova);
allegro_exit();
}
END_OF_MAIN();

Dunqueeee passiamo a spiegare pezzo per pezzo questo pataccone di codice =)

#include <allegro.h>
#include <winalleg.h>

"Dice" al compilatore di includere i file .h allegro e winalleg

PALETTE pal;
BITMAP *prova;

PALETTE dichiara un tipo di variabile (una struttura) atta a contenere la palette dei colori.
L'altra riga serve per dichiarare "prova" come un immagine.

allegro_init(); //Inizializza Allegro
install_keyboard(); //Inizializza tastiera

Queste due righe parlano da sole =)

set_color_depth(16);
set_gfx_mode(GFX_DIRECTX, 640, 480, 0, 0);

Dunqueee set_color_depth(16); Dichiara la profondità di colore a 16 bit. Si può configurare a 8, 16,24 o 32 bit questo valore. Ovviamente per un gioco in 2D il valore ideale è 16. Anche se 8 non è malaccio =).
L'altra riga set_gfx_mode(GFX_DIRECTX, 640, 480,0,0); serve per dichiarare di voler usare la modalità grafica Direct a 640x480. Visto che noi vogliamo usare le allegro come "interfaccia" per le directx questa modalità è perfetta =).

prova=load_bitmap("tuabmp.bmp", pal);

masked_blit(prova, screen, 0,0, 10, 20, prova->w, prova->h);
readkey(); //Attende pressione di un tasto

la prima riga assegna a prova l'immagine "tuabmp.bmp". pal è la struttura nella quale verranno memorizzati i colori dell'immagine. E' obbligatorio inserirla.

la seconda istruzione invece "blitta" cioè stampa sullo schermo l'immagine prova alle coordinate 10 x e 20 y. Di dimensioni: prova -> w = prova widht e prova->h = prova height. Cioè prova->larghezza e prova->altezza. In alternativa si può usare

blit(prova,screen, 0,0, 10, 20, prova->w, prova->h);

però non utilizzerà le trasparenze. Cioè il colore viola chiaro verrà stampato al posto che essere usato come colore di trasparenza come accade con masked_blit.

Da notare lo screen sempre posto dopo l'immagine da stampare. Possiamo immaginare come:
masked_blit(immagine, dovelastampo etc...)
Infatti le Allegro gestiscono lo schermo come una immensa bmp.

readkey();
penso parli da solo =) Procede con l'esecuzione del programma solo se un tasto viene premuto.

destroy_bitmap(prova);
allegro_exit();
}
END_OF_MAIN();

la prima istruzione serve per "scaricare" dalla memoria lo spazio occupato da "prova". La seconda istruzione invece determina la chiusura delle chiamate alla libreria allegro.
In fondo si può notare END_OF_MAIN(); questo è il pegno da pagare per utilizzare il vecchio main(); è obbligatorio aggiungere END_OF_MAIN(); alla fine di ogni funzione main.

Bene con questo è tutto =) Spero di essere stato abbastanza chiaro in questo tutorial.

Nuitari
03-09-2002, 12:37
Input da mouse e tastiera. Uso del video buffer, by Banglit

Dunque in questo tutorial imparerete a gestire l'input da parte dell'utente da tastiera e mouse e ad usare il cosi detto backbuffer.

Immaginate il backbuffer come una sorta di "lavagna" grande quanto lo schermo. Su questa lavagna possiamo disegnare ciò che vogliamo e solo quando vogliamo la "blittiamo" cioè stampiamo sullo schermo. Ovviamente capite anche da soli la sua grande utilità! Possiamo creare scene piene di immagini nel "caricamento" del livello ad esempio. Mi seguite? Possiamo creare moltissime illusioni grafiche ma questo sta alla vostra fantasia =) Io vi spiegherò solo come si inizializza e come si usa. Niente altro =).

Dunqueee partiamo però dall'input da tastiera il più facile da gestire =).

#include <allegro.h>
#include <winalleg.h>

main()
{

PALETTE pal;
BITMAP *test, *buffer;

int x,y;

/*Inizializzazioni */
allegro_init();
install_keyboard();
/* Fine inizializzazioni */

/* Modalità grafica */
set_color_depth(16);
set_gfx_mode(GFX_DIRECTX, 640, 480, 0, 0);
/* Fine modalità grafica */

/*Creazione buffer */
buffer=create_bitmap_ex(16,640,480);
/* Fine buffer */

test=load_bitmap("test.bmp", pal);

x = 10;
y = 10;

while (!key[KEY_ESC])
{

if (key[KEY_UP]) y--;
if (key[KEY_DOWN]) y++;
if (key[KEY_LEFT]) x--;
if (key[KEY_RIGHT]) x++;

masked_blit(test,buffer,0,0,x,y,test->w, test->h);

masked_blit (buffer,screen,0,0,0,0, buffer->w,buffer->h);
clear(buffer); //Pulisce il buffer


}
return 1;
}
END_OF_MAIN();

Questa linea di codice:
buffer=create_bitmap_ex(16,640,480);

Dice che la "buffer" conterrà una bitmap grande 640x480 ad una profondità di colore pari a 16bit. Facile no? E' importante che le dimensioni del buffer siano uguali a quelle dello schermo però... non in tutti i casi =) Infatti con dei piccoli accorgimenti che vi spiegherò più avanti è possibile realizzare uno scrolling super-fluido =)

Le linee:
x = 10;
y = 10;

Non serve neanche commentarle =)

while (!key[KEY_ESC])
{

if (key[KEY_UP]) y--;
if (key[KEY_DOWN]) y++;
if (key[KEY_LEFT]) x--;
if (key[KEY_RIGHT]) x++;

Bene questo è il cosidetto "main loop" di un videogame" cioè il ciclo di vita del gioco. Nel quale viene mosso "l'eroe" e gestito l'intero gioco. In questo caso il gioco termina quando abbiamo premuto ESC. Come potete notare i cicli If incrementano la variabile X e Y se il movimento è verso il basso o verso destra. E decrementano X e Y se il movimento è verso l'alto o verso sinistra. Questo per il famoso sistema di assi cartesiane che vi ho spiegato la volta scorsa =). Beh al posto di KEY_UP potete mettere qualsiasi altro tasto tipo: KEY_F12 o KEY_A etc. In questo modo potrete gestire la tastiera al meglio.

masked_blit (buffer,screen,0,0,0,0, buffer->w,buffer->h);
clear(buffer); //Pulisce il buffer

La prima linea di codice stampa il buffer sullo schermo e lo rende effettivamente visibile. La seconda riga invece pulisce il buffer in modo da poterci "riscrivere" sopra al prossimo ciclo. Spero di essere stato abbastanza chiaro sul backbuffer e sulla gestione della tastiera =). Ora vi farò un esempio rapido rapido sull'uso del mouse =)

#include <allegro.h>
#include <winalleg.h>

main()
{
PALETTE pal;
BITMAP *buffer, *test;

allegro_init();
install_mouse();
install_timer();
install_keyboard();

set_color_depth(16);
set_gfx_mode(GFX_DIRECTX, 640, 480, 0, 0);

test = load_bitmap("test.bmp", pal);

set_mouse_sprite(test);

buffer=create_bitmap_ex(16,640,480);

while (!key[KEY_ESC])
{
show_mouse(buffer);

masked_blit (buffer,screen,0,0,0,0, buffer->w,buffer->h);
clear(buffer);

}
return 1;
}
END_OF_MAIN();

Input da mouse e tastiera. Uso del video buffer.
Questo esempio "muove" l'immagine test.bmp sullo schermo tramite mouse. Analizziamo linea per linea =) Buona norma è "mostrare" il mouse sempre sul buffer in modo che venga poi stampato sullo schermo.

install_mouse();
install_timer();

Queste due linee di codice servono per inizializzare il mouse e i timer. I timer sono fondamentali per il funzionamento del mouse. Li vedremo in maniera più approfondita più avanti. Sappiate che rilevano ogni "tot" di tempo la posizione del mouse.

set_mouse_sprite(test);

Questa linea di codice fa in modo che il "cursore" del mouse sia l'immagine contenuta in "test".

show_mouse(buffer);

Questa linea di codice "mostra" il mouse sul buffer. Possiamo limitare il mouse a una singola bmp. Ad esempio se creiamo una bmp di dimensioni 32x32 possiamo "relegare" il mouse laddentro. Basta fare:

show_mouse(BITMAP);

Ora se vogliamo fare in modo di rilevare la pressione di uno dei tasti del mouse basta fare:

if (mouse_b & 1)
{
evento
}

Questo rileva la pressione del tasto sinistro del mouse

if (mouse_b & 2)
{
evento
}
Questo rileva la pressione del tasto destro del mouse

if (mouse_b & 3)
{
evento
}

Questo rileva la presisone del tasto centrale del mouse.

Altre variabili utili sono:
mouse_x = posizione x del mouse
mouse_y = posizione y del mouse
mouse_z = posizione della rotella del mouse se presente.

Queste variabili vengono "rinfrescate" ogni tot di tempo. Se volete fare un controllo super-preciso basta fare:

poll_mouse();

Questo "aggiornerà" quando volete voi la posizione x , y e z del mouse.

Bene con questo è tutto =) Spero di essere stato sufficientemente chiaro. In caso contrario non esistate a chiedere.

Nuitari
06-09-2002, 11:59
La gestione dei Midi, by Banglit

Ordunque visto che mi sono fioccate parecchie richieste su ICQ sull'uso dei midi facciamo questo piccolo "escursus".

Ecco un piccolo esempio di uso dei MIDI:

#include <allegro.h>
#include <winalleg.h>

allegro_init();
install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT, NULL);

MIDI *test;

main()
{
test = load_midi("nomemidi.mid");

play_midi(test, 0);
readkey();

destroy_midi(test);

return 1;
}
END_OF_MAIN();

Dunque ovviamente dovete avere un file "nomemidi.mid" ma questo credo sia superfluo spiegarvelo =)
Dunque:

install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT, NULL);
Vuol dire che inizializza il sonoro sulla shceda audio che "prenderà" la briga lui di cercare. Il "NULL" ormai è inutile e va mantenuto solo per avere una sorta di compatibilità con le vecchie versioni delle Allegro.

MIDI *test;
Dichiara test come struttura atta a contenere i MIDI.

test = load_midi("nomemidi.mid");
Assegna a test il midi "nomemidi.mid".

play_midi(test, 0);
Questo comando invece riproduce il midi contenuto in "test" per 0 volte. Cioè all'infinito. Se avessimo messo 1 al posto di 0 lo avrebbe riprodotto una sola volta e così via.

destroy_midi(test);
Questo comando fa sì che la memoria occupata da "test" venga liberata.
Esistono una infinità di comandi per la gestione dei MIDI, questi sono solo quelli basilari. Per appofondimenti controllate il file di help fornito con le allegro.

Nel prossimo articolo inizieremo gli argomenti un po' complicati: GESTIONE DELLE COLLISIONI =)

Nuitari
27-10-2002, 22:45
Gestione delle collisioni con la tecnica del bounding box.

Dunque in questo tutorial imparerete a gestire le collisioni con la tecnica del bounding box (d'ora in poi BB). Avete presente quando create un immagine? Questa viene racchiusa da un rettangolo (i bordi). La tecnica del BB consiste nel rilevare se un punto qualsiasi del perimetro di questo rettangolo tocca con il perimetro di un altro rettangolo. Semplice no? Ordunque per realizzare ciò di che cosa abbiamo bisogno? Delle cooordinate x ed y e della lunghezza e larghezza dell'oggetto.

immagine->w = dimensione width cioè larghezza
immagine->h = dimensione height cioè altezza

Questa è la sintassi usata dalle allegro per trovare questi due valori. Potremmo benissimo usare le dimensioni senza questa dicitura ma è mooolto conveniente. Infatti non serve che controlliamo ogni immagine.

Facciamo un piccolo esempio di codice:

if ((imagex+image->w>image2x) && (imagex<image2x+image2->w) && (imagey+image->h>image2y) && (imagey<image2y+image2->h))
{
}

Bene ora se ci ragionate troverete il sopra citato pezzo di codice moooolto semplice. Infatti prendete pure un pezzo di carta e una penna. Disegnate due quadrati o rettangoli che si "scontrano" in questo modo (scusate per il disegno a dir poco schifoso):

----- ####
| | # # Prima della collisione (1° stato)
| | # #
----- ####

----####
| # # Durante la collisione (2° stato)
| # #
----####

---####
| #| # Collisione finita (3° stato)
| #| #
---####

Bene nel 1° stato non c'è alcun tipo di collisione. Nel 2° stato invece c'è una collisione o meglio alcuni pixel di figura "-" tangono i pixel di figura "#". Bene al 3° stato NON dovete MAI arrivare in quanto verrebbe a crearsi un effetto veramente spiacevole. Voi dovete fare in modo che le due immagini non si sovrappongano mai. Però in alcuni casi può rivelarsi utile far passare un immagine sopra ad un altra. Ad esempio:

L'impavido eroe dopo aver saccagnato miriadi di mostri deve prendere la chiave.

e

L'impavido eroe dopo aver preso la chiave cade in una trappola rappresentata da un tile del terreno.

Nel primo caso si può arrivare fino al 2° stato infatti la chiave poi scomparirà (salvo diverso gameplay) e non si veranno a creare spiacevoli effetti "collaterali". Nel secondo caso invece visto che la collisione riguarda un tile del terreno (in giochi con visuale dall'alto) si può benissimo fare in modo che le due immagini si "sovrappongano" durante la collisione. Ufff quanta teoriaaa!!! Ora però passiamo ad analizzare ogni frammento del codice =P

if ((imagex+image->w>image2x)

ordunque qua si va a controllare se la somma della coordinata x e la larghezza dell'immagine (width = larghezza) è maggiore alla coordinata x dell'immagine numero 2. Poi però...

&& (imagex<image2x+image2->w)

si controlla anche se la coordinata x (imagex) dell'immagine 1 è minore alla somma fra la coordinata x di immagine 2 e la sua larghezza.

Stesso discorso per il resto della condizione =) Al posto che x però è y.

Da notare che la gestione delle collisioni funziona solo se tutte le condizioni sono vere!
Spero di essere stato completo =D. Nel prossimo mini-tutorial parlerò di... di... "tocchi di classe per i propri videogiochi" tipo: "funzioni per catturare le schermate" e altre belle cosette =D

Nuitari
01-11-2002, 08:29
Chiccherie varie da usare nelle proprie creazioni.

Bene ecco un po' tutte le features che spiegherò come utlizzare nei propri lavori:

1) Catturare uno screenshot
2) Funzioni di output sullo schermo con caratteri
3) Fare in modo che la pressione di un tasto del mouse non sia ripetuta

###########################################
1) Catturare uno screenshot
Bene avete presente le funzioni presenti nei vari videogiochi in grado di "catturare" la

schermata e salvarla in un file esterno in modo da poterla rivedere quante volte si vuole. Bene

non ci crederete ma con le allegro fare ciò è VERAMENTE semplice.

save_bitmap("screen.bmp", buffer, pal);

Bene save_bitmap è la funzione che ci permette ciò e i suoi argomenti sono:
"screen.bmp" = nome immagine che verrà salvata sul disco fisso
buffer = "bitmap" da salvare sul disco fisso
pal = palette di colori. Teoricamente è quasi inutile porlo se siete in modalità 16bit ma è

considerato errore se non lo mettete.
Ora fare in modo che solo a determinati eventi accada è molto semplice. Es a pressione del tasto

F12:

if (key[KEY_F12])
{
save_bitmap("screen.bmp", buffer, pal);
}
-------------------------------------------

2) Funzioni di output sullo schermo con caratteri
Un' altra cosa veramente utile è far apparire a schermo alcune informazioni sullo stato del gioco

con caratteri. Ad esempio possiamo eseguire il debug della posizione x o y di un oggetto e farla

apparire durante l'esecuzione dell'applicazione. Es:


textprintf(buffer, font, 20, 5, makecol( 35 , 125 , 87 ), "Quello che vuoi");

Facendo ciò si andrà a "scrivere" sul buffer alla posizione 20x e 5y e con colore RGB 35 Red, 125

Green e 87 Blu. Ciò che scriveremo sarà "Quello che vuoi" con colore pari alla miscela fra i 35

Red, 125 Green e 87 Blue. Ora immaginate di avere una variabile che contenga la posizione x di un

oggetto. La variabile sarà "obj_x" di tipo intero. Vogliamo fare apparire questa coordinata in

alto. Bene.

textprintf(buffer, font, 20, 5, makecol( 35 , 125 , 87 ), "X=%d", obj_x);

ora vedremo che apparirà effettivamente il valore della coordinata X. Bene ora potete mettere ciò

in un ciclo del genere:

while (!key[KEY_ESC])
{
funzione_di_modifica_coordinata_x();
textprintf(buffer, font, 20, 5, makecol( 35 , 125 , 87 ), "X=%d", obj_x);
}

dove funzione_di_modifica_coordinata_x(); è il sistema che regola l'incremento o il decremento di

tale variabile. Vedrete che il valore in alto aumenterà o decrementerà in base alla posizione

dell'oggetto. Ovviamente dovete fare in modo che obj_x sia in relazione con l'oggetto. Ma questo

sapete già farlo dal tutorial precedente.

IMPORTANTE!
Vi sconsiglio vivamente di usare questa funzione (textprintf()) in versioni "stabili" del vostro

gioco o meglio in versioni aperte al pubblico. Infatti textprintf() può creare problemi se lo

usate per far apparire chessò dati di gioco tipo "vita, munizioni etc." è consigliabile usare

immagini o sprite. Non temete più avanti vi spiegherò come si fa. Per adesso potete anche usarlo

ma il mio consiglio è di usarlo SOLO a scopo di debugging.

3) Fare in modo che la pressione di un tasto del mouse non sia ripetuta
Dunque mettiate questo caso: volete che quando l'utente prema il tasto del mouse non venga

continuamente rilevato il suo stato. Cioè provate a fare questo:

if (mouse_b & 1)
{
una_variabile++;
}

volete che al click del mouse la variabile incrementi di 1. Però se tenete premuto per + di 1ms

cosa succede? Ogni 1ms la variabile incrementa!!! Una cosa veramente fastidiosa... ma... non

abbiae paura =D Esiste un trucchetto semplice semplice che vi permette di ovviare a ciò. Basta

"creare" una variabile di controllo. Se il pulsante è premuto la variabile assume valore 0 e

dunque "interrompe" il click. Esempio:

if (!(mouse_b & 1)) flag = 1;

if (mouse_b & 1 && flag == 0)
{
una_variabile++;
flag = 0;
}

Ed eccovi che farà un solo click. Flag è una variabile di tipo intero.

Nuitari
11-11-2002, 19:19
I Tiles, By Banglit

Bene siete giunti pressochè in fondo a questa mia serie di tutorial. Già... sono quasi finiti... infatti dopo di questo ne scriverò un altro solo. Vabbe' bando alle ciance!

Dunque dovete sapere che i programmatori (quelli veri non quelli come me ;) ) si semplificano la vita nella grafica 2D dividendo lo schermo in tante piccole "parti". Queste parti prendono il nome di "tile". Ora immaginiamo che la nostra immagine sia di dimensioni 32x32. Bene allora dovremmo dividere sia la coordinata x e la coordinata y per questo valore. Dunque prendendo come esempio la risoluzione grafica 640x480:

640 -> 20 tiles
480 -> 15 tiles

Bene ora sappiamo che possiamo avere 15 tiles in verticale e 20 in orizzonatle. Bene ora proviamo a pensare... 20x15 tiles... che potremmo utilizzare per contenerli???
Io opto per un array bidimensionale anche se ci sono altre strade. Questa è sicuramente la migliore.

char mappa[15][20];

mappa è una matrice (array) bidimensionale. Perchè un char? Semplice perchè in questo modo si risparmia memoria =D. In un giochetto semplice semplice 255 tile sono più che sufficienti per ogni nostro livello. Infatti non ci serviranno certo migliaia di tiles!

Ora facciamo un array di puntatori a BITMAP:

BITMAP *tiles[num_tiles];

e si procede a caricarle una ad una:

tiles[0]=load_bitmap(...)


Bene ora prendiamo come esempio una piccola matrice di 2x2.

int mappa[2][2] = {{0,0},
{5,1}};

Bene ora vediamo che nella prima riga non si va a creare nulla mentre nella seconda si "posiziona" l'elemento 5 dell'array "tiles" nella mappa. Stessa cosa per l'elemento 1. Ora si pone un piccolo problema... come facciamo a riempire lo schermo con la nostra bella mappa??? Semplice!!!

for(y=0; y<15; y++) {
for(x=0; x<20; x++)
{
blit(tiles[mappa[y][x]], screen, 0, 0, x*32, y*32, 32, 32);
}
}

questo ciclo non fa altro che blittare ogni immagine contenuta nell'array sullo schermo fino a che y non è uguale a 15 (num max di colonne) e x è uguale a 20 (num max "righe").

Spero di essere stato chiaro su un argomento abbastanza complesso come questo. Beh vi lascio al prossimo tutorial poi...

Si inizierà a programmare un VERO gioco assieme!!!! Eggià l'introduzione triste era fatta volutamente!!! Infatti questo è il penultimo tutorial della serie d'introduzione poi c'è tutta la serie riguardante la programmazione vera e propria del gioco!!!

Nuitari
28-11-2002, 23:02
Compilare le Allegro sotto Linux, by Banglit

Dunque avete installato il sistema del pinguino e ora volete sviluppare i vostri bei giochini ma.... accidenti quanto è complicato compilare le allegro per Linux! Dunque andate sul sito: www.allegro.free.fr e scaricate la versione compressa (.tar.gz). A questo punto (da utente root) scompattatelo in una cartella a vostra scelta. Es:

tar zxvf allegro.tar.gz (il nome allegro varia a seconda della versione io ho messo solo la radice del nome )

dopo che ha scompattato vi ritroverete con la cartella "allegro". Entrare e scrivete (sempre come root):

chmod +x fix.sh

seguito da:

./fix.sh unix

appena avrà finito scrivete:

./configure

aspettate un paio di minuti (il tempo che finisca) e scrivete:

make

appena ha finito di compilare l'universo et oltre fate:

make install

dopo n'altra botta di tempo avete le vostre allegro belle che compilate. Se usate la mandrake 8.2 riceverete un errore alla fine del make install! Dovete ovviare a questo inconveniente editando il file contenuto nel path indicato dalle allegro inserendo il path indicato sempre dalle allegro. A questo punto rifate make install

Ora per compilare un file creato con allegro basta fare:

gcc main.c -o main `allegro-config --libs`

notate i caratteri ` non sono '. Potete farli premendo alt + ?. Altrimenti vi darà una caterba di errori!

Se ho scritto qualche incorrettezza e/o errori siete pregati di inviarmi una mail a:

banglit@jumpy.it

o un msg di icq a: 126807755.

Aloha =D