Click to See Complete Forum and Search --> : [AS3] Referencing the stage
mr_malee
07-17-2006, 09:24 PM
i just can't figure out for the life of me how to reference the stage or Stage to a class which does not extend the stage. If that makes sense.
I can access the stage from the document class because that is extending the Stage Sprite so it has access to it. I've tried importing all of the display classes like so:
import flash.display.*
and tried to reference like so:
var st:Stage = new Stage()
var st = stage
all i'm trying to do is add a mouse listener to the stage from a movieclip class which controls a function within that class. I can't add it to the movieclip itself because the mouse has to be over the movieclip.
I'll have a better look at the reference but its just so confusing.
Thanks
Fall_X
07-17-2006, 09:27 PM
This is not a clean way to do it, but you could try :
var sprite:Sprite=new Sprite();
var st=sprite.stage;
delete sprite;
Edit : or shorter:
var st:Stage=new Sprite().stage;
Not tested though.
mr_malee
07-17-2006, 09:36 PM
ok i think i found the mistake.
If a display object is not added to the display list, its stage property is set to null.
i was trying to add the listener from the construct function. Since i was creating the instance from another class and then adding it to that class after its constructed, it was not getting the stage. So all i had to do was create an init() function
i am correct in saying this right?
:)
EDIT - didn't see your post Fall, i'll try it out :)
Fall_X
07-17-2006, 09:58 PM
If your class extends displayobject (or sprite etc) you should be able to access it once it gets added to the display list. So my suggestion probably won't work because that sprite isn't added to the displaylist. You can try though.
A better solution would be to pass a reference to stage to the class in it's constructor.
Something like : var myClass:MyClass=newMyClass(this.stage);
and in your class:
class MyClass {
private var stage:Stage;
public function MyClass(stage:Stage) {
this.stage=stage;
}
}
(again, untested code)
jason merchant
07-17-2006, 10:21 PM
Maybe I misunderstood, but if you want to add a listener to the stage from within a movieclip class why can't you do this:
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class mymovie extends MovieClip {
public function mymovie() {
stage.addEventListener(MouseEvent.CLICK, mouseClick);
}
public function mouseClick(event:MouseEvent):void {
trace("Mouse Clicked.");
}
}
}
Edit:
Sorry missed a post. Yes, stage is a property of a DisplayObject and can not be accessed globally.
mr_malee
07-17-2006, 11:36 PM
got another reference question, i'm still very new to OOP.
I'm trying to figure out the best way (OOP Style) to control and create particles, what i think i need to do is create a base class "Particle" and have other particles extend off this class "Laser", "Bullet", "Cannon" etc.
having a bit of trouble trying to create this little setup, i'm trying to create a particle based on a String i pass to the "Particle" base class which then creates the appropriate instance. Like so:
//called within "Player" Class
var newParticle:Particle = new Particle("Laser")
i then tried using FallX's method of getting class instance names from a String. However i just keep getting reference problems, i've tried passing the string as the full file path but it doesn't work.
The problem i think is that i haven't imported the sub classes of the "Particle" class, so it doesn't know what to do when an instance name is passed. I can import the folder of all the sub class particles to the "Particle" class but then my subclasses return errors because they are extending the "Particle" class.
file system setup:
game - "Main", "Particle", "Player"
- particles - "Laser", "Bullet", "Cannon"
so, should i be extending the "Particle" class or simply extend a "DisplayObject" class for "Laser" "Bullet" and "Cannon". Or should i just get rid of my "Particle" class and call particles directly?
I hope someone has the answer
thanks guys
EDIT - not even sure if i really need the "Particle" class, its only point would be to add something to every particle which extends from it, if every particle has a different method of control what use is a Particle base class?
just ranting :)
iopred
07-18-2006, 12:32 AM
If you want to do it properly, you have Particle as a class, then Laser/Bullet/Cannon, are children of Particle class.
so you can get away with things like this:
var newParticle:Particle = new Laser(x,y);
and have a nice collection of particles inside your ParticleSystem which it iterates through.
mr_malee
07-18-2006, 12:57 AM
thanks Iopred, i understand what i was doing wrong now, cheers :)
just one last question.
Is it really really really worth caring about EnterFrames anymore, i would love to avoid using arrays and for in loops to control all my objects, and just give em event Listeners, i'm just wondering because its hard to keep track of instances and i've noticed that even if i set an instance to have a specific name i can't simply say:
myInstance1.control()
myInstance2.control()
i've been usinga a loop and: getChildAt(i) to control objects, but when an object doesn't have a control function and will never need a control fucntion i get an error because its trying to access an undefined property. And if i use an array or array's, i have to keep track of id's and constatly send these id's to objects so that when they need removing they can splice themselves correctly from the Array.
:(
i'm gonna go ahead and give all objects their own events, and see how the results vary
iopred
07-18-2006, 01:03 AM
Depends how you wan't to code.
If you're going to be calling multiple events every frame from a master enterFrame, there is most definately going to be slowdown.
But if you want to be say, adding enemies on a timer, then yes, you should be using events already =D
Eventing is slow in flash, which is why people use arrays, that way you only have the overhead of one event (the enterFrame)
Use the right tool for the right situation, for example. You could fire events for when an enemy should die, but I wouldn't fire events for the enemies enterFrame (obviously).
mr_malee
07-18-2006, 01:34 AM
yeah, its just frustrating trying to figure out how to access instance names that were created dynamically.
mr_malee
07-18-2006, 05:29 AM
this thread should be changed to "referencing problems"
I'm having trouble understanding static and public static vars. I understand public and private but what is static and why do i need to make instances static so that others can access them, shouldn't public do?
i'm going to add the source to what i've been trying to work on, would love if people could tell me better ways to code (don't have to write code) and ask why i did certain things, because i'm not really sure myself :confused:
also i would really love to extend my ParticleSystem and EnemySystem with my particles and enemys, but it gets very confusing with controlling those instances , maybe i should keep my ParticleSystem and EnemySystem classes but make a generic "Particle" and "Enemy" which should add itself to the right system, and then that system iterates over its children (easier said than done though)
hopefully one of you will help your old mate out ;)
iopred
07-18-2006, 07:10 AM
static means that every instance of the class share the SAME variable.
For instance if you had a static variable called 'instances' and incremented it in the constructor, then every single instance would have exactly the same variable, even when you increment the new one, the old ones have theirs updated etc.
To static a function means that the function is just that, static, it has no need for dynamic memory, so the only variables it can touch are static ones. Static functions let you make tasty utility classes that you don't need to make an instance of
class ThirtyTwo{
public static function getThirtyTwo():int{
return 32;
}
}
then you can go all crazy and do:
var i:int = ThirtyTwo.getThirtyTwo();
As for your particle/enemy system, you nailed it.
You have a ParticleSystem class, which deals ONLY in Particles, to that class, all it knows how to do is iterate through a list of Particles, and call a function on them (and add/remove them from itself of course). Then you have a Particle class, which really only needs the function which will be called. Then you have children of Particle which implement more advanced functions.
Oh and quick one after glancing at the code, don't use uint, it's slow as hell.
mr_malee
07-18-2006, 07:22 AM
thanks Iopred, yet again you have helped me out :)
i thought that uint was the fastest, is int the fastest or Number? :(
so i should make the player, enemies and partiles static, so that anything that gets updated in those instances can be referenced from something else?
iopred
07-18-2006, 07:36 AM
Generally not much is ever needed to be static, you may have confused what I was saying. To reference an instance, you just use it's name, I'm assuming the problem you're having is because you cant do stage["thingname"]. So use an array to hold references to the instance (array[0] = new Particle()) then you can use array[0].control(), if that is rejected (haven't tried) check the new "for each" operator, and you should be able to iterate through the array fairly easily.
int is faster than Number when you don't give it decimals to round.
Fall_X
07-18-2006, 07:53 AM
An example of something static (in AS2, it's not in AS3), is Key.isDown - you don't have to make an instance of the Key class before accessing isDown. It's there in the class, unlike normal methods.
An example of a static variable would be Key.SPACE or something. It's a static class-variable, which doesn't need an instance.
Hope this makes sense.
mr_malee
07-18-2006, 07:57 AM
i was trying to stay away from arrays, I take it the array would sit in the "Shooter" class and anything that needs control would be added to the array. How then does an instance in that array access another instance in the same array.
So technically i should be able to access the player instance created in "Shooter" class like so:
var player = Scroller.player
the question i really need to know is do i need to import the Scroller class whenever i need to access its property's, or should i just send the data through to the constructor.
i really don't want to use arrays. And i'm sure somehow i can do it like this
EDIT - FallX, so should i just make the "Scroller" class a static class?
Fall_X
07-18-2006, 08:03 AM
Why wouldn't you want to use arrays? I'd use them as much as possible :)
Alternatively, you can use the all new Dictionary class, which is pretty cool in some cases. It's like an array, but with === comparison for the keys. It basically lets you use objects as keys, meaning you can easily remove an object from the Dictionary, without looping through it to find the right entry.
If you want to use something from the Scroller class, you'll need to import it. However, I wouldn't recommend making Scroller.player a static variable, imho it's not very clean.
iopred
07-18-2006, 08:05 AM
Okies, as I said before, if a function is static, it can ONLY touch static variables, meaning for a game, with a map that is dynamic.. no, you wouldn't want to make the scroller static.
The array for Particles would sit in the ParticleSystem class if you were going to do it like that. If you don't want to do it like that, I'm sure you could add all the particles to the ParticleSystem with addChild, and then iterate using getChild I guess.
Array's are how things are done, it's just the way it goes, be happy that you don't have to use LinkedLists (C++)
Fall_X
07-18-2006, 08:13 AM
Hmmm, that reminds me, I was considering using a linked list for something in Flash recently, but I forgot what or why :)
EDIT : which is pretty useless information, I know :S
mr_malee
07-18-2006, 08:13 AM
hmmm, guess there's some re-working in order
thanks for the help, really appreciate it :D
iopred
07-18-2006, 08:29 AM
Hmmm, that reminds me, I was considering using a linked list for something in Flash recently, but I forgot what or why :)
EDIT : which is pretty useless information, I know :S
I don't think it'd be any faster than using arrays and the inbuilt array methods, it's always been the case that inbuilt data types are so much faster than anything we can assemble.
Fall_X
07-18-2006, 08:43 AM
I just remembered the reason, but it was before I found out about the Dictionary class.
I wanted to have a collection where I could easily say "delete object x". With an array, you'd have to loop through it first to find the right index in the array, then splice it, or keep an index stored in all the objects, but these would have to be reworked after splicing.
With a linked list, if I also stored a reference to the previous element, I would be able to take the previous element of the object, and update it's next-reference to the next-reference of the to-be-deleted object (and the other way round too, off course), and be done with it. But it would be a bit tedious, so I went for a dictionary instead.
iopred
07-18-2006, 09:35 AM
Yeah, removal and insertion are LinkList's champion tools, but it's really a trade off.
What you gain when you remove something, is equalled to the speed you lose when you iterate it.
In that case, unless you're removing every frame, you can just iterate through the array till the correct element, then remove it.
Or you can leave a int in each object with its position in the array, and then when you remove it, you go to N to remove that object, and then iterate through the REST of the array, and decrement the position of the other objects.
Dictionaries are nice however, but they don't have a way to iterate through their members.
Fall_X
07-18-2006, 09:42 AM
I think you can iterate through a dictionary using for...in, or the new for...each, can't you? I thought I tried that and it worked, but my memory might be playing tricks on me :)
Or you can leave a int in each object with its position in the array, and then when you remove it, you go to N to remove that object, and then iterate through the REST of the array, and decrement the position of the other objects.
Off course, but that would still depend on the size of the array. If it's large, it might not be an option.
iopred
07-18-2006, 09:55 AM
Ah, for each works? I'm mistaken then, score one for not actually trying things :)
Fall_X
07-18-2006, 10:02 AM
Yeah, it works (both for in and for each), just tried it again.
However, for dictionaries, you'll probably want to use for in, not for each. For each doesn't return the key, and because the keys in a dictionary are usually objects, you'll probably want the keys.
I tend to store a bunch of objects as keys, with a simple "true" as value. Not sure if it's a good idea, but it works for what I want to accomplish.
I'll try to do some benchmarking to see if dictionaries have a performance penalty compared to arrays.
Fall_X
07-18-2006, 10:09 AM
Hmmm, this is weird. Doing 10000 sets of a for each and a for in on an array takes 94ms. Doing the same on a dictionary takes only 31ms. So unless I'm doing something wrong, it seems that a dictionary is about 3 times as fast as an array. That can't be right, can it? :S
tonypa
08-08-2006, 07:20 AM
Moved to AS3 forum.
Pugger
08-09-2006, 05:13 AM
Hmmm, this is weird. Doing 10000 sets of a for each and a for in on an array takes 94ms. Doing the same on a dictionary takes only 31ms. So unless I'm doing something wrong, it seems that a dictionary is about 3 times as fast as an array. That can't be right, can it? :S
Can I see your test code?
flashkit.com
Copyright WebMediaBrands Inc., All Rights Reserved.