Previous Blog Next Blog
Prev/Next Blog
by date

Saving Games in TorqueX, on your 360 or PC

Saving Games in TorqueX, on your 360 or PC
Name:Will O*Reagan 
Date Posted:Jun 23, 2007
Rating:4.3 out of 5
Public:YES
Comments:YES
RSS Feed:GarageGames Blog feedor Subscribe with .
Profile Page:View profile page for Will O*Reagan

Blog post
This quick and dirty sample of how to get save game features working on your XBox and PC.

First Open a StarterGame, find your game.cs, and make your begin run look like this

 protected override void BeginRun()
{
base.BeginRun();


#if XBOX360
//Create an XboxStorage Device Object, that will keep track of our Device, and make sure it does what we want.
XboxStorageDevice myXboxStorage = new XboxStorageDevice();
//Name it, so we can find it in code using the TorqueObjectDatabase
myXboxStorage.Name = "MyXboxStorage";
//Give it a tick, so it can fire off saves and loads, after the device has been found.
ProcessList.Instance.AddTickCallback(myXboxStorage);

#endif


//Load our Scene, just a single ggPlayerObject, offscreen, with no velocity or anything.
//(just apply to it a world Limit and "Rigid Physics" for world Limit Collision Resolution)
SceneLoader.Load(@"data\levels\levelData.txscene");
//Create Our Save LoadObject
SaveLoad _saveLoad = new SaveLoad();
//name the object, so we can find it using the TorqueObjectDatabase
_saveLoad.Name = "SaveLoad";
//Activate an input map, so it can load and unload our game as well as move our "player buddy" around
_saveLoad._SetupInputMap(_saveLoad, 0, "gamepad" + 0, "keyboard");
//Load Initial Data, so we can have the option of loading a "New Game"
_saveLoad._loadInitialData();
//Give it a tick callback, so it can move our "player buddy" around
ProcessList.Instance.AddTickCallback(_saveLoad);
}



Grab your movement component, and cut out all the _sceneObject stuff, including the on Register method, unregister, etc, make it look like this...


using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

using GarageGames.Torque.Core;
using GarageGames.Torque.T2D;
using GarageGames.Torque.Sim;
using GarageGames.Torque.Platform;

