Getting from getCharBoundaries to BitMapData - actionscript-3

I'm trying to convert all letters in a textfield to bitmap data. I then want to animate each of them. I'm able to return an array of rectangles using getCharBoundaries. But then how do I convert each letter to BitMapData?
package
{
import flash.display.Sprite;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
public class LetterBitmapData extends Sprite
{
private var tf:TextField;
private var letterSprite:Sprite;
public function LetterBitmapData()
{
makeTF();
getRectangles();
};
private function makeTF():void
{
tf = new TextField();
tf.width = 400;
tf.height = 100;
tf.selectable = false;
tf.multiline = true;
tf.wordWrap = true;
tf.text = "Now is the winter of our discontent made glorious summer by this sun of York.";
tf.setTextFormat(new TextFormat("_sans", 16, 0));
addChild(tf);
}
private function getRectangles():Array
{
var result:Array = [];
var rectangle:Rectangle;
for (var i:int = 0; i < tf.text.length; i++)
{
rectangle = tf.getCharBoundaries(i);
result.push(rectangle); //create an array of CharBoundary rectangles
//trace("RECTANGLE x: " + rectangle.x + " y: " + rectangle.y + " width: " + rectangle.width + " height: " + rectangle.height );
}
return result;
}
}
}

You could animate your letters without turning them into Bitmaps as long as you're using embed fonts that is...
Instead of creating an array of rectangles, you could create an array of TextFields , associated to their specific rectangle in order to keep the coordinates of each letter. After that it should be possible to animate each TextField.

Related

Access of undefined propety and other errors (AS3)

