AS3.0 Moving a character (listener) doesn't work

Started by
25 comments, last by jeteran 11 years, 7 months ago
Hi. try this;
.......
Main._instaceMain.addChild(charObject._image) // The _instanceMain is an instance I created in the Main.as to make everything work there
Main._instaceMain.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); //I tried Main._instanceMain. ... and stage, , but the same, doesn't work

Main._instaceMain.addEventListener(MouseEvent.MOUSE_DOWN, function(e:Event):void
{
stage.focus = Main._instaceMain;
});

function keyPressed(event:KeyboardEvent)

..............
Advertisement
Thanks so much guys for your help.

Thanks fdn2012, sincerely I didn't try your code now that Deft's code was effective. But I can see that has the same logic.

I'm now working on making that character move inside the map. This is what I have:

I have 3 different MCs, one for each level. Inside Missions.as I have an array that captures each MCs.

I have a main character that is created inside MainCharacter.as.

I have a file called GameStart.as that runs both. I managed to put the character inside the scene, as well the levels.

Now what I want to do is, when the character hits an invisible MC inside the level, addChild the second MC of the array.

So far so good. But when I want to touch the next invisible MC inside the second level, still behaves like if it were from the first level. I tried to removeChild the first level but I sends me an error that the character can't hitTestObject a null object :S What could this be?

In my desperation, I created another MC, this one has 3 frames, one of each level and they all share 2 invisible MCs, one to the left of the scene and one to the right.

In this way, instead of creating another child, I just .gotoAndStop(#) the MC and works perfectly, but, as before, when I want to go to the 3rd room (gotoAndStop(3)) it doesn't work. I don't know what's happening with that number :S BUT I tried play() and works great.

But now coming back so the character touches the left invisible MC, I'm creating an if statement that if the character touches the leftLimit MC and his actualPosition is room3, trace("something"); but doesnt work. I changed the property ._actualLevel of the character when it is in the second level, but actualy is not happening.

I wish i make myself clear. I'm deeply tired guys I can't think clearly anymore. Please ANY ANY suggestion will work A LOT !!

Thanks once again !!
Can you paste the code?
rolleyes.gif Sorry. I did not understand all of your post.
Hey fdn2012, thanks for your reply.

I feel good today, let's keep on the good work.

Ok I'm going to paste the code and the files I'm using to create the game.

For the missions, I will paste only the first mission's code:

Missions.as

import all the flash. i will use

public class Missions extends MovieClip {

public var mission1:Array; //BTW I tried to use it as an object but didn't work
public var mission1room1:Mission1room1; //This is the instance of the MC of the first room
public var mission1room2:Mission1room2; //The same but second room
public var mission1room3:Mission1room3; //the same but third room

public function Missions() {

mission1 = new Array();
mission1room1 = new Mission1room1;
mission1room2 = new Mission1room2;
mission1room3 = new Mission1room3;

}

//Ok here is the code for that first mission and I just addChild to the scene using an instance of the Main.as file
public function mission1() {

mission1[0] = mission1room1;
mission1[1] = mission1room2;
mission1[2] = mission1room3;

Main._instanceMain.addChild(mission1[0]); // I add the first room to the Main scene.
}
}
}


MainChar.as

the same, I import all the flash.* i will need

public class MainChar extends MovieClip {

public var hero:Object; //The hero is an object that has many properties
public var heroImage:HeroImage; // the instance of the MC in the lib

public function MainChar() {

hero = new Object();
heroImage = new HeroImage();

//Ok here I create some properties, like:

hero._image = heroImage;
hero._vel = 10;
hero._moveRight = false;
hero._moveLeft = false;
hero._curRoom = "room1" // I create this to have a track of which room is the hero
}

public function Movements() {

Main._instanceMain.addChild(hero._image); //I create hero in the scene

hero._image.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyIsDown); //This works GREAT thanks to Deft !!!!
hero._image.stage.addEventListener(KeyboardEvent.KEY_UP, keyIsUp);
hero.addEventListener(Event.ENTER_FRAME, moveMyHero);

function keyIsDown(event:KeyboardEvent)
{
if (event.keyCode == 39)
{
hero._moveRight = true;
}

else if (event.keyCode == 37)
{
hero._moveLeft= true;
}
}
//Ok that was just a function that will trigger when the player hits left and right arrows. The very same for the keyIsUp function.
//Then I create the function for moveMyHero based on the info of both keyIsDown and keyIsUp functions.


So far so good. Now comes the tricky part:

StartGame.as


public class StartGame extends MovieClip {

public var missions:Missions; //I import the file Missions.as
public var mainChar:MainChar; //I import the file MainChar.as

public function StartGame() {

missions = new Missions();

//Here I create and use some scenes before the game. After a while, theres a button that says start game, and then... :

mainChar = new MainChar(); //Load the .as in the scene;
mainChar.Movements(); //I run Movements function;

//Ok now, this is where things got messed. This is what I did to find a way to handle both the hero and the first mission:

addEventListener(Event.ENTER_FRAME, detectInitEnd); //This function is to detect when the hero is far left or far right the rooms

function detectInitEnd(event:Event) {

if (mainChar.hero._image.hitTestObject(mission1[0].leftLimit1)) //This is: if the instance of the char hitTest the first room's left limit (left limit 1 because each room has it's own limits, so the first room has leftLimit1 and rightLimit2, the second room leftLimit3 and rightLimit4 and so on), then:
{ trace("left touched"); } //This works.

else if (mainChar.hero._image.hitTestObject(mission1[0].rightLimit2)) //This starts to get confused... :S
{
mainChar.hero._image.x = 50 //restart hero's position , good
Main._instanceMain.removeChild(mission1[0]); //remove current level
Main._instanceMain.addChild(mission1[1]); //add next level
mainChar.hero._curRoom = "room2"; //This didn't work
}

else if (mainChar.hero._image.hitTestObject(mission1[1].rightLimit4)) //Twice confused :S :S
{
mainChar.hero._image.x = 50 //restart hero's position , good
Main._instanceMain.removeChild(mission1[1]); //remove current level
Main._instanceMain.addChild(mission1[2]); //add next level
mainChar.hero._curRoom = "room3";
}


By this far, errors start to pop out, some say that I can't removeChild something is null, the third room never appeared, and so on :s

If you think there is a better way to do this, I will do it.

Please guys help me on this one, we are sooo close to it's conclusion, I just need this final thing.

ANY suggestions it's more than welcome !!

Happy day !!
If you're deleting an object from game scene, first you should remove all event listeners, which can be connected to this object. Just like:
[source lang="java"]Main._instanceMain.removeEventListener(/* There is your collision event definition, i.e. detectInitEnd */);
Main._instanceMain.removeChild(mission[1]);[/source]
The thing is that flash do not removes event listeners automatically, developer should keep it in mind :)
And you should compare your hit test object and hittable object for null-instance.
As always, thanks Deft for your reply :D

Ok I saved that tip, I will always delete event listeners after use, thanks !!

About this code, what I have is just an event listener that's a ENTER_FRAME, if I wanted to remove it, will be a mess.

So, to make it more clearly, I think will be better to have many event listeners, one for each collision with the left and right invisible walls; am I right??

How can I add an event listener that knows f.i. leftLimits is touched by hero??

Thanks SO much once again !!

As always, thanks Deft for your reply biggrin.png

Ok I saved that tip, I will always delete event listeners after use, thanks !!

About this code, what I have is just an event listener that's a ENTER_FRAME, if I wanted to remove it, will be a mess.

So, to make it more clearly, I think will be better to have many event listeners, one for each collision with the left and right invisible walls; am I right??

How can I add an event listener that knows f.i. leftLimits is touched by hero??

Thanks SO much once again !!

I've not recommend to add one event listener per each collision object, especially, if you call them for each call - it is overhead in performance, and be sure - it will be performance issue.
The problem is that you want to test object collisions after you removed this object from stage. You cannot test collisions if some object is out of stage.
If you had caught collision and do stage clean up, you may assume that collision tests should be stopped before doing this work. And moreover you need to clean up all events and objects, because in other cases you will get performance problems after loading few levels.

I hope, I understood what do you want )
hehe, Sorry for my English. I can't express my meaning properly.rolleyes.gif
If I do it, Like this:
[source lang="java"]var currentMission:Object = mission1;//this variable point at mission1 or mission1 or mission2 or mission3
function detectInitEnd(e:Event)
{
if(currentMission == null)
{
removeEventListener(Event.ENTER_FRAME, detectInitEnd)
return;
}
if(mainChar.hero._image.hitTestObject(currentMission.leftLimit1))
{
trace("left touched:" + currentMission);
}
else if(mainChar.hero._image.hitTestObject(currentMission.rightLimit2))
{
mainChar.hero._image.x = 50 //restart hero's position , good
if(Main._instanceMain.contains(currentMission))
{
Main._instanceMain.removeChild(currentMission); //remove current level
}
var i:int = mission1.indexOf(currentMission);
i ++;
currentMission = i < mission1.length ? mission1 : null;
if(currentMission != null)
{
Main._instanceMain.addChild(currentMission);
}
mainChar.hero._curRoom = currentMission != null ? "room" + i : "";
}
}[/source]
Thanks Deft for your message.

I've not recommend to add one event listener per each collision object.

Actually that makes a lot of sense. It will be very hard to handle all the event listeners !!

The problem is that you want to test object collisions after you removed this object from stage.

That's true, but what about if I use just 2 objects to test collisions? That's something I was trying, having just 1 MC with 3 frames (each frame has each room) and have 2 objects to test left and right collision but not for each room, but globaly? Crap I think this is more messed up right? :S

Well the thing what I want (I think I should had start here) is have a mission where a char can move freely inside it. That mission has 3 rooms, at both ends has doors. When the player in the first room reaches the right door, player goes to next room; ; and so on.

Of course, the left door of the first room and the right door of the third room won't work. ;)

Thanks so much Deft !!


hehe, Sorry for my English. I can't express my meaning properly.
If I do it, Like this:

Don't worry fdn2012 !!! And thanks so much for your code, I'm gonna try it out ;)

Let's keep up the good work and ANY more suggestions will be more than awesome :)
I think, you should remember in what room your player right now. After that you can use three containers: each container for 1 room.
These containers should contain list of objects for collision testing from each room. And I think that's will be goal: after that you can successfully remove collision objects from first room, when your player inside second or third room.

This topic is closed to new replies.

Advertisement