5 Replies Latest reply on Oct 2, 2014 6:25 AM by wmoner

    Edge/jQuery Function Scope: need advice

    wmoner

      Hi all ...

       

      I'm having difficulty with my Adobe Edge Animate code finesse, and I could use some advice. I'm more of a coder than an Edge/Flash guy, so I'm having trouble understanding the scope of variables and where I can use variables and anonymous functions on the global scope.

       

      I wrote a Tic-Tac-Toe game in Edge Animate, and I'd like many of my functions to be scoped globally so that I can just call them on a click action and play back the timeline once the function returns a response.

       

      Here's a typical onclick action:

       

               thisSym = sym.getSymbol("b1");

               var thisWinner = checkChoice(1, thisSym);

             

                // problematic code

               if (thisWinner === 1) {

                sym.getSymbol("winBox").$("theText").html("X WINS!");

                sym.play(2500);

               } else if (thisWinner === 2) {

                sym.getSymbol("winBox").$("theText").html("O WINS!");

                sym.play(2500);

               }

       

      Note that b1 is a square on the Tic-Tac-Toe grid and checkChoice is a function I wrote in Full Code view to handle checking whether the clicked box returns a winner.

       

      Currently, when I return a winner (1 for "X", 2 for "O") you'll note that I can go to a specific area on the timeline, dynamically update the text to say "X Wins" or "O Wins" depending on whomever wins, and then sym.play(2500) to go to the main timeline.

       

      Here's the problem: I want to abstract the portion of this click action that comes after my comment //problematic code. What's stopping me? The ability to control the stage timeline from outside of the stage scope in the code. I can *do* all the logic and get console.log to print whatever I want, but I can't get the stage to move to 2500.

       

      Any thoughts or advice? A good article on using custom functions in Edge Animate would be extremely helpful.

       

      Thanks!

      William

        • 1. Re: Edge/jQuery Function Scope: need advice
          joel_pau Level 5

          Hello,

           

          Well, i didn't understand (your code).

          Here is a demo file: games.zip - Box

          • 2. Re: Edge/jQuery Function Scope: need advice
            wmoner Level 1

            Joel,

            Thank you for this. The code that addresses my problem deals with the getVariable and setVariable methods. I couldn't quite figure out that I could set variables at the Stage level.

             

            This helped:

            if (sym.getComposition().getStage().getVariable("xo") == "X") {

              sym.getComposition().getStage().setVariable("xo","O");

              sym.getComposition().getStage().setVariable("toggleColor","green");

            } else {

              sym.getComposition().getStage().setVariable("xo","X");

              sym.getComposition().getStage().setVariable("toggleColor","red");

            };

             

            AND ALSO:

             

            sym.$("Stage").css("margin", "auto");

             

            I honestly didn't understand that $("Stage") was a possibility. I'll post my code when I'm done with the game example! Thanks again!

            • 3. Re: Edge/jQuery Function Scope: need advice
              wmoner Level 1

              Joel,

               

              Thanks again for your help. This is the full code as I wrote the Edge Animate Tic-Tac-Toe game (direct ZIP link):

              http://scriptingmedia.org/wp-content/uploads/2014/09/aea-tictactoe.zip

               

              The game absolutely works, but it works without playing by Edge's variable scope rules. How would you rewrite the global code to conform to Edge Animate? When I try to put any of this code in creationComplete or compositionReady the code fails completely.

               

              If you look at "Full Code" you'll see the global variables to control gameplay (including the functions to check for winners and to toggle choices, still reporting to console.log). The gameBoard array values are removed as a board piece is picked. xChoices and oChoices store these, and the array is compared against the winners. The code works well but I feel as though implementing this in Edge could be a bit easier.

               

              //wm

               

              var xChoices = [];

              var oChoices = [];

              var gameBoard = [0,1,2,3,4,5,6,7,8];

              var winners = [

                [0,1,2],[3,4,5],[6,7,8],

                [0,3,6],[1,4,7],[2,5,8],

                [0,4,8],[2,4,6]

              ];

              var turn = 0; //turn placeholder, manipulated by modulo

              var youWin;

               

               

              var checkChoice = function (theValue) {

               

               

                       var thisChoice = $.inArray(theValue, gameBoard);

               

               

                       console.log("Checking: " + theValue + " against " + thisChoice + " in " + gameBoard);

                console.log("Turn #: " + turn);

               

                       if (thisChoice > -1) {

               

               

                if (turn % 2 === 0) {

                xChoices.push(theValue);

                xChoices.sort();

                console.log(theValue + " X " + turn + " xChoices " + xChoices);

                thisSym.play(1000);

               

               

                } else if (turn % 2 === 1) {

                oChoices.push(theValue);

                oChoices.sort();

                console.log(theValue + " O " + turn + " oChoices " + oChoices);

                thisSym.play(2000);

                } else {

                console.log(turn);

                }

               

               

                gameBoard.splice(thisChoice, 1);

               

               

                if (turn > 3) {

                if (turn % 2 === 0) {

                var theWinner = checkWinners(xChoices, winners);

                } else if (turn % 2 === 1) {

                var theWinner = checkWinners(oChoices, winners);

                }

                }

               

               

                turn++;

                return theWinner;

               

                }

               

               

               

               

               

               

              };

               

               

              var checkWinners = function (arrA, arrB) {

               

               

                var counter = 0;

               

               

                if (turn > 8 ) {

                console.log("It's a tie!");

                } else {

                console.log("Checking for win...");

               

               

                for (var i = 0; i < arrB.length; i++) {

               

               

                for (var j = 0; j < arrB[i].length; j++) {

                for (var k = 0; k < arrA.length; k++) {

                if ($.inArray(arrA[k], arrB[i]) > -1) {

                if (arrA[k] === arrB[i][j]) {

                counter++;

                console.log(arrA[k] + " " + arrB[i] + " " + counter);

                }

                }

                }

                }

               

               

                if (turn % 2 === 0 && counter > 2) {

                console.log("X WINS");

                return 1;

                } else if (turn % 2 === 1 && counter > 2) {

                console.log("O WINS");

                return 2;

                }

                counter = 0;

               

               

                }

                }

              };

              • 4. Re: Edge/jQuery Function Scope: need advice
                joel_pau Level 5

                Hi wmoner,

                 

                As you built a version by dragging and dropping 9 instances from the panel library, here are 2 versions using sym.createChildSymbol().

                As the Edge API mentions sym.createChildSymbol() is a tool to create dynamically symbol instances. Dynamically means by code.

                ==> Edge Animate Tic-Tac-Toe - copie.zip - Box

                 

                Using this method, i can:

                1) move your Tic-Tac-Toe code (code within the previous post) to the creationComplete panel;

                2) i do not copy and paste 9 times the click event;

                3) i can truly reset the Tic-Tac-Toe game removing the 9 instances with sym.deleteSymbol().

                 

                New code to create dynamically symbols:

                //Using $.each() i browse the "gameBoard" array to create 9 instances (or children): [a1,...,c3].

                //Each instance is named "cell" and has a click event to display winBox.

                $.each(gameBoard, function(index,item){

                  var cell = sym.createChildSymbol("a1","gameboard");

                  cell.getSymbolElement()

                  .css({"display":"inline-block", "margin":"5px", "cursor":"pointer"})

                  .on("click", function(){

                  var thisWinner = checkChoice(index, cell);

                  if (thisWinner === 1) {

                  var winBox = sym.createChildSymbol("winBox","Stage");

                  winBox.getSymbolElement().css({"margin":"auto", "top":"25%"});

                  winBox.$("theText").html("X WINS!"); }

                  else if (thisWinner === 2) {

                  var winBox = sym.createChildSymbol("winBox","Stage");

                  winBox.getSymbolElement().css({"margin":"auto", "top":"25%"});

                  winBox.$("theText").html("O WINS!"); }

                  });

                });

                 

                New code to reset the game (click event):

                    

                console.log( "gameboard symbols:", sym.getComposition().getSymbols("a1") ); // it returns gameboard cells [a1,...,c3].

                $.each( sym.getComposition().getSymbols("a1"), function(){ this.deleteSymbol() } ); // it deletes gameboard cells.

                sym.getComposition().getStage().getVariable("reset")(); // new gameboard on stage. reset is created within the creationComplete panel using sym.setVariable().

                sym.deleteSymbol(); // it deletes the current symbol: winBox.

                • 5. Re: Edge/jQuery Function Scope: need advice
                  wmoner Level 1

                  Joel, this is fabulous! Thank you so much!

                   

                  My takeaways:

                  1. sym.getComposition().getSymbols("a1") ---> I had been unaware of the use of getSymbols to retrieve an array of objects. So useful!

                  2. The use of an init() function inside creationComplete. This one little bit of code solves a *ton* of my problems in Edge Animate.

                  3. jQuery's chaining to dynamically create instances based on symbols and set properties -- the API documentation is difficult to decipher and your example helps immensely!

                   

                  You deserve an award, a pay raise, and all the cookies you want!

                  Thank you!