Sounds still playing in another frame - actionscript-3

Hey I am still getting some unwanted sound effects still playing in another frame, for example when I click my left mouse button which is also my jump button it will play the jump sound as well as playing the collect coins sound wierdly even though i remove each child from the stage when going to the game over screen.
Now im a bit unfamiliar with the sound channel so if its needed to be used please be kind and explain :)
In Frame 1:
var myMusic1:Sound = new Game_Over_Noise();
var myMusic2:Sound = new Jump_Noise();
var myMusic3:Sound = new Coin_Noise();
var myMusic4:Sound = new Power_Up_Noise();
var myMusic5:Sound = new Theme();
var channel:SoundChannel = myMusic5.play();
In Frame 8, Game Screen:
function doJump(evt:MouseEvent):void
{
if(!isJumping) //If the player is jumping.
{
jumpPower = 30; //Jump power is equal to 30.
isJumping = true; //isJumping variable is also equal to true.
var channel:SoundChannel = myMusic2.play(); //Play sound effect.
}
}
function update(evt:Event):void
{
if(isJumping) //If the player is jumping.
{
MainChar.y -= jumpPower; //Subtract the value of jumpPower from the player's y co-ordinate.
jumpPower -= 2; //Decrease the value of jumppower by 2.
}
if(MainChar.y + gravity < ground) //If the value of the player's Y co-ordinate and gravity is less than ground.
MainChar.y += gravity; //Then add the value of gravity to the player's Y co-ordinates.
else //else
{
MainChar.y = ground; //The players Y co-ordinate is equal to ground.
isJumping = false; //Make isJumping equal to false.
}
}
in Frame 5, Game Over Screen:
SoundMixer.stopAll();
Now this stops the theme music and not the sound effects, now i actually dont mind the theme tune playing all the time but i would like ALL sound effects (game sounds) to only play in the game.
I know my coding isnt the best and efficient but its easily readible to me, I appreciate the help! :D