namespace StarterGame
{
//Note, we have changed "TorqueComponent" to "TorqueObject"
public class SaveLoad : TorqueObject, ITickObject
{
//======================================================
#region Constructors
#endregion

//======================================================
#region Public properties, operators, constants, and enums

#endregion

//======================================================
#region Public Methods
public void InterpolateTick(float k)
{
}

public void ProcessTick(Move move, float elapsed)
{
if (_player != null)
{

if (move != null)
{
if (move.Sticks[0].X > 0)
_player.Physics.VelocityX += 1;
if (move.Sticks[0].X < 0)
_player.Physics.VelocityX -= 1;
if (move.Sticks[0].Y > 0)
_player.Physics.VelocityY += 1;
if (move.Sticks[0].Y < 0)
_player.Physics.VelocityY -= 1;
}
}

}
public void _saveGame()
{

StorageSystem storageSystem = new StorageSystem();
StorageSystem.PlayerData playerData = new StorageSystem.PlayerData();
_player = (T2DSceneObject)TorqueObjectDatabase.Instance.FindObject("ggPlayer");
if (_player != null)
{
playerData.AngularVelocity = _player.Physics.AngularVelocity;
playerData.Rotation = _player.Rotation;
playerData.Velocity = _player.Physics.Velocity;
playerData.position = _player.Position;
storageSystem.SavePlayerData(playerData, "ExpertSaveSample", "SavedGame.vrd");
}


}
public void _loadSavedGame()
{
StorageSystem storageSystem = new StorageSystem();
StorageSystem.PlayerData loadPlayerData = new StorageSystem.PlayerData();
loadPlayerData = storageSystem.LoadPlayerData("ExpertSaveSample", "SavedGame.vrd");
if (loadPlayerData.Velocity != null)
{
T2DSceneObject _oldPlayer = (T2DSceneObject)TorqueObjectDatabase.Instance.FindObject("ggPlayer");
_oldPlayer.MarkForDelete = true;
_player = (T2DSceneObject)(TorqueObjectDatabase.Instance.FindObject("ggPlayerObject") as T2DSceneObject).Clone();
TorqueObjectDatabase.Instance.Register(_player);
_player.Name = "ggPlayer";
_player.Position = loadPlayerData.position;
_player.Rotation = loadPlayerData.Rotation;
_player.Physics.AngularVelocity = loadPlayerData.AngularVelocity;
_player.Physics.Velocity = loadPlayerData.Velocity;
}

}
public void _loadNewGame()
{
StorageSystem storageSystem = new StorageSystem();
StorageSystem.PlayerData loadPlayerData = new StorageSystem.PlayerData();
loadPlayerData = storageSystem.LoadPlayerData("ExpertSaveSample", "NewGame.vrd");
T2DSceneObject _oldPlayer = (T2DSceneObject)TorqueObjectDatabase.Instance.FindObject("ggPlayer");
if (_oldPlayer != null)
{
_oldPlayer.MarkForDelete = true;
}
_player = (T2DSceneObject)(TorqueObjectDatabase.Instance.FindObject("ggPlayerObject") as T2DSceneObject).Clone();
TorqueObjectDatabase.Instance.Register(_player);
_player.Name = "ggPlayer";
_player.Position = loadPlayerData.position;
_player.Rotation = loadPlayerData.Rotation;
_player.Physics.AngularVelocity = loadPlayerData.AngularVelocity;
_player.Physics.Velocity = loadPlayerData.Velocity;

}
public void _loadInitialData()
{
StorageSystem storageSystem = new StorageSystem();
StorageSystem.PlayerData playerData = new StorageSystem.PlayerData();
playerData.Velocity = new Vector2(0, 0);
playerData.position = new Vector2(0, 0);
playerData.AngularVelocity = 0;
playerData.Rotation = 0;
storageSystem.SavePlayerData(playerData, "ExpertSaveSample", "NewGame.vrd");
}
#endregion

//======================================================
#region Private, protected, internal methods


void _OnBackButton(float val)
{
if (val > 0.0f)
Game.Instance.Exit();
}


public void _SetupInputMap(TorqueObject player, int playerIndex, String gamePad, String keyboard)
{
// Set player as the controllable object
PlayerManager.Instance.GetPlayer(playerIndex).ControlObject = player;

// Get input map for this player and configure it
InputMap inputMap = PlayerManager.Instance.GetPlayer(playerIndex).InputMap;

int gamepadId = InputManager.Instance.FindDevice(gamePad);
if (gamepadId >= 0)
{
inputMap.BindMove(gamepadId, (int)XGamePadDevice.GamePadObjects.LeftThumbX, MoveMapTypes.StickAnalogHorizontal, 0);
inputMap.BindMove(gamepadId, (int)XGamePadDevice.GamePadObjects.LeftThumbY, MoveMapTypes.StickAnalogVertical, 0);
inputMap.BindAction(gamepadId, (int)XGamePadDevice.GamePadObjects.Back, _OnBackButton);
inputMap.BindCommand(gamepadId, (int)XGamePadDevice.GamePadObjects.A, null, _saveGame);
inputMap.BindCommand(gamepadId, (int)XGamePadDevice.GamePadObjects.X, null, _loadNewGame);
inputMap.BindCommand(gamepadId, (int)XGamePadDevice.GamePadObjects.Y, null, _loadSavedGame);
}

// keyboard controls
int keyboardId = InputManager.Instance.FindDevice(keyboard);
if (keyboardId >= 0)
{
//sorry, no keyboard commands yet
}
}
#endregion

//======================================================
#region Private, protected, internal fields
T2DSceneObject _player;
#endregion
}
}


Next, open up your "levelData" in your TXB editor. Remove the movement component if its not gone already. Drag the gg logo outside the viewable area. Mark it as a template. Give it a WorldLimit, and apply rigid physics so we can get some angular velocity on our bounces. (Remeber to size the world limit to the size of your screen/camera), (so we can see whats going on!) Name it "ggPlayerObject".

Finally, Create two new classes, with the following code in each.


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;


using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using GarageGames.Torque.Core;
using GarageGames.Torque.T2D;
using GarageGames.Torque.Sim;
using GarageGames.Torque.Platform;

namespace StarterGame
{
class XboxStorageDevice : TorqueObject, ITickObject
{
#region Constructors
#endregion
#region Public properties, operators, constants, and enums
public bool DeviceFound
{
get { return _deviceFound; }
set { _deviceFound = value; }
}
public StorageDevice Device
{
get { return device; }
set { device = value; }
}
#endregion
#region Public Methods
public void InterpolateTick(float k)
{
}
public void ProcessTick(Move move, float elapsed)
{
if (_savePending && _deviceFound != true)
{
if (result != null)
{
if (result.IsCompleted)
{
device = StorageDevice.EndShowStorageDeviceGuide(result);
if (device.IsConnected)
{
_deviceFound = true;
_savePending = false;
StorageSystem storageSystem = new StorageSystem();
storageSystem.SavePlayerData(_playerData, _containerName, _filename);
}
}
}
}
if (_loadPending && _deviceFound != true)
{
if (result != null)
{
if (result.IsCompleted)
{
device = StorageDevice.EndShowStorageDeviceGuide(result);
if (device.IsConnected)
{
_deviceFound = true;
_loadPending = false;
SaveLoad _saveLoad = (SaveLoad)TorqueObjectDatabase.Instance.FindObject("SaveLoad");
if (_filename == "NewGame.vrd")
_saveLoad._loadNewGame();
else if (_filename == "SavedGame.vrd")
_saveLoad._loadSavedGame();
}
}
}
}
}
public void FindDeviceAndAttemptSave(StarterGame.StorageSystem.PlayerData playerData, string containerName, string filename)
{
_savePending = true;
_playerData = playerData;
_containerName = containerName;
_filename = filename;
result = StorageDevice.BeginShowStorageDeviceGuide(PlayerIndex.One, null, null);

}
public void FindDeviceAndAttemptLoad(string containerName, string filename)
{
_loadPending = true;
_containerName = containerName;
_filename = filename;
result = StorageDevice.BeginShowStorageDeviceGuide(PlayerIndex.One, null, null);

}
#endregion
#region Private, protected, internal methods
#endregion
#region Private, protected, internal fields
bool _deviceFound = false;
StorageDevice device;
IAsyncResult result;
string _containerName = "";
StarterGame.StorageSystem.PlayerData _playerData;
string _filename = "";
bool _savePending = false;
bool _loadPending = false;
#endregion
}
}



