2017-02-13 59 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

谢谢。现在我明白你的代码是如何工作的。现在,我只需要知道如何找到不同形状之间的碰撞检测,除了鼠标之外。 –