AS3 / Stopping timer at a Vector? - actionscript-3

How do i start my timer at vector[2] and stop it at vec[13]. myTimer.stop();
I have done that the vector jumps to the next vector every 10 seconds (timerevent). The timer and vector will continue to count and then goes back to the vec[0]
If possible, I would like to start my timer at a later vector. And that the timer stops at the end.
var myTimer:Timer = new Timer(1000);
myTimer.repeatCount = 13;
myTimer.delay = 1000;
myTimer.addEventListener(TimerEvent.TIMER, countdownHandler);
function countdownHandler(event:TimerEvent):void
{
countdown.text = 0+myTimer.currentCount+" s remaining";
countdown2.text = 0+myTimer.currentCount+" s remaining";
if(myTimer.currentCount==10)
{
myTimer.reset();
myTimer.start();
}
}
myTimer.start();
&
function timerfunctie(event:TimerEvent)
{
for(var i:int = 0; i < vec.length; i++)
{
if (vec[i].parent) if (myTimer.currentCount == 9)
{
removeChild(vec[i]);
var next2:int = i+1;
if(next2 == vec.length) next2 = 0;
addChild(vec[next2]);
break;
}
}
}

Not sure where timerfunctie is called, but this code should detect when the currentCount of the timer is 2 and 13. If you want the Timer to run the full 13 iterations, you do not want to reset it at iteration 10.
function countdownHandler(event:TimerEvent):void
{
countdown.text = 0+myTimer.currentCount+" s remaining";
countdown2.text = 0+myTimer.currentCount+" s remaining";
if (myTimer.currentCount==2) {
// start with vector[2]
} else if (myTimer.currentCount==13) {
// end with vector[13]
}
}

Related

Shoot in different directions in as3

I'm having some troubles with the game I'm making. My character shoots bullets, but when it comes to shooting them in different directions it does not work properly. When it shoots the bullets follow the character's direction. Below I post the code.
var Bulli:Array = new Array();
var ShootTimer:Timer = new Timer(0);
stage.addEventListener(MouseEvent.MOUSE_DOWN, startShootTimer);
stage.addEventListener(MouseEvent.MOUSE_UP, stopShootTimer);
ShootTimer.addEventListener(TimerEvent.TIMER, shootBullo);
stage.addEventListener(Event.ENTER_FRAME, mainLoop);
function startShootTimer(e:MouseEvent):void
{
ShootTimer.start();
}
function stopShootTimer(e:MouseEvent):void
{
ShootTimer.stop();
}
function shootBullo(e:TimerEvent):void
{
var bullo:Bullo = new Bullo();
bullo.x = Jumbo.x;
bullo.y = Jumbo.y - 50;
if(destra)
{
bullo.dir = destra;
}
else
{
bullo.dir = sinistra;
}
addChild(bullo);
Bulli.push(bullo);
}
function mainLoop (e:Event):void
{
for (var b:int = 0; b < Bulli.length; b++)
{
if (Bulli[b].dir == destra)
{
Bulli[b].x += 10;
}
else
{
Bulli[b].x -= 10;
}
}
}
Don't add that listener to Stage, instead add it to each unique bullo...
//# not to Stage...
//stage.addEventListener(Event.ENTER_FRAME, mainLoop);
Try this (untested but may be useful for some ideas):
function shootBullo(e:TimerEvent):void
{
var bullo:Bullo = new Bullo();
bullo.x = Jumbo.x;
bullo.y = Jumbo.y - 50;
if(destra) { bullo.dir = destra; }
else { bullo.dir = sinistra; }
bullo.addEventListener(Event.ENTER_FRAME, mainLoop);
}
function mainLoop (e:Event):void //the "e" of this function parameter is each unique "Bullo"
{
//# currentTarget is whichever "bullo" is talking to this Event (via Listener).
if (e.currentTarget.dir == destra)
{ e.currentTarget.x += 10; }
else { e.currentTarget.x -= 10; }
}

Restarting timer in action script 3 function resetClock

