AS3 loop movieClip based on set timer - actionscript-3

I want to set a duration of time by hitting space bar twice. I then want a movieclip to play for that exact amount of time, then loop to play again at for that set amount of time, and so on. until I set a different amount of time by hitting the space bar twice again.
var beat:int;
var beatcount:int;
var tempopress:int;
var num:Number;
num = 0;
tempopress = 0;
stage.addEventListener(KeyboardEvent.KEY_DOWN,checker);
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
var myTimer:Timer=new Timer(20,0);
myTimer.addEventListener(TimerEvent.TIMER, stopWatch);
function stopWatch(event:TimerEvent):void {
beatcount = Number(myTimer.currentCount);
}
function checker(e:KeyboardEvent){
if(e.keyCode==Keyboard.SPACE){
if (tempopress == 0) {
trace('start');
beatcount = 0;
myTimer.reset();
myTimer.start();
tempopress = 1;
} else {
trace('stop');
myTimer.stop();
trace(beatcount);
tempopress = 0;
}
}
}
stage.addEventListener(Event.ENTER_FRAME, loopPlayback);
function loopPlayback() {
var loopTimer:Timer=new Timer(20,beatcount);
myTimer.addEventListener(TimerEvent.TIMER, loopWatch);
}
function loopWatch(event:TimerEvent):void {
if (MovieClipMan.currentFrame >= MovieClipMan.totalFrames ){
MovieClipMan.gotoAndStop(1);
} else {
MovieClipMan.nextFrame();
}
}
I know it's a mess haha. Please help! :]

I'd perhaps try something like this, which essentially is checking to see whether to do the loop or not each frame.
var timeStart:Number;
var loopDuration:Number;
var timeLastLoop:Number;
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onKeyDown(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.SPACE) {
if (!timeStart) { // First time SPACE is hit
timeStart = getTimer();
} else { // Second time SPACE is hit
loopDuration = getTimer() - timeStart; // set the loop duration
timeStart = NaN; // reset the start time
loop();
}
}
}
function onEnterFrame(e:Event):void {
if (loopDuration && timeLastLoop) {
if (getTimer() >= timeLastLoop + loopDuration) { // if it's time to loop
loop();
}
}
}
function loop():void {
timeLastLoop = getTimer();
someMovieClip_mc.gotoAndPlay(0);
}

First, use getTimer() to find the difference in time between space bar keypress.
Next, would be to stop creating a new Timer in every frame. It should be created outside of the enter frame handler. Then on the second keypress, you can set the delay property to the difference, and restart the timer.
The most important changes would be here:
if (tempopress == 0) {
trace('start');
myTimer.stop();
startTime = getTimer();
beatcount = 0;
tempopress = 1;
} else {
trace('stop');
myTimer.delay = getTimer() - startTime;
myTimer.reset();
myTimer.start();
tempopress = 0;
}
Then, the timer event handler can just send the MovieClip to frame 1.

Related

Can't make MovieClip in function dissapear

