Arcanoid 3D

310 views

Published on

The project is inspired by the famous 2D game Arkanoid, extending it in the 3D world.

Published in: Education, Travel, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
310
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Arcanoid 3D

  1. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  14. 14. Figura 2: Class-diagram delle trasformazioni 14
  15. 15. Figura 3: Class diagram delle geometrie 15
  16. 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

×