PDA

View Full Version : Problem with scoring system



john84
October 20th, 2009, 03:55 PM
I've made a simple application to help teach children how to measure using a centimetre scale. Random sized and random coloured boxes are generated, the child then drags a rule to measure the box and enters the number in a text box. A check button is clicked to check the answer. If correct the score goes up by 1.
My problem is that if a box size is repeated, the score goes up by 2. For example, a box comes up 2cm wide. I enter 2cm and score 1 point. Several boxes later a 2cm box appears. I put 2cm and score 2 points! Next time I score 3 points.
Obviously I should only score 1 point each time.
The relevant code is:


//create a box to be measured
btnAnother.addEventListener(MouseEvent.CLICK, anotherBox);
function anotherBox(evt:MouseEvent):void {
setUpBox();
inputBox.text = "";
feedback.text = "";
//display number of questions asked
total++;
questionsAsked_mc.scoreDisplay.text = String(total);
//hide button creating the box and reveal the button used to check the answer
goButton.visible = true;
btnAnother.visible = false;
//return rule to original position
rule_mc.x = 130;
rule_mc.y = 175;
}
//function to create the box - random dimensions and colour
function setUpBox():void {
var r:Number = Math.random();
var myColor:Number = Math.round( Math.random()*0xffffff );
var p:Number = int(Math.ceil(15*r));
graphics.clear();
graphics.beginFill( myColor, 1 );
graphics.drawRect( 200, 50, p*15, 20 + p*5 );
graphics.endFill();
//Checking the answer
goButton.addEventListener(MouseEvent.MOUSE_DOWN, goClicked);
function goClicked (evt:MouseEvent):void {
checkAnswer();
}
function checkAnswer():void {
goButton.visible = false;
btnAnother.visible = true;
var q:Number = int(inputBox.text);
if ( p == q) {
totalScore++;
score_mc.scoreDisplay.text = String(totalScore);
feedback.text = "Correct! the answer is " + p + " centimetres";
}
else {
feedback.text = "No, the answer is " + p + " centimetres";
}
}
}
setUpBox();

Hope that makes sense to someone - I'd appreciate any help!

micken
October 20th, 2009, 05:02 PM
That depends on the output you're getting. Is your score going up by two, or are you getting "Correct! the answer is p centimetres" twice ? the only way you'd get two points at once is if you managed to call checkAnswer twice for one click OR something somewhere else in your code is affecting the value of totalScore.

It might also be occuring because in setupBox() you are adding an event listener to your goButton. So each time you press "another box" you are adding an event listener for MOUSE_DOWN to goButton. I'm not sure how this would affect it but you only need to do this once.

A good strategy for debugging this kind of behaviour is watching your totalPoints variable closely (in every part of your code that affects it, trace it's value right after so you can pinpoint where the extra point is coming from)

john84
October 20th, 2009, 05:56 PM
Thanks for your help - I'll try your idea on tracing.

"Correct! the answer is p centimetres" only comes up once, but as I say the score goes up by 2 if that answer has already been used earlier. If the same size box appears again the score would go up by 3, though again just the one "Correct! the answer is p centimetres" .

IQAndreas
October 20th, 2009, 06:10 PM
There is obviously more code that you did not include, and the problem might be there.

Just one guess is that somewhere you have written:
currentScore += totalScore;
But I can't be sure without knowing your entire setup.

You might be able to fix it yourself, though. Use find and replace to find everywhere that references to "totalScore". Then, right after it "trace(totalScore)". That way, every time you change total score you trace out the new value, and if it doesn't increase by 1,2,3,4,5, it means that it is being changed somewhere you forgot about.

If you still can't find it, upload the FLA and it will be easier for us to debug.

john84
October 21st, 2009, 03:33 AM
I've tried the suggestions, but still puzzled by this. Here's the full script


inputBox.text = "";
feedback.text = "";
inputBox.restrict = "0-9";
stage.focus = inputBox;
goButton.visible = true;
btnAnother.visible = false;
rule_mc.x = 130;
rule_mc.y = 175;
var total:uint;
total = 1;
questionsAsked_mc.scoreDisplay.text = total;
var totalScore:uint;
totalScore = 0;
score_mc.scoreDisplay.text = totalScore;
//Drag ruler:
rule_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
rule_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
rule_mc.buttonMode = true;
function pickUp(event:MouseEvent):void {
event.target.startDrag();
}
function dropIt(event:MouseEvent):void {
event.target.stopDrag();
}


btnAnother.addEventListener(MouseEvent.CLICK, anotherBox);
function anotherBox(evt:MouseEvent):void {
setUpBox();
inputBox.text = "";
feedback.text = "";
total++;
questionsAsked_mc.scoreDisplay.text = String(total);
goButton.visible = true;
btnAnother.visible = false;
rule_mc.x = 130;
rule_mc.y = 175;
}
function setUpBox():void {
var r:Number = Math.random();
var myColor:Number = Math.round( Math.random()*0xffffff );
var p:Number = int(Math.ceil(15*r));
graphics.clear();
graphics.beginFill( myColor, 1 );
graphics.drawRect( 200, 50, p*15, 20 + p*5 );
graphics.endFill();
//Checking the answer
goButton.addEventListener(MouseEvent.MOUSE_DOWN, goClicked);
function goClicked (evt:MouseEvent):void {
checkAnswer();
}
function checkAnswer():void {
goButton.visible = false;
btnAnother.visible = true;
var q:Number = int(inputBox.text);
if ( q == p) {
feedback.text = "Correct! the answer is " + p + " centimetres";
totalScore++;
score_mc.scoreDisplay.text = String(totalScore);
trace(totalScore) ;
}
else {
feedback.text = "No, the answer is " + p + " centimetres";
}
}
}
setUpBox();


The fla is slightly too big to upload, but I'll try cutting it down later.

Any further ideas would be appreciated!!

IQAndreas
October 21st, 2009, 08:15 AM
Found it (I think). :) You have a line of code which add an event listener for when the checkAnswer button is clicked:

