eventlistener functions doesnot stop workning - actionscript-3

I have made a content where in one frame I have 10 movieclips(5 color pair) equally divided into two columns.I have added three event listener to the stage mousedown, mouseup, mouse move. I have drawn lines from one movieclip to another to match one column movie clip to another column same movie clip.. I added code to timeline but when I go to next frame or previous frame (where there are another acitvities) using next/prev button a warning is showing up :
Cannot access a property or method of a null object reference.
at CL3_Sc_Pat12_SL05_fla::MainTimeline/mMove()
this waring is not showing for mousedown() mouseup().i have used same next and same previous button for 3 frames.and for frame jumping i numbered each frame as frame no 1,2,3.if frameno == 3 goto frame 2 if frameno== 2 goto frame 1 thus it works..frame jumping code is in 1st frame..
Here is my code :
stage.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mMove);
function mDown(event:MouseEvent):void
{
mouseHolding = true;
clickedX = mouseX;
clickedY = mouseY;
myDrawing.graphics.moveTo(mouseX, mouseY);
Line_draw.graphics.moveTo(mouseX, mouseY);
if (pencil.hitTestObject(box1)) //box of 1st column
{
trace("box1 value is: "+chk_val_1);
}
}
function mUp(MouseEvent):void
{
myDrawing.graphics.lineTo(mouseX, mouseY);
mouseHolding = false;
if (pencil.hitTestObject(hit_box1)) ////box of 2nd column
{
trace(boxes have same color);
Line_draw.graphics.lineTo(mouseX, mouseY);
}
}
function mMove(MouseEvent):void
{
if (mouseHolding && mouseY < 510 )
{
clearTemp();
Line_draw.graphics.lineTo(mouseX, mouseY);
}
}
function clearTemp():void
{
Line_draw.graphics.clear();
Line_draw.graphics.lineStyle(6,0x0066CC,1);
Line_draw.graphics.moveTo(clickedX, clickedY);
}
function nxt_click(event:MouseEvent)
{
gotoAndPlay(3);
}
function prev_click(event:MouseEvent)
{
gotoAndPlay(1);
}
My code is working perfect but I want to know why is this warning coming again and again ?

You need to draw arrows (lines) just in your "anim4" frame so outside this frame you have to disable this function and remove all stage listener created for that, so you can do like this :
function nxt_click(event:MouseEvent)
{
if(){
// your other instructions
}
// your other instructions
else if (my_frame == 4)
{
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mDown);
stage.removeEventListener(MouseEvent.MOUSE_UP, mUp);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mMove);
gotoAndPlay("anim5");
}
}
And you should do the same thing when exiting the "anim4" frame by pressing the previous button.
Hope that can help.

Related

Need help fixing player jumping diagonally Flash CS4

