Breakout

Descriere generală

Proiectul are ca scop implementarea unui joc arcade de tip Breakout derivat din jocul clasic Pong utilizand un display de Nokia 3310.
Este un tip de joc destul de raspandit fiind usor de inteles si utilizat. Variatii ale acestuia se pot intalni atat pe telefoane cat si online.

Descriere joc

In parte de sus a ecranului se afla un numar de “caramizi”, blocuri ce sunt distruse cu ajutorul unei bile. Bila traverseaza ecranul si ricoseaza din peretii laterali si din peretele superior. Jocul se incheie cu succes in momentul in care toate blocurile sunt distruse. Daca bila atinge peretele inferior al ecranului, jocul este pierdut. Pentru a evita acest lucru jucatorul controleaza un pad situat in partea de jos a ecranului pe care il poate deplasa doar la stanga sau la dreapta. La contactul cu pad-ul bila ricoseaza.

Hardware Design

Schema bloc:

Implementarea hardware utilizeaza placa de baza realizata la etapa I a proiectului. Placa de baza contine un microcontroller ATmega16.




Pentru afisaj se utilizeaza un display de Nokia3310.


Seminificatie pini conform datasheet-ului (vezi resurse [2]):

  • VDD - POSITIVE SUPPLY VOLTAGE, sursa de voltaj (3.3V)
  • SCLK - SERIAL CLOCK LINE, semnalul de ceas de intrare; pana la 4 Mbits/sec
  • SDIN - SERIAL DATA LINE , linia seriala de date de intrare
  • D/C - MODE SELECT, specifica modul de comunicare: va primi date sau va primi comenzi
  • SCE - CHIP ENABLE
  • GND - GROUND
  • VOUT - voltaj de iesire
  • RES - RESET, semnalul reseteaza device-ul si trebuie utilizat la initializare; este activ pe LOW


Se observa ca LCD-ul de Nokia necesita 3.3V dar voltajul generat de ATmega16 este de 5V. Astfel s-a recurs la utilizarea unor divizoare de tensiune pentru fiecare dintre cei 6 pini conectati la microcontroller.


U2 = U1 * R2 / (R1 + R2), unde U2 = 3.3V necesari pentru LCD si U1 = 5V de la ATmega16.
⇒ 3.3*R1 = 1.7*R2 ⇒ (evident) R1 = 1.7K si R2 = 3.3K dar cum nu am gasit decat de 1.8K sau 1.6K am ales rezistente de 1.8K.
Conectare LCD Nokia 3310:

LCD ATMEGA16
1 (VDD) VCC
2 (SCLK) PB7
3 (SDIN) PB5
4 (D/C) PB0
5 (SCE) PB4
6 (GND)
7 (VOUT)
8 (RES) PB6


Controlul asupra pad-ului se realizeaza prin intermediul a doua butoane.

Conform celor precizate mai sus si datasheet-ului pentru ATmega16 (vezi resurse [3]) schema de conectare a componentelor precizate cu microcontrollerul este urmatoarea:



Software Design

Programarea microcontroller-ului este realizata integral in C.
Pentru comunicarea cu Nokia3310 am utilizat driver-ul de pe Quantum Torque cu urmatoarele functii (pe care le-am folosit eu) deja implementate:

  • lcd_init() - initializare LCD
  • lcd_clear() - “sterge” ecranul
  • lcd_goto_xy_exact(int x, int y) - modifica adresa cursorului in functie de x si y
  • lcd_base_addr(unsigned int addr) - seteaza cursorul la adresa addr

De asemenea driverul suporta apelul printf pentru afisarea pe ecran utilizand functiile lcd_chr (afisare caracter) si lcd_str (afisare string).
Pentru testarea in Proteus a fost necesara instalarea separata a librariei pentru display. Am utilizat urmatoarea schema:

Detalii de implementare

Pentru compatibilitatea cu schema proprie am configurat pinii pentru LCD in header-ul driver-ului astfel:

#define LCD_CLK_PIN 	(1<<PB7)
#define LCD_DATA_PIN 	(1<<PB5)
#define LCD_DC_PIN 		(1<<PB0)
#define LCD_CE_PIN 		(1<<PB4)
#define LCD_RST_PIN 	(1<<PB6)
#define LCD_PORT		PORTB
#define LCD_DDR			DDRB


