You are on page 1of 5

Raunalna grafika - Vjebe 2013/2014

Vjeba 6. Izrada jednostavne igre


U ovoj vjebi je opisan nain izrade jednostavne igre, tzv zmija. Igra funkcionira na nain da tipkama tipkovnice pomiete zmiju po prozoru te ona raste prolaskom preko nasumino postavljenih piksela. Poetni kod:
from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * window = 0 width, height = 500, 500 field_width, field_height = 50, 50 # broj prozora # velicina prozora # interna rezolucija

def refresh2d_custom(width, height, internal_width, internal_height): glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0.0, internal_width, 0.0, internal_height, 0.0, 1.0) glMatrixMode (GL_MODELVIEW) glLoadIdentity() def draw_rect(x, y, width, height): glBegin(GL_QUADS) glVertex2f(x, y) glVertex2f(x + width, y) glVertex2f(x + width, y + height) glVertex2f(x, y + height) glEnd() # # # # # # crtanje pravokutnika donja lijeva tocka donja desna tocka gornja desna tocka donja lijeva tocka kraj crtanja

def draw(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() refresh2d_custom(width, height, field_width, field_height) # crtanje hrane # crtanje zmije glutSwapBuffers() # inicijalizacija glutInit() glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH) glutInitWindowSize(width, height) glutInitWindowPosition(0, 0) window = glutCreateWindow("Vjezba 6 - zmija") glutDisplayFunc(draw) glutIdleFunc(draw) glutMainLoop()

Pokretanjem gornjeg koda dobije se samo prazan crni prozor.

Raunalna grafika - Vjebe 2013/2014

Izrada glavnog dijela igre: Zmije Zmija je samo lista piksela na razliitim pozicijama. U poetku je samo jedan piksel u prozoru, meutim nakon to zmija pojede piksel na ekranu, ona naraste za jedan itd. Glava zmije je prvi element koji je na prvoj poziciji na listi. Za predstavljanje zmije koriste se dvije varijable. Prva se odnosi na listu svih elemenata zmije, a druga na smjer gibanja. Varijable se deklariraju na poetku koda meu ostalim varijablama. Kako zmija ved ima glavu, tada se u poetnoj varijabli deklarira poetni poloaj prvog piksela zmije. Deklariramo varijable:
zmija = [(20, 20)] zmija_smj = (1, 0) # Lista x,y pozicija zmije # smjer gibanja zmije

Ovaj kod oznaava da je glava zmije na poetnoj poziciji (x=20, y=20). Zmija_smj je varijabla koja oznaava smjer gibanja zmije. U ovom sluaju oznaava (x=1, y=0), to znai da se zmija giba u desno. Nakon to zmija naraste, varijabla zmija se poveava za dodatne koordinate. Kada su deklarirane varijable, potrebno je napraviti funkciju koaj crta zmiju.
def crtaj_zmiju(): glColor3f(1.0, 1.0, 1.0) for x, y in zmija: draw_rect(x, y, 1, 1) # Boja zmije je bijela # za svaki (x, y) vrijednost # crtaj (x, y) sa sirinom=1 visinom=1

Unutar funkcije draw() potrebno je pozvati funkciju za crtanje zmije crtaj_zmiju() Ako se sada pokrene program, dobije se bijeli kvadratid unutar crnog prozora. Idudi korak je pomicanje zmije pomodu tipki na tipkovnici. Za pomicanje zmije, koristit de se tipke W,S,A i D za micanje gore, dolje, lijevo i desno. Za pomicanje de se koristiti update funkcija koju je potrebno definirati.
def update(value): # stvari koje se osvjezaju glutTimerFunc(interval, update, 0) # osvjezavanje

Varijabla interval se definira na vrhu meu varijablama, a oznaava interval osvjeavanja u milisekundama.
interval = 200 # interval osvjezavanja u milisekundama

U OpenGL inicijalizaciji koristi se glutTimerFunc da kae OpenGL-u da radi osvjeenje svakih 200 milisekundi kao to je definirano u varijabli interval. Nakon to se pokrene program, update funkcija se poziva svakih 200ms i slui samo kao petlja za osvjeavanje. Unutar inicijalizacije izmeu glutIdleFunc(draw) i glutMainLoop() potrebno je dodati:
glutTimerFunc(interval, update, 0) # osvjezavanje

Raunalna grafika - Vjebe 2013/2014

Idudi zadatak je pomicanje zmije. Kako zmija moe biti sastavljena od jednog ili vie piksela potrebno je pronadi najbolji nain za pomicanje zmije. Pomicanje zmije funkcionira na narin da se glava zmije pomakne gore, dolje, lijevo ili desno u odnosu na prethodni poloaj, a svi ostali pikseli da je prate. Ovaj problem se moe rijeti jednostavnije. Naime, oku je vidljivo samo da se prvi i posljednji piksel zmije pomidu. Zbog toga se moe napraviti algoritam prema kojem se brie zadnji piksel i postavlja na idude mjesto gdje bi trebala idi glava zmije. Ovim se dobije dojam da se zmija giba, premda se samo izbrisao zadnji piksel i stvorila nova glava zmije. Prilikom izrade algoritma, prvo je potrebno napraviti funkciju koja zbraja dvije pozicije:
def vec_add((x1, y1), (x2, y2)): return (x1 + x2, y1 + y2)

Ova funkcija slui za pomicanje zmije. Prilikom svakog osvjeenja, potrebno je pomaknuti zmija_smj listu: Nova_pozicija=vec_add(zmija[0], zmija_smj) gdje se zmija[0] odnosi na glavu zmije. Funkcija update tada izgleda:
def update(value): zmija.insert(0, vec_add(zmija[0], zmija_smj)) zmija.pop() # brisanje zdanjeg elementa glutTimerFunc(interval, update, 0)

Ako se sada pokrene program, vidi se gibanje kvadratida u desno. Sada je potrebno definirati upravljanje zmijom tipkama:
def tipkovnica(*args): global zmija_smj if args[0] == 'w': zmija_smj = (0, 1) if args[0] == 's': zmija_smj = (0, -1) if args[0] == 'a': zmija_smj = (-1, 0) if args[0] == 'd': zmija_smj = (1, 0)

# gore # dolje # lijevo # desno

Kako bi OpenGL znao da treba provjeravati ulaz sa tipkovnice, potrebno je u inicijalizaciju dodati glutKeyboardFunc(tipkovnica) prije glutMainLoop().

Raunalna grafika - Vjebe 2013/2014

Kako zmija treba jesti, potrebno je definirati varijablu u kojoj de biti koordinate hrane.
hrana = [] # lista hrane (x, y)

Za nasumino postavljanje hrane, potrebno je koristiti random funkciju. Stoga je potreno u programu navesti:
from random import randint

Hrana se definira u update funkciji koja sada izgleda ovako:


def update(value): zmija.insert(0, vec_add(zmija[0], zmija_smj)) zmija.pop() # brisanje zdanjeg elementa r = randint(0, 20) if r == 0: x, y = randint(0, field_width), randint(0, field_height) hrana.append((x, y)) glutTimerFunc(interval, update, 0)

to se dogaa kada se stvara nasumina vrijednost i pohranjuje u r varijabli.. Vrijednost je izmeu 0 i 20. Ako je vrijednost 0 (to je 5% anse jer je 100/20=5), nasumina funkcija stvara vrijednost u listi hrane. Sada je potrebno iscrtati hranu:
def crtaj_hranu(): glColor3f(0.5, 0.5, 1.0) for x, y in hrana: draw_rect(x, y, 1, 1) # boja hrane # crtanje hrane

Funkciju crtaj_hranu() je potrebno pozvati u draw() funkciji Napravljena je zmija, definirana je hrana, sada je potrebno definirati da zmija jede hranu. Slijededi kod ide u update funkciju:
# zmija jede hranu (hx, hy) = zmija[0] # glava zmije na x,y poziciji for x, y in hrana: # provjera liste hrane if hx == x and hy == y: # da li je glava gdje je hrana? zmija.append((x, y)) # produi zmiju hrana.remove((x, y)) # ukloni hranu

Raunalna grafika - Vjebe 2013/2014


Nakon to napravite igru potrebno je slijedede: 1. 2. 3. 4. Na tipku esc ugasiti igru Povedati brzinu gibanja zmije Promijeniti boju hrane u crvenu Promijeniti boju zmije u utu

You might also like