How do i add a countdown timer when the program begins? - actionscript-3

I'm creating a game where a spaceship has to collide with planets that are orbiting the centre of the screen. I want there to be a certain time limit so these planets have to be destroyed within the time limit

You can use the Timer class if you want to delay the explosion, if that's what you were getting at:
var myTimer:Timer = new Timer(5000, 1); // delay: 5s
myTimer.addEventListener("timer", timerHandler);
function timerHandler(event:TimerEvent):void {
trace('my planet explodes');
}
function enterFrameHandler(e:Event):void {
if (spaceship.hitTestObject(planet)) {
myTimer.start();
}
}
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
To learn more about Timer class.

You can also create the timer at ADDED_TO_STAGE event, so, your timer will begin when the program stars.
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);
// CREATE YOUR TIMER HERE
}

Related

as3 Error 1009 at Coin1/coin1go(), i am trying to get an enemy to drop a coin

So the enemy does drop a coin but i does not get the properties of the coin( if it hits the player it gives him +5 coins)
The coin will be removed if it hits the bottom of the stage, if the player dies or if the player hits it. Sadly, it does not work.
But this does work if i place a coin on the stage before i start the game, it gets all its properties, so then it must be the moment it gets added to the stage that it does not get linked with the coding or something..... and that is where i am right now.
this is the .as file for the coin:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Coin1 extends MovieClip
{
private var _root:Object;
private var speed:int = 0;
public function Coin1()
{
addEventListener(Event.ENTER_FRAME, Speed1);
addEventListener(Event.ADDED, beginClass);
addEventListener(Event.ENTER_FRAME, coin1go);
}
private function beginClass(event:Event):void
{
_root = MovieClip(root);
}
private function Speed1(event:Event):void
{
y += speed;
}
private function coin1go(event:Event):void
{
if (this.y > stage.stageHeight)
{
removeEventListener(Event.ENTER_FRAME, coin1go);
_root.removeChild(this);
}
if (hitTestObject(_root.player_mc))
{
_root.coin += 1;
removeEventListener(Event.ENTER_FRAME, coin1go);
_root.removeChild(this);
}
if (_root.playerhealth <= 1)
{
removeEventListener(Event.ENTER_FRAME, coin1go);
_root.removeChild(this);
}
}
}
}
This is the part from where it gets added to the stage:
if (enemy2health <= 0)
{
removeEventListener(Event.ENTER_FRAME, eFrame);
_root.score += _root.Enemy2Score * _root.scoremultiplyer;
stage.addChild(newExplosionSmall)
newExplosionSmall.x = this.x;
newExplosionSmall.y = this.y;
stage.addChild(newCoin1)
newCoin1.x = this.x;
newCoin1.y = this.y;
Ass you can see there is also an addchild for an explosion wich works perfectly fine but that may jus be because it does nothing else than appear and remove itself.
So long story short: enemy drops coin but it does nothing and floats to the bottom of the screen and i get a constant stream of 1009 errors. so does anyone know how to fix this?
You should add an enterframe listener only after receiving a valid stage reference, which only appears when Event.ADDED_TO_STAGE event is received. This is because your enterframe listener refers stage.
public function Coin1()
{
addEventListener(Event.ENTER_FRAME, Speed1);
addEventListener(Event.ADDED_TO_STAGE, beginClass);
}
private function beginClass(event:Event):void
{
_root = MovieClip(root);
addEventListener(Event.ENTER_FRAME, coin1go);
}

AS3 mouse events not firing when mouseX = 0

I'm creating what should be a very simple, full screen drag and drop game in Flash Develop. It works fine except in one frustrating instance.
I add items to the stage, add MOUSE_DOWN listeners to them and start dragging when one hears that listener. I then add a MOUSE_UP listener to figure out when to stop the drag. Again, this works fine unless mouseX = 0. When the mouse is all the way to the left of the screen and I mouse up or mouse down no listener is fired. I also took it out of full screen mode and if the mouse is at or below 0 no mouse events will fire.
What in the world is going on?
private function itemSelectedHandler(e:MouseEvent):void
{
thisItem = GameItem(e.currentTarget);
thisItem.startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP, itemUnselectedHandler, false, 0, true);
}
private function itemUnselectedHandler(e:MouseEvent):void
{
stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP, itemUnselectedHandler);
thisItem.removeEventListener(MouseEvent.MOUSE_DOWN, itemSelectedHandler);
}
You are calling stopDrag on the class and not the dragged sprite. Try something like the following :
package
{
public class Main extends Sprite
{
private var _draggedSprite:Sprite = null;
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
for (var i:int = 0; i < 10; i++)
{
createBox();
}
}
private function createBox():void
{
var sp:Sprite = new Sprite();
sp.graphics.beginFill(0xff0000, 1);
sp.graphics.drawRect(0, 0, 30, 30);
sp.graphics.endFill();
sp.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
sp.x = Math.random() * (stage.stageWidth - 30);
sp.y = Math.random() * (stage.stageHeight - 30);
addChild(sp);
}
private function onMouseDown(e:MouseEvent):void
{
var sp:Sprite = e.target as Sprite;
sp.startDrag();
_draggedSprite = sp;
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
private function onMouseUp(e:MouseEvent):void
{
_draggedSprite.stopDrag();
_draggedSprite = null;
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
}
}
This worked for me when mouseX=0 in fullscreen mode.

(AS3) Functions

I managed to fix the whole null stage error by following MJW's guide on debugging Error #1009. But now the function that initializes the bullets doesn't get called.
Snippets:
if (stage) {
 init();
} else {
addEventListener(Event.ADDED_TO_STAGE, init);
}
...
private function init(event:Event = null) {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.addEventListener(Event.ENTER_FRAME, shoot);
}
...
private function shoot(event:Event) {
var bullet:EnemyBullet = new EnemyBullet();
stage.addChild(bullet);
bullet.x = enemy.x;
bullet.y = enemy.y;
bullet.theta = Math.random() * 360;
bManager.bulletVector.push(bullet);
}
Note that when I put trace() within the second two functions, nothing happens, but the addEventListener() in the first snippet does get called (or so I think).
As a general practice, stage should not be referenced - especially in your case, where your reference is solely to add instances of your bullet class. If it's a matter of z-index, you could instead have a layer in which bullets are placed on top of other display objects on the display list.
Besides complexities loading multiple SWFs on a single stage, your code would become nice isolated functional units by adding display objects to their own hierarchy of the display list. Or, you could leverage a MVC pattern whereby a controller manipulated views.
In order for your code to work, that class must either be the main function of the SWF or added to stage.
If it's the main function of the SWF, init() will be called.
Otherwise, assure it's getting added to the display list via an addChild().
Do you really intend to fire a bullet every frame? That could be 24 to 60 bullets a second. You might want to throttle that with some probability whether a bullet with fire.
Say this was a battlefield, and your battlefield class was added to stage, it could be implemented as this:
package
{
import flash.display.Sprite;
import flash.events.Event;
[SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0x0, frameRate = 30)]
public class Battlefield extends Sprite
{
public function Battlefield()
{
if (stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
init();
}
protected function init():void
{
addEventListener(Event.ENTER_FRAME, frameHandler);
}
protected function frameHandler(event:Event):void
{
var odds:Number = Math.random();
trace((odds < 0.1 ? "Fire! " : "Skip...") + "Odds were: " + odds);
}
}
}
Which would output:
Skip... Odds were: 0.3539872486144304
Skip... Odds were: 0.742108017206192
Fire! Odds were: 0.025597115512937307
Skip... Odds were: 0.7608889108523726
Fire! Odds were: 0.08514392375946045
Skip... Odds were: 0.27881692815572023
Beyond Stage3D, I've never been fond of this initialization pattern, as you could just as easily rely on stage events, as in:
package
{
import flash.display.Sprite;
import flash.events.Event;
[SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0x0, frameRate = 30)]
public class Battlefield extends Sprite
{
public function Battlefield()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
addEventListener(Event.ENTER_FRAME, frameHandler);
}
protected function removedFromStageHandler(event:Event):void
{
removeEventListener(Event.ENTER_FRAME, frameHandler);
removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function frameHandler(event:Event):void
{
var odds:Number = Math.random();
trace((odds < 0.1 ? "Fire! " : "Skip...") + "Odds were: " + odds);
}
}
}
Therefore, upon added to stage the class initiates its actions, and upon removed from stage the class terminates its actions.
I think the issue is in the first block.
you are checking for stage, if stage is not null, then use a added to stage listener.
you should only be using addEventListener(Event.ADDED_TO_STAGE, init);
however, this is assuming that the class is DisplayObject subclass, objects that do not get added to stage cannot call the ADDED_TO_STAGE listener

