Prijavi problem


Obeleži sve katergorije koje odgovaraju problemu

Jos detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link
Na žalost nismo trenutno u mogućnosti da obradimo Vaš zahtev.
Molimo Vas da pokušate kasnije.

Programiranje grafike pomoću Pygame, priručnik za gimnaziju

Кретање објеката по екрану

Варијације на тему лоптице која се креће

У уводном поглављу смо приказали како можемо направити анимацију лоптице која се креће са леве ка десној страни екрана. Сада ћемо тај програм модификовати тако да се лоптица која изађе на десном крају екрана појављује поново на левом крају екрана.

Мана претходног програма је то што лоптица не испадне цела са пре него што се пребаци на леву страну. Такође, када се појави на левој страни, она се већ до пола види. Покушај да то поправиш.

Преправимо сада програм тако да лоптица промени полупречник сваки пут када се поново промени. Полупречник бирамо насумично, из интервала \([5, 30]\) (подсети се, насумичан цео број добијамо функцијом random.randint). Провери да испадање лоптице са екрана и њено ново појављивање ради исправно за сваку вредност полупречника.

Допунимо сада програм тако да се свака нова лоптица креће различитом брзином.

Допунимо сада програм тако да се свака нова лоптица креће на различитој висини. Висину бирај насумично, али тако да лоптица цела буде унутар прозора.

Једини параметар лоптице који је фиксиран је боја. На крају, допунимо програм тако да се и боја сваке нове лоптице бира насумично.

Вежбе ради, измени претходни програм тако да се лоптице крећу с десна налево.

Аутомобил који се креће

Напиши програм који приказује аутомобил који се креће ширином екрана. Када испадне на десном крају екрана, поново се појављује на левом крају.

Анимацију аутомобила можемо реализовати тако што ћемо га сваких неколико милисекунди померати и цртати у новом положају (на исти начин као што смо померали лоптицу).

Прикажимо прво варијанту програма у којој се приказује слика аутомобила auto.png.

../_images/auto.png

Положај аутомобила биће одређен познавањем координата његовог горњег левог угла (њих можемо чувати коришћењем променљивих auto_x и auto_y). Поред тога, можемо чувати и променљиве којима су представљене димензије слике аутомобила.

Цртање вршимо веома једноставно, приказивањем слике аутомобила на позицији одређеној тренутним координатама auto_x и auto_y.

Померање аутомобила вршићемо само по оси x. У сваком кораку петље координату auto_x ћемо увећавати за одговарајући померај. Њега ћемо израчунавати као производ времена протеклог од претходног фрејма и брзине аутомобила изражене у броју пиксела у једној секунди. Време dt које протекне између приказивања два фрејма лако израчунавамо на основу броја фрејмова у секунди (у питању је реципрочна вредност). Потребно је још проверити да ли је аутомобил излетео иза десне ивице екрана и ако јесте, она га пребацити на крајњи леви део екрана (иза леве ивице прозора). Сматраћемо да је ауто испао ван слике када му леви крај (одређен координатом auto_x) пређе ширину екрана (одређену променљивом sirina). Тада га враћамо тако да му десни крај буде на левој ивици екрана (леви крај му се тада налази у минусу и то тачно за ширину слике аутомобила).

Размотримо сада мало сложенију варијанту у којој не користимо слику, већ исцртавамо аутомобил програмским кодом. Аутомобил се исцртава помоћу два правоугаоника (горњег и доњег дела каросерије аутомобила) и два круга (точкова аутомобила). Цртање најлакше организујемо ако знамо положај централне тачке каросерије аутомобила (памтићемо је помоћу променљивих auto_cx и auto_cy - на доњој слици приказана је црвеном бојом). Израчунавање осталих релевантних координата врши се у односу на познати положај средине аутомобила, слично као што смо то радили у неколико задатака приказаних у поглављу о цртању.

../_images/auto_koordinate.png

На основу дужине и координата средине аутомобила можемо израчунати координате његовог левог краја и проверити да ли је координата x постала већа од ширине екрана. Ако јесте, онда ћемо координату auto_cx поставити тако да десни крај аутомобила буде тачно на левој ивици прозора.

У складу са овом дискусијом, допуни наредни програм.

Концентрични кругови

Напиши програм који приказује анимацију концентричних кругова чији се број у сваком фрејму повећава од 1 до 10, а затим смањује од 10 до 1.

Иако се у овом задатку кругови не померају по екрану, већ им се само мења величина, принцип решавања је веома сличан задацима у којима се објекат кретао по екрану.

Основна променљива која ће се мењати од фрејма до фрејма је број кругова. У првој фази ће се наредни број кругова добијати од претходног увећавањем за 1, а у другој умањивањем за 1. Стога ћемо чувати и променљиву која ће одређивати смер промене броја кругова и чија ће вредност бити 1 све док број кругова не достигне максимум (на пример 10 кругова), након чега ће се променити на -1 и бити таква све док број кругова не достигне минимум тј. док се не дође само до једног круга.

