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

Напиши програм који по средини прозора исцртава испрекидану линију код које је свака линијица обојена насумично одабраном бојом. Дужине линијица и размак између њих су једнаки 30 пиксела, а дебљина линије је 5 пиксела.
import random
import pygame as pg
import pygamebg
(sirina, visina) = (400, 400) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Isprekidana linija")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(isprekidana_linija)
Црта-тачка линија¶

Напиши програм који црта зелену испрекидану линију „црта-тачка“.
import random
import pygame as pg
import pygamebg
(sirina, visina) = (400, 400) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Isprekidana linija crta-tačka")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(crta_tacka)
Кругови дуж дијагонале¶

Напиши програм који дуж целе главне дијагонале прозора распоређује
Пречници кругова деле главну дијагоналу на
import math
import pygame as pg
import pygamebg
(sirina, visina) = (500, 400) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Krugovi na dijagonali")
# broj krugova
n = 10
# dužina dijagonale
d = round(???)
# poluprečnik krugova
r = round(???)
# razmak između centara krugova po x i y osi
kx = round(???)
ky = round(???)
# bojimo pozadinu prozora u belo
prozor.fill(pg.Color("white"))
# crtamo krugove
for i in range(n):
pg.draw.circle(prozor, pg.Color("red"), (???*kx, ???*ky), r, 3)
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(krugovi_na_dijagonali)
Шпартање дијагоналама¶
У једном од претходних задатака шпартали смо прозор водоравним и
усправним линијама. Тада смо видели да се крајње тачке тих линија
налазе на ободу прозора и имају координате облика

