2011-10-09 62 views
2

我想停止影片剪輯移動,當它撞牆(另一個動畫片段)時。 下面的例子工作,但在碰撞後,movieclip'阻止'左邊的所有動作... 我的問題是,這是一個好方法,爲什麼它不能正常工作?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是假的

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的方法應該工作,我會建議另一種方法來做你的hittests。

由於您可能正在創建遊戲(角色和界限),因此您將擁有多個界限。在那種情況下,我會強烈建議位圖測試。這樣,您可以在一個動畫片段中創建所有邊界,並測試一個命中。

我將通過使用迷宮的例子來解釋這一點。然後迷宮就會在電影片段中隨機放在一起。如果您使用HitTestObject並且您沒有碰到其中一行,但是您的角色已經位於影片剪輯之後,即使您沒有碰到牆,hitTestObject也會返回true。通過使用bitmapHitTesting,你可以克服這個問題(BitmapHitTest會考慮透明度像素,而hitTestObject不會)。

下面你可以找到一個如何做bitmapHitTesting的例子。如果不改變形狀,在這個函數中創建位圖不是必須的。在這種情況下,我會建議將位圖數據的代碼放置在added_to_stage方法中。

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; 
    }           
} 

我用回踩相反的方向相反。