This page will give a detailed explanation of the code for the Cereal Box Problem applet shown on the previous page. See the download section at the bottom of this page to get the source file that includes the stage setup from Page 1 as well as the code below already in place.
We begin by importing the classes for ActionScript tweening and defining variables for the total number of prizes (numbered 1 through numPrizes) and an array to hold the prizes (by number) already won so we know when we've collected them all.
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.*;
var numPrizes:Number = 5;
var arrPrizes:Array = new Array();
Next we need arrays to hold the cerealbox instances and the textboxes at the bottom of the screen to show which prizes have been won so far. We also need a variable to keep track of which box we're on and hence how many have been generated, and we define green and red textformats so we can visually denote which prizes have been won so far. We create a generic object to be tweened, and we will tie the motion of the cerealbox instances to this tween. If you missed it, you can read about this trick in the tutorial, Tween Tricks in ActionScript 3 and Flash CS3, in the Intermediate section of our website.
var arrBoxes:Array = new Array();
var txtBoxes:Array = new Array();
var index:Number = 0;
var tfGreenLetters:TextFormat = new TextFormat("Arial",36,0x00AA00);
var tfRedLetters:TextFormat = new TextFormat("Arial",36,0xCC0000);
var twObj:Object = {t:0};
The cash register button generates a new cerealbox, gives it a random prize, puts the random prize to the list of prizes won so far, and changes the textbox with that prize number to green. The newBox function manages all of this.
btnRegister.addEventListener(MouseEvent.CLICK, newBox);
function newBox(me:MouseEvent):void {
var thisPrize:Number = Math.ceil(numPrizes*Math.random());
arrBoxes[index] = new CerealBox();
arrBoxes[index].txtPrize.mouseEnabled = false;
arrBoxes[index].txtPrize.text = String(thisPrize);
// The cereal box starts off scaled to 0% and positioned at the corner of the cash register button.
arrBoxes[index].x = btnRegister.x;
arrBoxes[index].y = btnRegister.y;
arrBoxes[index].scaleX = 0.0;
arrBoxes[index].scaleY = 0.0;
addChildAt(arrBoxes[index],0);
// Place thisPrize in the arrPrizes array and highlight its textbox if its not already in the array.
if (arrPrizes.indexOf(thisPrize) < 0) {
arrPrizes.push(thisPrize);
txtBoxes[thisPrize-1].setTextFormat(tfRedLetters);
txtBoxes[thisPrize-1].border = true;
txtBoxes[thisPrize-1].borderColor = 0xFF0000;
}
/*
This tween moves the cereal box from its original location to its final destination according to the doMotion function. We don't allow the cash register button to be pressed again until the tween has finished.
*/
var tw:Tween = new Tween(twObj,"t",None.easeIn,0,1,1,true);
tw.addEventListener(TweenEvent.MOTION_CHANGE, doMotion);
tw.addEventListener(TweenEvent.MOTION_FINISH, doneMotion);
}
The following function gives the appropriate messages if the game needs to be reset. Otherwise it simply updates the number of cerealboxes bought and restores the ability of the cash register button to receive a mouse click.
function doneMotion(evt:Event):void {
index++;
if (allCollected()) {
txtFinalMessage.text = "You did it!! You only had to buy " + String(index) + " boxes in order to collect all " + String(numPrizes) + " prizes!";
btnRegister.visible = false;
btnReset.visible = true;
return;
}
if (index > 9) {
txtFinalMessage.text = "You're wasting money! You have bought " + String(index) + "
boxes and still have not collected all " + String(numPrizes) + " prizes!";
btnRegister.visible = false;
btnReset.visible = true;
return;
}
btnRegister.addEventListener(MouseEvent.CLICK, newBox);
}
While the twObj tween is running we move the cerealbox object, scale it up to 100%, and change its alpha value gradually to 100%. Feel free to add spin or color/filter effects as well!
function doMotion(evt:Event):void {
btnRegister.removeEventListener(MouseEvent.CLICK, newBox);
arrBoxes[index].x = btnRegister.x + twObj.t*(70 + 100*(index%5) - btnRegister.x);
arrBoxes[index].y = btnRegister.y + twObj.t*(110 + 120*Math.floor(index/5) -
btnRegister.y);
arrBoxes[index].scaleX = twObj.t*0.5;
arrBoxes[index].scaleY = twObj.t*0.5;
arrBoxes[index].alpha = twObj.t;
}
The following helper function checks if arrPrizes has all of the prizes in it.
function allCollected():Boolean {
if (arrPrizes.length == numPrizes) {
return true;
}
else {
return false;
}
}
The setup function clears everything.
btnReset.addEventListener(MouseEvent.CLICK, resetAll);
function resetAll(mevt:MouseEvent):void {
setup();
}
function setup():void {
for (var i=0; i<numPrizes; i++) {
txtBoxes[i].border = false;
txtBoxes[i].setTextFormat(tfGreenLetters);
}
for (i=0; i<index; i++) {
removeChild(arrBoxes[i]);
}
arrPrizes = [ ];
index = 0;
btnRegister.visible = true;
btnReset.visible = false;
btnRegister.addEventListener(MouseEvent.CLICK, newBox);
txtFinalMessage.text = "";
}
The following function creates the textboxes at runtime so that a change to numPrizes variable will update the applet entirely.
function firstSetup():void {
for (var i=0; i<numPrizes; i++) {
txtBoxes[i] = new TextField();
txtBoxes[i].autoSize = TextFieldAutoSize.LEFT;
txtBoxes[i].mouseEnabled = false;
txtBoxes[i].text = String(i+1);
txtBoxes[i].x = 60 + 50*i;
txtBoxes[i].y = 400;
txtBoxes[i].setTextFormat(tfGreenLetters);
addChild(txtBoxes[i]);
}
txtFinalMessage.text = "";
btnRegister.visible = true;
btnReset.visible = false;
}
firstSetup();
Download
You can download the file CerealBoxProblem.fla with the entire script above already in place.










