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.

Now we're learning Flash. Or at least, I am

Skoal CatSkoal Cat Registered User regular
edited August 2011 in Help / Advice Forum
I want to have a screen that looks like this
formei.jpg
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

Posts

  • L Ron HowardL Ron Howard The duck MinnesotaRegistered User regular
    Which version of Powerpoint are we talking about here?
    Do you know any VB?

  • Skoal CatSkoal Cat Registered User regular
    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.

  • BioHaz594BioHaz594 Registered User regular
    Flash would actually be perfect for what you're trying to do.

    orgblk_m50le_sig1.png
  • L Ron HowardL Ron Howard The duck MinnesotaRegistered User regular
    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.

  • Skoal CatSkoal Cat Registered User regular
    edited August 2011
    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?

    Skoal Cat on
  • ArbitraryDescriptorArbitraryDescriptor Registered User regular
    Skoal Cat wrote:
    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.

    Savvy? Kinda?

  • Skoal CatSkoal Cat Registered User regular
    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)

  • Skoal CatSkoal Cat Registered User regular
    edited August 2011
    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...

    Skoal Cat on
  • ArbitraryDescriptorArbitraryDescriptor Registered User regular
    Please post the error messages

    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.

  • Skoal CatSkoal Cat Registered User regular
    edited August 2011
    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.

    Here is my XML
    <?xml version="1.0" encoding="utf-8"?>
    <xml>
         <quiz>
              <question>"blah blah blah"</question>
              <question>"bloo bloo bloo"</question>
         </quiz>
    </xml>
    

    Here is the code that successfully loads the 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..

    Skoal Cat on
  • Skoal CatSkoal Cat Registered User regular
    Code fixed, xmlLoader.addEventListener(Event.COMPLETE, LoadXML) was calling from the wrong function.

  • ArbitraryDescriptorArbitraryDescriptor Registered User regular
    edited August 2011
    [Edit] Well spotted, then.
    I get this:
    Question 0: "blah blah blah"
    Question 1: "bloo bloo bloo"
    
    Don't know what to tell you.

    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>
    




    ArbitraryDescriptor on
  • Skoal CatSkoal Cat Registered User regular
    edited August 2011
    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?

    Skoal Cat on
  • ArbitraryDescriptorArbitraryDescriptor Registered User regular
    Assuming that
    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.

  • Skoal CatSkoal Cat Registered User regular
    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?

  • Skoal CatSkoal Cat Registered User regular
    Assuming that
    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.

  • ArbitraryDescriptorArbitraryDescriptor Registered User regular
    edited August 2011
    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.]

    ArbitraryDescriptor on
  • Skoal CatSkoal Cat Registered User regular
    edited August 2011
    //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?

    Skoal Cat on
  • ArbitraryDescriptorArbitraryDescriptor Registered User regular
    Different frames would be much easier to manage while helping you keep the different sections clear in your mind.

    I'll check out your code in a bit

  • Skoal CatSkoal Cat Registered User regular
    edited August 2011
    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:

    Skoal Cat on
  • ArbitraryDescriptorArbitraryDescriptor Registered User regular
    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]); 
    }
    
    Skoal Cat wrote:
    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()
    See notes on clickHdlr.
    Skoal Cat wrote:
    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.



  • Skoal CatSkoal Cat Registered User regular
    edited August 2011
    You forgot to declare
    var xmlLoader:URLLoader = new URLLoader();
    xmlLoader.addEventListener(Event.COMPLETE, completeHandler);
    xmlLoader.load(new URLRequest("file.xml"));
    
    But hey, guess what... I was able to figure that out based on what I've learned with your help!!!

    Thank you an incredible amount.
    PROGRESS!

    Now I think I'll tackle the timeline (oh god)

    Skoal Cat on
  • ArbitraryDescriptorArbitraryDescriptor Registered User regular
    Happy to help

Sign In or Register to comment.