1 Востаннє редагувалося Monolith (20.12.2017 20:12:27)

Тема: Оброблення зіткнень між об'єктами у 2д грі

Вітаю. Пиляю тут у вільний час навеличкий TDS (Top Down Shooter) на канвасі з мрією приліпити то все колись до веб-сокетів й погратися з друзями  :)

Маю пару питань.

Зараз маю таке. Є мапа, у вигляді масиву (потім можливо перенесу це все у .json формат чи у БД, коли більше тайлів буде, бо зараз більше вчуся, ніж розробляю). Ось якось так:

var map = [
    [0, 1, 1, 0],
    [1, 0, 0, 0],
    [1, 0, 1, 1],
    [1, 1, 0, 0]
];

Проходячи по масиву, малюю потрібний тайл:

for (var y = 0; y < map.length; y++) {
    for (var x = 0; x < map.length; x++) {
        // вибираємо потрібний тайл в залежності від елементу масива
        ctx.drawImage(tile, x*32, y*32, 32, 32);
    }
}

Я код трошки спрощую, щоб не розтягувати пост.

Так ось є така мапа. Ще є герой, якого малюю тим же способом:

ctx.drawImage(skin, this.x, this.y);

У нього є властивості x i y які відповідають за його координати (у пікселях від початку канваса). Далі вже дивлюся на натиснуті клавіши й якщо треба рухати героя, то змінюю йому значення цих властивостей (наприклад на 2 пікселі) та знову перемальовую все спочатку.

Тобто герой рухається не по клітинках, а вільно. Але тайли на фоні (земля, стінки тощо) мають фіксований розмір (32х32) й розташовані у вигляді таблички. Тобто звичайна тайлова мапа. І тепер власне питання: як зрозуміти, що герой наткнувся на ту ж стінку, наприклад?

Як визначити, що закінчився канвас, я знаю: дивимося координати героя, й перевіряємо чи не менші вони за 0, та чи не більші за висоту/ширину самого канваса. Це просто. Як зрозуміти, що герой врізався у стінку, це я теж якось через одне місце зробив. Я беру чотири краї спрайту героя, і для кожної перевіряю, чи в тому випадку, коли відбудеться переміщення, чи будуть вони розташовані (будь-який з цих країв) на тайлі. Рахую це, так:

var a = map[ Math.floor(this.y/tileSize) ][ Math.floor((this.x-step)/tileSize) ];

Це приклад, лівого верхнього краю, під час перевірки можливості руху ліворуч. Далі дивлюся, якщо ця змінна не містить тайлів через які не можна пройти, то все добре: переходимо до обробки наступного краю/переміщення героя.

Ніби і все нормально працює. Так все дійсно нормально працює, але що робити далі? Якщо в мене буде велика мапа в тій же БД, і треба буде показати гравцеві тільки частину мапи, як її намалювати? Взяти з БД потрібні тайли - ок, але чи буде добре у тому випадку працював алгоритм просто перебору масиву двома циклами, якщо мапа буде рухатися й може статися, що треба малювати починаючи не з початку тайлу, а наприклад з середини? Тобто буде неможливо намалювати так, щоб на екрані було ціле число тайлів у рядку чи стовпчику, при чому "обрізаний" тайл буде на початку. Які ще є методи малювання таких мап, як зручніше зробити?

Також, проблема в тому, що далі будуть з'являтися монстри там, чи якісь предмети, для них писати окремий алгоритм обробки з ними зіткнень, окремо від того, що обчислює зіткнення гравця зі стінами? І як такий алгоритм має виглядати? Так само перебирати кожного монстра та порівнювати його координати з координатами героя? Просто монстри/предмети як і гравець не будуть розташовані чисто по клітинках. Як гадаєте краще зробити?

Можете підказати будь ласка, або кинути ресурс, де нормально пояснюється вирішення такої проблеми.

Дякую  :)

P.S. Чому я не використовую готову бібліотеку, де це вже реалізовано: це чисто хоббі і роблю це в задоволення. Хочу зрозуміти, як це все робиться, бо мені це цікаво  :P

Post's attachments

Знімок екрану_2017-12-20_18-12-07.png 48.89 kb, 115 downloads since 2017-12-20 

Подякували: 221VOLT, sensei, NagarD, leofun01, 0xDADA11C75

2

Re: Оброблення зіткнень між об'єктами у 2д грі

колір на канвасі перевіряйте, якщо піксель кольору стіни - то не мона йти в цьому напрямку або робіть масив з булевих змінних, де 0 - не мона пройти, а 1 - мона пройти

Говоріть українською! Живіть українською! Відчувайте українською!
Подякували: Monolith1

3

Re: Оброблення зіткнень між об'єктами у 2д грі

