Key press issue in ActionScript 3 - actionscript-3

I'm creating a DDR-like game for an assignment and my keyboard seems to respond and trace it, but only if I press on the screen with the mouse first.
How can I get rid of that and just have it respond right away?
right_mc is the arrow that's moving
ArrowRight_mc is the arrow at the top
perfect_mc should pop up briefly
and so should a glowing arrow where it hits.
Here is what I have so far:
if(rightDown){
trace("right arrow");
if(right_mc){
if(right_mc.y >= ArrowRight_mc.y){
perfect_mc.visible = true;
glowRight_mc.visible = true;
}
}
}

This has been a long standing issue for Flash developers. Flash needs keyboard focus before it can detect keyboard events.
The problem is that the browser does not give focus to the SWF until the user clicks somewhere inside the SWF. This does make sense though. I don't want the web page I am on to lose focus just because there is a flash movie embedded somewhere. This is a security feature, to stop things like Flash banner ads being silent key loggers. However there are some instances that it makes sense to force the focus e.g. a Flash game where its the only thing on the HTML page.
Usually the best thing to do is have start menu screen with a "play" button. This forces the user to click on the SWF without even knowing about this "focus issue".
There is more info at the Adobe Technote - Giving keyboard focus to an embedded Flash movie.
***EDIT****
Whether the Flash has focus or not, only affects keyboard events. It will not affect code from running, movieclips from playing, or sounds/video from playing.

The issue here is that the embedded SWF file does not have focus when the screen first loads. You can assign focus to it using JavaScript but in my experience, this does not always work 100% of the time because of variations in the way browsers interpret JS. What a lot of people do is have a big START button following the load of the game so that players have to click on the SWF to begin playing. Some sites, even use JS to detect when the game has lost focus and will pause the game and alert the user.
I suppose I haven't exactly answered your question because I'm not that great at JavaScript but I hope this points you in the right direction.

In response to your comment...
I'm unclear on something. If you have to click to start the song then you've already clicked on the SWF and you should be getting keyboard events, right? So if you're having to click to start then click again, maybe you need to make sure your mouse listener is at the root of your display list.
// in your document class / main AS file...
this.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
Or perhaps you need to poll for input during an EnterFrame loop rather than listen for key events.

I know what you mean. You have a specific object on the stage that needs focus before keyboard events will trigger. I'm having the same issues with a game here. A sprite needs to move with the keyboard arrows but the container needs focus so it will respond. I'm just setting the object I want to move to be tabEnabled as my requirements are only for accessibility purposes so tabbing to the object first will give it keyboard control.

Related

Handling a keyboard event in one place for the whole program

I'm creating a little developer console for an AS3 AIR application, I'm wanting F12 to add the toggle the display of the console screen but I don't want to litter my program with a bunch of calls to the Console to show or hide it, I also don't really want to be re-creating the console on different screens of my application.
I'm wondering if there's a way or a place I can put my keyboard event to toggle the display that will handle it across the entire application? At the moment I've tried putting it into my Main class which calls the first screen in the hopes that would be able to handle it but as soon as I click on another screen my eventListener isn't called.
Any ideas?
You could add your event listener to FlexGlobals.topLevelApplication instead of specific views, this would achieve the reduction you require
For true application level keyboard handling, attach the listener on the NativeApplication.nativeApplication object.
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, toggleDevConsole,false,0,true);
Attaching the listener to the stage will only work when that particular stage (window) has the focus. This will become an issue if your application has multiple windows that require interaction.
For single window applications, either will work.
Woops, I'm not quite with it today!
For future reference I added the event listener to the Stage in my Main function and it's being picked up every time.
stage.addEventListener(KeyboardEvent.KEY_DOWN, toggleDevConsole, false, 0, true);

Is it possible to make an object "Transparent" to mouse click?

Im developing a flash game, and i would love to implement raining effect. Here's my progress on rain so far: http://www.squ4re.eu/Rain.html
The code is pretty simple; every raindrop is an object, when it hits the ground it places itself again at the top of the screen and adds splash animation.
But the problem is to click something BEHIND the rain. Lets say i have some selectable units at the battleground. In most cases an random raindrop interrupts selecting an object behind it. So here's my question: Is it possible in flash to create object "transparent" to mouse click, so i can click an object behind it? Or is there any other way to solve this problem?
Thank you in advance.
As #putvande mentioned, you could use mouseEnabled on every interactive object that should be disabled for mouse interaction. You also could create rainLayer and disable it for mouse interaction:
myRainLayer.mouseEnabled = false;
myRainLayer.mouseChildren = false;
mouseChildren - determines whether or not the children of the object are mouse, or user input device, enabled. If an object is enabled, a user can interact with it by using a mouse or user input device. The default is true.
Also consider to use display objects that don't inherit from InteractiveObject, like Bitmap, Shape and Video