I can't figure out why when I try and get my player to jump diagonally by pressing the right and up arrow key it does nothing, I've used trace to see if anything was happening and nothing was when they were used together.
Up won't work by itself or with right but when right is by itself it works.
player is named hero, platforms are named platform, platform2, platform3 etc
platforms are in the platform layer
stop();
var gravity:Number=5; //Very important, allows player to fall
var movex:Number=0; // Moving players X
// Moving player
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHero);
var speed=10;
function moveHero(event:KeyboardEvent) {
if (event.keyCode==Keyboard.LEFT) {
hero.x-=speed;
hero.play();
}
if (event.keyCode==Keyboard.RIGHT) {
hero.x+=speed;
hero.play();
}
}
hero.addEventListener(Event.ENTER_FRAME, testCollision2);
// Allowing player to jump when on platform
function testCollision2(e: Event) {
//Allowing player to jump when on platform continued
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHeroUP);
function moveHeroUP(event:KeyboardEvent) {
if (hero.hitTestObject(platform) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform2) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform4) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
}
if(hero.hitTestObject(platform) && event.keyCode==Keyboard.UP && event.keyCode==Keyboard.RIGHT){
movex = 20;
hero.x = hero.x + movex;
gravity =-50;
hero.y = hero.y + gravity;
}
}
I'm trying to get the player to jump in the code chunk at the very end
Flash CS4
AS3
To start, let's go through how you've set up this code and explain what's happening.
You have this line:
hero.addEventListener(Event.ENTER_FRAME, testCollision2);
Which is saying, every frame tick that hero exists, run the function testCollision2. Frame tick here doesn't relate to timeline frames, it relates to the frame rate of your application. So if that is set to 12, that function will run 12 times every second.
Inside testCollision2, you add another listener:
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHeroUP);
and create an inline function called moveHeroUP. So every frame tick, you create a new function, and attach it to a key down event. So (assuming 12 frames per second) 5 seconds into your application, you'll have 60 keyboard listeners all doing the same thing. This is also a memory leak (as you keep creating a new function every frame), so eventually your program will crash.
To get to the actual question, a keyboard event is tied to one specific key. This means the event's keyCode is only ever one key (the key that triggered the event). So doing something like (event.keyCode==Keyboard.UP && event.keyCode==Keyboard.RIGHT) will always be false because event.keyCode only ever holds one value.
A common approach to your situation, is to have one global key down and key up listener. Then use a dictionary to store which keys are currently down:
//create just one key down listener
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
//create a dictionary to store key presses
var keyboardDown:Dictionary = new Dictionary();
function keyDownHandler(e:KeyboardEvent):void {
keyboardDown[e.keyCode] = true;
}
function keyUpHandler(e:KeyboardEvent):void {
keyboardDown[e.keyCode] = false;
}
What you're doing here, is when a key down event fires, you set the value in the dictionary to true (with the keycode as the dictionary key), then on the key up event you set it to false.
Now, in your ENTER_FRAME handler, you use the dictionary values to check for key combinations:
hero.addEventListener(Event.ENTER_FRAME, moveHero);
function moveHero(event:Event) {
//DO ALL YOUR MOVEMENTS IN ONE ENTER FRAME FUNCTION
if (keyboardDown[Keyboard.LEFT]) {
hero.x-=speed;
hero.play();
}
if (keyboardDown[Keyboard.RIGHT]) {
hero.x+=speed;
hero.play();
}
if (hero.hitTestObject(platform) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform2) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform4) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
}
if(hero.hitTestObject(platform) && keyboardDown[Keyboard.UP] && keyboardDown[Keyboard.RIGHT]){
movex = 20;
hero.x = hero.x + movex;
gravity =-50;
hero.y = hero.y + gravity;
}
}

change keyboard event to mouse event as3

