Повернуся до тематики ігор для Android. Чи не для того ж ми, право справа, писали тут свій движок, щоб ось так безславно закінчити все це хрестиками-нулики. Тут недавно почитав на якомусь форумі пост користувача, який просить поетапно розписати процес створення квача.
Ну ось я і подумав, що п'ятнашки - це справа хороша. П'ятнашки це справа потрібна. Тим більше, що п'ятнашки - це ще і справа проста і для початківця android - програміста - саме те.
Почати слід з вивчення предметної області. Ігрове поле являє собою квадрат 4х4 на якому розташовані 15 фішок пронумеровані від 1 до 15 і одного порожнього поля. Не будемо винаходити велосипед і представимо ігрове поле у вигляді двовимірного масиву. Зробити хід можна перемістивши будь-яку кількість фішок в сторону порожнього поля. Гравець виграє коли всі фішки пронумеровані від 1 до 15 зверху вниз зліва на право і нижній правий кут вільний.
І так, ось він клас, який реалізує всю логічну складову гри:
Кожен метод досить докладно описаний і думаю у Вас не буде проблем з тим, щоб розібратися що тут до чого.
А ось наступний клас відповідає за взаємодію гравця і гри, а так само за відображення різних компонентів для користувача інтерфейсу з використанням мого движка (взяти останню версію якого можна ось за цим посиланням).
Думаю у людей, які не полінується почитати ось тут про те, що власне з себе представляє мій движок не повинно виникнути проблем з розумінням того що відбувається в цьому класі.
Власне два ці класу, і є повністю реалізована гра п'ятнашки :)!
Як правильно зауважив Павло, не всяку випадково задану гру можна виграти.
Тому я вирішив трохи підправити клас game15 з тим, щоб таких проблем не виникало. Замість того щоб перевіряти сгенерированное ігрове поле на можливість виграшу, я вирішив зробити дещо простіше. Згенерувати поле в положенні коли воно пройдено, а потім випадковим чином його заплутати.
Наводжу тут код класу:
Думаю так буде набагато цікавіше 🙂
UPD: Ось готовий проект для Android mEngine
Вам сподобалось? Було корисно? Поділіться!
Дякую за такі чудові уроки, мені вони дуже допомогли в знайомстві з розробкою під Android!
І у мене по ходу їх освоєння виникло кілька запитань:
1) Якщо між перемальовуванні сцени, мені необхідно перераховувати різні параметри, наприклад рух об'єктів, перезавантажувати спрайт, ну і взагалі виконувати будь-які дії, де їх краще виконувати (дані дії)? Чи правильно я розумію, що треба викликати окрему функцію в класі mDrawerTask, методі run () перед виконанням canvas = holder.lockCanvas () ;? І чи вплине на швидкість роботи відтворення сцени, якщо всі ці розрахунки буду робити після canvas = holder.lockCanvas () ;?
2) І ще незрозумілий для мене момент, при створенні поверхні ми плануємо завдання по таймеру, наприклад якщо у нас цільової FPS встановлений в 25 кадрів, то завдання буде запускатися кожні 40 мс:
drawer = new mDrawerTask (this.getHolder (), this.scene);
t.scheduleAtFixedRate (drawer, 0, mSettings.frameInterval);
Я так розумію, що якщо система на андроїд буде справлятися з отрисовкой сцени за 40 мс і перерахунками перед отрисовкой, то все буде добре, сцена буде змінюватися як і заплановано. Але якщо цього часу не вистачатиме на отрисовку, що буде відбуватися? повний цикл відтворення анімованих спрайтів сповільниться? Завдання будуть збиратися в стеці виконання одна за одною, поки всі вони, зрештою, не виконаються? Якщо так, то що потрібно зробити щоб цього уникнути?
Заздалегідь дякую за поради та підказки 🙂
Справа в тому, що отрисовка відбувається незалежно ні від чого - в окремому потоці. Тому логічно різні розрахунки виносити в окремий потік. Таким чином якщо ви хочете перерахувати нове положення спрайтів наприклад і з якихось причин не встигли, то спрайт так чи інакше Отріс на своєму старому місці. Такий підхід має як свої плюси так і свої мінуси. Але мені він здається найбільш виправданим для ігор не сильно залежать від розрахунків.