Flash restart functions after completion - actionscript-3

I have made this code which works fine - my problem is that at the end i wish to make it start over.
When i started making this my intent was, that the .swf movie would just loop when it ended - but that does not happen.
Then i figured that i would try and make a sort of "restart" function in the code itself that would reset the timer and strings..
I have googled around and tried a couple of things myself - But to no luck at all..
First i tried to reset the variable i. Then i tried to remove the timer eventListeners. But with no succes.
What would be the best way to go about getting this code to start over again?
import flash.utils.Timer;
import flash.events.TimerEvent;
import com.greensock.*;
import com.greensock.easing.*;
var str_one:String = 'På fredag udkommer metroXpress, som du kender den, for sidste gang... ';
var i:uint = 0;
var timer_one:Timer = new Timer(50);
timer_one.start();
timer_one.addEventListener(TimerEvent.TIMER, goTime);
var str_two:String = 'På fredag udkommer metroXpress, som du kender den, for sidste gang... Fra 2. april bliver du mødt af en helt ny avis, med det bedste fra den gamle, tilsat en masse nyt.';
var timer_two:Timer = new Timer(50);
timer_two.addEventListener(TimerEvent.TIMER, goTime_two);
var str_three:String = 'På fredag udkommer metroXpress, som du kender den, for sidste gang... Fra 2. april bliver du mødt af en helt ny avis, med det bedste fra den gamle, tilsat en masse nyt.Sådan vil vi skabe en endnu bedre avis til dig, der er på farten. Glæd dig – det gør vi!';
var timer_three:Timer = new Timer(50);
timer_three.addEventListener(TimerEvent.TIMER, goTime_three);
function goTime(e:TimerEvent) {
tekstbox1_txt.appendText(str_one.charAt(i));
i++;
if (i>=str_one.length) {
timer_one.stop();
TweenLite.to(hand, 1, {y:175, onComplete:ripwhite});
}
}
function ripwhite():void {
TweenLite.to(hand, 1, {y:405});
TweenLite.to(white_mask, 1, {y:320, onComplete:fadetekst1ud});
}
function fadetekst1ud():void {
TweenLite.to(tekstbox1_txt, 1, {alpha:0, onComplete:tekstnr2});
}
function tekstnr2():void {
timer_two.start();
}
function goTime_two(e:TimerEvent) {
tekstbox2_txt.appendText(str_two.charAt(i));
i++;
if (i>=str_two.length) {
timer_two.stop();
TweenLite.to(tekstbox2_txt, 1, {alpha:1, onComplete:forsinkelse});
}
}
function forsinkelse():void {
TweenLite.to(tekstbox2_txt, 1, {alpha:0, onComplete:tekstnr3});
}
function tekstnr3():void {
timer_three.start();
}
function goTime_three(e:TimerEvent) {
tekstbox3_txt.appendText(str_three.charAt(i));
i++;
if (i>=str_three.length) {
timer_three.stop();
TweenLite.to(tekstbox3_txt, 1, {alpha:1, onComplete:sidstefunktion});
}
}
function sidstefunktion():void {
TweenLite.to(tekstbox3_txt, 1, {alpha:0});
TweenLite.to(rippedpic, 1, {alpha:0});
}
EDIT:
When setting up a reset function and then making it loop back to my initial function like this:
function nulstil():void {
i = 0;
TweenLite.killTweensOf(hand);
TweenLite.killTweensOf(tekstbox1_txt);
TweenLite.killTweensOf(tekstbox2_txt);
TweenLite.killTweensOf(tekstbox3_txt);
timer_one.addEventListener(TimerEvent.TIMER, goTime);
timer_two.addEventListener(TimerEvent.TIMER, goTime_two);
timer_two.addEventListener(TimerEvent.TIMER, goTime_three);
TweenLite.to(white_mask, 0.1, {onComplete:goTimeAgain});
}
I get the following in the output:
ArgumentError: Error #1063: Argument count mismatch on Untitled_fla::MainTimeline/goTimeAgain(). Expected 1, got 0.
at Function/http://adobe.com/AS3/2006/builtin::apply()
at com.greensock.core::TweenCore/complete()
at com.greensock::TweenLite/renderTime()
at com.greensock.core::SimpleTimeline/renderTime()
at com.greensock::TweenLite$/updateAll()

