Action Script 3, how to make characters jump? - actionscript-3

I am creating a simple 2D platformer in Flash Develop as3 but I don't know how to create a way for my characters to jump.
Here is my code for main.as:
package
{
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
/**
* ...
* #author Harry
*/
public class Main extends Sprite
{
public var StartButton:Go;
public var FireBoy:Hero;
public var WaterGirl:Female;
public var Door1:Firedoor;
public var Door2:Waterdoor;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event = null):void
{
StartButton = new Go();
addChild(StartButton);
StartButton.addEventListener(MouseEvent.CLICK, startgame);
}
private function startgame(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
removeChild(StartButton);
FireBoy = new Hero ();
stage.addChild(FireBoy);
FireBoy.y = 495;
//This allows movement for FireBoy
stage.addEventListener(KeyboardEvent.KEY_DOWN, HandleHeroMove);
WaterGirl = new Female();
stage.addChild(WaterGirl);
WaterGirl.x = 70;
WaterGirl.y = 495;
stage.addEventListener(KeyboardEvent.KEY_DOWN, HandleFemaleMove);
Door1 = new Firedoor();
stage.addChild(Door1);
Door1.x = 5;
Door1.y = 62;
Door2 = new Waterdoor();
stage.addChild(Door2);
Door2.x = 100;
Door2.y = 62;
graphics.beginFill(0x804000, 1);
graphics.drawRect(0, 0, 800, 40);
graphics.endFill();
graphics.beginFill(0x804000, 1);
graphics.drawRect(0, 170, 600, 40);
graphics.endFill();
graphics.beginFill(0x804000, 1);
graphics.moveTo(800, 200);
graphics.lineTo(800, 700);
graphics.lineTo(400, 700);
graphics.lineTo(100, 700);
graphics.endFill();
graphics.beginFill(0x804000, 1);
graphics.drawRect(0, 580, 800, 40);
graphics.endFill();
}
//This handles FireBoys movement
public function HandleHeroMove(e:KeyboardEvent):void
{
trace(e.keyCode);
//This is for moving to the left
if (e.keyCode == 37)
{
FireBoy.x = FireBoy.x - 30;
Check_Border();
}
//This is for moving to the right
else if (e.keyCode == 39)
{
FireBoy.x = FireBoy.x + 30;
Check_Border();
}
else if (e.keyCode == 38)
{
FireBoy.grav = -15;
}
}
//This handles WaterGirls movement
public function HandleFemaleMove (e:KeyboardEvent):void
{
trace(e.keyCode);
//This is for moving to the left
if (e.keyCode == 65)
{
WaterGirl.x = WaterGirl.x - 30;
Check_Border();
}
//This is for moving to the right
else if (e.keyCode == 68)
{
WaterGirl.x = WaterGirl.x + 30;
Check_Border();
}
else if (e.keyCode == 87)
{
WaterGirl.grav = -15;
}
}
//This stops characters from leaving the screen
public function Check_Border():void
{
if (FireBoy.x <= 0)
{
FireBoy.x = 0;
}
else if (FireBoy.x > 750)
{
FireBoy.x = 750;
}
if (WaterGirl.x <= 0)
{
WaterGirl.x = 0;
}
else if (WaterGirl.x > 750)
{
WaterGirl.x = 750;
}
}
}
}
Here is my code for Hero.as (I have identical code for Female.as):
package
{
import flash.display.Bitmap;
import flash.display.Sprite;
/**
* ...
* #author Harry
*/
public class Hero extends Sprite
{
[Embed(source="../assets/FireBoy.jpg")]
private static const HeroFireBoy:Class;
private var FireBoy:Bitmap;
public var grav:int = 0;
public var floor:int = 580;
public function Hero()
{
FireBoy = new Hero.HeroFireBoy();
scaleX = 0.1;
scaleY = 0.1;
addChild(FireBoy);
}
public function adjust():void
{
FireBoy.y += grav;
if(FireBoy.y+FireBoy.height/2<floor)
grav++;
else
{
grav = 0;
FireBoy.y = floor - FireBoy.height / 2;
}
if (FireBoy.x - FireBoy.width / 2 < 0)
FireBoy.x = FireBoy.width / 2;
if (FireBoy.x + FireBoy.width / 2 > 800)
FireBoy.x = 800 - FireBoy.width / 2;
}
}
}
Please can you suggest exactly what code I should write and where to put it because, I can't find anything helpful and i am getting quite stressed over it.