Круг који пулсира

Напиши програм у којем се исцртава круг у центру екрана чији се полупречник мења од min_r до max_r у малим корацима dr, затим назад до min_r у истим корацима и тако у круг.

Иако се у овом задатку круг не помера, већ му се само мења величина, принцип решавања је веома сличан задацима у којима се објекат кретао по екрану.

Током анимације врши се промена полупречника r.

Цртање вршимо тако што нацртамо црвени круг на белој позадини, тако да му је центар у центру екрана, а полупречник једнак тренутој вредности полупречника r.

У сваком кораку анимације, приликом преласка на нови фрејм, r ће се увећавати за вредност dr која ће у неким тренуцима бити једнака 1, а у неким -1, у зависности од тога да ли се величина круга тренутно повећава или смањује. Допуштен распон полупречника биће одређен променљивама min_r и max_r и када се тренутни полупречник лоптице нађе ван интервала [min_r, max_r] тј. када се деси да је мањи од min_r или већи од max_r, тада ће dr мењати свој знак (због тога и dr треба да буде глобална променљива).

Стражар који патролира

Напиши програм који приказује стражара који патролира лево десно по екрану. Претпостави да на располагању имаш слике strazar_levo.png на којој је приказан стражар окренут на лево и strazar_desno.png на којој је приказан исти стражар окренут на десно.

../_images/strazar_levo.png ../_images/strazar_desno.png

Решење задатка је прилично слично оном у коме се ауто кретао ширином екрана. Постоје две разлике. Прво, уместо цртања слике помоћу графичких примитива (правоугаоника, кругова), учитавамо готову слику и приказујемо је на одговарајућем месту. Друго, када стражар дође до краја екрана не мења му се позиција, већ му се мења смер кретања. Дакле, у сваком тренутку је позната позиција стражара (на пример, позиција горњег левог угла слике којој је стражар представљен). У сваком кораку анимације мењамо координату x те позиције. Док се стражар креће на десно, ту координату ћемо увећавати за вредност dx, а док се креће на лево умањиваћемо је за dx. Умањивање за dx можемо схватити и као увећавање за -dx, па онда у сваком кораку можемо заправо увећавати за dx, при чему ће знак dx одређивати да ли се стражар креће налево или надесно. Када стражар испадне ван екрана (када му је координата x десног краја већа од ширине екрана или му је координата x левог краја мања од нуле, тј. када је x < 0 или је x + strazar_sirina > sirina), тада му се смер кретања мења тако што се промени знак помераја dx. Пошто знак броја dx одређује и смер кретања, на основу њега одређујемо и слику коју ћемо приказивати.

На основу претходне дискусије допуни наредни део програма.

Авион

Напиши програм који приказује авион који полеће (из доњег левог угла прозора), пење крећући се надесно док не додирне врх прозора, затим се спушта и даље крећући се надесно док не додирне земљу и онда наставља да се креће по земљи док изађе ван прозора на његовом десном делу. Можеш употребити слику avion.png, а на небо можеш поставити слику sunce.png.

../_images/avion.png ../_images/sunce.png

Одбијање лоптице

Напиши програм који приказује лоптицу која се креће и одбија о ивице екрана.

У сваком тренутку је потребно да знамо положај лоптице на екрану. То је најједноставније остварити тако што ћемо у променљивама x и y памтити координате центра лоптице (на почетку их можемо иницијализовати на половину ширине и висине, тако да се лотпица налази у центру екрана). Полупречник лоптице ћемо представити променљивом r.

Кретање лоптице се остварује тако што јој се у правилним временским интервалима мењају x и y координата. Пошто претпостављамо да је брзина константна у сваком тренутку ће промена сваке од координата бити идентична: координату x ћемо увећавати или умањивати за по 5 пиксела и координату y ћемо увећавати или умањивати за по 5 пиксела. Пошто су промене по обе координате идентичне, лоптица ће се увек кретати под углом од 45 степени у односу на ивице прозора. Промену координате x ћемо представити променљивом dx која ће имати вредност или 5 или -5, у зависности од тога да ли се лоптица креће надесно или налево. Слично ћемо употребљавати и променљиву dy. Уређени пар (dx, dy) заправо представља вектор брзине кретања лоптице. У правилним временским интервалима (на пример, на сваких 25 милисекунди) помераћемо лоптицу тако што x увећамо за dx, а y за dy.

