Actionscript 3: more than one sound channel possible? - actionscript

My problem is having several buttons in flash that play sounds when clicked, and I want only one button/sound to be active at a time. Problem is that if the mouse button is released outside of the flash window the last button's sound keeps sounding til the end, and if another button is pressed in the meantime it too starts sounding simultaneously, and so on.
So I thought of checking if the SoundChannel assigned to any other button than the currently pressed one is playing, and if so, stop that SoundChannel to only let the current button's SoundChannel play.
But if this Actionscript SoundChannel is a single object for all the buttons, this won't work, and then I don't see a solution to preventing multiple sounds sounding simultaneously other than adding a 'warning' box, which seems redundant and ineffective. So can you have a separate SoundChannel for each button or object in a flash movie, otherwise how can I bulletproof this so that only one button sound can sound at once no matter where the mouse is released, inside as or outside of the flash window?

Can you put the buttons in a container and addEventListener for MouseEvent.MOUSE_UP and in the handler to check if it cursor is outside the container like so:
private static function onMouseDownOutside(event:MouseEvent) : void {
var mouseDownInsideComponent : Boolean = false;
mouseDownInsideComponent = yourContainer.hitTestPoint(event.stageX, event.stageY, false);
if (!mouseDownInsideComponent) {
//stop the sound
}
}
and just to stop the sound when it gets out of the container? Seems like a possible workaround.

Related

AudioKit5 / Swift / iOS: Playing a clip does not start if one already playing

It would seem a simple question, but perhaps I am missing something, I am simply trying to have a second track play on a button press, that stops the current and plays!
The first time code is executed, first track plays fine, status is "playing"
Second time code executed, first track stops, status is "playing", but no sound.
Third time executed, desired track plays fine.
clipPlayer.stop()
do {
try clipPlayer.load(file: file)
clipPlayer.play()
print("status:\(clipPlayer.status)")
} catch {
Log(error.localizedDescription, type: .error)
}
I see this same odd behaviour in the Audiokit5 Cookbook / Audioplayer Playlist too - having to click the desired track twice, surely so basic problem would've been picked up? Or am I missing something simple?
EDIT: Oh, additional info - if the current track has already stopped by reaching its end point. Clicking the new track starts as it should just fine.

Managing states of multiple widgets via Bloc pattern

On my Main page I have 3 buttons: play video, play audio, record voice. All these button widgets use Bloc pattern to control its internal state (e.g. changing button Icon when file is playing) but I'm having trouble understanding how to access their states on my Main page because I'd like to disable other buttons when one of them is pressed.
Any recommendation on how to do this?
You can have a global bool variable and can make that variable state to true when any button is pressed, and as soon as your video playback released, you can make that variable to false, and don't forget to make all buttons disable until that variable is true.
Thanks

How to pause and resume UIDynamicAnimator physics simulation

How would you go about pausing and resuming a UIDynamicAnimator's physics simulation? There is no way to programmatically pause and resume. There is a "paused" state when all items are at rest however I am am looking for something different. For example, I'd like to have an item being pulled by a gravity field, then press a pause button to pause the simulation, and then press a resume button and have the simulation resumed as if nothing happened. The item maintains it's trajectory, velocity, etc.
My hunch is that I have to somehow save the item's physics properties, remove the dynamic behaviors, and then add the dynamic behaviors back to mimic the saved physics properties from before. Is this the right approach?
You can do this only by removing all behaviours using removeAllBehaviors().
To restart the simulation you have to add each behavior

How to effectively pause a game in spritekit?