I suggested in a comment that you use TimelineMax. Here's the full code that I think should work. Note carefully where I use the offset argument of append and where I don't. You'll need to fill out the resetEverything function to set all the visual elements to their proper starting positions, alphas, etc.
Basically how this works: Instead of using Timers we use the addCallback feature of TimelineMax. Callbacks have "length" of 0 in the timeline, so you have to manually advance the playhead when you are attaching the callbacks, and when you add the first tween after each batch of callbacks (that's where we use the offset argument). Tweens do have a length, though, so subsequent calls to append will automatically align the tweens to the end of the timeline as built up to the that point.
In the constructor of the TimelineMax we specified repeat : -1, which will cause the timeline to loop forever. Finally, we added the resetEverything callback at the very beginning so that every time the timeline restarts we are assured that all the elements are in the correct start position. The rest is completely automatic, handled by the timeline.
import com.greensock.*;
var str_one:String = 'På fredag udkommer metroXpress, som du kender den, for sidste gang... ';
var str_two:String = 'Fra 2. april bliver du mødt af en helt ny avis, med det bedste fra den gamle, tilsat en masse nyt.';
var str_three:String = 'Sådan vil vi skabe en endnu bedre avis til dig, der er på farten. Glæd dig – det gør vi!';
//-------- HELPER FUNCTIONS ---------//
// Set everything to start positions
function resetEverything():void {
// Set alphas, positions, etc.
hand.x = <start x>;
hand.y = <start y>;
//
}
// Quick reusable callback
function addText(textBox:TextField, text:String):void { textBox.appendText(text); }
//-------- BUILD THE TIMELINE ---------//
var timeline:TimelineMax = new TimelineMax({repeat : -1}); //repeat = -1 --> loop forever
timeline.pause();
timeline.addCallback(resetEverything, 0);
var lng:uint = str_one.length;
var playHead:Number = 0.05;
for(var i:uint = 0; i < lng; i++) {
timeline.addCallback(addText, playHead, [tekstbox1_txt, str_one.charAt(i)]);
playHead += 0.05;
}
timeline.append(new TweenLite(hand, 1, {y:175}), lng * 0.05); // !!Note the offset argument here!!
timeline.append(new TweenLite(hand, 1, {y:405}));
timeline.append(new TweenLite(white_mask, 1, {y:320}));
timeline.append(new TweenLite(tekstbox1_txt, 1, {alpha:0}));
playHead += 4;
lng = str_two.length;
for(i = 0; i < lng; i++) {
timeline.addCallback(addText, playHead, [tekstbox2_txt, str_two.charAt(i)]);
playHead += 0.05;
}
timeline.append(new TweenLite(tekstbox2_txt, 1, {alpha:1}), lng * 0.05); // !!Note the offset argument here!!
timeline.append(new TweenLite(tekstbox2_txt, 1, {alpha:0}));
playHead += 2;
lng = str_three.length;
for(i = 0; i < lng; i++) {
timeline.addCallback(addText, playHead, [tekstbox3_txt, str_three.charAt(i)]);
playHead += 0.05;
}
timeline.append(new TweenLite(tekstbox3_txt, 1, {alpha:1}), lng * 0.05); // !!Note the offset argument here!!
timeline.append(new TweenLite(tekstbox3_txt, 1, {alpha:0});
timeline.append(new TweenLite(rippedpic, 1, {alpha:0});
timeline.play();

Related

ActionScript 3.0: Moving to another scene by clicking a button

I have created the first scene of my small project. Now I want to move to the second scene of the app. The start one is called startScene, the second one playScene. Here is the code of the class linked to the first scene:
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.events.MouseEvent;
public class dragMain extends MovieClip {
public function dragMain() {
setWelcomeMessage();
drawArrow();
createStartButton();
}
// funzione per settare il messaggio di benvenuto
function setWelcomeMessage(): void {
// TextField contenete il messaggio di benvenuto
var welcomeMessage: TextField = new TextField();
// formattazione per il messaggio di benvenuto
var welcomeFormat: TextFormat = new TextFormat("Verdana", 40, 0xFF0000);
// imposto il testo da visualizzare
welcomeMessage.text = "Welcome, click the button to start playing";
//
welcomeMessage.autoSize = TextFieldAutoSize.LEFT;
// cerco di centrare il testo ad occhio nella schermata
welcomeMessage.x = 500;
// applico la formattazione al testo
welcomeMessage.setTextFormat(welcomeFormat);
// aggiungo il testo allo stage
addChild(welcomeMessage);
}
// funzione che disegnera' la freccia
function drawArrow(): void {
// Sprite che conterra' la freccia disegnata
var arrow: Sprite = new Sprite();
arrow.graphics.beginFill(0XFF0000);
arrow.graphics.moveTo(800, 100); //500,500 // 200,200
arrow.graphics.lineTo(1000, 100); //700,500 // 400,200
arrow.graphics.lineTo(1000, 550); //700,950 // 400,650
arrow.graphics.lineTo(1100, 550); //800,950 // 500,650
arrow.graphics.lineTo(900, 700); //600,1100// 300,800
arrow.graphics.lineTo(700, 550); //400,950 // 100,650
arrow.graphics.lineTo(800, 550); //500,950 // 200,650
arrow.graphics.lineTo(800, 100); //500,500 // 200,200
addChild(arrow);
}
// funzione per creare il bottone
function createStartButton(): void {
var button: Sprite = new Sprite();
button.graphics.beginFill(0xFF0000);
button.graphics.moveTo(700, 800);
button.graphics.lineTo(1100, 800);
button.graphics.lineTo(1100, 1000);
button.graphics.lineTo(700, 1000);
button.graphics.lineTo(700, 800);
var clickMeMessage: TextField = new TextField();
clickMeMessage.x = 855;
clickMeMessage.y = 865;
var welcomeFormat: TextFormat = new TextFormat("Verdana", 40, 0x000000);
// imposto il testo da visualizzare
clickMeMessage.text = "click me!";
//
clickMeMessage.autoSize = TextFieldAutoSize.CENTER;
// applico la formattazione al testo
clickMeMessage.setTextFormat(welcomeFormat);
addChild(button);
addChild(clickMeMessage);
button.addEventListener(MouseEvent.CLICK, onClick);
}
function onClick(evt: MouseEvent): void {
gotoAndPlay(1, "playWindow");
}
}
}
When I click the button that I created through code I'm always on the startScene and I can't move to the playScene. I have got a frame on startScene and a frame on playScene. What's the problem and how can I solve it? Thank you!
First things first.
You have done gotoAndPlay so it will keep iterating between all the scenes on frame 1
gotoAndStop(1,"playScene");
If you don't want all the stuffs you have added on start scene you should remove them or set their visibility to false because addchild adds the object to the stage
This is what i did.I made the following variables global
var welcomeMessage: TextField;
var button: Sprite;
var clickMeMessage: TextField;
var arrow: Sprite;
and changed the onclick function a bit
function onClick(evt: MouseEvent): void {
button.visible = false;
clickMeMessage.visible = false;
arrow.visible = false;
welcomeMessage.visible = false;
gotoAndStop(1, "playScene");
}
well i think this should work
Try gotoAndStop(1, "playWindow"); instead of gotoAndPlay(). I suspect you don't have a stop() on frame 1 of your playScene so Flash is continuing past that scene.

move enemy to the left

I'm still struggling with as3. My enemy won't move from right to left. The other side is no problem. Does anybody no what i'm doing wrong? The trace goleft is work.
package {
import flash.display.MovieClip;
import flash.events.Event;
public class mcEnemy extends MovieClip {
public var sDirection:String;
private var nSpeed:Number;
public function mcEnemy()
{
addEventListener(Event.ADDED_TO_STAGE, onAdd);
}
private function onAdd (e:Event): void
{
removeEventListener(Event.ADDED_TO_STAGE, onAdd);
init();
}
//radom enemy's worden gekozen
private function init ():void
{
// 3 frames
var nEnemies:Number = 3;
// pick random number between 1 and number of enemies
var nRandom:Number = randomNumber (1, nEnemies);
// Setup our playhead of this enemy clip to a random number
// Stop op frame 1,2 of 3
this.gotoAndStop(nRandom);
// Setup our enemys start position
setupStartPosition();
}
private function setupStartPosition (): void
{
// pick a random speed for the enemy
nSpeed = randomNumber (5,10);
// Pick random number for left or right, tussen 1 en 2, start position
var nLeftOrRight:Number = randomNumber (1,2);
// if our nLeftOrRight == 1 , enemy is on the left
if (nLeftOrRight == 1)
{
// start enemy on the left side
this.x = - (this.width/2);
sDirection = "R";
//trace ("right");
} else
{
// start enemy on the right side
this.x = stage.stageWidth + (this.width/2);
sDirection = "L";
//trace("left");
}
// set a random hoogte for our enemy
// set a 2 varibele for min and max hoogte
var nMinAltitude: Number = stage.stageHeight/2;
var nMaxAltitude: Number = 720 - (this.height/2);
// Setup our enemies altitude to a random point between our min and max altitudes
this.y = randomNumber (nMinAltitude, nMaxAltitude);
// move our enemy
startMoving ();
}
private function startMoving (): void
{
addEventListener(Event.ENTER_FRAME, enemyLoop)
}
private function enemyLoop (e:Event ): void
{
// test in what direction our enemy is moving
// if our enemy is moving right
if (sDirection == "R")
{
// move our enemy right
this.x += nSpeed;
//trace ("goright");
} else
{
// move our enemy left
this.x -= nSpeed;
//trace ("goleft");
}
}
// geeft random nummer tussen 0 en 1 en stuurt het terug
function randomNumber (low:Number=0, high:Number=1) : Number
{
return Math.floor (Math.random() * (1+high-low)) + low;
}
public function destroyEnemy (): void
{
// remove enemys from the stage
if (parent) {
parent.removeChild(this);
}
// remove any eventlisteners from enemy
removeEventListener(Event.ENTER_FRAME, enemyLoop);
}
}
}
I hope someone can help me. Sorry for my bad english.
As far as i can see and think of, is that "var nLeftOrRight:Number = randomNumber (1,2);" creates a random number between 1 and 2, with decibels(1.2929291 for instance), and then you turn it into an int, which makes the possibility of 1 REALLY high, and the chance of 2 REALLY low..., if this is the case don't make it randomNumber(1,2), but randomNumber(1,3), then to catch the 'possible' 3 you need to make an if for when it's 3 and turn it into eighter 1 or 2...
I could be wrong about the random number generation thingy though so excuse me if i give wrong information
What happens when it's supposed to move to the left? does it allways just move right or does it just sometimes go right and sometimes not move at all?

AS3 : Load image from xml

I try to load images from xml.
My script is on frame 1.
var fichierXML:URLRequest = new URLRequest("datas.xml");
//Chargement du fichier
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onLoaded);
loader.load(fichierXML);
//Traitement des données
function onLoaded(e:Event):void
{
//Récupération des données du fichier XML
var xml:XML = new XML(e.target.data);
//Extraction des données généralistes
var Name:XMLList = xml.list.name;
var pictureProfilOriginal:XMLList = xml.list.pictureProfilOriginal;
var pictureProfil:XMLList = xml.list.pictureProfil;
var totalView:XMLList = xml.list.totalView;
var totalLoves:XMLList = xml.list.totalLoves;
loadImage(image01, "crop_image_1.jpg");
}
function loadImage(mc:MovieClip, urlReq:String):void {
var loader:Loader = new Loader();
mc.addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, doneLoad);
// start loading
loader.load(new URLRequest(urlReq));
}
function doneLoad(e:Event):void {
e.target.loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, doneLoad);
// smoothing the bitmap
var bit:Bitmap = e.target.content;
if(bit != null)
bit.smoothing = true;
}
When my clip "image01" is on frame 1, it load my image crop_image_1.jpg, but if my clip "image01" is on frame 2, i have this error :
TypeError: Error #1009: Il est impossible d'accéder à la propriété ou à la méthode d'une référence d'objet nul.
at Film_animation_fla::MainTimeline/loadImage() [Film_animation_fla.MainTimeline::frame1:68]
at Film_animation_fla::MainTimeline/onLoaded() [Film_animation_fla.MainTimeline::frame1:62]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
I begin with actionscript, maybe anyone have an idea to help me.
Thanks
Try not to use more than one frame if you can. The target movie clip being on frame 2 means that is does not exist when you are trying to add the child to it "mc.addChild(loader);".
If you really need two frames, extend the key frame of the image01 to start from frame 1, and if it's not empty hide the movie clip. You will have to show image01 again when you arrive at frame 2.

