Looping Error when doing a hitTest in as3 - actionscript-3

So, I have this code:
public function hitTest1(e:Event) : void
{
if (hitTestObject(target.hit)){
gotoAndStop(2,"Scene 1");
removeEventListener(Event.ENTER_FRAME, hitTest1);
}
}
In which target is the object that is going to be hit, and hit is a symbol in a layer over said object. When I run the code I get this error over an over again.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.Mass.basics1::Asteroid/hitTest1()
NOTE: Asteroid is the .as file that contains all of this code.
Here is the rest of the code for reference :
package com.Mass.basics1
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class Asteroid extends MovieClip
{
public var target:Cosmo;
private var stageRef:Stage;
private var speed:Number;
// public var ourAsteroid:Asteroid = new Asteroid(stage);
public function Asteroid(stageRef:Stage)
{
this.stageRef = stageRef;
setupAsteroid(true);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
addEventListener(Event.ENTER_FRAME, hitTest1);
}
public function hitTest1(e:Event):void
{
if (hitTestObject(target.hit))
{
gotoAndStop(2,"Scene 1");
removeEventListener(Event.ENTER_FRAME, hitTest1);
}
}
public function setupAsteroid(randomizeY:Boolean = false):void
{
//inline conditional, looks complicated but it's not.
y = randomizeY ? Math.random() * stageRef.stageHeight:0;
x = Math.random() * stageRef.stageWidth;
rotation = Math.random() * 360;
scaleX = Math.random();
scaleY = scaleX;
speed = 20 + Math.random() * 10;
}
public function loop(e:Event):void
{
y += speed;
if (y > stageRef.stageHeight)
{
setupAsteroid();
}
}
}
}

So, where is the "target" object? You're just declaring a variable, but not creating the object or setting a reference. It's a public variable, so maybe you are setting a reference somewhere else? In that case, make sure you assign a reference before you are calling hitTest1 function...

Related

How can I solve this error in Flash game?

I have a problem in Flash puzzle game. If I create the game in the first frame of my timeline it's working, but if the game has been created (for example) in 5th frame it does'nt work!
It send me this error:
TypeError: Error #1009: Cannot access a property or method of a null
object reference.
at Map() TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at DragDrop/drop()
dragdrop class
package
{
import flash.display.*;
import flash.events.*;
public class DragDrop extends Sprite
{
var origX:Number;
var origY:Number;
var target:DisplayObject ;
public function DragDrop()
{
// constructor code
origX = x;
origY = y;
addEventListener(MouseEvent.MOUSE_DOWN, drag);
buttonMode = true;
}
function drag(evt:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, drop);
startDrag();
parent.addChild(this);
}
function drop(evt:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, drop);
stopDrag();
if(hitTestObject(target))
{
visible = false;
target.alpha = 1;
Object(parent).match();
}
x = origX;
y = origY;
}
}
}
I think the problem is in var target! and I don't know how to solve it.
Map.as
enter code here package
{
import flash.display.*;
import flash.events.*;
public class Map extends MovieClip
{
var dragdrops:Array;
public function Map()
{
// constructor code
dragdrops = [tt1];
var currentObject:DragDrop;
for(var i:uint = 0; i < dragdrops.length; i++)
{
currentObject = dragdrops[i];
currentObject.target = getChildByName(currentObject.name + "_target");
}
}
public function match():void
{
}
}
}
Edit:
There are multiple problems with the code. Too many to list, I'm afraid, but the biggest one is:
You're declaring a map, and trying to add your object to it, before your object exists. It doesn't exist until frame 5, so this won't work. I've re-written the code below, but honestly, there is so much wrong with the code that it's just not possible to fix without re-writing significant portions of it.
package
{
import flash.display.*;
import flash.events.*;
public class Map extends MovieClip
{
var dragdrops:Array;
public function Map()
{
// constructor code
dragdrops = new Array();
}
public function addElement(gamepiece:DragDrop):void {
dragdrops.push(gamepiece);
}
public function addChildElements():void {
var currentObject:Object;
for(var i:uint = 0; i < dragdrops.length; i++)
{
currentObject = dragdrops[i];
currentObject.test();
currentObject.target = (currentObject.name + "_target"); // this should work now, but doesn't. Why?
currentObject.target.test();
}
}
public function match():void
{
}
}
}
Then, on frame one, I added:
var map:Map = new Map();
Then, on frame five, I added:
map.addElement(tt1);
map.addChildElements();
This got tt1 added to map, at least, but that's as far as I got. Your problem now is;
currentObject.target = (currentObject.name + "_target");
It's the correct name, now, but it won't add it to target. That's as much as I can do.
It's because your hitTestObject method isn't correctly invoked. This method must be invoked in a Display Object instance to test if another instance of a Display Object hits it:
if (myDisplayObject.hitTestObject(anotherDisplayObject))
{
// do stuff
}
Adobe help about hitTestObject method.
Edit
So you should write you class like that:
package
{
import flash.display.*;
import flash.events.*;
public class DragDrop extends Sprite
{
var origX:Number;
var origY:Number;
var target:DisplayObject;
public function DragDrop()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
origX = x;
origY = y;
stage.addEventListener(MouseEvent.MOUSE_DOWN, drag);
buttonMode = true;
}
private function drag(evt:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, drop);
startDrag();
parent.addChild(this);
}
private function drop(evt:MouseEvent):void
{
target = (evt.target as DisplayObject);
stage.removeEventListener(MouseEvent.MOUSE_UP, drop);
stopDrag();
if(target.hitTestObject(target))
{
visible = false;
target.alpha = 1;
Object(parent).match();
}
x = origX;
y = origY;
}
}
}
Remark
You shouldn't call your variable target, because its the name of a Flash native variable. Rename it targ for example.

