-
Simple Question #3: Breaking things into classes
(All of this is being done in FlashBuilder 4.6)
Ok, I'm stumbling along on my learning curve here, and have come to a point where I need to understand better how classes and packages are structured.
I started off writing a little AS code to draw a rectangle in each corner of the stage:
package
{
import flash.display.Shape;
import flash.display.Sprite;
public class BoundaryRectangles extends Sprite
{
public function BoundaryRectangles()
{
var rectangles:Array = new Array();
for (var i:int = 0; i < 4; i++) {
var xPos:int = 20;
var yPos:int = 20;
rectangles[i] = new Shape();
rectangles[i].graphics.beginFill(0xFF0000);
switch(i){
case 0:
xPos=0;
yPos=0;
break;
case 1:
xPos=stage.stageWidth;
yPos=0;
break;
case 2:
xPos=5
yPos=stage.stageHeight-5;
break;
case 3:
xPos = stage.stageWidth;
yPos = stage.stageHeight-5;
break;
default:
xPos = 50;
yPos = 50;
}
rectangles[i].graphics.drawRect(xPos, yPos, 5, 5);
rectangles[i].graphics.endFill();
addChild(rectangles[i]);
}
}
}
}
So, that seems to be working fine. I can run it and I get my four little rectangles in the corners of the stage, so its a start.
Then I had the idea that I want to invoke this class from another. Toward that end, I created a little stub of a "caller" class like this:
package
{
import BoundaryRectangles;
public class Example2
{
var my_test:BoundaryRectangles = new BoundaryRectangles();
}
}
My assumption was that the constructor for BoundaryRectangles would get called there, and I would see the visual result.
However, when I run that, I get nothing. What I do get is a compile-time warning : "1084: var 'my_test' will be scoped to the default namespace: Example2: internal. It will not be visible outside of this package."
Which I do not understand.
I can't imagine I am too far off the mark here.
What am I doing wrong?
-
You're accessing the stage property in the constructor, which is going to be null because the new instance has not been added to the stage yet. The only exception is when a class is attached to the main movie clip. If your class needs information about the stage, you should listen for the ADDED_TO_STAGE and do the work inside the event handler.
You're getting the warning message because you didn't declare your variable to be public, protected, or private.
-
Thanks!
I got the warning message part sorted out, but I'm stuck on the event handler part.
I created a public function inside of the BoundaryRectangles class called "draw", but I'm not sure where to go from there.
My first effort looks like this:
package
{
import BoundaryRectangles;
import flash.display.Sprite;
import flash.events.Event;
public class Example2 extends Sprite
{
public function Example2 ():void
{
var my_test:BoundaryRectangles = new BoundaryRectangles();
my_test.addEventListener(Event.ADDED_TO_STAGE, my_test.draw);
}
}
}
That compiles and runs without error, but nothing happens. "draw()" never gets called. The process just sits there (I'm guessing the listener is sitting there listening for something that never comes...).
Then I had the idea that I needed to do an "addChild()" to attach the BoundaryRectangles instance to Example2's stage, so I changed Example2's constructor thus:
public function Example2 ():void
{
var my_test:BoundaryRectangles = new BoundaryRectangles();
my_test.addEventListener(Event.ADDED_TO_STAGE, my_test.draw);
addChild(my_test);
}
This compiles fine, but when I run it, I get an error: Argument count mismatch on BoundaryRectangles/draw(). Expected 0, got 1.
Which has me flummoxed.
Any help would be most appreciated.
-
0maha
I am continuously tracking from the beginning and every time tried to reply you.
But unfortunately I have a feeling that before you know FB you have to know AS3.
You are making very basic mistake and having wrong concept of using Classes.
I suggest you to throw out all your previous knowledge and start it freshly.
Regards
-
I am using Flex 3 most of the time and most of the work of our clients are still be done in this version of Flex.
This is why we love this IDE using SDK of 3.2 to 3.6.
We find this version of Flex is very handy and you can adopt almost all the needs an Apps needed.
This is not making sense for most of the member over here but it is a truth of our development.
We also use the other versions too.
But I suggest you to start with something which is very basic and gradually dive in for complex Class Structure.
Regards
-
Create a new Project with a meaningful name. Not Example 1,2.... or something else which will waste your knowledge in future. Because I am sure you have to pip into these every single day you study.
For Example: SimplePreloader
This will be a module for your future library too.
Hope this make sense.
You can ask any question you have regarding AS3, Flex/FB.
All the Best
-
Thank you for the reply.
I figured out the problem: The draw() function inside of BoundaryRectangles required and event object as a parameter. Once I added that, everything works perfectly.
-
What is the CODE now?
Can you post the Class Code?
-
The caller class is now:
package
{
import BoundaryRectangles;
import flash.display.Sprite;
import flash.events.Event;
public class Example2 extends Sprite
{
public function Example2 ():void
{
var my_test:BoundaryRectangles = new BoundaryRectangles();
my_test.addEventListener(Event.ADDED_TO_STAGE, my_test.draw);
addChild(my_test);
} } }
and BoundaryRectangles is now:
package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.*;
public class BoundaryRectangles extends Sprite
{
public function BoundaryRectangles()
{
}
public function draw(event:Event):void
{
var background:Shape = new Shape();
var rectangles:Array = new Array();
background.graphics.beginFill(0x44558C);
background.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
background.graphics.endFill();
addChild(background);
for (var i:int = 0; i < 4; i++) {
var xPos:int = 20;
var yPos:int = 20;
rectangles[i] = new Shape();
rectangles[i].graphics.beginFill(0xFF0000);
switch(i){
case 0:
xPos=0;
yPos=0;
break;
case 1:
xPos=stage.stageWidth-5;
yPos=0;
break;
case 2:
xPos=0
yPos=stage.stageHeight-5;
break;
case 3:
xPos = stage.stageWidth-5;
yPos = stage.stageHeight-5;
break;
default:
xPos = 50;
yPos = 50;
}
rectangles[i].graphics.drawRect(xPos, yPos, 5, 5);
rectangles[i].graphics.endFill();
addChild(rectangles[i]);
}
} } }
-
Actionscript Code:
package { import flash.display.Sprite; import flash.events.Event;
public class main extends Sprite { private var bRect:BoundaryRectangles; public function main() { bRect=new BoundaryRectangles(); addChild(bRect); } } }
Actionscript Code:
package { import flash.display.Shape; import flash.display.Sprite; import flash.events.*;
public class BoundaryRectangles extends Sprite { private var box:Box; private var rectangles:Array = new Array(); private var xPos:int = 20; private var yPos:int = 20; public function BoundaryRectangles() { addEventListener(Event.ADDED_TO_STAGE,added); } private function added(evt:Event):void{ evt.target.draw(); } public function draw():void{ box = new Box(0x44558C,0,0,stage.stageWidth, stage.stageHeight); addChild(box); fillStage(); } private function fillStage():void{ for (var i:int = 0; i < 4; i++) { position(i); box = new Box(0xFF0000,xPos, yPos, 5, 5); rectangles[i] = box; addChild(rectangles[i]); } } private function position(index:int):void{ switch(index){ case 0: xPos=0; yPos=0; break; case 1: xPos=stage.stageWidth-5; yPos=0; break; case 2: xPos=0 yPos=stage.stageHeight-5; break; case 3: xPos = stage.stageWidth-5; yPos = stage.stageHeight-5; break; default: xPos = 50; yPos = 50; } } } }
Actionscript Code:
package { import flash.display.Shape;
public class Box extends Shape { public function Box(color:uint,xPos:int,yPos:int,w:int,h:int) { this.graphics.beginFill(color); this.graphics.drawRect(xPos,yPos,w,h); this.graphics.endFill(); } } }
Try this..
-
Typically, you want a class to "take care of itself." So instead of Example2 calling BoundaryRectangles' addEventListener(), BoundaryRectangles should set up its listeners in its own constructor. If I were writing the class, I would do something like this:
Actionscript Code:
package { import flash.display.Sprite; import flash.events.Event; public class BoundaryRectangles extends Sprite { public function BoundaryRectangles() { addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true); } private function onAddedToStage(e:Event):void { redraw(); } private function redraw():void { graphics.clear(); if(stage) { var stageWidth:Number = stage.stageWidth; var stageHeight:Number = stage.stageHeight; graphics.beginFill(0x44558C); graphics.drawRect(0, 0, stageWidth, stageHeight); graphics.drawRect(5, 5, stageWidth - 10, stageHeight - 10); graphics.endFill(); } } } }
A couple things to note here: Notice how I set the stageWidth and stageHeight properties to local variables. Accessing an object property can be slow. If you need the value more than once, it's a good idea to store it in a local variable. It also means you can see their values more readily in the debugger. Helps with copy-and-pasting too. Double-click and the word is selected. Just a little tip that you might find useful. The second thing is how I draw the border: I just draw a smaller rectangle inside a bigger one. The default fill rule in Flash means the second, overlapping rectangle is excluded.
Last edited by cleong; 06-01-2012 at 06:18 PM.
-
Excellent help, guys! This is exactly the sort of thing a newbie like me needs!
Thank you very, very much!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|