Бархӯрдҳо ва шуоъҳо
Чаро бархӯрд шакли алоҳида мехоҳад
Қуттии тасвиршуда худ аз худ пеши гузаштани бозигарро намегирад. Барои таъсири мутақобил геометрияе лозим аст, ки муҳаррик онро санҷад. Collider ҳамин шакл аст ва одатан аз модели намоён содатар мебошад. Бо он фарш, девор ва расидан нисбат ба санҷиши ҳар рӯяи модели мураккаб тезтар санҷида мешаванд.
Дар Ursina collider="box", "sphere" ё "mesh" истифода мешавад. Ду шакли аввал содаанд; mesh тӯри моделро пайравӣ мекунад ва метавонад гаронтар бошад. Танҳо доштани collider вокуниши худкори физикиро намедиҳад: мантиқи бозӣ ё контроллер бояд қадамро бекор кунад, тирро боздорад ё ашёро ҷамъ кунад.
Қуттӣ аз фосила оғоз мешавад
Фосила қитъаи байни ҳади поён ва боло аст. Қуттии ногардида дар ҳар меҳвар фосилаи худро дорад. Агар маркази x ба 3 ва андоза ба 4 баробар бошад, рӯяи чап дар 1 ва рост дар 5 аст. Аввал танҳо як меҳварро меомӯзем.
from ursina import Entity
crate = Entity(x=3, scale_x=4)
lo = crate.x - crate.scale_x / 2
hi = crate.x + crate.scale_x / 2
print(lo, hi)
Натиҷа:
1.0 5.0
Фосилаҳо вақте бо дарозии мусбат мепӯшанд, ки max-и ҳадҳои поён аз min-и ҳадҳои боло хурд бошад. Баробарӣ танҳо расидан аст. Дар масъалаҳои курс расидан буриш ҳисоб намешавад; санҷиши муҳаррик метавонад таҳаммулҳои худро дошта бошад, бинобар ин ин қоида ошкоро дода мешавад.
a = (1, 5)
for b in ((4, 6), (5, 7), (7, 9)):
width = min(a[1], b[1]) - max(a[0], b[0])
print(width, width > 0)
Натиҷа:
1 True
0 False
-2 False
Се меҳвар ва системаҳои координата
Барои буриши ҳаҷмӣ ҳамзамон пӯшиши x, y ва z лозим аст. Як меҳвари дорои фосилаи холӣ ҳам объектҳоро ҷудо мекунад. Аз ин рӯ санҷиши танҳо фарши x–z барои ҷаҳиш мувофиқ нест: бозигар метавонад болотар аз қуттӣ бошад. Дар масъала қуттиҳо нагардидаанд ва дар як системаи координата дода шудаанд.
axis_overlaps = [True, False, True]
print(all(axis_overlaps))
print(any(axis_overlaps))
Натиҷа:
False
True
all ҳамаи шартҳоро талаб мекунад; any ақаллан яктояшро. Барои Entity-ҳои воқеӣ бо волидайни гуногун position-ро кӯр-кӯрона муқоиса накунед: он маҳаллӣ аст. Формулаи одии қуттӣ қуттии гардидаро низ тасвир намекунад. Дар саҳна collider-и мувофиқ ва entity.intersects()-ро истифода мебаранд; HitInfo-и натиҷа hit ва entity дорад.
Харита ва лағжиш
Лабиринтро бо сатрҳо нигоҳ доштан қулай аст: # девор ва . роҳ аст. Сатр ба z ва сутун ба x мувофиқ аст. Агар марказҳои ҳуҷайра бутун бошанд, ҳудудҳо аз нимҳо мегузаранд: индекс бо floor(value + 0.5) гирифта мешавад. Бар хилофи int, floor координатаҳои манфиро дуруст коркард мекунад.
import math
for x in (-0.6, -0.4, 0.4, 0.6):
print(x, math.floor(x + 0.5))
Натиҷа:
-0.6 -1
-0.4 0
0.4 0
0.6 1
Лағжиш ҳаракатро ба ду кӯшиш ҷудо мекунад: аввал x, баъд z. Агар ҳаракати x иҷозат бошад, санҷиши навбатӣ x-и навшударо мегирад. Ҷузъи баста бекор ва ҷузъи иҷозатшуда нигоҳ дошта мешавад. Ин ба бурдани ҷомадон дар канори девор монанд аст: девор наздик шуданро манъ мекунад, аммо ҳаракати мувозиро не. Санҷиши танҳо ҳуҷайраи охир барои қадамҳои хурд аст; ҷаҳиши калон метавонад аз девори борик гузарад.
Шуоъ ва параметри он
Шуоъ аз нуқтаи origin оғоз шуда, дар самти direction меравад. Нуқтаи он origin + direction * t аст. Агар дарозии direction ба 1 баробар бошад, t масофа аст. Аз ин рӯ пеш аз ҳисоби масофа самтро нормализатсия мекунанд.
from ursina import Vec3
origin = Vec3(1, 2, 0)
direction = Vec3(0, 0, 3).normalized()
print(origin + direction * 4)
Натиҷа:
Vec3(1, 2, 4)
Дар саҳнаи равзанадор raycast(origin, direction, distance=10, ignore=(player,))-ро мехонанд. hit.hit ёфтани collider, hit.entity объект, hit.distance масофа ва hit.world_point нуқтаи ҷаҳониро медиҳад. Объекти бе collider барои чунин шуоъ ноаён аст. ignore худи бозигарро истисно мекунад. Барои ин санҷиш Ursina()-и оғозшуда лозим аст, на танҳо ворид кардани Entity.
Усули қабатҳо чӣ тавр кор мекунад
Дар як меҳвар қуттӣ ду ҳамворӣ медиҳад. Буриши шуоъ бо онҳо ду қимати t медиҳад: даромад ва баромад. Ҷузъи манфии самт тартиби онҳоро иваз мекунад. Аз се меҳвар се фосилаи вақт ҳосил мешавад: шуоъ танҳо дар қисми умумии онҳо даруни қуттӣ аст. Дар мисоли поён фосилаҳо аллакай дода шудаанд, бе ҳисоби буриши рӯяҳо.
intervals = [(1, 7), (2, 6), (3, 8)]
enter = max(pair[0] for pair in intervals)
leave = min(pair[1] for pair in intervals)
print(enter, leave)
print(enter <= leave)
Натиҷа:
3 6
True
Хатоҳои маъмул ва ислоҳи онҳо
- Санҷиши танҳо x ва z ҳатто ҳангоми ҷаҳиш бо қуттӣ бархӯрд медиҳад. Баландии y-ро ба ҳисоб гиред.
- <= дар масъалаи пӯшиш расиданро буриш мешуморад. Барои ҳаҷми мусбат ҳади қатъӣ лозим аст.
- Санҷиши z бо x-и кӯҳна буридани кунҷро имкон медиҳад. Кӯшиши дуюм бояд натиҷаи якумро бинад.
- (lo - o) / d ҳангоми d=0 хатои ZeroDivisionError медиҳад. Аввал параллел будани шуоъро алоҳида коркард кунед.
- Шуоъи аз даруни бозигар саршуда метавонад худи ӯро ёбад. Дар санҷиши саҳна бозигарро ба ignore диҳед.
Ёддошт
- Collider шакли санҷиш ва model шакли намоён аст.
- Барои қуттиҳои ногардида пӯшиш дар ҳар се меҳвар лозим аст.
- intersects() ва raycast() HitInfo медиҳанд; аввал hit-ро санҷед.
- Харита: row ба z ва col ба x мувофиқ аст.
- Лағжиш: кӯшиши x, баъд кӯшиши z бо x-и нав.
- Шуоъ: origin + direction * t; direction-и воҳидӣ t-ро масофа мекунад.
- Усули қабатҳо фосилаҳои даромаду баромадро мебурад; ҷузъҳои сифрии самт ҳолати алоҳида мехоҳанд.