Actionscript 3: Trouble with removing child from parent

I am coding for learning purposes and have encountered an apparently unfixable problem.
I will first introduce you to my code.
This is a function in my Main class
public function confirm_route(evt:MouseEvent):void
{
var route = new Route(this, Airport.return_ROUTE);
Airport.return_ROUTE = new Array();
}
"Airport.return_ROUTE" is simply an array and its origin is not really relevant for the problem. In the Main class I'm also declaring my background var, and putting it as a public static var. Since I need to access this background from two other classes, I don't see another option but to declare it as that, even though I think it is not ideal. I will come back to this later in the explaination.
My Route class is dynamically creating new flights on the screen, hence the name. This is based on the Airport.return_ROUTE array. I need these flights to be added as childs to the background, which was created at Main class as mentioned. This is also why I added "this" as a parameter when calling the route function.
this.myparent = pMyParent;
I use the line above to be able to refer to the main instance. Since the Route instance is no movieclip I guess this is the only way to be able to refer to this.
As earlier mentioned the Route instance dynamically creats new_flights.
new_flight = new Flight(infoarray);
myparent.background_mc.addChild(new_flight);
This obviously is purposed to add the new_flight to the background movieclip.
Let us then look at the Flight class, since this is where the problem occurs.
Due to my game concept I need the new_flight to be removed once it reaches a certain point on the background movieclip.
This function is intended to do that job:
private function deleteThis():void
{
this.parent.removeChild(this)
}
This returns TypeError: Error #1009: Cannot access a property or method of a null object reference.
I really don't understand how to solve this differently.
EDIT: As requested, I will post my Route class.
package
{
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.EventDispatcher;
import Main;
public class Route extends Main
{
public var income:Number;
public var routePoints:Array;
private var routeTimer:Timer;
private var new_flight:Flight;
// ------------
private var myparent:Main;
public function Route(route_array:Array, pMyParent)
{
this.myparent = pMyParent;
this.routePoints = route_array;
routeTimer = new Timer(2000);// 2 second
routeTimer.addEventListener(TimerEvent.TIMER, route_function);
routeTimer.start();
}
private function route_function(event:TimerEvent):void
{
for (var counter:uint = 0; counter < routePoints.length - 1; counter ++)
{
trace("Coords: ", routePoints[counter][0],routePoints[counter][1],routePoints[counter + 1][0],routePoints[counter + 1][1]);
new_flight = new Flight(myparent, routePoints[counter][0],routePoints[counter][1],routePoints[counter + 1][0],routePoints[counter + 1][1]);
myparent.bg_image.addChild(new_flight);
var checkTimer:Timer = new Timer(15);// 1 second
checkTimer.addEventListener(TimerEvent.TIMER, check_function);
checkTimer.start();
function check_function(event:TimerEvent):void
{
if (new_flight.finished = true)
{
checkTimer.stop();
}
}
}
}
}
}
EDIT 2: Posting Flight class aswell
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.events.TimerEvent;
import flash.utils.Timer;
import fl.controls.Button;
import flash.display.DisplayObject;
public class Flight extends MovieClip
{
public static var speed:uint = 1
public var finished:Boolean = false;
protected var absvector:Number;
protected var vector:Array;
protected var myTimer:Timer;
//protected var parentContainer:MovieClip;
protected var utgangspunkt_x;
protected var utgangspunkt_y;
protected var destinasjon_x;
protected var destinasjon_y;
protected var vector_x;
protected var vector_y;
private var myparent:Main
public function Flight(pMyParent, utgangspunkt_x, utgangspunkt_y, destinasjon_x, destinasjon_y):void
{
addEventListener(Event.ADDED_TO_STAGE, init);
this.myparent = pMyParent;
this.utgangspunkt_x = utgangspunkt_x;
this.utgangspunkt_y = utgangspunkt_y;
this.x = utgangspunkt_x;
this.y = utgangspunkt_y;
this.destinasjon_x = destinasjon_x + 10;
this.destinasjon_y = destinasjon_y + 10;
this.vector_x = Math.abs(this.destinasjon_x-this.utgangspunkt_x);
this.vector_y = Math.abs(this.destinasjon_y-this.utgangspunkt_y);
this.height = 20;
this.width = 20;
}
public function init(evt:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
trace(this.parent)
trace("---------------------------------------------------")
if (utgangspunkt_x < destinasjon_x)
{
this.rotation = -(Math.atan((utgangspunkt_y-destinasjon_y)/(destinasjon_x-utgangspunkt_x)))/(Math.PI)*180;
}
else
{
this.rotation = 180-(Math.atan((utgangspunkt_y-destinasjon_y)/(destinasjon_x-utgangspunkt_x)))/(Math.PI)*180;
}
absvector = Math.sqrt(Math.pow((destinasjon_x - utgangspunkt_x),2) + Math.pow((utgangspunkt_y - destinasjon_y),2));
vector = [(destinasjon_x - utgangspunkt_x) / absvector,(utgangspunkt_y - destinasjon_y) / absvector];
stage.addEventListener(Event.ENTER_FRAME, movement)
}
private function movement(evt:Event):void
{
if (this.vector_x > this.vector_y)
{
if (destinasjon_x>utgangspunkt_x)
{
if (this.x < destinasjon_x)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
deleteThis()
}
}
else if (destinasjon_x<utgangspunkt_x)
{
if (this.x > destinasjon_x)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
deleteThis()
}
}
}
else
{
if (destinasjon_y>utgangspunkt_y)
{
if (this.y < destinasjon_y)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
deleteThis()
}
}
else if (destinasjon_y<utgangspunkt_y)
{
if (this.y > destinasjon_y)
{
this.x += speed*vector[ 0];
this.y -= speed*vector[1];
}
else
{
deleteThis()
}
}
}
}
private function deleteThis():void
{
finished = true;
this.parent.removeChild(this)
}
}
}
I suspect your deleteThis method is called more than once. That would explain why you have [object Image] and then nothing...
Is this method called by some kind of event? If that is the case, make sure this event is not triggered more than once.