AS3 - Move MovieClip across screen

I've 3 different MovieClips that I need to move at the same time across the screen. (From bottom to top)
What is the best way of doing this without using a tweening class like Caurina?
Thank you for tips.
You could add an event listener to the parent container of the display objects which listens for the Event.ENTER_FRAME event. On each Event.ENTER_FRAME event you simply decrement the y property of the display objects like in the following example.
package
{
import flash.display.Sprite;
import flash.events.Event;
[SWF(width="600", height="500")]
public class Main extends Sprite
{
private var _squares:Vector.<Square>;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}// end function
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
_squares = new Vector.<Square>();
var redSquare:Square = new Square(0xFF0000, 100);
redSquare.x = 0;
redSquare.y = 400;
addChild(redSquare);
var greenSquare:Square = new Square(0x00FF00, 100);
greenSquare.x = 300;
greenSquare.y = 300;
addChild(greenSquare);
var blueSquare:Square = new Square(0x0000FF, 100);
blueSquare.x = 500;
blueSquare.y = 100;
addChild(blueSquare);
_squares.push(redSquare, greenSquare, blueSquare);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}// end function
private function onEnterFrame(e:Event):void
{
for each(var square:Square in _squares)
{
if (square.y > 0) square.y -= 5;
}// end for
}// end function
}// end class
}// end package
import flash.display.Sprite;
internal class Square extends Sprite
{
public function Square(color:uint, size:Number)
{
graphics.beginFill(color);
graphics.drawRect(0, 0, size, size);
graphics.endFill();
}// end function
}// end function
I think you'd be making life easier for yourself though if you simply used Greensock's Tweening platform instead.
You can animate them in Flash IDE with frames and tweenings.
Also you can animate them programmatically yourself. Place every movie clip at the bottom of the screen, write some code that moves your movieClips a little to the top of the screen and gets called periodically (using Timer, EnterFrame event listener or setInterval), stop calling this code when all movieClips reached the top (using Timer.stop(), removeEventListener or clearInterval).
I don't see why you might need to do that because there are many tweening libraries that do all this for you.

