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

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.

Related

Need an object to become 'unclickable' behind certain objects. As3 Flash Cs4

How can I make a clickable movieclip 'hide' behind another object. Eg.. I have a rabbit movieclip - he is clickable - as he walks behind a tree(MC) he needs to hide behind that tree.
At the moment, if I click on the tree - the mouse click seems to ignore the tree completely and I can still click the unseen rabbit.
var HitCount:Number = 10;
var RabbitG1X:Number = 0;
var RabbitG1Y:Number = 0;
var RabbitG2X:Number = 0;
var RabbitG2Y:Number = 0;
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE, follow);
function follow(evt:MouseEvent)
{
Cursor_mc.x =mouseX;
Cursor_mc.y=mouseY;
}
stage.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void
{
if (Cursor_mc.hitTestObject(RabbitG1_mc))
{
trace ("you fed rabbit1 ");
RabbitG1_mc.x = RabbitG1X + 5000;
RabbitG1H_mc.x = RabbitG1X + 1271.85;
RabbitG1H_mc.y = RabbitG1Y + 184.05;
HitCount = HitCount -1;
Dec_txt.text = "" + HitCount + "";
}
if (Cursor_mc.hitTestObject(RabbitG2_mc))
{
trace ("you fed rabbit2 ");
RabbitG2_mc.x = RabbitG2X + 5000;
RabbitG2H_mc.x = RabbitG2X + 1271.85;
RabbitG2H_mc.y = RabbitG2Y + 184.05;
HitCount = HitCount -1;
Dec_txt.text = "" + HitCount + "";
}
if (HitCount ==0)
{
trace("You fed all the rabbits");
}
}
I tried adding this to the tree mc to see if I could kill the mouse when it moved over tree.
Tree2MC.addEventListener(MouseEvent.CLICK, solid);
function solid(e:MouseEvent):void{
Tree2MC.mouseEnabled = false;
}
However, it isn't ideal. I really need a clickable object to hide if it goes behind another object on the stage. So if he is half hidden and I click on the part of the MC still revealed, it will click.. And it didn't work.
First, there is no need to use the hitTest code to figure out what was clicked. You can use the mouse event's .target property to figure that out - that will also solve your issue of knowing if the tree was clicked or the rabbit.
For example:
function clickHandler(event:MouseEvent):void {
if (event.target == RabbitG1_mc){
//.....do you stuff
if (event.target == RabbitG2_mc){
Now, one thing to point out, is the .target of an event could also be a child object of a rabbit (if your rabbit MC had other objects inside it). So to make sure it's consistent, you can do something like this when you initialize your rabbits:
RabbitG1_mc.mouseChildren = false;
RabbitG2_mc.mouseChildren = false;
Alternatively, you could just add mouse event listeners to the rabbits directly instead of one listener on the stage that will catch everything. This way, if an object (tree) is in front of them (and is mouse enabled), the click event will dispatch on the tree instead of the rabbit and the clickHandler won't run.
RabbitG1_mc.addEventListener(MouseEvent.CLICK, clickHandler);
RabbitG2_mc.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void {
//event.currentTarget is a reference to what you attached the listener to
switch(event.currrentTarget){
case RabbitG1_mc:
//..do your code
break;
case RabbitG2_mc:
//..do your code
break;
}
}

Sounds still playing in another frame

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).

Double Click - Fullscreen

I'm working on a video player and I though that it could be usefull to include the fullscreen's function when the user double click on the stage.
I've done some research but I'm stuck right now because of this line:
player.display.mouseChildren = false;
I read somewhere that I have to include this before those:
player.display.doubleClickEnabled = true;
player.display.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickFS, false, 0, true);
However, if mouseChildren is false, the children are not working ^^'.
Do you have an idea to fix this ?
Thank you,
Lea.
Here is a cheat solution.
You just make a full size sprite over all layers, and set it to alpha 0.
Add double click listener to the sprite and set mouseChildren to false, this won't effect your player.
I just screwed up the event flow in AS3. Here is also a cheat solution.
Make your own DOUBLE_CLICK event use CLICK event.
var lastClickTime:Number = 0;
mc.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void
{
var curTime:Number = getTimer();
if( curTime - lastClickTime < 300 )
{
trace("Double Click");
}
else
{
trace("Single Click");
}
lastClickTime = curTime;
});

How do I stop a function of a parent movieclip when in a child of that parents?

Help!!
I have a piece of code on a mc that when the mouse is dragged it plays through that movie clip, giving a 360 spin of a product.
Inside this movieclip on different increments of the 360 spin i have child movieclips with various other animations to relate to each angle of the product.
exp..
Scene 1 > spinY_mc > AWComplete_mc
My code for the spin is written within the actions in scene1 and controls spinY_mc but once im in AWComplete_mc i do not want you to be able to drag the mouse and spin?
Im sure this is simple but im a noob at all this and am taking on a mammoth project!
Here is the code used on the movieclip (spinY_mc) I dont want this code to work when inside of its child mc (AWComplete_mc).
// Rotation of Control Body Y
spin_Y.stop();
spin_Y.buttonMode = true;
var spin_Y:MovieClip;
var offsetFrame:int = spin_Y.currentFrame;
var offsetY:Number = 0;
var percent:Number = 0;
spin_Y.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
spin_Y.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
function startDragging(e:MouseEvent):void
{
// start listening for mouse movement
spin_Y.addEventListener(MouseEvent.MOUSE_MOVE,drag);
offsetY = stage.mouseY;
}
function stopDragging(e:MouseEvent):void
{
// STOP listening for mouse movement
spin_Y.removeEventListener(MouseEvent.MOUSE_MOVE,drag);
// save the current frame number;
offsetFrame = spin_Y.currentFrame;
}
// this function is called continuously while the mouse is being dragged
function drag(e:MouseEvent):void
{
// work out how far the mouse has been dragged, relative to the width of the spin_Y
// value between -1 and +1
percent = (mouseY - offsetY) / spin_Y.height;
// trace(percent);
// work out which frame to go to. offsetFrame is the frame we started from
var frame:int = Math.round(percent * spin_Y.totalFrames) + offsetFrame;
// reset when hitting the END of the spin_Y timeline
while (frame > spin_Y.totalFrames)
{
frame -= spin_Y.totalFrames;
}
// reset when hitting the START of the spin_Y timeline
while (frame <= 0)
{
frame += spin_Y.totalFrames;
}
// go to the correct frame
spin_Y.gotoAndStop(frame);
}
I'm pretty sure you just want to stop the propagation of an event from the child so it doesn't make it out to the parent. If you add a listener for the event you want to block (lets say it's mouseDown you want to block).
child_mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownBlocker);
private function mouseDownBlocker(event:MouseEvent):void
{
event.stopImmediatePropagation();
}
The way events work is they start at the "deepeest" child which the mouse has a hit event with, then they "bubble" up through all the parents. By stopping the propagation you block the bubbling from occurring, so the parents never get the event.

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!