Professional Documents
Culture Documents
Vjezba 6
Vjezba 6
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()
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
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)
Kako bi OpenGL znao da treba provjeravati ulaz sa tipkovnice, potrebno je u inicijalizaciju dodati glutKeyboardFunc(tipkovnica) prije glutMainLoop().
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
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