stoping a yoyo() Tween within a function - actionscript-3

I am wanting to stop this yoyo movement when a sound stops.
This is not all the code but the important parts:
I DECLARED THE VAR OUTSIDE OF THE FUNCTION:
var BB:Tween;
........
function BounceBeau()
{
var BB:Tween = new Tween(Beau,"y",Strong.easeOut,stage.stageHeight - BeauHeight,33,5,false);
BB.addEventListener(TweenEvent.MOTION_FINISH, PlayBB);
function PlayBB(e:TweenEvent):void
{
BB.yoyo();
}
}
THE BOUNCE STARTS WITH SOUND AND STOPS WHEN OVER.
function PlaySound()
{
var ThemeSong:SoundChannel;
var s:Sound = new Sound(new URLRequest("MySound.mp3"));
ThemeSong = s.play();
...
BounceBeau();
...
ThemeSong.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
function onPlaybackComplete(event:Event):void
{
BounceBeauStop();
}
}
...
THIS CODE WAS IN BUT I FORGOT TO POST IT
function BounceBeauStop()
{
BB.stop();
}
THE ERROR I GET:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
Any Thoughts. :)

In your BounceBeau(), change var BB:Tween to just BB. You are inadvertently shadowing the declaration of BB by redeclaring it locally.
function BounceBeau()
{
BB = new Tween( ...
...

I believe you get that error here:
var ThemeSong:SoundChannel;
var s:Sound = new Sound(new URLRequest("MySound.mp3"));
ThemeSong = s.play();
Because you are not instantiating a new SoundChannel variable. Then, when you try to play the sound, and pass it to the channel, the latter one is not defined. I think you should try updating your code this way:
var themeSong:SoundChannel = new SoundChannel();
var s:Sound = new Sound(new URLRequest("MySound.mp3"));
themeSong = s.play();
Let us know if it works out. Have a great day.

Related

Remove the clicked objects

I'm trying to remove the array objects that are being clicked and add them into another array to display them else where. I posted the current code.
I think the problem maybe with .currentTarget. I tried replacing the .currentTarget to .target but the function wasn't getting past this line : if (socket_Array[i] == in_event.target) (in this version its .currentTarget, I am just saying when I tried changing it to .target)
The error I get is this:
TypeError: Error #1034: Type Coercion failed: cannot convert []#2c2a8f11 to flash.display.DisplayObject.
Function that creates the objects:
function createSockets():void
{
var socket_one:socket = new socket ();
var socket_two: socketyellow = new socketyellow ();
var socket_three: socketdarkorange = new socketdarkorange ();
var socket_four: socketlightgreen= new socketlightgreen ();
var socket_five: socketpurple = new socketpurple ();
var socket_six: socketdarkgreen = new socketdarkgreen ();
socket_Array.push(socket_one, socket_two,socket_three, socket_four, socket_five, socket_six);
for (var i:int=0; i<socket_Array.length; i++)
{
addChild(socket_Array[i]);
socket_Array [i].x = socket_x_position;
socket_Array [i].y = socket_y_position;
socket_Array[i].addEventListener(MouseEvent.MOUSE_DOWN, removeItemOnClick);
}
temp_update ();
}
Function that is suppose to get rid of the object clicked and add it to an array.
function removeItemOnClick(in_event:MouseEvent):void
{
var i:int = 0;
for (i=0; i<socket_Array.length; i++)
{
if (socket_Array[i] == in_event.currentTarget)
{
trace ("it goes here");
var removed = socket_Array.splice(i, 1);
trace (removed);
trace (socket_Array );
var drop:Sprite = in_event.currentTarget as Sprite;
removeChild (drop);
removedItem[removedItem.length] = removed;
createremovedItem ();
trace (removedItem);
updateDisplay ();
choice_updateDisplay ();
}
}
}
var removedItem_position = 0
function createremovedItem () {
for (removedItem_position; removedItem_position<removedItem.length; removedItem_position++){
addChild (removedItem [removedItem_position]);
}
}
First of all, .currentTarget is correct.
Secondly, there's no point in calling removeChild() and then calling addChild(). The net effect of both calls is nothing.
Almost all of the code in the second function is unnecessary. Here's a shorter version:
function removeItemOnClick(in_event:MouseEvent):void {
var index:int = socket_Array.indexOf(in_event.currentTarget);
var drop:Sprite = socket_Array.splice(index,1) as Sprite;
removedItem.push(drop);
updateDisplay();
choice_updateDisplay();
}
If you want to display the new item elsewhere, just change drop.x and drop.y.
As the error suggests it looks like it is problem with type coercion.
Try to replace the condition of your if statement with this:
if (DisplayObject(socket_Array[i]) == DisplayObject(in_event.currentTarget))
In case this is not working your might have more information while debugging by storing the two objects you want to compare into temporary variables

actionscript 3.0 function calling using button click

im creating a simple flash playlist using buttons, in my stage i have 4 buttons which is button for song1,song2, stop and play. i have a working code for this one, but i decided to revise it because my previous code is like, per song they have each stop and play button,so i created this one to have a dynamic stop and play, i created a function for each song, the function will change the filename of the song to be loaded,
heres the catch, so i first pick a song, (either song1 or song2) then i click stop, then when i select a new song this error appears
Error: Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
at flash.media::Sound/_load()
at flash.media::Sound/load()
at playlist_fla::MainTimeline/songSelect1()
i think its not calling the second function because i cant see the trace i put inside it,anyway heres my code, sorry for the long post,
THANKS IN ADVANCE
var mySound:Sound = new Sound();
var myChannel:SoundChannel = new SoundChannel();
var myTransform = new SoundTransform();
var lastPosition:Number = 0;
var song;
song1.addEventListener(MouseEvent.CLICK,songSelect1);
function songSelect1(e:MouseEvent):void{
song = "<filenameofthe1stsong>";
mySound.load(new URLRequest(song));
myTransform.volume = 0.5;
myChannel.soundTransform = myTransform;
lastPosition=0;
trace(1);
}
song2.addEventListener(MouseEvent.CLICK,songSelect2);
function songSelect2(e:MouseEvent):void{
song = "<filenameofthe2ndsong>";
mySound.load(new URLRequest(song));
myTransform.volume = 0.5;
myChannel.soundTransform = myTransform;
lastPosition=0;
trace(2);
}
btnStop.addEventListener(MouseEvent.CLICK,onClickStop);
function onClickStop(e:MouseEvent):void{
lastPosition = myChannel.position;
myChannel.stop();
}
btnPlay.addEventListener(MouseEvent.CLICK,onClickPlay);
function onClickPlay(e:MouseEvent):void{
myChannel = mySound.play(lastPosition);
myChannel.soundTransform = myTransform();
}
Correction:
According to Adobe:
Once load() is called on a Sound object, you can't later load a
different sound file into that Sound object. To load a different sound
file, create a new Sound object.
So, creating a new sound object would be the only way to fix it.
- - - Original Post - - -
If you enable debugging in your flash settings, it'd be easier to determine exactly what line is causing issues. That said, your code doesn't look incorrect apart from defining your sound transform twice. Try this:
var mySound:Sound = new Sound();
var myChannel:SoundChannel = new SoundChannel();
var myTransform = new SoundTransform();
myChannel.soundTransform = myTransform;
var lastPosition:Number = 0;
var song;
song1.addEventListener(MouseEvent.CLICK,songHandler);
song2.addEventListener(MouseEvent.CLICK,songHandler);
btnStop.addEventListener(MouseEvent.CLICK,onClickStop);
btnPlay.addEventListener(MouseEvent.CLICK,onClickPlay);
function songHandler(e:MouseEvent):void {
switch (e.currentTarget.name) {
case "song1":
songSelect("<filenameofthe1stsong>")
break;
case "song2":
songSelect("<filenameofthe2ndsong>")
break;
}
}
function songSelect(songPath:String):void {
mySound.load(new URLRequest(songPath));
myChannel.soundTransform.volume = 0.5;
lastPosition = 0;
trace("Loading " + songPath);
}
function onClickStop(e:MouseEvent):void {
lastPosition = myChannel.position;
myChannel.stop();
}
function onClickPlay(e:MouseEvent):void {
myChannel = mySound.play(lastPosition);
myChannel.soundTransform = myTransform();
}

Refreshing every XX seconds

I am new to actionscript and flash, but i managed to make code that gets data from php file and refresh result every 30 seconds:
var timerRefreshRate:Number = 30000;
var fatherTime:Timer = new Timer(timerRefreshRate, 0);
fatherTime.addEventListener(TimerEvent.TIMER, testaa);
fatherTime.start();
function testaa(event:Event):void{
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE,varsLoaded);
loader.load(new URLRequest("data.php"));
function varsLoaded (event:Event):void {
this.opaqueBackground = loader.data.color;
title.text=loader.data.title;
banner_text.text=loader.data.text;
}
}
But now i am facing 2 problems:
1.) User must wait 30 seconds for movie to load first time
2.) Setting background color does not work any more.
What am i doing wrong?
You can call your function once to load immediately without waiting 30 seconds. Just change the parameters of the function to default to a null event:
function testaa(event:Event = null):void{
//...
}
Now you can call the function like so:
//...
fatherTime.start();
testaa();
So you start the timer but immediately run the function once.
For your second problem, the issue is most likely that you are using a nested function, so this does not refer to your class but rather the testaa function. Nested functions are bad practice in general and you should avoid them if possible. Move the function and loader reference outside and it should work. Final result should be something like this:
var loader:URLLoader;
var timerRefreshRate:Number = 30000;
var fatherTime:Timer = new Timer(timerRefreshRate, 0);
fatherTime.addEventListener(TimerEvent.TIMER, testaa);
fatherTime.start();
testaa();
function testaa(event:Event = null):void{
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE,varsLoaded);
loader.load(new URLRequest("data.php"));
}
function varsLoaded (event:Event):void {
this.opaqueBackground = loader.data.color;
title.text=loader.data.title;
banner_text.text=loader.data.text;
}