Након сваког померања провераваћемо да ли је лоптица излетела ван граница екрана. Хоризонталну проверу можемо извршити тако што ћемо проверити да ли је леви крај лоптице лево од леве ивице екрана, или је десни крај лоптице десно од десне ивице екрана. Леви крај лоптице има x координату једнаку x-r, а десни крај има x координату једнаку x+r, па се провера своди на то да се провери да ли x-r < 0 или је x+r > sirina. Ако је то случај, тада се мења смер хоризонталног кретања тако што се промени знак вредности dx. Потпуно аналогно се врши и вертикална провера (само се уместо x користи y, уместо dx користи dy и уместо sirina користи visina).

Корњача и зец

Напиши програм који приказује корњачу и зеца који полазе са два краја прозора, крећу се једно према другом (зец се креће два пута брже од корњаче) док се не сусретну, након чега се на екрану исписује порука Здраво. Можеш употребити слике kornjaca.png и zec.png.

../_images/kornjaca.png ../_images/zec.png

Пинвин који пада

Напиши програм који приказује анимацију пингвина који се креће док не дође до ивице стене, затим пада на под и наставља да се креће до краја прозора. Можеш употребити слику pingvin.png.

../_images/pingvin.png

Пошто је у овом задатку положај доње ивице слике пингвина значајнији од положаја горње ивице, у програму ћемо памтити координате доњег левог темена слике (уместо горњег левог темена, што је можда уобичајеније). Да бисмо од те тачке добили координате горњег левог темена слике (које су нам потребне за цртање), од y координате доњег левог угла ћемо одузимати висину слике.

Приликом преласка на сваки наредни фрејм пингвина ћемо померати надесно (за један пиксел). У неком тренутку пингвин ће да пада и тада ћемо померати пингвина и надоле (за по пет пиксела). Пингвин треба да крене да пада када му леви крај пређе десни крај стене и када му доњи крај још није пао на земљу (када му је y координата доњег левог темена мања од висине прозора).

Пинвин који силази низ степенице

Преправи претходни програм тако да пингвин сиђе низ степенице.

Сцену ћемо организовати тако да се степенице пружају од почетка до краја прозора, тако што ћемо ширину степенице одређивати тако што укупну ширину прозора поделимо броје степеница. Висину једног степеника (разлику висине две суседне степенице) одредићемо тако да висина буде дупло мање од ширине.

Пошто нас параметри сваке појединачне степенице интересују у више различитих контекста (приликом цртања, приликом почетног постављања и приликом померања пингвина), дефинисаћемо функцију која ће одређивати све потребне параметре i-те степенице тј. правоугаоника који представља ту степеницу. Довољно је да знамо координате горњег левог угла тог правоугаоника, његову ширину и висину.

Цртање можемо извршити веома једноставно тако што обојимо позадину у бело, нацртамо слику пингвина (не заборавимо да од доњег десног угла израчунамо горњи леви) и онда у петљи нацртамо једну по једну степеницу, што је веома једноставно ако позивамо функцију која враћа параметре правоугаоника који представља ту степеницу.

У сваком наредном фрејму пингвин се помера за један пиксел надесно. Померање наниже ћемо вршити само ако се он налази изнад врха степенице изнад које се тренутно налази. Редни број те степенице можемо једноставно добити дељењем текуће x координате доњег левог темена пингвина ширином једне степенице.

Мачка која се креће по ободу прозора

Напиши програм који приказује мачку која се креће по ободу прозора (горњем, десном, доњем, левом).

Претпостављамо да на располагању имамо слику macka.png. Ако програм покрећеш из локала (а не из прегледача веба), мораш преузети и ову слику и снимити је на исто место на ком се и програм налази.

../_images/macka.png

У сваком тренутку можемо да пратимо смер у ком се мачка креће. Једноставан начин је да за то употребимо ниску ('levo', 'desno', 'gore', 'dole') и положај горњег левог темена слике мачке. На почетку мачку постављамо у горњи леви угао екрана (координате јој постављамо на (0, 0)) и смер кретања на десно. Гранањем на основу смера кретања одређујемо како ће се мачка померати. Приликом померања мачке провераваћемо и да ли је дошла до ивице екрана у смеру у ком се тренутно креће и ако јесте, мењаћемо јој смер кретања на одговарајући начин.

Допуни наредни део програма на основу претходне дискусије.

Уместо гранања, могли смо да користимо и листу у којој се за сваки правац одређује померај дуж обе осе. Смер тада представљамо као број од 0 до 3 (који уједно представља и индекс у тој листи). Смер мењамо увећавањем тог броја за 1, при чему водимо рачуна о томе да када смер 3 увећавамо за 1 опет добијемо 0. То једноставно постижемо израчунавањем остатка при дељењу са 4 (тј. дужином листе помераја). Предност овог приступа је то што смо избегли гранање и тиме добили краћи кôд, а мана је то што у сваком кораку морамо да вршимо проверу достизања све четири ивице (у претходном примеру смо при кретању надесно проверавали само достизање десне ивице).