Гузариш ба мундариҷа
Мавзӯи 2 аз 6

Равзана, шаклҳо ва Batch

Равзана ва шаклҳо барои чӣ лозиманд

Намоиши оғоз, бозӣ ва воситаи тасвирсозӣ вазифаи умумӣ доранд: объектҳои саҳнаро нигоҳ доштан ва дар равзана нишон додан. pyglet Python-ро бо низоми равзанаҳо, OpenGL ва воситаҳои навохтани садо мепайвандад. Дар ин курс аз ин қисмҳо тадриҷан намоиши аниматсионии оғоз бо мусиқӣ месозем.

Аввал се амалро ҷудо мекунем: сохтани равзана, сохтани объектҳо ва кашидани кадр. Координатаҳо ва андозаҳо ададҳои одӣ ҳастанд; китобхонаи графикӣ онҳоро ба тасвир табдил медиҳад. Аз ҳамин сабаб хатои ҷойгиркуниро пеш аз оғози аниматсия аз рӯйи ададҳо ёфтан қулай аст.

1. Равзана ва давраи кори он

Window объекти равзана ва муҳити графикии он аст: муҳите, ки OpenGL дар он тасвир мекашад. Дар мисолҳо равзана бо visible=False пинҳон аст, то барнома баъди санҷиш худаш анҷом ёбад. Барои дидани равзана ин аргументро гиред.

import pyglet
window = pyglet.window.Window(240, 160, visible=False)
print(window.get_size())
window.close()

Натиҷа:

(240, 160)

Андоза ҷуфти «паҳно, баландӣ» аст. Баъди close() равзана баста мешавад; дар он дигар шакли нав сохтан лозим нест. Дар барномаи интерактивӣ равзанаро кушода мемонанд, коркарди on_draw-ро бо декоратори @window.event эълон мекунанд ва сипас pyglet.app.run()-ро даъват мекунанд.

Давраи рӯйдодҳо паёмҳои низоми амалкунандаро гирифта, коркардкунандаҳои мувофиқро даъват мекунад. on_draw барои кадр масъул аст: одатан аввал window.clear(), сипас кашидан. Худи app.run() дар саҳна объект намесозад ва то баста шудани равзанаҳо ё даъвати pyglet.app.exit() кор мекунад.

2. Координатаҳо ва нуқтаҳои такягоҳи гуногун

Дар проексияи пешфарз (0, 0) дар кунҷи чапи поён аст. Зиёд кардани x объектро ба рост ва зиёд кардани y онро ба боло мебарад. Барои Rectangle координатаҳо кунҷи чапи поён, барои Circle марказ мебошанд. Line оғоз (x, y) ва анҷом (x2, y2) дорад; thickness ғафсии онро муайян мекунад.

Batch гурӯҳи маълумот барои якҷоя кашидан аст. Як Batch-ро ба се шакл дода, ҳар кадомро дар тағйирёбанда нигоҳ медорем. Мисоли навбатӣ дар равзанаи пинҳон як кадр кашида, геометрияро чоп мекунад.

import pyglet
window = pyglet.window.Window(240, 160, visible=False)
batch = pyglet.graphics.Batch()
rect = pyglet.shapes.Rectangle(10, 20, 40, 30, batch=batch)
circle = pyglet.shapes.Circle(100, 80, 12, batch=batch)
line = pyglet.shapes.Line(0, 0, 30, 40, thickness=2, batch=batch)
window.clear()
batch.draw()
print(rect.x, rect.y, rect.width, rect.height)
print(circle.radius, line.thickness)
window.close()

Натиҷа:

10 20 40 30
12 2

Канори рости росткунҷа дар x + width ва канори болояш дар y + height аст. Канори рости доира дар x + radius аст. Қиматҳои яксони x, y маънои яксон будани кунҷҳои ин шаклҳоро надоранд: аввал муайян кунед, ки координатаҳо ба кадом нуқта тааллуқ доранд.

3. Тағйир додани объекти тайёр

Барои ҳар ҳаракат шаклро аз нав сохтан лозим нест. Хосиятҳои объект маълумоти графикии онро нав мекунанд ва кашидани навбатӣ қиматҳои навро истифода мебарад. RGB се ҷузъи ранг аз 0 то 255 аст; opacity ношаффофиро аз 0 то 255 муайян мекунад, ки дар 0 шакл пурра шаффоф аст.

import pyglet
window = pyglet.window.Window(240, 160, visible=False)
rect = pyglet.shapes.Rectangle(10, 20, 40, 30)
rect.x += 5
rect.height = 50
rect.color = (20, 180, 90)
rect.opacity = 128
print(rect.x, rect.height, rect.color)
window.close()

Натиҷа:

15 50 (20, 180, 90, 128)

Дар pyglet 2.1.19 хондани color чор ҷузъи RGBA-ро бармегардонад: ҷузъи охир ношаффофии ҷорӣ аст. Ношаффофии 128 андоза ё мавқеи объектро тағйир намедиҳад. Доираи radius=0 ва шакли шаффоф метавонанд ҳамчун объект вуҷуд дошта бошанд, ҳатто агар чизе намоён накашанд.

4. Вақте сатрҳо аз боло ба поён мераванд

