Disable Mouse Blocker in Starling - actionscript-3

How to block all mouse touch input into my Actionscript 3 Starling game?
Basically I need to ignore all touch events for a set period of time.

If you don't want an object to be touchable, you can disable the "touchable" property. When it's disabled, neither the object nor its children will receive any more touch events.
There is no need to add new display object to prevent touches.
this.touchable = false;

Developed a quick solution! Basically create a Quad that is the size of your screen, and add it to the front most layer.
Add to init() function of front most layer file:
Starling.current.addEventListener('TOUCH_BLOCKER_ENABLE', touchBlockerEnable);
Starling.current.addEventListener('TOUCH_BLOCKER_DISABLE', touchBlockerDisable);
Then define these functions:
private function touchBlockerEnable(e:Event):void
{
if(!_quad)
{
_quad = new Quad(Starling.current.stage.width,Starling.current.stage.height,0xFFE6E6);
_quad.x = 0;
_quad.y = 0;
_quad.alpha = 0.1;
addChild(_quad);
}
}
private function touchBlockerDisable(e:Event):void
{
if(_quad)
{
removeChild(_quad);
_quad = null;
}
}
Call this function to activate the Touch Blocker:
Starling.current.dispatchEvent(new Event('TOUCH_BLOCKER_ENABLE'));

Related

How to use MuteButton video component?

I need to create a button, which plays/stops background music in my flash game. I could use Button component with custom images, but I found MuteButton component which appears to have everything that I need, including images. The problem is that I don't know how to set up MuteButton and is that even possible to use without using FLVPlayback component on first place?
If you want to enable mute button in single button you can use
var volumeOn:Boolean = true;
var globalVolume:Sound = new Sound();
btnSoundOff.onRelease = function():Void {
if (volumeOn) {
globalVolume.setVolume(0);
} else {
globalVolume.setVolume(100);
}
volumeOn = !volumeOn;
}

Unable to reference MovieClip inside Button AS3

I have this annoying issue that I hope someone might be able to help me with.
I have a mute button that I created and I have another movieclip inside of that button. All I want it to do is when I toggle the mute the movieclip inside will go to the according frame.
However, every time I try to call the movieclip inside of the button, this error comes up:
Access of possibly undefined property mcMuteToggle through a reference with static type flash.display:SimpleButton.
The instance name for the movieclip within is "mcMuteToggle".
Why not make movieClips that act like buttons?? Since I dont think actual button (simpleButton) types can deal with sub-MovieClips (especially if they too have code). Even if possible don't do it, I can predict a mess whereby Button does things it shouldn't do depending on what code you have in those MClips.
Try an alternate button method, just for a test... You didnt show any test code to work with so I will make assumptions..
1) Make a shape (rectangle?) and convert to MovieClip (or if all coded, then addchild shape to new MovieClip). Let's assume you called it mc_testBtn.
2) Make that MC clickable by coding mc_testBtn.buttonMode = true;
3) Add your mcMuteToggle inside the mc_testBtn
(or by code: mc_testBtn.addChild(mcMuteToggle);
Now you can try something like..
mc_testBtn.addEventListener (MouseEvent.CLICK, toggle_Mute );
function toggle_Mute (evt:MouseEvent) : void
{
if ( whatever condition )
{
mc_testBtn.mcMuteToggle.gotoAndStop(2); //go frame 2
}
else
{
mc_testBtn.mcMuteToggle.gotoAndStop(1); //go frame 1
}
}
This is likely due to strict mode. You can either disable it in the ActionScript settings dialog, access it with a different syntax myButton['mcMuteToggle'], or make a class for the symbol that includes a property mcMuteToggle.
You can also check to make sure the symbol is actually on the stage and that clip is actually in the button:
if('myButton' in root) {
// ...
}
if('mcMuteToggle' in myButton) {
// ...
}
i think u just overwrite that codes. You u can use something like this:
var soundOpen:Boolean = true;
var mySound:Sound = new Sound(new URLRequest("Whatever your sound is"));
var mySc:SoundChannel = new SoundChannel();
var mySt:SoundTransform = new SoundTransform();
mySc = mySound.play();
mcMuteToggle.addEventListener(MouseEvent.CLICK, muteOpenSound);
function muteOpenSound(e:MouseEvent):void
{
if(soundOpen == true)
{
mcMuteToggle.gotoAndStop(2);
/*on frame 2 u need to hold ur soundClose buton so ppl can see :)*/
soundOpen = false;
mySt.volume = 0;
mySc.soundTransfrom = st;
}
else
{
mcMuteToggle.gotoAndStop(1);
soundOpen = true;
mySt.volume = 1;
mySc.soundTransfrom = st;
}
}
This is working for me everytime. Hope u can use it well ;)

