adding score and displaying as3 - actionscript-3

I'm trying to implement a score to my quiz.
Currently how it works is when the user clicks the correct answer (which is a button), it displays to the frame where it says the answer is correct and displays the score.
if the user gets the answer wrong (again a button), it will go to the frame where it says the answer is wrong and the score will stay the same.
My code is as follows for the quiz buttons:
first correct answer:
//implementation of score
var score;
score = 0;
//adding points to score
score ++;
//setting the txt text field to score
scorecounter.text = score.toString();
//not embedding the font to display the score
scorecounter.embedFonts = false;
every corresponding correct answer:
//adding to score
score ++;
//setting the txt text field to score
scorecounter.text = score.toString();
scorecounter.embedFonts = false;
every corresponding incorrect answer:
//adding to score
score --;
//setting the txt text field to score
scorecounter.text = score.toString();
scorecounter.embedFonts = false;
I've got static text that says score, and dynamic text next to it that's blank and called scorecounter, where I'd like the score to go up by one.
What's happening now is that when the user answers the first answer incorrect (or enough incorrect) to display "NaN".
The quiz has five questions so I'd like the number variables to go down if the user gets the question wrong but only let it go down to zero, and to a maximum of five as the highest score possible (if user gets all correct).
How can I do that?
Cheers!

You are calling a function inside of itself. updateScore() can't be inside of function updateScore():void{}. That should make sense. The instruction for how to bake a cake can't include a step that says "bake cake". The instructions for how to get to the hospital can't include "get to hospital". Your instructions for updateScore include the step updateScore. So only call functions (that is, tell flash to execute a function) from outside of that function.
So what you need is to have all your code that will do what you want during updateScore() inside the function, and call it when the user does something that should cause an update.
function myFunction():void{
//do stuff
}
myFunction(); // this will trigger the function and "do stuff" will occur
For your new problem:
This code needs to go up at the top of your script outside of a function.
var score:int = 0;
instead of only declaring it after the first question is right.
You are declaring the variable score only after a correct answer, I think, so if the first answer is wrong, the score is NaN.

Related

Button Click Counter not incrementing

I have a similar animation in Flash with a replay button at the bottom. Once the animation completes, it does not loop. Instead if you click replay, the animation starts again.
I want a textbox which will display the amount of times the button was pressed.
My existing code is currently replaying the animation. It's incrementing the count to 1 (from 0) in trace but not getting set within the textbox. Additionally, if I click the button again, trace displays 1 again -- no increment occurred (1 to 2, 2 to 3, etc).
If I comment out gotoAndPlay(1), the incrementing works just fine and is displayed in the textbox -- but the animation does not play again.
What am I doing wrong?
import flash.events.MouseEvent;
var hitcount:Number = 0;
textCounter.text = String(hitcount);
function incCounter(event:MouseEvent):void
{
hitcount++;
textCounter.text = String(hitcount);
trace(hitcount);
gotoAndPlay(1);
}
replay_btn.addEventListener(MouseEvent.CLICK, incCounter);
The problem in your code is that you are creating and initializing every time your counter, so sure you will get every replay the value 1.
So to avoid that, you can just verify if you have already created the hitcount var otherwise create it :
if(!hitcount){ // hitcount is null, so create it
var hitcount:Number = 0;
}
As a good practice, you can also remove the MouseEvent.CLICK on your button if you don't need it. So you get something like this :
if(!hitcount){
var hitcount:Number = 0;
}
count.text = hitcount.toString();
function incCounter(event:MouseEvent):void
{
event.target.removeEventListener(MouseEvent.CLICK, incCounter);
hitcount++;
count.text = hitcount.toString();
gotoAndPlay(1);
}
replay_btn.addEventListener(MouseEvent.CLICK, incCounter);
Hope that can help.
If your flash movie is longer than one frame then the layer which you are placing your actions on the stage needs to extend that amount of frames as well. Otherwise the code is no longer there after frame 1. Also when you come back to frame 1 you are attaching yet another mouse event each time. Start your code with yourButton.removeEventListener to ensure you are only ever attaching one event to it. And every time the movie ends and goes back to frame 1 your counter is reset to 1.

Timer flash to show something at the right time