I am a new new person who learn action script 3.
i have problem when i convert keyboard event to mouse event when i moving a walking character.
when use the keyboard event i have no problem. this is my code
import flash.ui.Keyboard;
var speed:Number=2;
stage.addEventListener(KeyboardEvent.KEY_DOWN, stikman);
function stikman(e:KeyboardEvent)
{
if (e.keyCode==Keyboard.LEFT)
{
stik.x-=speed;
stik.scaleX=-1;
stik.stik2.play();
}
else if (e.keyCode==Keyboard.RIGHT)
{
stik.x+=speed;
stik.scaleX=1;
stik.stik2.play();
}
}
and then i try to change keyboard event to mouse event when moving character with button it should press click, click and click. i want to hold the click when moving the character and when mouse up the character stop. but i still don't know how. this my code when i try to change to mouse event
var speed:Number=2;
mundur.addEventListener(MouseEvent.MOUSE_DOWN, stikman);
function stikman(e:MouseEvent)
{
stik.x-=speed;
stik.scaleX=-1;
stik.stik2.play();
}
maju.addEventListener(MouseEvent.CLICK, stikman2);
function stikman2(e:MouseEvent)
{
stik.x+=speed;
stik.scaleX=1;
stik.stik2.play();
}
Because keyboard produces KeyboardEvent.KEY_DOWN event repeatedly as long as key is pressed, while MouseEvent.CLICK as well as MouseEvent.MOUSE_DOWN are dispatched only once per user action.
With mouse you need to change the logic.
// Subscribe both buttons.
ButtonRight.addEventListener(MouseEvent.MOUSE_DOWN, onButton);
ButtonLeft.addEventListener(MouseEvent.MOUSE_DOWN, onButton);
var currentSpeed:Number = 0;
var isPlaying:Boolean = false;
function onButton(e:MouseEvent):void
{
// Set up the directions and start the animation.
switch (e.currentTarget)
{
case ButtonLeft:
currentSpeed = -speed;
stik.stik2.play();
stik.scaleX = -1;
break;
case ButtonRight:
currentSpeed = speed;
stik.stik2.play();
stik.scaleX = 1;
break;
}
isPlaying = true;
// Call repeatedly to move character.
addEventListener(Event.ENTER_FRAME, onFrame);
// Hook the MOUSE_UP even even if it is outside the button or even stage.
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
function onFrame(e:Even):void
{
// Move character by the designated offset each frame.
stik.x += currentSpeed;
if (!isPlaying)
{
// Stop at last frame.
// if (stik.stik2.currentFrame == stik.stik2.totalFrames)
// Stop at frame 1.
if (stik.stik2.currentFrame == 1)
{
// Stop the animation.
stik.stik2.stop();
// Stop moving.
removeEventListener(Event.ENTER_FRAME, onFrame);
}
}
}
function onUp(e:MouseEvent):void
{
// Indicate to stop when the animation ends.
isPlaying = false;
// Unhook the MOUSE_UP event.
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
}

Flash CS3 AS3 Movieclips carrying over to other frames

OK so I am having a weird issue. I have some movieclips on screen, 4 of them, each with the following code (with different instance names of course):
stage.addEventListener(MouseEvent.MOUSE_DOWN,globalMouseDown,false,0,true); //add a global mouse listener
function globalMouseDown(e:Event):void {
//find out if the target is a descendant of this, if not, then something else was clicked.
var parent:DisplayObject = e.target as DisplayObject;
while(parent && parent != stage){
if(parent == this) return;
parent = parent.parent;
}
//something else was clicked that wasn't this, so go to the up state
gotoAndStop(1);
}
stop();
addEventListener(MouseEvent.MOUSE_DOWN, onHs1Press);
addEventListener(MouseEvent.MOUSE_OVER, onHs1Over);
addEventListener(MouseEvent.MOUSE_OUT, onHs1Out);
function onHs1Press(event:MouseEvent):void
{
// toggle between frame 1 and 3 on button press
gotoAndStop(this.currentFrame == 3 ? 1 : 3);
parent.addChild(this)
}
function onHs1Over(event:MouseEvent):void
{
if (currentFrame != 3)
{
gotoAndStop(2);
}
}
function onHs1Out(event:MouseEvent):void
{
// only switch back to UP state if the button is "pressed"
if (currentFrame != 3)
{
gotoAndStop(1);
}
}
Basically it lets you hover your mouse and the movieclip changes and then when you click on it a little pop up window appears until you click the movieclip again to close it.
There is also a button on screen that allows you to move forward or backwards to other frames with this code:
Next.addEventListener(MouseEvent.CLICK,Nclick);
function Nclick(event:MouseEvent):void {
nextFrame();
}
Back.addEventListener(MouseEvent.CLICK,Bclick);
function Bclick(event:MouseEvent):void {
prevFrame();
}
The button code is on the main timeline and the movieclip code is on the movieclip's timeline.
For some reason if you have the movieclip in the DOWN state (with the popup window open) and you click the button to go to the next frame, the movieclip follows onto the next and any other frames instead of just going away.
I have this same code present on other frames and none of the other ones behave this way, it's really weird.
You can even click it still when its on the other frames and bring up the popup window where the movieclip and code aren't even present.
What's going on with it?
I tried testing this, and could reproduce your issue. If you add a movieclip to the stage in FlashPro, after changing it's index or parentage, it will from that point on be treated like an object created from code and the timeline will ignore it and even create another instance of it on a frame where it is created.
You'll have to manually remove the buttons from the display list.
function Nclick(event:MouseEvent):void {
nextFrame();
removeBtns();
}
function Bclick(event:MouseEvent):void {
prevFrame();
removeBtns();
}
function removeBtns():void {
if(currentFrame != 2){ //whatever the frame of your buttons is
if(btn1 && btn1.parent) removeChild(btn1); //btn1 being whatever your button instnace name is
if(btn2 && btn2.parent) removeChild(btn2); //repeat for all buttons
}
}
OR If you'd prefer to have encapsulated code, instead of the above, put this on your button class/timeline:
var myFrame:int = MovieClip(parent).currentFrame;
this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
this.addEventListener(Event.REMOVED_FROM_STAGE,removedHandler);
function enterFrameHandler(e:Event):void {
if(MovieClip(parent).currentFrame != myFrame){
parent.removeChild(this);
}
}
function removedHandler(e:Event):void {
this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
this.removeEventListener(Event.REMOVED_FROM_STAGE, removedHandler);
}

AS3 How to make only 1 movieclip clickable at a time when there are multiple movieclips

Ok, so I have a page with 5 movieclips/buttons on it. When you mouse over each one they light up (OVER state) and when you click on them they expand (DOWN state). The problem is if you have multiple movieclips expanded (in the DOWN state) they overlap and it looks awful. I want to code them so only 1 can be expanded at a time. How can I do this? I imagine I need an IF statement on each button like "If any other movieclips are in the DOWN state, then disable DOWN for this movieclip, if no other buttons are in DOWN state then enable the DOWN state for this movieclip" or something like that but I don't know how to write it. Please help. Here is the code for one of the movieclips:
Step0btn.stop();
Step0btn.addEventListener(MouseEvent.MOUSE_DOWN, onStep0Press);
Step0btn.addEventListener(MouseEvent.MOUSE_OVER, onStep0Over);
Step0btn.addEventListener(MouseEvent.MOUSE_OUT, onStep0Out);
function onStep0Press(event:MouseEvent):void
{
// toggle between frame 1 and 3 on button press
Step0btn.gotoAndStop(Step0btn.currentFrame == 3 ? 1 : 3);
}
function onStep0Over(event:MouseEvent):void
{
if (Step0btn.currentFrame != 3)
{
Step0btn.gotoAndStop(2);
}
}
function onStep0Out(event:MouseEvent):void
{
// only switch back to UP state if the button is "pressed"
if (Step0btn.currentFrame != 3)
{
Step0btn.gotoAndStop(1);
}
}
Ok we have solved the issue with the overlapping movieclips, however on the movieclip's DOWN state there is another movie clip that has this code:
Step0img.stop();
Step0img.addEventListener(MouseEvent.MOUSE_DOWN, onStep0imgPress, false, 999);
function onStep0imgPress(event:MouseEvent):void
{
Step0img.gotoAndStop(2);
event.stopImmediatePropagation();
}
This allowed me to click on the nested movieclip without triggering the MOUSE DOWN even and closing the expanded movieclip. I think disabling the MOUSECHILDREN may have also disabled this functionality.
Here is one way this can be done: Replace the code above with this code on your button timelines (or better yet make a class file and have your buttons each have it as their base class like my answer to this question - then you only need to have the one code file that all your buttons share)
stage.addEventListener(MouseEvent.MOUSE_DOWN,globalMouseDown,false,0,true); //add a global mouse listener
function globalMouseDown(e:Event):void {
//find out if the target is a descendant of this, if not, then something else was clicked.
var tmpParent:DisplayObject = e.target as DisplayObject;
while(tmpParent && tmpParent != stage){
if(tmpParent == this) return;
tmpParent = tmpParent.parent;
}
//something else was clicked that wasn't this, so go to the up state
gotoAndStop(1);
}
stop();
addEventListener(MouseEvent.MOUSE_DOWN, onPress);
addEventListener(MouseEvent.MOUSE_OVER, onOver);
addEventListener(MouseEvent.MOUSE_OUT, onOut);
function onPress(event:MouseEvent):void
{
// toggle between frame 1 and 3 on button press
gotoAndStop(Step0btn.currentFrame == 3 ? 1 : 3);
}
function onOver(event:MouseEvent):void
{
if (currentFrame != 3)
{
gotoAndStop(2);
}
}
function onOut(event:MouseEvent):void
{
// only switch back to UP state if the button is "pressed"
if (currentFrame != 3)
{
gotoAndStop(1);
}
}

EventListener AS3 problems reset problems

Hey guys I am having a problem with Event Listeners in my AS3 file. I am trying to make this object that lasts for 83 frames to appear in a different location every time the parent (83 frame) movie clip resets. The problem is I have a function that places the object at a random y value which works great once. When it resets the ojbect appears on the same Y point. This is because I removeEventListener the function otherwise the object goes shooting off the screen when it loads. How do I call that event listener again without causing a loop that will shoot the object off screen?
Here is my code:
import flash.events.Event;
stop();
addEventListener(Event.ENTER_FRAME, SeaWeedPostion);
//stage.addEventListener(Event.ADDED_TO_STAGE, SeaWeedPostion);
function SeaWeedPostion(e:Event):void{
// if(newSeaWeed == 1) {
var randUint:uint = uint(Math.random() *500 + 50);
this.seaweedSet.y += randUint;
trace(randUint);
stopPos();
//}else{
//nothing
// }
}
function stopPos():void{
removeEventListener(Event.ENTER_FRAME, SeaWeedPostion);
//var newSeaWeed = 0;
}
function resetSeaWeed():void{
addEventListener(Event.ENTER_FRAME, SeaWeedPostion);
}
I have some // code in there from trying different things.
Anyone have any suggestions?
Thanks!
ENTER_FRAME event is triggered every frame, so rather than changing position on each frame maybe it's better to create a counter, count frames and if it reaches 82 change position of SeaWeed.
var counter:uint = 0;
Now add ENTER_FRAME listener
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function SeaWeedPostion(e:Event):void {
counter++;
//Are we there yet?
if(counter < 83) {
//Nope, carry on
}
else {
//Yey!
changePosition();
counter = 0;
}
}
//Reset SeaWeed position when called
function changePosition() {
var randUint:uint = uint(Math.random() *500 + 50);
this.seaweedSet.y += randUint;
trace(randUint);
}