Creating a resolution independent status panel
The status panel I created for Wasabi Defense required a bit of coding for making it resolution independent. The problem with Torque is that the level builder and GUI builder use different coördinate systems. The level builder uses world coördinates. These aren’t affected by the screen resolution and have, by default, the origin placed in the center of the screen. The GUI builder, however, uses window coördinates. This means the origin is placed in the top left of the screen, and this system is pretty much the same system Windows uses for window coördinates and is not resolution independent. If you develop a game that allows players to adjust the resolution and aspect ratio of the screen, you need to do some coding to work around this problem.
First of all, the background panel image. The actual GUI you see on the screenshots is actually only the green text; the metal panel with the inset displays isn’t really a part of the GUI. It’s just a static sprite that’s part of the level, so it automatically adapts to the resolution and I don’t have to worry about that one. The GUI is just a set of text fields that floats on top of the panel. To adjust this to the resolution, we need to do two things: move it to the correct position and adjust the font size. This tutorials assumes you are familiar with the GUI builder and know how to make text fields and assign profiles to them.
Let’s start with positioning the text. In short, this means determining the world coördinates where you want the text field to appear and calculating the window coördinates for them. The text field in the screenshots is placed at -160,475 in world coördinates. This needs to be converted to window coördinates, like this:
%XPos = mFloor(getWord(sceneWindow2D.
getWindowPoint(-160,475),0));
%YPos = mFloor(getWord(sceneWindow2D.
getWindowPoint(-160,475),1));
%Pos = “0 0″;
%Pos = setWord(%Pos,0,%XPos);
%Pos = setWord(%Pos,1,%YPos);
MessageText.Position = %Pos;
The first two lines convert the world coördinates to window coördinates for the current resolution. Next, an empty string is initialized and the coördinates are stored in it. Finally, the position of the text field is adjusted. Step number two is adjusting the size of the field.
%Width = mFloor(getWord(sceneWindow2D.
getWindowPoint(160,475),0) -
getWord(sceneWindow2D.getWindowPoint(-160,475),0));
%Height = mFloor(getWord(sceneWindow2D.
getWindowPoint(160,515),1) -
getWord(sceneWindow2D.getWindowPoint(-160,475),1));
%Size = “0 0″;
%Size = setWord(%Size,0,%Width);
%Size = setWord(%Size,1,%Height);
MessageText.Extent = %Size;
Pretty much the same approach as setting the position. You calculate the window coördinates for the top left and bottom right position and subtract them to get the size in window coördinate units.
The final step is adjusting the font size. The way I did it is probably not the most efficient and elegant way, but it works perfectly. If anyone knows a better way to do this, and I’m sure there is one, please let me know. When I started creating the GUI, I used a design resolution of 1024×768 pixels and set the font size of the text field to 28 points. This means that rougly every 55 pixels of screen height corresponds to a font size point. I created a series of GUI profiles for each font size and then checked the screen height to figure out wich size I had to use. Here’s a sample of the code:
%Screenheight = getWord(sceneWindow2D.getWindowExtents(),3);
if (%Screenheight <= 2030) %TextObject.Profile = “GuiGreenCenter74″;
if (%Screenheight <= 1975) %TextObject.Profile = “GuiGreenCenter72″;
if (%Screenheight <= 1920) %TextObject.Profile = “GuiGreenCenter70″;
if (%Screenheight <= 1865) %TextObject.Profile = “GuiGreenCenter68″;
if (%Screenheight <= 1810) %TextObject.Profile = “GuiGreenCenter66″;
if (%Screenheight <= 1755) %TextObject.Profile = “GuiGreenCenter64″;
if (%Screenheight <= 1701) %TextObject.Profile = “GuiGreenCenter62″;
if (%Screenheight <= 1646) %TextObject.Profile = “GuiGreenCenter60″;
if (%Screenheight <= 1591) %TextObject.Profile = “GuiGreenCenter58″;
if (%Screenheight <= 1536) %TextObject.Profile = “GuiGreenCenter56″;
if (%Screenheight <= 1481) %TextObject.Profile = “GuiGreenCenter54″;
if (%Screenheight <= 1426) %TextObject.Profile = “GuiGreenCenter52″;
if (%Screenheight <= 1371) %TextObject.Profile = “GuiGreenCenter50″;
if (%Screenheight <= 1317) %TextObject.Profile = “GuiGreenCenter48″;
if (%Screenheight <= 1262) %TextObject.Profile = “GuiGreenCenter46″;
if (%Screenheight <= 1207) %TextObject.Profile = “GuiGreenCenter44″;
if (%Screenheight <= 1152) %TextObject.Profile = “GuiGreenCenter42″;
if (%Screenheight <= 1097) %TextObject.Profile = “GuiGreenCenter40″;
if (%Screenheight <= 1042) %TextObject.Profile = “GuiGreenCenter38″;
if (%Screenheight <= 987) %TextObject.Profile = “GuiGreenCenter36″;
if (%Screenheight <= 933) %TextObject.Profile = “GuiGreenCenter34″;
if (%Screenheight <= 878) %TextObject.Profile = “GuiGreenCenter32″;
if (%Screenheight <= 823) %TextObject.Profile = “GuiGreenCenter30″;
if (%Screenheight <= 768) %TextObject.Profile = “GuiGreenCenter28″;
if (%Screenheight <= 713) %TextObject.Profile = “GuiGreenCenter26″;
if (%Screenheight <= 658) %TextObject.Profile = “GuiGreenCenter24″;
if (%Screenheight <= 603) %TextObject.Profile = “GuiGreenCenter22″;
This will have to be repeated for every text field I have, and the panel will eventually have seven of them. Like I said, not the most elegant solution but it works. And it’s executed only once so it won’t slow down the game.

Leave a Reply