I'm new to action script 3 so i will be picking your brains I lot.
I'm making a simple 5 min scoreboard for my workplace to use and now im stuck on making the reset button work.
I have made 3 buttons with instance of (start-btn, stop_btn and reset_btn) but I can't figure out the function code for the reset_btn. I need it to go back to 5:00 and stop so you can press start and begin counting from (5:00 or in my case 300) again.
This is my code so far:
import flash.events.TimerEvent;
import flash.utils.Timer;
var timeRemaining:int = 300;
showTime.text = formatTimeRemaining();
var timer:Timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.stop();
start_btn.addEventListener(MouseEvent.CLICK, startClock);
function startClock(event:MouseEvent):void
{
timer.start();
}
stop_btn.addEventListener(MouseEvent.CLICK, stopClock);
function stopClock(event:MouseEvent):void
{
timer.stop();
}
reset_btn.addEventListener(MouseEvent.CLICK, resetClock);
function resetClock(event:MouseEvent):void
{
timer.reset();
showTime.text = "300";
}
function onTimer( ev:TimerEvent ):void
{
timeRemaining--;
if (timeRemaining < 0)
{
timeRemaining = 0;
loseGame();
}
else
{
showTime.text = formatTimeRemaining();
}
}
function formatTimeRemaining():String
{
var mins : int = int (timeRemaining / 60);
var minstr:String = mins < 10 ? "0" + mins:"" + mins;
var secs:int = timeRemaining % 60;
var secstr:String = secs < 10 ? "0" + secs:"" + secs;
return minstr+":"+secstr;
}
function loseGame():void
{
timer.stop();
trace("Countdown is finished.");
showTime.text = formatTimeRemaining() + (" Time's Up!");
}
function resetClock(event:MouseEvent):void
{
timer.stop();
timeRemaining = 300;
showTime.text = formatTimeRemaining();
}
Simply stop the timer, reset the timeRemaining variable then display it.

ActionScript 3 Looping

