Tilemap that exists in the editor doesn't exist when the level is run
by Johannes Pauw · in Torque Game Builder · 01/27/2012 (10:20 am) · 10 replies
I created a tilemap using the editor, saved the tilelayer, saved the level, and ran the level -- nothing appeared. It's not invisible, it just doesn't exist. I gave it a name in the editor and tried to access it in script, but it doesn't exist. The tilelayer definitely exists and definitely contains the proper tile information. Torsion doesn't throw out any errors about creating the tilemap.
This is the generated code for the tilemap in the level.t2d file (named battleScene.t2d):
This is the code I use to check:
I copied the tilemap declaration into the main game.cs script, manually creating the object and assigning it to the scenegraph that holds this level:
This time it worked, the game didn't quit and the tilemap showed up properly. Now obviously I can do some stupid workaround, loading tilemaps somewhere else in script in this fashion for each level, but that will be both super messy and super time consuming compared to just using the editor. Does anyone have any clue what might be going on here?
This is the generated code for the tilemap in the level.t2d file (named battleScene.t2d):
new t2dTileLayer(MainTiles) {
LayerFile = "~/data/tilemaps/test2.lyr";
canSaveDynamicFields = "1";
Position = "-1.000 1.000";
size = "112.000 112.000";
Layer = "30";
CollisionPhysicsSend = "0";
CollisionPhysicsReceive = "0";
CollisionMaxIterations = "1";
CollisionCircleSuperscribed = "0";
mountID = "3";
};This is the code I use to check:
if (!isObject(MainTiles))
{
endGame();
}I copied the tilemap declaration into the main game.cs script, manually creating the object and assigning it to the scenegraph that holds this level:
new t2dSceneGraph(battleGraph);
battleGraph.loadLevel("game/data/levels/battleScene.t2d");
Mainscreen.setSceneGraph(battleGraph);//Set the t2dSceneWindow to the newly created sceneGraph
Mainscreen.setCurrentCameraArea(-50, -50, 50, 50);
%newTiles = new t2dTileLayer() {
scenegraph = battleGraph;
LayerFile = "~/data/tilemaps/test2.lyr";
canSaveDynamicFields = "1";
Position = "-1.000 1.000";
size = "112.000 112.000";
Layer = "30";
CollisionPhysicsSend = "0";
CollisionPhysicsReceive = "0";
CollisionMaxIterations = "1";
CollisionCircleSuperscribed = "0";
mountID = "3";
};
if (!isObject(%newTiles))
{
endGame();
}This time it worked, the game didn't quit and the tilemap showed up properly. Now obviously I can do some stupid workaround, loading tilemaps somewhere else in script in this fashion for each level, but that will be both super messy and super time consuming compared to just using the editor. Does anyone have any clue what might be going on here?
About the author
Recent Threads
#2
It just struck me that maybe I should also mention that I have two sceneGraphs in two t2dSceneWindows running simultaneously in my game. Not sure if it could be part of the problem.
01/27/2012 (12:33 pm)
Sure Michael, the console.log is here: http://pastebin.com/XBKN093kIt just struck me that maybe I should also mention that I have two sceneGraphs in two t2dSceneWindows running simultaneously in my game. Not sure if it could be part of the problem.
#3
01/27/2012 (12:42 pm)
@Johannes - I was already assuming you were using multiple sceneGraphs. Are there any other objects in battleScene.t2d, which are visible?
#4
I also did just try and drag and drop a new tilemap into the scene, draw in a few tiles, and save it, and when it ran it didn't exist either. I then once again copied the instantiation code from battleScene.t2d into game.cs and that works.
01/27/2012 (12:49 pm)
Although there weren't any other visible objects at the time (the only other object was an invisible sceneObject containing my manager code), I can drag and drop staticSprites from the library into the scene and they show up. I also did just try and drag and drop a new tilemap into the scene, draw in a few tiles, and save it, and when it ran it didn't exist either. I then once again copied the instantiation code from battleScene.t2d into game.cs and that works.
#5
01/27/2012 (12:57 pm)
What is your code for loading the first level, then the second level? It sounds like it might be an order problem.
#6
That's the code that loads the two levels, and here's the code for mainscreengui if that might be part of it:
http://pastebin.com/saDMZF6K
01/27/2012 (1:04 pm)
http://pastebin.com/TvDkCUR1That's the code that loads the two levels, and here's the code for mainscreengui if that might be part of it:
http://pastebin.com/saDMZF6K
#7
Note - The png descriptions referred to image attachments in the e-mail
GameLevel.png - This was a simple game level I set up, called "level.t2d". This where I create my game objects, like a player, tiles, etc. It has a space ship that constantly flies to the right.
HudLevel.png - This is a completely new level I created to contain my HUD, called "hud.t2d". This contains my player health sprite, power-up sprite and a particle effect that connects the two.
FinalResult.png - This is the game running outside of the editor. As you can see, it contains both levels. Additionally, the HUD level is on top (which is what you want for an interface)
Here are the steps to reproduce my example:
1. Create your game level (which you have already done)
2. Create your HUD level (contains your interface)
3. Open game/gui/mainScreen.gui and look for this code:
4. Add the following code immediately after that block:
5. Open game/gameScripts/game.cs and look for this code:
6. Change that line of code to explicitly load your game level:
7. Directly beneath that code, add the following:
Now for the explanation of what's going on. A t2dSceneWindow is a GUI that remains static to your game window. It also contains a camera and various other functions. A t2dSceneWindow is responsible for loading your levels. In a stock T2D project, you only get one t2dSceneWindow which loads a level at the start. That is the sceneWindow2D.loadLevel() call in startGame.
Because you want to load two separate levels and show them at the same time, you need a second t2dSceneWindow. That is where the hudWindow comes into play. You have to create a new one (which is added to mainScreen.gui), which will be responsible for loading your interface (hudWindow.loadLevel("game/data/levels/hud.t2d") ).
The reason I said you should explicitly change the sceneWindow2D.loadLevel(%level), is because that %level variable is set by the game editor to whatever level you were last working on. This can be bad, since you want to load and render two separate levels in a specific order.
01/27/2012 (1:10 pm)
@Johannes - Ok, I see what you are doing. I think you can simplify this a lot more. I'm copying the contents of an e-mail I sent someone else about a month ago, which illustrates the easiest way to have your main game level working nicely with a HUD level:Note - The png descriptions referred to image attachments in the e-mail
GameLevel.png - This was a simple game level I set up, called "level.t2d". This where I create my game objects, like a player, tiles, etc. It has a space ship that constantly flies to the right.
HudLevel.png - This is a completely new level I created to contain my HUD, called "hud.t2d". This contains my player health sprite, power-up sprite and a particle effect that connects the two.
FinalResult.png - This is the game running outside of the editor. As you can see, it contains both levels. Additionally, the HUD level is on top (which is what you want for an interface)
Here are the steps to reproduce my example:
1. Create your game level (which you have already done)
2. Create your HUD level (contains your interface)
3. Open game/gui/mainScreen.gui and look for this code:
new t2dSceneWindow(sceneWindow2D) {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiContentProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 0";
Extent = "640 480";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
hovertime = "1000";
lockMouse = "0";
useWindowMouseEvents = "1";
useObjectMouseEvents = "1";
};4. Add the following code immediately after that block:
new t2dSceneWindow(hudWindow) {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiContentProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 0";
Extent = "640 480";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
hovertime = "1000";
lockMouse = "0";
useWindowMouseEvents = "1";
useObjectMouseEvents = "1";
};5. Open game/gameScripts/game.cs and look for this code:
sceneWindow2D.loadLevel(%level);
6. Change that line of code to explicitly load your game level:
sceneWindow2D.loadLevel("game/data/levels/level.t2d");7. Directly beneath that code, add the following:
hudWindow.loadLevel("game/data/levels/hud.t2d");Now for the explanation of what's going on. A t2dSceneWindow is a GUI that remains static to your game window. It also contains a camera and various other functions. A t2dSceneWindow is responsible for loading your levels. In a stock T2D project, you only get one t2dSceneWindow which loads a level at the start. That is the sceneWindow2D.loadLevel() call in startGame.
Because you want to load two separate levels and show them at the same time, you need a second t2dSceneWindow. That is where the hudWindow comes into play. You have to create a new one (which is added to mainScreen.gui), which will be responsible for loading your interface (hudWindow.loadLevel("game/data/levels/hud.t2d") ).
The reason I said you should explicitly change the sceneWindow2D.loadLevel(%level), is because that %level variable is set by the game editor to whatever level you were last working on. This can be bad, since you want to load and render two separate levels in a specific order.
#8
http://pastebin.com/rF4hxczQ
The reason I wrote it the way I did was so that I could name the sceneGraphs for use in that function, and because I think there's a good chance I'll need references to them elsewhere in my code as well. I guess I could also just pull the reference out using getSceneGraph() and set it to a global though. Do you think that using the built in loadLevel from t2dSceneWindow might solve my issue?
01/27/2012 (1:20 pm)
So the issue with that in my game, is that I essentially have two games running simultaneously, one runs in the 'Minimap' t2dSceneWindow, and one runs in the 'Mainscreen' t2dSceneWindow. You can swap back and forth by pressing spacebar, at which point I run this code:http://pastebin.com/rF4hxczQ
The reason I wrote it the way I did was so that I could name the sceneGraphs for use in that function, and because I think there's a good chance I'll need references to them elsewhere in my code as well. I guess I could also just pull the reference out using getSceneGraph() and set it to a global though. Do you think that using the built in loadLevel from t2dSceneWindow might solve my issue?
#9
01/27/2012 (1:22 pm)
Actually nvm, I just tried it and the built in loadLevel did indeed solve the issue. I'll reorganize the other stuff, thanks for your help!
#10
01/27/2012 (1:34 pm)
Fantastic! Glad it's working for you.
Employee Michael Perry
ZombieShortbus