Войти
ПрограммированиеФорум2D графика и изометрия

Найти изометрический тайл по координатам мыши

#0
2:25, 7 янв. 2016

У меня изометрическая игра, координаты отрисовки определяю по позиции тайла относительно других тайлов следующими методами:
 

  Field tileX, tileY
  Const tileWidth = 114, tileHeight = 70
  Method x()
    Return tilex * (tileWidth / 2) - tiley * (tilewidth / 2)
  End Method
  Method y()
    Return tilex * (tileheight / 2) + tiley * (tileheight / 2)
  End Method

Таким образом я нахожу координаты отрисовки по координатам тайла. Внимание. Вопрос. Как мне найти координаты тайла по координатам отрисовки? Мне нужно определить на какой тайл указывает игрок по координатам мышки.


#1
8:53, 7 янв. 2016

Нужно обратное преобразование
Реши систему относительно tilex, tiley
tilex * (tileWidth / 2) - tiley * (tilewidth / 2) = x
tilex * (tileheight / 2) + tiley * (tileheight / 2) = y

#2
15:09, 7 янв. 2016

Aslan
Это не совсем верно. При отрисовке каждый тайл рисуется как прямоугольник, и по формулам Cancel_filipp можно найти координаты левого верхнего угла для отрисовки.
Чтобы найти координаты тайла по координатам мыши, нужно учитывать, что сам тайл в изометрии имеет форму ромба, т.е. повернутого на 45 градусов и сплюснутого по вертикали квадрата.
Здесь нужно иметь дело с преобразованием систем координат.

Берем координаты мыши относительно центра тайла: dx_s, dy_s.
Матрица масштабирования координат:

1 | Найти изометрический тайл по координатам мыши

В нашем случае:

2 | Найти изометрический тайл по координатам мыши
3 | Найти изометрический тайл по координатам мыши

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

4 | Найти изометрический тайл по координатам мыши

Если взаимная ориентация осей тайловой и экранной систем координат не совпадают - когда у них направления поворота от x к y различны, - нужно коэффициент scale_y взять отрицательным.

Матрица поворота:

5 | Найти изометрический тайл по координатам мыши

Соединяем все вместе.

6 | Найти изометрический тайл по координатам мыши

Здесь dx_s, dy_s - это исходные экранные координаты относительно центра тайла, а dx_t, dy_t - итоговые координаты в тайловой системе координат.
Фактически мы сделали следующее:

7 | Найти изометрический тайл по координатам мыши

Размер стороны квадрата равен:

8 | Найти изометрический тайл по координатам мыши

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

#3
16:16, 7 янв. 2016

Deirel, спасибо за столь развёрнутый ответ -))

#4
17:25, 7 янв. 2016

Deirel
Точно. Хотя верно если считать (x,y) с левого угла ромба

#5
18:16, 7 янв. 2016

Cancel_filipp

Можно ещё позанудничать, что проекция-де диметрическая, хотя 114/70 - довольно близко к [cht]\sqrt{3}[/cht].

https://en.wikipedia.org/wiki/Isometric_projection
https://en.wikipedia.org/wiki/Isometric_graphics_in_video_games_and_pixel_art

Но словосочетания "диметрическая игра" я вживую что-то и не слышал.

#6
22:40, 24 янв. 2016

Проще построить 4 прямые и посчитать, лежит ли точка выше двух и ниже двух. Несколько простых умножений и делений. Даже проверки можно не писать, так как мы заранее знаем природу этих прямых.

Может будет чуть затратнее по вычислениям (хотя сразу и не скажешь). Но зато просто и понятно реализуется.

#7
23:07, 24 янв. 2016

Это так же просто, как

if( condition == true ) return 0; else return 1;

#8
11:25, 5 мар. 2016

А я решаю простое математическое уравнение) грани изометрического тайла Нижняя и Верхняя это уравнения y=|x|/2 и y= |x|/-2. Координаты точки должны быть внутри получившегося ромба)

А то эксперты плохо учившие математику сейчас тебя научат..интегралы пойдешь постигать

#9
19:52, 7 мар. 2016

Cancel_filipp
http://www.gamedev.ru/code/forum/?id=123819&page=2#m18

#10
7:46, 11 мар. 2016

Начало системы координат и ограничения делай под себя.
c#, Unity.

  // Поиск индексов ячейки над которой находится курсор мыши
  public bool GetIndexCellDMNDOfMousePos(ref CGameServer.Index2 index)
  {
    // Текущий scale
    Vector3 scale = gameObject.GetComponent<RectTransform>().lossyScale;

    // Начало системы координат(пока центр)
    Vector2 axesPos = new Vector2((float)Screen.width / 2.0f,
                    (float)Screen.height / 2.0f + (CGame.GetBckgrHeight() / 2.0f + CGame.c_DeltaY + CGame.GetDmndHeight() / 2.0f) * scale.y);

    // Вектор мыши
    Vector2 m_MouseV = new Vector2(Input.mousePosition.x, Input.mousePosition.y);

    // Переносим в начало координат ромба
    m_MouseV -= axesPos;

    float p = CGame.GetDmndWidth() / 2.0f * scale.x;
    float q = CGame.GetDmndHeight() / 2.0f * scale.y;

    float xi = -(q * m_MouseV.x + p * m_MouseV.y) / (2 * p * q);
    float yi = (q * m_MouseV.x - p * m_MouseV.y) / (2 * p * q);

    index = new CBaseGameServer.Index2();

    // Если чтото меньше нуля то не попали
    if (xi < 0.0f || yi < 0.0f)
      return false;

    // Берём целую часть
    xi = (int)xi;
    yi = (int)yi;

    // Проверяем верхние границы
    if (xi > CGame.m_CellsCount - 1 || yi > CGame.m_CellsCount - 1)
      return false;

    // Всё ОК
    index.x = (int)xi;
    index.y = (int)yi;

    return true;
  }
ПрограммированиеФорум2D графика и изометрия

Тема в архиве.