Class problem

Hello All

I know, the title is not representative, but I have no clue what title would fit to my problem.

I am trying to get back to Flash and AS. So I thought I try to do a small project, just to get the feeling back.

As a result I got the attached .fla with 4 classes. Additionally I use TweenLite.

Now, if you open the .swf file you can clearly see, that it works, except for the lower right field (which should turn orange as well).
(On a second matter, the lower right field is always the last one, I guess I screwed up my random formula…If you have any Idea how to fix this let me know, thanks :slight_smile: )

I found out, that in the for loop the 10th field is instantiated, but not correctly created. The function createRect is never called, according to the debugger. The object has no name, it has no additional Child nothing. But the DropShadow is drawn.
I just cannot figure out why that happens.

If anybody could take a look at this, I would really appreciate it.

Also, because it’s my first OOP-project, I would be happy to receive whatever critique or comments you can spare :slight_smile: I think it’s best to get rid of all bad habits before they sink in.

If you need any more information, please let me know

Cheers H.2.O

As an additional Info to the project: I think it’s clearly visible, that this should become a preloader animation. Because I have nothing to preload I wrote the function incPerc in Preloader.as which simulates the whole preloading of data.

Huh… few things… the way you did it it wasn’t simulating download, and you ware starting to count from 1, while the first item in array is a 0 position… Anyway, it sort of works now, but I would rewrite it from the scratch… Why use uints with calculations that may produce negative numbers as the result? The idea of getting clips by name is wrong, name is the property you need for debugger, normaly you have to store the link to the object, not some parameter relying on which you may find it…

hey wvxvw

thanks a lot for having a look at my files.

Yeah, you’re right, it wasn’t simulating the download, it was just simulating the percentage, but that’s all I need for what I want to do.

Hmm…I see what you changed in my Preloader.as file, but I don’t agree with the changes. The way it is set up right now you would be correct to call grid.addShape() on line 59. But if the download would be fast (or you would have more shapes) it could happen, that one of the shapes would be skipped. That’s why I created the grid.emitShapes() function which can add more then one shape…does that make sense?

I only used uint where there shouldn’t be a negative number, but I see how that can end in problems that are hard to find, I will fix that.

That would be the next step, because i didn’t think of putting them in an Array before.

Thanks again for your help, appreciate it

Cheers Carlo

Try this:

trace(uint(Math.random()*2-2))

This would be a rough approximation of what would have happened when you tried to get first item from an array.
This may output both 0 and 4294967295.
In your code grid.emitShapes(n:int) n could never be >1… so, I just didn’t use it.
I don’t say it’s a perfect fix… it just made it work in the current situation… I’d think about totally different way of doing what you want. Like, subscribing some function to ProgressEvent.PROGRESS, and adding shapes depending on the loaded/total percentage.

The problem was timing
change in Preloader.as

  private function incrPerc(e:TimerEvent):void{
   _perc += Math.random()*2;
   _currShape = Math.floor(_perc/_step);
   grid.percentValue = _perc;
   if(_currShape > _countShapes){
    if(_currShape == _quantity){
     trace("x");
    }
    grid.emitShapes(_currShape-_countShapes,_currShape>=_quantity?true:false);
    _countShapes = _currShape;
    if(_currShape>=_quantity){
     timer.removeEventListener(TimerEvent.TIMER,incrPerc);
     grid.eraseBorder();
     grid.addEventListener(MouseEvent.CLICK,dropShapes);
    }
   }
  }