As3 collision test

Im doing a space invaders game in flash when i came to collisions i had a 1061 error possibly undefined hittestobject through a reference with a static type class....
How can i fix that? tried many ways can't get rid of that error
/* Código que pára a timeline na 1 frame para que o menu continue apresentado*/
stop();
/*Movimenta a nave fazendo a seguir os movimentos do rato e esconde o cursor do sistema operacional*/
stage.addChild(arma_tiro);
arma_tiro.mouseEnabled = false;
arma_tiro.addEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor);
function fl_CustomMouseCursor(event:Event)
{
arma_tiro.x = stage.mouseX;
}
Mouse.hide();
/* Mouse Click Event
Clicking on the specified symbol instance executes a function in which you can add your own custom code.
Instructions:
1. Add your custom code on a new line after the line that says "// Start your custom code" below.
The code will execute when the symbol instance is clicked.
*/
stage.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler_3);
function fl_MouseClickHandler_3(event:MouseEvent):void
{
var bullet:bullet_ = new bullet_();
addChild(bullet);
bullet.x=arma_tiro.x;
bullet.y=arma_tiro.y;
bullet.addEventListener(Event.ENTER_FRAME, moverbala);
}
function moverbala(event:Event):void // função para mover a bala para cima */
{
event.target.y=event.target.y-20;
}
//stage.addEventListener(Event.ENTER_FRAME, Primeira);
setInterval(Primeira, 1000) ; //define intervalo de tempo entre as varias repetiçoes da funçao
function Primeira(){ //funçao de spawn de nave 1
var invader1:invader_1 = new invader_1();
addChild(invader1);
invader1.x=0;
invader1.y=15;
invader1.addEventListener(Event.ENTER_FRAME, mover1);
}
function mover1(event:Event):void // função para mover a nave para lado direito */
{
event.target.x+=10;
}
//Nave 2
setInterval(Segunda, 1000) ; //define intervalo de tempo entre as varias repetiçoes da funçao
function Segunda(){ //funçao de spawn de nave 1
var invader2:invader_2 = new invader_2();
addChild(invader2);
invader2.x=0;
invader2.y=45;
invader2.addEventListener(Event.ENTER_FRAME, mover2);
}
function mover2(event:Event):void // função para mover a nave para lado direito */
{
event.target.x+=10;
}
//Nave 3
setInterval(Terceira, 1000) ; //define intervalo de tempo entre as varias repetiçoes da funçao
function Terceira(){ //funçao de spawn de nave 1
var invader3:invader_3 = new invader_3();
addChild(invader3);
invader3.x=0;
invader3.y=85;
invader3.addEventListener(Event.ENTER_FRAME, mover3);
}
function mover3(event:Event):void // função para mover a nave para lado direito */
{
event.target.x+=10;
}
// error line
if (bullet_.hitTestObject(invader_1))
{
//Remove bullet and enemy
mcGameStage.removeChild(bullet_);
mcGameStage.removeChild(invader_1);
}
it seems that bullet_ is a class and not an instance so you cannon call hitTestObject on it.
maybe try replace bullet_ by bullet.
there are many solution to do that but the simplest for me would be to keep 2 array, one for the bullets, one for the enemies.
so add arrays:
// create the array for the bullets
bullets :Array = [];
// create the array for the enemies
enemies :Array = [];
add an onEnterFrame event listener to do the tests and the game logic on each frame:
addEventListener( Event.ENTER_FRAME, _gameLoop );
change your function to create bullets and enemies:
function fl_MouseClickHandler_3( event:MouseEvent ):void
{
// create the bullet
var bullet:bullet_ = new bullet_();
addChild(bullet);
bullet.x=arma_tiro.x;
bullet.y=arma_tiro.y;
// add the bullet to the bullets array
bullets.push( bullet );
}
function Primeira():void
{
var invader1:invader_1 = new invader_1();
addChild(invader1);
invader1.x=0;
invader1.y=15;
enemies.push( invader1 );
}
function Segunda():void
{
var invader2:invader_2 = new invader_2();
addChild(invader2);
invader2.x=0;
invader2.y=45;
enemies.push( invader2 );
}
function Terceira():void
{
var invader3:invader_3 = new invader_3();
addChild(invader3);
invader3.x=0;
invader3.y=85;
enemies.push( invader3 );
}
now create the game loop function:
function _gameLoop():void
{
var firstLoop:Boolean = true;
// loop to move/remove the bullets
for( var a:int = bullets.length-1; a>=0; a-- )
{
bullets[a].y -= 20;
// if the bullet is not on screen anymore, remove it from array
if( bullets[j].y < 0 )
{
removeChild( bullet[a] );
bullets.splice(a,1);
continue;
}
}
// loop enemies
for( var i:int = enemies.length-1; i>=0; i-- )
{
// move the enemy
enemies[i].x += 10;
// loop the bullets to see if on collide the enemy
for( var j:int = bullets.length-1; j>=0; j-- )
{
// test collision with the enemy
if( enemies[i].hitTestObject( bullets[j] )
{
// make your enemy dead
removeChild( enemies[i] );
// remove it from the array
enemies.splice(i,1);
}
}
}
}
Hope this could helps you

How to add a sprite to box2d body?

I fixed. Problem solved.
I'm new in as3 and box2D, so at least I'm learning. I have a problem to add my sprites(movieclip) to a dynamic body. The sprite appear but it give me an error and because of that all the game-prototype works bad. With the statics I don't have any problem. What can I do?
This is my code:
Before the code I set them as a variable:
private var player:b2Body;
private var mc_player:MovieClip;
Firstly the function of my dynamic body:
public function createPlayer(px:int, py:int):void
{
mc_player = new _pork();
addChild(mc_player);
var playerDef:b2BodyDef = new b2BodyDef();
playerDef.position.Set(px / worldScale, py / worldScale);
playerDef.type = b2Body.b2_dynamicBody;
var playerShape:b2PolygonShape = new b2PolygonShape();
playerShape.SetAsBox(25 / 2 / worldScale, 40 / 2 / worldScale);
var playerForce:b2FixtureDef = new b2FixtureDef();
playerForce.shape = playerShape;
player = world.CreateBody(playerDef);
player.CreateFixture(playerForce);
}
Then a function to add the mc(movieclip):
private function drawPlayer():void
{
mc_player.x = player.GetPosition().x * worldScale;
mc_player.y = player.GetPosition().y * worldScale;
}
And in the update I just call it:
private function update(e:Event):void
{
drawPlayer();
}
The other proprieties I added, like set forces and gravity, this is not the problem.
This are the part where I think is the problem...
The error in flash:
TypeError: Error #1009: No se puede acceder a una propiedad o a un
método de una referencia a un objeto nulo. at Main/drawPlayer() at
Main/update()
I don't have any idea how can I fix it
Any help, please..
Thx everyone!
Edit:
Solution:
Sorry everyone I fail in my code. The error was that I never said to the game call the player when it is in the stage(I means the in the level) and not in the menu...because of this I was calling the player before appear the player. Sorry about my mistake..
So is something like that to call the movieclip player:
private function update(e:Event):void
{
//Call movieclips
if (mc_player) {
drawPlayer(); }
}
When/how is update() getting called? Is it a matter that you've created the callback before the mc_player has been initialized?