Actionscript 3: How to have a keyboard Keystroke "Button" go to specific Frame FROM a specific Frame?

I'm Super New to Programming in general and very New to Actionscript 3. It's been a rough but fun ride.
Anyway For the work I am doing I have my animation Play up to a certain point and it asks the viewer a question, The viewer has 3 choices, and each of those choices are connected to a button on the keyboard. A B C or D.
After searching for someone with a similar problem, My solution so far is this:
stage.addEventListener(KeyboardEvent.KEY_DOWN, cNote);
function cNote(event:KeyboardEvent):void {
trace(event.keyCode);
if (event.keyCode==67) {
gotoAndPlay(21);
}
I have this repeated 4 times each for the different Keys.
This works and allows me to move the viewer to the Frame with their response, however Any time during the animation they can press the button and it will move them to the Frame of the corresponding button (in this case Frame 21). How do I set it so that the keypress will only respond and move them to Frame 21 when they are on Frame 20 for example? (I suspect it has something to do with the "stage" part in the code but I cant get it to work without it.)
I also have the audio for the animation on a separate Layer and even though the visuals change as it goes to the correct frame, the audio continues as if the key was not pressed. Is there also a way to connect the key to make it stop the current audio and then play the new audio? Or is there a better way to do this?
Sorry if this is confusing. Thank you for your help :)
It has been quite awhile since I touch flash. From what I remembered, you can click on the frame at your movieclip, insert a keyframe by pressing f6, and press f9 to insert the listener at that frame and that frame only, after an input has been pressed, you remove it. for example:
if (event.keyCode==67) {
gotoAndPlay(21);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, cNote);
}
For the audios, I usually plays them using code, but I'm quite sure there's a way to drag and drop the audio from library to the movieclip. so I can do sound1.play(), when a button is pressed, I can do sound1.close() and sound2.play()
For more reference:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html

How to ENTIRELY remove an flvplayback from stage when going to another flvplayback on another frame?

