LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   JavaScript: function only taking constants, no variables. :/ (https://www.linuxquestions.org/questions/programming-9/javascript-function-only-taking-constants-no-variables-519350/)

RHLinuxGUY 01-14-2007 10:52 PM

JavaScript: function only taking constants, no variables. :/
 
I am making a Simon game for my web site. It utilizes javascript as it's language to run the game. Sadly, at one point in my game loop, it checks if it's the computers turn to do its' thing. If it is the computers turn, It generates a random number, and adds it to it's objects variable array.(algor[]) Than it goes through a for loop, and makes a setTimeout() function to another function(Called S_ChgImg(img_iter, img_num)). The for loop iterates every element of algor to S_ChgImg(img_iter, img_num). There is only 4 possible values (0,1,2,3) to send through S_ChgImg(). (one for every color on the simon game table)

The rest of the information on how the function works doesn't really matter (the code should be easy enough to be understandable, yet if you want more info, just ask), but here is my problem & question: I can only send constants (1,2,3,4,5.. etc) but no variables (S_GameData.algor[0], img_array, etc.) through the function.

Even when I write 'document.write(img_iter)' directly in S_ChgImg(img_iter, img_num) body of code, only if I click on the image (in which no variables are passed, only constants) will that line be reached. Or image change, if the line is taken out.

Any ideas?

Here is the relevant functions, variables, objects:

Code:

S_GameData = {

        "lives": 0,
        "speed": 1,
        "algor": new Array()
};

Code:

/*
        Just replaces image with a specified other.
        img_iter for the S_Images[][] array to extracft from,
        and img_num for the array element.
*/
function S_ChgImg(img_iter, img_num)
{
        if (img_iter < 0 || img_iter > 3) {
                document.write("<br>[S_ChgImg] :: img_iter(" + img_iter + ") is not a valid value.  Failure!<br>");
                return;
        }

        if (img_num < 0 || img_num > 1) {
                document.write("<br>[S_ChgImg] :: img_num(" + img_num + ") is not a valid value.  Failure!<br>");
                return;
        }

        document.S_Button[img_iter].src = S_Images[img_iter][img_num];
        document.getElementById('testInfo').innerHTML += "It go there<br>";
}

Code:

/*
        Is always running.
        Checks to see if game is started, and does its' magic if so.
*/
function S_GameLoop()
{
        if (S_runTres == 2)
        {
                document.getElementById('testInfoTwo').innerHTML = "S_GameLoop()3!<br>";
                document.write("GAME ENDED WITH A LOSS!!! FIXME!");
                return;
        }

        if (S_runBool)
        {
                if (!S_controlSwitch && S_CompGo)
                {
                        var RndNum = Math.floor(Math.random()*4);
               
                        S_GameData.algor[S_GameData.algor.length] = RndNum;

                document.getElementById('testInfo').innerHTML = "S_GameLoop() RndNum = " + RndNum + " :: S_GameData.algor.length = " + S_GameData.algor.length + " :: algor[0] = " + S_GameData.algor[0] + "<br>";
       
                        for (var iter = 0; iter < S_GameData.algor.length; ++iter)
                        {     
                                // Issue with constants, but not variables, can only be passed to S_ChgImg(,) needs to be fixed.
                                // For now, the switch substitute should work, but looks fugly.
                                //
                                var timeOutOne = setTimeout("S_ChgImg(S_GameData.algor[iter],1)",1000 * iter);
                                var timeOutTwo = setTimeout("S_ChgImg(S_GameData.algor[iter],0)",(1000 * iter) + 1000);

                                S_CheckCompState();
                        }

                        S_CompGo = false;
                }
                else if (S_controlSwitch && S_HumanGo)
                {
                        //document.getElementById('testInfo').innerHTML = "S_GameLoop() S_controlSwitch<br>";
                        var timeOut = setTimeout("S_CheckPlayerState()",1000);
                }
        }

        var timeOut = setTimeout("S_GameLoop()",250);
}


RHLinuxGUY 01-15-2007 10:42 PM

Ok, I've seem to fix the problem with :

Code:

var timeOutOne = setTimeout("S_ChgImg(S_GameData.algor[iter],1)",1000 * iter);
var timeOutTwo = setTimeout("S_ChgImg(S_GameData.algor[iter],0)",(1000 * iter) + 1000);

By changing it to look like this:

Code:

var timeOutOne = setTimeout(S_ChgImg(S_GameData.algor[iter],1),1000 * iter);
var timeOutTwo = setTimeout(S_ChgImg(S_GameData.algor[iter],0),(1000 * iter) + 1000);

Now the problem is that it does not seem to read the second setTimeout at all. :/

--UPDATE--
Looks like I found where my problems lies. To begin with, here is the problem block of code:

Code:

function S_GameLoop()
{
        if (S_runTres == 2)
        {
                document.getElementById('testInfoTwo').innerHTML = "S_GameLoop()3!<br>";
                document.write("GAME ENDED WITH A LOSS!!! FIXME!");
                return;
        }

        if (S_runBool)
        {
                if (!S_controlSwitch && S_CompGo)
                {
                        var RndNum = Math.floor(Math.random()*4);
               
                        S_GameData.algor[S_GameData.algor.length] = RndNum;
       
                        for (var iter = 0; iter < S_GameData.algor.length; ++iter)
                        {     
                                // Issue with constants, but not variables, can only be passed to S_ChgImg(,) needs to be fixed.
                                // For now, the switch substitute should work, but looks fugly.
                                //
                                var timeOutOne  = setTimeout(S_ChgImg(S_GameData.algor[iter],1),1000 * iter);
                                var timeOutTwo  = setTimeout(S_ChgImg(S_GameData.algor[iter],0),1000 * iter + 1000);
                                var timeOutThree = setTimeout(function(){S_CheckCompState();},1000 * iter + 1000);
                        }

                        S_CompGo = false;
                }
                else if (S_controlSwitch && S_HumanGo)
                {
                        var timeOut = setTimeout(function(){S_CheckPlayerState();},1000);
                }
        }

        var timeOutThree = setTimeout(function(){document.getElementById('testInfo').innerHTML += 'looped<br>';},250);
        var timeOut = setTimeout(function(){S_GameLoop();},250);
}

The above code runs... until it hits the first setTimeout().

It runs that line, than it stops running the function. :/

Any ideas?

RHLinuxGUY 01-16-2007 05:07 AM

--UPDATE UPDATE--

I got passed that problem, I got the lines to run, but the functions that are supposed to run after a certain period of time, do NOT run. Here is the new code:

Code:

var timeOutOne  = setTimeout(function(){S_ChgImg(S_GameData.algor[iter],1);},1000 * iter);
var timeOutTwo  = setTimeout(function(){S_ChgImg(S_GameData.algor[iter],0);},1000 * iter + 1000);
var timeOutThree = setTimeout(function(){S_CheckCompState();},1000 * iter + 1000);


ntubski 01-16-2007 12:35 PM

How did you determine which lines have run? From my tests, it's the loop that doesn't run.

I don't know much Javascript so I'm not sure what
Code:

S_GameData = {

        "lives": 0,
        "speed": 1,
        "algor": new Array()
};

does, but I think it's not doing what you want. I made a small test page:
Code:

<html>
  <head>
<title>jscript test</title>

<script type="text/javascript">
  S_GameData = {

  "lives": 0,
  "speed": 1,
  "algor": new Array()
  };
 
  function timedMsg()
  {
    document.write("length is" + S_GameData.algor.length);
    S_GameData.algo[S_GameData.algor.length] = 34; //this line should make array grow by 1?
    document.write("length is now" + S_GameData.algor.length);
  }
</script>

</head>
<body onload="timedMsg()">
</body></html>

This ouputs
Quote:

length is0
(note that the 3rd line of timedMsg is not run),
and an error in Firefox's JavaScript Console (which you should definitely use):
Quote:

Error: S_GameData.algo has no properties
Source File: file:///home/npostavs/tmp/jscript.html
Line: 16
Also I don't understand what you mean about constants, aren't you using the variable S_GameData.algor with the S_ChgImg function?

RHLinuxGUY 01-16-2007 05:38 PM

Fixed the .length issue.

...and wow... I remember JavaScript console, but that was a while ago, and I forgot about it. Thanks for the tip.

Quote:

Also I don't understand what you mean about constants, aren't you using the variable S_GameData.algor with the S_ChgImg function?
I meant about the constants as foo(1);, and variables as bar = 1; foo(bar);.

-- 800th post.

ntubski 01-16-2007 06:26 PM

Um, how did you fix it? Did it help anything else?

Quote:

Originally Posted by RHLinuxGUY
I meant about the constants as foo(1);, and variables as bar = 1; foo(bar);.

Code:

var timeOutOne = setTimeout("S_ChgImg(S_GameData.algor[iter],1)",1000 * iter);
Isn't that a variable?

RHLinuxGUY 01-16-2007 11:22 PM

Yea, and I wrote it only seemed to work if I used constants. But the variables didn't work. :/ I did some usage of the JS console, and I noticed that I can't have a document.getElementById(id)[element]. How would I be able to access different elements, instead of making a unique id over and over again?

--EDIT--

I changed the:

Code:

S_GameData.algo[S_GameData.algor.length] = 4;
to:

Code:

S_GameData.algo[S_GameData.algor.length +1] = 4;
--UPDATE UPDATE--

I still cannot send my variable S_GameData.algor[iter] to S_ChgImg. I added a debuging <div> tag in my code, and here is what is brought up in my S_ChgImg() function, when failing a simple case statement to see if img_iter is a value of 0 to 3:

NOTE: undefined (color Blue) is img_iter, and is the parameter that S_GameData.aglor[iter] copys its' value to.

Code:

-DEBUG-S_ChgImg(undefined, 1) img_iter switch found a non valid value.
S_ChgImg(undefined, 0) img_iter switch found a non valid value.

The following is outputted BEFORE it reached those two setTimeout()'s that I am having trouble with (timeOutOne & timeOutTwo):

NOTE: The first line (BEFORE) is what the array S_GameData.algor length, & followed by what it's width is, before and after the random number was inserted into it's array.

Code:

      LENGTH  ELEMENT 0
BEFORE :: 0 :: undefined
AFTER  :: 2 :: 1

This clearly shows that, before the for loop is executed, there is a number avaiable in S_GameData.algors' first element. Yet when passed to S_ChgImg(), S_ChgImg() only finds it as undefined. :/

ntubski 01-18-2007 01:00 AM

Quote:

Originally Posted by RHLinuxGUY
Yea, and I wrote it only seemed to work if I used constants. But the variables didn't work. :/ I did some usage of the JS console, and I noticed that I can't have a document.getElementById(id)[element]. How would I be able to access different elements, instead of making a unique id over and over again?

I think you could put the elements you want inside an id'd element and then use childNodes[index]. I don't really know that much so I'm guessing based on this reference: http://www.javascriptkit.com/domref/...operties.shtml

Quote:

I changed the:
Code:

S_GameData.algo[S_GameData.algor.length] = 4;
to:
Code:

S_GameData.algo[S_GameData.algor.length +1] = 4;

Oops, I think that is not a problem, my test page actually had a typo in it that caused the error (algo instead of algor). You should probably change it back. :o

Quote:

--UPDATE UPDATE--
...
Code:

      LENGTH  ELEMENT 0
BEFORE :: 0 :: undefined
AFTER  :: 2 :: 1

This clearly shows that, before the for loop is executed, there is a number avaiable in S_GameData.algors' first element. Yet when passed to S_ChgImg(), S_ChgImg() only finds it as undefined. :/
Um, it could that the fix you put in for the "problem" that I pointed out is screwing up: I think it would add 2 elements leaving one of them undefined. Did your debug statement output S_GameData.algor[1] or S_GameData.algor[0]? Anyways I think my earlier post probably did more harm than help :(

RHLinuxGUY 01-19-2007 02:49 AM

Yes... leaving
Code:

S_GameData.algo[S_GameData.algor.length +1] = 4;
to
Code:

S_GameData.algo[S_GameData.algor.length] = 4;
works without flaw. Because the length of the latter is just zero. And if there is no element zero, JS creates it. So it is fine. And when you do length again, it always 1 ahead of the actual number of elements in the array. So that is fine.

Code seems to be working. I'll add more info on the fix later on today, once I get some sleep.


All times are GMT -5. The time now is 08:58 AM.