Jump to content

  • Log In with Google      Sign In   
  • Create Account


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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
26 replies to this topic

#1 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 29 August 2012 - 02:03 PM

Hello guys.

I have been working in this single thing for more than 3 hours and can't get it done.

I want to add a listener to the main character in the game.

I'm using MainCharacter.as file to have al the properties and movements of it.

So far, everything works (appears in the scene, I can even click on it and trace works)

But when I want it to move when I press a button, it doesn't work.

I have an instance of the Main.as file that I'm using to addChild all the things of the game (including the main char, and works great)

Ok well,I tried:

addEventListener(KeyboardEvent.KEY_DOWN,keyDown);
scene.addEventListener(KeyboardEvent.KEY_DOWN,keyDown);
Main._instanceMain.addEventListener(KeyboardEvent.KEY_DOWN,keyDown);

and so much more I can't remember. But it doesn't work.

I even try to do it inside PlayGame.as and didn't work either.

What could it be??!

Thanks guys, ANY ANY suggestions will be much appreciated !!

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


Sponsor:

#2 greenvertex   Members   -  Reputation: 510

Like
2Likes
Like

Posted 29 August 2012 - 02:12 PM

Keyboard events are from the stage. You want to do:

addEventListener(Event.ADDED_TO_STAGE, onStage);
function onStage(e:Event):void {
  removeEventListener(Event.ADDED_TO_STAGE, onStage);
  stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
  addEventListener(Event.REMOVED_FROM_STAGE, offStage);
}

function offStage(e:Event):void {
  removeEventListener(Event.REMOVED_FROM_STAGE, offStage);
  stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}

Edited by greenvertex, 29 August 2012 - 02:14 PM.


#3 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 29 August 2012 - 02:31 PM

Hey greenvertex, it's good to see you around.

Awesome I'm going to try that. Just one thing (and sorry to ask I'm truly tired !!)

The function onStage I add it in the Main.as file? and the offStage in the MainCharacter.as ?

Thanks once again !!

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


#4 greenvertex   Members   -  Reputation: 510

Like
2Likes
Like

Posted 29 August 2012 - 02:41 PM

If you want to move your character, it makes sense to add the whole thing to MainCharacter.as:

When your character is added to the stage, he starts listening for key events. When one is pressed, some property changes (position or whatever else).
When your character gets removed from the stage, make sure to remove all those event listeners that he was listening to. Now he can't move anyway...

#5 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 29 August 2012 - 02:55 PM

Thanks greenvertex for your response.

But crap I can't get it move. It doesn't show any error.

I paste your code and show and error that onKeyDown was not found, so I change it for the name of the function that I want to run and nothing.

Then I add the instance of the Main.as, where everything is getting add, and nothing either.

What can be??

Thanks for your time greenvertex !!

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


#6 greenvertex   Members   -  Reputation: 510

Like
1Likes
Like

Posted 29 August 2012 - 03:46 PM

Can you paste the code in question?

#7 Deft   Members   -  Reputation: 218

Like
1Likes
Like

Posted 29 August 2012 - 03:52 PM

Thanks greenvertex for your response.

But crap I can't get it move. It doesn't show any error.

I paste your code and show and error that onKeyDown was not found, so I change it for the name of the function that I want to run and nothing.

Then I add the instance of the Main.as, where everything is getting add, and nothing either.

What can be??

Thanks for your time greenvertex !!

If you want handle whole keyboard events for control game object, use stage, and not your custom objects.
When you add keyboard event listener to stage, this is applied for all of your objects (this is not trully in lower-level of action script, but you can imaginate it like I said :)).
Just like a simple example:
[source lang="java"]myGameObject.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);[/source]

#8 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 29 August 2012 - 03:59 PM

Sure thing, thanks greenvertex.

I will paste it before adding your code to see what I'm wrong:

MainChar.as
package com.jeteran
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.events.Event;

