My self-imposed deadline is this weekend, so I'm almost out of time. I've learned a lot and managed to make a significant amount of progress on my project. My "engine" isn't complete or even ready to make a respectable game, but it should work just fine for the prototypes I'll be working on. I'm going to continue developing the engine as I experiment with gameplay using Box2d. I'm not giving up on Saga City, I just want to experiment with the physics and find something fun. Controlling the character so far has been no fun. I've been reading every list of game design tips and commandments that I can find. I've been reading the old "How to Prototype" article on Gamasutra and I want to start prototyping in quick intervals.
I've implemented my resource loader and I have my Ogg Vorbis music streamer sort of working. I know I said I'd have explosion shots, but I've done a bunch of other things instead. I'm going to stop declaring what I'll have done because I never do what I'm supposed to anyway. I'm still trying to figure out how to render the explosions.. Its more complicated than a single sprite animation for sure.
I can nudge objects in the editor to line them up by using the arrow keys, like in photoshop. I still need to make objects snap to the same resolution when dragged, like 1/100th of a unit or something. Actually, matching the snap resolution to the pixel density of the layer seems like an ideal solution.
The button "Create from Data" in the Sprite editor actually works now. It takes the text data file that my sprite renderer generates and creates the XML entity file. By default, it creates an 'action' from each sequence in the sprite data file. Hand-editing is still necessary for anything more complex than a single sequence.
Hitting 'r' and 't' cycle through the actions of the selected entity. I can now put a bunch of background images in a sprite sheet and cycle though the images (as actions) in a single entity while in the editor. I already have Ctrl-drag clone entities, so creating tiled backgrounds with variations is quick.
I now have my own custom resource files. I used this and this article to learn how. I altered the pak file creation code to use the stdio library instead of the (I'm assuming C) _open, _seek functions that use file descriptors. The C code to load the resources from the file caused heap corruptions, but the standard library worked like a charm.
There's an article at DevMaster on how to stream Ogg files using OpenAL. I followed the article and the follow-up corrections in the forum, but there's still some skipping and looping issues to deal with. I can use Ogg and Wavs now, and retrieve them from the resource files. Loading Ogg files from memory is explained in this article, also at DevMaster.
- figured out why v-sync made my sprite animations choppy: I still had the accumulator cutting updates into discrete timesteps. Doh! Mouse movement is still choppy with v-sync on. I don't know why yet.
There's now a turret enemy that tracks the player's movement within a radius and shoots constantly. The turret is two parts: the base and the cannon. The base is a static body, and the cannon is dynamic and connected with a revolute joint. I use the revolute joint's motor to close the gap between the joint's current angle and the target angle. Doing this meant taking the vector from the turret's position to the player, and converting it to an angle for use with Box2d. My weapon system takes a vector for aiming, but I can't use the target vector, I have to take the joint's current angle and convert it back to a vector to get the correct firing vector.
Here's the turret's update code:
void turret::onUpdate( ulong dT )
for( int i=0; i < goodGuys->size(); ++i )
aimVec = vec2((*goodGuys)->getPosition()) - current_state.pos;
if( aimVec.magnitude() < 30.0f )
// the vector in the dot operation must align w/ the "zero" position of the sprite
targetAngle = acosf( aimVec.dot( vec2(1,0) ) );
targetAngle = ( aimVec.y <= 0 )? targetAngle : -targetAngle;
pivotAngle = gunJoint->GetJointAngle();
float dif = targetAngle - pivotAngle;
/*if( dif < -PI ) // I'm not sure if this is necessary, or if box2d automatically adjust the joint angle
dif += 2.0f*PI;
if( dif > PI )
dif -= 2.0f*PI;*/
gunJoint->SetMotorSpeed( dif * 5.0f ); // speed up the turret a bit
if( shotTime <= 0 )
shotTime = 800;
// convert the joint's actual angle into a vector for the weapon system
vec2 bodyVec( sinf(pivotAngle + (PI/2.0f)), cosf(pivotAngle + (PI/2.0f)) );
vec2 origin = GetPivotPosition( "gunPivot" ) + bodyVec * 1.75f;
weaponSystem->Fire( world, WEAPON_BLASTER, origin, bodyVec * 2.0f, 0, CP_HOSTILE );
shotTime -= dT;
Sprite::onUpdate( dT );
The way the turret receives the array of possible targets is through a static vector given from the level class. It's ugly, and temporary, but it will have to do until I can figure out a better way.
I just need to make TinyXml work with loading resources from memory so my level, entity, and gui data files can be parsed. Once that's done, I'll post a demo. Its still not a game, but its becoming more playable. Now that I have a framework to use, I want to start making rapid prototypes with Box2d (time-permitting). I also have plans to use Doxygen and write a proper explanation for each part of the engine. Doing this would probably be more beneficial for me than anyone, helping me understand where I can improve things, and documenting my progress.
Oh, I turn 23 tomorrow! Its been a full year since I began this project... I haven't made the progress I would have liked, so I need to hit the gas and start producing playable demos. Its going to be tough to more productive while its glorious and sunny outside!