Изометрический экран на карту - PullRequest
5 голосов
/ 13 сентября 2010

Я пытаюсь выяснить, как получить правильную «активную» плитку под мышью, когда у меня есть плитки «рампа» и +1 высота (см. Рисунок ниже).

Example Isometric Image

Когда мой мир плоский, все работает без проблем.Как только я добавляю плитку с высотой, скажем, +1, вместе с рампой, возвращающейся к +0, моя процедура screen -> map по-прежнему выглядит так, как будто все «плоско».

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

Вот мой рендер карты (очень простой)

canvas.width = canvas.width; // cheap clear in firefox 3.6, does not work in other browsers
for(i=0;i<map_y;i++){
    for(j=0;j<map_x;j++){
        var xpos = (i-j)*tile_h + current_x;
        var ypos = (i+j)*tile_h/2+ current_y;

      context.beginPath();
      context.moveTo(xpos, ypos+(tile_h/2));
      context.lineTo(xpos+(tile_w/2), ypos);
      context.lineTo(xpos+(tile_w), ypos+(tile_h/2));
      context.lineTo(xpos+(tile_w/2), ypos+(tile_h));
      context.fill();

    }
}    

А вотмоя мышь -> подпрограмма карты:

ymouse=( (2*(ev.pageY-canvas.offsetTop-current_y)-ev.pageX+canvas.offsetLeft+current_x)/2 );
xmouse=( ev.pageX+ymouse-current_x-(tile_w/2)-canvas.offsetLeft );
ymouse=Math.round(ymouse/tile_h);
xmouse=Math.round(xmouse/(tile_w/2));

current_tile=[xmouse,ymouse];

У меня такое чувство, что мне придется начинать сначала и внедрять систему карт мира, а не простой экран -> подпрограмма карты.

Благодаря.

Ответы [ 2 ]

2 голосов
/ 15 сентября 2010

Если, как и на картинке, угол обзора всегда равен 45 градусам и всегда в одном и том же направлении, процедура мыши -> карты может использовать алгоритм, подобный следующему:

  1. вычислите i, j плитки, как вы делаете в данный момент (ваше окончательное значение xmouse, ymouse)
  2. посмотрите высоту и угол наклона плитки в i, j
  3. учитывая высоту и угол, пересекает ли эта плитка луч луча? Если это так, установите lasti, lastj = i, j
  4. увеличение / уменьшение i, j на один шаг по диагонали к зрителю
  5. мы упали с края карты? Если это так, верните Ласти, в прошлом. В противном случае вернитесь к 2.

В зависимости от максимальной высоты плитки, вам, возможно, придется проверять только 2 плитки, а не идти до самого края карты.

3 - сложная часть, которая зависит от геометрии вашего мира. Нарисуйте несколько треугольников, и вы сможете понять это. Или вы можете попробовать посмотреть на функцию intersect_quadrillar_ray () здесь .

2 голосов
/ 13 сентября 2010

Ваше предположение верно. Чтобы «выбрать» геометрию мира, ваша рутина должна быть осведомлена о мире (а не только о конфигурации плитки базового уровня). То есть без какого-либо представления о высоте плиток рядом с той, которая выбрана в данный момент (по вашему текущему алгоритму), невозможно определить, должна ли соседняя плитка (или даже еще дальше, в зависимости от разрешенной высоты) быть перехвачен, выбирая луч.

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

...