public class MainChar extends MovieClip
{
  public var charObject:Object; //create the object
  public var char:Char; //call the mc in the lib

//BTW this is a new approach I was working, creating an object of the character:
charObject = new Object();
char = new Char;

charObject._image = char;
charObject._id = 0;
charObject._moveLeft = false;
charObject._moveRight = false;

Main._instaceMain.addChild(charObject._image) // The _instanceMain is an instance I created in the Main.as to make everything work there

addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); //I tried Main._instanceMain. ... and stage, , but the same, doesn't work

function keyPressed(event:KeyboardEvent)
   {
    if (event.keyCode == 39)
    {
	 trace("RIGHT");
    }
   
    else if (event.keyCode == 37)
    {
trace("LEFT");
    }
   }

That's it, thanks so much for your kindly help guys !!!

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


#9 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 29 August 2012 - 04:10 PM

If you want handle whole keyboard events for control game object, use stage, and not your custom objects.

I CAN'T believe it !! It worked !!

My God I have hours on this and finally got it, thanks to you !!!

BTW, can you explain me a little more about this?! I want to learn ;)

Thanks SO SO much Deft, you are the man of the day !!

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


#10 Deft   Members   -  Reputation: 218

Like
1Likes
Like

Posted 29 August 2012 - 04:42 PM


If you want handle whole keyboard events for control game object, use stage, and not your custom objects.

I CAN'T believe it !! It worked !!

My God I have hours on this and finally got it, thanks to you !!!

BTW, can you explain me a little more about this?! I want to learn ;)

Thanks SO SO much Deft, you are the man of the day !!

The thing is keyboard events working only when user focused on it.
For example, you can't input into text area until you'll not selected it by clicking mouse or click "tab-tab-tab" to go into area (this is mean focus). When your pointer blinking in input area, you can enter characters. Yeap? This mean that you was focused on text area. For another object, such as text labels and other (including sprites/movie clips/etc.) focus rules are the same.
So, your keyboard events didn't worked because of your game object wasn't focused. So adding global KB event onto display object is not better choice. Just do KB handling on the stage, that is focused always by default (again, this is not same on low-level, but you understand what I mean)

P.S. But if you want implement such things like a input fields, you need to add KB event only onto object itself.

Edited by Deft, 29 August 2012 - 04:45 PM.


#11 fdn2012   Members   -  Reputation: 126

Like
1Likes
Like

Posted 29 August 2012 - 08:01 PM

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)

..............

#12 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 29 August 2012 - 09:18 PM

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 !!

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


#13 fdn2012   Members   -  Reputation: 126

Like
1Likes
Like

Posted 29 August 2012 - 11:00 PM

Can you paste the code?
Posted Image Sorry. I did not understand all of your post.

#14 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 30 August 2012 - 08:35 AM

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 !!

Edited by JETerán, 30 August 2012 - 08:39 AM.

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


#15 Deft   Members   -  Reputation: 218

Like
1Likes
Like

Posted 30 August 2012 - 09:22 AM

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.

Edited by Deft, 30 August 2012 - 09:23 AM.


#16 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 30 August 2012 - 09:32 AM

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 !!

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


#17 Deft   Members   -  Reputation: 218

Like
1Likes
Like

Posted 30 August 2012 - 10:24 AM

As always, thanks Deft for your reply Posted Image

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 )

Edited by Deft, 30 August 2012 - 10:24 AM.


#18 fdn2012   Members   -  Reputation: 126

Like
1Likes
Like

Posted 30 August 2012 - 11:43 AM

hehe, Sorry for my English. I can't express my meaning properly.Posted Image
If I do it, Like this:
[source lang="java"]var currentMission:Object = mission1;//this variable point at mission1 or mission1 or mission2 or mission3function 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[i] : null; if(currentMission != null) { Main._instanceMain.addChild(currentMission); } mainChar.hero._curRoom = currentMission != null ? "room" + i : ""; }}[/source]

#19 JETeran   Members   -  Reputation: 265

Like
0Likes
Like

Posted 30 August 2012 - 12:39 PM

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 :)

Success with courage.

José Eduardo Terán

Project Manager & Game Programming Professor. DSK International Campus

Indie Game Developer
Google + Account


#20 Deft   Members   -  Reputation: 218

Like
1Likes
Like

Posted 30 August 2012 - 12:44 PM

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS