Основанная на сетке игра-макет и удаление предметов - PullRequest
1 голос
/ 25 февраля 2011

Допустим, я получил коллекцию (простая сетка) захватчиков:

When everything is still intact

На этом изображении может снимать только захватчик типа C.

СнимкиПри срабатывании захватчик уничтожается:

Invader Destroyed

Теперь также можно запустить тип захватчика B в третьем столбце во втором ряду.Обратите внимание, что на экране одновременно может быть только три случайных выстрела захватчика.Так что стрелять могут только трое захватчиков в наборе {C, C, B, C, C, C}.

Как бы я поступил, реализовав это?Я имею в виду два решения:

  1. Использовать массив массивов [] [] (или [,]).Когда захватчик будет застрелен, место, где захватчик находился, устанавливается равным нулю.Затем, когда пришло время для захватчиков, по первому ряду проходит цикл.Обнаружение нуля заставляет его проверять пространство над нулем.Это ноль?Затем сделайте то же самое для пространства выше , что .Является ли пространство в верхнем ряду пустым?Перейти к следующему столбцу в первой строке.

  2. У каждого типа захватчика есть позиция (для этого я использую Point).Присвойте каждой позиции номер строки (используемой коллекцией будет своего рода словарь).Итак, при взгляде на изображение все C получают 1, все B получают 2, а все A получают 3.
    A picture 1024 words? На этом снимке C в позиции (2, 2) уничтожен.Затем следует вычесть 1 из него значение Y точки, которое будет (2, 1).Если в коллекции есть такая позиция, тогда присваивает захватчику в этой позиции (2, 1) позицию уничтоженного захватчика (2, 2). .Таким образом, мне не нужно иметь зубчатый массив, содержащий кучу нулей.

Мои мысли о том, как это должно выглядеть -> когда игра начинается, первый сет - {CCCCCC} и тогда это будет {CCBCCC}.Из этого набора три будут случайным образом выбраны для стрельбы.

Итак, есть мысли?

Ответы [ 4 ]

1 голос
/ 25 февраля 2011

Я не согласен с Миркулесом.Я бы посоветовал вам не хранить отдельную структуру данных только для тех захватчиков, которые могут стрелять.В общем, всегда полезно придерживаться шаблона DRY , чтобы избежать проблем с логикой в ​​дальнейшем.Для простого приложения, в котором вы можете хранить всю программу в своей голове, это, вероятно, не имеет большого значения.Но когда вы начинаете работать над более крупными проектами, становится все труднее помнить, что вам нужно обновлять несколько структур данных всякий раз, когда вы изменяете любую из связанных структур.

Преждевременная оптимизация - корень всех зол.Вам, вероятно, даже не нужно беспокоиться об оптимизации на таком минимальном уровне.По моему опыту, когда вы проводите много времени, работая над этими типами проблем, вы в конечном итоге получаете хороший код, но вам нечего показать.Вместо этого я предпочитаю тратить время на то, чтобы приложение делало то, что я намереваюсь, а затем реорганизую его позже.Правильная работа моего приложения дает мне мотивацию продолжать писать больше кода.

Удачи в вашей игре.На Xna так весело писать игры!

0 голосов
/ 25 февраля 2011

В разработке игр, особенно на управляемом языке, таком как C # и , особенно на Xbox 360, в целом, ваш первый приоритет должен быть избегать выделения памяти во время игры . Сохранение памяти и уменьшение количества операций является второстепенной задачей.

A null (в 32-битном формате, в котором работает XNA) - это просто четыре байта!

2D-массив ([,]), содержащий указатели на ваших захватчиков, кажется вполне уместным. Тем более что он позволяет сделать местоположение каждого захватчика неявным по его местоположению в структуре данных. (Вам даже нужно создавать отдельные объекты захватчиков и указывать на них? Просто используйте число, указывающее, к какому «типу» они относятся.)

Цикл по этой структуре данных (как вы предлагаете) будет настолько удивительно быстрым , что вполне может быть «свободной» операцией. Поскольку сам процессор может обрабатывать данные быстрее, чем вы можете в любом случае поместить их в кеш.

И вы даже не делаете это каждый кадр - только когда ваши захватчики стреляют! Я готов поспорить, что будет медленнее вычислять и хранить эти данные всякий раз, когда захватчик уничтожается, а затем загружать их, когда ваши захватчики стреляют.

(По сути, вы предлагаете кэшировать / предварительно вычислять эти данные. Полезный метод оптимизации производительности - но только , когда это действительно необходимо.)

Вы должны гораздо больше беспокоиться о затратах, которые происходят в каждом кадре, чем о тех, которые запускаются только из-за таймеров и пользовательского ввода.

Не использовать зубчатый массив ([][]). Это в основном массив массивов. Он использует больше памяти и включает дополнительный уровень косвенности, который, в свою очередь, также может потенциально уменьшить локальность ваших данных (то есть ваши данные могут не попасть в кэш за одно попадание - это «медленный бит») , Это также увеличивает количество объектов, о которых нужно подумать. Не используйте Dictionary по тем же причинам.


В разработке игр это помогает сохранять такие вещи, связанные с производительностью, по крайней мере, в уме, когда вы работаете (в других местах это было бы преждевременной оптимизацией).

Но для такой простой вещи, как Space Invaders , вы можете делать все, что захотите! Так что делай самое простое, что могло бы сработать.

0 голосов
/ 25 февраля 2011

Может ли захватчик изменить столбец?И может ли он пропустить захватчика, который находится перед ним?

Предполагая, что ответ на оба вопроса - нет, я бы вел Очередь / Список для каждого столбца.Затем набор захватчиков, которые могут запускаться, является первым элементом в каждой очереди.Когда захватчик уничтожен, вы просто выталкиваете его из очереди.Опять же, если предположить, что только первый ряд может быть уничтожен.

Каждый захватчик должен будет сохранить позицию для обновления и рисования.

0 голосов
/ 25 февраля 2011

Я бы сохранил 2D массив всех захватчиков.Кроме того, было бы намного быстрее, если бы вы поддерживали отдельную структуру данных с указателями только на тех захватчиков, которые могут запускаться, вместо того, чтобы выполнять циклический просмотр всего массива каждый раз, когда вам нужно запускать (из-за чего ваша программа действительно медленноначиная с того, что захватчиков будет намного больше).Итак, в вашей первой диаграмме ваша структура данных будет содержать все «C», а во второй диаграмме {C, C, B, C, C, C}.Когда приходит время срабатывать, вам просто нужно сослаться на эту структуру данных, получить их указатели и затем вызывать «fire ()» для любого из этих захватчиков.

Вы не совсем объяснили, как три захватчикакоторые могут выстрелить, выбраны, так что я предполагаю, что он выбран случайным образом - в этом случае все, что вам нужно сделать, это выбрать случайное число от 0 (включительно) до n-1 (где n - число захватчиков в ваших данныхструктура, в данном случае 6).

Наконец, когда придет время уничтожить захватчика, если у вас есть двумерный массив и вы знаете положение, будет очень легко убить убитого захватчика из ""структуры данных «отряд стрельбы», и назначьте находящийся над ним отряд стрельбы (т.е. invaderArray [KilledInvader.row-1] [KillerInvader.column])

Надеюсь, это имеет смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...