I'm trying to make simple shooting game with Fiat Multipla falling up to bottom of the screen. I have created function to generate falling multipla and within this function I have a problem.
The main issue is that after change of multideath status to 1 "Death" function does nothing even if It is kept with ENTER_FRAME. Child becomes invisible as I implemented it in multipla movieclip, but even after response from there with Death = 1, nothing happens.
I'm new to all this, I've met and solved few issues during programming, but here's my brickwall for now. Code's either failing completely or I don't know something that's obvious. As I said, I'm newbie.
Thanks a lot for help!
Here's the function:
import flash.events.Event;
import flash.desktop.NativeApplication;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
Mouse.hide();
var velocity = 0;
var ammo = 6;
LGUI.LGUIammo.gotoAndStop(6);
var counter = 0;
function multiplarain()
{
var x1 = Math.ceil(Math.random() * 280);
var y1 = -200;
var random:Multipla = new Multipla();
var life = 265;
var multideath = 0;
random.x = 100 + x1;
random.y = y1
addChild(random);
random.gotoAndStop(1);
setChildIndex(random, +1);
addEventListener(Event.ENTER_FRAME, Death);
function Death(event:Event):void
{
if(multideath >= 1)
{
removeEventListener(Event.ENTER_FRAME, Death);
removeChild(random);
}
}
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
function fl_EnterFrameHandler(event:Event):void
{
if(random.y >= 680)
{
removeEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler)
removeChild(random);
trace("rofl");
}
}
random.addEventListener(Event.ENTER_FRAME, fl_AnimateVertically);
function fl_AnimateVertically(event:Event)
{
velocity = velocity + 0.000035;
random.y += 1.5 + velocity;
}
random.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler);
function fl_TapHandler(event:TouchEvent):void
{
counter = counter + 1;
ammo -= 1;
}
if(ammo == 6)
{
LGUI.LGUIammo.gotoAndStop(6);
}
if(ammo == 5)
{
LGUI.LGUIammo.gotoAndStop(5);
}
if(ammo == 4)
{
LGUI.LGUIammo.gotoAndStop(4);
}
if(ammo == 3)
{
LGUI.LGUIammo.gotoAndStop(3);
}
if(ammo == 2)
{
LGUI.LGUIammo.gotoAndStop(2);
}
if(ammo == 1)
{
LGUI.LGUIammo.gotoAndStop(1);
}
if(ammo <= 0)
{
LGUI.LGUIammo.gotoAndStop(7);
}
HGUI.saved.text = counter;
this.addEventListener( Event.ENTER_FRAME, handleCollision)
var kucyk = LGUI.LGUIlife.lifeitself;
function handleCollision(e:Event):void
{
if (random.hitTestObject(LGUI))
{
kucyk = LGUI.LGUIlife.lifeitself;
kucyk.width -= 0.1;
}
/*if (kucyk.width == 0.75)
{
trace("cycki");
NativeApplication.nativeApplication.exit();
}*/
}
}
and here's multipla's movieclip in library code:
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
this.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler2);
function fl_TapHandler2(event:TouchEvent):void
{
this.gotoAndPlay(2);
}
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
function fl_EnterFrameHandler(event:Event):void
{
if(this.currentFrame == 60)
{
this.visible = false;
MovieClip(root).multideath = 1;
trace(MovieClip(root).multideath);
removeEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
removeEventListener(Event.ENTER_FRAME, fl_TapHandler2);
}
}
it's been like 10 years since I last time worked with AS2 but I'd guess that this Multipla sets the multideath property in the wrong place. If i remember corrctly, root is the top-most level (your application). So if your first code is not on the main timeline but in a movieclip that is on the main timeline it won't work. Try to put a trace into the Death function to see if the multideath is really changing there:
trace(multideath);
try this in the multipla code:
parent.multideath = 1;
instead of
MovieClip(root).multideath = 1;
And I'm asking myself why do you need so many enter frame listeners? You can have just one and combine all animations in one function.
Also you don't need to check for multideath on every frame, just remove the movieclip in a separate function:
function removeMultipla():void
{
removeChild(random);
}
Just call this function from your Multipla instead of setting the multideath property:
parent.removeMultipla();

"TypeError: Error #1009: Cannot access a property or method of a null object reference" while using gotoAndplay function

