Game Development Community

dev|Pro Game Development Curriculum

TGB 2-Player Split Screen

by David Higgins · 12/09/2006 (11:48 am) · 10 comments

Ok, I've been thumbing around in the TorqueX Beta starter kits and saw one that really peaked my interests. It's called the "Split Screen Starter", and it basically just sets up a 2-player split-screen interface for you automatically so all you have to do is write your game code and add your art resources.

I thought this was an awesome idea, and I immediately said to myself, "Why doesnt TGB have a Split Screen Starter Kit?". After about 15-20 minutes of messing around, I created a very basic and simple Split-screen system that is comprised of 2 files.

I have a splitScreen.gui which contains my SceneWindows (LeftSceneWindow and RightSceneWindow) as well as a split.cs script which contains my level loading initialization.

Here, have a look at them;

~/gui/splitScreen.gui
//--- OBJECT WRITE BEGIN ---
new GuiChunkedBitmapCtrl(splitScreenGui) {
   canSaveDynamicFields = "0";
   Profile = "GuiDefaultProfile";
   HorizSizing = "relative";
   VertSizing = "relative";
   position = "0 0";
   Extent = "640 480";
   MinExtent = "8 2";
   canSave = "1";
   Visible = "1";
   hovertime = "1000";
   bitmap = "~/data/images/logoblack.png";
   useVariable = "0";
   tile = "0";

   new t2dSceneWindow(LeftSceneWindow) {
      canSaveDynamicFields = "0";
      Profile = "GuiDefaultProfile";
      HorizSizing = "relative";
      VertSizing = "relative";
      position = "0 0";
      Extent = "315 480";
      MinExtent = "8 2";
      canSave = "1";
      Visible = "1";
      hovertime = "1000";
      lockMouse = "0";
      useWindowMouseEvents = "1";
      useObjectMouseEvents = "0";
   };
   new t2dSceneWindow(RightSceneWindow) {
      canSaveDynamicFields = "0";
      Profile = "GuiDefaultProfile";
      HorizSizing = "relative";
      VertSizing = "relative";
      position = "325 0";
      Extent = "315 480";
      MinExtent = "8 2";
      canSave = "1";
      Visible = "1";
      hovertime = "1000";
      lockMouse = "0";
      useWindowMouseEvents = "1";
      useObjectMouseEvents = "0";
   };
};
//--- OBJECT WRITE END ---

~/gameScripts/split.cs
function initSplitScreen(%level)
{
   if(isObject(splitScreenGui) && splitScreenGui.isVisible())
   {
      LeftSceneWindow.loadLevel(%level);
      RightSceneWindow.setSceneGraph(LeftSceneWindow.getSceneGraph());
      LeftSceneWindow.setCurrentCameraZoom(1);
      RightSceneWindow.setCurrentCameraZoom(1);
      LeftSceneWindow.setCurrentCameraArea(-512, -384, 0, 384);
      RightSceneWindow.setCurrentCameraArea(0, -384, 512, 384);
      
      
      // DEBUG CODE
      LeftSceneWindow.mount(fish1, 0, 0, 0, true);
      RightSceneWindow.mount(fish2, 0, 0, 0, true);
   } else { return; }
}

Modifies to the game.cs were also made, as follows;
function startGame(%level)
{
   // Set The GUI.
   exec("~/gui/splitScreen.gui");
   Canvas.setContent(splitScreenGui);
   Canvas.setCursor(DefaultCursor);

   moveMap.push();
   
   %levelToCheck = %level @ ".dso";
   
   if( isFile( %level ) || isFile( %level @ ".dso"))
   {
      if(isObject(splitScreenGui) && splitScreenGui.isVisible())
      {
         exec("./split.cs");
         initSplitScreen(%level);
      } else { sceneWindow2D.loadLevel(%level); }
   }
}


For my test, I created a simple level using the Fish Art provided with TGB, I dropped the water background onto the level and then placed two different fish objects -- named them Fish1 and Fish2 respectively, and used the following code to demo out my split-screen nature.