Дар харитаи матнӣ сатри навбатӣ одатан аз сатри пешина поёнтар аст, гарчанде рақамаш калонтар бошад. Баландии сатри болоро интихоб карда, бо афзудани рақами сатр онро кам кунед. Дар ин ҷо номи сатрҳо ва баландиҳоро чоп мекунем ва харитаи пурраи шаклҳо намесозем.

rows = ["ab", "cd", "ef"]
top = 90
cell = 10
for row, text in enumerate(rows):
    print(text, top - row * cell)

Натиҷа:

ab 90
cd 80
ef 70

Қадами cell масофаи байни сатрҳоро муайян мекунад; он ҳатман ба андозаи мураббаъи кашидашуда баробар нест. Агар мураббаъ аз қадам каме хурд бошад, байни катакҳо фосила пайдо мешавад. Мавқеи тамоми харита ва мавқеи як катакро алоҳида ҳисоб кардан фоиданок аст: ҷобаҷогузории нодуруст осонтар ёфт мешавад.

5. Нуқтаҳо дар рӯйи давра

Синус ва косинус кунҷро ба ҷобаҷогузорӣ дар ду меҳвар табдил медиҳанд. math.sin ва math.cos кунҷро бо радиан мегиранд: гардиши пурра 2 * math.pi аст. Дар тарзи маъмули математикӣ кунҷи сифр ба рост нигаронда шуда, кунҷҳои мусбат муқобили самти ақрабаки соат мераванд.

import math
cx, cy, r = 40, 30, 10
for angle in (0, math.pi / 2, math.pi):
    x = cx + r * math.cos(angle)
    y = cy + r * math.sin(angle)
    print(round(x), round(y))

Натиҷа:

50 30
40 40
30 30

Дар ин мисол маҳз ҳамин қоидаи кунҷ истифода шудааст. Барои соат, қутбнамо ё нишондиҳандаи дигар аввал муайян кунед, ки ҳисоб аз куҷо оғоз шуда, гардиш ба кадом самт меравад. round танҳо координатаҳои чопшударо бутун мекунад; худи ҳисобҳо координатаҳои касриро истифода мебаранд.

Кашидан дар дохил чӣ гуна кор мекунад

Шакл геометрия, ранг ва маълумоти қуллаҳоро барои OpenGL нигоҳ медорад. Тағйири хосият маълумоти мувофиқро нав мекунад. Batch маълумоти мувофиқро ташкил карда, муроҷиатҳои алоҳида ба низоми графикиро кам мекунад. Як batch.draw() метавонад чанд фармони дохилӣ дошта бошад, бинобар ин он ваъдаи маҳз як фармон ба корти графикӣ нест.

Batch рӯйхати объектҳои шуморо иваз намекунад: шаклҳоро дар тағйирёбанда ё маҷмуа нигоҳ доред. Баъди гум шудани истиноди охир объект бо маълумоти графикиаш нест шуда метавонад. Барои тартиби қабатҳо Group(order=...)-ро истифода баред: тартиби сохтани шаклҳо дар як Batch роҳи боэътимоди таъини қабатҳо нест.

Хатоҳои маъмул ва ислоҳи онҳо

  1. Барои ҳаракат ба поён rect.y += 10 навиштан. Дар координатаҳои пешфарз шакл боло меравад. Барои поён рафтан y-ро кам кунед.
  2. Circle(x, y, r)-ро доирае шуморидан, ки кунҷаш дар (x, y) аст. Доира аз ҷойи интизорӣ ба андозаи радиус кӯчида мемонад. Координатаҳои марказро диҳед.
  3. pyglet.shapes.Circle(20, 20, 5, batch=batch) сохтан ва истинодро нигоҳ надоштан. Ҳангоми нест шудани объект он ғайб зада метавонад. Натиҷаро ба тағйирёбанда ё рӯйхат гузоред.
  4. math.sin(90) навишта, 90 дараҷаро интизор шудан. Функсия 90 радианро ҳисоб мекунад. math.radians(90) ё math.pi / 2-ро истифода баред.
  5. batch.draw()-ро танҳо пеш аз app.run() даъват кардан. Баъди тоза ё пӯшида шудани равзана рамзи шумо тасвирро барқарор намекунад. Саҳнаро дар on_draw кашед ва аввал ҳар кадрро тоза кунед.

Ёддошти кӯтоҳ

Вазифа Восита
Сохтани равзана pyglet.window.Window(width, height)
Аз нав кашидани кадр on_draw: window.clear(), сипас batch.draw()
Оғози коркарди рӯйдодҳо pyglet.app.run()
Росткунҷа / доира / порча shapes.Rectangle / Circle / Line
Тағйири объект x, y, width, height, radius, color, opacity
Нигоҳ доштани шаклҳо тағйирёбандаҳо ва рӯйхатҳо; Batch соҳиби онҳо нест
Табдили дараҷа ба радиан math.radians(degrees)

Дар масъалаҳо равзана зери if __name__ == "__main__": ҷойгир аст. Ҳангоми ирсол санҷиш функсияҳоро бе равзанаи интерактивӣ даъват мекунад, бинобар ин геометрияи дуруст бояд аз додаҳои воридотӣ ҳосил шавад, на аз мушоҳидаи экран.