Много андроид игр даже не достаточно большой по масштабам не оправдывают сохранения / загрузки или опций / предпочтений, не говоря пользовательские символы и тому подобное, просто потому, что они играли экспромтом в течение 10 минут на поезде домой.
Не делайте ошибку, которую я сделал из посадки на что-то с большим простором для первого андроида игры. Сделать кучу небольших игр затем пойти на что-то большее
Android особенность мудрый:
Структура:
Я бы порекомендовал иметь почти все игры в одном классе деятельности. Android работает на идее, что каждый вид деятельности, как мини-приложение, полуприцеп независимо от других видов деятельности в приложении. Приложение является по существу стопкой деятельности, с пользовательским видением, когда-либо находится на вершине.
Когда вы вытаскиваете один из них сверху, он обычно уничтожается и будет воссоздан при следующем запуске пользователем нового действия (намерение startActivity). Это делает его трудно поддерживать состояния между деятельностью и ведет к единой архитектуре деятельности
Возможно, вы захотите, чтобы на экране «Домашний экран» отображалось меню «Новая игра / Загрузить игру / Параметры» и выполняйте запуск. Тем не менее, вы будете в конечном итоге, есть меню в игре, а также в игровой деятельности, которая будет иметь те же самые функции в нем
Мое собственное приложение, я сделал «MenuActivity», который имеет функции, которые запускают новую игру, сохранять, загружать, варианты изменения. Тогда мой HomeActivity продолжается, что, как это делает мой GameActivity.
Так как все в одном классе активности, я бы рекомендовал сделать иерархию классов деятельности и использованием личного, защищенный и область применения по умолчанию много. Делая это таким образом, вы по крайней мере, можно разделить вещи в другой файл для остановки от того, один неуправляемого файла Activity. Например, для моего приложения:
GraphicsEngine extends MenuActivity
,
PhysicsEngine extends GraphicsEngine
,
GameLogicActivity extends PhysicsEngine
,
UIActivity extends GameLogicActivity
,
Так как мое приложение 3D OpenGL-ES, много вещей, я не работает перекрестное деятельность таким образом, все в той же деятельности, поэтому, возможно, я пристрастен к использованию одной архитектуры деятельности
-
Резьбонарезной
Для игровой деятельности, у вас есть два потока (или 3, если вы делаете 3D OpenGL вещи). Один поток представляет собой пользовательский интерфейс / основной поток. Это поток, в который запускается и запускается действие, и передается вам android.
Этот поток пользовательского интерфейса является только один, вы можете обновить элементы пользовательского интерфейса (виды, макеты и т.д.). Это также является тот, в котором любые слушатель для ввода данных пользователя будет работать. Вы не видите какой-либо из механики потока пользовательского интерфейса, так что он работает в цикле в фоновом режиме где-то.
Второй поток, вы делаете себя (я бы рекомендовал использовать AsyncTask , несмотря на все свои недостатки). Это делает все не UI , что вы делаете в обычном цикле игр, такие как обновление движения, расчет столкновений, боевые расчеты и так далее.
Вы делаете это AsyncTask нить / класс как внутренний класс вашей деятельности. Таким образом, вы можете иметь некоторые действия по всей области видимости объектов ( Vector<Spaceship>
) , которые могут быть доступны как UI нити и петли нити игры.
Так как игровая логика происходит в потоке игрового цикла, это единственный поток, который должен будет фактически изменить значения переменных (обновить скорость танка, уменьшить HP игрока). Нить UI просто считывает значения, так что должна быть минимальными проблемы параллелизма.
Хитрость заключается в том, чтобы заставить поток пользовательского интерфейса выполнять обновления по запросу потока игрового цикла. Есть несколько способов сделать это. Если вы читаете документацию AsyncTask, он имеет метод publishProgress () / onProgressUpdate (). На самом деле это добавление материала в очередь UI потока вещей, чтобы сделать следующий цикл.
Handler делает ровно то же самое, в котором реализовать метод handleMessage () и этот метод фактически выполняется в потоке пользовательского интерфейса следующего цикла.
Наконец, любой пользовательский ввод, находящийся в потоке пользовательского интерфейса, позволяет сразу же обновлять элементы пользовательского интерфейса из него (т.е. внутри реализации любых слушателей onClick / onTouch). Если вам нужно обновить игровые объекты, вы можете использовать такие вещи, как синхронизация, или вы можете внедрить свою собственную очередь обновлений в AsyncTask, которая, подобно потоку пользовательского интерфейса, проходит в следующий раз при выполнении игрового цикла.
Android Guide Threading .
-
UI
Что касается фактической структуры пользовательского интерфейса в рамках одного вида деятельности, я рекомендую иметь компоновку кадра в качестве базового макета. Дочерние элементы в кадре макет работы, как очередь. Первый элемент рисуется первым, второй - поверх первого, третий - над вторым.
Таким образом, вы можете иметь несколько файлов макет XML и управление детьми в макете кадра, может легко заменить множество видов в и вне.
Если у вас всегда есть SurfaceView в нижнем (первом ребенке в макете кадра), то вы можете использовать все обычный андроид мнение / виджеты (кнопки, просмотр текста, просмотр прокрутки) и т.д. поверх представления поверхности, которая просто делает графическая часть игры.
Так, например, если что-то загружается, вы можете приостановить игровой цикл / просто заставить его пропустить все, добавить непрозрачный экран «загрузки» в качестве последнего дочернего элемента к макету фрейма, и пользователь увидит, что «загрузка» появится на их экране. совершенно не подозревая, что за этим стоят другие взгляды. Таким образом, вам не нужно удалять представления, которые требуют много времени для настройки или вызывают сложности при каждом добавлении / удалении.
Я также рекомендовал бы использовать View.setVisibility много. Например, вы можете добавить весь макет «инвентаря» к макету базового фрейма, а затем просто установить его, когда пользователь щелкает для просмотра своего инвентаря, и setVisibility (View.Gone), когда они снова закрывают его. Таким образом, вы даже не управление детьми макета кадра так, как просто добавить все и делать вещи видимой / невидимой, как и когда пользователь делает разные вещи
Это помогает с резьб снова; как пользователь нажимает, чтобы открыть свой инвентарь, то onCLickListener обрабатывается в потоке пользовательского интерфейса, инвентарь становится видимым в нем, и метод updateInventory называется, опять-таки из потока пользовательского интерфейса, только с добытчиками на все игровые объекты называют
Вот диаграмма, которую я сделал для более раннего вопроса об идее макета одного упражнения / фрейма: