墙碰撞问题AS3

时间:2014-02-28 21:23:19

标签: actionscript-3 flash collision-detection hittest flash-cs3

我正在制作一个角色在不同的房间里走动的游戏,但我想让它不要穿过墙壁。我尝试制作一个障碍符号来阻止它,但由于四个墙围住了角色,hitTestObject每次都返回true,而不仅仅是当它碰到墙壁的坚固部分时。简单地使用hero.x< 0是角色可以装备的物品,使英雄的符号延伸到0以下。所有符号都已调整大小,所以我不能只在英雄的符号中获得符号的宽度。有什么想法可以更好地检测碰撞?可能是hitTestPoint,但不确定如果没有大量的测试点,它将如何工作。 。

2 个答案:

答案 0 :(得分:0)

你可以使用迷宫游戏墙的逻辑。

它使用wall.hitTestPoint(character.x, character.y)

以下是maze game的示例。

答案 1 :(得分:0)

这是一个快速演示,展示了我在评论中提到的想法:

package {

    import flash.geom.Rectangle;

    import flash.geom.Point;

    import flash.utils.Proxy;

    import flash.external.ExternalInterface;

    import flash.text.TextField;

    import flash.ui.Keyboard;

    import flash.utils.Dictionary;

    import flash.events.KeyboardEvent;

    import flash.display.DisplayObject;

    import flash.events.Event;

    import flash.display.Sprite;

    public class HitTestShapeTest extends Sprite {



        private var player:Player;

        private var vx:Number = 0,vy:Number = 0;

        private var speed:Number = 2;

        private var previousValidPos:Point = new Point();

        private var maze:DisplayObject;

        private var keys:Dictionary = new Dictionary();

        private var t:TextField;

        public function HitTestShapeTest() {

            addEventListener(Event.ADDED_TO_STAGE,init);

        }

        private function init(e:Event):void{

            maze = addChild(new Maze());

            player = addChild(new Player()) as Player;

            player.x = stage.stageWidth * .5;

            player.y = stage.stageHeight * .5;

            previousValidPos.x = player.x;previousValidPos.y = player.y;

            stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);

            stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp);

            this.addEventListener(Event.ENTER_FRAME,update);     

            t = addChild(new TextField()) as TextField;   t.text = "oi";

            ExternalInterface.call("alert('ready');");

        }

        private function onKeyDown(e:KeyboardEvent):void{

            keys[e.keyCode] = true;//this key is pressed, make that available for the update call

            t.text = ""+e.keyCode;

        }



        private function onKeyUp(e:KeyboardEvent):void{

            keys[e.keyCode] = null;//clear the hash map entry for the released key

            vx = vy = 0;

        }



        private function update(e:Event):void{

            //move player

            if(keys[Keyboard.LEFT] != undefined)  vx = -speed;

            if(keys[Keyboard.RIGHT] != undefined) vx =  speed;

            if(keys[Keyboard.UP] != undefined)    vy = -speed;

            if(keys[Keyboard.DOWN] != undefined)  vy =  speed;

            //update positions

            player.x += vx;

            player.y += vy;



            //get the boundary point in the direction of movement

            var bounds:Rectangle = player.getBounds(this);     //beg the character's bounds

            var testPoint:Point = new Point();
            //check which point is at the edge of the character in the direction of movement
            if(vx != 0 || vy != 0){

                if(vx < 0) testPoint.x = bounds.x;//left

                else       testPoint.x = bounds.x+bounds.width;//right

                if(vy < 0) testPoint.y = bounds.y;//top

                else       testPoint.y = bounds.y+bounds.height;//bottom

                if(vy == 0) testPoint.y = bounds.y + bounds.height * .5;//moving on x axis only, use the vertical centre on y 
                if(vx == 0) testPoint.x = bounds.x + bounds.width * .5;//moving on y axis only, use the vertical centre on x 
            }

            //check collisions

            var isHit:Boolean = maze.hitTestPoint(testPoint.x,testPoint.y,true);//check for collisions

            if(!isHit){//didn't hit anything, remember this valid position

                previousValidPos.x = player.x;

                previousValidPos.y = player.y;

            }else{//restore position because we just hit something

                player.x = previousValidPos.x;

                player.y = previousValidPos.y;

            }

            //debug graphics

            graphics.clear();

            graphics.lineStyle(1,0x990000);

            graphics.drawRect(bounds.x,bounds.y,bounds.width,bounds.height);

            graphics.drawCircle(testPoint.x,testPoint.y,5);

            player.alpha = isHit ? .5 : 1;

        }

    }

}
import flash.display.BlendMode;

import flash.events.Event;

import flash.display.Shape;

class Player extends Shape{

    public function Player(){

        init(); 

    }

    private function init():void{

        graphics.lineStyle(10);

        graphics.drawCircle(0,0,10);

        graphics.moveTo(0,10);

        graphics.lineTo(0,20);

        graphics.lineTo(-10,20);

        graphics.moveTo(0,20);

        graphics.lineTo(10,20);

        graphics.moveTo(0,20);

        graphics.lineTo(0,30);

        graphics.lineTo(-10,40);

        graphics.moveTo(0,30);

        graphics.lineTo(10,40);
        blendMode = BlendMode.LAYER;
    }

}

class Maze extends Shape{

    private var size:Number = 50;

    public function Maze(){

        addEventListener(Event.ADDED_TO_STAGE,init);

    }

    private function init(e:Event):void{

        graphics.beginFill(0);

        graphics.lineTo(stage.stageWidth,0);

        graphics.lineTo(stage.stageWidth,size);

        graphics.lineTo(size*4,size);

        graphics.lineTo(size*4,size*3);

        graphics.lineTo(size*3,size*3);

        graphics.lineTo(size*3,size);

        graphics.lineTo(size,size);

        graphics.lineTo(size,size*8);

        graphics.lineTo(stage.stageWidth,size*8);

        graphics.lineTo(stage.stageWidth,stage.stageHeight);

        graphics.lineTo(0,stage.stageHeight);

        graphics.lineTo(0,0);

        graphics.endFill();

    }

}

将其另存为HitTestShapeTest.as并将其设置为新的.fla文件的文档类以运行代码,或尝试this 另请查看adobe网站上的maze tutorial