03 May 2007

So, I went to the 'My Coke Fest' in Joburg. It was pretty cool. Hoobastank rocked ;) their lead singer looked like he couldn't have been more than 20; turns out the whole band is over 30 -- there's hope for us yet.

The picture (left) is of Hoobastank, with their lead singer standing on his box -- he was so tiny. Apparently he's Incubus' brother, which is kinda cool. They played some Bon Jovi and AC-DC to warm the crowd up for their no. 1 track, "The Reason". It was unexpected to hear an international act covering, but they pulled it off with style. Definitely the high-point of the 12-hour concert for me.

Posted on Thursday, May 03, 2007 by campey

No comments

Not only is Rocket Commander a pretty cool looking (but rather boring) MDX game with publicly available source, it turns out they've done a series of 10 30-minute video tutorials on the making of the game. Sweet.

Posted on Thursday, May 03, 2007 by campey

No comments

02 May 2007

So, I wanted to add substance to my craft. This was quite easy. I rearranged the points in the VertexBuffer into a list describing a triangle fan and fiddled to get that to work.

pointList_VB = new VertexBuffer(typeof(CustomVertex.PositionColored),
12, device,
Usage.Dynamic | Usage.WriteOnly,
CustomVertex.PositionColored.Format,
Pool.Default);

CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[12];

// Triangle #1

verts[0].Position = new Vector3(0.0f, 0.5f, 0.0f);
verts[0].Color = Color.Blue.ToArgb();

verts[1].Position = new Vector3(0.5f, -0.2f, 0.0f);
verts[1].Color = Color.Green.ToArgb();

verts[2].Position = new Vector3(0.0f, 0.0f, 0.2f);
verts[2].Color = Color.Orange.ToArgb();

verts[3].Position = new Vector3(-0.5f, -0.2f, 0.0f);
verts[3].Color = Color.Red.ToArgb();

verts[4].Position = new Vector3(0.0f, 0.0f, -0.2f);
verts[4].Color = Color.Yellow.ToArgb();

verts[5].Position = new Vector3(0.5f, -0.2f, 0.0f);
verts[5].Color = Color.Green.ToArgb();

Yawn. Then I appended some points to that list for a triangle list to close off the object.

verts[6].Position = new Vector3(-0.5f, -0.2f, 0.0f);
verts[6].Color = Color.Red.ToArgb();

verts[7].Position = new Vector3(0.5f, -0.2f, 0.0f);
verts[7].Color = Color.Green.ToArgb();

verts[8].Position = new Vector3(0.0f, 0.0f, -0.2f);
verts[8].Color = Color.Yellow.ToArgb();

verts[9].Position = new Vector3(-0.5f, -0.2f, 0.0f);
verts[9].Color = Color.Red.ToArgb();

verts[10].Position = new Vector3(0.5f, -0.2f, 0.0f);
verts[10].Color = Color.Green.ToArgb();

verts[11].Position = new Vector3(0.0f, 0.0f, 0.2f);
verts[11].Color = Color.Orange.ToArgb();

pointList_VB.SetData(verts, 0, LockFlags.None);

And then drawing it with indexed calls to my VB stream as follows.

d3dDevice.SetStreamSource(0, pointList_VB, 0);
d3dDevice.DrawPrimitives(PrimitiveType.PointList, 0, 7);
d3dDevice.Transform.World = Matrix.Multiply(
Matrix.RotationYawPitchRoll(Geometry.DegreeToRadian(p1.Rotation.X), Geometry.DegreeToRadian(p1.Rotation.Y), Geometry.DegreeToRadian(p1.Rotation.Z)),
Matrix.Translation(p1.Position.X, p1.Position.Y, 20.0f)
);
d3dDevice.DrawPrimitives(PrimitiveType.TriangleFan, 0, 5);
d3dDevice.DrawPrimitives(PrimitiveType.TriangleList, 6, 11);

Drawing it revealed to me that I'd got up & down confused on the y-rotation.. so after fixing that it was all solid.

And it looks something like this. (from a few viewpoints)



Really has to be seen in motion for full effect.

Posted on Wednesday, May 02, 2007 by campey

No comments

So, I had collected a lovely bunch of variables to track the position of the craft, looking something like this: (gotta love having your dev history in an SVN repo)
        private Vector3 p1rot;
private Vector3 p1rotInput;
private float p1rotForce;
public Vector3 Player1Rotation
{
get { return p1rot; }
set { p1rot = value; }
}
private Vector2 p1;
public Vector2 Player1Location
{
get { return p1; }
set { p1 = value; }
}
private Vector2 p1force;
private Vector2 p1spring;
private Vector2 p1grav;

And the time had come to move it out into an object. Which ended up looking like this:

class Player
{
private Vector2 _position;
private Vector2 _force;
private Vector3 _rotation;
private Vector3 _rotationInput;
private float _thrust;
private float _rotationForce;

public Vector2 Position
{
get { return _position; }
set { _position = value; }
}

.. blah blah properties. Thankfully we can use CTRL-R,E in Visual Studio to make a private variable into a public property; no mess, no fuss. There was also dome debate as to where to put the public properties w.r.t. their privates, I went with Turner and used the C++ style approach.

And I even gave the object its very own method to update it's internals. Lucky thing.

public void HandleInput(float dt)
{ ..blah.. }
}


