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, 3 downloads since 2017-12-20 

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

2

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

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

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...
Подякували: Monolith1

3

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

FakiNyan написав:

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

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

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

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

4

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

Monolith написав:

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

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

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...
Подякували: Monolith, 221VOLT2

5

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

FakiNyan написав:

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

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

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

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

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

FakiNyan написав:

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

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


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

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

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

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

7

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

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

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

8

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

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

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

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