Looks to me like you need to remove your event listeners (they're active even when something is off-stage).

Related

Enemy move randomly

To make things quick, I have an arrangement of tiles that a player and an enemy are on.
public static var floor1:Array = new Array(7);
floor1[0] = [0,1,1,1,1,1,0];
floor1[1] = [1,1,1,1,1,1,1];
floor1[2] = [1,1,1,0,1,1,1];
floor1[3] = [1,1,0,0,0,1,1];
floor1[4] = [1,1,1,0,1,1,1];
floor1[5] = [1,1,1,1,1,1,1];
floor1[6] = [0,1,1,1,1,1,0];
public function Main()
{
var tilew:int = 60;
var tileh:int = 60;
for (var i:int=0; i<floor1.length; i++)
{
for (var u:int=0; u<floor1[i].length; u++)
{
var cell:MovieClip = new Tile();
cell.gotoAndStop(floor1[i][u]);
cell.x = ((u-i)*tileh);
cell.y = ((u+i)*tilew/2);
addChild(cell);
cell.addEventListener(MouseEvent.ROLL_OVER, mouseover);
cell.addEventListener(MouseEvent.ROLL_OUT, mouseout);
cell.addEventListener(MouseEvent.CLICK, mouseclick);
cell.addEventListener(Event.ENTER_FRAME, beginfloor1);
}
}
var player:Player = new Player();
addChild(player);
player.mouseEnabled = false;
player.x = 5 * (tileh);
player.y = 5 * (tilew/2);
var enemy:Enemy = new Enemy();
addChild(enemy);
enemy.mouseEnabled = false;
enemy.x = 9 * (tileh);
enemy.y = 9 * (tileh/2);
My goal is to have the enemy move randomly on tiles in his range. What I did was create a square graphic called enemyVisionArea that checks which tile is hitting the enemy, which is basically surrounding tiles.
I have a timer function that tells the enemy to move every 5 seconds if the player isn't near him and if he's next to an available tile.
function timerenemy (event:TimerEvent){
if (enemy.enemyVisionArea.hitTestObject(enemyMover) && !player.visionPoint.hitTestObject(enemyMover.tileMiddle))
{
enemy.x = (enemyMover.x)+55;
enemy.y = (enemyMover.y)+20;
trace("moved");
}
}
enemyMover is a variable that I made equal to the tile objects.
function beginfloor1(event:Event)
{
enemyMover = event.currentTarget as Tile;
}
It just stays where it is. I'm just want to have the enemy move on its own on any tile that its enemyVisionArea is hitTesting a nearby tile. The beginfloor1 function doesn't seem to be working. Is there any way I can declare enemyMover = event.currentTarget as Tile and have the enemy move on a random tile that its enemyVisionArea is hitTesting?
If this is confusing, I can post the full code.
You are assigning 49 enterframe listeners which are called in sequence, and they ALL change one single variable to the cell they are attached to. Of course, the last tile is what's always assigned.
I expect that you want an enemy to check if there's a tile available for it to move to. You are essentially checking for one tile which is enemyMover - how do you determine what's that tile? You have to check all available tiles that are around the enemy, make a list of them and select one out of that list that's not the current tile, then move the enemy there.
So, first you need a complete tileset to be addressable from somewhere. The best way will be to declare a class-wide var tileset:Array and fill it where you make new tiles. Drop the Event.ENTER_FRAME listener from the code there, as it's useless. Then, in your timerevent that's for the enemy you do check all of the tileset if they are within your enemy's vision area (you use hitTestObject, I'd use clear distance grid-wise or coordinate-wise - it's a whole lot faster), if so, you add them to the TEMPORARY array you create within that function. Of course, if your enemy is at the currently processed cell, you ignore it - you have to move your enemy, not make him stand in place. Then, select (somehow, it's up to you) what cell your enemy should move to, and execute a move. Yes, if you want your enemy to move randomly, select a cell at random by its index via Math.floor(Math.random()*selectedcells.length).

HitTestObject issues

I have a bit of a problem with hitTestObject in Flash.
I have these tiles generated on the screen and I have a player added to the tiles. I created an invisible square bitmap for the player, which is the size of the tile so it can register whether it is hitting the tile completely. The problem is, it is registering hit test from tiles that aren't even next to the player. The link below, My mouse is over the tile that is highlighted, and I have a trace that checks the hitTest between the player and the current Tile that it's on.
http://postimg.org/image/6so3npm19/
Here is the code for the bitmap. I've been playing around with the x and y position and the size of it.
visionArea.graphics.beginFill(0x00FF00, 1.0);
visionArea.graphics.drawRect(0, 0, 85, 85);
visionArea.graphics.endFill();
var matrix:Matrix = new Matrix();
matrix.rotate(Math.PI / 4);
matrix.scale(1, 0.5);
visionArea.transform.matrix = matrix;
addChild(visionArea);
visionArea.mouseEnabled = false;
visionArea.visible = false;
visionArea.x = 4;
visionArea.y = -21;
When I click a tile and the player is next to it, I move it to that tile.
if (player.visionArea.hitTestObject(event.currentTarget as Tile))
{
player.x = (event.currentTarget.x)+55;
player.y = (event.currentTarget.y)+20;
}
I also have an enemy on the screen (the green tile). I'm trying to have the player not be able to go on the tile that the enemy is on, but sometimes it would work, sometimes it wouldn't.
if (enemy.enemyVisionArea.hitTestObject(event.currentTarget as Tile))
{
player.x != (event.currentTarget.x)+55;
player.y != (event.currentTarget.y)+20;
}
if (player.visionArea.hitTestObject(event.currentTarget as Tile) && !enemy.enemyVisionArea.hitTestObject(event.currentTarget as Tile))
{
player.x = (event.currentTarget.x)+55;
player.y = (event.currentTarget.y)+20;
}
I've never seen anyone use != as an assignment operator.

Drag finger on X axis of mc, changes value - AS3

I have a rectangle mc. When the user swipes his finger slowly right on the mc, a value needs to increase, If moved left, it will decrease. 1 to 100 is the limit. How do I do that? i don't want a visible slider. It should not matter where the finger is on the mc, only which direction the finger is moving.
EDIT: I am currently looking into the touchEvent and am researching the web for solutions.
You'll want to keep track of whether or not a swipe is happening and, if so, where it started.
var dragging:Boolean = false;
var startX:Number = 0.0;
Then you'll use simple event listeners to keep track of this bool.
mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
mc.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
function mouseDown(event:MouseEvent):void
{
dragging = true;
startX = event.localX;
}
function mouseReleased(event:MouseEvent):void
{
dragging = false;
}
Then you're MOUSE_MOVE touch event can handle all the logic:
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove); // Notice this event is on stage, not mc.
function mouseMove(event.MouseEvent):void
{
value += event.localX - startX;
if (value < 0) value = 0;
if (value > 100) value = 100;
}
Happy Holidays!

AS3 CS5 How can I refresh the stage after a SOUND_COMPLETE?

I have an educational game where children hear a sound and then have to choose the correct image out of 3 images.
When they want to hear the sound again they can press a speaker button.
The 3 images are movieclips (named card1, card2 and card3) dynamically added to the stage, with the buttonMode = true.
Whenever they press the speaker to hear the sound again or get feedback if they press the wrong image, I remove the mouse_events from the cards for the duration of the sound. I also set the buttonMode = false, so the children know they won't be able to click while the sound is playing.
On SOUND_COMPLETE I add the eventListeners again. Now the buttonMode = true again as well.
I want to do a refresh of the screen like event.updateAfterEvent(); so the cursor changes to a hand, should they have placed it on one of the cards. BUT the event.updateAfterEvent() can't be attached to a SOUND_COMPLETE, you can only use it after an interaction event like MOUSE or GESTURE.
tldr; How can I refresh my stage so the cursor changes back to a hand after the SOUND_COMPLETE ?
HereĀ“s some of the code:
function speakerClick(event:MouseEvent):void
{
remLst();
SoundMixer.stopAll();
cardCnl = gameSnd.play();
cardCnl.addEventListener(Event.SOUND_COMPLETE, sndComplete);
}
function sndComplete(event:Event):void
{
cardCnl.removeEventListener(Event.SOUND_COMPLETE, sndComplete);
addLst();
}
function addLst():void
{
for (var i:int = 1; i < 4; i++)
{
var card:Card = getChildByName("card" + i) as Card;
card.addEventListener(MouseEvent.CLICK, fnClick);
card.addEventListener(MouseEvent.MOUSE_OVER, fnOver);
card.addEventListener(MouseEvent.MOUSE_OUT, fnOut);
card.buttonMode = true;
}
}
In your addLst function, when cycling through the 4 cards, you could check for the current mouse position, and check if it is inside the boundaries of one of the cards.
It could work like this:
if ( mouseX > card.x && mouseX < (card.x + card.width)
mouseY > card.y && mouseY < (card.y + card.height))
{
Mouse.cursor = MouseCursor.BUTTON;
}
I am not 100% sure though if buttonMode changes it back to Arrow when the mouse leaves the object. I usually don't use buttonMode.

AS3 laser weapon

I am pretty new to action script 3 (I did a little bit in as2) and i am trying to create a laser gun that rotates towards the mouse and shoots when the mouse is fired.
kind of like this but in as3
http://www.freeactionscript.com/2009/04/laser-hitting-solid-objects-walls/
Thanks,
Thor
You can start to play with something like this:
//adding listener to run all the time
m.addEventListener("enterFrame", runGame);
//listener for mouse is down
stage.addEventListener("mouseDown", md);
//listener for mouse is up
stage.addEventListener("mouseUp", mu);
//to know if mouse is down
var _fire:Boolean = false;
//function for all the time
function runGame(evt:*):void
{
//to know the angle where the mouse is from the "canon" in radians
var angle:Number = Math.atan2(stage.mouseY - m.y, stage.mouseX - m.x);
//set the canon's rotation
m.rotation = 180 * angle / Math.PI;
//if mouse us down -> fire
if(_fire)
{
//create a point far away, so it will always work if the screen is normal
var point:Point = Point.polar(10000, angle);
//shoot the laser
graphics.lineTo(point.x, point.y);
}
}
//when mouse is down
function md(evt:*):void
{
//prepare graphics
graphics.clear();
graphics.lineStyle(2, 0xff0000);
graphics.moveTo(m.x, m.y);
//set fire to true
_fire = true;
}
//when mouse is up
function mu(evt:*):void
{
//set fire to false
_fire = false;
//clear the laser
graphics.clear();
}
Create a new project, place a movieclip on the stage, name it "m" (without the quotes ;)). Paste the script where the actionscript goes on frame 1.
If you want the laser to follow the mouse when it's down, change
runGame function to this:
function runGame(evt:*):void
{
//to know the angle where the mouse is from the "canon" in radians
var angle:Number = Math.atan2(stage.mouseY - m.y, stage.mouseX - m.x);
//set the canon's rotation
m.rotation = 180 * angle / Math.PI;
//if mouse us down -> fire
if(_fire)
{
//create a point far away, so it will always work if the screen is normal
var point:Point = Point.polar(10000, angle);
//shoot the laser
graphics.clear();
graphics.lineStyle(2, 0xff0000);
graphics.moveTo(m.x, m.y);
graphics.lineTo(point.x, point.y);
}
}
and md function to this:
//when mouse is down
function md(evt:*):void
{
//set fire to true
_fire = true;
}
"Epic" laser, with source. Also great site btw.
Probably best to learn the basic concepts of programming before trying to tackle things like this. Cutting/Pasting code is not programming, and can have frankenstein-ish results.
There is no magical shortcut to programming, you need to learn the basic concepts and build on them. Wonderfl.net is a cool place to check out, but I'd suggest starting out far more basic concepts to start. Until you do that, it's all going to appear as voodoo to you.