FakiNyan написав:

колір на канвасі перевіряйте, якщо піксель кольору стіни - то не мона йти в цьому напрямку або робіть масив з булевих змінних, де 0 - не мона пройти, а 1 - мона пройти

1. А якщо це буде предмет, або ще щось, що матиме такий же колір як стіна? Або я не правильно зрозумів Вашу думку...

2. Так в мене так і є зараз, от тільки я ж кажу, що чи буде цей алгоритм працювати і надалі так нормально. Та чи є більш зручніші методи малювання таких мап...

Подякували: 221VOLT1

4

Re: Оброблення зіткнень між об'єктами у 2д грі

Monolith написав:

2. Так в мене так і є зараз, от тільки я ж кажу, що чи буде цей алгоритм працювати і надалі так нормально. Та чи є більш зручніші методи малювання таких мап...

та ви про це не переживайте, робіть, як знаєте, і вирішуйте проблеми, коли вони з'являються, бо думати наперед про все, що може бути, то дуже муторна і важка справа, коли ви просто бавитесь з чимось

Говоріть українською! Живіть українською! Відчувайте українською!
Подякували: Monolith, 221VOLT2

5

Re: Оброблення зіткнень між об'єктами у 2д грі

FakiNyan написав:

та ви про це не переживайте, робіть, як знаєте, і вирішуйте проблеми, коли вони з'являються, бо думати наперед про все, що може бути, то дуже муторна і важка справа, коли ви просто бавитесь з чимось

В принципі Ви праві. Дякую. Буду вже потім вирішувати. Відпишу про результати пізніше :)

Подякували: 221VOLT1

6 Востаннє редагувалося 221VOLT (21.12.2017 10:45:55)

Re: Оброблення зіткнень між об'єктами у 2д грі

FakiNyan написав:

колір на канвасі перевіряйте, якщо піксель кольору стіни - то не мона йти в цьому напрямку або робіть масив з булевих змінних, де 0 - не мона пройти, а 1 - мона пройти

фо-фо? який такий колір?
пропонуєте для кожного пікселя зберігати в js масиві його колір?
це скільки у вашому компютері оперативки?
(ну ок, допустимо що кольорів лише три і зберігаємо не пікселі а лише масив кольорів - це може спрацювати
проте чим більше кольорів - тим гірше цей алгоритм)


перше що спадає на думку -
перевіряти чи новий піксель лежить в дозволеній для руху зоні -
в збережених нами координатах зон, по яких ми можемо рухатись

друге - допустимо ми в якійсь зоні X2 Y2
ще коли ми перейшли сюди - ми одразу ж визначили -
що, для прикладу, наліво на вверх ми з цієї зони рухатись не можемо,
тобто вийти з її границь ми можемо лише направо чи вниз

треба подумати, думаю тут варіантів багато існує

https://blog.clever-games.win/
Це ще не кінець. Це навіть не початок кінця. Але, можливо, це кінець початку.
Зростання мудрості можна точно вимірювати ступенем зменшення злоби.
///// у творчій відпустці. не турбувати /////
Подякували: Monolith1

7

Re: Оброблення зіткнень між об'єктами у 2д грі

Я б рухався від героя: перевіряв усі перешкоди довкола поточної позиції, і визначав куди можна рухатися, а куди ні. Таким же чином можна і монстрів перевіряти. А сканувати одразу усю мапу - це марнування часу.

Подякували: leofun01, Monolith2

8

Re: Оброблення зіткнень між об'єктами у 2д грі

фо-фо? який такий колір?
пропонуєте для кожного пікселя зберігати в js масиві його колір?

Я теж так думаю, але зчитують прямо з канвасу колір, а не зберігають в масиві.

Говорила баба діду: «Я поїду к Білодіду, Ізучу двомовну мову І вернусь обратно знову». А дід бабі: «Не *изди, К Білодіду нєт їзди, — Туди не ходять поїзди»
Подякували: Monolith1

9

Re: Оброблення зіткнень між об'єктами у 2д грі

Обробляти зіткнення можна тільки на двіжку.. треба писати двіжок фізичний або використати готовий. Таких Багато.

(цей допис зроблено ботом. можете не звертати на нього уваги)
(цей підпис зроблено адміном. можете не звертати на нього уваги)

10 Востаннє редагувалося Alchimic (23.01.2018 15:34:49)

Re: Оброблення зіткнень між об'єктами у 2д грі

А якщо хочеш по бистрому.. то евент коліжен при загалній провірці колізії циклічній. І зміна вектору руху.

(цей допис зроблено ботом. можете не звертати на нього уваги)
(цей підпис зроблено адміном. можете не звертати на нього уваги)