moveMap.bindCmd(keyboard, "a", "fishLeft(fish1, true);", "fishLeft(fish1, false);");
moveMap.bindCmd(keyboard, "d", "fishRight(fish1, true);", "fishRight(fish1, false);");

moveMap.bindCmd(keyboard, "left", "fishLeft(fish2, true);", "fishLeft(fish2, false);");
moveMap.bindCmd(keyboard, "right", "fishRight(fish2, true);", "fishRight(fish2, false);");


function fishLeft(%fish, %move)
{
   if(%move)
   {
      %fish.setLinearVelocityX(-30);
   } else { %fish.setLinearVelocityX(0); }
}

function fishRight(%fish, %move)
{
   if(%move)
   {
      %fish.setLinearVelocityX(30);
   } else { %fish.setLinearVelocityX(0); }
}

That code was, in my demo, just tossed at the bottom of the split.cs

What occurs? Well, when you play the level, the splitScreen.gui is loaded and then set to be the active Content window, which replaces the standard mainScreen.gui. The startGame function tests to see if splitScreenGui is an object, and if so, it calls the initSplitScreen() function and passes the level to load into it.

The splitScreenGui then simply loads the level into the LeftSceneWindow object and then the RightSceneWindow object makes a reference to the LeftSceneWindow objects SceneGraph, so they both share the same SceneGraph, but are independant of each other as far as the camera and other scenewindow events are concerned.

Here is a screenshot of the split functionality, not really the greatest thing as it's best to see 'in action'.

www.greatgamesexperiment.com/userimages/b/be9cc95d7586bcd3dd52c15f8f59fc20_o.jpg
And here is a link to a ZIP file that can be extracted into your TGB/games directory and used as a Startup Project type, TGB Split Screen Startup Kit.

In the kit, name your player objects "Player1" and "Player2" for the default ActionMap to notice them, you can fully edit the action.cs to however you like, but the splitScreen.cs should probably stay as is, unless you want to tweak the splitscreen action a bit more ...

The Startup Project has some tweaks to it, so the code and filenames do not match up identically.

UPDATE: Updated Template Project Download Link

#1
12/09/2006 (12:13 pm)
very nice, might use this in a future idea of mine. I was meanign to download TorqueX and have a peak at it since I do have a 360, sounds like it has some nice stuff to it
#2
12/09/2006 (12:17 pm)
Nice!
#3
12/09/2006 (12:44 pm)
This is way coolio. Nice work.
#4
12/09/2006 (1:24 pm)
Thanks.
#5
12/09/2006 (4:43 pm)
Nice work!
#6
12/09/2006 (6:02 pm)
yeah, i do something similiar for a mini-map.
#7
12/10/2006 (5:38 pm)
Wow, this looks fantastic! I've been working on a zoomable camera for multiplayer games, but I was actually just thinking today about adding split-screen support for when the camera zooms out too far, and was wondering how I might do it. Thanks so much!!! :) This is definitely the kind of thing that should go up on TDN.
#8
12/10/2006 (6:06 pm)
@Clint, I'm working on a TDN resource for this already -- just figured I'd post it up here now for giggles, and update it later when the TDN resource is available... I figured the TDN resource could go into a bit more detail, such as integrating the SceneWindows into a nice layout, and/or changing Left/Right to Top/Bottom through code, etc -- when I first started on this, I was going to try to make it just a TorqueScript file you exec()'d and let it create the duplicate SceneWindow objects, etc for you, so you didn't have to load the splitScreen.gui and you could easily do 2-4-6-8 player split's, etc all through code ...

but that's a bit of a more complex thing, and takes more then 10 minutes to whip together and blog about ... so, here we are with the blog ... ;)

Also, does anyone know, when you write a TDN article, how to get it included in the TOC's ? I wrote an article for one of the wishlists, High Scores, and it's still listed as a wishlist and I can't edit the TOC to move it ... and I also wrote a resource on creating custom 'tools' (like the layer floater) but can't figure out how to get them listed where people can see them easily ... *shrug* -- wrong place to ask, but eh, my days been long ...
#9
05/20/2008 (8:52 am)
U just saved my project =)
#10
05/20/2008 (11:36 pm)
glad to be of help :)