Zoom HTML5 Template by templatemo.com Product Services About Contact Company Intro Testimonials

Download

Igra 3D tetris Vam pruža nezaboravno iskustvo stavljajući dimenzije i iskustvo igranja tetrisa na višu razinu! Igra je apsolutno besplatna i dostupna putem sljedeće poveznice.

Market

Ovaj projekt je u potpunosti open source, te ga možete preuzeti na GitHub-u putem ove poveznice.

Market Market

Multimedija


prtscreen prtscreen prtscreen prtscreen

univ.bacc.inf. Domić Krunoslav

Student Fakulteta organizacije i informatike Sveučilišta u Zagrebu, Diplomski studij informatike, smjer Informacijsko i programsko inženjerstvo
(kontakt: kdomic@foi.hr)

univ.bacc.inf. Knežević Matija

Student Fakulteta organizacije i informatike Sveučilišta u Zagrebu, Diplomski studij informatike, smjer Informacijsko i programsko inženjerstvo
(kontakt: mknezevi1@foi.hr)

Kontakt podaci

FOI, Pavlinska 2, Varaždin, Croatia

Krunoslav Domić - kdomic@foi.hr

Matija Knežević - mknezevi1@foi.hr

Dokumentacija

Tehničke specifikacije

Zahtjev za pokretanje: Android OS 2.2 i više

Aplikacija razvijena pod: Windows OS i Linux OS

Razvojno okruženje: Eclipse

API: OpenGL ES 1.1 i Android ADK

Dodaci razvojnom okruženju: android-support-v7-appcompat

Testna okolina: Genymotion

Diagram igre

Slika Slika

Objašnjanje realizacije

Za potrebe izrade ove igre kreirali smo nekoliko specijaliziranih algoritama kako bismo uspjeli realizirati cjelokupnu logiku igre. Značajniji algoritmi koji su kreirani su sljedeći:

  • Algoritam za kreiranje i iscrtavanje objekata
  • Algoritam za rotaciju objekata
  • Algoritam za detekciju kolizija
  • Algoritam za poništavanje redova

Algoritam za kreiranje i iscrtavanje objekata
Za pohranjivanje i iscrtavanje objekata u našem programu koristi se trodimenzionalna bool matrica. Kako bi se definirano novi objekt u programu sve što je potrebno napraviti je kreirati trodimenzionalnu kvadratnu matricu i popuniti je s bool vrijednostima (true ili false). Sukladno toj matrici algoritam će iscrtavati objekte na ekran.

Algoritam za rotaciju objekata
Za rotaciju objekata nije korištena nativna funkcija od OpenGl-a. Budući da su svi objekti napravljeni u matričnoj reprezentaciji rotacija objekata se vrši na tako da se trodimenzionalna matrica zarotira po određenoj osi.

Algoritam za detekciju kolizija
Budući da svi objekti u igri imaju matričnu reprezentaciju detekcija kolizija se vrši upravo pomoću njih. U igri osim matrice za svaki objekt postoje i dvije globalne matrice koje reprezentiraju stanje igre. Jedna globalna matrica je tipa bool i predstavlja zauzetost ploče, dok druga globalna matrica je tipa string te sadrži informaciju o boji zauzetog polja. Jednostavnom primjenom logičkih usporedbi globalnih matrica i matrica objekata dolazimo do algoritma za detekciju kolizije objekata.

Algoritam za poništavanje redova
I na kraju kreiran je algoritam za poništavanje redova koji u svakom ciklusu provjerava da li u nekoj matici postoji red da je u potpunosti popunjen, te ako postoji uklanja ga.

Dijelovi programskih kodova za algoritme biti će navedeni u nastavku.

Detekcija prstiju

Za interakciju korisnika s igrom koristili smo mogućnost detekcije pritiska. Naime, ako korisnik s jednim prstom prođe po ekranu u jednom od smjerova (gore, dolje, lijevo, desno) objekt se pomiče sukladno odabranom.
Ako korisnik prođe s dva ili tri prista po ekranu objekt se rotira sukladno gesti.
Dok ako korisnik napravi dupli klik po ekranu objekt se spušta na najnižu moguću razinu. Kod ove implementacije zanimljivo je pogledati matematičko određivanje smjera pomaka prstiju koje se određuje pomoću algoritma u nastavku.

   public int detectDirection(float xFirst, float yFirst, float xSecond, float ySecond) {
        int rez = 0;
        int limit = 50;
        try {

            float diffY = ySecond - yFirst;
            float diffX = xSecond - xFirst;
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) < limit)
                    return 0;  //noSwipe
                if (diffX > 0) {
                    return 1; // onSwipeRight();
                } else {
                    return 2; // onSwipeLeft();
                }
            } else {
                if (Math.abs(diffY) < limit)
                    return 0;
                if (diffY > 0) {
                    return 3; // onSwipeBottom();
                } else {
                    return 4; // onSwipeTop();
                }
            }

        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return rez;
   }    