One way to do is like this: in your Hero.as, you functions like jump, move_left and move_right and keep keep the coordinates within the Hero class. Then call those methods wherever you instantiate your Hero object.
As as example in your main.as, you may execute this code when space bar or up-arrow-key is pressed to make your Hero jump:
var hero:Hero = new Hero();
hero.jump();
If it is a simple jump on Y-axis, then you just have to change the Y-axis value. If it is both X-axis and Y-axis, like a forward jump, then you may consider Trigonometry Sine function to calculate the point on which your character should move to make it look smooth.
You don't need identical Female.as class. What you should do is this: Create a class (probably named Character). Add jump, move_left, move_right functions to this class. And then inherit Character class in Hero.as and Female.as. (You need to Google "inheritance" to learn more about this). Then you can instantiate Hero and Female with the same code that resides in Character class.
You may also need to override in Hero.as and Female.as:
[Embed(source="../assets/FireBoy.jpg")]
private static const HeroFireBoy:Class;
in your Hero.as and Female.as, to assign the correct image.

Related

AS3 changing between animation states

I am having troubles coding the animation state changes in flash. I have a little big planet style game with 3 horizontal rows the character can jump between. I have the motion set-up in a tween, but I haven't been able to get the character to transition from running animation to jump back/jump forward animation, and then back to run animation when it has finished transitioning between the layers.
The run animation frames are from 1 - 60, jump back a layer is 61, and jump forward a layer is 62. I haven't begun to worry about stationary yet, so it has no frames.
Edit: I've removed the anmatePlayer function and moved the animation control code into the checkEveryFrame function. I only made a separate function for the animations because I wasn't sure where it should go.
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
public class Main_Test_2 extends MovieClip
{
// variables
private var cam:MovieClip = new MovieClip();
private var player:Player = new Player();
private var topPosition:uint = 250;
private var centerPosition:uint = 430;
private var bottomPosition:uint = 610;
private var tweenSpeed:Number = 0.33;
private var UI:UserInterface = new UserInterface();
public function Main_Test_2():void
{
// initialize
init();
}
public function init():void
{
// initialize variables
stage.addChild (cam);
player.x = 200;
player.y = bottomPosition;
cam.addChild (UI);
cam.addChild (player);
// add event listeners
stage.addEventListener(Event.ENTER_FRAME, checkEveryFrame);
UI.topButton.addEventListener(MouseEvent.CLICK, topButtonClick);
UI.centerButton.addEventListener(MouseEvent.CLICK, centerButtonClick);
UI.bottomButton.addEventListener(MouseEvent.CLICK, bottomButtonClick);
}
public function checkEveryFrame(event:Event):void
{
cam.x -= player.x - player.x;
cam.y -= player.y - player.y;
player.vx = player.x - player.prevX;
player.vy = player.y - player.prevY;
player.prevX = player.x;
player.prevY = player.y;
/*if (player.y != topPosition || player.y != centerPosition || player.y != topPosition)
{
player.gotoAndStop (61);
}
else if (player.y == topPosition || player.y == centerPosition || player.y == topPosition)
{
player.gotoAndStop (1);
}*/
if (player.currentFrame == 60)
{
player.gotoAndStop (1);
}
else if (player.currentFrame < 60)
{
player.gotoAndStop (player.currentFrame + 1);
}
/*if (player.y < player.prevY)
{
player.gotoAndStop (61);
}
else if (player.y > player.prevY)
{
player.gotoAndStop (62);
}
else if (player.vy == 0)
{
player.gotoAndStop (1);
}*/
}
public function topButtonClick (event:MouseEvent):void
{
trace ("Top Click");
if (player.y >= bottomPosition)
{
var tween01:Tween = new Tween (player, "y", None.easeNone, bottomPosition, centerPosition, tweenSpeed, true);
}
else if (player.y == centerPosition)
{
var tween02:Tween = new Tween (player, "y", None.easeNone, centerPosition, topPosition, tweenSpeed, true);
}
else if (player.y < topPosition)
{
player.y = topPosition;
}
}
public function centerButtonClick (event:MouseEvent):void
{
trace ("Center Click");
if (player.y > centerPosition)
{
var tween01:Tween = new Tween (player, "y", None.easeNone, bottomPosition, centerPosition, tweenSpeed, true);
}
else if (player.y < centerPosition)
{
var tween03:Tween = new Tween (player, "y", None.easeNone, topPosition, centerPosition, tweenSpeed, true);
}
}
public function bottomButtonClick (event:MouseEvent):void
{
trace ("Bottom Click");
if (player.y <= topPosition)
{
var tween03:Tween = new Tween (player, "y", None.easeNone, topPosition, centerPosition, tweenSpeed, true);
}
else if (player.y == centerPosition)
{
var tween4:Tween = new Tween (player, "y", None.easeNone, centerPosition, bottomPosition, tweenSpeed, true);
}
else if (player.y > bottomPosition)
{
player.y = bottomPosition;
}
}
}
}
It would be helpful to see the code that actually calls animatePlayer; regardless, below is a solution.
Rather than rely on MovieClip to animate, you handle it in your existing checkEveryFrame, thereby providing you more exact control to change your animation state exactly when you need to. I've taken the liberty of unifying your UI clicking actions into a more maintainable function. Additionally, with the absence of your keybinding function, I've added playerState changes to the UI clicking for the sake of demonstration.
As best as I can tell, this should compile, but I'm unable to attempt it without the rest of your objects.
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
public class Main_Test_2 extends MovieClip
// variables
private var cam:MovieClip = new MovieClip();
private var player:Player = new Player();
private var tweenSpeed:Number = 0.33;
private var UI:UserInterface = new UserInterface();
public function Main_Test_2():void {
// initialize
init();
}
public function init():void {
// initialize variables
stage.addChild(cam);
player.x = 200;
player.y = playerTracks[0];
cam.addChild(UI);
cam.addChild(player);
// add event listeners
stage.addEventListener(Event.ENTER_FRAME, checkEveryFrame);
UI.topButton.addEventListener(MouseEvent.CLICK, movePlayer);
UI.centerButton.addEventListener(MouseEvent.CLICK, movePlayer);
UI.bottomButton.addEventListener(MouseEvent.CLICK, movePlayer);
}
public function checkEveryFrame(event:Event):void {
cam.x -= player.x - player.x;
cam.y -= player.y - player.y;
player.vx = player.x - player.prevX;
player.vy = player.y - player.prevY;
player.prevX = player.x;
player.prevY = player.y;
// Animation control
var a:Array = animations[playerState]; // current animation set
if (a.length == 2) {
var maxFrames:int = a[1] - a[0]; // Normalize the max value
var currentFrame:int = player.currentFrame - a[0]; // Normalize the current value
var nextFrame:int = normalizedCurrentFrame%maxFrames + a[0] // Modulus of max, and return to actual
player.gotoAndStop(nextFrame)
}
}
private var playerState:String = "run";
private var animations:Object = {
"run":[1,60],
"jump":[61],
"jumpForward":[62]
}
private var playerTracks:Array = [610, 430, 250];
private var playerLocIndex:int = 0;
public function movePlayer(e:MouseEvent):void {
// Based on the button clicked, increase/decrease/set the index of the destination
switch (e.currentTarget) {
case UI.topButton:
playerState = "jump";
playerLocIndex++;
if (playerLocIndex > 2) { playerLocIndex = 2; } // Clamp upper
break;
case UI.centerButton:
playerState = "run";
playerLocIndex = 1;
break;
case UI.bottomButton:
playerState = "jumpForward";
playerLocIndex--;
if (playerLocIndex < 0) { playerLocIndex = 1; } // Clamp lower
break;
}
new Tween(player, "y", None.easeNone, player.y, playerTracks[playerLocIndex], tweenSpeed, true);
}
}
}
Ok, I solved the problem. I had to use a timer that executed its action after the timer ran out. I placed it and a line of code to change states in each line of code with the tweens so the animation would go from run to the jump forward/backward animation and back to run at the end of the timer. Hope this helps someone else in the future.

AS3 game character only shoots in one direction

I'm making a top down shooter game and so far my character can move and can shoot when mouse is click. But it will only shoot to the right and not where my cursor is pointing. How do i fix this?
Here's the bullet code in the main class:
public var bulletList:Array = [];
stage.addEventListener(MouseEvent.CLICK, shootBullet, false, 0, true);
stage.addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
public function shootBullet(e:MouseEvent):void
{
var bullet:Bullet = new Bullet(stage, harold.x, harold.y, harold.rotation);
bullet.addEventListener(Event.REMOVED_FROM_STAGE, bulletRemoved, false, 0, true);
bulletList.push(bullet);
stage.addChild(bullet);
}
public function loop(e:Event):void
{
if(bulletList.length > 0)
{
for(var i:int = bulletList.length-1; i >= 0; i--)
{
bulletList[i].loop();
}
}
}
public function bulletRemoved(e:Event):void
{
e.currentTarget.removeEventListener(Event.REMOVED_FROM_STAGE, bulletRemoved);
bulletList.splice(bulletList.indexOf(e.currentTarget),1);
}
Here is the code in my Bullet Class:
package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
public class Bullet extends MovieClip
{
private var stageRef:Stage;
private var speed:Number = 10;
private var xVel:Number = 0;
private var yVel:Number = 0;
private var rotationInRadians = 0;
public function Bullet(stageRef:Stage, X:int, Y:int, rotationInDegrees:Number):void
{
this.stageRef = stageRef;
this.x = X;
this.y = Y;
}
public function loop():void
{
xVel = Math.cos(rotationInRadians) * speed;
yVel = Math.sin(rotationInRadians) * speed;
x += xVel;
y += yVel;
if(x > stageRef.stageWidth || x < 0 || y > stageRef.stageHeight || y < 0)
{
this.parent.removeChild(this);
}
}
}
}
A few thoughts:
As said by Aaron, you should compute rotationInRadians in the constructor, altought the real formula is this.rotationInRadians = rotationInDegrees * (Math.PI / 180);
You should make rotationInRadians a number, that is private var rotationInRadians:Number;
Are you aware displayObject has a getter/setter for rotation? In other words: harold.rotation is a property in harold object or is it referencing to said getter?
I think thats pretty much it.
I think you forgot to assign rotationInRadians in your constructor:
this.rotationInRadians = rotationInDegrees * (Math.PI / 180);
BTW, unless you want the bullet to be able to change direction during flight, you don't need to calculate the xVel and yVel each loop(), you can just calculate it in the constructor, store it, then update the x and y each loop().

Bullet won't fire?

I have been working on a space invaders game, I currently have no compiling errors finally but my bullets wont fire.
I kind of know where I should be looking to fix the problem but everything I try fails. Am I right in thinking it is to do with the bullet x-y argument?
I have a Movieclip symbol in the library named Bullet the same as my .as file but the script dose not seem to add the bullets to the scene.
Here is my ship and bullet code.
ship.as
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
/**
* ...
* #author Kenny Martin
*/
public class Ship extends MovieClip
{
private var fireRate:int = 6;
private var framesSinceFire:int = 0;
private var bulletHolder:Sprite
private var leftDown:Boolean = false
private var rightDown:Boolean = false
private var firing:Boolean = false
private var speed:int = 10;
private var bulletPool:Vector.<Bullet>
public function Ship(bHolder:Sprite)
{
x = 275;
y = 350;
bulletHolder = bHolder;
addEventListener(Event.ADDED_TO_STAGE, addedToStage, false, 0, true);
}
private function fillBulletPool():void
{
bulletPool = Vector.<Bullet>();
// while counter
var i:int = 0;
// while i is less than 25, keep adding bullets
while (i < 25)
{
//if we dont increase i,we risk getting stuck in an infinite loop
i++;
//push a new bullet straight into the vector
bulletPool.push(new Bullet());
}
}
public function update():void
{
// check if left is down and the ship is at least half its width from the edge
if (leftDown && x > (width / 2))
x -= speed;
// check if right is down and the ship is more than half its width from the right edge
if (rightDown && x < stage.stageWidth - (width / 2))
x += speed;
if (firing && framesSinceFire >= fireRate)
Fire();
}
public function updateBullets():void
{
framesSinceFire++;
updateBullets();
for (var i:int = 0; i < bulletPool.length; i++)
{
bulletPool[i].update();
}
}
public function Fire():void
{
var bullet:Bullet = findBullet();
if ( bullet != null)
{
bullet.activate(x,y);
bulletHolder.addChild(bullet);
framesSinceFire = 0;
}
}
private function addedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp, false, 0, true);
}
private function keyUp(e:KeyboardEvent):void
{
// check left arrow
if (e.keyCode == 37)
leftDown = false;
else if (e.keyCode == 39 ) // check right arrow]
rightDown = false;
else if ( e.keyCode == 32)// check space bar
firing = false;
}
private function keyDown(e:KeyboardEvent):void
{
// check left arrow
if (e.keyCode == 37)
leftDown = true;
else if (e.keyCode == 39 ) // check right arrow]
rightDown = true;
else if ( e.keyCode == 32)// check space bar
firing = true;
}
private function findBullet():Bullet
{
// loop through the bulletpool,from 0 to 24(we added 25 bullets to the pool)
for (var i:int = 0; i < bulletPool.length; i++)
{
if (!bulletPool[i].isActive)
{
// if its not active return the bullet for use
return bulletPool[i];
}
}
return null;
}
}
}
Bullet.as
package
{
import flash.display.MovieClip;
/**
* ...
* #author Kenny Martin
*/
public class Bullet extends MovieClip
{
public var isActive:Boolean = false
private var speed:int = 0.2;
private var _x:int;
private var _y:int;
public function Bullet()
{
super()
}
public function activate(_x:Number,_y:Number)
{
isActive = true;
x = _x;
y = _y;
}
public function deactivate():void
{
isActive = false;
// check we've got a parent before trying to remove ourselves from one
if (parent)
parent.removeChild(this);
}
public function update():void
{
if (isActive)
// move up the screen
y -= speed;
//until we go well past the top of the screen
if (y < -height)
{
deactivate();
}
}
}
}
You're not calling the updateBullets function.
The only call to updateBullets is... inside updateBullets... which is never called (and would cause a stack overflow if you did call it with a call to itself in there).
You need to move the updateBullets function call to update().