Напиши програм који дијагонално шпарта прозор у правцу споредне
дијагонале. Број линија изнад споредне дијагонале (укључујући и њу)
је
Крајње тачке ових дужи деле сваку од ивица прозора на по i
мења вредности од 1 до
n
цртамо дужи које спајају тачке са координатама (i*dx, 0)
и
(0, i*dy)
. Слично, прва дуж испод дијагонале спаја тачке са
координатама i
мења вредности од 1 до n-1
цртамо дуж која спаја тачке са
координатама (sirina, i*dy)
и (i*dx, visina)
.
На основу претходне дискусије напиши наредни програм:
import pygame as pg
import pygamebg
(sirina, visina) = (400, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Dijagonalno spartanje")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(dijagonalno_spartanje)
Програм се може мало једноставније написати ако се не обазиремо на то да крајње тачке дужи изађу ван граница прозора.
# crtamo linije i van granica prozora, računajuci da se deo linija
# koji ne pripada prozoru neće ni videti
for i in range(2*n):
pg.draw.line(prozor, CRNA, (0, i*dy), (i*dx, 0), 1)
(spartanje_dijagonale_van_prozora)

Ажурирај претходни програм тако да се додају и дијагонале паралелне главној дијагонали исцртане црвеном бојом.
import pygame as pg
import pygamebg
(sirina, visina) = (400, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Dijagonalno spartanje")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(dijagonalno-spartanje-2)
Правоугаона мрежа¶

Напиши програм који исцртава правоугаону мрежу која се састоји од 100 правоугаоних поља, распоређених у 10 врста и 10 колона (исцртати само линије мреже и то хоризонталне линије плавом бојом, а вертикалне црвеном, дебљине 5 пиксела).
Основни задатак је одредити координате x вертикалних линија и
координате y хоризонталних линија. Ширину једног правоугаоника можемо
одредити дељењем ширине прозора бројем колона (у нашем случају то је
10), док висину једног правоугаоника можемо одредити дељењем висине
прозора бројем врста (то је поново 10). Означимо те димензије са
for
, при чему је најбоље да се бројач
i
креће од један до девет, јер се тада у кораку i
црта линија
од тачке (i*dx, 0)
до тачке (i*dx, visina)
. Цртање
хоризонталних линија остварујемо веома слично, у независној петљи
for
у којој се црта линија од тачке (0, i*dy)
до тачке
(sirina, i*dy)
.
import pygame as pg
import pygamebg
(sirina, visina) = (400, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Pravougaona mreza")
# bojimo pozadinu prozora u belo
prozor.fill(pg.Color("white"))
brojPodeoka = 10
dx = sirina / brojPodeoka
dy = ??? # izračunaj razmak između podeoka po visini
# crtamo horizontalne linije
for i in range(1, brojPodeoka):
pg.draw.line(prozor, pg.Color("blue"), (0, i*dy), (sirina, i*dy), 5)
# dodaj kôd koji crta vertikalne linije crvenom bojom
???
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(pravougaona_mreza)
Још један начин да се одреди координата наредне линије је да се координата претходне линије увећа за ширину, тј. дужину правоугаоника.
x = dx
for i in range(1, brojPodeoka):
pg.draw.line(prozor, pg.Color("red"), (x, 0), (x, visina), 5)
x += dx
(pravougaona_mreza_alt)
Шарање ротираним дужима¶

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

Иако шара изгледа на први поглед прилично различито, овај програм је
заправо прилично сличан претходном. Прва дуж спаја тачке се
координатама i
креће од 1
до n-1
,
у чијем телу цртамо дуж која спаја тачке са координатама (0, i*dy)
и (i*dx, visina)
. Ако би се бројач у петљи мењао од 0
до
n
, тада би се цртале и прва вертикална и последња хоризонтална дуж
(oне се не виде, јер се поклапају са ивицама прозора).
На основу претходне дискусије допуни наредни програм:
import pygame as pg
import pygamebg
(sirina, visina) = (400, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Rotirane duzi")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(rotirane_duzi)

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

Пажљиво анализирај координате крајњих тачака дужи, уочи правилности, експериментиши и покушај тако да дођеш до решења.
import pygame as pg
import pygamebg
(sirina, visina) = (400, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Rotirane duzi")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(rotirane_duzi2)
Крешендо¶

Напиши програм који исцртава 100 паралелних вертикалних линија равномерно распоређених ширином прозора, тако да дужина тих линија равномерно расте од нуле па до висине прозора.
import pygame as pg
import pygamebg
(sirina, visina) = (800, 200) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Kresendo")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(kresendo)
Лоптице¶

Напиши програм који исцртава лоптице хоризонтално распоређене по средини висине прозора, које се међусобно додирују, тако да је полупречник прве 10 пиксела, а полупречник сваке наредне за 10 пиксела већи од претходне. Лоптице су наизменично црвене, зелене, плаве и жуте боје (и тако у круг).
import pygame as pg
import pygamebg
(sirina, visina) = (800, 200) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Sarene loptice")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(loptice.py)
Згуснуте линије¶

Нацртај цртеж у ком се 10 усправних линија удаљава једна од друге за размак који је 10% већи од размака претходне две линије. Линије се удаљавају како се померамо ка десној страни прозора. Размак између прве две линије је 20 пиксела.
import pygame as pg
import pygamebg
(sirina, visina) = (400, 400) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Zgusnute linije")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(zgusnute_linije)
Цигле¶
Редови цигала наизменично почињу целом циглом и половином цигле. Нека
је ширина цигле означена са -s // 2
. Тако постижемо да се види
само десна половина цигле. Остаје нам да решимо када цртамо померену циглу,
а када не.
Једно од решења је да место почетка реда цигала чувамо у променљивој,
назовимо је x_poc
. После сваког исцртаног реда, проверавамо да ли
променљива x_poc
има вредност нула или -s // 2
. Коју год
од ове две вредности променљива имала, доделићемо јој ону другу
вредност, да би у следећем реду цртање цигала почело другачије.
Нагласимо да корак у петљи мора бити целобројна вредност тако да пола ширине цигле морамо израчунати целобројним дељењем.
import pygame as pg
import pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Cigle")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(PyGame_loops_bricks1)
Тараба¶

Напиши програм који црта сеоску ограду (тарабу).
Сваку притку ограде представићемо у облику многоугла. Да бисмо притке
могли да цртамо на различитим позицијама, потребно је да координате
тог многоугла буду задате релативно. Пошто ће све притке бити увек на
истој висини (истој
Један начин је да у задавању темена притке користимо променљиву x
,
која се мења у петљи. Када би се притке померале и на горе или на
доле, онда би у задавању темена учествовала и променљива y.
for x in range(20, 300, 40):
pg.draw.polygon(prozor, pg.Color('brown'),
[(x, 80), (x + 10, 70), (x + 20, 80), (x + 20, 270), (x, 270)])
(ograda_1nacin)
Можемо и да уведемо функцију која црта притку у односу на њену
релативно задату
def pritka(x):
temena = [(x, 80), (x+10, 70), (x+20, 80), (x+20, 270), (x, 270)]
pg.draw.polygon(prozor, boja, temena)
for x in range(20, 300, 40):
pritka(x)
(ograda_2nacin)
Још једна могућност је да приликом цртања пресликамо координате основне листе (коришћењем компрехенсије тј. скуповне нотације за листе).
temena = [(20, 80), (30, 70), (40, 80), (40, 270), (20, 270)]
for i in range(7):
pg.draw.polygon(prozor, pg.Color('brown'), [(x + 40*i, y) for (x,y) in temena])
(ograda_3nacin)
Коришћењем било ког од наведених решења нацртај тарабу.
import pygame as pg
import pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Taraba")
???
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(PyGame_loops_fence)