views:

383

answers:

4

I'm trying to make a simple animation with Flash CS4 and Action Script 3.0 to make a number of Symbols fly by from right to left constantly. What I want is that once a symbol has reached the end of the screen it is destroyed and another one is placed at the start position.

I intend to give each symbol a random speed and create a random symbol each time one is 'destroyed'. Any clues where I can start?

A: 

Here's a few prompts to get you started.

MovieClips have an x and y property. If you were to add to these numbers over time you would see the MovieClip move along the x and/or y axis of the stage. Look into doing this using the Event.ENTER_FRAME which will allow you to change the values every time the screen is going to update.

Your stage will have a given width (a stageWidth property). You probably want to monitor when your MovieClip's x property is greater than the width of your stage. If it is remove (removeChild) it and add a new one (addChild) and place it back at the start x/y position.

James Hay
`stage.width` cannot be used to get the width of the stage. It exists but is not used for Stage objects. Use `stage.stageWidth` instead.
Cameron
I'm trying to apply Actionscript to one of my Graphic Symbols but it's telling me that 'The Current Selection cannot have actions applied to it'. Why is that?
William Calleja
@Cameron - fair shout. Amended
James Hay
@William Calleja - You can only add actions to MovieClips. try changing it to a MovieClip instance. That being said you'd be better putting all your code on the main time line and referencing your MovieClips through their instance name. I'd suggest doing some basic actionscript tutorials to figure out the basics first http://www.senocular.com/flash/tutorials/as3withflashcs3/
James Hay
@James Hay - Thanks mate! that's just what I needed.
William Calleja
A: 
  • Define a Circle (symbol) class that extends Sprite/Shape and has a velocity variable
  • Draw a circle (or whatever) with a random color
    Math.floor(Math.random() * 0xffffff)
  • Assign a random value to velocity
    minVelocity + Math.floor(Math.random() * velocityRange)
  • Create a start() method inside the Circle class that registers an enter frame handler
  • Increment this.y inside the enter frame handler, and dispatch a 'recycleMe' event if y is more than the max value.
  • Create N instances of Circle, addChild them, and call their start() methods.
  • listen to 'recycleMe' events on each of them, and reset the value of y from the handler.
Amarghosh
A: 

First, turn your symbols into MovieClips. Then create a base class MySymbol.as for your symbols, something like:

package {
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.geom.Point;


    public class MySymbol extends MovieClip
    {
        public var speed:Number;        // Pixels moved per frame


        public function MySymbol(speed:Number, startPosition:Point)
        {
            this.speed = speed;
            this.addEventListener(Event.ENTER_FRAME, update);

            this.x = startPosition.x;
            this.y = startPosition.y;
        }


        private function update():void
        {
            this.x -= this.speed;
            if (this.x < 0 - this.width) {      // We're at the left edge
                this.removeEventListener(Event.ENTER_FRAME, update);
                this.dispatchEvent(new Event(Event.COMPLETE));
            }
        }
    }
}

Then make sure your movie clips are exported for AS3 (the "linkage" option on the item in the library). Make the class name for each item unique (e.g. MySymbol1, MySymbol2), and set the base class to MySymbol.

Your document class might look something like this:

package {
    import flash.display.MovieClip;
    import flash.events.Event;
    import MySymbol;                // Not strictly needed

    public class DocumentClass extends flash.display.MovieClip
    {
        private static var SYMBOLS:Array = new Array(MySymbol1, MySymbol2);

        public function DocumentClass()
        {
            // Create five symbols:
            for (var i:int = 0; i < 5; i++) {
                makeSymbol();
            }
        }


        private function makeSymbol():void
        {
            // Pick a random symbol from the array:
            var symType:Class = SYMBOLS[Math.random() * SYMBOLS.length];

            // Construct the new symbol:
            var loc:Point = new Point(stage.stageWidth, Math.random() * stage.stageHeight);
            var sym:MySymbol = new symType(1 + Math.random() * 30, loc);

            // Listen for the object hitting the left edge:
            sym.addEventListener(Event.COMPLETE, remakeObject);
            this.addChild(sym);
        }


        private function remakeObject(e:Event):void
        {
            e.target.removeEventListener(Event.COMPLETE, remakeObject);
            this.removeChild(e.target);

            // Replace the dead symbol:
            makeSymbol();
        }
    }
}

It is a lot more efficient if instead of destroying and re-creating an object that flies off-stage you re-use the existing one and move it back to the right. But this is an optimization you can implement later, if things become slow.

Note that all the code above is UNTESTED and I have not coded AS3 in a while, so there's likely at least a few bugs in it. Hopefully it will serve as a good enough starting point.

Cameron
+1  A: 

As you seem new to flash as a platform I would think writing classes shouldn't be your first port of call when learning ActionScript. Definitely just play about on the timeline for now and learn the basics. As very simple solution to this, I would suggest creating a MovieClip in the library with a class name like 'MyBall'... then paste this onto the first frame of the main timeline et voila.

    // Create some variables to store data
var numberOfBalls : int = 20;
var myBalls : Array = [];
var xVelocities : Array = [];

var maxXVelocitySpeed : Number = 5;
var minXVelocitySpeed : Number = 2;

// Add your orginal balls to the stage
for (var i : int = 0; i < numberOfBalls; i++)
{
    var myBall : MyBall = new MyBall();
    myBall.x = -(Math.random() * stage.stageWidth);
    myBall.y = Math.random() * stage.stageHeight;

    var xVelocity : Number = minXVelocitySpeed + (Math.random() * (maxXVelocitySpeed - minXVelocitySpeed));

    myBalls.push(myBall);
    xVelocities.push(xVelocity);

    addChild(myBall);
}

// Add a listener for enter frame events
addEventListener(Event.ENTER_FRAME, enterFrameHandler);


//Run this code on every frame to move the balls and reposition them if they are off the stage
function enterFrameHandler(event : Event) : void
{
    for each( var myBall : MyBall in myBalls)
    {
        var ballIndex : int = myBalls.indexOf(myBall);

        myBall.x += xVelocity[ballIndex];

        if (myBall.x > stage.stageWidth)
        {
            myBall.x = -(Math.random() * stage.stageWidth);
            myBall.y = Math.random() * stage.stageHeight;
        }
    }
}
James Hay
Yep, much easier to understand than my example. I assumed the OP had experience with classes in other languages, but this may not be the case at all.
Cameron
@Cameron - Is fine. Good to have two different valid examples on the page anyway ;)
James Hay