Розпізнавання шестикутної кліки


17

Я працюю над грою, в якій збираються задихатись шестикутники.

В даний час у мене є зображення шестикутника, яке я використовую (усі сторони однакової довжини ... він вписується у зображення 50px на 50px).

Я дещо новачок у C # і справді новачок у XNA, але чи є якийсь простий метод, який я можу викликати, а не робити зведений, якщо твердження засноване на точках та кутах?


Дивіться сторінку gamedev.stackexchange.com/questions/6382/…, яка реалізує шістнадцяткове виявлення кліків.
Тім Холт

4
Я цілком гуглів "задихаючись шестикутників", як я був, "що це за шестикутник ?!" Здогадайтесь, у мене повільний день.
MichaelHouse

2
Хм, що станеться, якщо натиснути на задишку, а не на шестикутник?
Тім Холт

1
Залежно від ваших потреб, просте коло зробить, якщо його просто для області клацання. Інакше вам доведеться використовувати крапку в техніці багатокутника, наприклад, намотування суми або сум.
PhilCK

Якщо шестигранну карту не потрібно довільно обертати, точкою на полігоні є МАЖЛИЙ надмір. Що ви робите з картою розміром 1000x1000 шестигранниками? Перевірити кожного? RE: Кола, вони не працюватимуть. Біля вершини стику між трьома шестигранниками ви матимете три кола, що перекриваються. Менші кола, які повністю лежать в межах шестигранників, матимуть прогалини, коли законних клацань не буде в жодному колі.
Тім Холт

Відповіді:


18

Шестикутник - це прямокутник із обрізаними кутами. Те, як я бачив це, і я чув, що серія Civilization робить це так з ортогональними картами, це створити растрову карту з білим простором (ортогональним або шестикутним), червоним, зеленим, синім і жовтим куточок. (Або будь-яких кольорів вам подобається.)

Шестикутна: Шестигранна маскаабовведіть тут опис зображення

Ортогональні: введіть тут опис зображення

Потім просто визначте, на якому прямокутнику курсор закінчено, і протестуйте колір пікселя в цьому місці. Якщо вона біла, вони нависають над цим простором. Кожен інший колір відображається зі зміщенням, а вони наводять курсор на цей шестикутник. Цей спосіб ефективний, займає мало геометрії і може бути використаний для будь-якого довільно тесселюючого простору.


Лише зауваження: у шестикутника 6 сторін однакової довжини. Жодне із представлених вами зображень насправді не містить шестикутників. Натомість вони містять 6 однобічних багатокутників. Крім цього, цей метод працює. Це, мабуть, повільніше, ніж обчислення меж шестикутника, але для великих шестикутників, оскільки цей метод вимагає більше місця для більших шестикутників (якщо ви хочете зберегти точність пікселя). Для невеликих шестикутників (і в залежності від обладнання) цей метод, ймовірно, швидший, ніж обчислення меж.
Ольховський

9
Шестикутник - це будь-який шестигранний багатокутник. Те, про що ти думаєш, - це рівносторонній шестикутник (насправді ти, мабуть, думаєш про звичайний шестикутник, який є типом рівностороннього та рівнобедреного шестикутника)
Random832

Зверніть увагу, що я не казав, що ваша відповідь була поганою. Я думаю, що це хороша відповідь і рішення, яке має своє місце. При цьому я не вибрав би цей метод над обчисленням шестикутних меж, як обчислення шестикутника на будь-якій сучасній платформі, оскільки обчислення меж є набагато більш розтяжним способом зробити це. Наприклад, скажімо, що ви хочете змінити розмір шестикутника - тепер вам доведеться перебудувати зображення? Виробляти піксельну ідеальну шестикутну маску - це біль. Я думаю, те, що ви тут не створили жодного, є свідченням цього.
Ольховський

2
@Olhovsky - Я не створив тут ідеальної шестикутної маски, тому що я відповідаю на запитання як комунальна служба під час моїх декількох хвилинних перерв на роботі, а насправді не пишу відео-гру. ОП шукала рішення з меншою кількістю математики, і я подумала, що це акуратно, тому я подумав, що поділюсь, тому що я, звичайно , не міг би подумати самостійно.
dlras2

18

Не існує методу XNA, який би робив тест на шестикутник.

Ця стаття пояснює, як написати функцію, яка робить тест, і дає вам функцію:

Як перевірити, чи знаходиться точка всередині шестикутника

Ось короткий опис цієї статті: шестикутник клік

А функція, яка робить тест, працює так:

  1. Перевірте обмежувальний ящик навколо шестикутника, на початку, якщо він не перетинає його.
  2. Перетворіть точку в локальний квадрант, як показано вище.
  3. Виконайте наступний isInsideтест для локального квадранта.

public function isInside(pos:Vec2Const):Boolean
{
    const q2x:Number = Math.abs(pos.x - _center.x);       
    const q2y:Number = Math.abs(pos.y - _center.y);
    if (q2x > _hori || q2y > _vert*2) 
        return false;
    return 2 * _vert * _hori - _vert * q2x - _hori * q2y >= 0;
}

Детальну інформацію див. У статті.


Ось деякі інші корисні пов’язані джерела:


1

Тут я отримав метод, який можна використовувати для виявлення кліків всередині будь-якого багатокутника:

public bool PointInPolygon( Vector2 p, Vector2[] poly )
    {
        Vector2 p1, p2;
        bool inside = false;

        if( poly.Length < 3 )
        {
            return inside;
        }

        Vector2 oldPoint = new Vector2( poly[poly.Length - 1].X, poly[poly.Length - 1].Y );

        for( int i = 0; i < poly.Length; i++ )
        {
            Vector2 newPoint = new Vector2( poly[i].X, poly[i].Y );

            if( newPoint.X > oldPoint.X )
            {
                p1 = oldPoint;
                p2 = newPoint;
            }
            else
            {
                p1 = newPoint;
                p2 = oldPoint;
            }

            if( ( newPoint.X < p.X ) == ( p.X <= oldPoint.X )
                && ( (long)p.Y - (long)p1.Y ) * (long)( p2.X - p1.X )
                 < ( (long)p2.Y - (long)p1.Y ) * (long)( p.X - p1.X ) )
            {
                inside = !inside;
            }

            oldPoint = newPoint;
        }

        return inside;
    }

Вам потрібно надати кути свого шестикутника в масиві vector2 (poly) та натиснуту позицію (p) методу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.