Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are some good posts in that forum on the topic of unit testing. Here's my personal approach to unit testing in XNA:</p> <ul> <li>Ignore the Draw() method</li> <li>Isolate complicated behavior in your own class methods</li> <li>Test the tricky stuff, don't sweat the rest</li> </ul> <p>Here's an example of a test to confirm that my Update method moves Entities the right distance between Update() calls. (I'm using <a href="http://en.wikipedia.org/wiki/NUnit" rel="nofollow noreferrer">NUnit</a>.) I trimmed out a couple lines with different move vectors, but you get the idea: you shouldn't need a Game to drive your tests.</p> <pre><code>[TestFixture] public class EntityTest { [Test] public void testMovement() { float speed = 1.0f; // units per second float updateDuration = 1.0f; // seconds Vector2 moveVector = new Vector2(0f, 1f); Vector2 originalPosition = new Vector2(8f, 12f); Entity entity = new Entity("testGuy"); entity.NextStep = moveVector; entity.Position = originalPosition; entity.Speed = speed; /*** Look ma, no Game! ***/ entity.Update(updateDuration); Vector2 moveVectorDirection = moveVector; moveVectorDirection.Normalize(); Vector2 expected = originalPosition + (speed * updateDuration * moveVectorDirection); float epsilon = 0.0001f; // using == on floats: bad idea Assert.Less(Math.Abs(expected.X - entity.Position.X), epsilon); Assert.Less(Math.Abs(expected.Y - entity.Position.Y), epsilon); } } </code></pre> <p>Edit: Some other notes from the comments:</p> <p><strong>My Entity Class</strong>: I chose to wrap all my game objects up in a centralized Entity class, that looks something like this:</p> <pre><code>public class Entity { public Vector2 Position { get; set; } public Drawable Drawable { get; set; } public void Update(double seconds) { // Entity Update logic... if (Drawable != null) { Drawable.Update(seconds); } } public void LoadContent(/* I forget the args */) { // Entity LoadContent logic... if (Drawable != null) { Drawable.LoadContent(seconds); } } } </code></pre> <p>This gives me a lot of flexibility to make subclasses of Entity (AIEntity, NonInteractiveEntity...) which probably override Update(). It also lets me subclass Drawable freely, without the hell of n^2 subclasses like <code>AnimatedSpriteAIEntity</code>, <code>ParticleEffectNonInteractiveEntity</code> and <code>AnimatedSpriteNoninteractiveEntity</code>. Instead, I can do this:</p> <pre><code>Entity torch = new NonInteractiveEntity(); torch.Drawable = new AnimatedSpriteDrawable("Animations\litTorch"); SomeGameScreen.AddEntity(torch); // let's say you can load an enemy AI script like this Entity enemy = new AIEntity("AIScritps\hostile"); enemy.Drawable = new AnimatedSpriteDrawable("Animations\ogre"); SomeGameScreen.AddEntity(enemy); </code></pre> <p><strong>My Drawable class</strong>: I have an abstract class from which all my drawn objects are derived. I chose an abstract class because some of the behavior will be shared. It'd be perfectly acceptable to define this as an <a href="http://msdn.microsoft.com/en-us/library/ms173156.aspx" rel="nofollow noreferrer">interface</a> instead, if that's not true of your code.</p> <pre><code>public abstract class Drawable { // my game is 2d, so I use a Point to draw... public Point Coordinates { get; set; } // But I usually store my game state in a Vector2, // so I need a convenient way to convert. If this // were an interface, I'd have to write this code everywhere public void SetPosition(Vector2 value) { Coordinates = new Point((int)value.X, (int)value.Y); } // This is overridden by subclasses like AnimatedSprite and ParticleEffect public abstract void Draw(SpriteBatch spriteBatch, Rectangle visibleArea); } </code></pre> <p>The subclasses define their own Draw logic. In your tank example, you could do a few things:</p> <ul> <li>Add a new entity for each bullet</li> <li>Make a TankEntity class which defines a List, and overrides Draw() to iterate over the Bullets (which define a Draw method of their own)</li> <li>Make a ListDrawable</li> </ul> <p>Here's an example implementation of ListDrawable, ignoring the question of how to manage the list itself.</p> <pre><code>public class ListDrawable : Drawable { private List&lt;Drawable&gt; Children; // ... public override void Draw(SpriteBatch spriteBatch, Rectangle visibleArea) { if (Children == null) { return; } foreach (Drawable child in children) { child.Draw(spriteBatch, visibleArea); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload