Садржај
1. Програмирање у пајтону - Увод у Pygame
15. Цртање уз помоћ петљи - обнављање
16. Завршни квиз

15.1. Цртање уз помоћ петљи - обнављање

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

Задаци

Испрекидана линија

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

 
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, "Isprekidana linija")
7
8
9
10
# prikazujemo prozor i čekamo da ga korisnik isključi
11
pygamebg.wait_loop()
12

(isprekidana_linija)

Црта-тачка линија

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

12
 
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, "Isprekidana linija crta-tačka")
7
8
9
10
# prikazujemo prozor i čekamo da ga korisnik isključi
11
pygamebg.wait_loop()
12

(crta_tacka)

Кругови дуж дијагонале

Напиши програм који дуж целе главне дијагонале прозора распоређује n=10 једнаких кругова.

Пречници кругова деле главну дијагоналу на n једнаких делова. Полупречник кругова можемо израчунати тако што дужину дијагонале поделимо са 2n, а дужину дијагонале можемо израчунати Питагорином теоремом као s2+v2, где су s и v ширина тј. висина прозора. На основу Талесове теореме, пројекције центара кругова на x осу и на y осу деле ивице прозора у истом односу у ком центри кругова деле дијагоналу. Ако са kx означимо n-ти део ширине прозора, а са ky означимо n-ти део висине прозора, тада прва тачка има координате (kx2,ky2), друга има координате (kx2+kx,ky2+ky), трећа има координате (kx2+2kx,ky2+2ky) итд. На основу овога допуни наредни програм.

26
 
1
import math
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (500, 400) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Krugovi na dijagonali")
7
8
# broj krugova
9
n = 10
10
# dužina dijagonale
11
d = round(???)
12
# poluprečnik krugova
13
r = round(???)
14
# razmak između centara krugova po x i y osi
15
kx = round(???)
16
ky = round(???)
17
18
# bojimo pozadinu prozora u belo
19
prozor.fill(pg.Color("white"))
20
# crtamo krugove
21
for i in range(n):
22
    pg.draw.circle(prozor, pg.Color("red"), (???*kx, ???*ky), r, 3)
23
24
# prikazujemo prozor i čekamo da ga korisnik isključi
25
pygamebg.wait_loop()
26

(krugovi_na_dijagonali)

Шпартање дијагоналама

У једном од претходних задатака шпартали смо прозор водоравним и усправним линијама. Тада смо видели да се крајње тачке тих линија налазе на ободу прозора и имају координате облика (idx,0), (idx,v), (0,idy) и (s,idy), где су dx и dy хоризонтално тј. вертикално растојање између две линије, док су s и v ширина тј. висина прозора. Ако употребимо исте тачке, али их спојимо дужима на мало другачији начин, можемо добити веома интересантне шаре.

Напиши програм који дијагонално шпарта прозор у правцу споредне дијагонале. Број линија изнад споредне дијагонале (укључујући и њу) је n=10 (исто важи и за број линија испод споредне дијагонале).

Крајње тачке ових дужи деле сваку од ивица прозора на по n једнаких делова. Стога се растојање dx између суседних тачака на горњој (и доњој) ивици прозора може израчунати дељењем ширине, а растојање dy између суседних тачака на левој (и десној) ивици дељењем висине прозора бројем n. Посматрајмо дужи које спајају леву и горњу ивицу прозора (последња таква је споредна дијагонала). Прва дуж спаја тачке са координатама (dx,0) и (0,dy), друга дуж тачке са координатама (2dx,0) и (0,2dy) итд. Дакле, те дужи можемо нацртати тако што у петљи у којој бројачка променљива i мења вредности од 1 до n цртамо дужи које спајају тачке са координатама (i*dx, 0) и (0, i*dy). Слично, прва дуж испод дијагонале спаја тачке са координатама (w,dy) и (dx,h), друга тачке са координатама (w,2dy) и (2dx,h) итд, где w означава ширину, а h висину прозора. Дакле, те дужи можемо нацртати тако што у петљи у којој бројачка променљива i мења вредности од 1 до n-1 цртамо дуж која спаја тачке са координатама (sirina, i*dy) и (i*dx, visina).

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

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Dijagonalno spartanje")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(dijagonalno_spartanje)

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

5
 
1
# crtamo linije i van granica prozora, računajuci da se deo linija
2
# koji ne pripada prozoru neće ni videti
3
for i in range(2*n):
4
    pg.draw.line(prozor, CRNA, (0, i*dy), (i*dx, 0), 1)
5

(spartanje_dijagonale_van_prozora)

Ажурирај претходни програм тако да се додају и дијагонале паралелне главној дијагонали исцртане црвеном бојом.

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Dijagonalno spartanje")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(dijagonalno-spartanje-2)

Правоугаона мрежа

Напиши програм који исцртава правоугаону мрежу која се састоји од 100 правоугаоних поља, распоређених у 10 врста и 10 колона (исцртати само линије мреже и то хоризонталне линије плавом бојом, а вертикалне црвеном, дебљине 5 пиксела).

Основни задатак је одредити координате x вертикалних линија и координате y хоризонталних линија. Ширину једног правоугаоника можемо одредити дељењем ширине прозора бројем колона (у нашем случају то је 10), док висину једног правоугаоника можемо одредити дељењем висине прозора бројем врста (то је поново 10). Означимо те димензије са dx и dy. Вертикалне линије се онда налазе на растојању dx, 2dx, 3dx, …, 9dx пиксела од леве ивице прозора (то су им координате x). Пошто се те линије простиру од врха до дна прозора, координате y крајњих тачака су једнаке нули, односно висини прозора. Понављање цртања линија остварујемо, наравно, употребом петље for, при чему је најбоље да се бројач i креће од један до девет, јер се тада у кораку i црта линија од тачке (i*dx, 0) до тачке (i*dx, visina). Цртање хоризонталних линија остварујемо веома слично, у независној петљи for у којој се црта линија од тачке (0, i*dy) до тачке (sirina, i*dy).

23
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Pravougaona mreza")
6
7
# bojimo pozadinu prozora u belo
8
prozor.fill(pg.Color("white"))
9
10
brojPodeoka = 10
11
dx = sirina / brojPodeoka
12
dy = ???                   # izračunaj razmak između podeoka po visini
13
14
# crtamo horizontalne linije
15
for i in range(1, brojPodeoka):
16
    pg.draw.line(prozor, pg.Color("blue"), (0, i*dy), (sirina, i*dy), 5)
17
18
# dodaj kôd koji crta vertikalne linije crvenom bojom
19
???
20
21
# prikazujemo prozor i čekamo da ga korisnik isključi
22
pygamebg.wait_loop()
23

(pravougaona_mreza)

Још један начин да се одреди координата наредне линије је да се координата претходне линије увећа за ширину, тј. дужину правоугаоника.

5
 
1
x = dx
2
for i in range(1, brojPodeoka):
3
    pg.draw.line(prozor, pg.Color("red"), (x, 0), (x, visina), 5)
4
    x += dx
5

(pravougaona_mreza_alt)

Шарање ротираним дужима

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

../_images/petlja1.png

Иако шара изгледа на први поглед прилично различито, овај програм је заправо прилично сличан претходном. Прва дуж спаја тачке се координатама (0,dy) и (dx,h), друга спаја тачке са координатама (0,2dy) и (2dx,h), итд, све до дужи која спаја тачке (0,(n1)dy) и ((n1)dx,h), где је h висина прозора. Дакле, дужи можемо нацртати у петљи у којој се бројачка променљива i креће од 1 до n-1, у чијем телу цртамо дуж која спаја тачке са координатама (0, i*dy) и (i*dx, visina). Ако би се бројач у петљи мењао од 0 до n, тада би се цртале и прва вертикална и последња хоризонтална дуж (oне се не виде, јер се поклапају са ивицама прозора).

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

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Rotirane duzi")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(rotirane_duzi)

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

../_images/petlja2.png

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

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Rotirane duzi")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(rotirane_duzi2)

Крешендо

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

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (800, 200) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Kresendo")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(kresendo)

Лоптице

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

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (800, 200) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Sarene loptice")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(loptice.py)

Згуснуте линије

Нацртај цртеж у ком се 10 усправних линија удаљава једна од друге за размак који је 10% већи од размака претходне две линије. Линије се удаљавају како се померамо ка десној страни прозора. Размак између прве две линије је 20 пиксела.

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 400) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Zgusnute linije")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(zgusnute_linije)

Цигле

Редови цигала наизменично почињу целом циглом и половином цигле. Нека је ширина цигле означена са s, а њена висина са v. Целу циглу на почетку реда добијамо тако што цртамо правоугаоник од тачке на датој висини, са x координатом једнаком нули. Половину цигле на почетку реда можемо да добијемо тако што нацртамо целу циглу померену за s2 улево, то јест тако што цртамо правоугаоник од тачке на истој висини, али са x координатом једнаком -s // 2. Тако постижемо да се види само десна половина цигле. Остаје нам да решимо када цртамо померену циглу, а када не.

Једно од решења је да место почетка реда цигала чувамо у променљивој, назовимо је x_poc. После сваког исцртаног реда, проверавамо да ли променљива x_poc има вредност нула или -s // 2. Коју год од ове две вредности променљива имала, доделићемо јој ону другу вредност, да би у следећем реду цртање цигала почело другачије.

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

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (300, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Cigle")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(PyGame_loops_bricks1)

Тараба

Напиши програм који црта сеоску ограду (тарабу).

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

Један начин је да у задавању темена притке користимо променљиву x, која се мења у петљи. Када би се притке померале и на горе или на доле, онда би у задавању темена учествовала и променљива y.

4
 
1
for x in range(20, 300, 40):
2
    pg.draw.polygon(prozor, pg.Color('brown'),
3
                    [(x, 80), (x + 10, 70), (x + 20, 80), (x + 20, 270), (x, 270)])
4

(ograda_1nacin)

Можемо и да уведемо функцију која црта притку у односу на њену релативно задату x координату.

7
 
1
def pritka(x):
2
    temena = [(x, 80), (x+10, 70), (x+20, 80), (x+20, 270), (x, 270)]
3
    pg.draw.polygon(prozor, boja, temena)
4
5
for x in range(20, 300, 40):
6
    pritka(x)
7

(ograda_2nacin)

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

4
 
1
temena = [(20, 80), (30, 70), (40, 80), (40, 270), (20, 270)]
2
for i in range(7):
3
    pg.draw.polygon(prozor, pg.Color('brown'), [(x + 40*i, y) for (x,y) in temena])
4

(ograda_3nacin)

Коришћењем било ког од наведених решења нацртај тарабу.

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (300, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Taraba")
6
7
???
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(PyGame_loops_fence)

(Created using Swinx, RunestoneComponents and PetljaDoc)
© 2022 Petlja
A- A+