I'm trying to create an EXE projector using flash 5.5 AS3 where I have a few videos (FLVs) to show (their location is right next to the exe file in the same directory) - each load in a different frame, and all of those videos should also have a full screen option to them. Those are original videos that people WILL want to watch in full screen. It's essential for the experience...
The problem(s) I currently have (after fixing the sound that didn't stop after going to a different video) are hard to describe, but I'll try really hard.
Ok, so when I click the full screen button on a video and watch it in full screen, I will eventually want to exit the full screen, so I click on the same icon at the bottom to exit full screen (or ESC button, it's the same) and then click the navigation button to go to the SECOND FLV's frame to watch the other video. After watching the second video in full screen and then exiting full screen, flash takes me to the FIRST video's frame and that is a big problem. Also, now the button that takes me BACK to the second video's frame won't work. It's like flash is stuck.
I use the Components --> FLVPlayback 2.5 from the componant menu (I don't really know AS3 programming) and I fix its properties in the component parameters.
Also, I don't think that any of the followings are the reason for the bug, but I use these 3 scripts to stop all sound when navigating away from one frame (with an FLVplayback) to
another frame with another FLVplayback:
MyFLV.stop();
SoundMixer.stopAll();
MyFLV.addEventListener(Event.REMOVED_FROM_STAGE,xyz);
function xyz(e:Event):void{
MyFLV.stop();
}
I've found these online where people asked help for the sound bug I described.
The third script was suppose to remove the FLVplayback from the stage before going to another frame, but it works only when NOT GETTING INTO FULL SCREEN. I need something that will COMPLETELY remove the previous video from the stage so after exiting the SECOND viewed video, flash won't take me to a video that from some reason is still in its memory. I have something like 30 videos in my project and I need to remove each and every one of them off of the stage before navigating to the next frame to open a new FLVPlayback.
I tried to add a link to a demo I made with the problem so you can look at it, but it triggered a "oops, something went wrong" error, probably anti spam mechanism...
I would recommend using only one frame and only one flvplayback instance. Otherwise you have to deal with weird bugs like the one you are getting (usually caused by misplaced or forgotten code). Of course, using only one frame requires using more code, but with the number of hard-fixes it looks like you were making for the bugs, you may end up with less code.
Don't worry, I'll walk you through everything!
Reasons to use code (as opposed to multiple frames):
Easier to keep track of:
Know where all your code is so you can easily find and fix any problems.
Make changes more easily
You want to switch an existing video? edit a file reference and you are done.
Want to add a video? no more dragging a new flvplayback instance onto a new frame just add some very simple code and a button and you're done.
More customization
Reasons to use multiple frames (and multiple flvplayback instances):
easier to place visually
Some people find it easier when they have an actual movieclip that they can visually place on the stage
Less code
Here we go:
//import flv library
import fl.video.*;
This allows you to use ActionScript to manipulate the flv player
//video playback code-----------------------//
var myVideo:FLVPlayback = new FLVPlayback();
this creates an instance of FLVPlayback called myVideo (referenced from now on in the code as myVideo)
this next chunk shows many of the customizable features of the flv player. It is not necessary to include them.
//places the video player on stage at x,y
myVideo.x = 115;
myVideo.y = -10;
//uses SkinOverPlayFullscreen.swf for controls
myVideo.skin = "SkinOverPlayFullscreen.swf";
//color of controls
myVideo.skinBackgroundColor = 0x333333;
//hide controls and time it takes controls to fade and reappear (milliseconds)
myVideo.skinAutoHide=true;
myVideo.skinFadeTime=300;
//add the player to the stage
addChild(myVideo);
And now comes the important part. I have made buttons and added them to the stage. I gave each of the buttons a different instance name (box1_btn, box2_btn, and box3_btn). When someone clicks on a button, an "event" will occur.
//button listener code-------------------------//
//when button 1 is clicked throw button 1 event
box1_btn.addEventListener(MouseEvent.CLICK, clicked1);
//when button 2 is clicked throw button 2 event
box2_btn.addEventListener(MouseEvent.CLICK, clicked2);
//when button 3 is clicked throw button 3 event
box3_btn.addEventListener(MouseEvent.CLICK, clicked3);
//play different videos for different buttons---------//
//when button 1 event is thrown
function clicked1($e:MouseEvent):void
{
//play video 1.flv
myVideo.source = "1.flv";
}
//when button 2 event is thrown
function clicked2($e:MouseEvent):void
{
//play video 2.flv
myVideo.source = "2.flv";
}
//when button 3 event is thrown
function clicked3($e:MouseEvent):void
{
//play video 3.flv
myVideo.source = "3.flv";
}
This code will not have any sounds that keep playing because two videos cannot play at the same time in one instance of the player. Nor will it have any mess-ups when you come out of fullscreen because there is only one frame for the video to go back to.
Some possible problems you may run into:
It doesn't work at all:
Make sure you have added an instance of FLVPlayback to the library by adding an instance to the stage from the components menu (window>>components or ctrl+F7) and then deleting it from the stage (it should still appear in the library).
The playback buttons I want aren't showing up:
There is a great explanation of how to use As3 to manipulate FLVPlayback here:
http://www.republicofcode.com/tutorials/flash/as3flvplayback/
find the section about "Applying a Skin to the FLVPlayback Component" and follow it to use an adobe playback skin. If you want to make your own unique skin I would recommend opening and editing one of the pre-made skins. I found mine in
C:\Program Files (x86)\Adobe\Adobe Flash CS6\Common\Configuration\FLVPlayback Skins\FLA\ActionScript 3.0
I hope this helps!
Below would be simplest way to unload the FLVPlayback
removeChild(MyFLV);
it works fine for me
flvPlayBack.stop();
removeChild(flvPlayBack);
stops the sound and removes the playback.

How to capture flash events outside the swf?

I would like to know if flash events (say clicking a button) can be captured somewhere outside the swf. Say, I click on a button and a popup comes up telling which buttom was clicked. The popup should not be a part of swf.
Thanks in advance
Try:
In your javascript:
function sayClicked(whatWasClicked) {
alert(whatWasClicked);
}
in ActionScript:
protected function onButtonClicked(e:MouseEvent):void {
ExternalInterface.call('sayClicked', (e.target as MovieClip).name);
}
ok your short answer is you cant, flash is only limited to its own movie, anything outside this movie, object can only be detected from another language such as java, php.
So by stand alone im assuming just a swf on a html page or just a pop out advertisement.
But it is possible to trace the mouse when it leaves the flash movie area,again it is detecting that there is no mouse in the flash movie area, its not detecting the mouses position on the rest of the screen to say, or web browser.