Выбор мыши XNA 2D - PullRequest
       20

Выбор мыши XNA 2D

2 голосов
/ 24 декабря 2010

Я работаю над простой стратегической игрой в реальном времени с использованием XNA.Прямо сейчас я достиг точки, когда мне нужно иметь возможность щелкнуть спрайт для юнита или здания и иметь возможность ссылаться на объект, связанный с этим спрайтом.Из исследований, которые я проводил в течение последних трех дней, я нашел много ссылок на то, как сделать «выбор мыши» в 3D, что, кажется, не относится к моей ситуации.Я понимаю, что другой способ сделать это состоит в том, чтобы просто иметь массив всех «выбираемых» объектов в мире, и когда игрок нажимает на спрайт, он проверяет местоположение мыши по расположению всех объектов в массиве.проблема, с которой я сталкиваюсь при таком подходе, состоит в том, что он станет довольно медленным, если число единиц и зданий увеличится до большего числа.(это также не кажется очень изящным), так каковы некоторые другие способы, которыми я мог бы сделать это.(Обратите внимание, что я также работал над идеями использования таблицы Hash, чтобы связать объект с местоположением спрайта, и использованием двумерного массива, где каждое местоположение в массиве представляет один пиксель в мире. Еще раз они кажутся довольнонеуклюжие способы ведения дел.)

Ответы [ 3 ]

5 голосов
/ 24 декабря 2010

Для сотен юнитов должно быть достаточно просто выполнить линейный поиск O (n) по всем юнитам в мире, если области щелчков - это круги или прямоугольники. Особенно учитывая, что это будет один раз за клик, а не один раз за кадр.

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

Для более подробного ответа, вот мой ответ на аналогичный вопрос о разделении пространства. Там я упоминаю сетки и квадриты с ячейками в качестве потенциальных структур для оптимизации производительности.

Но вы никогда не должны выполнять оптимизацию производительности, пока не протестируете, и у на самом деле не возникнет проблема производительности!

1 голос
/ 30 декабря 2010

Если у вас есть класс, который управляет объектами drawabel, у вас может быть статическое int, которое вы увеличиваете каждый раз, когда создаете новый объект, и сохраняете старый как локальный экземпляр Color в объекте drawabel.Затем вы можете использовать конвертер типов .Net, чтобы преобразовать его в массивы и обратно, не запомните его имя и имя на моем телефоне в поезде, поэтому не могу проверить вас, я боюсь.

Когда вы строите цветиз байтового массива просто помните, чтобы максимизировать альфа-канал, и если вам случится получить слишком много объектов, вы могли бы переполнить индексы, которые вы можете использовать ... не уверен, что делать потом ... вероятно, все ваши объекты будут требовать новых цветов от 0: 0: 0: 255 еще раз, поскольку, надеюсь, некоторые старые больше не используются: P

Не уверен, что я имел много смысла, но так как я в поезде, это все, что я могу вам дать, извините:)

0 голосов
/ 24 декабря 2010

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

По сути, вы визуализируете свою сцену, используя уникальный цвет для каждого объекта. Затем вы превращаете backbuffer в текстуру и возвращаете данные текстуры, наконец, вы можете просто проверить пиксель под мышью и выяснить, на каком объекте находится мышь.

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

Color[] pixel = new Color[1];
texture.GetData(pixel, mousePosition.Y * texture.Width + mousePosition.x, 1);
//pixel[0] == colour of the item the mouse is over. You can now look this up in a dictionary<Color, item>

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

Добавление в ответ на ваш комментарий.

Чтобы назначить уникальный цвет каждому объекту, просто увеличьте байт для каждого объекта. Когда этот байт переполняется, инкремент увеличивается, а когда этот переполняется, увеличивается другой; Затем вы можете использовать эти три байта как красный, зеленый и синий. Помните, чтобы держать альфа на максимальном значении, вы не хотите, чтобы сквозь объекты!

Чтобы разрешить задний буфер немного изменен в XNA4. Теперь вы должны выполнить рендер-объект и разрешить его. Сделать это довольно просто, и обрисовано в общих чертах Шоном Харгривзом здесь

...