Processing math: 100%

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još 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.

Час 11 - Анимације

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

На пример, од наредних осам сличица лика у различитим положајима:

../_images/liktrci1.png ../_images/liktrci2.png ../_images/liktrci3.png ../_images/liktrci4.png ../_images/liktrci5.png ../_images/liktrci6.png ../_images/liktrci7.png ../_images/liktrci8.png

настаје следећа анимација трчања:

../_images/liktrci.gif

Анимације подразумевају брзу промену слике на екрану (на пример, 20 пута у секунди), обично у правилним временским интервалима (на пример, на сваких 50 милисекунди). Свака тако кратко приказана слика назива се оквир или фрејм анимације (енгл. frame). У овом делу приручника видећемо како можемо направити програме у којима се приказују неке анимације.

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

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

Програмирање анимација на сајту „Петља”

Све анимације које ћемо у наставку приказати разликоваће се само по томе који подаци одређују оно што се на слици налази, коду који извршава цртање и коду који мења податке када се прелази на наредни фрејм. Да бисмо ти олакшали сналажење са кодом који већ постаје дугачак и компликован, цртање и прелазак са тренутног на наредни фрејм ћемо издвојити у две помоћне функције које ти треба да напишеш, док ћемо главну петљу програма која те две функције позива ми писати уместо тебе (и она ће бити у „сивом делу кода”). Осим те две функције твој задатак ће бити и да дефинишеш променљиве које описују оно што се налази на екрану током анимације. То ће бити обично променљиве које описују положај (координате) објеката тј. ликова који се током анимације померају, њихову брзину, али и неки други подаци који се мењају током анимације.

Постоји неколико начина да се анимације реализују и у зависности од тога „сиви кôд” може бити реализован на различите начине. Ако програмираш анимације само на сајту „Петља”, тада не мораш уопште да читаш и анализираш сиви кôд (он ће увек бити унапред припремљен за тебе). Ако желиш да правиш програме са анимацијама и ван овог сајта, тада ипак треба да разумеш како сиви кôд функционише. За то ти онда препоручујемо да прочиташ овај текст.

Прикажимо сада кроз неколико примера технику коју ће вам олакшати прављење анимација у примерима који следе. Сви ће бити засновани на библиотеци PyGameBg, тако да ће и „сиви кôд” бити прилично једноставан.

Посебна функција за цртање у програму без анимације

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

 
1
import pygame as pg
2
import pygamebg
3
4
# otvaramo prozor
5
(sirina, visina) = (200, 200)
6
prozor = pygamebg.open_window(sirina, visina, "Три круга")
7
8
9
prozor.fill(pg.Color("white")) # bojimo pozadinu u belo
10
(cx, cy) = (sirina // 2, visina // 2) # centar krugova je u sredni ekrana
11
pg.draw.circle(prozor, pg.Color("red"), (cx, cy), 100)   # crveni krug
12
pg.draw.circle(prozor, pg.Color("blue"), (cx, cy), 75)   # plavi krug
13
pg.draw.circle(prozor, pg.Color("green"), (cx, cy), 50)  # zeleni krug
14
15
16
# prikazujemo prozor i čekamo da ga korisnik isključi
17
pygamebg.wait_loop()
18

(tri_kruga)

Цртање кругова је део главног програма. Исти ефекат можемо постићи ако дефинишемо функцију crtaj коју ћемо позвати из главног програма.

22
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (200, 200) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Три круга")
6
7
8
9
def crtaj():
10
    prozor.fill(pg.Color("white")) # bojimo pozadinu u belo
11
    (cx, cy) = (sirina // 2, visina // 2) # centar krugova je u sredni ekrana
12
    pg.draw.circle(prozor, pg.Color("red"), (cx, cy), 100)   # crveni krug
13
    pg.draw.circle(prozor, pg.Color("blue"), (cx, cy), 75)   # plavi krug
14
    pg.draw.circle(prozor, pg.Color("green"), (cx, cy), 50)  # zeleni krug
15
16
17
# pozivamo funkciju za crtanje
18
crtaj()
19
20
# prikazujemo prozor i čekamo da ga korisnik isključi
21
pygamebg.wait_loop()
22

(tri_kruga_funkcija)

Насумично одређивање боје позадине током анимације

Наредни програм ће приказивати једноставну анимацију у којој ћемо четири пута у секунди на насумичан начин одређивати боју позадине. Одређивање насумичне боје вршићемо помоћу посебне функције nasumicna_boja. Дефинисаћемо функцију crtaj у којој ће се насумично одређивати боја и затим ће се позадина прозора бојити том бојом. Пошто ћемо користити библиотеку PyGameBg, анимацију ћемо на крају програма покретати позивом pygamebg.frame_loop(4, crtaj), чиме ћемо постићи да се функција crtaj аутоматски изнова позива 4 пута у секунди.

19
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (200, 200)
6
prozor = pygamebg.open_window(sirina, visina, "Боја позадине")
7
8
9
def nasumicna_boja():
10
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
11
12
def crtaj():
13
    boja = nasumicna_boja()  # nasumično određujemo boju pozadine
14
    prozor.fill(boja)        # bojimo pozadinu prozora
15
    
16
17
# pokrećemo animaciju tako što funkciju crtaj pozivamo 4 puta u sekundi
18
pygamebg.frame_loop(4, crtaj)
19

(boja_pozadine_nasumicno_bez_stanja)

Подијум за игру

По истом принципу можемо прилагодити програм који је исцртавао подијум за игру, тако да подијум стварно „оживи”. Пронађи кôд који исцртава подијум и на основу тога допуни функцију crtaj.

16
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (400, 400) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Подијум за игру")
7
8
def nasumicna_boja():
9
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
10
11
def crtaj():
12
    ???
13
14
# pokrećemo animaciju tako da se svake sekunde poziva funkcija crtaj
15
pygamebg.frame_loop(1, crtaj)
16

(podijum_animacija)

Промена боје позадине у круг

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

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

20
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (200, 200)   # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Боја позадине")
7
8
9
boje = ["red", "green", "blue"]  # boje koje ćemo postavljati
10
broj_boje = 0                    # pozicija tekuće boje
11
12
def crtaj():
13
    global broj_boje                         # ova promenljiva se menja u funkciji
14
    prozor.fill(pg.Color(boje[broj_boje]))   # postavljanje boje pozadine na tekući element liste
15
    broj_boje = (broj_boje + 1) % len(boje)  # prelazimo na narednu boju
16
    
17
18
# pokrećemo animaciju tako što se funkcija crtaj poziva dva puta u sekundi
19
pygamebg.frame_loop(2, crtaj)
20

(boje_pozadine_u_krug_samo_crtaj)

Приметимо да кôд који се налази у функцији користи променљиве boje и broj_boje које су дефинисане ван функције. Такве променљиве се називају глобалне променљиве и њихова се вредност може без икаквих проблема очитати из функције. Међутим, промена вредности глобалних у функцији је компликованија. Наиме, ако желимо да глобалној променљивој променимо вредност у функцији, на почетку те функције морамо нагласити да је та променљива глобална (помоћу кључне речи global иза које следи листа глобалних променљивих, раздвојених запетама, којима ћемо у тој функцији мењати вредност). Ако у функцији не бисмо навели реч global, добили бисмо поруку о грешци.

UnboundLocalError: local variable 'broj_boje' referenced before assignment

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

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

23
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (200, 200) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Боја позадине")
7
8
9
boje = ["red", "green", "blue"]  # boje koje ćemo postavljati
10
broj_boje = 0                    # pozicija tekuće boje
11
12
def crtaj():
13
    prozor.fill(pg.Color(boje[broj_boje]))  # postavljanje boje pozadine na tekući element liste
14
15
def novi_frejm():
16
    global broj_boje # menjaćemo ovu globalnu promenljivu
17
    broj_boje = (broj_boje + 1) % len(boje)  # prelazimo na narednu boju
18
    crtaj() # ponovo iscrtavamo prozor
19
20
21
# pokrećemo animaciju tako što se funkcija novi_frejm poziva dva puta u sekundi
22
pygamebg.frame_loop(2, novi_frejm)
23

(boje_pozadine_u_krug)

Анализирајмо још једном претходни пример.

  • Стање програма је једнозначно одређено глобалном целобројном променљивом broj_boje која одређује редни број боје којом се прозор боји. Почетна вредност ове променљиве је нула, што значи да боје крећу да се приказују од почетка листе. Боје су смештене у глобалној листи boje која се не мења током извршавања програма.

  • Функција crtaj боји прозор бојом одређеном вредношћу променљиве broj_boje.

  • Функција novi_frejm ажурира вредност стања тј. променљиве broj_boje тако што јој увећава вредност и враћа је на нулу када вредност достигне укупан број боја. Пошто се мења вредност променљиве broj_boje која је глобална, у функцији novi_frejm морамо да променљиву broj_boje означимо помоћу кључне речи global.

Сви програми са анимацијама које ћемо у наставку писати биће организовани на овај начин и твој задатак ће бити да дефинишеш променљиве које одређују стање програма и функције crtaj и novi_frejm. На пример, програм који насумично мења боју позадине можемо написати на следећи начин.

28
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (200, 200) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Боја позадине")
7
8
9
# funkcija koja vraća nasumično određenu boju
10
def nasumicna_boja():
11
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
12
13
boja = nasumicna_boja()  # postavljamo nasumično početnu boju
14
15
# funkcija koja se izvržava svaki put kada se iscrtava ekran
16
def crtaj():
17
    prozor.fill(boja) # bojimo pozadinu na tekuću boju
18
19
# funkcija koja se izvršava na svaki otkucaj tajmera
20
def novi_frejm():
21
    global boja
22
    boja = nasumicna_boja()  # postavljamo nasumično tekuću boju
23
    crtaj()
24
25
26
# zapocinjemo animaciju tako sto svake sekunde pozivamo funkciju novi_frejm
27
pygamebg.frame_loop(1, novi_frejm)
28

(boje_pozadine_nasumicno)

Анализирајмо још једном претходни пример.

  • Стање програма је једнозначно одређено глобалном целобројном променљивом boja која одређује тренутну боју позадине екрана. Почетна вредност ове променљиве се одређује насумично.

  • Функција crtaj боји прозор бојом одређеном вредношћу променљиве boja.

  • Функција novi_frejm ажурира вредност стања тј. променљиве boja тако што јој насумично додељује нову вредност. Пошто се мења вредност променљиве boja која је глобална, у функцији novi_frejm морамо да променљиву boja означимо помоћу кључне речи global. Ова се функција позива аутоматски у правилним временским итервалим и након ажурирања променљивих она позива функцију crtaj да би се прозор поново исцртао.

Кретање лоптице

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

23
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 100)   # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Лоптица")
6
7
8
x = 0  # pozicija loptice
9
10
def crtaj():
11
    # crtamo lopticu
12
    prozor.fill(pg.Color("white"))
13
    pg.draw.circle(prozor, pg.Color("red"), (x, visina // 2), 30)
14
15
def novi_frejm():
16
    global x
17
    x += 1    # pomeramo lopticu za jedan piksel nadesno
18
    crtaj()
19
20
21
# pokrecemo animaciju tako što funkciju novi_frejm pozivamo 50 puta u sekundi
22
pygamebg.frame_loop(50, novi_frejm)
23

(loptica_jednostavna)

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

  • Функција crtaj се сада реализује веома једноставно. У њој бојимо позадину екрана у бело и затим исцртавамо лоптицу коришћењем вредности њеног положаја x.

  • При преласку на сваки нови фрејм потребно је да лоптицу померимо мало (на пример, за 1 пиксел) удесно. Дакле, у функцији novi_frejm потребно је само да увећамо вредност променљиве x за 1. Пошто се мења вредност променљиве x која је глобална, у функцији novi_frejm морамо променљиву x означимо помоћу кључне речи global. Након померања лоптице позивамо функцију crtaj.

Општи облик програма са анимацијама

Видели смо неколико примера и можеш приметити да смо у свима њима анимације остваривали по истом принципу, који ћеш ти примењивати и у наредним задацима.

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

2. Потребно је да дефинишеш функцију crtaj која коришћењем тих података црта сцену. У тој функцији нећемо вршити никакву промену података.

3. Потребно је да дефинишеш функцију novi_frejm која ажурира податке о ликовима и објектима на сцени (при чему све променљиве којима се у тој функцији мења вредност морају на њеном почетку бити експлицитно означене као глобалне коришћењем кључне речи global). Након ажурирања променљивих, потребно је да позовеш функцију crtaj, да би се промењена сцена исцртала.

Неке једоставне анимације

Сада знаш општи принцип по ком ћемо програмирати анимације. Провежбај ово кроз наредних неколико задатака.

Насумично цртање кругова

Напиши програм који четири пута у секунди мења положај и боју круга који се приказује на прозору. Положај и боју одређивати насумично, тако да се круг у сваком тренутку налази унутар прозора.

Приступимо решавању овог задатка на начин који смо описали. Размисли прво који подаци описују стање наше анимације.

Q-1: Које променљиве одређују стање анимације?







  • Дакле, тренутно стање програма одређено је координатама центра x и y, полупречником r и бојом круга boja и њих ћемо представити глобалним променљивама (при чему се полупречник неће мењати).

Размисли сада шта је задатак функције crtaj.

Q-2: Шта функција crtaj треба да уради?







  • Дакле, функција crtaj ће бојити позадину у бело (како би се обрисао претходни круг) и цртаће круг на основу тренутних вредности глобалних променљивих.

Размисли сада шта је задатак функције novi_frejm.

Q-3: Шта функција novi_frejm треба да уради?







  • Дакле, функција novi_frejm ће насумично одредити боју новог круга и одредиће x и y координате центра, тако да круг не испадне ван екрана. То ће важити ако x координата буде у интервалу [r,sirinar], а y координата буде у интервалу [r,visinar].

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

12
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (250, 250)   # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Насумични кругови")
7
8
9
10
# pokrecemo animaciju tako što funkciju novi_frejm pozivamo 4 puta u sekundi
11
pygamebg.frame_loop(4, novi_frejm)
12

(nasumicni_krugovi)

Срце које куца

Напиши програм који приказује анимацију срца које куца. Срце можеш приказати коришћењем слике srce.png.

../_images/srce.png
  • Једини податак који се мења од фрејма до фрејма је то да ли треба или не треба приказати срце. Можемо увести логичку променљиву treba_crtati.

  • У функцији crtaj слику ћемо приказивати само ако променљива treba_crtati има вредност тачно (тј. True).

  • У функцији novi_frejm мењаћемо вредност променљиве treba_crtati. Ако јој је тренутно вредност True, тада треба да се промени на False, а ако јој је тренутно вредност False, тада треба да се промени на True. Најлакши начин да се то уради је да текућу вредност негирамо помоћу оператора not (наравно, можемо употребити и гранање).

Покушај да на основу овога допуниш започети програмски кôд.

22
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (200, 181)  # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Срце")
6
7
srce_slika = pg.image.load("srce.png")  # slika srca
8
treba_crtati = True  # da li treba crtati srce
9
10
def crtaj():
11
    prozor.fill(pg.Color("white"))   # bojimo pozadinu u belo
12
    if ???:                          # crtamo srce ako je to potrebno
13
        prozor.blit(???, (0, 0))
14
15
def novi_frejm():
16
    global treba_crtati
17
    treba_crtati = ???      # negiramo vrednost treba_crtati
18
    crtaj()
19
20
# animacija poziva funkciju novi_frejm dva puta u sekundi
21
pygamebg.frame_loop(2, novi_frejm)
22

(srce_slika)

Смајлић и тужић

Микица често мења расположење. Час је срећна, час је тужна. Напиши програм који приказује слике смајлића и тужића које се наизменично смењују. Можеш употребити слике smajlic.png и tuzic.png.

../_images/smajlic.png ../_images/tuzic.png

Овај задатак је поново веома сличан претходном.

  • Логичка променљива smajlic ће одређивати стање програма.

  • Ако је у функцији crtaj вредност те променљиве True, приказаћемо слику смајлића, а ако је вредност False, приказаћемо слику тужића.

  • У функцији novi_frejm негираћемо вредност променљиве smajlic.

Покушај да на основу овога потпуно самостално напишеш програм. Ако не успеш, онда потражи помоћ и допуни започети програмски кôд.

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (230, 230)  # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Смајлић и тужић")
6
7
8
9
# animacija poziva funkciju novi_frejm dva puta u sekundi
10
pygamebg.frame_loop(2, novi_frejm)
11

(smajlic_tuzic)

Домаћи задатак - сијалице

Напиши програм који приказује дисплеј на коме је поређано 10 сијалица, тако да се наизменично укључује једна по једна.

  • Стање програма ће у потпуности бити одређено вредношћу променљиве редним бројем сијалице која је укључена.

  • У функцији crtaj исцртаваћемо само укључену сијалицу у облику белог круга. Пречник сваке сијалице ћемо одредити тако што ћемо ширину екрана поделити редним бројем сијалице. Координата x центра те сијалице биће одређена редним бројем укључене сијалице (центар сијалице 0 налази се на растојању r од леве ивице екрана, центар сијалице 1 на растојању r + 2r, центар сијалице 2 на растојању r+4r и тако даље).

  • У функцији novi_frejm увећаваћемо редни број укључене сијалице, при чему ћемо га враћати на нулу када достигне укупан број сијалица.

Покушај да на основу претходне дикусије потпуно самостално решиш задатак. Ако не успеш, онда потражи помоћ, па допуни започети кôд.

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 100) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Диоде")
6
7
8
9
# tokom animacije se funkcija novi_frejm poziva 5 puta u sekundi
10
pygamebg.frame_loop(5, novi_frejm)
11

(diode_jednostavno)

Домаћи задатак - цртани филм

Напиши програм који приказује цртани филм тако што наизменично приказује пет слика на екрану на којима је приказан дечак који се шета у различитим положајима. Слике носе називе setanje1.png до setanje5.png.

../_images/setanje1.png ../_images/setanje2.png ../_images/setanje3.png ../_images/setanje4.png ../_images/setanje5.png

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

  • Стање анимације биће одређено искључиво редним бројем слике која се тренутно приказује. Променљива slika представљаће позицију слике у листи која се приказује у текућем фрејму.

  • Функција crtaj има задатак само да обрише екран (бојећи позадину у бело) и да затим прикаже слику из листе slike која се налази на позицији одређеној променљивом slika (подсетимо се, слику приказујемо помоћу функције prozor.blit).

  • Функција novi_frejm ће имати задатак да увећа вредност променљиве slika, тако да се вредност врати на нулу када превазиђе последњу вредност у листи.

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

28
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (150, 180)  # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Цртани филм")
6
7
sredina_y = visina / 2
8
9
# učitavamo u listu slike setanje1.png, setanje2.png, ..., setanje5.png
10
slike = []   # niz u koji dodajemo slike
11
for i in range(1, 6):
12
    naziv_slike = "setanje" + str(i) + ".png"  # gradimo naziv slike od delova
13
    slike.append(???)   # učitavamo sliku i dodajemo je na kraj niza
14
15
slika = 0  # indeks tekuće slike
16
17
def crtaj():
18
    prozor.fill(pg.Color("white"))    # bojimo pozadinu prozora u belo
19
    ???                               # prikazujemo sliku
20
21
def novi_frejm():
22
    global slika  # ovu globalnu promenljivu menjamo
23
    slika = ???   # prelazimo na sledeću sliku
24
    crtaj()
25
26
# animacija poziva funkciju novi frejm 5 puta u sekundi
27
pygamebg.frame_loop(5, novi_frejm)
28

(crtani_film)

Пројекат - дигитални сат

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

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

Ова анимација је необична јер нема потребе за представљањем стања прозора. Дакле, нећемо имати нити глобалне променљиве нити функцију за прелазак на нови фрејм. У функцији crtaj очитаваћемо тренутно време и приказивати га на средини екрана.

Језик Python нам пружа подршку да очитамо тренутно време системског сата рачунара на ком се програм извршава. Функција datetime.now() из модула datetime (који увозимо на почетку програма помоћу import datetime) враћа тренутно време у облику структуре чије поље hour садржи број сати (од 0 до 23), поље minute садржи број минута (од 0 до 59) и second садржи број секунди (од 0 до 59). На основу тога поставићемо вредности променљивих sati, minuti, sekunde.

На основу броја сати, минута и секунди градимо текст који ћемо приказати. Желимо да и сати и минути и секунде увек имају тачно две цифре (ако су једноцифрени, желимо да се допуне водећим нулама). У језику Python ниску str можемо допунити водећим нулама до дужине n позивом str.rjust(n, "0"). Подсетимо се да ниске надовезујемо применом оператора +.

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

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

46
 
1
import pygame as pg, datetime
2
3
pg.init() # inicijalizujemo biblioteku PyGame
4
pg.display.set_caption("Дигитални сат") # otvaramo prozor
5
(sirina, visina) = (200, 200)
6
prozor = pg.display.set_mode((sirina, visina))
7
8
def tekst_centriran(poruka, x, y):
9
    font = pg.font.SysFont("Arial", 40)     # font kojim će biti prikazan tekst
10
    # gradimo sličicu koja predstavlja tu poruku ispisanu crnom bojom
11
    tekst = font.render(poruka, True, ???)
12
    # određujemo veličinu tog teksta (da bismo mogli da ga centriramo)
13
    (sirina_teksta, visina_teksta) = (tekst.get_width(), ???)
14
    # položaj određujemo tako da tekst bude centriran
15
    (x, y) = (???, ???)
16
    # prikazujemo sličicu na odgovarajućem mestu na ekranu
17
    prozor.blit(???, (x, y))
18
19
def crtaj():
20
    prozor.fill(pg.Color("white"))          # bojimo pozadinu u belo
21
    vreme = datetime.datetime.now()         # određujemo trenutno vreme
22
    sati = vreme.hour
23
    minuti = vreme.minute
24
    sekundi = vreme.second
25
    # tekst koja će se ispisivati
26
    poruka = (str(sati).rjust(2, "0") + ":" +
27
              ??? + ":" + \
28
              ???)
29
    tekst_centriran(poruka, sirina / 2, ???)
30
kraj = False
31
sat = pg.time.Clock()  # sat koji određuje broj frejmova u sekundi
32
while not kraj:
33
    # crtamo i ažuriramo sadržaj prozora
34
    crtaj()
35
    pg.display.update()
36
37
    # proveravamo da li je korisnik isključio prozor
38
    for dogadjaj in pg.event.get():
39
        if dogadjaj.type == pg.QUIT:
40
            kraj = True
41
42
    # pauziramo do sledeceg frejma
43
    sat.tick(1)
44
45
pg.quit() # isključujemo rad biblioteke PyGame
46

(digitalni_sat)