//Checking the answer
goButton.addEventListener(MouseEvent.MOUSE_DOWN, goClicked);
function goClicked (evt:MouseEvent):void {
checkAnswer();
}
The problem is that you add an event listener every single time you create a new box, which means that the first time you click the goButton, it will run goClicked once. Then, when you create a new box, you run the addEventListener function AGAIN, so when you click goButton a second time, this time it runs goClicked twice.

Test to see if this works better. I also indented more, added whitespace, and renamed some variables to be more readable:


inputBox.text = "";
feedback.text = "";
inputBox.restrict = "0-9";
stage.focus = inputBox;
goButton.visible = true;
btnAnother.visible = false;

rule_mc.x = 130;
rule_mc.y = 175;

var total:uint;
total = 1;
questionsAsked_mc.scoreDisplay.text = total;
var totalScore:uint;
totalScore = 0;
score_mc.scoreDisplay.text = totalScore;

//Drag ruler:
rule_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
rule_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
rule_mc.buttonMode = true;
function pickUp(event:MouseEvent):void {
event.target.startDrag();
}
function dropIt(event:MouseEvent):void {
event.target.stopDrag();
}


btnAnother.addEventListener(MouseEvent.CLICK, anotherBox);
function anotherBox(evt:MouseEvent):void {

setUpBox();

inputBox.text = "";
feedback.text = "";
total++;
questionsAsked_mc.scoreDisplay.text = String(total);

goButton.visible = true;
btnAnother.visible = false;

rule_mc.x = 130;
rule_mc.y = 175;
}


//Save the value for the correct answer outside of the "setupBox" function
//to it can be accessed and used outside of it.
var correctAnswer:Number;


function setUpBox():void {

var r:Number = Math.random();
var boxColor:uint = Math.round( Math.random()*0xffffff );
correctAnswer = int(Math.ceil(15*r));

graphics.clear();
graphics.beginFill( boxColor, 1 );
graphics.drawRect( 200, 50, correctAnswer*15, 20 + correctAnswer*5 );
graphics.endFill();

}

//Checking the answer
goButton.addEventListener(MouseEvent.MOUSE_DOWN, goClicked);
function goClicked (evt:MouseEvent):void {
checkAnswer();
}

function checkAnswer():void {
goButton.visible = false;
btnAnother.visible = true;

var userAnswer:Number = int(inputBox.text);

if ( userAnswer == correctAnswer ) {
feedback.text = "Correct! the answer is " + correctAnswer + " centimetres";
totalScore++;
score_mc.scoreDisplay.text = String(totalScore);
trace(totalScore) ;
}
else {
feedback.text = "No, the answer is " + correctAnswer + " centimetres";
}
}


setUpBox();

john84
October 21st, 2009, 01:44 PM
Thanks for your help - that makes a lot of sense! I'll try it now and post again to say if it works.
Thanks again

john84
October 21st, 2009, 01:54 PM
Fantastic!!
You've made my day IqAndreas - it works perfectly.
Thanks again