CategoryXNA

Down into the SceneGraph hole

Ok, this gonna be a very long post. This is my SceneGraph implementation, or, at least the most important parts of it. I thought it would be nice to share it with the world (and hear you scream, though), so let’s start with some code!

public abstract class ISceneNode
{
#region Members

private ISceneNode _parent = null;

#endregion Members

public ISceneNode()
{
}

#region Methods

public void Update(GameTime gameTime)
{
if (!IsActive)
return;

BeforeUpdate(gameTime);

int count = Children.Nodes.Count;
for (int i = 0; i != count; ++i)
Children.Nodes[i].Update(gameTime);

AfterUpdate(gameTime);
}

#endregion Methods

#region Interface

protected virtual void BeforeUpdate(GameTime gameTime) { }
protected virtual void AfterUpdate(GameTime gameTime) { }

#endregion Interface

#region Properties

public ISceneNode Parent { get { return _parent; } internal set { _parent = value; } }

internal SceneNodeCollection Children = new SceneNodeCollection();

public bool IsActive = true;

#endregion Properties
}

 

This is fairly standard, so I won’t talk much about it. What I think is worth notice is the SceneNodeCollection Children, marked as internal. My intention was to not allow people to add/remove nodes freely from another node, but use the SceneGraphService (I’ll show that later) for this job. Here’s the implementation of SceneNodeCollection:

public class SceneNodeCollection : IEnumerable<ISceneNode>
{
internal List<ISceneNode> Nodes = new List<ISceneNode>();

public IEnumerator<ISceneNode> GetEnumerator()
{
return Nodes.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return Nodes.GetEnumerator();
}
}

As you can see, it inherits fromIEnumerableto allow foreach and nothing more. Now the juicy part, the SceneGraphService. It’s a GameComponent that implements this interface:
public interface ISceneGraphService
{
void AddNode(ISceneNode node, ISceneNode parent);
void RemoveNode(ISceneNode node);
ISceneNode Root { get; }
}

SceneGraphService is added to the Services collection and to the Components collection of the Game at the very beginning, and is used to handle all the entities in the game (player, enemies, lights, bullets, whatever). I usually use a “Level” class as the root and then build the whole three using ISceneNodes as collections to group entities when needed (for example, to keep togheter a group of enemy ships). Here’s the code:

public class SceneGraphService : GameComponent, ISceneGraphService
{
#region Members

private ISceneNode _root = null;
private Dictionary<string, ISceneNode> _nodes = null;

#endregion Members

public SceneGraphService(Game game)
: base(game)
{
_nodes = new Dictionary<string, ISceneNode>();

game.Services.AddService(typeof(ISceneGraphService), this);
}

#region Methods

public override void Update(GameTime gameTime)
{
if (null != _root)
_root.Update(gameTime);
}

public void AddNode(ISceneNode node, ISceneNode parent)
{
if (null != node.Parent)
RemoveNodeFromParent(node);

if (null == parent)
{
if (null != Root)
throw new Exception(“Unable to add another root”);
_root = node;
}
else
{
node.Parent = parent;
parent.Children.Nodes.Add(node);
}
}

public void RemoveNode(ISceneNode node)
{
if (null != node.Parent)
{
RemoveNodeFromParent(node);
}
else if (node == _root)
_root = null;
}

private void RemoveNodeFromParent(ISceneNode node)
{
node.Parent.Children.Nodes.Remove(node);
node.Parent = null;
}

#endregion Methods

#region Properties

public ISceneNode Root { get { return _root; } }

#endregion Properties

 

Next step: Component Based Entities!

Xong…Xong…Xong…

Due to a lack of time (and of a good modeler), I started working on a 2d engine..but this time with adifferent approach.

So, which is for you the best starting point? I’m pretty sure many of you will answer “Tetris!”, but for me is..Pong!
I’m using XNA, so the natural choice for the name is Xong, but whatever…these are the results:

screen1

screen2

As you can see, I tryied to keep the old-style-look, all the “so-called-graphics” are dynamically created, no files are used (well, except the fonts).

It took me 3 days of work: 1 day to write a good basecode, an input manager and putting all into a sligthly modified version of the wonderful Xna Game State Manager.
1 day to write the necessary classes, ball response and AI.
And… another day to play with my 7-years-old cousine 😀

It was really funny to realize that a child doesn’t see the difference from a game made in few hours and a AAA title. She just played, and enjoyed it.

Next stop: Snakex!

Engine updates

Finally I did it! After a lot of reading and coding, I managed to finish a nice deferred renderer. Actually it’s just an XNA demo, but I’ll try to replicate the changes also in the Phoenix Engine.
For now, here’s a small preview of what I’ve accomplished :

deferred1 deferred2

© 2019 Davide Guida

Theme by Anders NorenUp ↑