Line 108 1136: Incorrect number of arguments. Expected 1

I cant fix this error and when I do it causes another one. I want to be able to hit key "71" and have a new instance of the movieclip added to the stage. any suggestions? Im a novice so probably alot of mistakes...
package {
import flash.display.MovieClip; //imports needed
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.engine.EastAsianJustifier;
import flash.events.KeyboardEvent;
import flash.display.Stage;
public class myJellyFish extends MovieClip {
private var startScaleX:Number;
private var startScaleY:Number;
//private var cliqued:Number;
private var stayonscreenLeft:Number;
private var stayonscreenRight:Number;
private var stayonscreenTop:Number;
private var stayonscreenBottom:Number;
private var moveDirection:Number;
private var speed:Number;
private var turnspeed:Number;
public function myJellyFish() {
startScaleX = this.scaleX;
startScaleY = this.scaleY;
stayonscreenBottom = 400;
stayonscreenRight = 500;
stayonscreenLeft = 5;
stayonscreenTop = 5;
moveDirection = .5;
speed = Math.random()*10;
turnspeed = 25;
this.addEventListener(MouseEvent.ROLL_OVER, scrolledOver);
this.addEventListener(MouseEvent.ROLL_OUT, scrolledOff);
this.addEventListener(MouseEvent.CLICK, directionChange);
this.addEventListener(Event.ENTER_FRAME, life)
trace("custom class be a working");
// constructor code
}
function myMethod () {
trace("method also be a workin'");
}
private function scrolledOver(Event:MouseEvent):void{
this.alpha = .5;
}
private function scrolledOff(Event:MouseEvent):void{
this.alpha = 1;
}
private function directionChange(e:Event):void{
moveDirection = moveDirection * -1;
}
private function life(e:Event):void{
if (moveDirection > 0){
Hmovement();
}
if (moveDirection < 0){
Vmovement();
}
}
private function Vmovement():void{
this.y += speed;
if(this.y <= stayonscreenBottom){
speed = speed * -1;
this.startScaleY * -1;
}
if(this.y >= stayonscreenTop){
speed = speed * -1;
this.startScaleY * -1;
}
}
private function Hmovement():void{
this.x += speed;
if(this.x >= stayonscreenRight){
speed = speed * -1;
}
if(this.x <= stayonscreenLeft){
speed = speed * -1;
}
}
private function generate(e:KeyboardEvent):void{
var movieClip:myJellyFish = new myJellyFish();
addChild(movieClip);
movieClip.x = (Math.random() * 200) + 20;
movieClip.y = (Math.random()*200) + 20;
movieClip.name = "jellyfish";
}
public function moreClips (event:KeyboardEvent){ //if that key is "F" it will play the tween
trace(event.keyCode);
if (event.keyCode == 71){
generate();
}
}
}//end class
}//end package
First of all, as Rin said, there will be an argument error when calling the generate function.
Secondly, you need to add a KeyboardEvent (ref) listener in order to receive the keyboard events.
The easiest way to listen to keyboard events is to add the listener to the Stage (because the KeyboardEvents will bubble to the Stage no matter where they were triggered.) In order to get a reference to the Stage, you need to wait until your MovieClip has been added to the DisplayList (when your instance of myJellyFish has been added as a child somewhere).
You do this by listening for the Event.ADDED_TO_STAGE event.
// Your constructor
public function myJellyFish() {
// ...
// Add event listener which will trigger when
// the MovieClip has been added to the DisplayList
this.addEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);
}
protected function handleAddedToStage(e:Event):void {
// Remove event listener since it's no longer needed
this.removeEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);
// You now have a reference to the stage, let's add the KeyboardEvent listener
stage.addEventListener(KeyboardEvent.KEY_DOWN, moreClips);
}
Edit: fixed typo in removeEventListener.
Your generate function has 1 argument wich is e:KeyboardEvent, since you have function moreClips which alredy has the KeyboardEvent, you don't need the argument for the generate function.
Basicly what you are doing now is calling the generate() function without the argument. All you should do is remove the argument from the function.
private function generate():void{
var movieClip:myJellyFish = new myJellyFish();
addChild(movieClip);
movieClip.x = (Math.random() * 200) + 20;
movieClip.y = (Math.random()*200) + 20;
movieClip.name = "jellyfish";
}