I was trying to add a gameover screen with a restart button for my game.I had placed the restart button at frame 22.When my player dies it goes to frame 22 and i'm able to restart the game on clicking the button,but this message gets looped in the output area.Please help me how i can correct this issue.
Issue is not there when i remove the line
gotoAndPlay(22);
at Frame 17,but without that i will not get the desired functionality.
Please find my code below
At Frame 17 - Game code
stop();
import flash.events.Event;
import flash.events.MouseEvent;
var mouseIsDown = false;
var speed = 0;
var score = 0;
addEventListener(Event.ENTER_FRAME,mainLoop);
stage.addEventListener(MouseEvent.MOUSE_DOWN,clicked);
stage.addEventListener(MouseEvent.MOUSE_UP,unclicked);
function clicked(m:MouseEvent)
{
mouseIsDown = true;
}
function unclicked(m:MouseEvent)
{
mouseIsDown = false;
}
function mainLoop(e:Event)
{
score = score + 10;
output.text = "Score: "+score;
if(mouseIsDown)
{
speed -= 2;
}
else
{
speed+=2;
}
if(speed > 10) speed = 10;
if(speed < -10) speed = -10;
player.y += speed;
for(var i = 0; i < numChildren; i++)
{
if (getChildAt(i) is Cloud || getChildAt(i) is Boundary)
{
var b = getChildAt(i) as MovieClip;
if(b.hitTestObject(player))
{
for(var counter = 0; counter < 12; counter++)
{
var boom = new Boom();
boom.x = player.x;
boom.y = player.y;
boom.rotation = Math.random() * 360;
boom.scaleX = boom.scaleY = 0.5 + Math.random();
addChild(boom);
}
player.visible = false;
removeEventListener(Event.ENTER_FRAME,mainLoop);
gotoAndPlay(22);
}
}
}
}
At frame 22 - Restart screen
stop();
import flash.events.MouseEvent;
foutput.text = "Score: "+ fscore;
btn_playagain.addEventListener(MouseEvent.CLICK, playagain);
function playagain(m:MouseEvent)
{
gotoAndPlay(17);
}
btnback3.addEventListener(MouseEvent.CLICK, backMain3);
function backMain3(m:MouseEvent)
{
gotoAndPlay(1);
}
At frame 1 - Main Menu screen
stop();
import flash.events.MouseEvent;
import flash.system.fscommand;
btnnewgame.addEventListener(MouseEvent.CLICK, newGame);
function newGame(m:MouseEvent)
{
gotoAndPlay(17);
}
btnins.addEventListener(MouseEvent.CLICK, instruct);
function instruct(m:MouseEvent)
{
gotoAndPlay(6);
}
btncredits.addEventListener(MouseEvent.CLICK, credits);
function credits(m:MouseEvent)
{
gotoAndPlay(11);
}
btnexit.addEventListener(MouseEvent.CLICK, exitfunc);
function exitfunc(m:MouseEvent)
{
fscommand("quit");
}
At Frame 6 - Instructions Screen
stop();
btnback1.addEventListener(MouseEvent.CLICK, backMain1);
function backMain1(m:MouseEvent)
{
gotoAndPlay(1);
}
At Frame 11 - Credits Screen
stop();
btnback2.addEventListener(MouseEvent.CLICK, backMain2);
function backMain2(m:MouseEvent)
{
gotoAndPlay(1);
}
That error means that you are trying to call a method on a null object, meaning one of the objects you are using on frame 22 doesn't actually exist at that moment.
The likely candidates for the offending variable are foutput, btn_playagain, and btnback3. Check to make sure that they are on the stage at frame 22, and are spelt correctly.
You use output.text on frame 17, are you sure that it should be foutput.text on frame 22?

How do I display a button at a certain time, then have it disappear again in Actionscript 3?