I want to make a timer that will show text at my panelText (dynamic text box) at specific time, actually I have a video that I want to have subtitles, and I want to use timer, my video is 3 minutes and 37 second long, and I have script that I want to show at some time, example at 1 minute 0 seconds it will show the text "hello, this is my video to learn about solar system" in my panelText, and at 2 minute I want to show text "There are 8 planets in our solar system", something like that. For information, I'm using flvPlayback to play the video and load the external video.
An example from my code:
var myTimer:Timer = new Timer(217000);
var time = 0;
myTimer.start()
myTimer.addEventListener(TimerEvent.TIMER,timerHandle);
function timerHandle(event:TimerEvent){
if(myTimer == 120000)
{
panelText.text="There's 8 planets in our solar system";
}
and i got error 1176: Comparison between a value with static type flash.utils:Timer and a possibly unrelated type int. can someone help me?, i'm sorry for my bad english
You should use FLVPlayback's addASCuePoint() function to make precise actions when your FLVPlayback fideo is playing. You use this function to set up whatever points you want to display custom subtitles, there can be as many of these as you want, then you listen for MetadataEvent.CUE_POINT event on your FLVPlayback instance, and process the cue point in order to display the associated subtitle. Note though, you will have to separately parse subtitle expiration, or assign a cue point to remove the displayed subtitle several seconds past the displaying cue point. Although it will be better if you will be able to add subtitles directly on the video, so that seeking through your video will not require handling of misaligned subtitles. Still, it's doable with pure AS3 code, if you would also listen to VideoEvent.FAST_FORWARD and VideoEvent.REWIND events to handle user interaction with playback and display corresponding subtitle by calling findNearestCuePoint() to find the closest earlier subtitle-enabled cue point.
An example of adding a cue point:
flv.addASCuePoint(0.1,"1",{text:"Subtitle one"});
flv.addASCuePoint(6.8,"2",{text:"Subtitle two"});
flv.addASCuePoint(11.8,"2 hide",{text:""}); // remove old subtitle
flv.addASCuePoint(120.0,"3",{text:"There are 8 planets in our solar system"});
Note that each call returns an Object, which is also returned whenever a MetadataEvent.CUE_POINT event is dispatched. This has a parameters sub-object that you have passed into addASCuePoint as third parameter, which you then parse and take actions depending on what's in there. Here, I've placed a single field "text" into each of the parameter objects, which should be the text to display as subtitles. So, then you listen to the cue point event and take actions, like this:
flv.addEventListener(MetadataEvent.CUE_POINT,cueHandler);
// do this only once, a listener does not need to be added per cue point
function cueHandler(e:MetadataEvent):void {
var cuepoint:Object=e.info;
if (cuepoint.parameters) {
panelText.text=cuepoint.parameters.text;
} else {
// DEBUG here
}
}
In case of seeking, you listen for FF and rewind events with a function that will call findNearestCuePoint(), retrieve its parameters.text and place that text into your text field.
You misunderstood the usage of the Timer class.
var myTimer:Timer = new Timer(n) means that the Timer will always "tick" at the specified interval n, in your case every 217000 milliseconds (217 seconds).
This might not be the best solution, but it'll show you how you can use the timer class for a scenario such as yours.
var myTimer:Timer = new Timer(1000); //a timer that will tick every second
myTimer.addEventListener(TimerEvent.TIMER, timerHandler);
myTimer.start(); //you should set up your listener before you start the timer
function timerHandler(event:TimerEvent):void{
//myTimer.currentCount will tell you how many times your Timer has ticked
//every tick, in this scenario, represents exactly one second, because we initialized the Timer with 1000 milliseconds
//so, if you want to show some text 86 seconds after the video has started, you could do:
if(myTimer.currentCount == 86){
panelText.text = "We're 86 seconds into the video";
}else if(myTimer.currentCount == 217){
//after reading your code it seems like you intended to let the timer only run 217 seconds, because that's the length of your video
//my proposed solution could also handle this, in this else if clause
myTimer.stop();
myTimer.removeEventListener(TimerEvent.TIMER, timerHandler);
myTimer = null;
}
}
The error is right.you are comparing a timer with a number!!.
fixed part of code:
if(myTimer.currentCount==120000){
panelText.text="There's 8 planets in our solar system";
}
and your timer constructor is wrong!the first argument is delay and next is repeat count.
the fixed code:
var myTimer:Timer = new Timer(100,2170);
var time = 0;
myTimer.start()
myTimer.addEventListener(TimerEvent.TIMER,timerHandle);
function timerHandle(event:TimerEvent){
if(myTimer.currentCount == 1200)
{
panelText.text="There's 8 planets in our solar system";
}
in this code, our timer ticked at every 0.1 second(100 miliseconds) and is ticked 2170 times. so, to set your text, you must put a zero after your desired second.
hope this helps :)

Restricting input text to numbers only

Is there a way to restrict text to nubmers only in an input textfield?
I tried using:
myInputText.restrict = "0-9";
But it had no effect. Are there any other solutions?
myInputText.restrict = "0-9\\-\\^\\\\";
Try this, this should work.
[EDIT: My method described below is an alternative to .restrict, and can theoretically allow for much finer control.]
Yes, you can, quite quickly. We're going to combine a Regex and an event listener.
First off, you're going to need to set up an event listener on the text box. I'll call the input box txtInput, for the sake of conversation. This will point to a function we'll write called validate();
txtInput.addEventListener(KeyboardEvent.KEY_DOWN, validate);
Now, we need to create our function.
function validate(evt:KeyboardEvent):void
{
var currentString:String = txtInput.text; //It is usually easier to work with the textInput contents as a string.
var numbersRegex:RegExp = /^\d*$/; //A regular expression accepting zero or more numbers ONLY.
var invalidRegex:RegExp = /\D+/; //A regular expression accepting one or more NON-numbers.
if(numbersRegex.test(currentString) == false) //Run the test. If it returns false...
{
currentString = currentString.replace(invalidRegex, ""); //Removes all non-numbers.
}
//Else, we do nothing.
txtInput.text = currentString; //Put the updated string back into the input box.
}
(Granted, that code is untested, but it should more or less work.)
The logic going on here: The user enters a character into the box. The event listener fires as soon as the key is pressed. If the string isn't 100% numbers, then the string is searched for all non-number characters, and those characters are removed.
EDIT AS REQUESTED: Also, make sure you don't have conflicting instance names. If you have two input boxes with the same name, Flash may be looking at the wrong one.
txtInput.text = "Sample text." should throw a compiler error if there's a duplicate, or in the worst case, show you which input box you ARE affecting.

AS3 Using Many Event Listeners Causing Problems, How to Reduce?

Confusing title, my bad.
Basically, I have a list of names. Looping through, I add a MovieClip, Set 2 properties to it, the name, and an ID. The MovieClip is at the same time made to function as a button and I add 4 listeners, mouse up, over, down, or out. I do this with every name. The function each one is set to is the same.
EX: enemyButton[i].addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
The enemyID turns up "not valid property," time to time when I click, it doesn't crash at all, but sometimes I have to hit the button a few times.
I have narrowed the problem down to having to be caused by the listeners.
The function as simple as:
EX: function mouseUpHandler(e:MouseEvent):void { enemySelected(e.target.enemyID); }
My question is, is too many listeners likely to be the problem? and how can I reduce them?
Here's a snippet of the loop:
var C:Class = Class(getDefinitionByName(enemies[i]));
var c:* = new C();
c.gotoAndStop(1);
enemyButton[i].enemyID = i;
c.name = "select" + i;
c.enemyID = i;
trace(c.enemyID);
enemyButton[i].addChild(c);
enemyScroll.addChild(enemyButton[i]);
enemyButton[i].enemyName.text = info[i][Const.NAME];
enemyButton[i].setChildIndex(enemyButton[i].getChildByName("enemyName"), enemyButton[i].numChildren-1);
Thanks.
If enemyButton is a MovieClip (created via attachMovie, maybe) and not strongly typed as a EnemyButton class, then the ID property becomes dynamic. In this situation, if your list of names contains incorrect data (missing ID field, maybe), then the ID property will remain undefined on some instances of the MovieClip.
You can check the list of data used to generate movie clips. You can run into the same error if you have blank lines in your data.
This has nothing to do with event listeners.
So you just want to generate a bunch of buttons with unique properties and know what button was clicked last. Generally it is very bad idea to implement button logic outside button object. Why? Because you work with object oriented language. Good news is that you work with as3 and it treats functions as objects, so you can assign function to var like this:
var callback:Function = function(name:String, enemyId:int){ /*do something*/ }
And.. you can pass function as a parameter to another function
function setCalback(func:Function){}
button.setCallback(callback);
So, what you really need is to create your own button class, add listeners inside it, add handlers(static handlers will reduce memory usage) and pass callback function to it, that will be called when user clicks button.
Don't mean to spam this much but this was easily fixed, though the responses might have been a better method.
I just had to change target to the currentTarget, that then allowed clicking anywhere on the "button" to work. Whereas before the target varied from childs added to it.
So, solved.
Thanks for the help.

Change a public var at runtime in as3? (flixel)

I'm trying to create a guessing game that has the user clicking on different colored boxes to see which one is correct. I have a public var that dictates which color(later image) to use. The code is this in my update:
if (FlxG.mouse.justPressed())
{
block2.distributionp = Math.random() * 2;
block2.colorArray = block2.distributionp;
block2.colorUnit = block2.colorArray;
}
(colorUnit and colorArray both equal distributionp, which is a ranom of 2 in the class file)
When I run this code, the change does occur, but it only seems to switch out once. The other times it's ignored. How can I get this to continuously switch out a random number that I can use later?
Thanks in advance!
Math.random() * 2 Returns a Number ranging from 0.000000000000 to 2.00000000, this includes numbers like 0.123456789 and 1.99999999 (Not sure exactly what decimal place it goes to but just saying it doesn't only return integers 0, 1 and 2). I'm not sure but I think you're problem lies in the range, so if you want a better range use this code.
MIN_VALUE * Math.random() + (MAX_VALUE - MIN_VALUE);
If you would like to only get integers you can use either Math.ceil() or Math.floor() like so :
Math.ceil(MIN_VALUE * Math.random() + (MAX_VALUE - MIN_VALUE));
I'm sorry if this does not help you but let me know if it doesn't and I will continue to try and help.
The value I'm getting is whole integers between 0 and 2. What I'm trying to do, is change the vaue for each time I click. I'm not sure what occurs. Perhaps I shouldn't have asked now. I'll ask later when I have more info. Sorry.