Making multiple objects draggable

I have about 50 symbols that I want to make draggable. Nothing fancy, just the ability to click it and drag it to a different location.
I found as3 code for doing so but when I paste it into my file it gives me errors:
**Error** Scene=Scene 1, layer=Units, frame=1:Line 9: The class or interface 'MouseEvent' could not be loaded.
function mouseDownHandler(evt:MouseEvent):void {
That code is:
// Register mouse event functions
fighter_uk.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
// Define a mouse down handler (user is dragging)
function mouseDownHandler(evt:MouseEvent):void {
var object = evt.target;
// we should limit dragging to the area inside the canvas
object.startDrag();
}
function mouseUpHandler(evt:MouseEvent):void {
var obj = evt.target;
obj.stopDrag();
}
I'm using flash pro 8, so I tried finding as2 code but couldn't find it.
Also, is there an 'easy' way to code all 50 objects?
I think you're trying to compile AS3 code with AS2 compiler. Try changing your compilation settings to target AS3.
Also you may need to include the class import at the top of your code:
import flash.events.MouseEvent;
To drag 50 objects, add them all on the same container sprite and add the listener to the container sprite only:
var holder:Sprite = new Sprite();
for ( var i:int = 0, l:int = 50; i < l; i++ ) {
var dragee:YOUR_CUSTOM_OBJECT = new YOUR_CUSTOM_OBJECT();
holder.addChild(dragee);
}
addChild(holder);
holder.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
holder.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
holder.addEventListener(Event.MOUSE_LEAVE, mouseUpHandler);
var currentDragee:YOUR_CUSTOM_OBJECT = null;
function mouseDownHandler(evt:MouseEvent):void {
currentDragee = evt.target as YOUR_CUSTOM_OBJECT;
if ( currentDragee !== null ) {
currentDragee.startDrag();
holder.addChild(currentDragee); // bring current to front position
}
}
function mouseUpHandler(evt:Event):void {
if ( currentDragee !== null ) currentDragee.stopDrag();
currentDragee = null;
}
YOUR_CUSTOM_OBJECT being the object class you need to drag. Hope it helps!
This page seems to have the answers you are looking for (AS2 drag and drop). If you've already seen it, you'll need to explain why it's not good enough for your needs.
If you want to drag/drop multiple instances in AS2, you can still add the code to the movieClip symbol, export it from the library and load the instances up using attachMovie (all 50 of them). If they are all different, then attach the code as necessary to the clips themselves, or to some function elsewhere that will capture all the clicks and decide what was clicked. This is all very doable in AS2.
Remember you can use your onClipEvent(load) function to set up a lot of the initial lifting.
Here's a sample I made in AS2 for making a node tree. It's all draggable (mouse drag) and zoomable (with mouse Wheel). You can add nodes by clicking on the little down arrow in the node box. Each node is listening for the mouse.
You'll want to look at this section for the most part:
// Enable drag on button press
on (press)
{
startDrag(this);
}
// Stop the drag on release of mouse button
on (release)
{
stopDrag();
}
Besides this, I'm not really sure how your setup looks, so I hope this helps get the ball rolling. (Check the link, there's lots of little gems in there).
Flash Professional 8 only supports ActionScript 2 & 1
You can follow this official URL and learn how to do that in ActionScript 2, but I extremely recommend you to work with ActionScript 3.

Is there any way to remove and addListener based on a timer?