Dijelovi programskog koda

Primjer oblikovanja objekta: Prikazan je primjer oblikovanja objekta L. Pritom su realizirane dvije različite implementacije. Prva implementacija je zakomentirana i ona se sastoji od kreiranja složenog objekta (objekta L) od niza kockica (objekta klase Cube) koje se translatiraju i iscrtavaju kako bi dale traženi složeni objekt. Druga implementacija je optimizirana i sastoji se od matrične reprezentacije objekta. Tu matričnu reprezentaciju prima metoda drawObject() koja potom iscrtava objekt, na gore opisan način, a ovisno o datoj matričnoj reprezentaciji

        String color = "#1D1DE7";

	boolean objectMatrix[][][];

	public ObjectL() {
		objectMatrix = createFalsMatrix(3);
		objectMatrix[0][0][0] = true;
		objectMatrix[0][0][1] = true;
		objectMatrix[0][0][2] = true;
		objectMatrix[1][0][0] = true;
	}

	@Override
	public void draw(GL10 gl) {
		drawObject(gl, objectMatrix, color);
		/*gl.glPushMatrix();
		Cube c = new Cube(color);
		gl.glTranslatef(1, 0, 0);
		c.draw(gl);
		gl.glTranslatef(-1, 0, 0);
		c.draw(gl);
		gl.glTranslatef(0, 0, 1);
		c.draw(gl);
		gl.glTranslatef(0, 0, 1);
		c.draw(gl);
		gl.glPopMatrix();*/
	}
                                    

Metoda za crtanje objekata: Kako je već gore opisano metoda drawObject iscrtava složeni objekt zadan njegovom matričnom reprezentacijom

                public void drawObject(GL10 gl, boolean objectMatrix[][][], String color){
		gl.glPushMatrix();
		Cube c = new Cube(color);
		for (int i = 0; i < objectMatrix.length; i++)
			for (int j = 0; j < objectMatrix.length; j++)
				for (int k = 0; k < objectMatrix.length; k++)
					if(objectMatrix[i][j][k] == true){
						gl.glPushMatrix();
						gl.glTranslatef(i, j, k);
						c.draw(gl);
						gl.glPopMatrix();
					}
		gl.glPopMatrix();
                }                    
                                    