passing parameters to addEventListener AS3

I am struggling passing paramters to function on onComplete event handler.
It seems that my problem is with the event.Complete code..
I just want to load image from a url and transfer parameter.
This is my code:
var imageURLRequest:URLRequest = new URLRequest(pic);
var myImageLoader:Loader = new Loader();
myImageLoader.load(imageURLRequest);
myImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(evt:Event.COMPLETE){
doIt(evt, "Shift key was down:")
},false,0, true);
function doIt(evt:Event, msg:String) {
var myBitmapData:BitmapData = new BitmapData(myImageLoader.width, myImageLoader.height);
myBitmapData.draw(myImageLoader);
var myBitmap:Bitmap = new Bitmap;
myBitmap.bitmapData = myBitmapData;
}
Thank you very much.
Remove .COMPLETE from the handler inner function so that your listener looks like this:
myImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(evt:Event)
{
doIt(evt, "Shift key was down:")
} , false, 0, true);
Look at the Loader class as loader, not as DisplayObject even when it is:
var myBitmap:Bitmap;
var contentLoader:Loader = new Loader();
contentLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);
contentLoader.load(imageURLRequest);
function handleComplete(e:Event):void
{
myBitmap = contentLoader.content as Bitmap;
}
Firstly, as Gio said, remove that .COMPLETE from evt:Event.COMPLETE because it's returning a String instead of the Event the function needs.
Then, instead of setting that last fearsomely unpredictable parameter (useWeakReference) to true in your addEventListener(), I recommend you keep the reference in a variable to use removeEventListener() on it at the right time. A way to do this (while answering your question) is:
var imageURLRequest:URLRequest = new URLRequest(pic);
var myImageLoader:Loader = new Loader();
myImageLoader.load(imageURLRequest);
var functionDoIt:Function = doIt("Shift key was down:");
myImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, functionDoIt);
function doIt(msg:String):Function {
return function(evt:Event):void {
// Now you can use both "msg" and "evt" here
var myBitmapData:BitmapData = new BitmapData(myImageLoader.width, myImageLoader.height);
myBitmapData.draw(myImageLoader);
var myBitmap:Bitmap = new Bitmap(myBitmapData);
}
}
// Remove the listener when you don't need it anymore:
//myImageLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, functionDoIt);
You can understand this solution better by reading this answer.