ok so I am trying to work on making my scripts external .as files.
I had them on the timeline and they worked fine but when I put them in the as file they don't work at all.
This is my code as of right now
so I got the script working externally thank you very much :)
I just need to addchild to the stage. I use
import Scripts.resources.main;
var Main:main = new main;
addChild(Main);
In my external script I addchild in the main function now.
package Scripts.resources
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLLoader;
import flash.net.URLRequestMethod;
import flash.events.OutputProgressEvent;
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.EventDispatcher;
public class main extends EventDispatcher{
private var _stage:Stage;
var url:String = "php/data_user.php";
//declare our graphic vars
var stmBar:resourceBar;
var tenBar:resourceBar;
var potBar:resourceBar;
var spdBar:resourceBar;
var crtBar:resourceBar;
var awrBar:resourceBar;
var resBar:resourceBar;
var statUp:Sprite;
//This Returns the number of milliseconds since midnight January 1, 1970
//Tacking the time variable at the end of your php file locations will ensure their is no caching
var now:Date = new Date();
var time:Number = now.getTime();
/*
* These should point to your PHP files. I recommend NOT using an http path because accessing
* the site via 'www.yoursite.com' versus 'yoursite.com' makes a difference and will cause undefined
* issues. Instead use a relative path like: var registerLocation:String = "membership/php/register.php";
*/
var registerLocation:String = "php/register.php" + "?" + time;
var loginLocation:String = "php/login.php" + "?" + time;
var editProfileLocation:String = "php/editprofile.php" + "?" + time;
var forgotPWLocation:String = "php/forgotpw.php" + "?" + time;
var statsLocation:String = "php/user_stats.php" + "?" + time;
var statsGylph:String = "php/data_user.php" + "?" + time;
//userInfo is the Object that gets populated that stores all of the users information.
var userInfo:Object = new Object();
//The minimum length of a password.
var passwordLength:Number = 4;
/*
* var cookie refers to swfObjects addVariable. If you look at membership.php, where swf
* object is defined, addVariable shows a var called usercookie.
* This help decide if the program should remember the users username or not.
*/
//cookieUserName would be the username that gets put into the user field if the cookie has been set
public function main(stage:Stage)
{
_stage = stage;
var _loader:URLLoader = new URLLoader();
var _request:URLRequest = new URLRequest(url + "?id=" + userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
_stage.addChild(stmBar);
stmBar.x = -50;
stmBar.y = 200;
}
public function MyClass(){
this.addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
private function addedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
//this code will run after you've added this object to the stage
//it is the equivalent of when timeline code runs
}
function onLoadData(e:Event):void {
var str:String = e.target.data;
var array:Array =str.split("-");
for(var i:int;i < array.length; i++)
output(i+1,array[i]);
}
public function output(field:Number,i:int):void
{
if (field == 5)
{
stmBar = new resourceBar(0, 0, i, "Stamina", 0x990000);
stmBar.x = -200;
stmBar.y = 50;
}
else if (field == 6)
{
tenBar = new resourceBar(0, 0, i, "Tenacity", 0xFF9900);
tenBar.x = 200;
tenBar.y = 50;
}
else if (field == 7)
{
potBar = new resourceBar(0, 0, i, "Potency", 0xCC3399);
potBar.x = -200;
potBar.y = 100;
}
else if (field == 8)
{
spdBar = new resourceBar(0, 0, i, "Speed", 0x00CC00);
spdBar.x = 200;
spdBar.y = 100;
}
else if (field == 9)
{
crtBar = new resourceBar(0, 0, i, "Crit", 0x009999);
crtBar.x = -200;
crtBar.y = 150;
}
else if (field == 10)
{
awrBar = new resourceBar(0, 0, i, "Awareness", 0x3399CC);
awrBar.x = 200;
awrBar.y = 150;
}
else if (field == 11)
{
resBar = new resourceBar(0, 0, i, "Resistance", 0x999999);
resBar.x = -200;
resBar.y = 200;
addEventListener(Event.ENTER_FRAME, onLoop);
}
function onLoop(e:Event):void
{
stmBar.change(1);
tenBar.change(1);
potBar.change(1);
spdBar.change(1);
crtBar.change(1);
awrBar.change(1);
resBar.change(1);
}
}
}
}
my problem is it won't add the children in the main function when I addchild of main. am I able to add a child with children inside it?
In class files, all code needs to be wrapped in a function. So where you have:
_loader = new URLLoader();
_request = new URLRequest(url + "?id=" + (STAGE.parent as MovieClip).userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
You need to place it in a function for the code to be valid. If you want that bit of code to run right away, then you can place it in a constructor (that is the function in class that runs when you instantiate with the new keyword, eg new main(). If main is your document class, then the constructor is the very first code to run in the application.
Constructors are public functions that have the exact name of your Class.
public function main(){
_loader = new URLLoader();
_request = new URLRequest(url + "?id=" + (STAGE.parent as MovieClip).userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
}
Something to keep in mind, is that in the constructor of display objects, the stage/parent/root keywords will NOT have any value, as those are populated once the display object has been added to the display. So, it's common to use this approach:
package MyClass extends Sprite {
public function MyClass(){
this.addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
private function addedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
//this code will run after you've added this object to the stage
//it is the equivalent of when timeline code runs
}
}
Also, a tip now that you are writing class files - follow the convention of making class names start with an Uppercase letter, and instances of classes start with lowercase letters.

ActionScript - how to put 10 different dishes (loaders) in a random sequence?

Hello im with a doubt and need your help if its possible.
I have a class dish and i load 1 file ".swf", and i have a little game that works like this:
The dish moves in the x and y axis and i when i click in the dish it falls down.
But i want to have not only 1 dish i want have 10 different dishes with diferent images.
And i want that they appear in a random sequence.
But i dont have ideia how i cant do that...someone can give me "light"?
I use this variables to load my dish to the stage in my game project.
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest("dish.swf");
Here's an example of what you could do to get a random dish each time :
// whenever you need to create a new dish
var dishFilenames:Array = ['dish1.swf', 'dish2.swf', 'dish3.swf']; // etc etc
var randomIndex:int = Math.random() * dishFilenames.length;
var filename:String = dishFilenames[randomIndex];
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest(filename);
thank for the answer!
so i cant have all the dishes in the same "swf"?
I need to create swf as many as i need?
My class dish is like this until now:
I dont have other way to do that?(with only a swf that contains all the dishes)
package {
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.MouseEvent;
public class Dishe {
var velX: int;
var velY: int ;
var game:Game; //i have also a class game to control everyting
var broken_dish:URLRequest = new URLRequest("broken_dish.swf");
var gravity:int = 2;
var dishFilenames:Array = [ 'dish.swf','second_dish.swf'];
var randomIndex:int = Math.random() * dishFilenames.length;
var filename:String = dishFilenames[randomIndex];
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest(filename);
public function Dishe(e:Game, vX:int, vY:int)
{
velX = vX;
velY = vY;
load_dish.x = -180;
load_dish.y = randomBetween(250,-5);
load_dish.load(caminho);
game = e;
game.myStage.addChild(load_dishe);
load_dish.addEventListener(MouseEvent.CLICK, _shoot);
}
public function broken_dish(e:Event)
{
velY += gravity;
load_dish.y +=velY ;
if(load_dish.y >= game.myStage.stageHeight)
{
game.game_states(Game.state_playing);
}
}
public function _enterFrame(e:Event):void
{
if(load_dish.content!=null)
{
load_dish.x += velX;
load_dish.y += velY *(1 - (load_dish.x / game.myStage.stageWidth) * 2 );
if(load_dish.x > game.myStage.stageWidth)
{
load_dish.y = randomBetween(250,-5);
load_dish.x = -180;
}
}
}
public function _shoot(e:MouseEvent):void
{
trace("nice!!");
game.game_states(Game.state_stop);
load_dishe.load(broken_dish);
}
function randomBetween(a:int, b:int) : int {
return a + int(Math.round( (b-a)*Math.random() ));
}
}
}

Nape Physics ShapeDebug seems to be scaled

i have a strange problem with a simple nape demo... here's my code
package com.secretpackage {
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import nape.phys.Body;
import nape.shape.Circle;
import nape.space.Space;
import nape.util.ShapeDebug;
import nape.geom.Vec2;
import nape.phys.BodyType;
import nape.phys.Material;
public class Main extends Sprite {
// -------
private var world_db:Space=new Space(new Vec2(0,1000));
private var debug:ShapeDebug;
private var napeDebugSprite:Sprite = new Sprite();
private var sphere:Body;
private var labels:TextField;
// -------
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
debug = new ShapeDebug(stage.stageWidth, stage.stageHeight, stage.color);
labels = new TextField();
var posX:int = stage.stageWidth/4;
var posY:int = stage.stageHeight/4;
var r:int = 10;
sphere= new Body(BodyType.KINEMATIC, new Vec2(posX, posY));
sphere.shapes.add(new Circle(r, new Vec2(posX, posY), Material.rubber()));
sphere.space = world_db;
labels.x = 0;
labels.y = 0;
addChild(labels);
var tc:test_circle = new test_circle();
addChild(tc);
tc.x = stage.stageWidth / 2;
tc.y = stage.stageHeight / 2;
addChild(napeDebugSprite);
debug.drawConstraints=true;
napeDebugSprite.addChild(debug.display);
addEventListener(Event.ENTER_FRAME, update);
}
private function update(e:Event):void {
world_db.step(1/stage.frameRate, 10, 10);
debug.clear();
debug.draw(world_db);
debug.flush();
labels.text = sphere.position.x + " - " + sphere.position.y +
"\n" + stage.stageWidth + " - " + stage.stageHeight +
"\n" + napeDebugSprite.width + " - " + napeDebugSprite.height +
"\n" + debug.display.width + " - " + debug.display.height;
}
}
}
Plese note:
- sphere is a Circle with radius=10 placed at StageWidth/4 and StageHeight/4;
- test_circle is a Movieclip of a circle with radius=10 placed at StageWidth/2 and StageHeight/2;
When i compile this script i get ... http://i.imgur.com/MAYF3j9.png?1
The two circles are centered and sphere has a doubled radius.
Am i doing something wrong?
Thank you.
You set up the Body to have position (stageWidth/4, stageHeight/4), you then added a Circle shape, whose local offset is also (stageWidth/4, stageHeight/4), so when the body is un-rotated the circle will end up being at (stageWidth/2, stageHeight/2).
As to the graphical size difference, I can only assume that your graphic is not actually 'radius 10' but 'width/height 10' which is half the width/height of a radius 10 circle (whose width/height is 20)
A temporary solution is to scale debug:ShapeDebug, so code becomes...
....
addChild(napeDebugSprite);
debug.drawConstraints=true;
//Scaling
debug.display.scaleY = 0.5;
debug.display.scaleX = 0.5;
napeDebugSprite.addChild(debug.display);
....
This fixes the problem, but it is just a workaround.

How do i pass String from Php to VO file to another .as file in AS3?

Hi I am pretty new to AS3, i am trying to parse some data from php to a VO file, and then transfer the string of data into another .as file where it will put the data into boxes. I am stuck in how do i parse the data from the VO file into the other .as File(Pulling the data from php into BookVO, then parsing BookVO to VectorTest). I tried tracing the data in BookVO, it works ok, but i can't get the data from BookVO to VectorTest.
Please help, thanks
BookVO.as
package com.clark
{
import flash.display.*;
import flash.net.*;
import flash.events.*;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLLoaderDataFormat;
import flash.net.URLVariables;
public class BookVO
{
public var nobed1:String;
public var LoZip1:String;
public var rangelow1:String;
public var rangehigh1:String;
public var Bend:URLRequest;
public var variabless:URLVariables;
public var nLoader:URLLoader;
public function BookVO() {
Bend = new URLRequest("http://localhost/Autoresult.php");
Bend.method = URLRequestMethod.POST;
variabless = new URLVariables();
Bend.data = variabless;
nLoader = new URLLoader();
nLoader.dataFormat = URLLoaderDataFormat.TEXT;
nLoader.addEventListener(Event.COMPLETE,Jandler);
nLoader.load(Bend);
// handler for the PHP script completion and return of status
function Jandler(event:Event) {
var responseVariables: URLVariables = new URLVariables(event.target.data);
this.nobed1 = responseVariables.nobed1 ;
this.LoZip1 = responseVariables.LoZip1;
this.rangelow1 = responseVariables.rangelow1;
this.rangehigh1 = responseVariables.rangehigh1;
}
}
}
}
VectorTest.as
package com.clark
{
import flash.display.MovieClip;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.display.Sprite;
public class VectorTest extends MovieClip
{
public function VectorTest()
{
super();
var books:Vector.<BookVO> = new Vector.<BookVO>();
for (var i:int = 0; i < length; i++)
{
var book:BookVO = new BookVO();
book.nobed1 = "nobed1";
book.LoZip1 ="LoZip1";
book.rangelow1 = "rangelow1";
book.rangehigh1 ="rangehigh1";
books.push(book);
}
for (var j:int = 0; j < books.length; j++)
{
trace("Test", j, "has a name of", books[j].nobed1);
trace("Test", j, "Zip", books[j].LoZip1);
trace("Test", j, "ranglow", books[j].rangelow1);
trace("Test", j, "rangehigh", books[j].rangehigh1);
books[j].nobed1;
books[j].LoZip1;
books[j].rangelow1;
books[j].rangehigh1;
}
var currentY:int = 270;
for (var k:int = 0; k < books.length; k++)
{
var Bolder:Listing2 = new Listing2();
Bolder.x=80;
var tf:TextField = new TextField();
var tf1:TextField = new TextField();
tf1.width = 100;
var tf2:TextField = new TextField();
tf2.width = 100;
tf.defaultTextFormat = new TextFormat("Arial", 12, 0, null, null, null, null, null, TextFormatAlign.CENTER);
tf.width = 100;
tf.autoSize = TextFieldAutoSize.CENTER;
tf1.width = 100;
tf1.autoSize = TextFieldAutoSize.CENTER;
tf2.autoSize = TextFieldAutoSize.CENTER;
tf2.width = 100;
tf1.y= tf.height+5;
// Pulling the textfields content out from the current bookVO
tf2.text = books[k].nobed1;
tf1.text = books[k].rangelow1;
tf.text = books[k].rangehigh1;
tf1.x = (Bolder.height-tf.height)*.5
tf2.x = (Bolder.height-tf.height)*.5
tf.x = (Bolder.height-tf.height)*.5
tf.y = (Bolder.height-tf.height)*.15
Bolder.addChild(tf);
Bolder.addChild(tf1);
Bolder.addChild(tf2);
// position the object based on the accumulating variable.
Bolder.y = currentY;
addChild(Bolder);
currentY += Bolder.height + 35;
}
}
}
}
First off, good job on your classes. Much better than most people who say they're new to AS3. ;)
That said...
In VectorTest, you're calling super() on a MovieClip. You don't need this.
If you're not using the timeline of a MovieClip (which, I'd recommend not using anyway), extend Sprite instead; it's lightweight as it doesn't carry the timeline baggage MovieClip does.
Your first for loop in VectorTest Constructor loops to length... of no array.
You're overwriting the properties of BookVO in that loop, which should be populated by your URLLoader. This is superfluous.
Your second loop references the 4 properties of BookVO, neither reporting or setting the variables (ie., books[j].nobed1;). Might want to remove that.
In BookVO, you've written a nested function. Unless you're dealing with a massive number of variables and have issues with variable scope, don't do it. As it stands, the only variables Jandler() is accessing are already Class level globals.
Loading data is an asynchronous operation, meaning, data doesn't populate instantly (LoadRequest > Wait > ProgressEvent > Wait > LoadComplete). Because you're both instantiating BookVO and reading the properties in the same function, all you'll get are null properties. Unlike the VectorTest constructor, because Jandler() is called on Event.COMPLETE (asynchronously), it will have access to the variables you're looking for.
Try this instead...
You'll still need to address the length of how many books you want to instantiate, however, I've split out your reading of the properties from the constructor, and added a reference to the method to call when the loading is complete.
It will print out all the variables, and if it is the last book in your Vector, it'll call finish() which... um... does the rest of what you were doing. :)
-Cheers
BookVO Updated 2013.11.07 # 12:30 AM
package com.clark{
import flash.display.*;
import flash.net.*;
import flash.events.*;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLLoaderDataFormat;
import flash.net.URLVariables;
public class BookVO {
public var nobed1:String;
public var LoZip1:String;
public var rangelow1:String;
public var rangehigh1:String;
public var Bend:URLRequest;
public var variabless:URLVariables;
public var nLoader:URLLoader;
private var callMethod:Function;
public var data:Object;
public function BookVO(listener:Function = null) {
Bend = new URLRequest("http://localhost/Autoresult.php");
Bend.method = URLRequestMethod.POST;
variabless = new URLVariables();
Bend.data = variabless;
nLoader = new URLLoader();
nLoader.dataFormat = URLLoaderDataFormat.TEXT;
nLoader.addEventListener(Event.COMPLETE,Jandler);
nLoader.load(Bend);
if (listener != null) {
callMethod = listener;
}
}
public function Jandler(event:Event) {
// handler for the PHP script completion and return of status
var responseVariables:URLVariables = new URLVariables(event.target.data);
data = event.target.data;
report(data);
if (callMethod != null) {
callMethod(this);
}
}
private function report(obj:*, prefix:String = ""):void {
for (var k in obj) {
var type:String = getType(obj[k]);
if (type == "Array" || type == "Object" || type == "Vector") {
trace(prefix + k + ": (" + type + ") ¬")
report(obj[k], prefix + " ")
} else {
trace(prefix + k + ":" + obj[k] + " (" + type + ")")
}
}
}
private function getType(value:*):String {
// Returns the class name of object passed to it.
var msg:String = flash.utils.getQualifiedClassName(value);
if (msg.lastIndexOf("::") != -1) {msg = msg.split("::")[1];}
return msg;
}
}
}
VectorTest
package com.clark {
import flash.display.MovieClip;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.display.Sprite;
public class VectorTest extends MovieClip {
public var books:Vector.<BookVO>;
public function VectorTest() {
books = new Vector.<BookVO>();
for (var i:int = 0; i < length; i++) {
var book:BookVO = new BookVO(response);
books.push(book);
}
}
private function response(book:BookVO):void {
trace("Name: ", book.nobed1);
trace("Zip: ", book.LoZip1);
trace("ranglow: ", book.rangelow1);
trace("rangehigh: ", book.rangehigh1);
// call finish() if this is the last book.
if (books.indexOf(book) == books.length - 1) {
finish();
}
}
private function finish():void {
var currentY:int = 270;
for (var k:int = 0; k < books.length; k++) {
var Bolder:Listing2 = new Listing2();
Bolder.x=80;
var tf:TextField = new TextField();
var tf1:TextField = new TextField();
tf1.width = 100;
var tf2:TextField = new TextField();
tf2.width = 100;
tf.defaultTextFormat = new TextFormat("Arial", 12, 0, null, null, null, null, null, TextFormatAlign.CENTER);
tf.width = 100;
tf.autoSize = TextFieldAutoSize.CENTER;
tf1.width = 100;
tf1.autoSize = TextFieldAutoSize.CENTER;
tf2.autoSize = TextFieldAutoSize.CENTER;
tf2.width = 100;
tf1.y = tf.height+5;
// Pulling the textfields content out from the current bookVO
tf2.text = books[k].nobed1;
tf1.text = books[k].rangelow1;
tf.text = books[k].rangehigh1;
tf1.x = (Bolder.height-tf.height)*.5
tf2.x = (Bolder.height-tf.height)*.5
tf.x = (Bolder.height-tf.height)*.5
tf.y = (Bolder.height-tf.height)*.15
Bolder.addChild(tf);
Bolder.addChild(tf1);
Bolder.addChild(tf2);
// position the object based on the accumulating variable.
Bolder.y = currentY;
addChild(Bolder);
currentY += Bolder.height + 35;
}
}
}
}

Creating 10 circles in ActionScript 3

Iam trying to create a simple method in AS3 that adds 10 circles, each 30px in diameter in a column down the left-hand-side of the stage, so the first appears in the top-left corner and the last in the bottom-right. I would appreciate any help here. Thanks.
My current code follows: - It currently just returns 10 circles with no positioning.
package
{
import flash.display.*;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Circles extends MovieClip
{
private var timer:Timer = new Timer(100, 10);
public function Circles()
{
timer.addEventListener(TimerEvent.TIMER, createCircles);
timer.start();
}
private function createCircles(e:TimerEvent):void
{
var bcircle:MovieClip = new MovieClip();
var xpos:int = 0;
var ypos:int = 0;
bcircle.graphics.beginFill(0x0033CC);
bcircle.graphics.drawCircle(xpos,ypos,15);
bcircle.graphics.endFill();
bcircle.x = Math.random() * stage.stageWidth;
bcircle.y = Math.random() * stage.stageHeight;
addChild(bcircle);
}
}
}
bcircle.x = Math.random() * stage.stageWidth;
bcircle.y = Math.random() * stage.stageHeight;
These are the lines you want to be paying attention to as these lines control where each circle is placed when added to the stage.
Circle diameter = 30px, stage height (for example) = 400px.
30 goes into 400 13.33 times (400/30) so each circle needs to be spaced 13.3px further down than the last.
You can store a variable that counts how many circles are already on the stage and use it to multiply 13.3 to find the appropriate y value:
var i:int = 0;
private function createCircles(e:TimerEvent):void
{
var bcircle:MovieClip = new MovieClip();
var xpos:int = 0;
var ypos:int = 0;
bcircle.graphics.beginFill(0x0033CC);
bcircle.graphics.drawCircle(xpos,ypos,15);
bcircle.graphics.endFill();
bcircle.x = 0;
bcircle.y = (30 + 13.3) * i; // First circle placed at 0, Second placed at 43.3...
i++; // Increment i each time function is called
addChild(bcircle);
}
You can apply a similar method to then increment the x position of each circle once i reaches 10 (10 circles have been placed), use a trigger to detect this: if(i == 10)
This might help ...
package {
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Circles extends Sprite {
private const _circles:Array = []; // reusable container
private var _timer:Timer;
public function Circles() {
_timer = new Timer(1000, 10);
_timer.addEventListener(TimerEvent.TIMER, timer_timerHandler);
_timer.addEventListener(TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler);
_timer.start();
}
private function createCircle():Sprite {
const sprite:Sprite = new Sprite();
drawCircleInGraphics(sprite.graphics);
addChild(sprite);
return sprite;
}
private function drawCircleInGraphics(graphics:Graphics, color:uint = 0x0033CC, radius:uint = 15):void {
graphics.beginFill(color);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
private function createNewCircleAndPositionIt():void {
_circles[_circles.length] = createCircle();
if (_circles.length > 1) {
const last:Sprite = _circles[_circles.length - 1],
predecessor:Sprite = _circles[_circles.length - 2];
last.x = predecessor.x + 30;
last.y = predecessor.y + 30;
}
}
private function timer_timerHandler(event:TimerEvent):void {
createNewCircleAndPositionIt();
}
private function timer_timerCompleteHandler(event:TimerEvent):void {
_timer.removeEventListener(TimerEvent.TIMER, timer_timerHandler);
_timer.removeEventListener(TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler);
_timer = null;
}
}
}