Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
225 views
in Technique[技术] by (71.8m points)

flash - (Actionscript 3) Pixel-perfect collision detection between the walls and player?

I am trying to make a flash game in which there is collision detection between the player and the walls. However, when I try using Wall11.hitTestPoint(), I cannot get the collision detection to be perfect. Then, I decided to use bitmap but it is hard to code this because the wall is irregularly shaped (it is not a square, rectangle, circle or any regular shape). Is there anyway to improve the collision detection with walls?

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;
    }    
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

These are basics of hitTestPoint stuff.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...