The new forums will be named Coin Return (based on the most recent vote)! You can check on the status and timeline of the transition to the new forums here.
The Guiding Principles and New Rules document is now in effect.
If the person I'm asking the question gets it right, I click right and it moves to a totally new topic. If they get it wrong, I want to click wrong and have it generate a new question from the category at hand. Rather than nesting a few hundred slides into each other (which would make a bit of an angry presentation), how else can I do this?
I'm trying with Powerpoint because that is one piece of software available to me and while I'm a bit of a techy, I don't have much coding experience and can't build this from scratch by myself. If existing code exists for something similar, I can probably figure out how to modify it to meet my needs.
The reason I want to use an external source file for the questions is because I'm going to be changing this content on a regular basis. Changing a single text file is a lot easier than changing 100+ fucking slides (I hate these slides already).
Any ideas?
Update: Also currently downloading Flash.
Skoal Cat on
0
Posts
L Ron HowardThe duckMinnesotaRegistered Userregular
Which version of Powerpoint are we talking about here?
Do you know any VB?
The one at work is 2008 Mac which apparently doesn't like macros. I don't know any VB but I did find http://www.pptfaq.com/FAQ00570.htm
Which is telling me what to do if I had a version that would run macros. I might be able to find a different copy at work, we have a couple of Window machines and god knows what they run. I'm also downloading a trial of Adobe Flash Professional to see if I can't get something running there. This doesn't need to be pretty, just functional.
Flash would actually be perfect for what you're trying to do.
0
L Ron HowardThe duckMinnesotaRegistered Userregular
The Powerpoint I'm looking at, 2003 for Win, lets you use macros, which is what I would use.
But, I think Bio's right. Use Flash, that would be a whole lot better.
How do I set this up in Flash? Is each frame made in a new scene? Do I make a button under the text to click? How do I get the text to change within a frame/scene?
How do I set this up in Flash? Is each frame made in a new scene? Do I make a button under the text to click? How do I get the text to change within a frame/scene?
Google a bit of actionscript on dynamic text and arrays, you won't need to learn much for this.
You don't need multiple frames, you'll just change the text property of a dynamic TextField when the user clicks a button.
Arrange your questions in Arrays separated by category. A wrong answer pulls the next question out of the current category's array, a right answer pulls the first question out of the next category array; if I understand your goal.
I think I can do this. As long as I know the terms to learn I should be able to get this going.
Thanks for the help.
(not solved, just waiting for the next problem to come up)
Everything was working out great until everything stopped working!
Here is the code I'm using to pull text from an external .txt
var loader:URLLoader = new URLLoader(new URLRequest("science.txt"));
loader.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void
{
var loadedText:URLLoader = URLLoader(event.target);
question_box.htmlText = loadedText.data;
}
It works great, but it loads the entire .txt when I need it to load one line at a time. A friend of mine suggested
function completeHandler (evnt:Event):void
{
var textLoader:URLLoader = URLLoader(event.target);
var text:String = loadedText.data;
var delimiter:String = ","; //Whatever delimiter you want to use--in this case, the comma.
var lineList:Array = text.split(delimiter); //An array containing each line you want to use.
//Loops through each element in the array and traces it, tracing out each line, one at a time.
for (var lineNum:int = 0 ; lineNum < lineList.length ; lineNum++)
{
trace("line " + lineNum + ": " + lineList[lineNum]);
}
}
But when I copy paste that below my existing code, I get an error and the .txt never loads. I'm sure I'm not implementing it right. I did however wind up getting the right effect with
stop();
//Loads external .txt, splits at the "," and loads a randomly selected question into the scene
var myLoader:URLLoader = new URLLoader();
myLoader.load(new URLRequest("science.txt"));
myLoader.addEventListener(Event.COMPLETE, scienceLoaded);
var scienceArray:Array = new Array();
var scienceContent:String
var scienceSplit:String;
function scienceLoaded(event:Event):void {
scienceContent = event.target.data;
scienceArray = scienceContent.split("\r\n");
scienceSplit = scienceArray[Math.floor(Math.random() * scienceArray.length)];
scienceSplit = scienceSplit.split(",").join("\r\r");
question.text= scienceSplit;
}
//advances to a different scene
button_12.addEventListener(MouseEvent.CLICK, fl_ClickToGoToScene_16);
function fl_ClickToGoToScene_16(event:MouseEvent):void
{
MovieClip(this.root).gotoAndStop(1, "Scene 7");
}
//Generates a new question within the scene
button_154.addEventListener(MouseEvent.CLICK, fl_ClickToGoToScene_168);
function fl_ClickToGoToScene_168(event:MouseEvent):void
{
scienceSplit = scienceArray[Math.floor(Math.random() * scienceArray.length)];
scienceSplit = scienceSplit.split(",").join("\r\r");
question.text= scienceSplit;
}
And that totally works, except when I add it to more than one scene. Then the entire program freaks the fuck out.
I am at a complete loss as to how to proceed here.
Help me please...
I've wound up with much simpler code since that post. Its still not working, but things seem to be closer to elegant here. I am now working with an XML.
var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML = new XML();
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
xmlLoader.load(new URLRequest("file.xml"));
function LoadXML(e:Event):void
{
xmlData = new XML(e.target.data);
trace(xmlData.quiz.question.text());
}
This gives me the output of
"blah blah blah""bloo bloo bloo"
Hurrah, its loading the text! Now to randomly select lines and only display that one!
I've cobbled together from what I've found online the following which is supposed to give me a random line from the XML file
function completeHandler (event:Event):void
{
var textLoader:URLLoader = URLLoader(event.target);
var text:String = xmlLoader.data;
var xml:XML = new XML(text);
//Loops through each element in the xml and traces it, tracing out each line, one at a time.
for (var lineNum:int = 0 ; lineNum < xml.quiz.question.length() ; lineNum++)
{
trace("Question " + lineNum + ": " + xml.quiz.question[lineNum]);
}
}
This still gives me the output of
"blah blah blah""bloo bloo bloo"
rather than randomly selecting and displaying only one as
Question: "blah blah blah"
I'm also using scenes because this is part of a branching story where the choices have permanent affects later in the game. For example, burning a bridge removes all choices to cross the bridge in the future. There is probably a better way to do this than the absurd number of scenes I have, but hey, that's how my beginner brain organized things..
It looks like you're only tracing "trace(xmlData.quiz.question.text());" from LoadXML*, not what's in completeHandler. Are you actually calling that function?
var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML;
xmlLoader.addEventListener(Event.COMPLETE, loadXML);
xmlLoader.load(new URLRequest("file.xml"));
function loadXML(e:Event):void {
xmlData = new XML(e.target.data);
trace("What you're seeing:" xmlData.quiz.question.text());
for (var lineNum:int = 0 ; lineNum < xmlData.quiz.question.length() ; lineNum++)
{
trace("What you want to see:");
trace("Question " + lineNum + ": " + xmlData.quiz.question[lineNum]);
}
}
*This is a poor practice. Classes have initial capital letters. Methods and properties start with a lowercase letter.
So you're making a Choose Your Own Adventure type thing, rather than a quiz?
You might set your XML up differently. For example: as 'chapters' rather than questions, each with a proper ID, and have your responses determine which chapterID to load next, rather than the next one in the list.
<chapter id="0001">
<text>It is pitch dark. You are likely to be eaten by a Grue</text>
<option link="0002">Burn the bridge</option>
<option link="0003">Put the kettle on for Grue-stew</option>
<option link="0004">Give sandwich to the dog</option>
</chapter>
Its a combination of the two, really.
Since the scene structure is already working (minus random question code), I'm not going to worry about changing it unless I've done something horribly wrong and wrote myself into a corner.
Thanks for the help so far!
This does bring me to a new problem... how do I make a button that on mouse click refreshes the dynamic text field and loads a new line from the XML? Do the refresh button and the dynamic text box need to exist on different layers?
Nor do scenes matter in that sense either, correct? So I would use the same button and text box in each scene rather than creating new ones in each scene?
If they both exist in the scene with the same names, the code will still work.
You will have to keep adding that eventlistener in each Scene though. You do not want to mess with scenes. There is a reason that the Scene panel is buried under Window > Other Panels... > Scenes
and it isn't because they're so fun and great they didn't want them to overshadow the windows.
[edit] Ignore the myButton:Sprite, etc bit. I'm just just referring to whatever you are using for a button, and whatever you are using for a text field.
Sibling refers to... they are both inside the same container, ie: both sitting on the main timeline or inside the same symbol, and you put that code on the main timeline or inside that symbol, or in the class that represents them
Note: "MOUSE_CLICK" should be "MouseEvent.CLICK" brain-fart.
[edit2: I guess I should toss out an @Skoal Cat if I'm going to keep revising this.]
//Output random line to dyanmic text field named myText
function completeHandler (event:Event):void
{
var textLoader:URLLoader = URLLoader(event.target);
var text:String = xmlLoader.data;
var xml:XML = new XML(text);
var randomQuestion:int = Math.random()*xml.quiz.question.length();
trace("Question: " + xml.quiz.question[randomQuestion]);
myText.text=("Question: " + xml.quiz.question[randomQuestion]);
}
//New question on mouse click
myButton.addEventListener(MouseEvent.CLICK, clickHdlr);
function clickHdlr(event:MouseEvent):void
{
var textLoader:URLLoader = URLLoader(event.target);
var text:String = xmlLoader.data;
var xml:XML = new XML(text);
var randomQuestion:int = Math.random()*xml.quiz.question.length();
myText.text=("Question: " + xml.quiz.question[randomQuestion]);
}
When I click the button for a new question, I get
TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::SimpleButton@249ebf31 to flash.net.URLLoader.
at Real_fla::MainTimeline/clickHdlr()
in my output and a new question does not load. Is this because I'm reusing variables defined in the previous function? I tried it without the variables, since they were already defined, and then nothing shows up and I get
Access of unidentified property xml (and) randomQuestion
edit: If I decide to forego scenes, how should I set up what I now have as scenes? In different frames on the time line?
So if I'm understanding frames right, I would have... one page of code? Tons of buttons, don't get me wrong here, but one page of code?
That would be amaaaazing
:rotate:
Yes, but you don't have to have tons of buttons, either. You can write this so that the same buttons, on the same keyframe, will just do different things when you want them too.
See comments in code:
//Output random line to dyanmic text field named myText
function completeHandler (event:Event):void
{
var textLoader:URLLoader = URLLoader(event.target); //Do you even use this? I only see a reference to xmlLoader.
var text:String = xmlLoader.data; //You don't need this step if you're loading an actual XML file.
var xml:XML = new XML(text); //Declare this outside the function, or the 'xml' variable will be destroyed when the function complete.
var randomQuestion:int = Math.random()*xml.quiz.question.length();
trace("Question: " + xml.quiz.question[randomQuestion]);
myText.text=("Question: " + xml.quiz.question[randomQuestion]);
}
Revise to:
//Variable declarations that we will need to access later, so we declare them outside a function
var xml:XML;
var randomQuestion:int;
//Output random line to dyanmic text field named myText
function completeHandler (event:Event):void
{
xml = new XML(xmlLoader.data); //Note that we are not declaring them anymore, we're just assigning a value to them
randomQuestion = Math.random()*xml.quiz.question.length(); //Note that we are not declaring them anymore, we're just assigning a value to them
trace("Question: " + xml.quiz.question[randomQuestion]);
myText.text=("Question: " + xml.quiz.question[randomQuestion]);
}
//New question on mouse click
myButton.addEventListener(MouseEvent.CLICK, clickHdlr);
function clickHdlr(event:MouseEvent):void
{
var textLoader:URLLoader = URLLoader(event.target);
//Ok, 'event.target' is myButton, which is a SimpleButton. You're trying to assign that to a URLLoader. It's a square peg/round hole situation. This is what Error 1034 is.
//But you shouldn't be doing any of this here. Delete that line
var text:String = xmlLoader.data; // And delete this
var xml:XML = new XML(text); //And delete this
var randomQuestion:int = Math.random()*xml.quiz.question.length(); //Pulls a random Question index, good, but now we've already declared this variable.
myText.text=("Question: " + xml.quiz.question[randomQuestion]); //Sets the text. Keep
}
revise to
//New question on mouse click
myButton.addEventListener(MouseEvent.CLICK, clickHdlr);
function clickHdlr(event:MouseEvent):void
{
randomQuestion = Math.random()*xml.quiz.question.length();
myText.text=("Question: " + xml.quiz.question[randomQuestion]);
}
TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::SimpleButton@249ebf31 to flash.net.URLLoader.
at Real_fla::MainTimeline/clickHdlr()
in my output and a new question does not load. Is this because I'm reusing variables defined in the previous function? I tried it without the variables, since they were already defined, and then nothing shows up and I get
Access of unidentified property xml (and) randomQuestion
If you declare a variable in a function, it does not exist outside of that function. See notes on first function, where we define these outside of it so that BOTH functions may access them.
Posts
Do you know any VB?
http://www.pptfaq.com/FAQ00570.htm
Which is telling me what to do if I had a version that would run macros. I might be able to find a different copy at work, we have a couple of Window machines and god knows what they run. I'm also downloading a trial of Adobe Flash Professional to see if I can't get something running there. This doesn't need to be pretty, just functional.
But, I think Bio's right. Use Flash, that would be a whole lot better.
Google a bit of actionscript on dynamic text and arrays, you won't need to learn much for this.
You don't need multiple frames, you'll just change the text property of a dynamic TextField when the user clicks a button.
Arrange your questions in Arrays separated by category. A wrong answer pulls the next question out of the current category's array, a right answer pulls the first question out of the next category array; if I understand your goal.
Savvy? Kinda?
Thanks for the help.
(not solved, just waiting for the next problem to come up)
Here is the code I'm using to pull text from an external .txt It works great, but it loads the entire .txt when I need it to load one line at a time. A friend of mine suggested
But when I copy paste that below my existing code, I get an error and the .txt never loads. I'm sure I'm not implementing it right. I did however wind up getting the right effect with
And that totally works, except when I add it to more than one scene. Then the entire program freaks the fuck out.
I am at a complete loss as to how to proceed here.
Help me please...
And explain the function of the scenes, or why you feel they are needed.
I ask this because you said "It breaks when I use scenes," and my first solution would be to stop using scenes.
Here is my XML
Here is the code that successfully loads the XML This gives me the output of Hurrah, its loading the text! Now to randomly select lines and only display that one!
I've cobbled together from what I've found online the following which is supposed to give me a random line from the XML file This still gives me the output of rather than randomly selecting and displaying only one as
I'm also using scenes because this is part of a branching story where the choices have permanent affects later in the game. For example, burning a bridge removes all choices to cross the bridge in the future. There is probably a better way to do this than the absurd number of scenes I have, but hey, that's how my beginner brain organized things..
It looks like you're only tracing "trace(xmlData.quiz.question.text());" from LoadXML*, not what's in completeHandler. Are you actually calling that function?
*This is a poor practice. Classes have initial capital letters. Methods and properties start with a lowercase letter.
So you're making a Choose Your Own Adventure type thing, rather than a quiz?
You might set your XML up differently. For example: as 'chapters' rather than questions, each with a proper ID, and have your responses determine which chapterID to load next, rather than the next one in the list.
Since the scene structure is already working (minus random question code), I'm not going to worry about changing it unless I've done something horribly wrong and wrote myself into a corner.
Thanks for the help so far!
This does bring me to a new problem... how do I make a button that on mouse click refreshes the dynamic text field and loads a new line from the XML? Do the refresh button and the dynamic text box need to exist on different layers?
myButton:Sprite
myText:TextField
are siblings, and this code is on their parent:
myButton.addEventListener(MOUSE_CLICK, clickHdlr);
function clickHdlr(e:MouseEvent):void{
myText.text = "blah"
}
Then that's all you have to do.
Layers don't matter in terms of referencing objects by name.
I am a goose and don't understand what this means.
You will have to keep adding that eventlistener in each Scene though. You do not want to mess with scenes. There is a reason that the Scene panel is buried under Window > Other Panels... > Scenes
and it isn't because they're so fun and great they didn't want them to overshadow the windows.
[edit] Ignore the myButton:Sprite, etc bit. I'm just just referring to whatever you are using for a button, and whatever you are using for a text field.
Sibling refers to... they are both inside the same container, ie: both sitting on the main timeline or inside the same symbol, and you put that code on the main timeline or inside that symbol, or in the class that represents them
Note: "MOUSE_CLICK" should be "MouseEvent.CLICK" brain-fart.
[edit2: I guess I should toss out an @Skoal Cat if I'm going to keep revising this.]
edit: If I decide to forego scenes, how should I set up what I now have as scenes? In different frames on the time line?
I'll check out your code in a bit
That would be amaaaazing
:rotate:
See comments in code:
Revise to: revise to See notes on clickHdlr.
If you declare a variable in a function, it does not exist outside of that function. See notes on first function, where we define these outside of it so that BOTH functions may access them.
Thank you an incredible amount.
Now I think I'll tackle the timeline (oh god)