Initialized property CCArray is still NULL after new CCArray - cocos2d-x

I have in scene class property in private section like
private:
CCArray* objects;
and in init I initialize
objects = new CCArray();
but when I put breakpoint in line below objects is NULL and I don't know why. It crashes when I call objects->count();
Why I cannot initialize property ?

you have tagged this post with cocos2d-x 3.0.
Array has changed in cocos2d-x-3.0.
Initialize :
cocos2d::Vector<cocos2d::Sprite *> _bullets;
Populate:
// add a bullet
Sprite *bullet = Sprite::create("circle.png")
this->_bullets.pushBack(bullet); // retains bullet
Looping:
// loop through bullets
for (auto bullet: this->_bullets)
{
// do something with bullet.
// no need to cast in this case
if (bullet->getPositionX() > 160)
{
// ...
}
}
Erasing :
this->_bullets->removeObject(bullet);
You can read all about it here:
http://dev.bunnyhero.org/2014/01/cocos2d-x-30-beta-the-new-vector-class/

Related

Using .stage not giving desired result

I make a global variable equal to a movieclip
A function gets run with an if statement checking if [x] movieclip exists, if it doesn't add it.
Despite the MovieClip being on the stage it continues using the if statement.
Document class
public static var skinHolder:MovieClip = new test;
Seperate Class (function runs every frame)
function animHandler():void
{
if (! Game.skinHolder.stage)
{
// if its not on the stage we add it to the stage
addChild(Game.skinHolder);
}
}
The stage is not set immediately after a MovieClip is added, usually it happens on the next frame.
It is an odd way to check if an object exist though, you should do something like this:
private var mySkinHolder:MovieClip;
if (!mySkinHolder)
{
// if it not exist we add it to the stage
mySkinHolder = addChild(new test());
}
I don't completely understand your structure, but to check if a DisplayObjectContainer (MovieClip in your case) has a specific child, you can use the contains() method.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html#contains()
if (!contains(Game.skinHolder)) {
addChild(Game.skinHolder);
}

Flash AS3 - Access Dynamic Text on Stage through MovieClip

I have a problem accessing Objects on my stage...
In my case I created a movieclip (mc1) with two different movieclips (mc2, mc3) inside it and a separate dynamic text field (tf1) on the stage.
If you click on mc2 or mc3, the tf1 should change to a fixed text.
Unfortunately, I always get errors accessing tf1...
Code from mc1:
mc2.addEventListener(MouseEvent.MOUSE_DOWN, Mouse_up2);
mc3.addEventListener(MouseEvent.MOUSE_DOWN, Mouse_up3);
function Mouse_up2(event:MouseEvent):void {
stage.tf1.text="text2"; }
function Mouse_up3(event:MouseEvent):void {
stage.tf1.text="text3"; }
The origin of this error message comes from the fact that your textField isn't a child of the Stage but of the MainTimeline, which is itself placed on the Stage.
trace(tf1.parent); // [object MainTimeline]
trace(tf1.parent.parent); // [object Stage]
To target your textField, you just have to write:
mc2.addEventListener(MouseEvent.MOUSE_DOWN, Mouse_up2);
function Mouse_up2(event:MouseEvent): void
{
tf1.text = "text2";
}
Note
The keyword this makes reference to the object MainTimeline contained by the object Stage. These two codes are equivalent:
tf1.text = "text2";
this.tf1.text = "text2";
Therefore, you can also write:
this.mc2.addEventListener(MouseEvent.MOUSE_DOWN, Mouse_up2);
function Mouse_up2(event:MouseEvent): void
{
this.tf1.text = "text2";
}

ActionScript 3 - use [brackets] instead of getChildByName

I have a MovieClip inside library, linkaged to MyObject and it contains a textField.
I don't know how I can access this textField without using the getChildByName method.
Apparently, the 3rd section works when object is on stage (without using addChild). But when using addChild I think there has to be some kind of casting; which I don't know how.
var childElement: MyObject = new MyObject();
childElement.name = "theChildElement";
container.addChild(childElement);
btn.addEventListener(MouseEvent.CLICK, changeText);
function changeText(event: MouseEvent): void
{
var targetBox:MovieClip = container.getChildByName(childElement.name) as MovieClip;
targetBox.textField.text = "hello"; // THIS WORKS
// This works too:
// MovieClip(container.getChildByName("theChildElement"))["textField"].text = "hello"; // THIS WORKS TOO.
// THIS DOESN'T WORK. why?
// container["theChildElement"]["textField"].text = "hello";
}
As confusing as it may seem, instance name, and name are not the same. From your code you should always be able to get to your MC by it's variable name. To get your last like to work you could just use this.
childElement["textField"].text = "hello";
There is a difference between Symbols created by the Flash IDE, which aggregate other DisplayObjects and programmatically created DisplayObjects.
When a DisplayObject is created in the Flash IDE, it's instance name can be used to resolve the instance as a property - which means it can be accessed via []. The [] can be used to access properties or keys of dynamic declared classes - like MovieClip. This necessary because you'll most likely down cast to MovieClip instead of using the symbol class created by Flash. That is not possible when simply using addChild, addChildAt or setChildAt from the DisplayObjectContainer API.
It is always the save way to access it via getChildByNameand check for null because otherwise your app, website or whatever is doomed for 1009 errors as soon as someone is changing the symbols.
I'd create a bunch of helper methods, like
// not tested
function getChildIn(parent:DisplayObjectContainer, names:Array):DisplayObject {
var child:DisplayObject, name:String;
while (names.length > 0) {
name = names.shift();
child = parent.getChildByName(name);
if (!child) {
// log it
return null;
}
if (names.length == 0) {
return child;
}
}
// log it
return null;
}
function getTextFieldIn(parent:DisplayObjectContainer, names:Array):TextField {
return getChildIn(parent, names) as TextField;
}
function getMovieClipIn(parent:DisplayObjectContainer, names:Array):MovieClip {
return getChildIn(parent, names) as MovieClip;
}
Your third method doesn't work because you are trying to call the ChildElement by it's name
without using getChildByName method. On the other hand, you shouldn't call your textField textField, because that's already an actionScript property.
Your should rather call it 'displayText' for example.
For a textField called 'displayText' contained in childElement :
function changeText(event:MouseEvent): void
{
childElement.displayText.text = "hello";
}

