Kia Azad
Kia Azad

Reputation: 186

HitTest with movieClips on the stage from within a class

I followed a simple tutorial trying to make a simple top-down game and I have this class so far but I can't figure out how to do a hit test with a movie clip on the stage.

package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import KeyObject;

public class Player extends MovieClip
{
    public var stageRef:Stage;
    public var key:KeyObject;

    public var leftPressed:Boolean = false;
    public var rightPressed:Boolean = false;
    public var upPressed:Boolean = false;
    public var downPressed:Boolean = false;
    public var lastMove:String;

    public var speed:Number = 5;

    public function Player(stageRef:Stage, X:int, Y:int):void
    {
        this.stageRef = stageRef;
        this.x = X;
        this.y = Y;

        key = new KeyObject(stageRef);

        addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
    }

    public function loop(e:Event):void
    {
        checkKeypresses();

        if(leftPressed){
            x -= speed;
            if(this.currentFrame < 7 || this.currentFrame > 9){
                this.gotoAndPlay("left");
                lastMove="left";
                checkKeypresses();
            }
        } else if(rightPressed){
            x += speed;
            if(this.currentFrame < 12 || this.currentFrame > 14){
                this.gotoAndPlay("right");
                lastMove="right";
                checkKeypresses();
            }
        }
        if(upPressed){
            y -= speed;
            if(this.currentFrame < 17 || this.currentFrame > 19){
                this.gotoAndPlay("up");
                lastMove="up";
                checkKeypresses();
            }
        } else if(downPressed){
            y += speed;
            if(this.currentFrame < 2 || this.currentFrame > 4){
                this.gotoAndPlay("down");
                lastMove="down";
                checkKeypresses();
            }
        }
    }

    public function detectPlayer(){

    //HOW  VVVVVVVVVVV ?
        if(lvl.wall_mc.hitTestPoint(this.x,this.y,true)){ 
            if( lastMove == "right"){
                this.x -= speed;
            }
            if( lastMove == "left"){
                this.x += speed;
            }
            if( lastMove == "up"){
                this.y += speed;
            }
            if( lastMove == "down"){
                this.y -= speed;
            }
        }
    }

    public function checkKeypresses():void
    {
        if(key.isDown(37) || key.isDown(65)){ // left arrow or A
            leftPressed = true;
        } else {
            leftPressed = false;
        }

        if(key.isDown(38) || key.isDown(87)){ //up arrow or W
            upPressed = true;
        } else {
            upPressed = false;
        }

        if(key.isDown(39) || key.isDown(68)){ //right arrow or D
            rightPressed = true;
        } else {
            rightPressed = false;
        }

        if(key.isDown(40) || key.isDown(83)){ //down arrow or S
            downPressed = true;
        } else {
            downPressed = false;
        }
    }
}
}

in the line "if(lvl.wall_mc.hitTestPoint(this.x,this.y,true))" I got my problem. please point me in the right direction.

Upvotes: 0

Views: 608

Answers (1)

Marcela
Marcela

Reputation: 3728

Where is lvl defined? If it is a MovieClip on the stage, then you need to understand that your instance of Player is most likely a sibling of lvl, this means that you need to "go up a level" in order to access it.

Although this is bad design, it should work:

if ( MovieClip( stage.getChildByName("lvl") ).wall_mc.hitTestPoint(this.x,this.y,true) )

What this is doing is it's finding the child named "lvl" on stage, casting it as a MovieClip, then accessing the wall_mc child.

If you would like to improve upon this design to make it less tightly-coupled, you should move this logic up a level into either your Document Class or some other class that has access to both Player and lvl.


UPDATE:

After looking at your full code, there are a few ways to fix your issue.

First, you have Main.as as your Document Class, however in the constructor, you're adding the Player instance to the stage instead of parenting it under Main. This causes Player to be a sibling of your Main document class rather than a child.

One way to fix this would be to add Player to main, then change your detectPlayer method to check against Player's parent:

if ( MovieClip( parent.getChildByName("lvl") ).wall_mc.hitTestPoint(this.x,this.y,true) )

Second, it doesn't appear as though you were ever actually calling the method (detectPlayer) that checks for collision with the walls. To remedy this, you can place a call to detectPlayer at the end of your Player.loop method.

As mentioned before, this is not best practice. Additionally, I noticed that you're passing stage to your Player class and later passing it to a KeyObject, so re-parenting the Player in this way may break some of your intended gameplay.

If you are interested in refactoring for loose coupling, I would suggest modifying your Player.detectPlayer method to accept a DisplayObject as an argument and call that from and ENTER_FRAME listener within your Main class:

package
{
    import flash.display.Stage;
    import flash.display.MovieClip;
    import flash.events.Event;

    public class Main extends MovieClip
    {
        public var player:Player;

        public function Main():void
        {
            player = new Player(stage, 320, 240);
            stage.addChild(player);

            addEventListener(Event.EXIT_FRAME, loop);
        }

        private function loop($event:Event):void 
        {
            player.detectPlayer(lvl.wall_mc);
        }
    }
}

This would require the following change in Player:

public function detectPlayer($testObject:DisplayObject)
{
    if ( $testObject.hitTestPoint(this.x, this.y, true) )
    { 
        if( lastMove == "right"){
            this.x -= speed;
        }
        if( lastMove == "left"){
            this.x += speed;
        }
        if( lastMove == "up"){
            this.y += speed;
        }
        if( lastMove == "down"){
            this.y -= speed;
        }
    }
}

Upvotes: 1

Related Questions