Як ефективно зберігати та відображати карту плитки в Інтернеті?


9

Про

Це фактично два питання в одному. Перш за все, я шукаю спосіб ефективного зберігання великої кількості даних про плитку. Інший аспект стосується запиту набору даних та відображення плиток. Дозвольте спочатку дати вам декілька відомостей.

Ми створюємо багатокористувацьку гру-магнат на основі браузера, використовуючи бібліотеку CraftyJS, щоб повернути її на Canvas. На фоні GUI ми запускаємо Yii Framework на PHP, і все це підключається до генератора випадкових карт Python та ігрового двигуна.

Ось так виглядає перший грубе відображення карти: http://i.imgur.com/khAXtl.png

Зберігання даних карти

Світ ігор генерується випадковим чином щоразу, коли гра починається. Розмір - 100х100 шестикутних плиток для кожного гравця. Це означає, що для гри для трьох гравців створено 90 000 плиток. В даний час я просто створюю масив JavaScript, з якого я відтворюю карту.

Це добре працює для візуалізації, але для будь-якої взаємодії з картою нам потрібно зберігати, якому гравцеві належить плитка, яка структура будується поверх неї, яка поточна ціна тощо. Спочатку, принаймні для прототипу, ми хотіли використовувати MySQL, але після деяких тестувань це не так швидко, як хотілося б. Можливо, сховище об'єктів на зразок MongoDB краще підходить для зберігання даних плиток замість таблиці SQL. А може, щось інше?

Відображення карти

Ще одна проблема, яку я бачу, - це переміщення по карті. Наразі я створюю хитрі об’єкти для кожної плитки, навіть якщо її немає у вікні перегляду. Це повільно, оскільки, хоча Crafty відображає лише ті, які переглядаються у вікні перегляду, він зберігає та, можливо, повторює всі плитки для кожної події візуалізації. Наразі у мене є намальована генерована карта, яка дуже повільно завантажується і заїкається, коли ви рухаєтесь навколо, тепер я хотів би зробити її відтворюваною.

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

Способом отримання плавної продуктивності на карті може бути попереднє завантаження більшого набору плиток у масив javascript та використання його як кешу. У гравця буде кілька екранів, "кешованих", і коли він пересуває вікно перегляду, я б завантажував більше плиток у "кеш" JS.

Я прямував у правильному напрямку? Я хотів би отримати більше інформації від того, хто зробив щось подібне. Я новачок у розробці ігор, але останні кілька тижнів переживаю безліч джерел.


1
Я здивований, що ви визначили MySQL як вузьке місце. Що ви протестували, щоб дійти висновку, що це уповільнює справи?
bummzack

@bummzack Якщо у нього є ряд на плитку, я навряд чи бачу, як все не може бути повільним.
aaaaaaaaaaaa

1
@eBusiness Запит на кілька тисяч рядків з БД насправді не повинен бути проблемою. Це все ще повинно знаходитися в межах декількох мілісекунд. Також це не буде 90'000 рядів, а швидше 30'000 рядків для 3 гравців (100x100 на гравця).
bummzack

Вибачте за заплутану математику, крім гравця в зоні також є вдвічі більше місця між гравцями, так що вони знаходяться на рівній відстані один від одного, що становить 90 к. Запит - це не проблема. Вибір плитки 90 к і створення карти. Але це не гарний спосіб зробити це. Я буду серіалізувати дані карт і використовувати запит на плитки в db, коли запитається детальна інформація.
елемент

Відповіді:


2

Ігровий процес
Перш за все я хотів би запитати вас, чи вам насправді потрібно 10000 плиток на гравця? Хоча я не знаю, яку гру ви робите, як правило, великі карти роблять довгі ігри. Найбільша карта в Civilization 5 - це 10240 плиток, і це працює лише на сортах, тому що вам не потрібно грати на більшій частині.

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

Зберігання JavaScript
Що стосується клієнта, я б сказав, що вам краще зберегти всю карту завантаженою, принаймні, якщо ви будете дотримуватися газильйонних плиток, щоб все це було в хорошому дереві об'єктів, можливо, було занадто багато, тому ви, ймовірно, повинні зберігати дані у кодованому форматі "напів бінарний". Струни відмінно справляються з подібними матеріалами, по черзі ви можете безпечно зберігати непідписані цілі числа до 53 біт у 64-бітовому поплавці, набираючи багато цих масивів, і я думаю, ви побачите досить скромний слід пам’яті.

Візуалізація JavaScript
Хоча я не скажу, що ви обов'язково не повинні використовувати полотно, вам насправді не потрібні такі речі. Встановіть це як купу елементів img та змініть властивість src для відображення різних частин карти.

Порада щодо слова
До речі, іноді легше ділитися насінням, яке використовується для його вироблення, ніж ділитися цілою картою.


+1, але, на жаль, веб-додаток, написане на PHP, зазвичай не має можливості зберегти ігровий стан у пам'яті.
bummzack

@bummzack, Ага, правда, я думаю, я якось пропустив слово PHP і просто прочитав Python. Тоді може бути змінена база допоміжних рамок. Node.js може бути варіантом.
aaaaaaaaaaaa

Я будую конкурентного транспортного магна, подумайте про OpenTTD, карта розміром 512x512 (262k) не така велика для пари гравців. Я розумію, що це амбітно, але якби карта була не такою великою, гра закінчилася б занадто рано. Оскільки це багатокористувацька гра, мені потрібно синхронізувати зміни на карті між гравцями. Першим моїм інстинктом було просто використовувати поняття, які я знаю з веб-розробки, і переходити з датою бази даних. Це не потрібно бути в режимі реального часу. Я йду з візуалізацією JS, тому що я хотів би мати на карті динамічні речі.
елемент

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

Я згоден, ваша відповідь дала мені багато їжі для роздумів. Я спробую знайти спосіб збереження серіалізованих даних карт у пам’яті та зберегти базу даних як резервну копію. Але тоді я повинен розібратися, як поділитися змінами між гравцями. Я повернусь до того, що придумав після того, як пройду додаткові тестування.
елемент

1

MySQL не повільний. Швидше за все, ви виконуєте наївні запити або маєте неоптимальні показники. Підходи NoSQL, такі як MongoDB, можуть бути швидшими, а може й ні. Ваша модель доступу та вибір запиту - це те, що дійсно має значення тут. Можна дати пораду, як покращити продуктивність, але не побачивши, що ви вже робите.

Способом отримання плавної продуктивності на карті може бути попереднє завантаження більшого набору плиток у масив javascript та використання його як кешу.

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

Додаток:

ми запускаємо Yii Framework на PHP, і все це підключається до генератора випадкових карт Python та ігрового двигуна.

Якщо ви вмієте з Python, то я б радив вам вийти з посередника PHP. Якщо ви запускаєте гру як процес Python, тоді ви можете зберегти свої дані плитки в пам'яті набагато легше і значно зменшити доступ до MySQL. Це допомагає Python набагато безпечнішою мовою, ніж PHP.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.