I am creating a FlashCS4 Application that is in the style of a quiz. The questions are stored in a seperate text file and are called into the program through as3. This all works fine, however I am wondering how to randomise this data, but to make sure that the same question is not pulled twice.
For example, at the moment when I navigate to the questions page, I can display each part of the question (answer a,b,c,d + the question itself) and then this can be proceeded through 10times.
What I am trying to do is make these 10questions be randomly generated from the (27?) questions that I have in the text file.
import flash.geom.Transform;
import flash.geom.ColorTransform;
import fl.motion.Color;
var glowFilter:GlowFilter = new GlowFilter(0x000000, 1, 2, 2, 10, 3)
var questionNumber:int = 0;
var totalCorrect:int = 0;
var selectedAnswer:String;
var checkAnswer:String;
var correctAnswer:String;
var questionCount:int = 0;
var numberOfQuestions:int = 10;
txt_loggedin_Question.text = (userName);
//Displays the Question Number which is called in from XML
txt_QuestionNumber.text = ("Question #"+questions[questionNumber].ref +" of"+numberOfQuestions);
function CheckAnswer() {
if (selectedAnswer == correctAnswer){
totalCorrect = totalCorrect + 1;
trace("Correct");
}else{
totalCorrect = totalCorrect;
trace("incorrect");
}
questionNumber = questionNumber + 1;
questionCount = questionCount + 1;
//Random questions set up new variable questioncount
if (questionCount == numberOfQuestions){
trace("we are at 10");
gotoAndStop (1, "Result");
//STOP RUN NEXT SCENE
}else{
setUpQuestions()
}
There is a fair bit of code missing, but I am hoping that this covers the essentials, the file is called on a seperate page,
var questions:Array = [ ];
var request:URLRequest = new URLRequest("1.txt");
var loader:URLLoader = new URLLoader(request);
loader.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void
{
// loader data - the questions.txt file
var data:String = event.target.data;
// split data by newline for each question
var lines:Array = data.split("\n");
// for every line
for each (var line:String in lines)
{
// split line by "||" delimiter
var question:Array = line.split("||");
// add the question to the questions array:
questions.push({ref: question[0],
question: question[1],
answerA: question[2],
answerB: question[3],
answerC: question[4],
answerD: question[5],
answerE: question[6],
correct: question[7],
answer: question[8],
type: question[9],
file: question[10]});
}
}
All of this works but the only thing I am struggling with is to randomly generate the questions from within the text file each time that the scene is loaded. Sorry for the long winded question.
Thanks for reading.
Here are the steps you need to do:
Get your list of questions as an array called "orderedQuestions".
Create a second empty array called "shuffledQuestions".
Create while loop:
while(orderedQuestions.length > 0){
shuffledQuestions.push(orderedQuestions.splice(Math.floor(Math.random()*orderedQuestions.length),1));
}
The loop removes one question at random from the sorted list and adds it to the shuffled list. When done your sorted list will be empty and the shuffledQuestions will have all of the questions added in a random order.
Related
Hello and thank you so much for your time.
I'm trying to build a quiz for my students, where the start button will go to a random frame out of 7. Then on the landing frame, question appears and the answer is selected via radiobutton then submitted via another button which goes to the next random question. This needs to happen 5 times so it will pick 5 questions randomly out of 7 and not repeating any previous question. If anyone can point me to right direction, it'll be much appreciated.
//Start Button - AS3 Frame #8157
startBtn.addEventListener(MouseEvent.CLICK, startQuiz);
function startQuiz(event:MouseEvent):void{
}
//Submit Button with score count - AS3 Frame #8158
var count:Number = 0;
var mygroup1:RadioButtonGroup = new RadioButtonGroup("group1");
q1a1.group = q1a2.group = q1a3.group = q1a4.group = q1a5.group = mygroup1;
b1.addEventListener(MouseEvent.CLICK, quizHandler1)
function quizHandler1(event:MouseEvent):void{
if(mygroup1.selection.label=="B) 12") {
count = count + 20;
scoreresult.text = (count).toString();
var number_array:Array = [8158,8159,8160,8161,8162,8163,8164 ];
var final_array:Array = [];
var count_selected:int = 5;
var i:int;
for(i = 0; i < count_selected; i++)
{
if(number_array.length == 0)
break;
else
final_array.push(number_array.splice(Math.floor(Math.random() * number_array.length), 1)[0]);
}
trace(final_array);
}
}
Since you don't want to repeat the same value, you need to know what values you've used already. There's a bunch of ways you could do this, but probably the most straight forward is to put all your values in an array, then remove a random value until the array is empty. Here's an example:
// create an array with all the frames you want to visit
var frames:Array = [0, 1, 2, 3, 4, 5, 6];
// when you want to pick one randomly, remove it using splice
var frame:int = frames.splice(Math.random() * frames.length, 1)[0];
// when the array is empty, you've visited every frame
if(frames.length == 0)
trace("all done!");
Here's the docs on splice(): http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#splice%28%29
I'm a bit new with AS3 (but not really with coding) so please forgive my ignorance. I'm creating a small function that will be called by a Main Function to update the position of 52 Pointers that have the x and y position of multiple point objects (empty movie clips). It will also then update two global arrays with those values (one array for the x and one for the y).
The problem is, as there are 52 of them, and they will probably grow in quantity, I'd like to be able to use a FOR function to do it, but I can't seem to be able to figure it out.
I get this error: Access of undefined property _point.
Here is a piece of the code that dream about:
function happyFunc():void
{
var avpointers:int = 52;
var vpointx:Array = new Array();
var vpointy:Array = new Array();
for (aa=0; aa<vpointers; aa++)
{
vpointx[aa] = _point[aa].x;
vpointy[aa] = _point[aa].y;
}
}
And this is the code that I'm stuck with...
function reallySadFunc():void
{
_point1 = localToGlobal(new Point(point1.x,point1.y));
//...
_point52 = localToGlobal(new Point(point52.x,point1.y));
vpointx[0] = _point1.x;
vpointx[1] = _point2.x;
//...
//oh god there are 104 lines of this why do I have to suffer
}
Thank you!
If I read your question correctly, I think this is what you need:
public static const CLIP_COUNT:int = 52;
// ...
private function happyFunc(parentClip:DisplayObjectContainer):void
{
var vpointx:Vector.<Number> = new Vector.<Number>(CLIP_COUNT, true);
var vpointy:Vector.<Number> = new Vector.<Number>(CLIP_COUNT, true);
var clipPoint:Point = new Point ();
var globalPoint:Point;
for (var i:int = 0; i < CLIP_COUNT; i++)
{
var childClip:DisplayObject = parentClip.getChildByName("point" +
(i + 1).toString());
clipPoint.x = childClip.x;
clipPoint.y = childClip.y;
globalPoint = parentClip.localToGlobal(clipPoint);
vpointx[i] = globalPoint.x;
vpointy[i] = globalPoint.y;
}
// do something with vpointx and vpointy - they're local variables
// and will go out of scope unless you declare them as class members
// or somehow return them from this function.
}
This function works by taking the parent display object (the one that contains the 52 movie clips - this could be the Stage) and iterates through them by getting each movie clip by name. The code assumes that your movie clips are called point1, point2, ..., point52.
To speed up the local-to-global coordinate conversion, two Point objects are created and then reused during the for loop to avoid creating many temporary Point instances.
Instead of using Array, use Vector.<Number> - this class has better performance than Array does.
I'm in need of some help. To start with, what I have is an interaction where you fill out 5 text boxes in response to 2 questions. Each of the 5 answers must be filled out as input text and then checked against an array of acceptable responses when the done button is clicked. Also, there are two type differences in the fields. So the first three answer fields belong to a range of acceptable responses in the array: Type A and the next two questions to Type B. It's possible to fill out the correct responses in any order, so long as the typing is correct.
What I can't seem to figure out is why the textFields aren't translating to Strings.
import flash.text.TextField;
import flash.events.MouseEvent;
stop();
//*--------------------------------------------
//
// THINGS YOU CAN CHANGE
//
//*--------------------------------------------
var a_inputType:Array = new Array("Doggie Day Spa", "Deb's Dog Walking Service", "Pet Market", "Pampered Pet", "TLC Grooming"); //All recognized type responses, Type A listed before Type B
var n_typeA:Number = new Number(3); //Sets the range for Type A
//*--------------------------------------------
//
// PAGE SETUP
//
//*--------------------------------------------
var n_typeB:Number = new Number(a_inputType.length - n_typeA +1); //Finds the range of Type B
var a_testArray:Array = new Array(); //Holds push data from submit button
var a_correctArray:Array = new Array(); //Creates an array to run a final test against
for(var c = 0; c<=a_inputType.length-1; c++){ //Loop populates the array
a_correctArray.push(1);
}
var inputField1:TextField = new TextField(); //Creates the Text Fields
var inputField2:TextField = new TextField();
var inputField3:TextField = new TextField();
var inputField4:TextField = new TextField();
var inputField5:TextField = new TextField();
var txtString1:String = new String(); //Creates the strings for translating the input text
var txtString2:String = new String();
var txtString3:String = new String();
var txtString4:String = new String();
var txtString5:String = new String();
for(var f = 1; f<=a_inputType.length; f++){ //Assigns them properties, locations, and adds a listener for text
var fieldBuilder = "inputField"+f;
var fieldFinder = "txt_pos"+f;
addChild(this[fieldBuilder]);
this[fieldBuilder].border = false;
this[fieldBuilder].width = 290;
this[fieldBuilder].height = 25;
this[fieldBuilder].x = this[fieldFinder].x;
this[fieldBuilder].y = this[fieldFinder].y;
this[fieldBuilder].type = "input";
this[fieldBuilder].multiline = true;
this[fieldBuilder].text = "";
this[fieldBuilder].addEventListener(TextEvent.TEXT_INPUT, function (){
var stringBuilder = "txtString"+f;
this[stringBuilder] = this[fieldBuilder].text;
});
}
//*--------------------------------------------
//
// FUNCTIONS
//
//*--------------------------------------------
function SUBMIT(event:MouseEvent):void{
for(var t=1; t<=a_inputType.length; t++){ //Loop establishes checks for each String against an input type
if(t<=n_typeA){ //if/else divides the textfields into two ranges: typeA and typeB
checkTypeA(this["txtString"+t], a_inputType); //sends the array of correct responses and the captured String to checkTypeA
}else{
checkTypeB(this["txtString"+t], a_inputType); //sends the array of correct responses and the captured String to checkTypeB
}
}
var TEMPSELECT = a_testArray.toString(); //reduces the testArray recieving push data into a String
var TEMPCORRECT = a_correctArray.toString(); //reduces the correctArray from scene set-up into a String
if(TEMPSELECT == TEMPCORRECT){ //compares the strings and determines a trace response
trace("correct");
}else{
trace("incorrect");
}
}
function checkTypeA(value:String, arr:Array){ //Checks the String against all the array values within the specified range for type A
for (var a=1; a<=n_typeA; a++){ //determines the range
if (arr[a]==value){ //checks the value
a_testArray.push(1); //if true, generates a push value for a testArray to be checked later
}
}
}
function checkTypeB(value:String, arr:Array){
for (var b = n_typeA; b<=n_typeB; b++){
if (arr[b-1]==value){
a_testArray.push(1);
}
}
}
//*--------------------------------------------
//
// BUTTONS
//
//*--------------------------------------------
done_bttn.addEventListener(MouseEvent.CLICK, SUBMIT); //Launches the SUBMIT function when "Done" is pressed.
Upon further investigation I've noticed that the loop isn't terminating when it reaches 5. It keeps regurgitating TextFields over and over again with the same variable names and instancing. Because of this, the addChild is dumping input fields one on top of one another in the flash file (which makes editing a text field impossible since your always clicking on a new field positioned directly on top of the one you just edited).
The trace on the loop comes back like this:
inputField1
txt_pos1
inputField2
txt_pos2
inputField3
txt_pos3
inputField4
txt_pos4
inputField5
txt_pos5
inputField1
txt_pos1
inputField2
txt_pos2
inputField3
txt_pos3
inputField4
txt_pos4
inputField5
txt_pos5
inputField1
txt_pos1
inputField2
txt_pos2
and so on.... how can I stop this looping behavior. I've tried if/else breaking and that's not working.
The context of the this keyword changes when you call it from a local function. You can easily verify it if you add trace(this) to your anonymous function. It will trace out [object global]. Two solutions come to mind, store a reference of this in a variable:
var self:MovieClip = this;
for(var f = 1; f<=a_inputType.length; f++){
//...
this[fieldBuilder].addEventListener(TextEvent.TEXT_INPUT, function (){
var stringBuilder = "txtString"+f;
self[stringBuilder] = self[fieldBuilder].text;
});
}
Or declare a new function:
for(var f = 1; f<=a_inputType.length; f++){
//...
this[fieldBuilder].addEventListener(TextEvent.TEXT_INPUT, myFunction);
}
function myFunction(t:TextEvent){
var stringBuilder = "txtString"+f;
this[stringBuilder] = (t.target as TextField).text;
}
I am currently building a project where I have a map with a number of ship and aircraft. What I am trying to achieve is to check the Line of Sight distance between them.
I have set up a LOS Calculator which checks the height of one platform and the height of a second platform then gives a response. That works fine.
I then wanted to addCircle based on the result from this calculator. So if the result was 10 it would draw a circle 10cm in radius. If the result was 100 then it would draw it at 100, you get the picture. This works.
My problem now is that I need to be able to click on one platform either before or after I have made the calculation and the .addCircle be added to that movieClip. I have set up an array to store the movieclips instance names and traced that. I have added a field on stage so that you can click on a platform and it will recognise the platform clicked. I am just lost as to how to get the circle into the movieClip that has been clicked.
I am very new to AS3 so this is starting todo my head in. Any help would be greatly appreciated.
The code I have is attached below. I hope I have inserted this properly. Thanks again
import flash.events.MouseEvent;
import flash.display.MovieClip;
stage.focus=ht1;
// creation of array containing movieclips and code that adds the clicked movieclip to Array-platformClicked
var platformArray:Array = [arunta_mc, f15_mc];
var platformClicked = [];
var selectedPlatform:MovieClip = new MovieClip();
for(var i:int = 0; i < platformArray.length; i++) {
platformArray[i].buttonMode = true;
platformArray[i].addEventListener(MouseEvent.CLICK, item_onClick);
}
function item_onClick(event:MouseEvent):void {
var selectedPlatformArray:Array = platformArray.filter(checkName);
selectedPlatform = selectedPlatformArray[0];
myText.text = event.currentTarget.name + " was clicked";
var platformClicked = String(event.currentTarget.name);
trace(platformClicked);
}
function checkName(item:MovieClip, index:int, array:Array):Boolean
{
return(item.name == platformClicked);
}
//setup of LOS Calculator code
var counter:Number=1;
operator_txt.text = "+";
ht1.restrict="-0123456789.";
ht2.restrict="-0123456789.";
var myresult:Number;
var test = [];
//start of code when equal button is pressed
equal_btn.addEventListener(MouseEvent.CLICK, equalhandler);
var newCircle:Shape = new Shape();//defines circle to be drawn
function equalhandler(event:MouseEvent):void{
newCircle.graphics.lineStyle(1, 0x000000);
newCircle.graphics.beginFill(0x435632);
newCircle.alpha = .1;
//start of result code
result_txt.text = String(int((1.23*(Math.sqrt(Number(parseFloat(ht1.text)+parseFloat(ht2.text)+""))))));
var test = String(int((1.23*(Math.sqrt(Number(parseFloat(ht1.text)+parseFloat(ht2.text)+""))))));
trace(test);
//end of result code
newCircle.graphics.drawCircle(0,0,test);//add circle based on LOS calculation
newCircle.graphics.endFill();
//var selectedPlatform:MovieClip = selectedPlatformArray[0];
selectedPlatform.addChild(newCircle);//this is where I need to add newCircle to the movieClip that is clicked
trace(selectedPlatform);
//trace(platformClicked);
}
//start of code for the clear button
clear_btn.addEventListener(MouseEvent.CLICK, clearhandler);
function clearhandler(event:MouseEvent):void{
ht1.text=ht2.text=result_txt.text="";
removeChild(newCircle);
var test = [];
}
You can use the filter() method to check each item's name, like so:
var selectedPlatformArray:Array = platformArray.filter(checkName);
and somewhere in your code, define the checkName function
function checkName(item:MovieClip, index:int, array:Array):Boolean
{
return (item.name == platformClicked);
}
selectedPlatformArray will now contain all elements that return true for the checkName function, and as long as you don't have multiple MovieClips with the same name the array should only contain one element, which you can retrieve simply by accessing the first element of the array:
var selectedPlatform:MovieClip = selectedPlatformArray[0];
Alternatively, you can also use the getChildByName() function, like so:
var selectedPlatform:MovieClip = stage.getChildByName(platformClicked);
However this depends on where the objects are added to, and if they're not all in the same container (or not added at all), then this isn't the best option. It's a quick and simple solution for small projects though.
Anyway, whatever method you use you can then easily add the circle to it in your equalHandler function as usual:
selectedPlatform.addChild(newCircle);
I'd recommend checking out the documentation for both filter() and getChildByName(), to get a better understanding of how they work, since my examples only showed how you'd use them in this specific situation.
Complete code that you should have:
import flash.events.MouseEvent;
import flash.display.MovieClip;
stage.focus=ht1;
// creation of array containing movieclips and code that adds the clicked movieclip to Array-platformClicked
var platformArray:Array = [arunta_mc, f15_mc];
var platformClicked:String = "";
var selectedPlatform:MovieClip = new MovieClip();
for(var i:int = 0; i < platformArray.length; i++) {
platformArray[i].buttonMode = true;
platformArray[i].addEventListener(MouseEvent.CLICK, item_onClick);
}
function item_onClick(event:MouseEvent):void {
var selectedPlatformArray:Array = platformArray.filter(checkName);
selectedPlatform = selectedPlatformArray[0];
myText.text = event.currentTarget.name + " was clicked";
platformClicked = String(event.currentTarget.name);
trace(platformClicked);
}
function checkName(item:MovieClip, index:int, array:Array):Boolean
{
return(item.name == platformClicked);
}
//setup of LOS Calculator code
var counter:Number=1;
operator_txt.text = "+";
ht1.restrict="-0123456789.";
ht2.restrict="-0123456789.";
var myresult:Number;
var test:String = "";
//start of code when equal button is pressed
equal_btn.addEventListener(MouseEvent.CLICK, equalhandler);
var newCircle:Shape = new Shape();//defines circle to be drawn
function equalhandler(event:MouseEvent):void{
newCircle.graphics.lineStyle(1, 0x000000);
newCircle.graphics.beginFill(0x435632);
newCircle.alpha = .1;
//start of result code
result_txt.text = String(int((1.23*(Math.sqrt(Number(parseFloat(ht1.text)+parseFloat(ht2.text)+""))))));
test = String(int((1.23*(Math.sqrt(Number(parseFloat(ht1.text)+parseFloat(ht2.text)+""))))));
trace(test);
//end of result code
newCircle.graphics.drawCircle(0,0,test);//add circle based on LOS calculation
newCircle.graphics.endFill();
//var selectedPlatform:MovieClip = selectedPlatformArray[0];
selectedPlatform.addChild(newCircle);//this is where I need to add newCircle to the movieClip that is clicked
trace(selectedPlatform);
//trace(platformClicked);
}
//start of code for the clear button
clear_btn.addEventListener(MouseEvent.CLICK, clearhandler);
function clearhandler(event:MouseEvent):void{
ht1.text=ht2.text=result_txt.text="";
selectedPlatform.removeChild(newCircle);
test = "";
}
So, in short, my problem is this. I am using a variable which is a movieclip loaded from an external swf. I want to "spawn" multiple instances of the movieclip that all react to the same code, so for example if I say var1.x = 100, they all are at 100x. But my problem is when I run addChild(var1) multiple times(I'm not actually typing in addChild(var1) over and over, I just have it set to add them at random times), the new child just replaces the old one, instead of making multiple movieclips. Should I do something like
var var1:MovieClip
var var2:MovieClip = new var1 ?(which doesnt work for me btw, gives me errors)
Oh, heres the code, and also, I am pretty new to as3 fyi, still don't even know how arrays work, which was my second guess to the problem.
var zombieExt:MovieClip;
var ldr2:Loader = new Loader();
ldr2.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoaded2);
ldr2.load(new URLRequest("ZombieSource.swf"));
function swfLoaded2(event:Event):void
{
zombieExt = MovieClip(ldr2.contentLoaderInfo.content);
ldr2.contentLoaderInfo.removeEventListener(Event.COMPLETE, swfLoaded2);
//zombieExt.addEventListener(Event.ENTER_FRAME, moveZombie)
zombieExt.addEventListener(Event.ENTER_FRAME,rotate2);
function rotate2 (event:Event)
{
var the2X:int = playerExt.x - zombieExt.x;
var the2Y:int = (playerExt.y - zombieExt.y) * 1;
var angle = Math.atan(the2Y/the2X)/(Math.PI/180);
if (the2X<0) {
angle += 180;
}
if (the2X>=0 && the2Y<0) {
angle += 360;
}
//angletext.text = angle;
zombieExt.rotation = (angle*1) + 90;
}
playerExt.addEventListener(Event.ENTER_FRAME,spawn1);
function spawn1 (event:Event)
{
if(playerExt.y < 417)
{
var someNum:Number = Math.round(Math.random()*20);
if(someNum == 20)
{
addChild(zombieExt)
zombieExt.x = Math.round(Math.random()*100)
zombieExt.y = Math.round(Math.random()*100)
}
}
}
}
addChild() does not create new instances. It is used to add an already created instance to the display list. If you call addChild() multiple times on the same instance then you are just readding itself.
Also each instance is unique, you can not globally change the x position of an instance by changing another one of them. What you would do is as Henry suggests and add each new instance of a MovieClip into an array, then whenever you change something you can loop through the array and apply the changes to each instance.
You can not go var2:MovieClip = new var1 either since var1 is an instance and not a class.
Here's a different method of receiving loaded MovieClips, which i use when i need many copies of the item.
in the swf you are loading, give the target movieclip a linkage name in the library, for this example i will use "foo"
private var loadedSwfClass:Class
private var newZombie:MovieClip;
private var zombieArray:Array = new Array();
function swfLoaded2(event:Event):void
{
loadedSwfClass = event.target.applicationDomain.getDefinition("foo");
for(var n:int = 0; n<100; n++){
newZombie = new loadedSwfClass()
zombieArray.push(newZombie);
addChild(newZombie);
}
}
as per this tutorial
http://darylteo.com/blog/2007/11/16/abstracting-assets-from-actionscript-in-as30-asset-libraries/
although the comments say that
var dClip:MovieClip = this;
var new_mc = new dClip.constructor();
this.addChild(new_mc);
will also work.
It sounds like you might be accessing the same instance some how in your code. It would be helpful to see your code to figure this one out.
If I wanted to load in one swf files and add a MovieClip multiple times I would place it in the library of that SWF file. And then instantiate it and store it into an object pool or a hash or some list.
// after the library were finished loading
var list:Array = [];
for(var i:int=0; i<10; i++) {
var myCreation:MySpecialThing = new MySpecialThing();
addChild(myCreation);
list.push(myCreation);
}
where my library would contain a linkage to the class MySpecialThing.
Calling addChild(var1) multiple times on the same parent doesn't have any effect (unless you have added another child to the same parent in between, in which case it will change the child index and bring var1 to the top). If you call it on different parents, it will just change the parent of var1, doesn't duplicate. Call addChild(new MovieClassName()) at random times instead to add new copies of it. Use an array as suggested here to access them later.
Wow, thanks there henry, just using an array did exactly what I needed, and made things alot simpler.
when you load in using a loader you only get 1 instance, however you can do some funky reflection to determine what class type the given loader.content is, and then instantiate them using that. For Example:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_completeHandler);
loader.load(new URLRequest("ZombieSource.swf"));
var classType:Class;
function loader_completeHandler(evt:Event):void
{
var loadInfo:LoaderInfo = (evt.target as LoaderInfo);
var loadedInstance:DisplayObject = loadInfo.content;
// getQualifiedClassName() is a top-level function, like trace()
var nameStr:String = getQualifiedClassName(loadedInstance);
if( loadInfo.applicationDomain.hasDefinition(nameStr) )
{
classType = loadInfo.applicationDomain.getDefinition(nameStr) as Class;
init();
}
else
{
//could not extract the class
}
}
function init():void
{
// to make a new instance of the ZombieMovie object, you create it
// directly from the classType variable
var i:int = 0;
while(i < 10)
{
var newZombie:DisplayObject = new classType();
// your code here
newZombie.x = stage.stageWidth * Math.random();
newZombie.x = stage.stageHeight * Math.random();
i++;
}
}
Any problems let me know, hope this helps.