1 Востаннє редагувалося Monolith (20.12.2017 19: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, 222 downloads since 2017-12-20 

Подякували: 221VOLT, sensei, NaharD, 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 09:45:55)

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

FakiNyan написав:

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

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


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

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

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

Подякували: Monolith1

7

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

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

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

8

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

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

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

Подякували: Monolith1

9

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

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

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

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

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