Спрайтҳо ва рӯйхатҳои спрайтҳо
Ин барои чӣ лозим аст
Қариб ҳама чизе, ки дар бозӣ намоён аст, — спрайтҳо мебошанд: бозингар, тангаҳо, тирҳо, душманон, платформаҳо. Спрайт мавқеъ, андоза, тасвир ва суръат дорад. Дар arcade спрайтҳо маводи асосии сохтмонӣ мебошанд: бархӯрдҳо, физика ва расмкашии тез дар онҳо кор мекунанд.
Дар бозӣ одатан спрайтҳо бисёранд, бинобар ин онҳоро дар рӯйхатҳои спрайтҳо (SpriteList) нигоҳ медоранд. Дар ин мавзӯъ мебинем, ки чӣ тавр спрайт сохтан, онро ҳаракат додан ва аз канор набаровардан, бисёр спрайтҳоро нигоҳ доштан ва нолозимҳоро дуруст хориҷ кардан мумкин аст.
Қадами 1. Спрайт месозем
Спрайтро аз тасвир ё аз шакли оддӣ сохтан мумкин аст — барои бозиҳои таълимӣ дуюмӣ қулайтар аст, файлҳо лозим нестанд:
player = arcade.Sprite("player.png", scale=0.5) # аз тасвир, ду баробар хурд
box = arcade.SpriteSolidColor(40, 40, color=arcade.color.RED) # росткунҷаи рангаи 40 × 40
coin = arcade.SpriteCircle(10, arcade.color.GOLD) # доираи радиусаш 10
Мавқеи спрайт — маркази он аст: center_x, center_y ё ҷуфти position.
import arcade
box = arcade.SpriteSolidColor(40, 20, center_x=100, center_y=50)
print(box.position, box.width, box.height)
box.position = (300, 200)
print(box.center_x, box.center_y)
Натиҷа:
(100, 50) 40.0 20.0
300 200
Марказ ҳамон тавре нигоҳ дошта мешавад, ки онро доданд (дар ин ҷо — бо ададҳои бутун), андозаҳо ва тарафҳо бошанд ададҳои касрӣ (float) мебошанд, бинобар ин бо .0 чоп мешаванд. Дар хотир доред: дар arcade y ба боло меафзояд.
Қадами 2. Тарафҳои спрайт
Ғайр аз марказ спрайт тарафҳо дорад: left, right, bottom, top. Онҳо аз марказ ва андоза ҳисоб карда мешаванд: тарафи чап — ба нисфи бар аз марказ чаптар, болоӣ — ба нисфи баландӣ болотар.
import arcade
s = arcade.SpriteSolidColor(40, 20, center_x=100, center_y=50)
print(s.left, s.right, s.bottom, s.top)
Натиҷа:
80.0 120.0 40.0 60.0
Тарафҳоро на танҳо хондан, балки таъин кардан ҳам мумкин аст — он гоҳ тамоми спрайт мекӯчад, андоза тағйир намеёбад:
import arcade
s = arcade.SpriteSolidColor(40, 20, center_x=100, center_y=50)
s.right = 400 # канори рост дар 400
print(s.center_x)
s.bottom = 0 # канори поён дар «фарш»
print(s.center_y)
Натиҷа:
380.0
10.0
Ин барои ба девор ё фарш зич гузоштани объект қулай аст: марказро тавассути нисфи андоза ҳисоб кардан лозим нест.
Қадами 3. Марказ ё канор?
Хатои маъмул — санҷидани баромадан аз сарҳад аз рӯи марказ. Маркази киштӣ шояд ҳанӯз дар дохили равзана бошад, вале нисфи киштӣ аллакай берун аст:
import arcade
ship = arcade.SpriteSolidColor(60, 30, center_x=10, center_y=300)
W = 800
print(ship.center_x >= 0, ship.left >= 0)
print(ship.left)
Натиҷа:
True False
-20.0
Аз рӯи марказ «ҳама чиз хуб аст», вале сеяки чапи киштӣ аллакай аз канор берун аст. Бо сарҳадҳои равзана он тараф-ро муқоиса кардан лозим аст, ки ба ин сарҳад наздиктар аст: чапро — бо 0, ростро — бо бар, поёниро — бо 0, болоиро — бо баландӣ.
Қадами 4. Суръат: change_x ва change_y
Ҳар спрайт майдонҳои change_x ва change_y дорад — суръати он бо пиксел дар як кадр. Худи онҳо ҳеҷ чизро ҳаракат намедиҳанд: онҳоро ба координатаҳо бозӣ дар on_update илова мекунад (ё муҳаррики физикӣ — дар бораи он дар мавзӯи физика).
import arcade
enemy = arcade.SpriteSolidColor(20, 20, center_x=0, center_y=0)
enemy.change_x = 5
for frame in range(3):
enemy.center_x += enemy.change_x
print(enemy.center_x)
Натиҷа:
15
Спрайт инчунин методи тайёри update() дорад, ки ҳамин корро мекунад — change_x ва change_y-ро ба мавқеъ илова мекунад:
import arcade
s = arcade.SpriteSolidColor(10, 10, center_x=0, center_y=0)
s.change_x, s.change_y = 3, -2
s.update()
s.update()
print(s.position)
Натиҷа:
(6.0, -4.0)
Баргаштан — иваз кардани аломати суръат. Агар объект метавонад паси сарҳад монад, change_x = -change_x-и оддӣ онро ба ин сӯ ва он сӯ «такон медиҳад». Боэътимодтар аст, ки самтро ошкоро таъин кунем: abs(change_x) — ҳамеша ба рост, -abs(change_x) — ҳамеша ба чап. Ва объектро ба сарҳад баргардонем, то берун намонад.
Қадами 5. Рӯйхати спрайтҳо
Спрайтҳоро дар arcade.SpriteList нигоҳ медоранд. Он ба рӯйхати оддӣ монанд аст, вале ҳамаи спрайтҳоро бо як даъват-и видеокорт кашида метавонад — ин чандин маротиба аз кашидан якто-якто тезтар аст.
import arcade
coins = arcade.SpriteList()
for i in range(3):
coins.append(arcade.SpriteCircle(5, arcade.color.GOLD))
print(len(coins))
for i, c in enumerate(coins):
c.center_x = i * 50
print([c.center_x for c in coins])
Натиҷа:
3
[0, 50, 100]
Дар бозӣ рӯйхатро дар on_draw мекашанд:
def on_draw(self):
self.clear()
self.coins.draw()
Қадами 6. Хориҷ кардани спрайтҳо
Спрайтро аз ҳамаи рӯйхатҳое, ки дар онҳо ҳаст, хориҷ кардан — sprite.remove_from_sprite_lists(). Ҳамин тавр тангаҳои ҷамъшуда, душманони нестшуда, тирҳои аз экран паридаро хориҷ мекунанд.
import arcade
a = arcade.SpriteSolidColor(2, 2)
b = arcade.SpriteSolidColor(2, 2)
everything = arcade.SpriteList()
enemies = arcade.SpriteList()
for s in (a, b):
everything.append(s)
enemies.append(s)
a.remove_from_sprite_lists()
print(len(everything), len(enemies))
Натиҷа:
1 1
Дом. Аз рӯйхате, ки давр аз рӯи он меравад, унсурҳоро хориҷ кардан мумкин нест: унсурҳо мекӯчанд ва давр аз болои ҳамсоя меҷаҳад. Агар спрайтҳои «фаромӯшшуда» дар рӯйхат то абад монанд, бозӣ бо мурури вақт суст шуданро сар мекунад.
Яке аз роҳҳои боэътимод — аввал он чиро, ки хориҷ кардан лозим аст, ба рӯйхати оддии алоҳида ҷамъ кардан ва баъд хориҷ кардан:
import arcade
rocks = arcade.SpriteList()
for y in (10, 500, 700, 20):
rocks.append(arcade.SpriteSolidColor(4, 4, center_x=0, center_y=y))
gone = [r for r in rocks if r.bottom > 400] # онҳое, ки аз 400 болотар париданд
for r in gone:
r.remove_from_sprite_lists()
print(len(rocks))
Натиҷа:
2
Роҳи дуюм — на худи рӯйхатро, балки нусха-и онро гузаштан: он гоҳ хориҷкунӣ аз асл ба давр халал намерасонад.
Дар дохил чӣ тавр кор мекунад
SpriteList координатаҳо, андозаҳо ва текстураҳои ҳамаи спрайтҳояшро дар хотираи видеокорт ҳамчун як массиви калон нигоҳ медорад. draw() — як фармони «тамоми массивро каш» аст, на сад фармони алоҳида. Вақте ки шумо center_x-ро тағйир медиҳед, arcade қайд мекунад, ки маълумот тағйир ёфт ва пеш аз расмкашии навбатӣ ба видеокорт танҳо навсозиҳоро мефиристад.
Тарафҳои спрайт (left, top ва ғайра) дар ҳеҷ ҷо алоҳида нигоҳ дошта намешаванд: онҳо аз марказ ва андозаҳо ҳисоб карда мешаванд, таъини тараф бошад марказро аз нав ҳисоб мекунад.
Хатоҳои маъмул
1. Санҷиши сарҳад аз рӯи марказ. Объект нисфан аз канор берун меравад. Тарафҳои спрайтро муқоиса кунед.
2. Боло ва поён омехта шудаанд. Дар arcade болои равзана — y = баландӣ, поён — y = 0. top-ро бо баландӣ, bottom-ро бо сифр муқоиса мекунанд.
3. Хориҷкунӣ ҳангоми гузариш. Қисми спрайтҳо гузаронида мешаванд ва дар рӯйхат то абад мемонанд.
4. change_x = -change_x дар назди сарҳад. Объект паси сарҳад дар ҷояш меларзад. Самтро тавассути abs таъин кунед ва объектро ба сарҳад баргардонед.
5. Аз чор тараф танҳо ду тараф маҳдуд шуд. Объект ба чап ва поён намеравад, вале ба рост ва боло озодона мепарад.
Варақаи ёддошт
| Чӣ | Код |
|---|---|
| спрайт аз тасвир | arcade.Sprite("file.png", scale=0.5) |
| росткунҷаи ранга | arcade.SpriteSolidColor(w, h, center_x=…, center_y=…, color=…) |
| доира | arcade.SpriteCircle(r, color) |
| мавқеъ (марказ) | s.center_x, s.center_y, s.position |
| тарафҳо | s.left, s.right, s.bottom, s.top (таъин кардан мумкин) |
| андоза | s.width, s.height |
| суръат | s.change_x, s.change_y; кӯчиш — s.update() |
| ҳамеша ба рост / чап | abs(v) / -abs(v) |
| рӯйхати спрайтҳо | lst = arcade.SpriteList(), lst.append(s), len(lst) |
| ҳамаро кашидан | lst.draw() |
| хориҷ кардани спрайт | s.remove_from_sprite_lists() |
| хориҷкунии бехатар | хориҷшавандаҳоро алоҳида ҷамъ кардан ё нусхаро гузаштан |