AS3 - Error #2025: The supplied DisplayObject must be a child of the caller

After 2 days of trying and searching for an answer I still didn't found it. I keep getting Error #2025: The supplied DisplayObject must be a child of the caller. I'm making a game where if the user hits an enemy, the enemy get destroyed. The code:
My main class
package classes
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
public class Main extends MovieClip
{
var enemyTimer:Timer;
public function Main()
{
var user:ship = new ship();
addChild(user);
user.name = "user";
user.initialize();
enemyTimer = new Timer(2000);
enemyTimer.addEventListener("timer", sendEnemy);
enemyTimer.start();
function sendEnemy(e:Event)
{
var badboy:enemy = new enemy();
addChild(badboy);
badboy.initialize();
}
}
}
}
the enemy class
package classes.enemy
{
import flash.display.MovieClip;
import flash.events.Event;
public class Enemy extends MovieClip
{
var speed:Number;
public function initialize()
{
addEventListener("enterFrame", enterFrame);
}
public function Enemy()
{
this.x = 700;
this.y = Math.random()*200 + 50;
speed = Math.random()*5 + 5;
}
function enterFrame(e:Event)
{
this.x -= speed;
if(this.hitTestObject(parent.getChildByName("user")))
{
kill();
}
}
function kill()
{
removeEventListener("enterFrame", enterFrame);
stage.removeChild(this);
}
}
}
The files are in different folders (classes > Main.as & classes.enemy.Enemy.as), don't know if that has anything to do with it.
Any help would be appreciated.
That's probably because you try to remove the Enemy MovieClip from stage, that it is not a (direct) child of.
I suggest you change this:
stage.removeChild(this);
to this:
this.parent.removeChild(this);
When you have a reference to a DisplayObject, like this in this case, you can always remove it from its parent, even if you don't know what that parent is. Or rather, you can remove it if you know it is on the display list, so you could also first check that it is, by doing:
if(this.parent) {
this.parent.removeChild(this);
}
I have got the solution: Just copy and paste the script and create few essentials symbols on stage, and in library; then, check it.
import flash.display.MovieClip;
var myArr:Array = [];
abc.startDrag(true);
var mymc:MovieClip = new MovieClip();
addChild(mymc);
init();
function init()
{
for (var i=0; i<25; i++)
{
var par:Particle = new Particle();
par.x = Math.random() * stage.stageWidth;
par.y = Math.random() * stage.stageHeight;
mymc.addChildAt(par,0);
myArr.push(par);
}
this.addEventListener(Event.ENTER_FRAME, hitTes);
}
function hitTes(e:Event):void
{
for (var j=0; j<myArr.length; j++)
{
if (abc.hitTestObject(myArr[j]))
{
if (myArr[j].parent)
{
myArr[j].parent.removeChild(myArr[j]);
}
}
}
}
I think you misplaced a method. See if this revision helps. (Also note that this does not include any cleanup of objects, which will eventually be a problem.)
package classes
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
public class Main extends MovieClip
{
public var enemyTimer:Timer;
public var user:ship = new ship();
public var badboy:enemy = new enemy();
public function Main()
{
user = new ship();
addChild(user);
user.name = "user";
user.initialize();
enemyTimer = new Timer(2000);
enemyTimer.addEventListener("timer", sendEnemy);
enemyTimer.start();
}
// *** I moved this out of the constructor:
public function sendEnemy(e:Event):void
{
badboy = new enemy();
badboy.name = "badboy"; // you probably have to make this unique, though.
addChild(badboy);
badboy.initialize();
}
}
}

A loop in enterframe?

I'm animating a bunch of words in AS3. Because I'm going to be using this on a mobile device, I want to use bitmaps rather than Sprites. So I've created WordObjects, which have a .bitmap property that I can access.
I have the following code, which fires on the click event and loops through an array inside an enterframe event. This is probably a bad idea, but I'm not sure how to do it better. (What is surprising is that it runs just fine in Flashbuilder, but slows to a crawl in Flash CS5.)
Is there some better way to do this? I just want an efficient way to animate the array of bitmaps.
private function clickhandler (e:MouseEvent){
this.addEventListener(Event.ENTER_FRAME, blowemup);
}
private function blowemup(e:Event){
var newPosition:Number;
for(var i:int=0; i<arrWordObjects.length; i++)
{
newPosition = updatePosition(arrWordObjects[i].bitmap);
arrWordObjects[i].bitmap.x += newPosition;
arrWordObjects[i].bitmap.y += getRandomNumber();
}
}
Something that will make a huge difference is using for each(Object in Array) rather than the standard for loop.
private function blowemup(e:Event):void
{
var newPosition:Number;
var i:ArrWordsObjectClass; // <-- don't know what the class for this is, just replace
for each(i in arrWordObjects)
{
newPosition = updatePosition(i.bitmap);
i.bitmap.x += newPosition;
i.bitmap.y += getRandomNumber();
}
}
A for each loop is typed, meaning a lot of time is saved where normally it'd be trying to work out what arrWordObjects[i] is every iteration.
Also, side note: using one ENTER_FRAME driven function and looping through everything in your application that you want to handle each frame is much more efficient than applying hundreds of listeners for objects.
I normally create a handler class that contains the ENTER_FRAME and an array storing my objects, like so:
package
{
import flash.events.Event;
import flash.display.Sprite;
public class Handler extends Sprite
{
// vars
public var elements:Array = [];
/**
* Constructor
*/
public function Handler()
{
addEventListener(Event.ENTER_FRAME, _handle);
}
/**
* Called on each dispatch of Event.ENTER_FRAME
*/
private function _handle(e:Event):void
{
var i:Element;
for each(i in elements)
{
i.step();
}
}
}
}
Then I create a base class for all the objects that I want to handle, containing the step() function called above.
package
{
import flash.display.DisplayObject;
public class Element extends Object
{
// vars
public var skin:DisplayObject;
/**
* Called on each dispatch of Event.ENTER_FRAME at Handler
*/
public function step():void
{
// override me
}
}
}
Now just extend Element with your objects:
package
{
import flash.display.Sprite;
public class MyThing extends Element
{
/**
* Constructor
*/
public function MyThing()
{
skin = new Sprite();
skin.graphics.beginFill(0);
skin.graphics.drawCircle(0,0,40);
skin.graphics.endFill();
}
/**
* Override step
*/
override public function step():void
{
skin.x += 4;
}
}
}
And get it all going!:
var handler:Handler = new Handler();
var m:MyThing;
var i:uint = 0;
for(i; i<10; i++)
{
m = new MyThing();
m.y = Math.random()*stage.stageHeight;
handler.elements.push(m);
addChild(m.skin);
}
How many bitmaps do you plan to have on the stage at a time?
I have had 40 900x16px bitmaps animating on the stage at full speed running on my iphone using air 2.6.
I used a foreach loop in an enterframe event which i added on mouseclick and removed once the animation was finished.
Remember to compile it for the mobile with gpu rendering enabled. (gpu in your app.xml if you are using air 2.6)
This is worth a read too, it explains a lot about performance for mobile devices
http://help.adobe.com/en_US/as3/mobile/WS901d38e593cd1bac-3d719af412b2b394529-8000.html
Here is a basic example of what I had...
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
[SWF(frameRate="30", backgroundColor="#FF00FF")]
public class Test extends Sprite
{
private var fields:Vector.<Bitmap> = new Vector.<Bitmap>();
public function Test()
{
this.stage.scaleMode = StageScaleMode.NO_SCALE;
this.stage.align = StageAlign.TOP_LEFT;
for(var i:int = 0; i< 37; i++){
var bd:BitmapData = new BitmapData(960, 16, true, 0x000000);
bd.fillRect(new Rectangle(0, 0, 900, 16), Math.round( Math.random()*0xFFFFFFFF ));
var b:Bitmap = new Bitmap(bd);
b.x = 0;
b.y = i*16;
stage.addChild(b);
fields.push(b);
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}
private var inertia:Boolean = false;
private var yCurrent:Number;
private var ySpeed:Number;
private var startY:Number;
private var cy:Number = 0;
private function onEnterFrame(e:Event):void{
if(!inertia){
ySpeed = (startY - yCurrent) ; // / 16;
startY = yCurrent
} else {
ySpeed *= 0.8;
if(ySpeed < 0.01 && ySpeed > -0.01){
inertia = false;
stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}
cy += ySpeed;
if(cy > 640)
cy -= 640;
var ty:Number = cy;
for each(var tf:Bitmap in fields){
tf.y = ty;
ty += 16;
if(ty > 640)
ty -= 640;
}
}
private function onMouseDown(e:MouseEvent):void{
inertia = false;
startY = e.stageY;
yCurrent = e.stageY;
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
private function onMouseMove(e:MouseEvent):void{
yCurrent = e.stageY;
}
private function onMouseUp(e:Event):void{
inertia = true;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
}
}
I would suggest looking at writing a custom effect on Adobe's website over registering for ENTER_FRAME event. What you've put up there means this code will forever run as long as the program is running. If you wanted to stop the effect or run for 10 frames and stop then you'll have to write more code. It gets even more complex if you want to apply this to several instances. You're going to have to resolve problems that custom effects framework solves.
I'd read how to write custom effects here:
http://livedocs.adobe.com/flex/3/html/help.html?content=createeffects_1.html