2011-10-09 4 views
2

무비 클립이 벽에 부딪 힐 때 (다른 무비 클립) 멈추고 싶습니다. 아래의 예는 작동하지만 충돌이 발생하면 무비 클립이 모든 동작을 왼쪽으로 '차단'합니다. 내 질문은 이것이 좋은 방법일까요? 왜 제대로 작동하지 않는 것입니까?AS3 캐릭터가 벽을 통해 움직이는 것을 막으십시오.

이 코드에는 문제가있을 수 있지만 잘 배우고 있습니다. 이제는 leftArrow 키를 사용한 예제입니다. 충돌 키/운동

var leftArrow:Boolean; 
var speed:int = 10; 
var hitting:Boolean; 
var ismoving:Boolean; 

이벤트 리스너 및 검출 :

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); 
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased); 
stage.addEventListener(Event.ENTER_FRAME, walking); 
stage.addEventListener(Event.ENTER_FRAME, detectHit); 

는 충돌 검출 기능이 이동하거나하지 않다면

변수는 벽을 때리고 경우 키를 체크하고 :

function detectHit(e:Event) :void 
{ 
    if(char.hitTestObject(bounds)) 
    { 
     hitting = true; 
    } 
} 

왼쪽 화살표 키 기능 :

function keyPressed(event:KeyboardEvent):void 
{ 

    if (event.keyCode == Keyboard.LEFT) 
    { 
     leftArrow = true; 
    } 

} 

function keyReleased(event:KeyboardEvent):void 
{ 

    if (event.keyCode == Keyboard.LEFT) 
    { 
     leftArrow = false; 
    } 

} 

그리고 그것은 작동하지 않는 이유는 아마 여기에,하지만 난 왜하지 이해하지 않는다 : hitting이 false 인 경우

function walking(event:Event):void { 
    if (rightArrow) { 
     char.x += speed;  
    } 

    if (leftArrow && ! hitting) { 
     char.x -= speed; 
    } 
    else 
    { 
     ismoving = false 
    } 

답변

4
if (leftArrow && ! hitting) 

char가 이동합니다. char.hitTestObject(bounds)이 참일 경우 hitting을 true로 설정합니다. 아무 곳에서나 hitting을 다시 false로 설정하지 않습니다. 그래서 왼쪽 벽이 한 번 치면 왼쪽 움직임이 영구적으로 멈추는 것입니다. hitting을 false로 다시 설정하기에 적합한 조건을 찾아야합니다.

detectHit에 else 분기를 추가하면 문제가 해결됩니다.

function detectHit(e:Event):void { 
    if(char.hitTestObject(bounds)) 
    { 
     hitting = true; 
    } else { 
     hitting = false; // add this 
    } 
} 
+2

아니면 그냥 'hitting = char.hitTestObject (bounds)' – LiraNuna

+0

예, 좋을 것입니다. – taskinoor

+0

@ taskinoor 설명과 시간을내어 주셔서 감사합니다. – Opoe

1

Allthough Taskinoor의 방법이 작동해야합니다. 나는 당신의 히트 테스트를 할 다른 방법을 제안합니다.

게임 (캐릭터 및 경계)을 작성하고 있으므로 둘 이상의 경계가 설정됩니다. 이 경우 비트 맵 히트 테스트를 강력하게 제안합니다. 이렇게하면 하나의 무비 클립에서 모든 범위를 만들고 히트를 테스트 할 수 있습니다.

미로의 예를 사용하여 설명하겠습니다. 미로는 무작위로 모인 무비 클립의 일부 선이됩니다. HitTestObject를 사용하고 행 중 하나에 충돌하지 않지만 캐릭터가 무비 클립 위에 있으면 hitTestObject는 벽을 치지 않고 있어도 true를 반환합니다. bitmapHitTesting을 사용하면이 문제를 극복 할 수 있습니다 (BitmapHitTest는 투명 픽셀을 고려하지만 hitTestObject는 그렇지 않습니다).

아래에서 bitmapHitTesting을 수행하는 방법의 예를 찾을 수 있습니다. 모양을 변경하지 않으면이 함수에서 비트 맵을 만드는 것이 필요하지 않습니다. 이 경우, 비트 맵 데이터의 코드를 added_to_stage-method에 두는 것이 좋습니다. 내 힌트에서

private var _previousX:int; 
private var _previousY:int; 
private var _bmpd:BitmapData ; 
private var _physicalBitmapData:BitmapData; 

private function walkAround(e:Event):void 
{ 
    var _xTo:int = //Calculate x-to-position; 
    var _yTo:int = //Calculate y-to-position; 

    //If your character doesn't change shape, you don't have to recalculate this bitmapData over and over. 
    //I suggest placing it in a ADDED_TO_STAGE-Event in that case. 
    _bmpd = new BitmapData(char.width, char.height, true, 0); 
    _bmpd.draw(char); 

    //If your bounds are static, you don't have to recalculate this bitmapData over and over. 
    //I suggest placing it in a ADDED_TO_STAGE-Event in that case. 
    _physicalBitmapData = new BitmapData(bounds.width, bounds.height, true, 0); 
    _bmpd.draw(bounds); 

    //The below line is the actual hittest 
    if(_physicalBitmapData.hitTest(new Point(0, 0), 255, _bmpd, new Point(char.x, char.y), 255)) 
    { 
     char.x = _previousX; 
     char.y = _previousY; 
    } 
    else 
    {   
     char.x = _xTo; 
     char.y = _yTo; 
    } 

    _previousX = char.x; 
    _previousY = char.y; 
} 
+0

이 답변 주셔서 감사합니다. 시간을내어 평가 해 주시면 감사하겠습니다! – Opoe

1

봐,

function loop(Event) 
{  
    if(isHit==false) 
    { 
     if(isRight==true){head_mc.x+=1} 
     if(isLeft==true){head_mc.x-=1} 
     if(isUp==true){head_mc.y-=1} 
     if(isDown==true){head_mc.y+=1} 
    } 

    if(head_mc.hitTestObject(build_mc)) 
    { 
     isHit=true; 

     if(isRight==true){head_mc.x-=1} 
     if(isLeft==true){head_mc.x+=1} 
     if(isUp==true){head_mc.y+=1} 
     if(isDown==true){head_mc.y-=1} 
    } 
    else 
    { 
     isHit=false; 
    }           
} 

내가 대신 반대 방향으로 돌아 단계를 사용합니다.

관련 문제