I am trying to make a game that involves hitting keys/clicking buttons at the right time. I want to have the button/indicator hidden until the right time but am having a bit of trouble getting it to display. This is the code I have for it so far.
var count:Number = 5;
var myTimer:Timer = new Timer(1000, count);
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.start();
function countdown(event:TimerEvent): void {
timer_txt.text = String((count)-myTimer.currentCount);
}
btnthing.addEventListener(MouseEvent.CLICK, btnclick);
btnthing.visible=false;
while (((count)-myTimer.currentCount)==1) {
btnthing.visible=true;
}
function btnclick(e:MouseEvent): void {
if (((count)-myTimer.currentCount) == 1) {
myTimer.stop();
btnthing.visible=false;
time_txt.text = "Yay!";
} else {
myTimer.stop();
gotoAndStop(3);
}
}
So far my code starts the timer and displays a countdown. If I remove the part that hides/shows the button, everything works fine.
var count:Number = 5;
var myTimer:Timer = new Timer(1000, count);
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.start();
function countdown(event:TimerEvent): void {
timer_txt.text = String((count)-myTimer.currentCount);
}
btnthing.addEventListener(MouseEvent.CLICK, btnclick);
function btnclick(e:MouseEvent): void {
if (((count)-myTimer.currentCount) == 1) {
myTimer.stop();
btnthing.visible=false;
timer_txt.text = "Yay!";
} else {
myTimer.stop();
gotoAndStop(3);
}
}
If anyone could help me get this right that would be awesome. Thanks!
You're not using the 'while' loop correctly. Change it to a 'if' statement and put it inside the countdown function like this:
function countdown(event:TimerEvent): void
{
timer_txt.text = String((count)-myTimer.currentCount);
if (((count)-myTimer.currentCount)==1) {
btnthing.visible=true;
}
}
so that your code tests for the currentCount on each tick of the timer and finally does something about it.
Read up on 'while' loops - they don't do exactly what you think they do and it's easy to get 'em into infinite repitions if you don't increment the thing that you're changing within the loop.

how to change boolean values with timerEvent in as3

I had written this small code to change a boolean value for 0 to 1 and vice versa every second
but it doesnt work.
The result is it always stays as 0. I must be making some stupid mistake. Please help. Thanks
var booleanL:Number = 0;
var myTimerL:Timer = new Timer(1000,60);
myTimerL.addEventListener(TimerEvent.TIMER, timerListenerL);
function timerListenerL (e:TimerEvent):void{
if(booleanL == 0) {
booleanL = 1;
} else if(booleanL == 1) {
booleanL = 0;
}
}
myTimerL.start();
trace(booleanL);
EDIT:
You can try using the computer clock time to make a stopwatch. The boolean will update every time the clock's end_time time is [delay] seconds higher than start_time. Delay is set by this line: delay = start_time.seconds + 2; here gives +2 seconds delay as limit before update
Try it like this...
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.utils.getTimer;
import flash.events.TimerEvent;
import flash.events.Event; //added this for enter frame events
public class timer extends MovieClip
{
public var booleanL:int = 0;
public var start_time:Date = new Date;
public var end_time:Date = new Date;
public var delay:int;
public function timer()
{
//var myTimerL:Timer = new Timer(1000, 5);
//myTimerL.addEventListener(TimerEvent.TIMER, timerListenerL);
//myTimerL.start();
timer_Reset();
}
function timerListenerL ():void //(event:TimerEvent):void
{
trace("Am updating Boolean...");
if( 1 == booleanL)
{ booleanL = 0; trace(booleanL); }
else if (0 == booleanL)
{ booleanL = 1; trace(booleanL);}
}
//USE REAL TIME CLOCK VERSION
public function timer_Reset():void
{
start_time = new Date; //reset time to now..
delay = start_time.seconds + 2; //two seconds test delay
stage.addEventListener(Event.ENTER_FRAME, _update);
}
function _update (e:Event):void
{
//set end_time to now-time every frame,
//then check if end seconds are [+ delay] higher than start_time.seconds
end_time = new Date(); //set to Now time
if (end_time.seconds == delay)
{
trace(end_time.hours + ":" + end_time.minutes + ":" + end_time.seconds);
stage.removeEventListener(Event.ENTER_FRAME, _update);
timerListenerL (); //we update boolean via this function
timer_Reset(); //we reset for next check via this function
}
}
}

Character getting faster everytime I reset my game from gameover screen in action script 3

