Ending the game
by Anthony Ratcliffe · in Torque Game Builder · 03/17/2008 (12:26 pm) · 28 replies
Hello i've written a movement script based on an if loop(see below) at the end of the loop it should load a new scene in this case called end.t2d how ever tgb crashes when it reaches the end and i cannot work out why
function mo::onLevelLoaded(%this)
{
$level = "game/data/levels/end.t2d"; // looks for level end
$node= 0;
%this.setPositionTarget(49,-47, true, true);
%this.setLinearVelocityX(15);
$node++;
}
ECT ECT .......
else if ($node==35)
{
echo ("reached call36");
%this.setPositionTarget(-48,-11, true, true);
%this.setLinearVelocityX(0);
%this.setLinearVelocityY(2);
$node++;
}
else if ($node==36)
{
echo ("reached call36");
%this.setPositionTarget(48,-11, true, true);
%this.setLinearVelocityX(20);
%this.setLinearVelocityY(0);
$node++;
}
else if ($node==37)
{
sceneWindow2D.endLevel();
sceneWindow2D.loadLevel($level);
}
// ADD A ELSE IF TO TAKE IT TO A DIFFRENT LEVEL SAYING GAME OVER THEY REACHED THE CITY WALLS
}
function mo::onLevelLoaded(%this)
{
$level = "game/data/levels/end.t2d"; // looks for level end
$node= 0;
%this.setPositionTarget(49,-47, true, true);
%this.setLinearVelocityX(15);
$node++;
}
ECT ECT .......
else if ($node==35)
{
echo ("reached call36");
%this.setPositionTarget(-48,-11, true, true);
%this.setLinearVelocityX(0);
%this.setLinearVelocityY(2);
$node++;
}
else if ($node==36)
{
echo ("reached call36");
%this.setPositionTarget(48,-11, true, true);
%this.setLinearVelocityX(20);
%this.setLinearVelocityY(0);
$node++;
}
else if ($node==37)
{
sceneWindow2D.endLevel();
sceneWindow2D.loadLevel($level);
}
// ADD A ELSE IF TO TAKE IT TO A DIFFRENT LEVEL SAYING GAME OVER THEY REACHED THE CITY WALLS
}
About the author
#22
03/25/2008 (9:03 pm)
Ok will do is it possible i could send it via pm insted of open on the forums?
#23
There is a notable advantage in this new code.
First, it is likely a bit easier to digest when and if you have to return to this code later for updating, debugging, whatever. A switch statement is often a little cleaner to use when your evaluations are so straight forward (but highly repetitive) like in your original code.
Second, imagine that you needed to do something like, oh, add +5 to the X linear velocity for any node update. You would have to update some 36+ lines of code to reflect your desired change. Now, you can just update the single line found in the new function rather than weed your way through the many IF statements in the old format.
Anyhow, here is the code:
Note that it is quite possible that an error or three worked its way in, most likely as I transposed the node position and velocity information to the new format. It should be fairly easy to verify, all the same!
As to sending the project code via PM? That I don't know ... good question. I suppose you could try :)
If you're just concerned about keeping the data in it private, or it can't be sent by PM, put it in a zip that is password protected and upload to sendspace. Then provide the password via PM to Terra or I, for example.
NOTE: I realized that the node increment ($node++;) can't (or shouldn't) occur in the new function call because of the way switch statements are evaluated in TS--the node value would increment after a call and potentially satisfy one or more of the later switch cases, causing multiple undesired calls.
Sorry, I've been awake for nearly 24 hours now so I'm not at my sharpest. :D
updated/fixed a couple errors in the code sample above ...
03/26/2008 (8:48 am)
Anthony: The following bit is unrelated to solving the problem that this thread has been about. Basically, you have a lot of repetitive code that is best compacted into another method native to your MO class objects.There is a notable advantage in this new code.
First, it is likely a bit easier to digest when and if you have to return to this code later for updating, debugging, whatever. A switch statement is often a little cleaner to use when your evaluations are so straight forward (but highly repetitive) like in your original code.
Second, imagine that you needed to do something like, oh, add +5 to the X linear velocity for any node update. You would have to update some 36+ lines of code to reflect your desired change. Now, you can just update the single line found in the new function rather than weed your way through the many IF statements in the old format.
Anyhow, here is the code:
function mo::onLevelLoaded(%this)
{
// We don't need to init $node
// as its value will be handled in the nodeUpdate call.
// So, we do a node update for this object now ...
%this.nodeUpdate(49, -47, 15, 0);
// we do need to increment it after the call, however ...
$node++;
}
function mo::onPositionTarget(%this)
{
switch ($node)
{
case 1:
%this.nodeUpdate(49, -45, 0, 2);
case 2:
%this.nodeUpdate(-49, -45, -15, 0);
case 3:
%this.nodeUpdate(-49, -43, 0, 2);
case 4:
%this.nodeUpdate(49, -43, 15, 2);
case 5:
%this.nodeUpdate(49, -41, 0, 2);
case 6:
%this.nodeUpdate(-49, -41, -15, 0);
case 7:
%this.nodeUpdate(-49, -39, 0, 2);
case 8:
%this.nodeUpdate(49, -39, 15, 2);
case 9:
%this.nodeUpdate(49, -37, 0, 2);
case 10:
%this.nodeUpdate(-49, -37, -15, 2);
case 11:
%this.nodeUpdate(-49, -35, 0, 2);
case 12:
%this.nodeUpdate(49, -35, 15, 2);
case 13:
%this.nodeUpdate(49, -33, 0, 2);
case 14:
%this.nodeUpdate(-49, -33, -15, 0);
case 15:
%this.nodeUpdate(-49, -31, 0, 2);
case 16:
%this.nodeUpdate(48, -31, 15, 0);
case 17:
%this.nodeUpdate(48, -29, 0, 2);
case 18:
%this.nodeUpdate(-48, -29, -15, 0);
case 19:
%this.nodeUpdate(-48, -27, 0, 2);
case 20:
%this.nodeUpdate(48, -27, 15, 0);
case 21:
%this.nodeUpdate(48, -25, 0, 2);
case 22:
%this.nodeUpdate(48, -25, -15, 0);
case 23:
%this.nodeUpdate(48, -23, 0, 2);
case 24:
%this.nodeUpdate(49, -23, 15, 0);
case 25:
%this.nodeUpdate(48, -21, 0, 2);
case 26:
%this.nodeUpdate(-48, -21, -17, 0);
case 27:
%this.nodeUpdate(-48, -19, 0, 2);
case 28:
%this.nodeUpdate(48, -19, 17, 0);
case 29:
%this.nodeUpdate(48, -17, 0, 2);
case 30:
%this.nodeUpdate(-48, -17, -18, 0);
case 31:
%this.nodeUpdate(-48, -15, 0, 2);
case 32:
%this.nodeUpdate(48, -15, 18, 0);
case 33:
%this.nodeUpdate(48, -13, 0, 2);
case 34:
%this.nodeUpdate(-48, -13, -20, 0);
case 35:
%this.nodeUpdate(-48, -11, 0, 2);
case 36:
%this.nodeUpdate(48, -11, 20, 0);
case 37:
$level = expandFilename("~data/levels/end.t2d");
sceneWindow2D.schedule(100, 0, "endLevel");
sceneWindow2D.schedule(500, 0, "loadLevel", $level);
default:
// should never reach this, send a console msg alerting to this
warn("mo::onPositionTarget() reached switch default case (invalid).");
// Might want to use this for "Game Over" handling ... (??)
}
// increment the node now ...
$node++;
}
// ===================================== //
// FUNCTION: nodeUpdate
// PARAMETERS: %posX desired target x position
// %posY desired target y position
// %velX desired velocity on the x dimension
// %velY desired velocity on the y dimension
// SUMMARY: Handles a node update for an MO object
// by updating desired (target) position coordinates and velocity
// Note that the actual node increment is NOT handled in this function ...
function mo::nodeUpdate(%this, %posX, %posY, %velX, %velY)
{
// A little handling to mimic default values for our function arguments ...
// Set the values below to some other desired value if you
// want or need a different default when no value is passed into this function
if(%posX $= "")
%posX = 0;
if(%posY $= "")
%posY = 0;
if(%velX $= "")
%velX = 0;
if(%velY $= "")
%velY = 0;
// And a little handling of our $node value to make sure it is saavy
if($node < 0 || $node == "" || $node == " ")
$node = 0;
echo("Updating from node " @ $node @ " to node " @ ($node + 1));
%this.setPositionTarget(%posX, %posY, true, true);
%this.setLinearVelocityX(%velX);
%this.setLinearVelocity(%velY);
}Note that it is quite possible that an error or three worked its way in, most likely as I transposed the node position and velocity information to the new format. It should be fairly easy to verify, all the same!
As to sending the project code via PM? That I don't know ... good question. I suppose you could try :)
If you're just concerned about keeping the data in it private, or it can't be sent by PM, put it in a zip that is password protected and upload to sendspace. Then provide the password via PM to Terra or I, for example.
NOTE: I realized that the node increment ($node++;) can't (or shouldn't) occur in the new function call because of the way switch statements are evaluated in TS--the node value would increment after a call and potentially satisfy one or more of the later switch cases, causing multiple undesired calls.
Sorry, I've been awake for nearly 24 hours now so I'm not at my sharpest. :D
updated/fixed a couple errors in the code sample above ...
#24
P.S. The line 90 error from the code I gave was because I missed a needed " around the levelLoaded parameter.
03/26/2008 (8:50 pm)
Anthony: Just got a copy of your project and I'll start looking over it shortly to see what you've got cooking within.P.S. The line 90 error from the code I gave was because I missed a needed " around the levelLoaded parameter.
#25
Well, it is working. I've commented fairly heavily to changes made along with comments on other considerations that might be had. Here is the link to the updated project files:
http://www.sendspace.com/file/oygrsx
There appears to be a bug, or perhaps something that simply eludes me, with respect to the use of endLevel in your project.
For example, if you pull the console down while the "invader" is moving from node to node and type "EndGame()", the level clears and all is well. However, if you replace the code for node 37 with EndGame(), the result is a crash. Same call, just used at different times so there is something to it, but ...
I tried a few variations to see if it would stop crashing when endLevel was called (either on the Scene Window or the Scenegraph itself), still to no avail. Tera's code wasn't working either--it is as though the schedule calls never fired. Odd, though I noticed a while back that schedule calls can be a little finicky for whatever reason.
If I took some more time I could likely figure out just what is happening but I don't seen an answer on the face of it.
Regardless, I believe it is working as you want and you should be able to dig back in to start work again, minus those previous frustrations. Let me know if you have any problems with it. :D
03/27/2008 (2:14 am)
Anthony: Me again ...Well, it is working. I've commented fairly heavily to changes made along with comments on other considerations that might be had. Here is the link to the updated project files:
http://www.sendspace.com/file/oygrsx
There appears to be a bug, or perhaps something that simply eludes me, with respect to the use of endLevel in your project.
For example, if you pull the console down while the "invader" is moving from node to node and type "EndGame()", the level clears and all is well. However, if you replace the code for node 37 with EndGame(), the result is a crash. Same call, just used at different times so there is something to it, but ...
I tried a few variations to see if it would stop crashing when endLevel was called (either on the Scene Window or the Scenegraph itself), still to no avail. Tera's code wasn't working either--it is as though the schedule calls never fired. Odd, though I noticed a while back that schedule calls can be a little finicky for whatever reason.
If I took some more time I could likely figure out just what is happening but I don't seen an answer on the face of it.
Regardless, I believe it is working as you want and you should be able to dig back in to start work again, minus those previous frustrations. Let me know if you have any problems with it. :D
#26
03/27/2008 (12:56 pm)
Wow it worked :D with that as an example i could change level for a win screen aswell, i think i'm in love ha, i think i finally have an understanding of what you did, however i'm not entirly sure what the benifits of a switch statment over and if (also be aware i never knew switch statments existed lol)
#27
Nonetheless, SWITCH is inherently a multiple-selection structure that can make code easier to read and maintain. Some programmers simply don't like to use SWITCH, so it is in part a matter of preference. You could likely do all the programming you ever need with IF/ELSE/ELSE IF and WHILE statements, after all.
Still, it can be argued that SWITCH statements improve code readability and are therefore easier to maintain and debug. I think "back in the day" that SWITCH statements may have afforded a mild performance gain over IF/ELSE IF for integer evaluations. That probably no longer applies and at the least you won't find anyone arguing that performance is a consideration in its use.
There is another reason to use SWITCH statements (over IF/ELSE IF) though it doesn't apply in TorqueScript. The reason is that in other languages, SWITCH can only be used to evaluate integer values (i.e, not string or conditionals).
So, the type of evaluation occurring could be distinguished based the control structure involved--so long as the programmers agree to use SWITCH for single integral evaluations and IF/ELSE IF for string and conditional evaluations. In TorqueScript, you can evaluate strings using switch$.
Beyond all of that, Anthony, I'd offer up a tip to consider whenever you find yourself dealing with a "many evaluations" situation. Chances are, if you step back, there exists a better design that will either a) reduce the number of evaluations you need to make, or b) eliminate the need for a voluminous control structure entirely.
That is, once you start to reach beyond a certain number of evaluations it is more and more likely that a better design exists than what you are have before you. It could signal a need for better object or method design, or even the need for additional methods or objects.
I wouldn't say that it always holds true but I find it is often the case, so it can't hurt to review the situation more closely to see if an improvement can be made.
03/27/2008 (11:03 pm)
Anthony: As to the use of the switch statement, quite honestly you could have continued on more or less unaware and never miss a beat for it.Nonetheless, SWITCH is inherently a multiple-selection structure that can make code easier to read and maintain. Some programmers simply don't like to use SWITCH, so it is in part a matter of preference. You could likely do all the programming you ever need with IF/ELSE/ELSE IF and WHILE statements, after all.
Still, it can be argued that SWITCH statements improve code readability and are therefore easier to maintain and debug. I think "back in the day" that SWITCH statements may have afforded a mild performance gain over IF/ELSE IF for integer evaluations. That probably no longer applies and at the least you won't find anyone arguing that performance is a consideration in its use.
There is another reason to use SWITCH statements (over IF/ELSE IF) though it doesn't apply in TorqueScript. The reason is that in other languages, SWITCH can only be used to evaluate integer values (i.e, not string or conditionals).
So, the type of evaluation occurring could be distinguished based the control structure involved--so long as the programmers agree to use SWITCH for single integral evaluations and IF/ELSE IF for string and conditional evaluations. In TorqueScript, you can evaluate strings using switch$.
Beyond all of that, Anthony, I'd offer up a tip to consider whenever you find yourself dealing with a "many evaluations" situation. Chances are, if you step back, there exists a better design that will either a) reduce the number of evaluations you need to make, or b) eliminate the need for a voluminous control structure entirely.
That is, once you start to reach beyond a certain number of evaluations it is more and more likely that a better design exists than what you are have before you. It could signal a need for better object or method design, or even the need for additional methods or objects.
I wouldn't say that it always holds true but I find it is often the case, so it can't hurt to review the situation more closely to see if an improvement can be made.
#28
03/27/2008 (11:07 pm)
Thanks for your help everyone, i'm glad there people on the forum who know there stuff lol. I think i may add this to the tutorials when i have completed the game, if your all ok with that? Just somthing i've never seen mentioned before and somthing that really needs to be looked at.
Torque Owner Tetraweb
Greg