Lesson: Responsive Circle

  • create a new as3 flash (.fla) file
  • create a new as3 (.as) file
    • this file should be saved in the same folder as the .fla file, ideally with the same name. it is common to capitalize the first letter of the file name
  • link the as3 file to the root of the movie
    • under the properties of the root movie, under class enter the name of the file (without the extension
    • test the link by clicking on the pen icon adjacent to the class text input
  • extend the class file
    • you do this by adding extends MovieClip to the end of the name of the class, and adding the corresponding import statement. This tells the compiler that the class is built on the movieclip class (which is what the root of the movie is)

package {

import flash.display.MovieClip;

public class InClass extends MovieClip

{

//default constructor function

public function InClass ():void { }

}//class InClass


}

  • add a test to the pre-made constructor

//default constructor function

public function InClass ():void

{

trace(“file started up”);

}

  • run the flash file, verify the constructor is firing
  • create a new as3 (.as) file, lets call this something like ResponsiveCircle.as
  • define the new class to be an extension of the sprite class
    • add the import statements as we will need these later on
    • the sprite class is a simple graphic object which doesnt have a timeline like a movieclip


package {

 

import flash.display.Sprite;

import flash.events.Event;

import flash.display.Shape;

 

public class ResponsiveCircle extends Sprite

{

 

public function ResponsiveCircle():void {

}

}

  • add a test to the constructor

public function ResponsiveCircle():void {

trace(“you just made a new responsive circle”);

}

 

  • in the root class file constructor add some code to test the instantiation of the new class, dont forget to import the new class file


import flash.display.MovieClip;

import ResponsiveCircle;

 

//default constructor function

public function InClass ():void

{

trace(“file started up”);

circle = new ResponsiveCircle(); //instantiating our custom class

}

 

  • run the flash file and verify that a new object is being made

in the circle class, create a variable to store the shape we are going to draw in this object

public class ResponsiveCircle extends Sprite {

//circle shape

private var sphere:Shape = new Shape();

  • add the shape to the rendering pipeline

public function ResponsiveCircle():void {

trace(“you just made a new responsive circle”);

//add sphere to the root of this class

this.addChild(sphere);

  • add a variable to the circle class to define the radius of the circle

//circle shape

private var sphere:Shape = new Shape();

//startup radius

public var sphereRadius:Number = 50;

  • create a new function in the circle class to perform the drawing

public function myDraw() {

//draw the circle

sphere.graphics.clear();

sphere.graphics.beginFill(255);

sphere.graphics.drawCircle(0,0,sphereRadius);

}

call the draw function from the constructor

public function ResponsiveCircle():void {

trace(“you just made a new responsive circle”);

//add sphere to the root of this class

this.addChild(sphere);

myDraw();

 

  • run the flash file and verify that the circle is drawn, is it drawn?
    • you’ve add the sphere to the circle object, but we haven’t yet added the circle to rendering pipeline of the root movie
  • in the root class file, add the circle to the rendering pipeline

//default constructor function

public function InClass ():void

{

trace(“file started up”);

circle = new ResponsiveCircle(); //instantiating our custom class

//place it on the screen

this.addChild(circle);

}

  • run the flash file and verify that the circle is drawn, is it drawn?
    • the circle is drawn, but only on the first frame following the call of the constructor. So we need to get it to be called every frame
  • add an event listener to the constructor of the circle class to fire a function every frame

public function ResponsiveCircle():void {

trace(“you just made a new responsive circle”);

//add sphere to the root of this class

this.addChild(sphere);

//create x fps loop

this.addEventListener(Event.ENTER_FRAME, myDraw);

}

  • to avoid an error you will need to add an event argument to the my draw function

public function myDraw(e:Event) {

  • run the flash file and verify that the circle is drawn, is it drawn?
  • now let’s make more
  • make a new function in the root class to make a grid of circles

public function makeSquareGrid(num:int) {

//pointer to a circle object

var circle:ResponsiveCircle;

//variables defining position
var xLoc:int;

var yLoc:int;

}

  • create a for loop which will iterate based on the passed argument

public function makeSquareGrid(num:int) {

//pointer to a circle object

var circle:ResponsiveCircle;

//variables defining position
var xLoc:int = 100;

var yLoc:int = 100;

//loop num times

for(var j:int = 0; j< num; j++) {

}

}

  • in the for loop instantiate a circle object and define its location, how many do you see?

for(var j:int = 0; i < num; j++) {

//make a new circle and store a reference to it in the variable (pointer)

circle = new ResponsiveCircle(); //instantiating our custom class


//set the x+y of the circle

circle.x = xLoc;

circle.y = yLoc;


//place it on the screen

this.addChild(circle);

}

  • change the position based on the loop index, how many do you see?

//set the x+y of the circle

circle.x = j*xLoc;

circle.y = j*yLoc;

  • is it a grid? how do you make a grid?
  • put the for loop inside a new for loop

//loop through num*num times

for(var i:int = 0; i < num; i++) {

for(var j:int = 0; j<num; j++) {

//make a new circle

circle = new ResponsiveCircle(); //instantiating our custom class

//set the x+y of the circle

circle.x = j*xLoc;

circle.y = j*yLoc;

//place it on the screen

this.addChild(circle);

}

}

  • adjust the position to be influenced by the new for loop index
    • youll have to add some variables in the class, outside function to be used in the grid, and then

//variables defining position
var xLoc:int = 100;

var yLoc:int = 100;

var spacing:int = 100;

var xStart:int = 50;

var yStart:int = 50;

 

//loop through num*num times

for(var i:int = 0; i < num; i++) {

for(var j:int = 0; j<num; j++) {

//calc grid spacing

xLoc = i*spacing + xStart;

yLoc = j*spacing + yStart;


//make a new circle

circle = new ResponsiveCircle(); //instantiating our custom class

//set the x+y of the circle

circle.x = j*xLoc;

circle.y = j*yLoc;

//place it on the screen

this.addChild(circle);

}

}

  • test the grid production
  • lets add some responsiveness to the circle, in the circle class
  • make a new function called respond

public function respond(event:Event):void { }

  • add a call to draw in the respond function

public function respond(event:Event):void {

myDraw();

}

  • you will need to remove the event argument from the myDraw function again

public function myDraw() {

  • alter the listener to point to the respond function instead of draw

this.addEventListener(Event.ENTER_FRAME, respond);

  • test everything still works
  • add some parameters to the circle to control it’s interactive conditions

//values to clamp to

public var smallRadius:Number = 10;

public var largeRadius:Number = 100;

//startup radius

public var sphereRadius:Number = 50;

//circle shape

private var sphere:Shape = new Shape();

  • use the respond function to alter the parameters, can you find a way to alter the sphereRadius variable? what about incrementing (sphereRadius++) or decrementing (–). Can you use an if statement with the small/large radius variables as conditionals to make the circle throb?
  • how about connecting the parameters to the mouse
    • this will require you to create and use another custom function, called clamp

//get the distance of the mouse to the object

var distToMouseX:Number = clamp(Math.abs(this.mouseX),smallRadius,largeRadius);

var distToMouseY:Number = clamp(Math.abs(this.mouseY),smallRadius,largeRadius);

var dist:Number = Math.max(distToMouseX,distToMouseY);

//compute the radius

sphereRadius = largeRadius + smallRadius – dist;

add this function, inside the class outside the respond function

//utility function to clamp “val” to a particular range

private function clamp(val:Number, min:Number, max:Number) {

return Math.max(min,Math.min(max,val));

}

 

  • test the file again, the circles should be independently responding to the position of the mouse
  • in the root class file create a new variable, an array

 

public class InClass extends MovieClip {

//data members

public var circles; //declare the array

  • in the constructor instantiate the array

//default constructor function

public function InClass ():void {

trace(“file started up”);

circles = new Array(); //instantiate the array

makeSquareGrid(4);

  • by storing references to the circles we make in the makesquaregrid, we can reference them later on, from the root/outside the circle class. To do this we will need to add an index variable that we can increment inside the loops, as a series num*num times, as well as an assignment of the pointer to the array

/ //variables defining position
var xLoc:int = 100;

var yLoc:int = 100;

var spacing:int = 100;

var xStart:int = 50;

var yStart:int = 50;

var idx:int = 0;

 

//place it on the screen

this.addChild(circle);

//store the object in the array

circles[idx++] = circle;

  • to test this remote access with the array, make a new function in the root class to modifiy the transparency

public function setTransparency() {

//determine a factor of transparency based on the number of elements in the

array, aka length

var factor:Number = 1/circles.length;

trace(“factor:” + factor); //for debug

//loop through each of the array elements and adjust properties

for (var i:int=0; i<circles.length; i++) {

circles[i].alpha = i*factor;

trace(“alpha:” + (i*factor))

}

}

  • add a call to this new function in the constructor of the root class, after the make grid (you need to make objects, before you can access them)

public function InClass ():void {

trace(“file started up”);

circles = new Array(); //instantiate the array

makeSquareGrid(4);

setTransparency();

}

  • you have now successfully immersed yourself in the world of object oriented programming using action script 3. Explore the possibilities of this simple system experimenting with changes to key parameters.

Leave a comment