6 각형 클릭 박스 인식


17

나는 헐떡 거림 육각형 과 관련된 게임을 만들고 있습니다.

현재 사용중인 육각 이미지가 있습니다 (모든면의 길이는 동일합니다 ... 50 x 50px 이미지에 맞습니다).

나는 C #에 다소 익숙하지 않고 실제로 XNA에 익숙하지 않지만 점과 각도를 기반으로 복잡한 if 문을 수행하는 대신 호출 할 수있는 쉬운 방법이 있습니까?


16 진 클릭 감지를 구현하는 gamedev.stackexchange.com/questions/6382/… 를 참조하십시오 .
팀 홀트

4
나는 "어떻게 육각형입니까?" 내가 느린 하루를 보내고 있다고 생각합니다.
MichaelHouse

2
흠 육각형이 아닌 가스켓을 클릭하면 어떻게됩니까?
팀 홀트

1
귀하의 요구에 따라 클릭 영역에 대한 간단한 원이 가능합니다. 그렇지 않으면 권선 합계 또는 합계와 같은 다각형 기술의 점을 사용해야합니다.
PhilCK

16 진 맵을 임의로 회전하지 않는 한 다각형의 점은 MAJOR overkill입니다. 1000x1000 헥스 인지도로 무엇을합니까? 모두 확인 하시겠습니까? RE : 서클, 작동하지 않습니다. 3 개의 육각형 사이의 정점 근처에는 3 개의 원이 겹칩니다. 육각형 안에 완전히 놓인 작은 원은 적법한 클릭이 원 안에 없을 때 간격이 있습니다.
팀 홀트

답변:


18

육각형은 모서리가 잘린 사각형입니다. 내가 본 것을 보았고 문명 시리즈가 직교 맵 으로이 작업을 수행하는 것을 들었습니다. 공백 또는 직교 또는 육각형 공백과 빨강, 녹색, 파랑 및 노랑이있는 비트 맵을 만드는 것입니다 모서리. (또는 원하는 색상)

육각형 : 육각 마스크또는여기에 이미지 설명을 입력하십시오

직교 : 여기에 이미지 설명을 입력하십시오

그런 다음 커서가있는 사각형을 결정하고 해당 위치의 픽셀 색상을 테스트하십시오. 흰색이면 그 공간을 가리키고 있습니다. 서로 다른 색상은 오프셋에 매핑되며 대신 해당 육각형 위로 가져갑니다. 이 방법은 효율적이며 형상이 거의 필요 없으며 임의의 테셀레이션 공간에 사용할 수 있습니다.


참고 사항 : 육각형의 길이는 6과 같습니다. 제시 한 이미지에는 실제로 육각형이 없습니다. 대신 6면 다각형을 포함합니다. 그 외에는이 방법이 효과적입니다. 큰 육각형의 경우 육각형의 경계를 계산하는 것보다 느릴 수 있습니다.이 방법은 큰 육각형을위한 더 많은 공간이 필요하기 때문에 (픽셀 당 정확도를 유지하려는 경우). 작은 육각형 (및 하드웨어에 따라 다름)의 경우이 방법은 범위를 계산하는 것보다 빠릅니다.
Olhovsky

9
육각형은 6면 다각형입니다. 당신이 생각하는 것은 인 육각형 (실제로, 당신은 아마 생각하고 정기적으로 정의 유형입니다 육각형, 등각 육각)
Random832

당신의 대답이 나쁘다는 말은 아닙니다. 나는 그것이 좋은 대답이라고 생각합니다. 즉, 경계를 계산하는 것이 훨씬 확장 가능한 방법이므로 현대 플랫폼에서 육각 경계를 계산할 때 육각 경계를 계산하는 것 보다이 방법을 선택하지 않을 것입니다. 예를 들어 육각형 크기를 변경하고 싶다고 말하면 이미지를 다시 만들어야합니까? 완벽한 픽셀 육각 마스크를 만드는 것은 고통입니다. 당신이 여기서 생산하지 않았다는 사실은 그 증거입니다.
Olhovsky

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 배열 (폴리)과 클릭 한 위치 (p)로 메서드에 제공해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.