2017-02-13 60 views
0

我想製作一個Flash Player,其中有玩家和牆壁之間的碰撞檢測。但是,當我嘗試使用Wall11.hitTestPoint()時,我無法使碰撞檢測完美。然後,我決定使用位圖,但很難對其進行編碼,因爲牆是不規則形狀的(它不是正方形,矩形,圓形或任何規則形狀)。無論如何,改善與牆壁的碰撞檢測?(Actionscript 3)牆壁和球員之間的像素完美的碰撞檢測?

function checkCollision(_debug:Boolean = false):Boolean {   
     var bmd1:BitmapData = new BitmapData(Wall11.width, Wall11.height, true, 0); 
     var bmd2:BitmapData = new BitmapData(LevelOnePlayer.width, LevelOnePlayer.height, true, 0); 

     bmd1.draw(Wall11); 
     bmd2.draw(LevelOnePlayer); 

     if (_debug) { 
      var bmp:Bitmap = new Bitmap(bmd1); 
      bmp.x = Wall11.x; 
      bmp.y = Wall11.y; 
      addChild(bmp); 

      var bmp2:Bitmap = new Bitmap(bmd2); 
      bmp2.x = LevelOnePlayer.x; 
      bmp2.y = LevelOnePlayer.y; 
      addChild(bmp2); 
     } 
     if(bmd1.hitTest(new Point(Wall11.x, Wall11.y), 255, bmd2, new Point(LevelOnePlayer.x, LevelOnePlayer.y), 255)) 
     return true; 
     if (!_debug) { 
      bmd1.dispose(); 
      bmd2.dispose(); 
     } 
     return false; 
    }  
+0

請解釋爲什麼hitTestPoint(最後一個參數shapeFlag = true)不適合你? – Organis

+0

無論我的觀點如何,當玩家距離牆太近或過遠時,牆會始終檢測到碰撞。我不知道如何將碰撞設置到我想要碰撞點的位置。 –

+0

再次,排除。你使用形狀和形狀的標誌?另外,您是否使用點座標或本地座標? – Organis

回答

0

這些是hitTestPoint的基礎知識。

package 
{ 
    import flash.geom.Point; 

    import flash.events.Event; 

    import flash.display.Shape; 
    import flash.display.Sprite; 
    import flash.display.StageAlign; 
    import flash.display.StageScaleMode; 

    import flash.text.TextField; 
    import flash.text.TextFormat; 
    import flash.text.TextFormatAlign; 

    public class HitTest extends Sprite 
    { 
     private var textArea:TextField; 
     private var Circle:Shape; 
     private var Box:Shape; 

     public function HitTest() 
     { 
      if (stage) onStage(); 
      else addEventListener(Event.ADDED_TO_STAGE, onStage); 
     } 

     private function onStage(e:Event = null):void 
     { 
      removeEventListener(Event.ADDED_TO_STAGE, onStage); 

      stage.scaleMode = StageScaleMode.NO_SCALE; 
      stage.showDefaultContextMenu = false; 
      stage.align = StageAlign.TOP_LEFT; 
      stage.stageFocusRect = false; 

      addShapes(); 
      addLabel(); 
      onFrame(); 

      // Call it every frame to keep things updated. 
      addEventListener(Event.ENTER_FRAME, onFrame); 
     } 

     private function onFrame(e:Event = null):void 
     { 
      // Place graphics to the center of the stage. 
      x = stage.stageWidth >> 1; 
      y = stage.stageHeight >> 1; 

      // Lets detect collision with the circle. 
      var aPoint:Point = new Point(); 

      // Take local mouse coordinates within the target shape. 
      aPoint.x = Circle.mouseX; 
      aPoint.y = Circle.mouseY; 

      // Convert them into the root coordinates - it is the ONLY correct way. 
      // Comment the next 2 lines to see how local coordinates fail to work. 
      aPoint = Circle.localToGlobal(aPoint); 
      aPoint = root.globalToLocal(aPoint); 

      // Hit test the point against shape. 
      // Set the last parameter to false to see hitTest against the shape bounding box. 
      var aHit:Boolean = Circle.hitTestPoint(aPoint.x, aPoint.y, true); 

      textArea.text = aHit? "! HIT !": "NO HIT"; 
     } 

     private function addShapes():void 
     { 
      Circle = new Shape(); 
      Circle.graphics.lineStyle(2, 0x000000, 1); 
      Circle.graphics.beginFill(0xCC99FF, 1); 
      Circle.graphics.drawCircle(0, 0, 50); 
      Circle.graphics.endFill(); 

      Box = new Shape(); 
      Box.graphics.lineStyle(0, 0xCCCCCC, 1); 
      Box.graphics.drawRect(-50, -50, 100, 100); 

      addChild(Box); 
      addChild(Circle); 
     } 

     private function addLabel():void 
     { 
      textArea = new TextField(); 

      textArea.x = 10; 
      textArea.y = 10; 
      textArea.width = 70; 
      textArea.height = 20; 

      textArea.border = true; 
      textArea.wordWrap = false; 
      textArea.multiline = true; 
      textArea.selectable = true; 
      textArea.background = true; 
      textArea.mouseEnabled = false; 

      var aFormat:TextFormat; 

      aFormat = textArea.getTextFormat(); 
      aFormat.font = "_typewriter"; 
      aFormat.size = 12; 
      aFormat.bold = true; 
      aFormat.align = TextFormatAlign.CENTER; 

      textArea.setTextFormat(aFormat); 
      textArea.defaultTextFormat = aFormat; 

      stage.addChild(textArea); 
      textArea.text = "NO HIT"; 
     } 
    } 
} 
+0

對不起,我沒有在一個月內回覆。無論如何,感謝您的幫助。雖然我不清楚這個部分:Circle.mouseX是什麼意思? –

+0

@GaryLuKOTH圓形座標系內的本地鼠標座標。請閱讀http://stackoverflow.com/questions/6062209/flash-as3-understanding-localtoglobal和http://www.emanueleferonato.com/2010/06/22/understanding-as3-localtoglobal-method/以獲得更好的理解。 – Organis

+0

謝謝。現在我明白你的代碼是如何工作的。現在,我只需要知道如何找到不同形狀之間的碰撞檢測,除了鼠標之外。 –