Ответ 1
Если все, что вы делаете, - это рисование спрайтов в 2D-мире, тогда в основном нужно две вещи, чтобы отслеживать, какие спрайты рисовать на экране и где на экране их рисовать. Вы должны думать о своих спрайтах как о существовании в определенном месте в мире, и о том, что вы видите на экране как только один взгляд на мир, сосредоточившись на области.
Две вещи, которые вам нужно отслеживать, следующие:
- Каждый спрайт должен иметь свое местоположение в мире
- Ваша "камера" должна отслеживать свое местоположение по отношению к миру.
Итак, скажем, у вас большой большой мир с пространством 2D координат (x, y) размером 1 000 000 x 1 000 000 пикселей (я использую пиксели в качестве единицы измерения здесь, но это произвольный выбор и размер мира не имеет значения, я только что выбрал большой). Затем скажем, что у вас есть "камера", указывающая на этот мир, и вид этой камеры - это то, что отображается на вашем экране. Дисплей, который дает вам камера, имеет размер 1024x768 пикселей.
Предположим также, что вы используете клавиши со стрелками для перемещения этой камеры по всему миру.
Итак, ваше мировое координатное пространство отображает ваш экран как таковой:
(0, 0) +x
+------------------>
|
+y |
| * <= example sprite in your world @ coordinates (x=200, y=200)
|
\ /
Когда ваши спрайты перемещаются "вправо", они увеличивают координату x
. Когда они перемещаются "влево", они уменьшают свою координату x
. При перемещении "вверх" они уменьшают их координату y
(потому что y
увеличивается вниз, на мониторах), а при перемещении "вниз" спрайты увеличивают их y
координата.
Теперь, опять же, то, что вы видите на нашем экране, - это просто просмотр камеры в мире. Итак, допустим, что верхний левый угол камеры находится в (x=500, y=500)
. Это выглядит примерно так:
(0, 0) +x
+---------------------------------->
|
+y |
| * <= example sprite in your world @ coordinates (x=200, y=200)
|
|
| +===================+
| | the area |
| | that the camera |
| | "sees" and |
| | shows on your |
| | screen |
| +===================+
\ /
С этой настройкой скажем, что камера находится на (500, 500) (то есть верхний левый угол обзора камеры, как показано в этом примере, находится в мировых координатах (500, 500). И поскольку камера показывает вам область размером 1024x768, тогда противоположный нижний правый угол (500 + 1024, 500 + 768) = (x=1524, y=1268)
.
Обратите внимание, что спрайт в нашем мире не внутри области просмотра камеры. Это означает, что когда мы отображаем вид камеры на экране, мы не увидим спрайт.
Если вместо этого камера переместилась на (200, 200), тогда область обзора камеры будет покрывать мировые координаты слева и слева (200, 200) до нижнего правого @(1224, 968), и выглядят примерно так:
(0, 0) +x
+---------------------------------->
|
+y | +===================+
| | |
| | * <= sprite |
| | |
| | | <= camera view of the world
| +===================+
|
|
|
|
\ /
Когда камера находится в этом положении, спрайт виден. Если спрайт равен @(500, 500), а камера находится на (200, 200), тогда, когда мы нарисуем спрайт на экране, появится спрайт на нашем экране в координатах 300, 300.
Почему?
Потому что, и это действительно ответ на ваш вопрос, , где вы рисуете вещи на экране, это sprite местоположение мира (500, 500), минус местоположение камеры (200, 200), что равно (300, 300).
Итак, чтобы рассмотреть:
Вы перемещаете положение камеры по всему миру, используя клавиши со стрелками (или мышь или любую другую схему управления), и вы визуализируете расположение спрайтов относительно положения камеры, принимая положение спрайта и вычитая положение камеры, и то, что вы получаете, - это координаты экрана, где должен появиться спрайт.
Но есть еще одна вещь...
Неэффективно рисовать каждый спрайт в мире. Вам нужно всего лишь нарисовать спрайты, которые находятся внутри камеры, иначе вы будете рисовать вещи, которые вы не увидите на экране, и, следовательно, тратите время рендеринга /CPU/GPU.
Итак, когда вы показываете представление камеры, вам нужно перебирать спрайты, проверяя, являются ли они "на камере" (то есть, находятся ли они в режиме просмотра камеры) и только рисовать их, если они находятся в этом представлении.
Чтобы сделать это, вы должны принять размеры вашей камеры (1024x768, в нашем примере) и проверить, находится ли положение спрайта внутри прямоугольника камеры - который представляет собой положение верхнего левого угла камеры, плюс ширина и высоту камеры.
Итак, если наша камера показывает нам, что размер 1024x768 пикселей, а верхний левый угол равен (200, 200), тогда прямоугольник представления:
(200, 200) (1224, 200)
+===================+
| |
| * |
| |
| |
+===================+
(200, 968) (1224, 968)
Положение спрайта @(500, 500) находится в пределах камеры. В этом случае.
Если вам нужно больше примеров, у меня есть рабочая демонстрация технологии Slick2D, называемая Pedestrians, на которой есть код, на который вы можете посмотреть. Для получения подробной информации о том, как я вычисляю область мира, которая должна быть отображена, посмотрите на метод render
внутри этот файл и обратите особое внимание к переменным startX
, startY
, stopX
, stopY
, которые я контролирую область спрайтов, которые я собираюсь нарисовать. Следует также отметить, что мои спрайты (или "пешеходы" ) существуют на TileMap
, поэтому они не равны 1 пикселю - у них есть их ширина и высота. Это добавляет небольшую сложность в том, как решить, что делать, но в основном это сводится к тому, "рисуйте, что внутри камеры, плюс немного больше по краям".
Клонировать репозиторий Pedeestrians на вашей собственной машине, заставить его работать, добавив те же зависимости к проекту, что и любой другой проект Slick2D, и воспроизведите/измените код рендеринга, пока не поймете, что происходит. Только с помощью практики и учебы вы получите все незначительные выводы о том, как это работает. Хорошей новостью является то, что как только вы выясните, как сделать рендеринг с помощью этого базового метода 2D-мира против камеры, вы в значительной степени знаете, как визуализировать графику для всех 2D-приложений, потому что концепции переводятся на все языки.
У меня также есть различные ролики пешеходов, которые запускаются на моем канале YouTube (наиболее релевантным видео является, вероятно, этот, в котором показаны мои основные пешеходы, которые отображаются, и камера перемещается), поэтому вы можете видеть, как это все выглядит, не создавая проект в первую очередь.