views:

82

answers:

4

Hello,

I have a class named TextLink. The text is meant to be clicked on and it should dispatch an event (which I'm not too concerned about yet)... currently it just prints out a message. The class takes an x, y, and a string to set the text. Dead simple... But it crashes the browser.

Instance calls in main:

package {
    import flash.display.Sprite;

    import nav.text.TextLink;

    public class test_array_of_objects extends Sprite
    {
     public function test_array_of_objects()
     {
      var ary:Array = new Array(5);
      var i:uint;
      var ty:uint;
      var tx:uint = 30;

      for(i=0; i<ary.length; i++)
      {
       ty = i * 20 + 20; 
       var tmp:TextLink = new TextLink(tx, ty, "some text" + i.toString());
       ary.push(tmp);
      }   
     }
    }
}

Class:

package nav.text
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.external.ExternalInterface;

    public class TextLink extends Sprite
    {
     public var tf:TextField = new TextField();

     public function TextLink(tx:uint, ty:uint, tft:String)
     { 
      tf.text = tft;
      tf.x = tx;
      tf.y = ty;
      tf.autoSize = TextFieldAutoSize.LEFT;

      addChild(tf);
     }

     private function rollfunc(e:Event):void
     {
      ExternalInterface.call("console.log", "got a clicky"); 
     }

     /*
     protected function rollfunc(e:Event):void
     { //dispatch a custom event 
      dispatchEvent(new Event(Event.COMPLETE)); 
     }
     */
    }
}

You'll notice that I have commented out the rollfunc function because I was going to add it later- What I would like to do here is to dispatch an event for whoever is listening to the class so that I can do something specific with the event of clicking on the text. The instance would be defined by an addEventListener() call.

Thanks

A: 

I see you 'newing' up a TextLink object but doing nothing with it.

Did you mean to add that to the array 'ary' ?

As it stands, you're creating this new instance and it goes out of scope as the loop iterates.

POopMonster
yeah; thanks for mentioning that. i've updated the code.
jml
+1  A: 

ary[i] is an undefined element of the array ary, so ary[i].push will throw an exception. You probably want either:

ary.push(tmp);

or

ary[i] = tmp;

but I can't say for certain, since you didn't say what behavior you're getting, you merely stated that the code "won't work".

outis
the browser crashes, whether i am debugging or not.i have a listener being added in the textlink class, but this shouldn't matter too much.
jml
+1  A: 

You got several problems going on here that might be causing your snippet to fail. The use of ary[i].push(tmp) is improper. Doing this would assume that ary[i] is itself another array that you would be pushing (appending to). I personally wouldn't use uint in this fashion either, just as a general practice. It is actually slower than int and serves no solid purpose here. Additionally, instead of creating an array of a specific length, I will use constants as shown below. Arrays are mutable, so the length isn't relevant, but this is just a stylistic concern.

package
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;

    public class Test extends Sprite
    {
     private static const NUM_SPRITES:int = 15;

     private var ary:Array;

     public function Test()
     {
      var i:int;
      var ty:int;
      var tx:int = 30;

      ary = [];

      for(i=0; i<NUM_SPRITES; i++)
      {
       ty = i * 20 + 20;
       var tmp:Sprite= new Sprite();
       tmp.addEventListener(MouseEvent.CLICK, handleClick);
       tmp.graphics.beginFill(0xFF0000);
       tmp.graphics.drawRect(0,0,20,20);
       tmp.x = tx;
       tmp.y = ty;
       addChild(tmp);
       ary.push(tmp);
      }
     }

     public function handleClick(event:MouseEvent):void
     {
      for each(var spr:Sprite in ary)
      {
       if(spr == event.target)
        trace(spr.x, spr.y);
      }
     }
    }
}
Joel Hooks
can you explain to me how or why uint would be slower than int? this simply shouldn't be, by definition. i cam imagine though, that uint is emulated rather than actually smaller in runtime terms.
jml
i also don't understand why you would want to put a for loop inside of your handleClick function in order to determine the target of the event. wouldn't it be easier to just call a handleClick function from the listener you'd already made in the previous for loop?
jml
Hi again Joel,I have a post here that I cannot figure out: http://stackoverflow.com/questions/1992456/as3-removing-objects-by-array-item-referencedo you have any idea of what I could do here to remove the items from the stage? I don't think I need a utility wrapper for such simple functionality, esp. because I am not going to make a new one for each different type of loading-oriented sprite-class.
jml
+3  A: 
for(i=0; i<ary.length; i++)
{
    ...
    ary.push(tmp);
}

This is an infinite loop. ary.push() will increase ary.length on each iteration and i will never be able to catch up to it.

I think you want @outis's second suggestion here; i.e. ary[i] = tmp

Or just create an empty array and push things into it.

aib
yeah; i think you're right about this.thank you for your observation... that helps a lot.
jml