2017-01-08 7 views
0

Sprite 클래스를 확장하는 Avatar 클래스가 있습니다. 또한 Walkable 영역과 Walkable 영역의 Bitmap과 방의 삽화 자체를 포함하는 Room 클래스가 있습니다.마스크상의 스프라이트 이동

흑백 마스크를 실제로 보이지 않고 사용자가 방 "마스크"의 흰색/투명한 부분을 걸을 수 있는지 확인해야합니다. 사용자가 마스크의 검은 부분에 신속하게 들어가는 것을 방지하기 위해 사용할 수있는 기능은 무엇입니까? 스프라이트가 제대로 자신의 (0,0) 점을 중심으로 정렬되어

+0

오래 전 나는 무작위로 내부에 탁구 공 충돌을 프로그램했습니다. 공의 윤곽선에 몇 가지 가드 포인트를 추가하고 내부 그래픽과 함께 hitTest (귀하의 경우에는 비트 맵 픽셀 테스트)를 추가했습니다. – Organis

+0

그런 실행 취소 마스크를 사용하여 적중 테스트의 예를 들어 주시겠습니까? 샘플 코드. – Fuselight

+0

아래에 게시하십시오. – Organis

답변

1

당신은

private const ALLOWANCE:Number = .1; 
private function isTurnAllowed(maskBMD:BitmapData, position:Point):Boolean 
{ 
    //0xAARRGGBB 
    var color32:uint = maskBMD.getPixel32(int(position.x), int(position.y)); 
    var alpha:uint = color32 >> 24 & 0xff; 
    var red:uint = color32 >> 16 & 0xff; 
    var green:uint = color32 >> 8 & 0xff; 
    var blue:uint = color32 & 0xff; 

    var color24:uint =color32 >> 8 & 0xffffff; 

    /* 
    if (alpha == 0 || color24 == 0xffffff) return true 

    strictly speaking this string is enough but in real your bitmap mask after resampling can have some interpolation artifacts so you need some allowance to pass not strictly white. 
    */ 
    var absoluteLightness:Number = red + green + blue + (0xff - alpha);//transparent is 0x00 
    var maximalLight:Number = 0xff * 4; 
    var lightness:Number = absoluteLightness/maximalLight; 
    if (lightness > 1 - ALLOWANCE) 
     return true 
    else 
     return false 

} 
+0

getPixel32()가 느리지 않습니까? 이 이벤트는 KeyDown 이벤트가 발생할 때마다 실행됩니다. – Fuselight

+1

프레임 당 백만 건의 작업이 필요하면 충분히 느립니다. 하지만 초당 100 ~ 200 위치를 확인하는 것이 좋습니다. 간단한 테스트로 성능을 확인할 수 있습니다. \t \t var bitmapData:BitmapData = new BitmapData(1000, 1000, true); \t \t var pos:Point = new Point(100, 100); \t \t var lastTime:Number = getTimer(); \t \t for (var i:int = 0; i < 100000; i++) \t \t { \t \t \t var isAllow:Boolean = isTurnAllowed(bitmapData, pos); \t \t } \t \t trace(getTimer() - lastTime); //78 millisecond

1

당신의 아바타를 말할 수 있습니다 메모리에이 '걷기'비트 맵이 필요합니다. 그런 다음 Walkable : Sprite를 만들 수 있습니다. 을 표시 목록에 첨부해야하지만 반드시 표시 할 필요는 없으며 Walkable.visible = false로 설정할 수 있습니다.

function moveBy(dx:Number, dy:Number):void 
{ 
    var aPoint:Point = new Point(); 
    aPoint.x = Avatar.x + dx; 
    aPoint.y = Avatar.y + dy; 

    // hitTestPoint works with Stage coordinates. 
    aPoint = Avatar.parent.localToGlobal(aPoint); 

    if (Walkable.hitTestPoint(aPoint.x, aPoint.y, true)) 
    { 
     Avatar.x += dx; 
     Avatar.y += dy; 
    } 
} 

이 코드는 매우 간단합니다.이 코드는 Walkable지도에서 아바타를 옮기는 것을 허용하지 않습니다.

+0

내 아바타가 실제로 큰 스프라이트 시트 인 경우 scrollRect가있는 비트 맵은 무엇입니까? 이 코드가 스프라이트 시트의 보이지 않는 부분을 걷지 못하는 영역과 충돌시키는 것을 허용하지 않을까요? – Fuselight

+0

DisplayObject.hitTestPoint (...)는 스테이지의 좌표로 단일 점을 검사합니다. 세 번째 인수는 경계 상자가 아닌 표시 객체의 실제 모양을 사용하도록 지정하기 때문에 Walkable이 모양 채우기 여야합니다. 방금 다른 프로젝트에서 사용한 것을 기억합니다. http://delimiter.ru/games/umoria/ 반사 벡터를 계산하기 위해 여러 점을 테스트 할 때 상황이 스크립트보다 조금 더 복잡하지만 기본은 같은. – Organis

+1

내 말은 상자 대 경계 상자 충돌을 경계 짓는 것이 아니라 무작위 형태의 충돌과 포인트가 맞다고 생각하며 귀하의 필요에 정확히 부합한다고 생각합니다. – Organis