Metode za rotaciju objekata

      public boolean[][] rot(boolean[][] a) {
		boolean rotatedMatrix[][] = new boolean[a.length][a.length];
		for (int i = 0; i < a.length; i++)
			for (int j = 0; j < a.length; j++)
				rotatedMatrix[a.length - (j + 1)][i] = a[i][j];
		return rotatedMatrix;
	}

	public boolean[][][] rotateX(boolean objectMatrix[][][]) {
		if(GameStatus.getCurrentObjectX()+GameStatus.getCurrentObject().getZsize()>=GameStatus.getGridSize()){
			return objectMatrix;
		}
		boolean rotatedMatrix[][][] = createFalsMatrix(objectMatrix.length);
		for (int j = 0; j < objectMatrix.length; j++) {
			boolean temp[][] = new boolean[objectMatrix.length][objectMatrix.length];
			for (int i = 0; i < objectMatrix.length; i++)
				for (int k = 0; k < objectMatrix.length; k++)
					temp[i][k] = objectMatrix[i][j][k];
			temp = rot(temp);
			for (int i = 0; i < objectMatrix.length; i++)
				for (int k = 0; k < objectMatrix.length; k++)
					rotatedMatrix[i][j][k] = temp[i][k];
		}
		return align(rotatedMatrix);
	}

	public boolean[][][] rotateY(boolean objectMatrix[][][]) {
		if(GameStatus.getCurrentObjectY()+GameStatus.getCurrentObject().getZsize()>=GameStatus.getGridSize()){
			return objectMatrix;
		}
		boolean rotatedMatrix[][][] = createFalsMatrix(objectMatrix.length);
		for (int i = 0; i < objectMatrix.length; i++) {
			boolean temp[][] = new boolean[objectMatrix.length][objectMatrix.length];
			for (int j = 0; j < objectMatrix.length; j++)
				for (int k = 0; k < objectMatrix.length; k++)
					temp[j][k] = objectMatrix[i][j][k];
			temp = rot(temp);
			for (int j = 0; j < objectMatrix.length; j++)
				for (int k = 0; k < objectMatrix.length; k++)
					rotatedMatrix[i][j][k] = temp[j][k];
		}
		return align(rotatedMatrix);
	}

	public boolean[][][] rotateZ(boolean objectMatrix[][][]) {
		if(GameStatus.getCurrentObjectY()+GameStatus.getCurrentObject().getXsize()>GameStatus.getGridSize()){
			return objectMatrix;
		}
		if(GameStatus.getCurrentObjectX()+GameStatus.getCurrentObject().getYsize()>GameStatus.getGridSize()){
			return objectMatrix;
		}				
		boolean rotatedMatrix[][][] = createFalsMatrix(objectMatrix.length);
		for (int k = 0; k < objectMatrix.length; k++) {
			boolean temp[][] = new boolean[objectMatrix.length][objectMatrix.length];
			for (int i = 0; i < objectMatrix.length; i++)
				for (int j = 0; j < objectMatrix.length; j++)
					temp[i][j] = objectMatrix[i][j][k];
			temp = rot(temp);
			for (int i = 0; i < objectMatrix.length; i++)
				for (int j = 0; j < objectMatrix.length; j++)
					rotatedMatrix[i][j][k] = temp[i][j];
		}
		return align(rotatedMatrix);
	}
                                    

Algoritam za brisanje redova

       public static boolean removeFullRows() {
		ArrayList rowsToRemove = new ArrayList();
		for (int k = gameHeight; k >= 0; k--) {
			boolean remove = true;
			for (int i = 0; i < gridSize; i++)
				for (int j = 0; j < gridSize; j++)
					if (gameBoolMatrix[i][j][k] == false)
						remove = false;
			if (remove)
				rowsToRemove.add(k);
		}
		if (!rowsToRemove.isEmpty()) {
			removeRows(rowsToRemove);
			return true;
		}
		return false;
	}

	private static void removeRows(ArrayList rowsToRemove) {
		for (Integer x : rowsToRemove) {
			for (int k = x; k < gameHeight; k++)
				for (int i = 0; i < gridSize; i++)
					for (int j = 0; j < gridSize; j++)
						if (x == gameHeight - 1){
							gameBoolMatrix[i][j][k] = false;
							gameColorMatrix[i][j][k] = "";
						}else{
							gameBoolMatrix[i][j][k] = gameBoolMatrix[i][j][k + 1];
							gameColorMatrix[i][j][k] = gameColorMatrix[i][j][k + 1];
						}
		}
	}
                                    

Preuzmi dokumentaciju u PDF formatu

Projekt

3D tetris i popratna web stranica su izrađeni u sklopu projekta iz kolegija Računalna grafika koji se izvodi na diplomskom studiju Fakulteta organizacije i informatike Sveučilišta u Zagrebu (Doc. dr. sc. Hip Ivan, Damir Horvat, prof.). Naziv teme je bio: "OpenGL ES 1.1 na Androidu - 3D Tetris" a cilj je bio primijeniti naučene vještine kolegija i pritom steći neke nove. Vjerujemo da smo taj zadatak ispunili u potpunosti.

prtscreen

OpenGL ES je API za naprednu cross-platform 2D i 3D grafiku koji se temelji na podskupu OpenGL-a. On dakle predstavlja otvoreni standard koji definira programsko sučelje za korištenje široke palete grafičkih mogućnosti na cijelom nizu uređaja. Otvorenost i višeplatformnost su svakako jedne od glavnih karakteristika koje su doprinijele da OpenGL ES postane opće prihvaćen u struci. Zanimljivost kod OpenGL ES-a jest nastojanje za kompatibilnošću prema prethodnim verzijama što ga je svojevremeno prilično kočilo u razvoju.

izvor: www.khronos.org/opengles/