CHIẾN THẮNG KÌ THI TUYỂN SINH VÀO LỚP 10 THPT MÔN NGỮ VĂN - PHAN THẾ HOÀI (36...
Arcanoid 3D
1. Raffaele De Amicis, Giuseppe Conti
Arkanoid 3D
Relazione del progetto per il corso di Principi di Computer
Graphics
Roberto Zandonati mat. 132945
19 gennaio 2008
1
2. Indice
1 Specifiche del progetto 3
2 Funzionamento 3
2.1 Controllo delle collisioni . . . . . . . . . . . . . . . . . . . . . 4
2.2 Collisione della sfera con un mattoncino . . . . . . . . . . . . 4
2.3 Collisione della sfera con un lato del mondo . . . . . . . . . . 4
2.4 Collisione della sfera con il vaus . . . . . . . . . . . . . . . . . 4
2.5 Collisione di un mattoncino bonus con il vaus . . . . . . . . . 7
3 Trasformazioni 8
4 Matrici e stack 10
4.1 Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5 Geometrie 11
6 Bonus (e malus) 11
7 Aiuti nel gioco 12
8 Gestione eventi 12
8.1 Eventi della tastiera . . . . . . . . . . . . . . . . . . . . . . . 12
8.2 Eventi del mouse . . . . . . . . . . . . . . . . . . . . . . . . . 12
9 UML Class Diagram 13
10 Possibili sviluppi 16
2
3. 1 Specifiche del progetto
Il progetto prende spunto dal noto gioco 2D Arkanoid, estendendolo nel mon-
do 3D.
Per la creazione del progetto, come da specifiche, mi sono basato sulle mie
geometrie e sulle mie matrici per effettuare le trasformazioni.
L’unica eccezzione per quanto riguarda le matrici di trasformazione riguarda
il posizionamento del punto di vista. Per spostarlo infatti ho utilizzato infatti
le trasformazioni di openGl; questo per un fatto di comodit`. a
2 Funzionamento
La classe principale per la gestione del gioco ` la classe GLEventCatcher.
e
Il ruolo di questa classe ` quello di aggiornare tutte le geometrie, ossia la
e
posizione della sfera, la posizione del vaus, la posizione dei mattoncini bonus
colpito e la posizione del mondo di gioco.
Le operazioni principali che questa classe esegue ad ogni operazioni sono:
• posizionamento del mondo utilizzando le funzioni offerte da openGL;
• creazione di un nuovo gioco, se richiesto;
• aggiunta di una nuova sfera, se richiesta;
• disegnare il mondo;
• aggiornare la posizione del vaus in accordo con gli eventi creati dell’u-
tente e mostrarlo a video;
• aggiornare e controllare la posizione delle sfere;
• disegnare i mattoncini;
• eventualmente disegnare il terreno in modo da non far morir le sfere;
• aggiornare il punteggio e le vite;
• aggiornare i valori globali;
• creare un nuovo livello se quello corrente ` stato terminato.
e
All’interno della lista di operazioni sopra elencate, la pi` importante `
u e
senza dubbio l’operazione che aggiorna la posizione delle sfere, in quanto si
devono anche controllare eventuali collisioni, e gestirle di conseguenza.
3
4. 2.1 Controllo delle collisioni
Le eventuali collisioni delle sfere con gli ostacoli presenti nel mondo vengono
controllate dalla procedura checkCollisions() implementata della classe GL-
Sphere.
Le collisioni che possono avvenire sono:
• Collisione della sfera con un mattoncino
• Collisione della sfera con un lato del mondo
• Collisione della sfera con il vaus
L’idea di base per il controllo delle collisioni delle sfere ` quella di con-
e
trollare la distanza tra il centro della sfera e l’ostacolo.
Inoltre ` presente un altro tipo di collisione che ` la collisione di un matton-
e e
cino bonus con il vaus.
2.2 Collisione della sfera con un mattoncino
Per controllare se la sfera ` entrata in collisione con qualche mattoncino
e
effettuo i controlli relativi alla distanza del centro della sfera dal centro di
ogni singola faccia di ogni mattoncino. Affinch` una sfera collida con un
e
mattoncino ` necessario che la sfera entri nel mattoncino.
e
2.3 Collisione della sfera con un lato del mondo
Al contrario di quanto avviene nei controlli precedenti, affinch` una sfera
e
collida con un lato del mondo basta che quest’ultima vi sia molto vicina.
Questo in quanto i movimenti sono dei movimenti discreti e non continui e
quindi non ` possibile far rimbalzare la sfera l’istante esatto in cui questa
e
batte con un ostacolo.
Quindi una sfera rimbalza su un lato del mondo quando ` molto vicina al
e
bordo stesso oppure quando lo supera.
2.4 Collisione della sfera con il vaus
Quando la sfera collide con il vaus, le trasformazioni che devono essere ap-
plicate dipendono dal punto in cui la sfera lo collide.
Se questo punto ` vicino al centro allora viene applicata la riflessione normale,
e
altrimenti se il punto ` vicino al bordo destro o sinistro del vaus viene appli-
e
cata una riflessione sulle coordinate X ed Y, mentre se il punto di collisione
` vicino al bordo superiore oppure inferiore viene applicata una riflessione
e
sulle coordinate Y e Z.
4
5. Algoritmo 1 Collisione sfera con un mattoncino
center = coordinate del centro della sfera
for all b bricks not yet hit do
{Collisione sulla bottom-face di b}
∆x = distanza di center.x dalla coordinata x della bottom face di b
∆y = distanza di center.y dalla coordinata y della bottom face di b
∆z = distanza di center.z dalla coordinata z della bottom face di b
if ∆x ≤ brickW idth and ∆y ≤ brickHeight and ∆z ≤ brickDepth then
2 2 2
collisione sulla bottom face di b
{Collisione sulla front-face di b}
∆x = distanza di center.x dalla coordinata x della front face di b
∆y = distanza di center.y dalla coordinata y della front face di b
∆z = distanza di center.z dalla coordinata z della front face di b
if ∆x ≤ brickW idth and ∆y ≤ brickHeight and ∆z ≤ brickDepth then
2 2 2
collisione sulla front face di b
{Collisione sulla top-face di b}
∆x = distanza di center.x dalla coordinata x della top face di b
∆y = distanza di center.y dalla coordinata y della top face di b
∆z = distanza di center.z dalla coordinata z della top face di b
if ∆x ≤ brickW idth and ∆y ≤ brickHeight and ∆z ≤ brickDepth then
2 2 2
collisione sulla top face di b
{Collisione sulla back-face di b}
∆x = distanza di center.x dalla coordinata x della back face di b
∆y = distanza di center.y dalla coordinata y della back face di b
∆z = distanza di center.z dalla coordinata z della back face di b
if ∆x ≤ brickW idth and ∆y ≤ brickHeight and ∆z ≤ brickDepth then
2 2 2
collisione sulla back face di b
{Collisione sulla right-face di b}
∆x = distanza di right.x dalla coordinata x della right face di b
∆y = distanza di right.y dalla coordinata y della right face di b
∆z = distanza di right.z dalla coordinata z della right face di b
if ∆x ≤ brickW idth and ∆y ≤ brickHeight and ∆z ≤ brickDepth then
2 2 2
collisione sulla right face di b
{Collisione sulla left-face di b}
∆x = distanza di left.x dalla coordinata x della left face di b
∆y = distanza di left.y dalla coordinata y della left face di b
∆z = distanza di left.z dalla coordinata z della left face di b
if ∆x ≤ brickW idth and ∆y ≤ brickHeight and ∆z ≤ brickDepth then
2 5
2 2
collisione sulla left face di b
6. Algoritmo 2 Collisione sfera con un lato del mondo
center = coordinate del centro della sfera
if (| center.x + raggio - worldSize | ≤ 0.1) or (center.x + raggio ≥
2
worldSize
2
)
then
collisione con la right face del mondo
if (| center.x - raggio + worldSize | ≤ 0.1) or (center.x - raggio ≤ − worldSize )
2 2
then
collisione con la right face del mondo
if (| center.y + raggio - worldSize | ≤ 0.1) or (center.y + raggio ≥
2
worldSize
2
)
then
collisione con la right face del mondo
if (| center.y - raggio - worldSize | ≤ 0.1) or (center.y - raggio ≤ − worldSize )
2 2
then
collisione con la right face del mondo
if (| center.z + raggio - worldSize | ≤ 0.1) or (center.z + raggio ≥
2
worldSize
2
)
then
collisione con la right face del mondo
if (| center.z - raggio - worldSize | ≤ 0.1) or (center.z - raggio ≤ − worldSize )
2 2
then
collisione con la right face del mondo
6
7. Algoritmo 3 Collisione sfera con un il vaus
center = coordinate del centro della sfera
vaus = coordinate del centro del vaus
if (center.y-raggio ≤ worldSize + vausHeight) and ((center.x ≥ vaus.x -
2
vausW idth
2
) and (center.x ≤ vaus.x + vausW idth )) and ((center.z ≥ vaus.z -
2
vausDepth
2
) and (center.z ≤ vaus.z + vausDepth )) then
2
if (|center.x - vaus.x| ≤ vausW idth ) and (|center.z - vaus.z| ≤ vausDepth )
4 4
then
Collisione con il vaus nel centro
else
if |center.x - vaus.x| ≥ vausW idth then
4
Collisione sul bordo sinistro o destro
else
Collisione sul bordo superiore o inferiore
2.5 Collisione di un mattoncino bonus con il vaus
In Arkanoid3D per prendere un bonus si deve, una volta colpito, prendere
col il vaus il mattoncino che scender`. Inoltre non ` sufficiente intersecare il
a e
mattoncino bonus con il vaus, ma lo si deve intersecare nel centro, altrimenti
non si avranno i vantatti (o svantaggi) portati dal bonus/malus.
Algoritmo 4 Collisione bonus con il vaus
for all hit bonus brick b do
center = centro di b
vaus = centro del vaus
if ((center.x ≥ vaus.x - vausW idth ) and (center.x ≤ vaus.x + vausW idth ))
2 2
and ((center.y ≥ vaus.y) and (center.y ≤ vaus.y + vausHeight)) and
((center.z ≥ vaus.z - vausDepth ) and (center.z ≤ vaus.z - vausDepth )) then
2 2
colpito bonus brick b
rimuovi b dalla lista dei mattoncini colpiti
7
8. 3 Trasformazioni
La funzione checkCollision() restituisce il lato sul quale ` stata affettuata la
e
collisione ed i valori che restituisce sono ripostati in tabella 1
X, -X Collisione sulle faccia sinistra/destra di un mattoncino
Y, -Y Collisione sulla faccia in alto/in basso di un mattoncino
Z, -Z Collisione sulla faccia in alto/in basso di un mattoncino
BX, -BX Collisione sulle faccia sinistra/destra del mondo
BY, -BY Collisione sulla faccia in alto/in basso del mondo
BZ, -BZ Collisione sulla faccia posteriore/anteriore del mondo
VAUSMIDDLE Collisione con il vaus nel centro
VAUSBORDERX Collisione con il vaus su lbordo superiore o inferiore
VAUSBORDERZ Collisione con il vaus sul vordo destro o sinistro
DIE Collisione con la faccia inferiore del mondo, senza la
presenza del terreno
NONE Nessuna collisione
Tabella 1: Tabella delle collisioni
In base al tipo di collisione devono essere apportate le opputune trasfor-
mazioni, come ` possibile notare nello pseudocodice 5
e
8
9. Algoritmo 5 Riflessioni
collision = checkCollision()
if collision = NONE then
return
stack.pushMatrix(rotationMatrixZ(-angleZ))
stack.pushMatrix(rotationMatrixY(-angleY))
if (| collision | = X) or ((| collision | = BX) and (lastCollision = collision))
then
lastCollision = collision
stack.puskMatrix(scaleMatrix(-1, 1, 1))
if (| collision | = Y) or ((| collision | = BY) and (lastCollision = collision))
then
lastCollision = collision
stack.puskMatrix(scaleMatrix(1, -1, 1))
if (| collision | = Z) or ((| collision | = BZ) and (lastCollision = collision))
then
lastCollision = collision
stack.puskMatrix(scaleMatrix(1, 1, -1))
stack.pushMatrix(rotationMatrixZ(angleZ))
stack.pushMatrix(rotationMatrixY(angleY))
9
10. 4 Matrici e stack
Tutte le classi per la gestione delle matrici si trovano nel package math; e nel-
lo specifico nel package math.matrix2D sono presenti le classi per la gestione
delle matrici e dei vertici nel mondo 2D, mentre nel package math.matrix3D
sono presenti le classi per la gestione delle matrici e dei vertici nel mondo
3D.
Infine la classe GLMath, contenente tutti metodi statici, si occupa della ge-
stione della moltiplicazione di matrici.
4.1 Stack
Lo stack per le geometrie ` implementato nella classe GLMatrixStack, la
e
quale contiene una variabile di tipo java.util.Stack di GLMatrix3D, e tutti i
metodi principali per operare sullo stack, che sono:
• pushMatrix : incerisce una matrice in testa allo stack;
• popMatrix : estrae e restituisce la matrice in testa allo stack;
• getCurrentStateMatrix : restituisce lo stato corrente moltiplicando le
matrici presenti nello stack;
• clearStack : pulisce lo stack.
La funzione principale dello stack ` la funzione getCurrentStateMatrix la
e
quale moltiplica tra loro le matrici nello stack, in un ordine ben specifico.
Se per esempio nell stack sono presenti, partendo dal basso, le matrici m1,
m2, m3 lo stato corrente ` dato da m3(m2*m1).
e
Ci` permette di avere l’ultima trasformazione che si vuole eseguire in ci-
o
ma allo stack, inserendo quindi le trasformazioni nello stack nell’ordine di
esecuzione e non nell’ordine inverso.
10
11. 5 Geometrie
Le geometrie implementate sono tutte nel package geometry.
La classe principale ` l’interfaccia GLBasicGeometry in quanto in questa
e
interfaccia sono presenti i metodi base che tutte le interfaccie devono avere,
che sono:
• display: metodo utilizzato per la visualizzazione a video;
• setCurrentState: metodo per impostare lo stato corrente del mondo
all’oggetto.
Un’altra classe importante per le geometrie ` la classe GLColor la quale ha
e
come compito quello di gestire i colori di una geometria. Questa classe ha
tre variabili, r, g, b che sono rispettivamente i colori rosso, verde e blu.
Importante ` anche la classe GLVertex che ha come compito la gestione di
e
un vertice nel mondo 3D. Questa classe ha un ruolo di primaria importanza
nelle geometrie in quanto tutte le geometrie pi` complesse altro non sono che
u
punti (e nello specifico GLVertex ) collegati tra loro in un determinato modo.
Inoltre la classe GLVertex estende la classe GLColor, questo f` si che il colore
a
non sia associato ad una superficie ma ad un singolo vertice, in modo tale da
ottenere degli effetti grafici piacevoli.
6 Bonus (e malus)
Nel gioco sono anche presenti dei bonus e dei malus.
Quando un mattoncino contenente un bonus oppure un malus viene colpito,
questo cade verso il basso e solamente quando, e se, colpir` il vaus l’effetto
a
del mattoncino avr` luogo.
a
Sia i bonus che i malus sono delle classi che devono essere implementate
estendendo la classe GLBrickBonus e devono essere messe nel package geo-
metry.glBrick.bonusBrick.
Se si vuole implementare un bonus ` necessario semplicemente che la clas-
e
se sovrascriva il metodo updateValues nel quale scrivere le operazioni che
devono essere eseguite se il bonus viene preso, e nel costruttore impostare,
eventualmente, il percorso della texture.
La cosa interessante ` che il programma si accorge automaticamente, al suo
e
avvio, della presenza di un nuovo bonus e quindi allo sviluppatore del nuovo
bonus ` richiesto solamente la creazione di una nuova classe senza che ne-
e
cessiti di metter mano ad altro codice, aumentanto cos` anche il livello di
ı
sicurezza.
11
12. 7 Aiuti nel gioco
Per aiutare l’utente finale nel gioco sono stati inseriti come aiuti delle circon-
ferenze di raggio variabile sui lati del mondo, escluso su quello superiore.
Il raggio di queste circonferenze aumenta se la pallina si allontana, mentre
diminuisce se la pallina si avvicina.
Sulla circonferenza disegnata sul lato inveriore del mondo ` presente anche
e
una linea che indica la direzione della pallina, e questa linea ` tanto pi` corta
e u
quanto maggiore ` l’angolo di rotazione sull’asse Z. Ci` permette di avere una
e o
idea migliore dello spostamento della sfera.
Inoltre ` presente un piccolo trucco che consiste nel riuscire a muovere il vaus
e
anche quando il gioco e‘ in pausa.
8 Gestione eventi
In questa sezione verranno riportate le liste degli eventi che il programma
gestisce.
8.1 Eventi della tastiera
La tabella seguente mostra gli eventi della tastiera che sono gestiti dal gioco:
Pulsante Evento
Spazio Nuovo gioco
A ruota il mondo in senso antiorario
D ruota il mondo in senso orario
W ruota il mondo in avanti
S ruota il monto in indietro
R ripristina il punto di vista
T ricomincia il gioco
Freccia destra muove il vaus a destra
Freccia sinistra muove il vaus a sinistra
Freccia in alto muove il vaus in avanti
Freccia in basso muove il vaus indietro
8.2 Eventi del mouse
Gli eventi del mouse gestiti dal gioco sono invece i seguenti:
• Mouse dragged con il tasto sinistro del mouse: ruota il mondo a destra,
sinistra, avanti, indietro a seconda del delta dello spostamento;
12
13. Figura 1: Class-diagram generico
• Mouse dragged con il tasto destro del mouse: zoom-in se il mouse si
sposta verso il basso, zoom-out se invece si sposta verso l’alto.
9 UML Class Diagram
In figura 1 ` riportato il class diagram generico, mentre in figura 2 ` riportato
e e
il class diagram relativo alle matrici (o trasformazioni) ed in figura 3 quello
relativo alle geometrie implementate.
13
16. 10 Possibili sviluppi
I possibili sviluppi futuri di questo progetto riguardano principalmente la
collision-detection che deve essere raffinata.
Mentre come sviluppi secondari vi ` quella di migliorare l’interfaccia grafica,
e
inserendo delle texture migliori e migliorare l’estetica delle sfere.
16