Бозии хурди шахси аввал
Чаро бозӣ ҳадаф ва ҳолат мехоҳад
Саҳна вақте бозӣ мешавад, ки амал натиҷа дошта бошад: ҷамъ кардани ашё, то анҷоми давр расидан ва гирифтани бозхӯрди равшан. Дар бозии хурди шахси аввал қисмҳои шиносро якҷо мекунем: Entity, collider, ҳаракат, камера ва вақт. Вазифаи нав ҳамоҳанг кардани ҳолат, яъне маълумот дар бораи вазъи ҷорӣ аст.
Барои равзана Ursina(), сипас фарши дорои collider="box" ва FirstPersonController аз ursina.prefabs.first_person_controller месозанд. Он WASD, нигоҳи муш, ҷаҳиш ва ҷозибаро медиҳад. Деворҳо низ collider мехоҳанд. Мисолҳои хурди поён маълумоти бозиро аз даври пайвастаи равзана ҷудо меомӯзанд; ҳар яке мустақил иҷро мешавад.
Мавқеи бозигар ва масофа
Дар FirstPersonController position ба пойҳо мувофиқ аст. Барои гирифтани ашёи баланд онро бо нуқтаи наздиктар ба маркази бадан муқоиса кардан қулай аст. distance ҳар се координатаро ба ҳисоб мегирад: ашёи болои сар дар харита наздик, аммо дар фазо дур буда метавонад.
from ursina import Vec3, distance
feet = Vec3(0, 0, 0)
body = feet + Vec3(0, 1, 0)
item = Vec3(0, 4, 0)
print(distance(feet, item))
print(distance(body, item))
Натиҷа:
4.0
3.0
Рӯйхат ва саҳна анборҳои ҷудоянд
Рӯйхати crystals истинодҳоро ба объектҳо нигоҳ медорад ва саҳна Entity-ҳои бозиро. destroy(entity) объектро аз саҳна гирифта, навсозӣ ва тасвири маъмулии онро қатъ мекунад. Ин фармон ҳамаи истинодҳоро аз рӯйхатҳои шумо нест намекунад. Баръакс, list.remove ҳам Entity-ро нест намекунад.
from ursina import Entity, destroy
item = Entity()
items = [item]
print(item.is_empty())
destroy(item)
print(item.is_empty())
print(len(items))
Натиҷа:
False
True
1
is_empty() месанҷад, ки гиреҳи Panda3D нест шудааст ё не. Пас аз destroy гиреҳ холӣ аст, аммо дарозии рӯйхати одӣ тағйир наёфт. Ursina 8.3 рӯйхати дохилии саҳнаро ҳангоми коркарди кадр тоза мекунад, бинобар ин набудани фаврӣ дар scene.entities санҷиши боэътимоди нестшавӣ нест.
Ҳангоми тағйир додани рӯйхат дар вақти гузариш индексҳо ҷобаҷо шуда, унсури навбатӣ метавонад гузаронда шавад. Усули умумии бехатар гузаштан аз нусхаи list(items) ва тағйир додани асл аст. Ин нусхаи сатҳӣ мебошад: рӯйхат нав аст, аммо объектҳои дохил ҳамонанд. Танҳо рафтори Python-ро бо ададҳо мебинем, бе функсияи тайёри ҷамъкунӣ.
items = [1, 2, 3]
snapshot = list(items)
items.remove(1)
print(items)
print(snapshot)
Натиҷа:
[2, 3]
[1, 2, 3]
Интерфейс ва маълумот
Text навиштаи интерфейсро нишон медиҳад. Волидайни маъмулии он camera.ui аст, пас position дар фазои интерфейс дода мешавад, на бо метрҳои сатҳ. Навиштаро як бор баъди Ursina(), масалан label = Text("0", position=(-0.85, 0.45)), созед ва сипас label.text-ро иваз кунед. Ҳар кадр Text-и нав сохтан лозим нест.
Ҳисобро ҳамчун адад нигоҳ дошта, навиштаро аз он гиред. Сатри интерфейс намоиши маълумот аст, на ягона манбаи ҳолат. Он гоҳ забони навиштаро бе тағйир додани ҳисоби хол иваз кардан мумкин аст.
state = {"score": 2, "running": True}
state["score"] += 1
label_text = f"{state['score']:02d}"
print(label_text)
print(state["running"])
Натиҷа:
03
True
Вақти боқимонда ва қолаб
Вақти бозиро бо time.dt ҷамъ мекунанд. Вақти боқимонда фарқи маҳдудият ва вақти гузашта аст. Барои намоиш сонияи мусбати касриро бо math.ceil ба боло гирд мекунанд: то имкони амал ҳаст, интерфейс набояд барвақт сифр нишон диҳад. Пас аз анҷом қимати манфиро ба сифр маҳдуд мекунанд. Инҳо ду қадами ҷудоянд.
import math
for value in (7.0, 7.1, 0.2):
print(math.ceil(value))
print(max(0, -3))
Натиҷа:
7
8
1
0
Барои навишти вақт дақиқаҳои пурра ва бақияи сонияҳо лозиманд. divmod ҳам ҳосили тақсим ва ҳам бақияро медиҳад. Қолаби :02d адади бутунро ақаллан бо ду рақам чоп карда, аз пеш сифр мегузорад. Дар ин ҷо танҳо адади бутуни тайёри сонияҳоро қолаббандӣ мекунем, на тамоми функсияи таймерро.
seconds = 187
minutes, rest = divmod(seconds, 60)
print(minutes, rest)
print(f"{minutes}:{rest:02d}")
Натиҷа:
3 7
3:07
Пас аз бурд ё бохт ҳолати давр бояд дигар тағйир наёбад. Доштани running ва санҷиши он дар update() қулай аст. player.enabled = False контроллерро хомӯш мекунад, аммо update()-и умумии шумо аз ин нест намешавад. Рӯйдоди таъхирдорро бо invoke(callback, delay=2) таъин кардан мумкин аст; функсияро бе қавс диҳед, вагарна фавран иҷро мешавад.
Харитаи сатҳ ва роҳи кӯтоҳтарин
Дар харитаи сатрӣ ҳуҷайраи (row, col) ба мавқеи ҷаҳонии (col, y, row) мувофиқ аст. Баландиро мувофиқи ашё мегиранд: масалан, маркази девори баландияш 2 дар y=1 аст. # девор, . роҳ ва o ашё мебошад. Ҳангоми ҷамъкунӣ саҳна, маҷмӯаи объектҳо ва харитаро ҳамоҳанг нав кардан лозим аст, вагарна ишора ба ҳуҷайраи аллакай холӣ мебарад.
row, col = 2, 4
world_position = (col, 1, row)
print(world_position)
Натиҷа:
(4, 1, 2)
Масофаи рост деворҳоро ба ҳисоб намегирад. Ҷустуҷӯ дар паҳно (BFS) дар ҳуҷайраҳои ҳамсоя мавҷвор паҳн мешавад: аввал масофаи 0, баъд 1 ва сипас 2. Навбат ҳуҷайраҳои коркарднашударо бо тартиби воридшавӣ нигоҳ медорад. collections.deque аз рост илова ва аз чап мегирад: FIFO, аввал ворид шуд, аввал баромад.
from collections import deque
queue = deque([(0, 0)])
current = queue.popleft()
queue.append((0, 1))
queue.append((1, 0))
print(current)
print(queue.popleft())
print(list(queue))
Натиҷа:
(0, 0)
(0, 1)
[(1, 0)]
Дар BFS масофаи ёфтаи ҳуҷайра нигоҳ дошта шуда, ҳангоми илова ба навбат он ҳамчун дидашуда қайд мешавад. Ин бозгаштҳои беохир байни ҳамсояҳоро пешгирӣ мекунад. Барои қадамҳои ҳамарзиш навбат кафолат медиҳад: роҳи дарозтар пеш аз кӯтоҳтар коркард намешавад. Ҳуҷайраи оғозро ҳам санҷед; навбати холӣ бе ҳадафи ёфта маънои дастнорасиро дорад. Гузариши пурраи харита бо ҳудуду деворҳо вазифаи шумост.
Хатоҳои маъмул ва ислоҳи онҳо
- for item in items ҳамроҳи items.remove(item) аз сабаби ҷобаҷоии индексҳо унсурҳоро мегузаронад. Аз нусха гузаред.
- Танҳо destroy(item) дар рӯйхати шумо истинод мегузорад ва ашё метавонад боз ҳисоб шавад. Ҳар ду сохторро нав кунед.
- int(0.2) қимати 0 медиҳад: таймер барвақт анҷомёфта менамояд. Бақияи мусбати касриро ба боло гирд кунед.
- f"{minutes}:{rest}" қимати 3:7 нишон медиҳад. Барои сония :02d лозим аст, то 3:07 ҳосил шавад.
- queue.pop() ба ҷойи popleft() навбатро ба стек табдил дода, кафолати роҳи кӯтоҳтаринро гум мекунад. Барои BFS аз чап гиред.
Ёддошт
- FirstPersonController бозигари тайёр аст; фарш ва деворҳо collider мехоҳанд.
- distance x, y, z-ро мегирад; нуқтаи бадан аз мавқеи пой фарқ мекунад.
- destroy саҳна ва remove рӯйхатро тағйир медиҳад; гузариш аз нусха санҷишҳоро нигоҳ медорад.
- Ҳисоб ва вақт маълумотанд; Text.text намоиши онҳост.
- Таймер: гирдкунӣ ба боло, маҳдудкунӣ бо сифр, баъд дақиқа ва сонияи дурақама.
- Харита: (row, col) → (col, y, row); ҳангоми ҷамъкунӣ харитаро нав кунед.
- BFS: deque, popleft, қайд ҳангоми илова ва қадамҳои ҳамарзиш.
- Баъди анҷоми давр ҳам тағйири ҳолат ва ҳам идоракунии бозигарро боздоред.