Copy link to clipboard
Copied
I have a sprite named Jim, and Jim has a mouth named Jaw.
Jim has a function I want to call once he closes his mouth.
This function works perfectly when called from Jim's timeline, but when called from the jaw's timeline, it goes wrong.
Suppose the function is named "function()", "function()" doesn't work, nor does "Jim.function".
What do I do? I'm really starting to hate working with classes.
What you describe doesn't seem to involve classes, but in any case, if it's AS3 try this:
MovieClip(parent).function();
from within 'jaw'. If it's HTML5, try:
this.parent.function();
Copy link to clipboard
Copied
What you describe doesn't seem to involve classes, but in any case, if it's AS3 try this:
MovieClip(parent).function();
from within 'jaw'. If it's HTML5, try:
this.parent.function();
Copy link to clipboard
Copied
The addition of "MovieClip(parent)" made everything work exactly as I expected. That said, I have only a vague idea of what "MovieClip(parent)" probably means, and don't know if there is any other "...(parent)" or "MovieClip..." I have to learn.
Could you please refer me to a tutorial that will fill this knowledge gap of mine?
Copy link to clipboard
Copied
Don't know of a tutorial, but I can explain this bit easily enough.
In ActionScript the compiler needs to be convinced that what you're trying to do is legal. The thing that 'jaw' is inside need not be a MovieClip, there are various other display objects that are capable of containing things, and some of those are not able to include code. You know that it's a MovieClip, but for the compiler to be sure that it is you spell it out, by saying MovieClip(parent).function() instead of just parent.function().
In programming that would be called type casting, where you force the compiler to think of the variable as being a particular type.
Copy link to clipboard
Copied
I tried to follow that, but I got lost.
That's why I suggested a tutorial. I'm going to need the "For Dummies" version of that explanation.
I think you're telling me that the compiler should be able to recognise it, but chooses not to, in case I typed it in error. By adding "MovieClip(parent)" I am clarifying that I did intend to type what I typed.
Still, that leaves two questions:
-What sorts of errors it the compiler protecting me from?
-Is there an even more general and generic rule I must learn to avoid all errors of this category in future?
Also, I'm not even fully sure I understand "parent.function()". Under what circumstances is code in a parent of another? Does the metaphor follow all the way through, with grand-parents and siblings etc? If there is this whole family structure, what must I remember to be able to get any function to call any other function regardless of where it is stored?
(I know, this is sacrilegious among object oriented purists to allow for such chaos, but I still want to know how to do it.)
Copy link to clipboard
Copied
Code is never a parent of another. Objects are. Objects can store code in the form of methods (functions). Objects can also contain other objects. Those are its children. A child object's container is its parent.
Copy link to clipboard
Copied
If you go to File/ActionScript Settings... you'll see a checkbox for Errors/Strict Mode. If that box is not checked you will be allowed to do a Test Movie, but when the parent.function() line is reached there will be an error in the Output panel. If you do check that box you will see an error in the Compiler panel. It's generally a good idea to use strict mode, so that you get a detailed error right away.
grandparent.function() would be a cute idea, but the way it's really done is parent.parent.function(). Still you would want to let the compiler know that it's a MovieClip, but you wouldn't have to do that for each level, MovieClip(parent.parent).function() should work.
If you want to tell another object to do something, but you don't want to worry about where it is in the hierarchy (or maybe where it is changes over time), you can use events. For example, suppose your character needs to look frightened at some point, like if you click on his hand you want his eyes, nose, and mouth to all go to a particular frame, it would be a hassle to have to figure out the path to get from the hand to those three other places.
So, you could dispatch an event, and have those other objects listen for that event. In the hand you might have:
addEventListener(MouseEvent.CLICK,scared);
function scared(e:MouseEvent){
stage.dispatchEvent(new Event("bescared"));
}
and in each of the other objects you would have:
stage.addEventListener("bescared",scared);
function scared(e:Event){
gotoAndStop("scared frame");
}
I just typed all that code here, so may have made mistakes. But it should let you know what sorts of tutorials to search for.
By the way, nothing I've said requires object oriented programming techniques, and I have done some quite complex things just with non-OOP timeline AS3. There are some advantages to OOP, but you can figure that out some other time, get used to AS3 first.
Copy link to clipboard
Copied
I know I marked your earlier answer as correct, but now I'm getting a 1009 error. I only see it when I look through the trace statements.
Thanks for your patience with me, by the way.
Copy link to clipboard
Copied
If you turn on that strict mode I mentioned, and then do a test, the compiler panel will give you more information on the problem. You can also double click on the error line, and it should take you to the script that has the problem.
Most likely you have misspelled something. Function names are case sensitive by the way.
Copy link to clipboard
Copied
Strict mode was never off.
This is what I wrote
"
MovieClip(parent).enableLeft();
MovieClip(parent).enableRight();
"
This is code that works exactly as required in the parent
enableLeft()
enableRight()
The only typos I see is in the code that worked, I forgot to end each line with ";" but it still works.
Copy link to clipboard
Copied
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at JawMovieclip/frame44()
Copy link to clipboard
Copied
Would you be willing to post the FLA somewhere, that I can look at it?
Copy link to clipboard
Copied
It's a fan game, so I'm hoping that no members of the fan community are in this forum, or even if they are, they know to keep everything secret until I'm ready to release it for free on Newgrounds.com
Microsoft OneDrive - Access files anywhere. Creat...
​
​To replicate the error:
​-press and hold the left arrow
​-press and hold "z" while holding the left arrow
​-release "z"
​-close the program
​-find the error by scrolling up in the output window
​
​Thanks for your time.
​
​Notes:
​-the behaviour should be symmetrical, but the error only happens when moving left.
Copy link to clipboard
Copied
I looked at the files, you could remove them if you like.
There are a few complications caused by the fact that you're using classes to control movieclips and you also have the timeline removing those movieclips. Now and then there will be an instant where the class code is running, but the timeline has removed the movieclip from the stage. That means it no longer has a parent.
I tried adding some tests to see if 'parent' was not null, but still there were cases when it would go wrong.
The sending events I talked about might be the easiest solution. In places where you are saying either enableLeft() or MovieClip(parent).enableLeft(), you would do:
stage.dispatchEvent(new Event("enableleft"));
and in the jim playable code you would have:
stage.addEventListener("enableleft",enableLeft);
The start of the enableLeft function would change from:
public function enableLeft(): void
to:
public function enableLeft(e:Event): void
Something else to be aware of is that at the start of the class code the item in question is not on the stage. You work around that by listening for when it does get added to the stage. In your case:
public function JimPlayable()
{
gotoAndStop('Turn Right');
addEventListener(Event.ENTER_FRAME, everyFrame);
}
could become:
public function JimPlayable()
{
addEventListener(Event.ADDED_TO_STAGE,added);
}
private function added(e:Event){
removeEventListener(Event.ADDED_TO_STAGE,added);
gotoAndStop('Turn Right');
addEventListener(Event.ENTER_FRAME, everyFrame);
}
That might be safer. There is also something to listen for when the item is removed from the stage. If you don't do that you will get cases where the everyFrame function is still running after the movieclip is no longer there. That's most likely what's leading to most of your problems. Here's the above code modified to take care of the item being removed from the stage:
public function JimPlayable()
{
addEventListener(Event.ADDED_TO_STAGE,added);
}
private function added(e:Event){
removeEventListener(Event.ADDED_TO_STAGE,added);
addEventListener(Event.REMOVED_FROM_STAGE,destroy);
gotoAndStop('Turn Right');
addEventListener(Event.ENTER_FRAME, everyFrame);
}
public function destroy(e:Event){
removeEventListener(Event.ENTER_FRAME, everyFrame);
removeEventListener(Event.REMOVED_FROM_STAGE,destroy);
}
You can see that this all can get a little tricky. Do you know anyone who has done more AS3 than you, who could help you in person while you're figuring all of this out?
Copy link to clipboard
Copied
That was so helpful, and so much effort on your part, I looked up the MVP program to see what you were getting out of it. It seems you are earning points towards a $50 gift voucher. Huh. I think Adobe needs to take better care of you. I may have given up my subscription entirely if you hadn't fixed that for me. (I'm assuming it's fixed. I haven't implemented it yet.)
I'll reply again in an hour or so and let you know how it went.
Copy link to clipboard
Copied
I have received a few of those vouchers! But, so you feel happier for me, I'm also ACP. My CC subscription is covered too.
Copy link to clipboard
Copied
I have been looking over your solutions, and I'm thinking, "why not just leave the error in?" The program otherwise functions as it should (I think) and although your solution will stop the error from appearing, will it give the final project a performance boost?
I know performance isn't everything, and following conventions, avoiding error messages, and having it readable by other programmers is important too. But as things scale up, performance will become more important.
That said, the thing that has really been doing my head in, is why does the error only happen when he's walking to the left? I've gone over my code so many times, and every single element of it is exactly symmetrical.
Copy link to clipboard
Copied
I made progress!
It comes down to:
MovieClip(parent).enableRight();
MovieClip(parent).enableLeft();
vs
MovieClip(parent).enableLeft();
MovieClip(parent).enableRight();
Which ever command goes second crashes. Whichever command goes first works fine.
Given that clue, I think I have a few ideas as to what is causing the problem. If you don't hear back from me this week, it means that I've solved it.
Copy link to clipboard
Copied
If one of those functions causes the timeline to go to a frame where the parent is no longer on the stage, you would get the problem. Thinking about it, although I tried this:
if(parent){
MovieClip(parent).enableRight();
MovieClip(parent).enableLeft();
}
I didn't try this:
if(parent) MovieClip(parent).enableRight();
if(parent) MovieClip(parent).enableLeft();
That might well work around the issue.
Copy link to clipboard
Copied
The bug is actually a lot worse than that, but you're correct, that would fix the error.
The solution is for the jaw's timeline to change a Boolean value in the document class. Could you please tell me the correct syntax for that? I really struggle with knowing how to get things to call each other if they're in different places.
Copy link to clipboard
Copied
Ignore that last one. I figured it out.
I just have to start the command with "Jimulator." because that is the name of the document class.
I thought it would be more complex, because jaw is inside jim, which is inside jimulator, making the relationship grandparent-grandchild, but apparently it doesn't work like that.
Copy link to clipboard
Copied
Also no, I don't know anyone personally who even knows what "actionscript" is.
Copy link to clipboard
Copied
if you need to call function (eg, jawF in class Jim) from outside Jim, you need to use a non-private function in Jim.
eg, in Jim:
public function jawF():void{
}
and in a class that has a reference to a Jim member, eg
var jim:Jim = new Jim();
you can use
jim.jawF();