MOUSE_DOWN trigger every frame, ActionScript 3

as I am new to as3, I want to implement a MachineGun, that fires while has ammo, and the trigger is pulled, In my case, the MouseEvent.MOUSE_DOWN.
The problem is that this event fires only once.
The closest I get is to this is MouseEvent.MOUSE_MOVE, but it fails my purpose when the mouse position is sustained
EDIT:
I need the updated mouse cursor every frame
When your MouseEvent.MOUSE_DOWN event handler you can create an event listener that listens for the Event.ENTER_FRAME event to be dispatched. Using the Event.ENTER_FRAME event handler you can repeatedly call a method that handles shooting the bullet. The following is an example I modeled after an example at http://www.benoitfreslon.com/actionscript-throw-bullets-to-mouse-direction:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(width="500", height="500", frameRate="24", backgroundColor="0xFFFFFF")]
public class Main extends Sprite
{
private var _gun:Gun;
private var _interval:int;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}// end function
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
_gun = new Gun();
_gun.x = stage.stageWidth / 2 - _gun.width / 2;
_gun.y = stage.stageHeight / 2 - _gun.height / 2;
addChild(_gun);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
}// end function
private function onStageMouseDown(e:MouseEvent):void
{
stage.addEventListener(Event.ENTER_FRAME, onStageEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
}// end function
private function onStageEnterFrame(e:Event):void
{
shootBullet();
}// end function
private function shootBullet():void
{
if (_interval > 5)
{
var bullet:Bullet = new Bullet();
bullet.addEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
bullet.x = _gun.x;
bullet.y = _gun.y;
bullet.angleRadian = Math.atan2(stage.mouseY - _gun.y, stage.mouseX - _gun.x);
bullet.addEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
addChild(bullet);
_interval = 0; // reset
}// end if
_interval++;
}// end function
private function onBulletEnterFrame(e:Event):void
{
var bullet:Bullet = Bullet(e.target);
bullet.x += Math.cos(bullet.angleRadian) * bullet.SPEED;
bullet.y += Math.sin(bullet.angleRadian) * bullet.SPEED;
if ( bullet.x < 0 || bullet.x > 500 || bullet.y < 0 || bullet.y > 500)
{
removeChild(bullet);
bullet.removeEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
}// end if
}// end function
private function onStageMouseUp(e:MouseEvent):void
{
stage.removeEventListener(Event.ENTER_FRAME, onStageEnterFrame);
stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
_interval = 0;
}// end function
}// end class
}// end package
import flash.display.Sprite;
internal class Gun extends Sprite
{
public function Gun()
{
graphics.beginFill(0x000000);
graphics.drawCircle(0, 0, 10);
graphics.endFill();
}// end function
}// end class
internal class Bullet extends Sprite
{
public var angleRadian:Number;
public const SPEED:Number = 10;
public function Bullet()
{
graphics.lineStyle(1, 0x000000);
graphics.drawCircle(0, 0, 10);
graphics.endFill();
}// end function
}// end class
The point of interest is in the onStageEnterFrame() method. There's an if statement that checks whether the _interval property's value is greater than 5, if so, a new bullet is created and shot otherwise the _interval property's value is incremented. The purpose of the _interval property is to space out the bullets being shot.
[UPDATE]
Here is an image of the example flash application running:
The mouse button is being held down in the top right corner hence the bullets being shot in that direction.
On receiving a MouseEvent.MOUSE_DOWN event, run a while loop making the machine gun fire. The loop breaks on receiving a MouseEvent.MOUSE_UP event. Something like this
private function handleMouseDown( event:Event ):void
{
this.addEventListener( MouseEvent.MOUSE_UP , handleMouseUp );
startFiring();
}
private function handleMouseUp( event:Event ):void
{
this.removeEventListener( MouseEvent.MOUSE_UP , handleMouseUp );
this.addEventListener( MouseEvent.MOUSE_DOWN , handleMouseDown);
stopFiring();
}
EDIT: For clarification, the stop and start firing functions are functions that run a loop to keep the machine gun firing animation going however that may be.
add firing action to ENTER_FRAME event when mouse is pressed and remove when mouse is up
this.addEventListener( MouseEvent.MOUSE_DOWN, this.handler_down );
this.addEventListener( MouseEvent.MOUSE_UP, this.handler_up );
private function handler_down(event:Event):void {
super.addEventListener( Event.ENTER_FRAME, this.handler_frame );
}
private function handler_up(event:Event):void {
super.removeEventListener( Event.ENTER_FRAME, this.handler_frame );
}
private function handler_frame(event:Event):void {
this.fire();
}
I have to do this regularly, and instead of using an enter_frame listener, I opt for a Timer() and TimerEvent.Timer listener. That way I have more control over how often the repeat is fired without accounting for frame rate and what not.
private var fireRepeat:Timer;
private function triggerDown(e:MouseEvent):void {
if (!this.fireRepeat) { // create the repeater
this.fireRepeat = new Timer(500, 0);
this.fireRepeat.addEventListener(TimerEvent.TIMER, this.fire);
}
fire(); // fire the first bullet
this.fireRepeat.reset(); // reset the repeater
this.fireRepeat.start(); // start the repeater
}
private function triggerUp(e:MouseEvent):void {
if (this.fireRepeat) { this.fireRepeat.stop(); }
}
public function fire(e:* = null):void {
trace('fire!');
}