I have a function that creates a pointer on the screen after certain other conditions are met. I have a separate function that I use for moving the pointer around the screen (since the conditions for the first function and the second function are mutually exclusive). The problem, as far as I can tell, is that upon loading the movie flash instantly looks at all the code on the main timeline and realizes that my second function, the one for moving the pointer, is referencing the pointer's .x and .y even though the pointer doesn't exist. The second function's conditions prevent it from occurring until the first function has executed and the pointer has been created.
My question is, is there any command that I can use to tell flash "pointer.x and pointer.y don't exist YET, but by the time you need them they will, so chill" or do I need to start burying code on the movieclip itself or something? I'm still very new to AS3 so my methods aren't the most... Effective yet.
Yes, there is some. You go into second function and check:
if (!pointer) return;
This will check if "pointer" exists, and is not null or undefined. Basically this is the correct method of programming, first check availability of your objects, then access them.
Related
Are there any general guide lines for using retain and release for objects in cocos2d-X ? When creating objects in a function, is it true that the functions memory is cleaned up the second the function returns. When a object is created, calling the retain function of the object, will retain object beyond the function return ?
Kind Regards
Generally in c++ you have this behaviour:
void foo() {
Object a;
Object *pA = new Object();
(…)
}
This would result in a being destroyed automatically at function end, as it was allocated on stack. The *pA would not get destroyed, as it was allocated on the heap (thus, you only loose the reference to it, but the object itself still lives).
Cocos implements a thing called "Automatic Reference Counting" : each CCObject has a reference counter and two methods retain() and release(). The way this works is, that every time you create an object, it gets registered in cocos structers (CCPoolManager). Then with every frame (between them being drawn) there is a maintenance loop which checks the reference counter of all objects : if it is 0 this means (to cocos) that no other objects reference it, so it is safe to delete it. The retain count of an object is automatically incresead when you use this object as an argument for an addChild function.
Example :
void cocosFoo() {
CCSprite *a = CCSprite::create(…);
CCSprite *b = CCSprite::create(…);
this->addChild(b);
}
What happens here is this :
Two CCSprites are created, cocos knows about them.
The b sprite is added to this object (say a CCLayer)
The function ends, no objects are destroyed (both of them being on heap).
Somewhere between this and next frame, the maintanance gets run. Cocos chcecks both sprites and sees that a has reference count == 0, so it deletes it.
This system is quite good, as you don't need to worry about memory management. If you want to create a CCSprite (for example), but not add it as a child yet, you can call retain() on it, which will raise its reference counter, saving it from automatic deletion. But then you'd have to remember about calling release() on it (for example, when adding it as a child).
The general things you have to remeber about are :
Each call to retain() by you needs to be paired with release().
You generally shouldn't delete CCObjects yourself. If you feel that you need to, there is a conveniece macro : CC_SAFE_DELETE(object)
So to answer your questions in short :
Are there any general guide lines for using retain and release for objects in cocos2d-X ?
Yes, you should generally not need to do it.
When creating objects in a function, is it true that the functions memory is cleaned up the second the function returns.
Answer to this is the whole text above.
When a object is created, calling the retain function of the object, will retain object beyond the function return ?
Yes, as will adding it as a child to another (retained in any way) object.
Here is the thing,
cocos2dx has an autorelease pool which drains the objects which have retain count=0 which is a variable to keep in check the scope of the cocos2dx object.
Now when you create new object using the create method it is already added to the autorelease pool and you don't need to release it or delete it anywhere , its like garbage collector in java, takes care of garbage objects behind your back.
But when you create new object using 'new' you definitely need to release it in its destructor or after its use is over.
Second thing,
when your object is added to the autorelease pool but you need it somewhere else you could just retain it , this increments its retain count by one and then you have to manually release it after its use is over.
Third Thing,
Whenever you add child your object it is retained automatically but you don't need to release it rather you remove it from the parent.
I've just started to learn actionscript for a month or so, and I've been stuck on this part of the code for about 2 days now ><
So basically, I wanted to write a hitTestObject in a movieclip ("fire_mc") to detect if it overlaps the the child I added on stage (enemy)
So here's what I wrote in the main stage...
var newtarget:enemy=new enemy();
stage.addChild(newtarget);
newtarget.x=40;
newtarget.y=30;
and every time I traced the newtarget in the fire_mc, it turns out to be NULL...
So should I be tracing enemy or newtarget? (Cuz I tried both and nothing works).
And how can I hitTestObject in the fire_mc movieclip?
Is it possible for me to hitTestObject newtarget if I were to create multiple newtarget-s?
If not, what should I do?
And can someone tell me the difference between root, and MovieClip(root) (Because sometimes in a movieclip I have to use the former one to work, and sometimes the latter, and I have no idea why cuz I'm all referencing to the same place)
Sorry for these simple and lengthy questions, I'm really just a noob and I tried looking up for answers in the web for hours, but nothing helpful turned up><
Thanks in advance :)
In this statement
var newtarget:enemy=new enemy();
var - keyword used to define varibles, newtarget - variable name in which pointer to new class instance stored, :enemy - data type (the class name), new - keyword used to create new class instances, and finally enemy is class constructor (by the way there is a rule of good manners by which class names are capitalized)
So answer for you question which should you use when you want check is some is overlapping is 'newtarget'.
Now about hit test - all you need do to check if two objects hit each other is correctly use their references from the part of project where your code is writen.
For example if you have your fire_mc on MainTimeline created by IDE, and code of creation of you enemy instance stored in newtarget sameplace, then if you check will be placed in frame of MainTimeline where both object present it will be like this
fire_mc.hitTestObject(newtarget);
or this
newtarget.hitTestObject(fire_mc);
All these statements give you same result - if objects intersect each other you have true returned.
If you created 'newtarget' on MainTimeline and checks will be from fire_mc (which is on MainTimeline to) frame, then code will something like that
this.hitTestObject(MovieClip(root).newtarget);
Now about root. Primarily it is a property of DisplayObject in which reference to the top-most display object in swf-file structure is stored. So as such it is inherited by all child classes. So here's the trick. When you try get your objects in swf structure using root here the differences are based on the fact that root always return object as DisplayObject and that means what if you object contains something that DisplayObject shouldn't you can't get it. So you must convert returned reference to need data-type usign MovieClip(...).
What does a period with a name before a function mean when calling it in Arduino code (C/C++)?
For example, I am using an OLED display library and one function is called like this:
display.setTextSize(1);
I know what this function does, but what does the syntax mean where there is some variable "display" or something before it?
In other words, why is a function called this way versus a normal call with just the function name and input?
"display" is an instance of an object, or a reference to some global/system variable. The "setTextSize" method is a member of that object. The end result means that you are setting the text size of, or on, "display".
This lets you do things more concisely by being able to say display.setTextSize(1), foo.setTextSize(1) and bar.setTextSize(1) without having to specify unique functions for each different item on which you are setting the text size.
Within setTextSize you will probably see "this". "this" in only this one instance means "display". If you used bar.setTextSize(1), "this" would mean "bar" and so on.
I could be incredibly wrong, but I think its got to do with structures. In the arduino environment there's a few different functions that revolve around using serial communication. They have it set up as a library that gets called on whenever you use Serial.something();
The something could be any of the functions that is part of serial, like Serial.read();
EDIT forgot to put a source in. http://arduino.cc/en/Reference/Serial
Apologies if I'm way off, still new at this, and also can't figure out how to just make a comment.
Riddle me this: I have my MouseEvent.MOUSE_DOWN which calls mouseHandler. The latter looks something like this:
public function mouseHandler(evt:MouseEvent):void
{
var p:Point = new Point(mouseX, mouseY);
var objs:Array = new Array(getObjectsUnderPoint(p));
}
Now what I want to know is thusly: will the objs array and p point be overwritten every time, simply causing the previous objs array and p point to be wiped and a new one generated, or...does it just create a new array and point over and over and over? Of course if I trace(objs) it gives me the expected results, but am I chocking up the system in the background without realising? Your expertise would be appreciated.
EDIT: well after learning a fair bit from the answerers -thanks btw- that made me think of something else and, a quick search later, found a way to theoretically reliably remove the references:
var a = null;
Now I appreciate that this is probably not needed as they'll be GCed at the end of the function, but considering it takes two ticks to write, better safe than sorry, no?
It works like this from what I understand - references for these variables will be lost after function will end. The values will be GC'ed then eventually.
If you will call the function second time, the new references will be created, and filled with new data, the values of previous references hovewer, may still exist in memory, and wait for Garbage Collector, but that may not necessarily happen! If they have attached listeners, the Flash Player will think that they are still useful, so they will exist in the memory to the end of the application run and listen, and even react to events - even if you theoretically cannot access them anymore.
Edit:
In your case whats happening is that you are creating two references that will disappear at the end of the function. They are not related to event listener, the listener creates them, but is not attached to them so it won't stop GC from collecting them after function will end. You creates an array of references, but that are just references to other objects that values are referred in other places (like the display list), if the array alone is not referred anywhere outside of this function, it should be GCted.
Since p is an object, not a primitive, the memory allocation for it will come from the Heap (and therefore need to be garbage collected) instead of the stack like local primitives (and are wiped once the function ends.
So new memory will be allocated every time this function is called, which will temporarily increase memory usage until they get GC'd, but the amount is probably insignificant (assuming that array isn't massive!).
Given the below:
object.addEventListen(eventType01,handler01);
object.addEventListen(eventType01,handler01);
object.removeEventListener(eventType01,handler01);
How many event listeners for eventType01 are on object? One or zero?
Zero. If you call addEventListener, using the exact same arguments more than once all subsequent calls after the first "silently fail." Call add as many times as you want, but that single remove will wipe the listener away.
EDIT: Another thing to keep in mind is that there's no penalty to calling multiple identical removeEventListener() functions on the same object, aside from needless performance overhead. No deadly error will occur, it will simply "silently fail" much the same way as repeated identical addEventListener calls will.
EDIT 2: To answer #ThomasM :: if your listener "fires twice" then you do not have exactly the same listener. Try putting this quick and dirty code on frame 1 in a fla that has one square movieclip as a child:
import flash.events.*
function foo(e):void{
trace("hi");
}
this.addEventListener(MouseEvent.CLICK,foo);
this.addEventListener(MouseEvent.CLICK,foo);
this.addEventListener(MouseEvent.CLICK,foo);
Notice that your output when you click the movieclip is precisely one trace action.
Now add this line to the end of the code
this.removeEventListener(MouseEvent.CLICK,foo);
Even though you added foo as a listener for click 3 times, this one call kills the listener completely.
So if you're experiencing an issue where "the same listener" fire twice then probably what you're doing is something like this:
this.addEventListener(MouseEvent.CLICK, function(e){
trace("hi");
});
this.addEventListener(MouseEvent.CLICK, function(e){
trace("hi");
});
That will definitely "fire twice" because the listener functions ARE NOT THE SAME. They perform the same actions but they do not reference identical positions in memory. They do not point to the same function object. Furthermore this is highly bad practice because you have no way to actually remove those listeners. How would you do it? You have no reference to them.