in Grid.as

  public function emitShapes(numofShapes:uint,immediatelly:Boolean=false):void{
   if (immediatelly) addShape(null) else {
    timer = new Timer(uint(Math.random()*25+25),numofShapes);
    timer.addEventListener(TimerEvent.TIMER,addShape);
    timer.start();
   }
  }
  
  private function addShape(e:TimerEvent):void{
   //create sprites first
   //mask
   var m = new Sprite();
   m.graphics.beginFill(0xFF0000);
   m.graphics.drawRect(-_shapeW/2-1,-_shapeH/2-1,_shapeW+2,_shapeH+2);
   m.graphics.endFill();
   
   //pic
   _pic = new PicTest();
   
   //new Rect
   var r:Rect = new Rect(_shapeW,_shapeH);
   var rand:uint = Math.floor(Math.random()*_arrBuild.length);
   var tmpIndex:uint;
   r.x = _arrBuild[rand][0] * _shapeW + _shapeW/2;
   r.y = _arrBuild[rand][1] * _shapeH + _shapeH/2;
   r.name = "shape_" + _arrBuild[rand][0] + "_" + _arrBuild[rand][1];
   trace(r.name);
   //add _pic and position
   r.addChild(_pic);
   _pic.x = -(r.x)+(_cols*_shapeW-_pic.width)/2-1;
   _pic.y = -(r.y)+(_rows*_shapeH-_pic.height)/2-1;
   
   //check if pic is visible and add mask if TRUE
   if(r.getChildByName("box").hitTestObject(_pic)){
    r.addChild(m);
    _pic.mask = m;
   }else{
 //   r.removeChild(_pic);
   }
   
   tmpIndex = _cols-uint(_arrBuild[rand][0])-1 + uint(_arrBuild[rand][1])*_cols;
   addChildAt(r,tmpIndex);
   removeChildAt(tmpIndex+1);
   _arrBuild.splice(rand,1);
  }

wvxvw and Felixz

Thank you both for your help.

@wvxvw: I already started to change my “uint” to “int”, thanks.
I cannot implement the ProgressEvent.PROGRESS yet, because
I don’t preload anything yet. But that would of course be the
final goal to let it act on the percentage of the preload.

@Felixz: Thank you for your time, really appreciate it.
I will check it as soon as I am home, because I don’t have Flash at work.

@anybody watching:
My next step will be to change the getChildByName to directly working with
an Array of all the shapes in the grid. Will keep this post updated with my
newest version.
I am still happy for every Input I can get.

cheers Carlo

Hello All

Thanks to wvxvw and Felixz I was able to achieve the goals that I set for myself.

I rewrote a lot of parts that wvxvw gave me feedback to.

I still would like to know if I made some major rookie mistakes with classes.
So, if anybody has some spare time I would really appreciate the feedback.

thanks in advance

cheers

Yes, this looks much better, but there still things to improve =)

public function reposition(xPos:Number, yPos:Number):void {
			x = Math.round(xPos);
			y = Math.round(yPos);
		}

I’d rather do like this:

public override function set x(n:Number):void {
			super.x = int(n);
		}
		public override function get x():Number {
			return super.x;
		}
		public override function set y(n:Number):void {
			super.y = int(n);
		}
		public override function get y():Number {
			return super.y;
		}

First: you may need to set X and Y separately. Second: you’re extending Sprite class, so, having these properties set in the same way as they are set in the parent class would be a good idea (other developers, if they would like to use it, won’t need to search for an additional custom function + won’t get unexpected results trying to set X/Y).

Adobe recommends using literals in place of new [ClassName] whenever possible. I.e. someVar = [] instead of someVar = new Array().
The same for naming private vars (name should start with underscore).
Although new SomeClass and new SomeClass() may give the same result, basicaly, it’s not the same. (If you have some functions calls in constructor they won’t be executed if you dont put () after class name.)

in Rect class u can use static const

private static const shadow:DropShadowFilter = new DropShadowFilter(5,135,0,.7,1,1);

And why u are constantly using length-1?

Math.floor(Math.random()*(_arrBorder.length-1))

It wont give u last index (only when u have one element). It is enough to set

int(Math.random()*(_arrBorder.length))

In Grid function eraseBorder is too complicated (read: Slow)

		public function eraseBorder():void {
			for each(var rect:Rect in _arrBorder) rect.eraseBorder();
			_arrBorder=[];
			addChild(fr);
		}

Also setting a textFormat can be done without creating dozens of vars, just:

			_tfield.defaultTextFormat = new TextFormat(new FGCheryl().fontName,30,0x800000,null,null,null,null,null,TextFormatAlign.RIGHT);

Those overrides seem to be fine, but overriding getter is just too officious (don’t know whether it is right word). And one thing; Adobe’s components have function move(x,y);

Hey Guys

I don’t know why I didn’t see your replys…really sorry, that I didn’t answer earlier!
Thank you very much for taking your time and helping me.

As soon as I have time (tonight or tomorrow night) I will have a close look at your suggestions.

I also have a newer version which I would like to show you, but I don’t have it here at work.

Thanks again

Carlo