PDA

View Full Version : help creating a self animating class...



justinswartsel
August 27th, 2007, 12:02 PM
Hey everyone, my goal here is to create a class that will display and animate a small square in size and color. My problem is that nothing is showing up on the screen and I'm not sure why... here is the class code:



package {

import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.display.Shape;
import flash.display.MovieClip;


public class AbstractSquare extends MovieClip {



private var scolor:uint;
private var sTrans:ColorTransform;
private var sShape:Shape;
private var flashT:Timer;
private var hideT:Timer;
private var showT:Timer;

public function AbstractSquare(sx:int, sy:int, swidth:int, sheight:int, col:uint){

this.x = sx;
this.y = sy;
this.width = swidth;
this.height = sheight;
scolor = col;
sShape = new Shape();

flashT = new Timer(30, 10);

flashT.addEventListener(TimerEvent.TIMER, animStep);
flashT.addEventListener(TimerEvent.TIMER_COMPLETE, resetTimers);
this.addEventListener(Event.ADDED_TO_STAGE, squareInit);

}


private function squareInit(e:Event){
addChild(sShape);
beginAnimation();
}

private function beginAnimation(){

trace("in beginAnimation");
sShape.graphics.beginFill(scolor);
sShape.graphics.drawRect(0, 0, this.width*1.25, this.height*1.25);
sTrans.redOffset = 255;
sTrans.greenOffset = 255;
sTrans.blueOffset = 255;
sShape.transform.colorTransform = sTrans;

this.x -= 2.5;
this.y -= 2.5;

flashT.start();

}

private function animStep(e:Event):void {

this.width -= .5;
this.height -= .5;
this.x += .75;
this.y += .75;
sTrans.redOffset -= (256/10);
sTrans.blueOffset -= (256/10);
sTrans.greenOffset -= (256/10);
sShape.transform.colorTransform = sTrans;

}


private function resetTimers(e:Event):void {
flashT.reset();
}

}
}
On frame 1 of my movie I have:



import AbstractSquare;

var asq:AbstractSquare = new AbstractSquare(50,60,40,40,0xff0000);
addChild(asq);
There are no compile errors and the trace works in beginAnimation. Any help would be appreciated!

Justin

soulwire
August 27th, 2007, 12:29 PM
I do get an error


TypeError: Error #1009: Cannot access a property or method of a null object reference.
at AbstractSquare/::beginAnimation()
at AbstractSquare/::squareInit()
at flash.display::DisplayObjectContainer/addChild()
at test_fla::MainTimeline/test_fla::frame1()

The problem is that you never envoke your colorTransform.

Try
private var sTrans:ColorTransform = new ColorTransform(); in your class constructor.

GrndMasterFlash
August 27th, 2007, 12:32 PM
what happens when you trace AbstractSquare in its function, maybe this is pointing somewhere else?

also can you do a trace asq for me

soulwire
August 27th, 2007, 12:59 PM
The instance is added fine, it is the refferences to the colorTransform properties that are returning null because the colorTransform class isnt being initiated

justinswartsel
August 27th, 2007, 01:09 PM
Thanks everyone for your advice. I instantiated the ColorTransform and the error (that I somehow missed) went away.

Also, I traced asq as mentioned and it returned "[object AbstractSquare]" . So my AbstractSquare object is there. Its just the internal display stuff that still isnt working.

hm...

justinswartsel
August 27th, 2007, 02:52 PM
For anyone who is interested, I got it to work. I started referencing the 'graphics' property of 'this' instead of a new shape. Maybe addChild is inneffective inside of some classes?




package {

import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.display.Shape;
import flash.display.MovieClip;


public class AbstractSquare extends MovieClip {



private var scolor:uint;
private var sTrans:ColorTransform = new ColorTransform();
private var sShape:Shape = new Shape();
private var flashT:Timer;


public function AbstractSquare(sx:int, sy:int, swidth:int, sheight:int, col:uint){



//trace("swidth " + swidth + " sheight " + sheight);
this.graphics.beginFill(col);
this.graphics.drawRect(0, 0, swidth*1.125, sheight*1.125);
//trace("this.width " + this.width + " this.height " + this.height);
this.x = sx;
this.y = sy;

flashT = new Timer(30, 10);

flashT.addEventListener(TimerEvent.TIMER, animStep);
flashT.addEventListener(TimerEvent.TIMER_COMPLETE, resetTimers);

beginAnimation();

}


private function beginAnimation(){

sTrans.redOffset = 255;
sTrans.greenOffset = 255;
sTrans.blueOffset = 255;
this.transform.colorTransform = sTrans;
trace(sShape);
this.x -= 2.5;
this.y -= 2.5;
trace("this.x " + this.x + " this.y " + this.y);

flashT.start();

}

private function animStep(e:Event):void {

this.width -= .5;
this.height -= .5;
this.x += .25;
this.y += .25;
sTrans.redOffset -= (256/10);
sTrans.blueOffset -= (256/10);
sTrans.greenOffset -= (256/10);
this.transform.colorTransform = sTrans;

}

private function resetTimers(e:Event):void {
//trace("this.x " + this.x + " this.y " + this.y + " this.width " + this.width + " this.height " + this.height);
flashT.reset();

}

}
}

soulwire
August 28th, 2007, 04:06 AM
Nice one Justin, glad you got it sorted ;)

soulwire
August 28th, 2007, 04:22 AM
Thanks motiveminds, interesting Actionscript 3.0 solution. :h:

Xannax
August 29th, 2007, 12:56 PM
I'm having the same issue, and i am unable to resolve it.

Here's my code, contained in Sqr.as:

