Reputation: 186
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
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