Question

I'm making a game where a character walks around different rooms, but I want to keep it from going through the walls. I tried making a barrier symbol to stop it, but since the four walls enclose the character, hitTestObject returns true every time, not just when it hits the solid parts of the walls. My problem with simply using hero.x < 0 is that there are items that the character can equip that cause the hero's symbol to extend below 0. All of the symbols have been resized so I can't just get the width of the symbol within the hero's symbol. Any ideas for a better method of detecting collision? Possibly hitTestPoint, but not really sure how that would work without a huge array of points to test . . .

Was it helpful?

Solution

Here is a quick demo showing the ideas I mentioned in the comment:

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();

    }

}

Save this as HitTestShapeTest.as and set it as the Document Class for a new .fla file to run the code, or try this Also check out the maze tutorial on the adobe website

OTHER TIPS

You can use the logic of maze game walls.

It uses wall.hitTestPoint(character.x, character.y),

Here is an example of maze game.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top