Actionscript: How to set an Image/Icon to a DisplayObject?

Now there is a Constructor: MyMarker(icon:DisplayObject=null) which accepts any DisplayObject, if I create a new instance of MyMarker(just new MyMarker()),it will be dsplayed with a default Icon,so how to set a Image/Icon into this Constructor? Any ideas are much appreciated!
It's kind of hard to tell from your question but, if you want to set a default icon if NO DisplayObject is passed, just check if icon is null in the MyMarker constructor, eg:
...
public function MyMarker(icon:DisplayObject=null) {
if (icon==null) {
// set default icon here...
}
}
...
As for the inheritance issue, so long as the object passed inherits from DisplayObject, you should be fine. You may run into trouble if you try to invoke methods on the object that don't appear in DisplayObject.
You should create an appropriate DisplayObject in advance and then pass the reference to this object in the constructor:
var myLittleCustomIcon:Sprite = new Sprite();
myLittleCustomIcon.graphics.beginFill(0x00FF00, 1);
myLittleCustomIcon.graphics.drawRect(0, 0, 100, 50);
myLittleCustomIcon.graphics.endFill();
var myCustomMaker:MyMarker = new MyMarker(myLittleCustomIcon);

movie clip class parameters ane null

I have a movie clip with an external class attached.
here is the MC code (I've shorten it only for the relevant part...)
package {
//all the imports here...
public class mc_masterChapter extends MovieClip {
public function mc_masterChapter() {
trace (picFile,strChapTitle);
}
//Properties
public var picFile:String;
public var strChapTitle:String;
}
}
In the main class file I'm adding this object to stage using addChild:
var masterChapter:mc_masterChapter = new mc_masterChapter;
masterChapter.picFile = "pic_Chap1.jpg";
masterChapter.strChapTitle = "ABCD:
addChildAt(masterChapter,1);
now, the trace in the MC class code gives nulls to both parametes but if i put a trace inside the MC timeline (instead of the attached class code), it gives the right value!
how can I access the values from the MC class itself without getting nuls?
Thank you.
It works! Let me explain:
var masterChapter:mc_masterChapter = new mc_masterChapter; // Calls class constuctor
// so calls trace() too!
// You will get null null
masterChapter.picFile = "pic_Chap1.jpg"; // Assign the variables
masterChapter.strChapTitle = "ABCD"; // so they can be read
trace(masterChapter.picFile, masterChapter.strChapTitle); // Should trace pic_Chap1.jpg ABCD
If you add the following method to your class:
public function test():void {
trace(picFile, strChapTitle);
}
Then call masterChapter.test() it will successfully trace those two properties. So yes, the class can read its properties.
Make the var you use in your main class public static vars.
OK!
I solved the mystery.
I put two traces. one in the main MC class saying "hey, I'm inside the MC - the picFile="
and one in the put Function saying "I'm putting this file into picFile:"
well this is what I've got:
hey, I'm inside the MC - the picFile=null
I'm putting this file into picFile:image.jpg
got it!?! at the moment I asked him to give birth to an instance of the MC (even before putting it on stage - just defining the object (with this line:)
var masterChapter:mc_masterChapter = new mc_masterChapter;
it allready run the class, so of course that in this stage the parameters were not defined allready and were null.
the definition code came right after that line (in the main.as)
masterChapter.pic="pic_Chap1.jpg";
so what I did, was to move all the code from the main class of the MC object to a public function inside the same package called init(). Then I called this function manually from the parent main class.
By that I can decide when to call it (after I declare all the parameters of course).
That's it.
god is hiding in the small details : )
tnx for all the helpers.
Possibly a better solution would be to use a getter/setter pair, so you can know at the exact moment the properties are set:
protected var _picFile:String:
public function get picFile():String {
return _picFile;
}
public function set picFile(value:String):void {
if (value != _picFile) {
_picFile=value;
trace('picFile set to', _picFile);
}
}