using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

using GarageGames.Torque.Core;
using GarageGames.Torque.T2D;
using GarageGames.Torque.Sim;
using GarageGames.Torque.Platform;


using System.IO;
using System.Xml.Serialization;

namespace StarterGame
{
public class StorageSystem
{
[Serializable]
public struct PlayerData
{
//Assign all relevent data, so we can update our game accurately
public float AngularVelocity;
public float Rotation;
public Vector2 position;
public Vector2 Velocity;
}
public void SavePlayerData(PlayerData playerData, string containerName, string fileName)
{

#if XBOX360
XboxStorageDevice _xboxStorage = (XboxStorageDevice)TorqueObjectDatabase.Instance.FindObject("MyXboxStorage");
if (_xboxStorage.DeviceFound != true)
{
_xboxStorage.FindDeviceAndAttemptSave(playerData, containerName, fileName);
}
else
{
StorageDevice device = _xboxStorage.Device;
// Open a storage container
StorageContainer container = device.OpenContainer(containerName);
// Get the path of the save game
string tempFileName = Path.Combine(container.Path, fileName);
// Open the file, creating it if necessary
FileStream stream = File.Open(tempFileName, FileMode.OpenOrCreate);
// Convert the object to XML data and put it in the stream
XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
serializer.Serialize(stream, playerData);
// Close the file
stream.Close();
// Dispose the container, to commit changes
container.Dispose();
}
#endif
#if !XBOX360
StorageDevice device = StorageDevice.ShowStorageDeviceGuide();
// Open a storage container
StorageContainer container = device.OpenContainer(containerName);
// Get the path of the save game
string tempFileName = Path.Combine(container.Path, fileName);
// Open the file, creating it if necessary
FileStream stream = File.Open(tempFileName, FileMode.OpenOrCreate);
// Convert the object to XML data and put it in the stream
XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
serializer.Serialize(stream, playerData);
// Close the file
stream.Close();
// Dispose the container, to commit changes
container.Dispose();
#endif

}
public PlayerData LoadPlayerData(string containerName, string fileName)
{
PlayerData playerData = new PlayerData();
#if XBOX360
XboxStorageDevice _xboxStorage = (XboxStorageDevice)TorqueObjectDatabase.Instance.FindObject("MyXboxStorage");
StorageDevice device = _xboxStorage.Device;
#endif
#if !XBOX360
StorageDevice device = StorageDevice.ShowStorageDeviceGuide();
#endif
// Open a storage container
StorageContainer container = device.OpenContainer(containerName);
// Get the path of the save game
string tempFileName = Path.Combine(container.Path, fileName);
// Check to see if the save exists
if (!File.Exists(tempFileName))
// Notify the user there is no save
return playerData;
// Open the file
FileStream stream = File.Open(tempFileName, FileMode.OpenOrCreate, FileAccess.Read);
// Read the data from the file
XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
playerData = (PlayerData)serializer.Deserialize(stream);
// Close the file
stream.Close();
// Dispose the container
container.Dispose();
return playerData;
}

}

}


That should pretty much do it. Dont forget to add a reference to System.XML in your game.

My references, were mostly taken from the GSE Help, Contents. Check under Programming Guide, Storage.

Also...(http://www.virtualrealm.com.au/blogs/mykre/archive/2007/05/06/xna-storage-the-beginning.aspx)

And of course, the GG TX forums

You can save and load all 4 properties of the GG Logo, accross multiple games and loads on your XBox or PC. Now I'm going to go put this in MY game..

enjoy,

Heres a Sample Picture of what it might look like..


edit: removed dead links

Recent Blog Posts
List:02/29/08 - New prototype
12/15/07 - TorqueX brain recovery
07/20/07 - *Free* Sticker, MMI, *Free* Become involved with up and coming developement company
06/23/07 - Saving Games in TorqueX, on your 360 or PC
06/07/07 - A new overlay
03/01/07 - XNA game game studio express contest

Submit ResourceSubmit your own resources!

You must be a member and be logged in to either append comments or rate this resource.