All my references to the stage method are throwing null reference errors in as3

I'm not sure what the change was that caused this, but suddenly i'm getting null object references in all the cases that I use the stage method as a parameter. My code is too long to fit all the different instances, so I'll just attach one or two.
package com.Mass.basics1
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class Main extends MovieClip
{
public var ourPlanet:Cosmo = new Cosmo(stage);
public var ourAsteroid:Asteroid = new Asteroid();
private var numStars:int = 80;
private var numAsteroids:int = 5;
public static var a:Number = 0;
private var stageRef:Stage;
//public var ourAsteroid:Asteroid = new Asteroid(stage);
//private var ourAsteroid:Asteroid = new Asteroid();
//our constructor function. This runs when an object of
//the class is created
public function Main()
{
//create an object of our ship from the Ship class
stop();
//add it to the display list
stage.addChild(ourPlanet);
ourPlanet.x = stage.stageWidth / 2;
ourPlanet.y = stage.stageHeight / 2;
this.stageRef = stageRef;
for (var i:int = 0; i < numStars; i++)
{
stage.addChildAt(new Star(stage), stage.getChildIndex(ourPlanet));
}
for (var o:int = 0; o < numAsteroids; o++)
{
stage.addChildAt(new Asteroid(), stage.getChildIndex(ourPlanet));
}
My debugger tells me there is a null object reference at line 13, and this code is from my engine. Cosmo is another external file that is linked to a symbol. I'll post the code from there, but there are about 4 of these errors across 4 different .as files, but it'd be too much code to put in here, so I'll just add from one other file I think would be important.
Code From Cosmo.as
package com.Mass.basics1
{
import flash.display.MovieClip;
import flash.display.Stage;
import com.senocular.utils.KeyObject;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.text.TextField;
public class Cosmo extends MovieClip
{
private var stageRef:Stage;
private var key:KeyObject;
private var speed:Number = 20;
private var vx:Number = 0;
private var vy:Number = 0;
private var friction:Number = 0.93;
private var maxspeed:Number = 8;
public var destroyed:Boolean = false;
public function Cosmo(stageRef:Stage)
{
this.stageRef = stageRef;
var key:KeyObject = new KeyObject(stage);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
public function loop(e:Event) : void
{
//keypresses
if (key.isDown(Keyboard.A))
vx -= speed;
else if (key.isDown(Keyboard.D))
vx += speed;
else
vx *= friction;
if (key.isDown(Keyboard.W))
vy -= speed;
else if (key.isDown(Keyboard.S))
vy += speed;
else
vy *= friction;
//update position
x += vx;
y += vy;
//speed adjustment
if (vx > maxspeed)
vx = maxspeed;
else if (vx < -maxspeed)
vx = -maxspeed;
if (vy > maxspeed)
vy = maxspeed;
else if (vy < -maxspeed)
vy = -maxspeed;
//ship appearance
rotation = vx;
scaleX = (maxspeed - Math.abs(vx))/(maxspeed* 4) + 0.75;
//stay inside screen
if (x > stageRef.stageWidth)
{
x = stageRef.stageWidth;
vx = -vx;
}
else if (x < 0)
{
x = 0;
vx = -vx;
}
if (y > stageRef.stageHeight)
{
y = stageRef.stageHeight;
vy = -vy;
}
else if (y < 0)
{
y = 0;
vy = -vy;
}
}
}
}
I'm also getting an error here at line 26 for the same thing.
Code from another file
package com.senocular.utils {
import flash.display.Stage;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.utils.Proxy;
import flash.utils.flash_proxy;
/**
* The KeyObject class recreates functionality of
* Key.isDown of ActionScript 1 and 2
*
* Usage:
* var key:KeyObject = new KeyObject(stage);
* if (key.isDown(key.LEFT)) { ... }
*/
dynamic public class KeyObject extends Proxy {
private static var stage:Stage;
private static var keysDown:Object;
public function KeyObject(stage:Stage) {
construct(stage);
}
public function construct(stage:Stage):void {
KeyObject.stage = stage;
keysDown = new Object();
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
}
flash_proxy override function getProperty(name:*):* {
return (name in Keyboard) ? Keyboard[name] : -1;
}
public function isDown(keyCode:uint):Boolean {
return Boolean(keyCode in keysDown);
}
public function deconstruct():void {
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.removeEventListener(KeyboardEvent.KEY_UP, keyReleased);
keysDown = new Object();
KeyObject.stage = null;
}
private function keyPressed(evt:KeyboardEvent):void {
keysDown[evt.keyCode] = true;
}
private function keyReleased(evt:KeyboardEvent):void {
delete keysDown[evt.keyCode];
}
}
}
In this file, i'm getting errors at lines 23 and 29. Thanks in advance, let me know if you need more information of any kind.
The stage property is going to be null until added to the display list hierarchy of the stage. You can't add the object to the stage until after the constructor is executed, so therefore you won't ever be able to access stage in the constructor. It's going to be null.
Call the construct method after creating the instance and adding it to the stage's display list hierarchy.

ADDED_TO_STAGE Event doesn't work in certain frame?

This is Heli's Class and it'll called in main class ,the target of main class in frame 2 .
The frame 1 contain button that can make me go to frame 2 .but this movie clip of Heli doesn't added to the stage . but it'll work if i targeting main class in frame 1 . so can anyone tell me how to use added_to_stage event in specified frame ??? (sorry about my english)
package com.ply
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
public class Heli extends MovieClip
{
//Settings
public var xAcceleration:Number = 0;
public var yAcceleration:Number = 0;
private var xSpeed:Number = 0;
private var ySpeed:Number = 0;
private var up:Boolean = false;
private var down:Boolean = false;
private var left:Boolean = false;
private var right:Boolean = false;
private var bullets:Array;
private var missiles:Array;
public function Heli()
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
public function onAddedToStage(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
init();
}
private function init():void
{
stage.addEventListener(Event.ENTER_FRAME, runGame);
}
private function runGame(event:Event):void
{
xSpeed += xAcceleration ; //increase the speed by the acceleration
ySpeed += yAcceleration ; //increase the speed by the acceleration
xSpeed *= 0.95; //apply friction
ySpeed *= 0.95; //so the speed lowers after time
if(Math.abs(xSpeed) < 0.02) //if the speed is really low
{
xSpeed = 0; //set it to 0
//Otherwise I'd go very small but never really 0
}
if(Math.abs(ySpeed) < 0.02) //same for the y speed
{
ySpeed = 0;
}
xSpeed = Math.max(Math.min(xSpeed, 10), -10); //dont let the speed get bigger as 10
ySpeed = Math.max(Math.min(ySpeed, 10), -10); //and dont let it get lower than -10
this.x += xSpeed; //increase the position by the speed
this.y += ySpeed; //idem
}
}
}
public function Heli()
{
if (stage) init();
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
here it is the main class
package
{
import com.ply.Heli;
import com.peluru.Bullet;
import com.musuh.Airplane2;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.*;
import flash.events.*;
import flash.utils.*;
public class Main extends MovieClip
{
public static const STATE_INIT:int = 10;
public static const STATE_START_PLAYER:int = 20;
public static const STATE_PLAY_GAME:int = 30;
public static const STATE_REMOVE_PLAYER:int = 40;
public static const STATE_END_GAME:int = 50;
public var gameState:int = 0;
public var player:Heli;
public var enemy:Airplane2;
//public var bulletholder:MovieClip = new MovieClip();
//================================================
public var cTime:int = 1;
//the time it has to reach in order to be allowed to shoot (in frames)
public var cLimit:int = 10;
//whether or not the user is allowed to shoot
public var shootAllow:Boolean = true;
//how much time before another enemy is made
public var enemyTime:int = 0;
//how much time needed to make an enemy
//it should be more than the shooting rate
//or else killing all of the enemies would
//be impossible :O
public var enemyLimit:int = 64;
//the player's score
public var score:int = 0;
public var gameOver:Boolean = false;
public var bulletContainer:MovieClip = new MovieClip();
//================================================
public function Main()
{
//stage.addEventListener(Event.ENTER_FRAME, gameLoop);
// instantiate car class
gameState = STATE_INIT;
gameLoop();
}
public function gameLoop(): void {
switch(gameState) {
case STATE_INIT :
initGame();
break
case STATE_START_PLAYER:
startPlayer();
break;
case STATE_PLAY_GAME:
playGame();
break;
case STATE_REMOVE_PLAYER:
//removePlayer();
break;
case STATE_END_GAME:
break;
}
}
public function initGame() :void {
//addChild(bulletholder);
addChild(bulletContainer);
gameState = STATE_START_PLAYER;
gameLoop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, myOnPress);
stage.addEventListener(KeyboardEvent.KEY_UP, myOnRelease);
stage.addEventListener(Event.ENTER_FRAME, AddEnemy);
}
public function startPlayer() : void {
player=new Heli();
player.x = stage.stageWidth / 2;
player.y = stage.stageHeight / 2;
// add car to display list
stage.addChild(player);
gameState = STATE_PLAY_GAME;
}
public function playGame():void {
//CheckTime();
gameLoop();
//txtScore.text = 'Score: '+score;
}
public function myOnPress(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.LEFT)
{
player.xAcceleration = -1;
}
else if(event.keyCode == Keyboard.RIGHT)
{
player.xAcceleration = 1;
}
else if(event.keyCode == Keyboard.UP)
{
player.yAcceleration = -1;
}
else if(event.keyCode == Keyboard.DOWN)
{
player.yAcceleration = 1;
}
else if (event.keyCode == 32 && shootAllow)
{
fireBullet();
}
}
public function fireBullet() {
//making it so the user can't shoot for a bit
shootAllow = false;
//declaring a variable to be a new Bullet
var newBullet:Bullet = new Bullet();
var newBullet2:Bullet = new Bullet();
//changing the bullet's coordinates
newBullet.x = player.x+20; //+ player.width/2 - player.width/2;
newBullet.y = player.y;
newBullet2.x = player.x-20;
newBullet2.y = player.y;
//then we add the bullet to stage
bulletContainer.addChild(newBullet);
bulletContainer.addChild(newBullet2);
}
function AddEnemy(event:Event){
if(enemyTime < enemyLimit){
//if time hasn't reached the limit, then just increment
enemyTime ++;
} else {
//defining a variable which will hold the new enemy
enemy =new Airplane2();
//making the enemy offstage when it is created
enemy.y = -1 * enemy.height;
//making the enemy's x coordinates random
//the "int" function will act the same as Math.floor but a bit faster
enemy.x = Math.floor(Math.random()*(stage.stageWidth - enemy.width));
//then add the enemy to stage
addChild(enemy);
//and reset the enemyTime
enemyTime = 0;
}
if(cTime <= cLimit){
cTime ++;
} else {
//if it has, then allow the user to shoot
shootAllow = true;
//and reset cTime
cTime = 1;
}
}
public function myOnRelease(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT)
{
player.xAcceleration = 0;
}
else if(event.keyCode == Keyboard.UP || event.keyCode == Keyboard.DOWN)
{
player.yAcceleration = 0;
}
}
}
}