My game starts with a start frame. click a button to the game. if I hit an object I go to game over screen. Everytime I hit the start over button on the game over screen my characters controls get faster. I have set no variables for speed, simply just "mc_guy.x +=3" or .y , etc. If I had to say by how much faster I would want to say that the speed doubles.
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.MovieClip;
//prevent game loop
stop();
// event listeners for movement
mc_Guy.addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownGuy);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUpGuy);
// this array holds references to all the keys
var keys:Array = [];
//initiate default values
fuelGauge.height = 100;
//Gravity
addEventListener(Event.ENTER_FRAME,Gravity)
var GyAmt:Number = 5;
function Gravity(e:Event){
mc_Guy.y += GyAmt;
if (gameFloor.hitTestObject(mc_Guy)){
mc_Guy.y = gameFloor.y;}
else if (gameFloor2.hitTestObject(mc_Guy)){
mc_Guy.y = gameFloor2.y;}
else if (gameFloor3.hitTestObject(mc_Guy)){
mc_Guy.y = gameFloor3.y;}}
// the event listeners
function update(e:Event):void
{
if (keys[Keyboard.RIGHT])
{
mc_Guy.x += 3;
}
if (keys[Keyboard.LEFT])
{
mc_Guy.x -= 3;
}
if (keys[Keyboard.SPACE]){
mc_Guy.y -= 10;
//drain fuel
fuelGauge.height -= 1;
gaugePercent.text = String(fuelGauge.height)
if (fuelGauge.height == 0){
nextFrame();}}
}
function onKeyDownGuy(e:KeyboardEvent):void
{
keys[e.keyCode] = true;
}
function onKeyUpGuy(e:KeyboardEvent):void
{
keys[e.keyCode] = false;
}
//Array storing each wall
var MC_wall:Array = new Array(mc_Wall,mc_Wall2,mc_Wall5,
mc_Wall6,mc_Wall7,mc_Wall8,mc_Wall9,mc_Wall10,mc_Wall11,mc_Wall12, mc_Wall13)
//Collision Detection
addEventListener(Event.ENTER_FRAME,loop);
function loop(e:Event){
var i:Number = 0;
do {
if (MC_wall[i].hitTestObject(mc_Guy)){
nextFrame();}
i++;
} while (i < MC_wall.length);
/* for (var i:Number = 0; i < MC_wall.length; i++){
if (MC_wall[i].hitTestObject(mc_Guy)){
nextFrame();}
}*/
if(mc_Guy.hitTestPoint(mc_WallRun.x, mc_WallRun.y, false)){
nextFrame();}
else if(mc_Guy.hitTestObject(fuelPowerup)){
removeChild(fuelPowerup);
fuelGauge.height = 100;
gaugePercent.text = String(fuelGauge.height)}
else if(mc_Guy.hitTestObject(doorKey)){
removeChild(doorKey)
//open door
mc_Wall13.height -=20
mc_Wall13.y -= 10
}
}
//Object Movement
addEventListener(Event.ENTER_FRAME, onEnterFrame);
var spinSpeed:Number=6;
var axisMove:Number = 90;
var axisMovement:Number = 3;
function onEnterFrame(event:Event):void
{
mc_WallRun.rotation+=spinSpeed;
//count the movement on axis and move
axisMove -= 3;
mc_Wall9.x += axisMovement;
gameFloor3.x += axisMovement * .9;
if(axisMove <= 0){
axisMove += 90
axisMovement = axisMovement*-1
}
}
Gameover frame:
import flash.events.MouseEvent;
stop();
restartGame.addEventListener(MouseEvent.MOUSE_DOWN, playAgain);
function playAgain(event:MouseEvent):void{
prevFrame();
}
It sounds like when you restart your game
mc_Guy.addEventListener(Event.ENTER_FRAME, update);
is called again, without removing the previously added listener.
So update is now called two times on Event.ENTER_FRAME, and then once more per frame per game reset, causing the guy to move faster.