How to control sound/music playblack in AS3 - actionscript-3

I'm making a game with AS3. I would like to put a different music in each background.
So far, I've succeed to start the music when the player enters in a scene. But if he goes out, the music is still playing...(I want the music to stop when the players leave a scene).
I don't understand why the music is still playing.. Here's my code :
public function newBackground(thisBack:String):void{
var room = back.currentBack;
switch (thisBack){
case "maisonExt":
var mySound:Sound = new exterieur ();
mySound.play ();
My mp3 file is named "exterieur.mp3".
If you can think of anything it would be a great help.
Thanks !

You need to stop the music again. If you don't stop it, it will keep on playing :)
When you call .play it will return a SoundChannel which lets you control the playback -- changing position, stopping the playback, and accessing the SoundTransform which lets you control the volume. Here is some example code for you:
public var currentSoundChannel:SoundChannel;
public function newBackground(thisBack:String):void
{
var room = back.currentBack;
if (currentSoundChannel != null)
{
currentSoundChannel.stop()
}
var nextSong:Sound;
switch (thisBack){
case "maisonExt":
nextSong = new exterieur ();
break;
}
currentSoundChannel = nextSong.play();
}
If you want to learn more about sound, I would recommend this tutorial http://gamedev.michaeljameswilliams.com/2009/03/03/avoider-game-tutorial-9/. It's part of a larger tutorial which teaches you many aspects of game making, taking you from novice to capable of creating a game. You should really check that out.

Related

AS3 tween object not working with .hitTestObject()

I am having a major problem in my new browser app.
Okay so I made game where different cubes (squares) spawn at the top of the screen and I use the Tween class to make them go down the screen and then disappear.
However I want to detect a collision when a cube hits the player (that is also a flying cube).
I tried everything, truly everything but it does not seem to work. The problematic thing is that when I remove the "Tween" function it does detect collision with the hitTestObject method but when I add the "Tween" line collision won't be detected anymore.
It looks like this:
function enemiesTimer (e:TimerEvent):void
{
newEnemy = new Enemy1();
layer2.addChild(newEnemy);
newEnemy.x = Math.random() * 700;
newEnemy.y = 10;
if (enemiesThere == 0)
{
enemiesThere = true;
player.addEventListener(Event.ENTER_FRAME, collisionDetection)
}
var Tween1:Tween = new Tween(newEnemy, "y", null, newEnemy.y, newEnemy.y+distance, movingTime, true);
}
And the collision detection part:
private function collisionDetection (e:Event):void
{
if (player.hitTestObject(newEnemy))
{
trace("aaa");
}
}
I am desperate for some information/help on the topic, it's been bugging me for days.
Thanks for your time, I would be very happy if someone could help me out^^
First, make sure the "newEnemy" instance and the "player" instance are within the same container. If they are not, their coordinate systems might not match up and could be the source of your problem.
Otherwise, you need to keep a reference to each enemy instance you create. It looks like you are only checking against a single "newEnemy" variable which is being overwritten every time you create a new enemy. This might be why you can successfully detect collision between the player and the most recent "enemy" instance.
So... you need a list of the enemies, you can use an Array for that.
private var enemyList:Array = [];
Every time you create an enemy, push it to the Array.
enemyList.push(newEnemy);
In your "collisionDetection" function, you need to loop through all of the enemies and check if the player is touching any of them.
for(var i:int = 0; i < enemyList.length; i++)
{
var enemy = enemies[i];
if (player.hitTestObject(enemy))
{
trace("Collision Detected!");
enemy.parent.removeChild(enemy); // remove the enemy from the stage
enemies.splice(i, 1); // remove the enemy from the list
}
}
I'd suggest that you move to TweenMax, it just might solve your problem, and in my experience it's much better in every possible way.
Scroll down the following page to see a few variations of this library, I myself use TweenNano, they're completely free of charge:
https://greensock.com/gsap-as
I think some plugins cost money, but I doubt you'll ever need them.

nonClickable buttons after loading same FLA 2nd time

Basically Im trying to make a FLA where if i click a button and close the FLA, next time I load the same FLA, the buttons that have been clicked before , now have an alpha of 0.5 and are nonClickable.
Currently i have only the logic for creating the buttons and saving the data:
private var savedData:SharedObject = SharedObject.getLocal("sharedStorage10");
private var buttonInfoArr:Array = [];
public function Main()
{
for (var i:int = 0; i < 4; i++)
{
var myImage_mc:MovieClip = new MovieClip();
myImage_mc.graphics.beginFill( 0xFFFFFF * Math.random() );
myImage_mc.graphics.drawRect(0,0,100,100);
myImage_mc.graphics.endFill();
myImage_mc.x = 50 + i * (myImage_mc.width + 10);
myImage_mc.y = 100;
myImage_mc.name = "myImage_mc" + i
this.addChild(myImage_mc);
myImage_mc.mouseEnabled = true;
myImage_mc.buttonMode = true;
myImage_mc.addEventListener(MouseEvent.CLICK, onClick);
}
}
private function onClick(ev:MouseEvent):void
{
var thisButton:MovieClip = ev.currentTarget as MovieClip
trace(thisButton.name)
thisButton.alpha = 0.5
thisButton.buttonMode = false;
thisButton.removeEventListener(MouseEvent.CLICK, onClick);
buttonInfoArr.push( thisButton.name );
savedData.data.myArray = buttonInfoArr;
}
But i dont know how to load/use the data and make the buttons (that have been clicked before) start with an alpha of 0.5 and without an EventListener(MouseEvent.CLICK, onClick)
PS:Could it be done without the use of Dictionary, cause i haven`t grasp my mind over it yet.
_EDIT__
to represent my problem in a more detailed way:
So im creating a game in which I collect objects that represent money.After I die in the game i get into the Shop Class in which i can buy different items depending on the money i have.
So lets say that after dying i have enough money to get item1 and item2. So i Click on button1 (representing item1) and button2 (representing item2) (when clicked their alpha gets to 0.5) and start the game again.Ok so now i have 1 life more and i get more money.But suddenly out of nowhere i feel something strange deep in me, something that i have never felt before -> HUNGER,
I shut down the PC (cause I love Earth )and run as fast as possible to the nearest shop.
lets say item1 is : +1life and item2 is : get more money from objects
After I had satisfied my primal needs I feel the strong urge to play that awesome game of mine again. But when i start the game I start to see some strange things: It seems that I havent got one life more and neither do i get more money and just to be sure that Im not hallucinating (or that i didnt rememer the lifes i had last time) I die on purpose so the Shop menu shows. So now what I see is making me sad -> button1 and button2 are active and have an alpha of 1( and that means that the game thinks that they were never bought/clicked, that i have never played this game before in my life)
So i go crazy (cause all that play before was for nothing and i have to start all over again).
After i calm down, I decide to change my life. 1st BIG change is adding some code into the game. To be more specific: a method that will save the items that i bougth, so when i close the game and start again the things i see will bring joy to my life - >: I still have the items that i bougth last time.
So long story short:
how do i make that when i click a button (it changes its alpha to 0.5)and close the FLA ,
whenever i open the same FLA, the button that i clicked before will be shown as clicked now(it alpha will be 0.5)
What is happening is normal. All variables are stored in RAM, which is temporary memory. Your button states are variables, too. Whenever any program closes, everything it has in RAM is deleted, thus the variables are cleared. This is true of all programs, in all programming languages. There are absolutely no exceptions.
Quite simply, you need to create a file that can store all this data long-term, on the hard drive (which is "permanent" memory).
If you're creating a game for the internet, you're going to need to store this data using SharedObjects (a.k.a. cookies).
If you're creating a game to be installed on the computer or mobile, you'll want to store data in a file. I recommend XML files, as they're the easiest to work with by far.
I am not going into either here, because those are lectures, not SO answers. See the above links to get started.
I didn't understand what exactly you're trying to do. But here is my simply approach would be that way.
// this is basically saved your latest clip we will control this if user click this button then we will be blocked
private var lastClickedButton:MovieClip;
private function onClick(ev:MouseEvent):void
{
var thisButton:MovieClip = ev.currentTarget as MovieClip
trace(thisButton.name)
thisButton.alpha = 0.5
thisButton.buttonMode = false;
thisButton.removeEventListener(MouseEvent.CLICK, onClick);
buttonInfoArr.push( thisButton.name );
savedData.data.myArray = buttonInfoArr;
// set the lastclicked button
lastClickedButton = thisButton;
// save this savedData sharedObject
savedData.data.lastClickedItem = lastClickedButton;
}
addEventListener(Event.ENTER_FRAME, loop)
{
if(savedData.data.lastClickedItem)
{
// do something here.
lastClickedButton.alpha = 0.5;
lastClickedButton.mouseEnabled=false;
// clear your sharedobject
savedData.flush();
}
}
I hope this will help you. good luck...

Switch language (audio and lyric) seamlessly in Adobe Flash

I’m creating a multilingual flash game with multilingual narrations. Till now i’ve got one language with an audio stream and lyric to accompany it in it’s own timeline controlled by a button on the main timeline to pause and play. I would like to add 2 more languages with audio and own lyric(karaoke style) for each language in this scene. And eventually have buttons on the main timeline that would switch the language(audio and lyric) and seamlessly continue from where the last language left off. Till now I have this action from the main timeline controlling the audio and lyric. englyr being the movie clip, with audio and lyric in it.
toggleButton.addEventListener(MouseEvent.CLICK, toggleClick3);
toggleButton.buttonState = "off";
function toggleClick3(event:MouseEvent) {
if (toggleButton.buttonState == "on") {
englyr.play();
toggleButton.buttonState = "off";
} else {
toggleButton.buttonState = "on";
englyr.stop();
}
}
I’m assuming I should put the other 2 languages as well as their lyric in englyr so that I can disable/mute languages that are not needed to be heard or seen. One problem is I can’t group the lyric and the narration(2 layers) together as a movie clip in that timeline. Therefore cannot disable the 2 other languages that shouldn’t be heard or seen. Any solutions?
It's probably easier to let them both play from code instead of via the timeline.
The first thing to do is to go to the settings of your audioclips in the library, enable "Export for Actionscript" and set a different class name for both your clips. I have named mine "english" and "french".
The following code manages two sounds and changes the language when you press the button of a language that is currently not playing.
var englishClip:Sound = new english(); //load both sounds.
var frenchClip:Sound = new french();
//create the sound and the sound channel.
var myChannel:SoundChannel = new SoundChannel();
var mySound:Sound = englishClip;
//if you want to have lots of different languages it might be easier to just have different buttons instead of one with a state.
englishButton.addEventListener(MouseEvent.CLICK, SpeakEnglish);
frenchButton.addEventListener(MouseEvent.CLICK, SpeakFrench);
//we'll start with having just the english sound playing.
myChannel = mySound.play();
function SpeakEnglish(event:MouseEvent) {
if (mySound != englishClip) { //if the english sound is already playing, do nothing.
var currentPlayPosition:Number = myChannel.position; //save playback position.
myChannel.stop(); //stop playing
mySound = englishClip.play(currentPlayPosition); //resume playing from saved position.
}
function SpeakFrench(event:MouseEvent) {
if (mySound != frenchClip) { //if the French sound is already playing, do nothing.
var currentPlayPosition:Number = myChannel.position; //save playback position.
myChannel.stop(); //stop playing
mySound = frenchClip.play(currentPlayPosition); //resume playing from saved position.
}
This could all be made more compact by having a single function that you pass the appropriate sound to. It would look something like this:
function SpeakEnglish(event:MouseEvent) {
ChangeSound(englishClip);
}
function SpeakFrench(event:MouseEvent) {
ChangeSound(frenchClip);
}
function ChangeSound(newSound:Sound){
if (mySound != newSound) { //if the sound is already playing, do nothing.
var currentPlayPosition:Number = myChannel.position; //save playback position.
myChannel.stop(); //stop playing
mySound = newSound.play(currentPlayPosition); //resume playing from saved
}
And that should solve the problem, i hope that helped :)
Resource: http://www.republicofcode.com/tutorials/flash/as3sound/

How to Remove a Sound

Hey guys so I can't figure this out. I want to Remove a single sound from a Class. So I have a start screen and when you press "Play Game" it takes you to the game but the start screen music keeps playing. Ive tried sound mixer remove all sounds which works but it removes every sound in the game even the Main game music. So i just to remove this single sound which is added in its class like so:
public class mcStartGameScreen extends MovieClip
{
private var sndmainSong:Sound;
public var mcStart:MovieClip;
public function mcStartGameScreen()
{
mcStart.buttonMode = true;
mcStart.addEventListener(TouchEvent.TOUCH_TAP, startOnTouch, false, 0, true)
//To completely end game when back button pushed on android
NativeApplication.nativeApplication.addEventListener( KeyboardEvent.KEY_DOWN, handleKeyDown, false, 0, true);
//create sound object from main song in library
sndmainSong = new DST10Class();
sndmainSong.play();
}
Now i want to remove the sound through the mcStart event listener function which is this:
private function startOnTouch(e:TouchEvent):void
{
dispatchEvent(new Event("START_GAME"));
//Tried null but didnt work either
//DST10Class = null;
}
So is their any easy way i can acccomplish this? Any help will be appreciated thank you!
Get a handler of the playing sound, then call stop() when you need to stop it.
var mainChannel:SoundChannel;
sndmainSong = new DST10Class();
mainChannel=sndmainSong.play();
Then, to stop it you call mainChannel.stop() and your sound will stop. To play it again, you need to create another SoundChannel object via sndmainSong.play().

How would I go about playing a sound object in reverse in Actionscript 3?

For a project I'm working on, it's necessary that I am able to play a sound object in reverse. How would I be able to do this in AS3?
This is doable as of player 10, but it's not a quick/simple implementation. You'll have to build your own custom support. Lets take a look:
var soundSource:Sound; //assuming this actually references a real sound file such as a MP3
var position:int = soundSource.bytesTotal;
var numBytesToReadEachSample:int = 8192;
var snd:Sound = new Sound();
snd.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleData);
snd.play();
function sampleData(e:SampleDataEvent):void {
position -= numBytesToReadEachSample;
//here we read data from our source, and write it to the playing sound
e.data.writeBytes(soundSource.extract(position, numBytesToReadEachSample))
}
That's NOT TESTED AND INCOMPLETE, but is the general idea of what you want to do. Hopefully it points you into the right direction!
More information here: http://www.adobe.com/livedocs/flex/3/langref/flash/events/SampleDataEvent.html#SampleDataEvent%28%29
Best of luck!