I just started using Looping in AS3 recently and I have much to learn. here is the question. Below is a Loop that puts 5 balls one on top of the other on the stage. So far so good. however, I'd like to create a situation when clicking on a button, the bottom ball is removed, and then each ball take the place of the ball below it one by one, continue this for each click until all the balls are gone. . I have created this situation with add/remove child and I thought it could be more efficient with looping. I just don't know how to access the balls since I don't have instance name or class name that I can reference too.
var ball: gBall4M;
var i: Number;
for (i = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17
addChild(ball);
}
function release2Ball2(event: MouseEvent): void {
This is the effect I want to get https://youtu.be/B4GLolw8QVA
As mentioned in the answer of #daniel-messer, you can use an Array to store your balls, and for the second part of your question, when removing the last ball and moving the other ones, you can use array.pop() to remove the last element of the array, and then you can use array.map() to move the other balls :
function release2Ball2(event:MouseEvent): void
{
if(balls.length > 0){
ball = balls.pop(); // remove and get the last element of the array
ball.parent.removeChild(ball); // remove that element from the DisplayObjectContainer
function move_ball(item:Ball, index:int, array:Array):void {
item.y += 17;
}
// move the rest of elements
balls.map(move_ball, this);
}
}
EDIT :
Take a look on the code working, I added numbers to understand how balls are moving :
Your full code can be like this :
var balls:Array = [],
ball:gBall4M;
for (var i:int = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17;
balls.push(ball);
addChild(ball);
}
btn.addEventListener(MouseEvent.CLICK, release2Ball2);
function release2Ball2(event:MouseEvent):void {
if (balls.length > 0) {
ball = balls.pop();
ball.parent.removeChild(ball);
function move_ball(item:gBall4M, index:int, array:Array):void {
item.y += 17;
}
balls.map(move_ball, this);
}
}
EDIT 2:
To do that kind of animation, you can use a Timer like this :
var balls:Array = [],
ball:gBall4M;
for (var i:int = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 30;
ball.y = 25 + i * 17;
balls.push(ball);
addChild(ball);
}
btn.addEventListener(MouseEvent.CLICK, release2Ball2);
function release2Ball2(event:MouseEvent):void {
if (balls.length > 0) {
ball = balls.pop();
ball.parent.removeChild(ball);
if(balls.length > 0){
timer.start();
}
}
}
var timer:Timer = new Timer(150);
timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent){
if(balls.length >= timer.currentCount){
balls[balls.length - timer.currentCount].y += 17;
} else {
timer.reset();
}
})
Which will give you something like this :
Hope that can help.
Just save the instances inside an array or similar that you can use later.
I hope you are using a code file and not writing the code directly inside a frame inside the flash editor. Otherwise you might end up with issues.
Something similar to this should work
package {
class Main {
var balls:Array = [];
function createBalls() {
var ball: gBall4M;
var i: Number;
for (i = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17;
balls.push(ball); //Save them to array
addChild(ball);
}
}
function release2Ball2(event: MouseEvent): void {
var clickedBall:gBall4M = event.currentTarget as gBall4M; //this might be wrong depending on what you are listening for, and what type of object gBall4M is...
for(var i=0; i<balls.length; ++i) {
if(balls[i] == clickedBall) {
balls[i].splice(i, 1); //remove instance from array
removeChild(clickedBall); //remove instance from display list
break;
}
}
}
}
}
OK I figured it out. using this code on frame 1
function release2Ball2(event: MouseEvent): void {
if (ballA.length > 0) {
ball = ballA.pop();
removeChild(ball);
ball = null
gotoAndPlay(2);
}
}
stop();
using this code on frame 10:
for (i = 0; i < ballA.length; i++) {
ballA[i].y += 17;
stop();
That does the trick.
Thank you so much for your help

Flash As3 Variable Issue

I have a variable on frame 1 that starts at 3000 and keeps decreasing. This variable determines the gap of time between the spawn of an object. so basically the objects spawn quicker and quicker as the this number decreases. Everything works fine except the fact when i make the character die and the main timeline goes to frame 2 to show the death screen. When clicked "play again" on that frame that makes you come back to frame 1. the objects keep spawning at whatever speed they were spawning before death. Even though the variable resets to 3000 when "play again" clicked..
I traced the variable and it does truely reset. but for some reason those spawning objects follow the previous variable.
Heres the code on the first Frame:
import flash.events.Event;
stop();
var num1:Number = 0;
var scrollSpeed:Number = 3000;
var playerState:Number = 1;
var alive:Boolean = true;
var Redbars:Array = new Array();
var Bluebars:Array = new Array();
var scoreCount:Number = 10;
addEventListener(Event.ENTER_FRAME, update);
function update(e:Event){
trace(scrollSpeed);
scoreCount += 1;
scoreText.text = (scoreCount).toString();
//SCROLL SPEED-------------------
if(scrollSpeed > 300)
{
scrollSpeed -= 1;
}
//--------------------------------
CheckForCollisionBlue();
CheckForCollisionRed();
//trace(alive);
if(player.currentFrame == 1){
playerState = 1;
}
//Check if lost
if(player.hitTestObject(leftHitBox)){
gotoAndStop(2);
scoreEnd.text = (scoreCount).toString();
}
//If dead Delete Object
if(currentFrame == 2){
deleteBlue();
deleteRed();
}
}
////
//Timer////////////////////////////////
var myTimer:Timer = new Timer(scrollSpeed,10000000);
myTimer.addEventListener(TimerEvent.TIMER, timerListener);
function timerListener (e:TimerEvent):void{
//Generate Random number
num1 = randomRange();
trace(num1);
//IF NUM1 = 1------------------------------------------
if(num1 == 1){
//Create a Red Bar
var redBar = new Jump_Cube();
Redbars.push(redBar); //add enemy to the array
redBar.x = -33;
redBar.y = 99;
redBar.width = 12.5;
redBar.height = 20.45;
//Update the Bar
for(var i:int=0; i < Redbars.length; i++){
if(currentFrame == 1)
{
addChild(Redbars[i]);
}
}
}
//IF NUM1 = 2------------------------------------------
if(num1 == 2){
//Create a Blue Bar
var blueBar = new Jump_Cube2();
Bluebars.push(blueBar); //add enemy to the array
blueBar.x = -26.8;
blueBar.y = 10;
blueBar.width = 12.25;
blueBar.height = 31.90;
//Update the Bar
for(var j:int=0; j < Bluebars.length; j++){
if(currentFrame == 1)
{
addChild(Bluebars[j]);
}
}
myTimer.delay = scrollSpeed;
}
}
myTimer.start();
//--------------------------------------------------------------------
//Check for Collision------------------------------
function CheckForCollisionBlue(){
for(var i:int=0; i < Bluebars.length; i++){
if( player.hitTestObject(Bluebars[i]) ){
//Collision
trace("Didnt Hit Blue");
player.x -= 5;
player.y += 1;
}
}
}
//Check for Collision------------------------------
function CheckForCollisionRed(){
for(var i:int=0; i < Redbars.length; i++){
if( player.hitTestObject(Redbars[i]) ){
//Collision
trace("Didnt Hit Red");
player.x -= 5;
player.y += 1;
}
}
}
function randomRange():Number
{
return (Math.floor(Math.random() * (2 - 1 + 1)) + 1);
}
///////////BUTTONS------------------
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
redButton.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchEndRed);
function onTouchEndRed(e:TouchEvent):void{
player.gotoAndPlay(2);
playerState = 2;
}
blueButton.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchEndBlue);
function onTouchEndBlue(e:TouchEvent):void{
player.gotoAndPlay(19);
playerState = 3;
}
///////--CLEARING STAGE
//--------------------------------------------------------------------
//delete Blue------------------------------
function deleteBlue(){
for(var i:int=0; i < Bluebars.length; i++){
removeChild(Bluebars[i]);
}
}
//delete Red------------------------------
function deleteRed(){
for(var i:int=0; i < Redbars.length; i++){
removeChild(Redbars[i]);
}
}
Heres the code on the second frame:
stop();
alive = false;
againButton.addEventListener(TouchEvent.TOUCH_END, again);
function again(e:TouchEvent):void{
gotoAndStop(1);
playerState = 1;
scrollSpeed = 3000;
deleteBlue();
deleteRed();
}
You have to put in a removeEventListener(Event.ENTER_FRAME, update); inside your onTouchEndRed function. And probably also inside of this 'if' conditional: if(player.hitTestObject(leftHitBox)){...
Simply stop programming using frames. Use classes instead. AS3 is based on classes. It'll take you a lot of benefits. This link may help you to start: http://www.adobe.com/devnet/actionscript/getting_started.html
Additionally, FlashPlayer executes frame's code each time you jump to another frame. Thats why your variables are reinitializing.

AS3.0 Two For-loops with a delay

I've got the following code and i would like to add an delay of 200 ms after each trace statement
for (var x_pos:uint = 0; x_pos <= 12; x_pos++){
for (var y_pos:uint = 0; y_pos <=12; y_pos++){
trace("hello world " +"("x_pos+","+y_pos+")");
//CODE FOR DELAY OF 200ms
}
}
The real situation is a bit more complex but kind of the same:
//For each Row
for (var x_pos:uint = 0; x_pos <= tile_amount-1; x_pos++){
//For each column
for (var y_pos:uint = 0; y_pos <= tile_amount-1; y_pos++){
//New tile;
var newtile:Tile = new Tile;
//Set position
newtile.x = ((40*y_pos)-(40*x_pos));
newtile.y = ((20*y_pos)+(20*x_pos));
//Add to stage
addChild(newtile);
}
}
Anyone any suggestions ?
private var x_pos:uint;
private var y_pos:uint;
private var timer:Timer;
public function startLoop():void
{
x_pos = 0;
y_pos = 0;
timer = new Timer(200);
timer.addEventListener(TimerEvent.TIMER, onTick);
timer.start();
}
private function onTick(event:TimerEvent):void
{
trace("hello world " +"("x_pos+","+y_pos+")");
if (++y_pos <= 12)
return;
y_pos = 0;
if (++x_pos <= 12)
return;
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, onTick);
timer = null;
}
You can't stop the execution of code in the middle of a statement like that, your best bet is to use a timer:
package
{
import flash.events.TimerEvent;
public class Foo
{
private var x_pos:uint = 0;
private var y_pos:uint = 0;
private var timer:Timer;
public function Foo()
{
timer = new Timer(200, 0);
timer.addEventListener(TimerEvent.TIMER, handleTick);
timer.start();
}
public function handleTick(e:TimerEvent):void {
trace("hello world " +"("x_pos+","+y_pos+")");
y_pos++;
if(y_pos > 12){
x_pos++;
y_pos = 0;
}
if(x_pos > 12) timer.stop();
}
}
}
Actionscript does not have a blocking timeout system -- you need to do a recursive function of your own. This following perfect, but it is a start.
import flash.utils.setTimeout;
// call the final function.
delayedRecursion(12,12,200,
function(curX:Number, curY:Number):void
{
trace("hello world " +"("+curX+","+curY+")");
});
//This is really a wrapper around delayedRecursionHelper
function delayedRecursion(maxX:Number, maxY:Number,
delay:Number, callback:Function):void
{
delayedRecursionHelper(0,-1,maxX,maxY,delay,callback);
}
// each time you call this, it creates a function which holds the variables
// passed in, but incremented by 1.
function delayedRecursionHelper(
curX:Number, cury:Number,
maxX:Number, maxY:Number,
delay:Number, called:Function ):Function
{
return function():void
{
called(curX, curY);
// Exit condition: nothing to do here!
if( curX == maxX && curY == maxY ) return;
if( curY == maxY )
{
curY = -1;
curX++;
}
curY++;
setTimeout(delayedRecursionHelper(curX, curY, maxX, maxY, delay), delay);
}
}
You can not delay the loops in as3.
For this purpose you need to use timers. Some help for your solution you can find here: How to show the current progressBar value of process within a loop in flex-as3?
At the end you just need to modify the function logic.