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

Реаговање на догађаје мишем - напреднији примери

Топло-хладно

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

У функцији crtaj одређујемо нијансу црвене боје у зависности од близине непознате тачке тренутној позицији миша (обе позиције ћемо памтити у глобалним променљивима). Питагорином теоремом лако можемо израчунати растојање између непознате тачке и текуће позиције миша. Желимо да најдаља тачка од непознате унутар прозора буде обојена црно (да је нијанса црвене боје 0), а да сама тачка буде обојена црвено (да је нијанса црвене боје 255). Најдаља тачка је сигурно неко од 4 темена прозора. Зато тражимо максимум од 4 растојања (нека је то M) и постављамо пропорцију тј. одређујемо линеарну функцију која пресликава вредност M у 0, а вредност 0 у 255 (то је функција \(f(x) = \frac{-255 \cdot x}{M} + 255\). Плаву и зелену нијансу ћемо све време држати на нули. Логичком променљивом ћемо одређивати и да ли се приликом цртања приказује непозната тачка или не.

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

Кругови мишем

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

У односу на претходне задатке, кључна новина у овом задатку је то што је након притиска дугмета миша потребно знати координате на екрану на којима се миш налазио у тренутку када је дугме притиснуто. То је, међутим, веома лако одредити, пошто догађаји миша имају поље dogadjaj.pos које садржи управо уређени пар координата на којима се миш налазио.

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

Цртање помоћу миша

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

Да бисмо задатак могли решити потребно је да реагујемо на догађај померања миша pg.MOUSEMOTION. Након детекције овог догађаја морамо проверити да ли је током померања било притиснуто лево дугме миша (то можемо урадити провером логичке вредности dogadjaj.buttons[0]). Након сваког померања на цртеж је потребно додати дуж која спаја позицију на којој је миш након померања (њу очитавамо помоћу dogadjaj.pos) и позицију на којој је миш био пре померања (њу можемо одредити сабирањем координата парова dogadjaj.pos и dogadjaj.rel).

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

Задатак смо могли решити и без коришћења поља dogadjaj.buttons и dogadjaj.rel. Можемо памтити претходу позицију миша (за то користимо променљиву prethodna_pos) као и податак о томе да ли је дугме притиснуто (за то користимо логичку променљиву crtanje). Када се региструје догађај pg.MOUSEBUTTONDOWN тада иницијализујемо претходну позицију и региструјемо да је дугме притиснуто. Док се догађају догађаји pg.MOUSEMOTION проверавамо да ли је дугме притиснуто и ако јесте цртамо линијице од претходне до тренутне позиције миша. Када се региструје догађај pg.MOUSEBUTTONUP тада памтимо да дугме више није притиснуто.

Двобој

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

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

Кључно место у задатку је како насумично одредити победника битке. Ако прва снага има a војника, а друга b војника (те две вредности чувамо у глобалним променљивама), тада можемо генерисати насумичан број између 1 и a+b и прву војску прогласити за победничку ако је извучен број који је мањи или једнак a.

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

Приликом обраде догађаја реагујемо на догађај клика мишем. Гранањем одређујемо да ли је кликнуто у левом, централном или десном делу прозора (у левом делу је координата x између нуле и ширине слике мишића, у десном је координата x између ширине прозора умањене за ширину те слике и ширине прозора, док се све остало сматра централним делом). Ако је кликнуто у левом или десном делу прозора, проверава се којим је дугметом кликнуто (испитивањем вредности dogadjaj.button). Ако је кликнуто левим дугметом (вредност 1), и ако је снага одговарајућег играча мања од максималне (то је, на пример, 10), тада се снага увећава, а кликнуто десним дугметом (вредност 3) и ако је снага одговарајућег играча већа од минималне (то је вредност 1), тада се снага умањује. Ако је кликнуто средњим дугметом, тада се насумично одређује победник (на начин који смо описали). У свим случајевима се сигнализира да се сцена поново исцрта.

../_images/misic.png

Очи које прате миша

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

Кључно питање је како на основу положаја миша и на основу познатог центра и полупречника ока одредити центар зенице. Претпоставимо да око има центар у тачки \(O\) и да му је полупречник \(R\), док се миш налази у тачки \(M\). Претпоставимо и да ће пречник зенице бити дупло мањи од полупречника ока. Нека је центар зенице тачка \(C\) и нека су \(C_x\) и \(C_y\) њене пројекције на осе, док су \(M_x\) и \(M_y\) пројекције тачке \(M\) на осе.

../_images/oci_koordinate.png

Троуглови \(OC_xC\) и \(OM_xM\) су слични, па је однос \(OC_x : OM_x = OC : OM\). Величина \(OM_x\) се израчунава као разлика x координата центра ока и позиције миша, \(OM\) је растојање између те две тачке, док је \(OC\) полупречник зенице тј. пола полупречника ока. Одатле можемо израчунати дужину \(OC_x\), а пошто знамо координате тачке \(O\), одатле и координату x центра зенице. Координата x центра зенице се може израчунати аналогно. Обратимо пажњу на специјални случај у ком се тачке \(O\) и \(M\) поклапају (тада нам једино преостаје да центар зенице поставимо у тачку \(O\)).