I have been making an advent calendar in which when you press the button the door opens. I have created a variable to control which date you can open them on called 'AllowOpen' if it is the right date. I have also created a function to go to a frame when clicked.
var AllowOpen: Boolean = false;
if (Day == 1) {
AllowOpen = true;
} else {
AllowOpen = false;
}
button1.addEventListener(MouseEvent.MOUSE_DOWN, click);
function click(event:MouseEvent):void
{
gotoAndStop(2)
}
I can't work out how I would tell the the program to only open the door if allow open is true. I have tried the 'if' statement but it doesn't seem to work. Thanks
OK, you could put the 'if' loop inside the function as already suggested thusly:
function click(e:Event):void{
if (AllowOpen) {
gotoAndStop(2);
}
}
BUT, spidey senses tingling. I would opt for adding an ENTER_FRAME listener so that as the day changes you automatically change boolean values for each day/door to open:
var my_boolean_var_i:boolean = false;
addEventListener(Event.ENTER_FRAME, checkDay);
function checkDay(e:Event):void{
if(Day == day_i){
my_boolean_var_i = true;
}
}
"i" would be another variable that you would declare to store an integer from 1 to 28 depending on the date and then a set of variables 'day + i'. Then you can have a listener/function for each door named sequentially with i to keep everything organized:
door_i.addEventListener(Event.MOUSE_CLICK, click_i);
function click_i(e:Event):void{
if(my_boolean_var_i == true){
gotoAndStop(2);
}
}
This is the way I would go about settling the task. It's a lot of repetitive code so there is bound to be some more elegant way to do this from a more advanced user. Also, if you want to animate the door look up GreenSock TweenLite. VERY useful and friendly for graphics and whatnot.
Related
I'm very much a beginner when it comes to programming; I'm doing a flash game for my 2D Game class on Adobe Animator, and I had a doubt about the code that my instructor couldn't answer himself. Long story short, I want the character speed to increase based on how long the key has been pressed, so I came up with this:
spdX = spdX + aclMov*(tempo) - aclFrc*(tempo);
Where the variable tempo would increase as long as the key is being held down, and I would check if it is with KeyboardEvent.repeat, as in:
if(heldDown){while(heldDown){tempo += 1}}
else{tempo = 0}
spdX = spdX + aclMov*(tempo) - aclFrc*(tempo);
However when I try to do that, the output responds with "Property repeat not found on flash.events.KeyboardEvent and there is no default value". I assume that this is because KeyboardEvent.repeat is not defined in the medium I'm using. Is there anyway I can reproduce the same effect of KeyboardEvent.repeat, perhaps by creating a function that mimics what it would have done?
Thanks in advance.
(Edit 1)
I begin apologizing for my shortness of clarification, as well as my ignorance in the topic as I am barely a beginner when it comes to as3, and am not properly presented yet to many of the terms I've read.
So, thanks to the meaningful contributions of comments, I already have been given a glimpse of what kind of workaround I would need to do to substitute KeyboardEvent.repeat. There are other parts of the code of relevance to the problem, as well:
stage.addEventListener(KeyboardEvent.KEY_DOWN,pressKey)
function pressKey (Event){
(...)
if(Event.keyCode == (Keyboard.A)) {left = true;}
(...)
}
stage.addEventListener(KeyboardEvent.KEY_UP,releaseKey)
function releaseKey (Event){
(...)
if(Event.keyCode == (Keyboard.A)) {left = false;}
(...)
}
This is how the code was intended to go. It was suggested that I use the getTimer() method to record the moment the event KEY_DOWN happens, stopping when the KEY_UP comes into effect. Problem is, how can I increment the code to make it differentiate between those two events, and more specifically, how can I adapt the ENTER_FRAME event so that differentiating between them still works with it? Here's the most relevant parts of it, by the way:
addEventListener(Event.ENTER_FRAME,walk);
function walk(Event) {
if(left) {
(...)
char.x -= spdX;
(...)
}
I assume that the code worked up till now because, as the state of "left" constantly switched between "true" and "false", the if conditional was met repeatedly, leading the character to move. However, if I try to make it so that the conditional depends on "left" staying "true" for a certain time, the code becomes incompatible with itself.
In short, it brings the question of how to adapt the "KEY_[]" event listeners and the "walk" function to work, in using the getTimer() method, to work together.
Again, thanks in advance.
I believe that would be somehow self-explanatory .
stage.addEventListener(KeyboardEvent.KEY_DOWN, onDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onUp);
addEventListener(Event.ENTER_FRAME, onFrame);
var pressedKeyA:int;
// Never name variables and arguments with the same name
// as existing classes, however convenient that might seem.
function onDown(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.A)
{
// Let's record the moment it was pressed.
pressedKeyA = getTimer();
}
}
function onUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.A)
{
// Mark the key as not pressed.
pressedKeyA = 0;
}
}
function onFrame(e:Event):void
{
// It is true if it is not 0.
if (pressedKeyA)
{
// That's how long it has been pressed. In milliseconds.
var pressedFor:int = getTimer() - pressedKeyA;
// Change the position with regard to it.
// For example 1 base + 1 per second.
char.x -= 1 + pressedFor / 1000;
}
}
I'm currently building a 50 button interactive display, it needs on a specific frame to log 3 button clicks then save a variable or something that 2 slides later will relay whether the user has chosen the correct 3 buttons. This warning is a simple movie clip. Below I listed the 2 frames that need to relate to each other. Please keep in mind I am fairly new to programming Flash and still struggle correct syntax and utilization.
I appreciate any or all input on how I can better accomplish this using Actionscript 3
The below is hiding 3 boxes that will surround the correct answer once clicked. The fl_check36 needs to somehow in the else section send a variable or something i can reference that would let me show the error box movie clip to the user. (I already have a reset button working for that page)
[Frame 36]
MDI_07_box_mc.visible = false;
MDI_08_box_mc.visible = false;
MDI_14_box_mc.visible = false;
// Boxes to be clicked
MDI_07_btn.addEventListener(MouseEvent.CLICK, fl_ClickToShow_14a);
function fl_ClickToShow_14a(event:MouseEvent):void
{
MDI_07_box_mc.visible = true;
}
MDI_08_btn.addEventListener(MouseEvent.CLICK, fl_ClickToShow_14b);
function fl_ClickToShow_14b(event:MouseEvent):void
{
MDI_08_box_mc.visible = true;
}
MDI_14_btn.addEventListener(MouseEvent.CLICK, fl_ClickToShow_14c);
function fl_ClickToShow_14c(event:MouseEvent):void
{
MDI_14_box_mc.visible = true;
}
// Check for boxes correct and go to next frame
MDI_18_btn.addEventListener(MouseEvent.CLICK, fl_check36);
function fl_check36(event:MouseEvent):void
{
if (MDI_14_box_mc.visible && MDI_08_box_mc.visible && MDI_07_box_mc.visible)
gotoAndStop(37);
else
Feedback_07_Wrong_mc.visible = false;
}
This frame just needs to check if the user got the information correct on frame 36 and show or hide the Feedback based on that.
[Frame 38]
stop();
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler_2);
function fl_EnterFrameHandler_2(event:Event):void
{
if (globalVar = 1)
Feedback_07_Wrong_mc.visible = true;
Feedback_07_Wrong_mc.gotoAndPlay(2);
}
Reset_Btn.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndPlayFromFrame_2);
function fl_ClickToGoToAndPlayFromFrame_2(event:MouseEvent):void
{
gotoAndPlay(1);
}
Thanks in advance!
What #Karma said is true. When you declare any variable on frame 36, it is accessible to any other frames that preceed it. You can also do the same by creating another layer called "Variables" with no keyframes in between which stores all your variables. This way, you would have confidence that the variable is acceccible to all the keyframes of the other layer.
EDIT: I don't know if this is the norm, but I preferred to leave the original question in and add updates. Please, feel free to let me know if I should eliminate the original code snippets and somesuch.
I am trying to create a slideshow-like presentation in flash CS6, using a main timeline with one symbol in each frame and the different animations (some quite complex) in those symbols. Since I'm going to use a presenter remote, I've captured the keystrokes and coded pg_up and pg_down to go to the next and previous frame respectively:
stage.addEventListener(KeyboardEvent.KEY_DOWN, pagerFunction);
var symb:movieClip;
function pagerFunction(e:KeyboardEvent):void
{
var myKey = e.keyCode;
if (myKey == Keyboard.PAGE_DOWN){
if (symb != null){
//some code that allows to control the symbols timeline forward
} else {
nextFrame();
}
}
if (myKey == Keyboard.PAGE_UP){
if (symb != null){
//some code that allows to control the symbols timeline backward
} else {
prevFrame();
}
}
The problem I'm having is the following. I've added framelabels and stop(); code inside the symbol animations where I needed to control the step from one animation to the next one. However, after having tried numerous solutions on the web, I haven't been able to succeed having the symbols react to pg_up and pg_down as if they were part of the main timeline.
To sum up, what I need to solve is this:
Enter Main timeline Frame
Identify symbol instance (labeled as _mc)
Inside symbol timeline, play from first frame (labeled '0') until next labeled frame ('1' and so on)
stop and wait for next pg_down to start playing from next labeled frame to the following (i.e. '1'-'2'), or pg_up to start playing from the previous labeled frame (i.e. '0' to '1') (for this, I would use a variable to keep track.
on last frame (labeled 'final') exit symbol focus and return keyboard control to main timeline to allow pg_down and pg_up to move to the next / previous frame. on pg_up on symbol.currentFrame == 0, do same.
BTW, if there's a better way to achieve this, I'm open (and quite desperate) for better suggestions / solutions.
Thank you so much to anyone who can help!
Edit: Ok, I guess I wasn't too clear on the issue, so I'll try to add a bit to this:
addEventListener(KeyboardEvent.KEY_DOWN, mc_pagerFunction);
var lbl:String;
var counter:Number = 0;
function mc_pagerFunction(e:KeyboardEvent):void {
var myKey = e.keyCode;
if (myKey == Keyboard.PAGE_DOWN){
lbl = this.currentFrameLabel;
if (this.currentFrameLabel == 'final'){
stop();
stage.focus = this.parent; //which would be the main timeline
} else if (Number(lbl) == counter){
this.gotoAndStop(lbl);
counter++;
} else {
this.gotoAndPlay(lbl);
}
}
if (myKey == Keyboard.PAGE_UP){
lbl = this.currentFrameLabel;
if (this.currentFrameLabel == '0'){
stop();
stage.focus = this.parent; //which would be the main timeline
} else if (Number(lbl) == counter){
this.gotoAndStop(lbl);
counter--;
} else {
this.gotoAndPlay(lbl);
}
}
}
Now, this bit is the behaviour I'd like to see inside the symbol when the main timeline goes into the next frame, thus being able to use the main timeline as sort of slideholder and the real thing happening inside the symbol.
Btw, I'd like to try and keep all code within the main action layer, not in the symbols. I tried that, shifting focus to the symbol and it didn't work either, and having code all over the place grates against my nerves ;).
I hope this throws some light on what I'm stuck at.
Again, any help is appreciated. Thanks all in advance
UPDATE:
Please someone help me out here!
This is what I'm trying. Logically, it makes all the sense in the world, except that it doesn't work.
var symb:MovieClip;
symb = MovieClip(root); //assign symbol I want to be controlled by pg_up/pg_down
symb.focusRect = false;
stage.focus = symb; //focus on current symbol
symb.addEventListener(KeyboardEvent.KEY_DOWN, mc_pager); //add keyboard event listener
function mc_pager(e:KeyboardEvent):void{
var myKey = e.keyCode;
if (myKey == Keyboard.PAGE_DOWN){
do{
symb.play(); // it plays, then checks if the lbl is null or final, then quits
} while (symb.currentFrameLabel == null && symb.currentFrameLabel != 'final');
symb.stop();
symb.removeEventListener(KeyboardEvent.KEY_DOWN, mc_pager);
stage.focus=MovieClip(root); //return focus to main timeline (in the next keyframes, the focus is on the nested _mc
}
if (myKey == Keyboard.PAGE_UP){
do{
symb.prevFrame();
} while (symb.currentFrameLabel == null && symb.currentFrameLabel != '0');
symb.stop();
symb.removeEventListener(KeyboardEvent.KEY_DOWN, mc_pager);
stage.focus=MovieClip(root);
}
}
Where am I being to moronic to get it right? Please, guys, you're the experts, I need your advice here. Thanks!
UPDATE:
Doing a trace on symb, it seems like as soon as it enters the function, it forgets the initial assignment (symb = MovieClip(root)) and shows null. Why?
In this sample, I created a basic proof of concept where I have a circle MC with an instance name of "c" on the main timeline. Within this mc, I created with 2 keyframes inside with stop actions on both. I colored the circle a different color on frame 2 and labeled it as "two".
In the Main timeline I have the following code:
import flash.events.KeyboardEvent;
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyEvt);
function keyEvt(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.PAGE_DOWN){
trace("down");
c.gotoAndPlay("two");
}
}
This should help form a foundation for your code as long as you stick with targeting the symbol through direct reference and ensure your keyboard event is attached to the stage.
Also, always stick with getting a basic working version down first. I.E. Check to see if your keyboard listeners are working for your target object and then build additional functionality off of that.
TLDR: I need code in action script 3 which will let users press keys like QWER to jump to a specific scene.
So what I'm doing is creating and interactive comic within flash, and to be blunt I didn't know any AS3 code before this and still pretty much know none.
So I'm going to need some help on this one and I think it is worth mentioning that I am using sound in this project.
what I need to know is how to use letter keys (eg. QWER) to act as shorts cuts to jump to specific scenes. What I have so far which is working is this and another version which uses a mouse click instead.
stop(); ( 1 )
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_KeyboardDownHandler);
function fl_KeyboardDownHandler(event:KeyboardEvent):void {
gotoAndPlay(currentFrame+1);
}
and of course all this does is advance the frame, which I do need for some sections of dialogue but that's the basis I've been trying to get it to work.
I do know that q = 81, w = 87, e = 69 and r = 82.
Besides that I've got nothing and I need some help real bad.
You need to check which key has been pressed, you can do it like this:
function fl_KeyboardDownHandler(event:KeyboardEvent):void {
if(event.keyCode == Keyboard.Q){
//do what you need to do when Q was pressed
}else if(event.keyCode == Keyboard.W){
//same for W
}
...etc
}
The KeyboardEvent instance contains data about the event itself, part of it being keyCode, which gives the code of the pressed key. Using this property, you can detect which key the user pressed, and react accordingly.
As you understood, you can use gotoAndPlay() and gotoAndStop() to move around your animation.
It gives us the following code :
stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_KeyboardDownHandler);
function fl_KeyboardDownHandler(event:KeyboardEvent):void {
if(event.keyCode == Keyboard.Q) {
gotoAndPlay(1); // Back to the start
} else if (event.keyCode == Keyboard.W) {
gotoAndPlay(currentFrame-1); // Back one frame
} else if (event.keyCode == Keyboard.E) {
gotoAndPlay(currentFrame-1); // Forward one frame
} else if (event.keyCode == Keyboard.R) {
gotoAndPlay(100); // Go to 100th frame
}
}
Note that I am using the Keyboard class to get the keyCode associated to a specific key.
I am a complete n00b.
I'm working on a game. Basically, I have to perform no action if a button is pressed on a certain keyframe, but if it's not clicked, I need the scene to proceed until a certain point and then go to another frame.
In my stupid head I thought: if I can create an empty global variable I could input "something" when the button is clicked on my frame and check on a latter frame "if globalvar == "something": nothing happens, else: gotoAndPlay(where I need)"
Explanatory image:
Apparently that's not how AS3 works. So what can I do?
import flash.events.MouseEvent;
var pressed = "no";
function work(event:MouseEvent):void
{
pedal.visible = false;
cursor_mc.visible = false;
pressed = "yes"
}
pedal.addEventListener(MouseEvent.CLICK, work);
This is what I've got when the action needs to be performed.
Then I would put (I've never written an if statement in as3)
if (pressed == "no") {
gotoAndPlay(some other frame);
}
This would be put on a complete different frame AND LAYER from the previous so that the part in between is still played.
You got to add a new event, and ENTER_FRAME event to which will fire a function on every frame. There you could check whether the button is pressed. For example:
stage.addEventListener(Event.ENTER_FRAME, updateFunction);
function updateFunction(e:Event){
if(pressed == "no"){
if(currentFrame == frame number when you want to check){
gotoAndPlay(some other frame);
}
}
}