as3 loop loading urls - continue loop on complete

I am trying to load a bunch of files in order. I want the other to start downloading once the previous has downloaded. I thought the best way to do this would be thru a for loop.
TheURL = is a bunch of urls in a ARRAY
for(var i:int=0;i<TheURL.length;i++)
{
var urlString:String = TheURL[i];
var urlReq:URLRequest = new URLRequest(urlString);
var urlStream:URLStream = new URLStream();
var fileData:ByteArray = new ByteArray();
urlStream.addEventListener(Event.COMPLETE, loaded);
urlStream.load(urlReq);
function loaded(event:Event):void
{
/// code to continue loop
}
}
It is important that the others do not start downloading until the previous has completed. Any suggestions on how to do that? Thanks
function downloadFiles():void
{
downloadNextFile();
}
function downloadNextFile():void
{
var urlString:String = TheURL.shift();
var urlReq:URLRequest = new URLRequest(urlString);
var urlStream:URLStream = new URLStream();
var fileData:ByteArray = new ByteArray();
urlStream.addEventListener(Event.COMPLETE, loaded);
urlStream.load(urlReq);
}
function loaded(event:Event):void
{
downloadNextFile();
}
Using a for-loop does not solve what you want to do.
In my opinion the easiest way should be to use the array of URLs as a queue. This can be done by using Array.shift(). But you should make a copy of your array if you need the original set of URLs when finished, because shift() makes an inline modification of the array.
The solution could be the following:
function loadQueue(urlQueue:Array):void
{
var url:String = urlQueue.shift();
var request:URLRequest = new URLRequest(url);
var stream:URLStream = new URLStream();
var data:ByteArray = new ByteArray();
var completeHandler:Function = function(event:Event)
{
// remove listener from stream to be a clean coder ;)
stream.removeEventListener(Event.COMPLETE, completeHandler);
// handle completion in the way you need ...
// continue with the next element
if (urlQueue.length > 0)
loadQueue(urls);
}
urlStream.addEventListener(Event.COMPLETE, loaded);
urlStream.load(urlReq);
}
Loading your queue will then look like:
loadQueue(TheURL.concat()); // concat() will clone your array
You should use a library like greensock LoaderMax http://www.greensock.com/loadermax/.
It's much more difficult than it seems to create your own loading queue. There are plenty of bugs, traps and special cases to deal with. It seems to work fine, and one day a customer call you back because of a bug on this particular flash version on this computer behind this firewall... I've started to do mine library, but finally I used LoadManager.