Verificare coliziune bila-bloc
Testul de verificare a coliziunii se apeleaza din functia de desenare a bilei doar atunci cand aceasta se afla in zona blocurilor.

void collision_detection (void) {

	int i;

	for (i = xgl_ball; i < (xgl_ball + 3); i++) 
		if (ball[x_ball][i-xgl_ball] & blocks[y_ball-1][i-1]) {
			//avem coliziune
			nr_blocks --;
			points += 100;

			if (nr_blocks == 0)  //nu mai sunt blocuri in joc
				gameState = 2;
			
			//identificare bloc coliziune
                        //pozitiile relative a blocurilor in cadrul liniei se cunosc
			if ((i-1) < 17) {
                                //se sterge blocul de pe ecran si din memorie (varibila)
				remove_block (7, y_ball);
				return;
			}

			if ((i-1) < 38) {
				remove_block (28, y_ball);
				return;
			}

			if ((i-1) < 59) {
				remove_block (49, y_ball);
				return;
			}

			if ((i-1) < 80) {
				remove_block (70, y_ball);
				return;
			}

			return;
		}
} 


Verificare Game Over
Functia de mai jos este apelata de functia de desenare a bilei cand aceasta se afla pe ultima linie pentru a verifica daca atinge pad-ul sau nu.

void check_end_game(void) {

	//ca sa nu fie end game tb sa fie diferit de 0
	unsigned char res = 0;

	for (int i = xgl_ball; i < (xgl_ball + 3); i++) 
                //verifica daca bila atinge pad-ul
		res |= (ball[x_ball][i - xgl_ball] & pad_line[i]);

	if (res == 0) { //bila nu a atins pad-ul
		gameState = 2; //se incheie jocul
		gameOver = 1; //jucatorul a pierdut
	}
	else { //verificare schimbare directie
		if (xgl_ball >= (x_pad + 4) && xgl_ball <= (x_pad + 6))
			x_ball_dir = 0; //perpendicular
		else 
			if (xgl_ball < (x_pad + 4))
				x_ball_dir = -1; //diagonal stanga
			else 
				x_ball_dir = 1; //diagonal dreapta
		
	}

} 


Desenare
Desenarea pe ecran se face doar atunci cand este necesara si doar intr-o anumita zona. Astfel daca doar bila se misca pe ecran, numai pixelii pentru bila vor fi redesenati. In acest mod functiile pentru desenare s-au complicat (trebuie sa se testeze daca mai e ceva in zona in care desenez pentru a nu-l sterge din greseala) dar s-au eliminat in mare parte acele flickere determinate de lcd_clear() si redesenare integrala.

Rezultate Obţinute

Am obtinut un software functional simplist dar numai in simulare. Partea hardware nu am reusit sa o implementez, conectarea lcd-ului de Nokia s-a dovedit prea meticuloasa pentru aptitudinile mele de lipit. Singura “realizare” in acest domeniu fiind o arsura pe brat. :-D
S-a implementat un singur nivel. Pentru mai multe functionalitati este necesara o memorie mai mare.

In continuare voi prezenta starile prin care trece jocul cu screenshot-uri din simulare.

Pornire program

Se afiseaza un mesaj de intampinare si apoi se asteapta ca utilizatorul sa apese pe un buton pentru a porni jocul.


In joc

Jucatorul controleaza pad-ul din partea de jos a ecranului.



Sfarsit de joc

La finalul jocului se afiseaza un mesaj corespunzator (daca a castigat sau nu) precum si numarul de puncte. Daca s-a incheiat cu succes sunt 1200 de puncte iar daca este game over numarul de puncte variaza in functie de numar de blocuri distruse.



Se asteapta 5 secunde apoi aplicatia se reseteaza.

Concluzii


Proiectul a fost interesant, ma refer la desenarea si comunicarea cu lcd-ul Nokia. Acest lucru l-am realizat insa spre final cand mi-am dat seama ca nu i-am acordat timpul necesar pentru a-l duce pana la capat.

Download

Arhiva de mai jos contine sursele, makefile, schema si libraria pentru Proteus.

333ca_simonastefan_breakout.zip

Contact

Simona Maria Stefan 333CA e-mail: simona.maria.stefan@gmail.com

Bibliografie / Resurse

pm/prj2010/mcarjaliu/simonastefan.txt · Last modified: 2021/04/14 17:07 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0