I am fairly new to AS3, so here is my problem.
I have two text input boxes p1 and p2. I want to do a conditional test to see if p1 has the focus. If it does not, then p2 must have the focus. Here is some code I am trying to get to work.
if ((Selection.getFocus()) == (p1totalScore.text)){
p1Score();
} p2Score();
Thanks for your help.
David
Without a FocusManager, you could test what the stage is returning for focus:
(If you have textInput1 and textInput2 on the art-board)
import flash.events.MouseEvent;
import fl.controls.TextInput;
var textInput1:TextInput;
var textInput2:TextInput;
stage.addEventListener(MouseEvent.CLICK, mouseClickHandler);
function mouseClickHandler(event:MouseEvent):void
{
if(stage.focus == textInput1.textField)
trace("text field 1 has focus.");
else if(stage.focus == textInput2.textField)
trace("Text field 2 has focus.");
}
I think a better approach than you're attempting is to add event handlers for focus change:
import fl.controls.TextInput;
import fl.managers.FocusManager;
import flash.events.FocusEvent;
var textInput1:TextInput;
var textInput2:TextInput;
var focusManager:FocusManager = new FocusManager(this);
textInput1.addEventListener(FocusEvent.FOCUS_IN, textInput1FocusHandler);
textInput2.addEventListener(FocusEvent.FOCUS_IN, textInput2FocusHandler);
function textInput1FocusHandler(event:FocusEvent):void
{
trace("textInput1 has focus.");
}
function textInput2FocusHandler(event:FocusEvent):void
{
trace("textInput2 has focus.");
}
Adobe will get you 99% of the way:
'http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/fl/managers/FocusManager.html'
I just changed the function to return the name of the control that has focus, instead of the instance name that their example returns.
private function focusChange(e:FocusEvent):void {
var ti_now:InteractiveObject;
ti_now = fm.getFocus();
trace("Focus now: ", ti_now.name);
}
Related
I'm writing this code that tests your reaction time and then advances to the next frame. It shows a box and then time the difference between when the box appeared and when the use presses [A]. Heer is my code
import flash.utils.Timer;
import flash.events.Event;
import flash.utils.getTimer;
stop();
var canPress = false;
var startClock:Timer = new Timer(4000+Math.random()*6000, 1);
grbox.y = -500;
startClock.start();
var startTime:int = 0;
function displayBox(evt:Event):void{
canPress = true;
grbox.y = 143;
var startTime:int = getTimer();
}
function Tpressed(e:KeyboardEvent):void
{
if(e.keyCode==Keyboard.A){
if(canPress==true){
var endTime:int = getTimer();
score1 = endTime-startTime;
if(score2<0){
//gotoAndStop(3);
}
else{
//gotoAndStop(4);
}
}
}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, Tpressed);
startClock.addEventListener(TimerEvent.TIMER, displayBox);
For some reason if I just spam the [A] button it will advance to the next frame. Why is this happening?!?! My 'gotoAndStop(4);' command is commented out so it should do anything, yet it is.
EDIT: Here is my .fla file: https://drive.google.com/open?id=0BxtLreFIVnSWR2VPSGdSaHZGaVk
RAW CODE: https://docs.google.com/document/d/1GRZIaKAdRNu3z3aPjjXNcgqMl2BhR-ZBT6gU7OeSbWQ/edit?usp=sharing
On one of your frames you added an event listener for key presses to the stage. That's probably where your problem is at. So when you press any key, it calls the pressed function as well as the Tpressed function. And since the key that is being checked for in each function is "A", both functions execute their if blocks. And both if blocks call a gotoAndStop method.
Without knowing exactly what you are trying to accomplish in the big picture, this problem could be fixed by removing the event listener for the pressed function when you leave that frame.
Could look like:
function pressed(e:KeyboardEvent):void
{
if(e.keyCode==Keyboard.A){
gotoAndStop(Math.round(Math.random()+2));
// remove the event listener since we are leaving this frame and you apparently only want this function to work on this frame
stage.removeEventListener(KeyboardEvent.KEY_DOWN, pressed);
}
}
I have called a setInterval on TouchEvent.TOUCH_END and I want to clear it when ever screen is touched.
Here is my code:
import fl.motion.MotionEvent;
import flash.display.MovieClip;
import flash.utils.*;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
stage.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
function onTouchBegin(evt:TouchEvent)
{
clearInterval(MovieClip(root).myInterval);
}
function onTouchEnd(evt:TouchEvent)
{
MovieClip(root).myInterval = setInterval(showTimer,1000);
}
function showTimer()
{
trace("interval working");
}
Your provided code doesn't really explain everything so there will be a fair bit of speculation in this answer:
Possiblity No. 1:
Your way of casting root to MovieClip is not working. Try changing to following:
function onTouchBegin(evt:TouchEvent)
{
var intervalRef:int = (root as MovieClip).myInterval;
clearInterval(intervalRef);
}
Possiblity No. 2:
It seems that your code is written in a frame. And although if you define something in a previous frame it should work, but if you have the code on a different (lower) layer on the same keyframe it could define the variable later and your MovieClip(root).myInterval variable is undefined or null is the value is not defined. So check if your variable even exists:
function onTouchBegin(evt:TouchEvent)
{
trace(MovieClip(root) == null); // see if the root is defined
trace(MovieClip(root).myInterval); // see if the myInterval is defined
}
Possiblity No. 3:
You're cycling through frames. When I had 2 frames: one blank and one with your code, the code didn't work properly. Tested in Flash CC.
Possibility No. 4:
You have a run-time error somewhere else and your whole frame's code is not being executed. Do you use the debug version of Flash Player?
Possible solution for less headache:
Use a Timer. It's easy to control, easy to manage and dispose of. I've edited your code to work with Timer and tested. Feel free to use it for your project.
import fl.motion.MotionEvent;
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
var timer:Timer = (timer == null) ? new Timer(1000) : timer;
timer.addEventListener(TimerEvent.TIMER, onTick);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onTouchBegin); // you can change back to TouchEvent, but since you're using TOUCH_POINT it's pointless so I'd just use MouseEvent
stage.addEventListener(MouseEvent.MOUSE_UP, onTouchEnd);
function onTouchBegin(evt:Event)
{
timer.stop();
}
function onTouchEnd(evt:Event)
{
timer.start();
}
function showTimer()
{
trace("interval working");
}
function onTick(e:TimerEvent):void
{
showTimer();
}
I do want to note that your code works if I just copy-paste it in a single frame Flash file. But still, it's encouraged by Adobe to use Timer instead.
Hi im trying to create a very simple drag and drop game in flash and I the scene to just loop round itself so say, if ( user does this) then go back to the beginning of the scene. but when I try this the symbols that the user has moved stay to where they have moved them too rather than returning to the position they were in at the start of the scene.
Can anyone explain a way to get the symbols to return to where they were at the begining of the scene once the if statement has completed?
The following example will traverse the display list, storing symbols along with their initial positions in a Dictionary. When it's time to reset, just call the resetToOriginalPositions method, passing it the Dictionary that was created.
import flash.utils.Dictionary;
import flash.display.DisplayObject;
import flash.geom.Point;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.MovieClip;
var originalPositions:Dictionary;
if(!originalPositions)
{
originalPositions = collectPositions(this);
}
function collectPositions(container:DisplayObjectContainer):Dictionary
{
var positions:Dictionary = new Dictionary(true);
for(var i:int = 0; i < container.numChildren; i++)
{
var currentSymbol:DisplayObject = container.getChildAt(i);
positions[currentSymbol] = new Point(currentSymbol.x, currentSymbol.y);
// this will allow the symbols to be dragged/dropped
currentSymbol.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler);
currentSymbol.addEventListener(MouseEvent.MOUSE_UP, clickHandler);
}
return positions;
}
function clickHandler(e:MouseEvent):void
{
var target:MovieClip = e.target as MovieClip;
if(e.type == MouseEvent.MOUSE_DOWN)
{
target.startDrag();
}
else
{
target.stopDrag();
}
}
function resetToOriginalPositions(positions:Dictionary):void
{
for(var currentSymbol:Object in positions)
{
var position:Point = positions[currentSymbol];
DisplayObject(currentSymbol).x = position.x;
DisplayObject(currentSymbol).y = position.y;
}
}
// this line should be called in your if statement that you already have set up
resetToOriginalPositions(originalPositions);
Marcela's answer may work for you, but just in case you would like something a little simpler...you can store the original positions on a dynamic property of each object. When the condition you require is met to go back to the original positions you can call a function that resets the current x and y positions to the original ones.
//place in frame 1
dragObject1.originalY = dragObject1.y;
dragObject1.originalX = dragObject1.x;
dragObject2.originalY = dragObject2.y;
dragObject2.originalX = dragObject2.x;
//...rest of object posisitions
function resetObjectPositions()
{
dragObject1.y = dragObject1.originalY;
dragObject1.x = dragObject1.originalX;
dragObject2.y = dragObject2.originalY;
dragObject2.x = dragObject2.originalX;
//...rest of object positions
}
//later in scene
if(condition)
{
resetObjectPositions();//make sure to run this code before going back to frame one in the scene to use the original values;
}
Hi I browsed the web and this web page for answer but can't seem to find solution for my problem. I've created a typewriter effect. It's being displayed through dynamic text box(tekst_txt). What I would like to achieve is to be able to use html tags to change specific word's font to bold or italic by just including i.e. < b > and < /b > but I can't seem to pull this of. I would really appreciate some advice.
That is code that shows up in first frame (text box doesn't exist on that frame):
import flash.events.MouseEvent;
stop();
var tekst:String = "";
var i:uint = 0;
var licznik:Timer = new Timer(20);
tekst_txt.htmlText = tekst_txt.text;
stage.addEventListener(MouseEvent.CLICK, klikaj);
function klikaj(event:MouseEvent):void
{
if (licznik.running == true)
{
tekst_txt.htmlText = tekst;
licznik.stop();
}
else if (licznik.running == false || licznik == null)
{
nextFrame();
tekst_txt.text = "";
}
}
And this is code from next frame(textbox already exist in this frame):
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
stop();
tekst="Tekst1Tekst1<i>Tekst1</i>Tekst1Tekst1Tekst1Tekst1Tekst1Tekst1Tekst1";
licznik.start();
licznik.addEventListener(TimerEvent.TIMER, odpalaj);
function odpalaj(e:TimerEvent):void
{
//tekst_txt.htmlText = tekst_txt.text;
tekst_txt.appendText(tekst.charAt(i));
//tekst_txt.htmlText=tekst_txt.text;
i++;
if (i >= tekst.length)
{
licznik.stop();
}
}
The problem you are facing is that any form of HTML formatting will take more than 1 character to describe, so when you try to do this animation character by character, you are really just setting the raw html markup into the text.
This may seem a bit messy, but here's something you can try...
You would create a temporary textfield and set the whole html markup text into its htmlText value first, then you can getTextFormat to copy the formatting for every character as you are appending... this allows Flash to process the html for you.
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
stop();
tekst="Tekst1Tekst1<i>Tekst1</i>Tekst1Tekst1Tekst1Tekst1Tekst1Tekst1Tekst1";
// shove your html markup text into the htmlText of a textfield
// this allows Flash to deal with parsing the html
var myTextField:TextField = new TextField();
myTextField.htmlText = tekst;
licznik.start();
licznik.addEventListener(TimerEvent.TIMER, odpalaj);
function odpalaj(e:TimerEvent):void
{
// get the text directly from the temp textfield
// you want to do this because it will have already processed the html markup
// and will give you the correct indexes and length of your text
tekst_txt.appendText(myTextField.text.charAt(i));
// copy the textformat
var format:TextFormat = myTextField.getTextFormat(i, i+1);
tekst_txt.setTextFormat(format, i, i+1);
i++;
if (i >= tekst.length)
{
licznik.stop();
}
}
I have a problem with flash component ComboBox. When i wont to save a name in ComboBox its always without last letter!?
Here is the code:
var input_name:String;
text_field.addEventListener (TextEvent.TEXT_INPUT, text_input);
button.addEventListener (MouseEvent.CLICK, save);
function save (e:MouseEvent):void
{
text_field.visible = true;
text_field.adddEventListener(KeyboardEvent.KEY_DOWN, save_text);
}
function text_input(e:TextEvent):void
{
input_name = text_field.text;
}
function save_text(e:KeyboardEvent):void
{
var keyPressed:String = e.keyCode.toString();
if (keyPressed == "13")
{
combo.addItem({label:input_name, data:input_name});
}
}
So when i enter 'foo' in text field and press ENTER it saves in combobox just 'fo'...
Thx for answers :)
TextEvent.TEXT_INPUT is dispatched before the value has changed.
Event.CHANGE is dispatched after the value has changed.
This will work, including handling the enter key.
import flash.events.MouseEvent;
import flash.events.Event;
var input_name:String;
text_field.addEventListener(Event.CHANGE, text_input);
text_field.addEventListener("enter", save);
button.addEventListener(MouseEvent.CLICK, save);
function text_input(e:Event):void
{
input_name = text_field.text;
}
function save(e:*):void
{
text_field.visible = true;
combo.addItem({label:input_name, data:input_name});
}