How would i go about disabling the controls for a character for 5 seconds after they've hit an object and then immediatly afterwards allowing the character to move freely? So far, i've been able to get the code for the hitTest done and the removing keyboard controls (the easy part) but now i'm stumped as to how i would set the keyboard controls on a timer. Any help? My code for the hitTest and removing of controls is as follows.
if (player.hitTestObject(folder))
{
trace("success!");
addChild(myInfo);
//stops player movement
stage.removeEventListener(KeyboardEvent.KEY_DOWN,kD);
}
else
{
addChild(myInfo);
removeChild(myInfo);
}
The other problems in the code are of no concern right now (such as the add/remove child in the else function.
private var m_tmr:Timer = new Timer(5000, 1);
private function someFunc():void
{
if (player.hitTestObject(folder))
{
trace("success!");
addChild(myInfo);
//stops player movement
stage.removeEventListener(KeyboardEvent.KEY_DOWN,kD);
m_tmr.addEventListener(TimerEvent.TIMER, onTimer);
m_tmr.start();
}
else
{
addChild(myInfo);
removeChild(myInfo);
}
}
private function onTimer(pEvent:TimerEvent):void
{
m_tmr.removeEventListener(TimerEvent.TIMER, onTimer);
stage.addEventListener(KeyboardEvent.KEY_DOWN, kD);
}
Adding/removing the timer's event listener each time is for purposes of efficiency; it's not critical that you keep adding/removing it like that.

FULL_SCREEN_INTERACTIVE mode: the "Allow" button click is passed to the application

In an AS3 game (using Flex 4.10.0) I would like to allow players to chat, even when they are in fullscreen mode.
So I am using the following ActionScript code (the _fullBox checkbox triggers fullscreen mode in my web application):
public function init():void {
if (stage.allowsFullScreenInteractive)
stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen, false, 0, true);
}
private function toggleFullScreen(event:MouseEvent):void {
stage.displayState =
stage.displayState == StageDisplayState.NORMAL ?
StageDisplayState.FULL_SCREEN_INTERACTIVE :
StageDisplayState.NORMAL;
}
private function handleFullScreen(event:FullScreenEvent):void {
_fullBox.selected = event.fullScreen;
}
<s:CheckBox id="_fullBox" click="toggleFullScreen(event)" label="Full Screen" />
This works in the sense that the fullscreen mode is entered successfully and users can use the keyboard to chat too.
Unfortunately, the click at the "Allow" button in the dialog (displaying "Allow full screen with keyboard controls?") is being passed down to the web application.
And in my case it resuls in the click at a playing table in the lobby as you can see in the screenshot and thus (unwanted) joining a game:
This (bug?) has been seen with Windows 7 / 64 bit and Flash Player 11,8,800,115.
Can anybody please share a good workaround for this?
I was thinking of adding a transparent Sprite or UIComponent above my web application, but the question is when (i.e. in which methods) to display/hide it?
UPDATE:
Calling event.stopPropagation() from handleFullScreen() doesn't help anything.
UPDATE 2:
I've submitted Bug #3623333 at Adobe.
UPDATE 3: A note to myself - stage.allowsFullScreenInteractive is useless, because only set when allready in fullscreen mode.
As you mentioned, you need to create transparent layer to avoid undesired click events. you can hide this layer when screen returned to normal state or user accepted fullscreen state (FULL_SCREEN_INTERACTIVE_ACCEPTED event will fired).
Demo (flashplayer 11.3 required)
var transparentLayer:Sprite=new Sprite();
var timer:Timer = new Timer(50, 1);
init();
function init():void {
transparentLayer.graphics.beginFill(0,0.1);
transparentLayer.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
transparentLayer.graphics.endFill();
transparentLayer.visible=false;
addChild(transparentLayer);
timer.addEventListener(TimerEvent.TIMER_COMPLETE,handleTimerComplete);
stage.addEventListener(FullScreenEvent.FULL_SCREEN_INTERACTIVE_ACCEPTED,handleFSIA);
_fullBox.addEventListener(MouseEvent.CLICK,toggleFullScreen);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen);
}
function toggleFullScreen(e:MouseEvent):void {
if(stage.displayState == StageDisplayState.NORMAL){
stage.displayState=StageDisplayState.FULL_SCREEN_INTERACTIVE;
transparentLayer.visible=ExternalInterface.available;
}else
stage.displayState=StageDisplayState.NORMAL;
}
function handleFullScreen(e:FullScreenEvent):void {
_fullBox.selected = e.fullScreen;
if(stage.displayState == StageDisplayState.NORMAL)
transparentLayer.visible=false;
}
function handleFSIA(e:FullScreenEvent):void{
timer.reset();
timer.start();
}
function handleTimerComplete(e:TimerEvent):void{
transparentLayer.visible=false;
}
Found one workaround.
Allow and Cancel buttons are not the parts of the application, so when you hover one of those buttons you receive rollOut event for application.
<s:Application
rollOut="application_rollOutHandler(event)"
rollOver="application_rollOverHandler(event)">
Inside event handler you can disable mouse events for child objects. Don't disable for application as you won't get rollOver event after that.
private function application_rollOutHandler(event:MouseEvent):void
{
this.mouseChildren = false;
}
private function application_rollOverHandler(event:MouseEvent):void
{
this.mouseChildren = true;
}