Ваш первоначальный вопрос относительно этих двухмерных объектов немного расплывчат, и лучший ответ зависит от более строгого определения.
Если это объекты в вашем игровом мире (например, имена над головами, рекламные щиты), то им нужна позиция в мире, и вы переводите ее в положение на экране, как правило, с помощью класса камеры, как описано в другом ответе.
Если, однако, это объекты графического интерфейса пользователя, такие как меню, формы, заголовки и т. Д., То это совсем другое. В этом случае вам нужно только сохранить позицию относительно родительского элемента (т.е. локальную позицию), и рисование их может быть выполнено рекурсивно. Положение каждого элемента - это, в основном, глобальная позиция его родителя плюс его собственная локальная позиция, и это поднимается вверх по дереву любым родителям верхнего уровня, локальные позиции которых также являются глобальными позициями.
РЕДАКТИРОВАТЬ: пример, приведенный для пояснения. Неопробованный псевдокод в Python-стиле (извините, я не знаю C #)
def draw(element, parentScreenX, parentScreenY):
# Draw this element relative to its parent
screenX = parentScreenX + element.localX
screenY = parentScreenY + element.localY
render(element, screenX, screenY)
# Draw each child relative to this one
for childElement in element.children:
draw(childElement, screenX, screenY)
# Normal usage (root element should be at 0,0,
# and typically just an invisible container.)
draw(rootElement, 0, 0)
# Slightly different mathematics for the mouseover test,
# but that's just personal preference
def elementAtPos(element, posX, posY):
# Translate that space to element local space
posX -= element.localX
posY -= element.localY
# Compare against this element's dimensions
if (posX, posY) is within (0, 0, element.width, element.height):
# it's within this element - now check children
for childElement in element.children:
# Do this same check on the child element (and its children, etc)
targetedChildElement = elementAtPos(childElement, posX, posY)
if targetedChildElement is not None:
return targetedChildElement
# it wasn't within any of our descendants so return this one
return element
# It wasn't within our bounds at all, so return None
return None
#Normal usage
targetedElement = elementAtPos(rootElement, mouseScreenX, mouseScreenY)
Вам могут потребоваться две отдельные функции: одна, которая получает точный целевой элемент (как указано выше), и другая, которая просто возвращает, если мышь находится где-либо над элементом, которая может возвращать true для нескольких элементов одновременно, например. кнопка, панель, кнопка включена, форма панели включена и т. д. Это можно реализовать несколькими способами, но, вероятно, проще всего реализовать рекурсивный вызов, чтобы позволить любому элементу получить свою позицию на экране:
def screen_position(element):
if element.parent is not None:
(parentLocalX, parentLocalY) = screen_position(element.parent)
else:
(parentLocalX, parentLocalY) = (0,0)
return (element.localX + parentLocalX, element.localY + parentLocalY)
Не упустите круговую ссылку теперь между родителями и детьми.
Все они требуют наличия корневого элемента в 0,0 - это облегчает преобразование между экранным пространством и локальным пространством для корневого элемента, потому что они фактически одинаковы. Тогда остальная часть алгоритма может работать в локальном пространстве.