This also meant that I can now make my property grid show only properties of Player p1.



Which is a lot more useful.

Also evident is the pretty point field I forgot to blog about; this is just a bunch of for loops adding the gravity vector at a point in the grid to the vector to that point.. the result is a point distorted by gravity.

Posted on Wednesday, May 02, 2007 by campey

No comments

01 May 2007

So, I demoed my game on battery power.. and it sucked. Interestingly whenever windows showed a tooltip, the game ran at full pelt.. something fishy there. But anyway, I introduced a Δt (delta t for the unicode (or greek) unaware) into my calculations. The first stumbling block was that I was using the tick counter, which sucks a bit. The thing is, even though it has damn good accuracy, it is only updated every now and then. Which is a bit odd. I managed to hack it into working by doing the following:

private void Physics()
{
    while (System.DateTime.Now.Ticks == Tick) { }
    //time interval
    long thisTick = System.DateTime.Now.Ticks;
    float dt = (Tick - thisTick) / 100000.0f;
    Tick = thisTick;
But that really feels dirty. All that hanging around waiting for the tick. - Spoon! So, anyways. After a bit of ferreting, I found the Coding4Fun: Beginning Game Development article I'd been reading, which contains a section "All about timers". In summary, I grabbed the dxmutmisc.cs file from the sample code (in DirectX SDK\Samples\Managed\Common), commented out everything but NativeMethods and FrameworkTimer, called FrameworkTimer.Start() before starting the Main loop, then did
private void Physics()
{
    dt = (float)(FrameworkTimer.GetElapsedTime()*1000);
to get the time interval since the last physics call. The *1000 is just to get the number into something I could count on my fingers-and-toes. And, with a little tweaking of cosmological constants, all was working again.

Posted on Tuesday, May 01, 2007 by campey

No comments

19 April 2007

I wanted to have my game panel run inside a splitter with a collapsible properties panel. This was quite easy to achieve, merely needing the changing of the handle that directX was pointing at. i.e. changing this:

d3dDevice = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, flags, d3dpp);

to this:

d3dDevice = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this.panel1, flags, d3dpp);


But-it-broke-my-game.

How? The OnKeyDown event doesn't percolate to parents. That truly sucks. Oddly the only key that does percolate is ALT+key which windows needed to get menu key-presses (ALT-F,X) -- ain't that just too hacky. The mechanism is there, but disabled to frustrate us.

I didn't really want my players to have to play while holding ALT ;) so I went and figured out how to use DirectInput, with the aid of Riemer's tutorial. And it just works. Quickly.

I'm polling the input from my main loop now, and compared to the handling of the OnKeyDown event I'm getting squagillions more keypresses. Needless to say ints became floats (Vector3s actually) rather quickly to handle the smaller iterations.

Other changes include having to have to input de-bounce. I do this by copying the previous state's keys and passing them into the next input parse.

private List Input(List laststate)
{
List seen = new List();
Vector3 rotationInput = new Vector3(0, 0, 0);
KeyboardState keys = keyb.GetCurrentKeyboardState();
if (keys[Key.Escape]) this.Dispose();
if (keys[Key.W]) rotationInput.Y++;
...
if (keys[Key.P] && !laststate.Contains(Key.P))
{
PropertyGridVisible = !PropertyGridVisible;
splitContainer1.Panel2Collapsed = !PropertyGridVisible;
OnResetDevice(d3dDevice, null);
}

...
return seen;
}

And in the main loop:

static void Main()
{ ...
using (Game grav = new Game())
{ ...
List laststate = new List();
while (grav.Created) { ...
laststate = grav.Input(laststate);
... }}}

The debouncer was necessary to do 'edge detection' on the squagillion keypresses that I was getting, e.g. to toggle the property pane once only. The extra call to OnResetDevice is to handle the change in FoV which is done based on the current size of the panel.



End of dev iteration.

Posted on Thursday, April 19, 2007 by campey

No comments

17 April 2007

Update: I'm using MDX, Rein's using XNA and Colin has joined us using GL.

My first deliverable was to have an object in a scene with tilt-to-steer and gravity.

This is done.



yay!

The object


The object is a triangle list primitive with a single triangle in it. Each vertex is differently coloured to help with orientation. It whizzes around quite satisfactorily with a simple spring function restoring it to zero-tilt, resulting in a max thrust of about 70deg.

Gravity


Gravity... sucks. Really.

Inverse r-squared explodes quite quickly near to the centre, I had great fun experimenting with my singularity-like point-source gravity and watching things magically teleport off into the far reaches of game-space, never to be seen again. Okay, maybe frustration as well as fun ;) .

Other things



  • I'm thinking of a few weapon types: a shotgun of low-damage point-bullets, thrust based rockets (possibly steerable).
  • Planets should bubble into their positioins from the deep below the playing surface, with a bouyant-spring effect upon arriving. The gravity field vis should ripple away from them as they arrive.
  • Thinking of indicating a planet's power charge by encasing the planet in a platonic solid, increasing/decreasing count to indicate power. Maybe CTF-style planet capturing? Perhaps charged planets repel craft.
  • Sitting in a gravity field charges the batteries in proportion to the strength of the field. See, in the future they've figured out how to generate power from gravity: It's a cunning arrangement of pulleys, levers, cats and buttered toast.

Posted on Tuesday, April 17, 2007 by campey

No comments