package {
import flash.display.MovieClip; //importing the movieclip library; this is a requirement to be able to use MCs properties
import flash.display.BitmapData //importing bitmapData library; this is also a requirement
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
public class Sqr extends MovieClip{
public function Sqr(size:Number=175, bgColor:uint=0xFFCC00, borderColor:uint=0x666666, borderSize:uint=0, cornerRadius:uint=9,){
var child:Shape = new Shape();
child.graphics.beginFill(bgColor);
child.graphics.lineStyle(borderSize, borderColor);
child.graphics.drawRoundRect(0, 0, size, size, cornerRadius);
child.graphics.endFill();
addChild(child);
}
}//End of Sqr class
}//end of package definitionin my flash file, test.fla:

import Sqr;
var currSqr:Sqr = new Sqr();
trace(currSqr.width);I don't get any error, but nothing happens. Trace outputs what's expected ("175"). If I take the code out of the class and paste it in the flash file, it works; If I enter "Sqr" in the Document Class of my flash file, it also works.
What am I doing wrong? I don't want to use Sqr as document class, for one because I might need another class as document class, and also because I want to understand what I'm doing wrong. I'm new to Flash CS3 and AS3, and I feel a bit confused about all this.
Edit: of course, I tried removing the shape and using "this" as suggested, but it didn't work.

justinswartsel
August 29th, 2007, 01:00 PM
Try referencing "this" instead of your variable "child". Something like...
public function Sqr(size:Number=175, bgColor:uint=0xFFCC00, borderColor:uint=0x666666, borderSize:uint=0, cornerRadius:uint=9,){

this.graphics.beginFill(bgColor);
this.graphics.lineStyle(borderSize, borderColor);
this.graphics.drawRoundRect(0, 0, size, size, cornerRadius);
this.graphics.endFill();
}
}//End of Sqr class
}

Then when you add your Sqr instance to the stage, it will take on those properties. Originally, I was doing the same thing, but I think the problem has something to do with nested "addChild" methods. I don't know why it doesnt work, but when you addChild(Sqr) and then addChild() within Sqr, it gets finnicky.

Xannax
August 29th, 2007, 04:31 PM
Thank you for the suggestion, but it doesn't work. Wether it is referencing "this" or the shape object, it doesn't display anything. The only way I could get it to work was to write "addChild(currSqr)" in the flash file.
My code in the flash file is:


import Sqr;
var currSqr:Sqr = new Sqr();
addChild(currSqr);

Which means I have to addChild each instance of the class for the thing to work, which kind of renders the whole process of creating a class useless.
I don't know, it shouldn't be that hard to just create a shape class. I must be doing something wrong; surely, there's a way to render the shape without an external addChild?!
Maybe if I use another class? Sprite? or if I use the old method? like curveTo and stuff?
I don't know. I'm really confused about AS3, but i want to understand it.

cesig
August 29th, 2007, 04:45 PM
When you instantiate a MovieClip, nothing will show up until you add it to the Display list. It works the same way with subclasses of MovieClip.

In your case, you HAVE to add currSqr to the display list after you instantiate it. Otherwise it won't be displayed.

This is normal behavior in Flash.

Xannax
August 29th, 2007, 05:51 PM
Cesig: Ok I get it, but then there's no way to have this automated from inside the class? Because I'm building a big library of classes to use in a project with people that know nothing about coding. I wanted to attach classes to movieclips and let them design without paying any attention to scripting

cesig
August 29th, 2007, 06:35 PM
I'm building a big library of classes to use in a project with people that know nothing about coding. I wanted to attach classes to movieclips and let them design without paying any attention to scripting

Do you want them to be able to use assets from the library? Is that what you mean?

cesig
August 29th, 2007, 06:44 PM
Do you want them to be able to use assets from the library? Is that what you mean?

I bring this up because it's possible to do using the base class of library assets.

Right click on a library asset and select properties. You should see a place for "base class." This is the class type of this library asset. For you, put your custom class in here.

Then, when these non-coders want to use your classes, they can drag them to the stage and they'll have an instance, already attached to the display list at runtime.

If that makes sense.

Xannax
August 29th, 2007, 07:17 PM
If that makes sense.
Yes, it DOES!
Thank you!
Ok, in case someone ends up here after a search and doesn't want to read all the posts, I'm going to sum it up.

To display a dynamic-generated graphic:
1) create a package:


package {
2) import the relevant libraries:


import flash.display.MovieClip;
import flash.display.BitmapData
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
3) Create the class,and the constructor for it:


public class Sqr extends MovieClip{
public function Sqr(size:Number=175, bgColor:uint=0xFFCC00, borderColor:uint=0x666666, borderSize:uint=0, cornerRadius:uint=9){
this.graphics.beginFill(bgColor);
this.graphics.lineStyle(borderSize, borderColor);
this.graphics.drawRoundRect(0, 0, size, size, cornerRadius);
this.graphics.endFill();
}//end of constructor
}//end of class
}//end of package
4) save as Sqr.as
5) in a flash file, create a symbol (it can be empty if you want to)
6) Right-click on it in the library, click "advanced", and in "class", write Sqr
Don't add "as".

You're done!

Alternatives:
on the first frame in the flash stage:


import Sqr;
var currSqr:Sqr = new Sqr(100);
addChild(currSqr);
or
type "Sqr" in the document class file

Both work, but aren't as intuitive as having to just drop a symbol on the stage.

---------------------

Sorry, maybe this isn't the place for a quick tutorial but I'm thinking about my fellow non-coders colleagues who will want a quick answer to this questions.

Cesig, thanks again

edit: please, flash gurus, check and see if everything is alright. I'm planning to release my source code when I'm finished, so I'd like to check at each step of the way if everything is fine.

cesig
August 31st, 2007, 10:45 AM
Yes, it DOES!
Thank you!

Glad to help. Good luck with the designers!