This seems like such a basic concept but there is really no good answer.
I currently have a pretty basic setup, in my game's scene, I have an enum gameState which is currently either inGame or gamePaused.
I have my button set up, and I have it so pressing simply toggles gameState.
Then, to make it work, I have two separate update methods: One for when gamePaused, one for when inGame.
This works for 95% of my game, as the updates in my game can be pretty readily started and stopped without any issues. There are some issues I cannot tackle though.
First and foremost are actions. I use SKActions for a bit of my project (some movement, scaling, fading...) and this method does NOT pause them. This can be catastrophic in certain points. Secondly, this doesn't handle particles, physics, and a few other things that are not directly associated to my update methods.
The only clue I have is self.view.paused = YES, but that isn't going to work either.
First off, this DOES fix my actions, particles, and physics problem... kinda. But This question suggests that SKActions aren't actually PAUSED by this, but actually STOPPED completely. Is this true? If it is, then it won't work smoothly either because my actions are thrown out of whack.
Also, pausing the view seems to do what it says: stop everything. EVERYTHING. Newbie question here, but how am I supposed to get any code to run at that point? It's all cut off. Is this where I need subViews? I have never used a subView yet, but it sounds like its what I want in this case.
Simply put, there are a lot of unanswered questions for me, and I don't know how to proceed. I'm hoping there's some 'standard procedure' for pausing in Sprite Kit, but with pausing the view halting actions I truly have no idea where to proceed.
Should I move away from using actions? Is my idea of a pause subView sound?
I don't want to babble, all I want to know is how you go about pausing in your average Sprite Kit project. Additional info provided upon request.
Pausing a node will pause (not stop) the node's actions, and i suppose pause will also be applied to all children of the paused node in the same way. All other unpaused nodes will continue to run their actions to completion.
You should have a "game layer" node with all game nodes in them that you want to pause, and then just pause that "game layer" node. Then have a "pause game menu" node where you add all the pause menu stuff you need which will continue to function normally even if the game layer is paused.
Be very sure you do not use performSelector or NSTimer or GCD or any other scheduling methods besides actions or the scene's update: method because those will not adhere to a node's paused state.
Pausing the view effectively freezes everything in it, pausing the scene according to some will not pause the update: calls - but I have not verified this myself. If this were the case you can always check inside the update method whether a given node that you send a message to is paused and if so, decide not to send certain messages to that node.
I just called a map function on all children of the scene and set the paused property to true
self.children.map{($0 as SKNode).paused = false}
By setting it to true you can easily undo the freeze.
EDIT:
Better use a for-loop to iterate over the children.
for node in self.children as [SKNode] {
node.paused = false
}
I can tell you what I did in my game:
Pause the SKView on -applicationWillResignActive: (or equivalent, using NSNotifications),
Un-pause the SKView on -applicationDidBecomeActive: (or equivalent, using NSNotifications),
For the actual game scene only, I set a boolean flag _isPaused when resigning active, and if it is true I just skip the -update: method (frame updates). (I also show the "paused" menu when the user resumes the app).
...But my game is a simple puzzle game, and there's no long actions that should continue past the pause/resume. I can not confirm right now that all actions are aborted, but I think it's not the case.
I also used self.children.map{($0 as SKNode).paused = false} and it does work if you create a var layer of type SKSpriteNode and add it on top of the scene. But I also have an NSTimer I'm using to spawn sprites on the scene. Everything currently on the scene is paused, but sprites keep appearing and moving across the screen. It is not pausing the spawning.
I tried pausing the NSTimer when I call the above code by setting repeats to false, then setting it to true when I remove the layer but it doesn't work. I also tried self.scene?.view?.paused = true but that freezes everything and the layer I create does not even appear onscreen.
You need to set the delegate for the View!
func PauseGame(){
self.scene.view.paused = true
}
fun playGame(){
self.scene.pause = false
}
This function is work perfectly if you are not using the NSTimer to call a function. If you use NSTimer your view will pause perfectly but when you play the game again by play game functionality you see that all the functions that use the NSTimer function that runs in the back end and your screen full with your sprite-kits. So when you use NSTimer in the function you have to first pause the NSTimer functions also after that this function work perfectly.
//For Pause
func pauseGame() {
scene?.view?.paused = true
}
//For play.
func playGame() {
scene?.view?.paused = false
}

AS3 Run code continuously while holding a Button down - Air For iOS/Android

I am developing an iOS game in Flash CS6.
I have a basic movement test that I put in an Event.MOUSE_DOWN handler.
What I'm expecting/wanting is when I held my finger down on the button, that the player would keep moving until I stop touching the screen.
What happens though, is I have to keep constantly tapping to keep the player moving - rather than just hold my finger on the button and the player keeps moving.
What code should I use to accomplish what I want?
To accomplish this, you'll need to run a function continuously in between MouseEvent.MOUSE_DOWN and Event.MOUSE_UP as MouseEvent.MOUSE_DOWN will only get dispatched one time per press.
Here is a simple script to do just that:
myButton.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
function mouseDown(e:Event):void {
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUp); //listen for mouse up on the stage, in case the finger/mouse moved off of the button accidentally when they release.
addEventListener(Event.ENTER_FRAME,tick); //while the mouse is down, run the tick function once every frame as per the project frame rate
}
function mouseUp(e:Event):void {
removeEventListener(Event.ENTER_FRAME,tick); //stop running the tick function every frame now that the mouse is up
stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUp); //remove the listener for mouse up
}
function tick(e:Event):void {
//do your movement
}
As an aside, you may want to use the TOUCH events, as it gives more flexibility with multi-touch control. Though if you're only ever going to allow one item to be pressed at any given time, it's not an issue.
TO do that, just add Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT in your document class, then replace your MouseEvent listeners with the appropriate touch event:
MouseEvent.MOUSE_DOWN becomes: TouchEvent.TOUCH_BEGIN
MouseEvent.MOUSE_UP becomes: TouchEvent.TOUCH_END

Resources