Showing posts with label tips. Show all posts
Showing posts with label tips. Show all posts

Tuesday, June 15, 2010

TTF_RenderText_Solid is the devil

I added game state and gave the player a few lives, so Shmup01 FINALLY plays like a real game! There's still a lot of work to do, but one lovely thing I noticed is that, after the game is over, the process begins consuming approximately 12MB/second... given that the ENTIRE debug folder (exe, media, third party dlls) is just over 9MB total.... I found that to be absolutely insane.

Turns out that the SDL_TTF function TTF_RenderText_Solid is the culprit. My game over state basically said "keep on drawing the game over screen." Unfortunately, this included lines like this:

tempText = TTF_RenderText_Solid( font, "Final Score: ", textColor );
apply_surface( 350, 570, tempText, screen );

Every single call to TTF_RenderText_Solid was creating a brand new surface and assigning it to tempText. My faulty assumption was that the rendered surface only existed in the scope of assignment to tempText and then disappeared. This does not seem to be the case and it resulted in a heinous memory leak. For me, the solution was simply to have it render the text once instead of 30 times per second, but I could still see issues with regularly needing to update text on the screen (such as with scores or lives). I suppose you could pre-load a set of text surfaces (such as the single digit characters 0-9, etc), but that doesn't seem good either. I'm not sure if I'm missing something here or if I'm just running into limitations of SDL.

The good news is that I've been formulating some of the requirements for what Shmup02 will look like. There are still a couple gameplay bugs that I need to work out, but soon enough Shmup02 will be underway.

Sunday, June 13, 2010

Cleaning things up

Still no video, although I should be very close. I spent a lot of time cleaning things up and paving the way for smoother coding down the road. I haven't used any sort of revision control in the past, so I spent a lot of time learning about how it works and finding a good service. I ended up hosting my code for free on Assembla and using TortoiseSVN on the front end. So far, I'm very pleased with both of these products, and using version control in general! I'm amazed that I made it this far without using it.

I also spent a lot of time restructuring my inheritance hierarchy. Somehow, this led to a really nasty bug that has been in my code for a while but only surfaced after restructuring. Sometimes the program would crash AFTER I closed it, but the behavior was intermittent. The good news is that I became very good friends with Visual Studio's debugger. I still need to figure out where it debugs "from", as I could only get my game media to load if I used absolute paths instead of relative paths. The culprit ended up being a line in certain classes destructors:

GraphicalObject::~GraphicalObject()
{
SDL_FreeSurface( image );
}

I have no idea what SDL is doing when it frees surfaces, but I don't think my intuition was right in this case. My guess is that sometimes the program would try to access invalid memory or something as all the destructors were called (i.e. if a GraphicalObject frees an image that an EnemyShip is using as well, when the EnemyShip's destructor is called, there will be nothing to free).

I think I'm close to implementing the next set of features. Although I haven't made a ton of progress on the game in the last week and a half, I would say it has been extremely productive nonetheless.

Friday, May 28, 2010

Phase 5: Complete (???)

It looks like collision detection is working! I implemented the method mentioned in my last post (hint: ????? was a much more involved step than I thought it would be), and now when the playership fires bullets at the one enemyship on the screen, it registers as hits. Time for some extensive testing...

Also, time to do some SERIOUS code cleanup. I need to go back and finish phase 4 (give enemy ships the ability to fire), and then tie all 5 phases together into what would technically be a "working" prototype for the game. I'll also need to do some pretty basic things (set up boundary conditions for all of the game objects, figure out what the final function prototype is going to look like for the collision detection function, create a GameManager class and throw everything into it instead of in main(), etc). So, as simple as phase 4 will be, it probably wont be done for a little while.

RANDOM tip of the day: I noticed that when I moved my ship diagonally up-right, I could fire at the same time. However, when I moved diagonally in ANY other direction, I couldn't fire! The code that handles movement and firing is extremely simple, so I was pulling my hair out before I finally did a little googling and realized that.... certain keyboards have limitations to how many keys can be pressed at once in certain regions of the keyboard (not even kidding). Once I changed my "fire" button from Space to S, everything started working.

Tuesday, May 11, 2010

Phase 3: Complete

Phase 3 (adding enemy ships) took a little longer than planned.... mainly because I've been teaching myself object oriented design on the fly and had to rearrange my inheritance hierarchy a little bit to enable greater flexibility down the road.

Still, I can now throw enemies on the screen and the player can shoot at them. Granted, the bullets don't do anything, which brings me to my next point...

I'm skipping Phase 4 (enable the enemies to fire) and heading straight to Phase 5 (collision detection). The more I've been thinking about it, the more I realized how tough this could be. Short version of the story: If a bullet is travelling at 10 pixels per frame and the player's hitbox is 5 pixels, it is possible that bullet could jump right over the player in one frame! (I made a post about this on gamedev.net: http://www.gamedev.net/community/forums/topic.asp?topic_id=570333 )

In any case, between the suggestions made on gamedev.net and some collision detection articles I read, I've decided to go with something like this:

  • Assume every collision object is circular. Not ideal, but will work for now.
  • For each frame, calculate the relative velocity of two items (say, a ship and a bullet) by subtracting one motion vector from the other.
  • Now, all I'll have to do is see if this "relative velocity" vector ever get's too close to the ship (or bullet, depending on how I subtract the vectors). This will be done by...
  • Taking the inverse slope of the "relative velocity" vector
  • Use this slope and the position of the ship to determine the equation of the line perpendicular to the vector that passes through the point.
  • Find the intersection of this line with the relative velocity vector. This is the closest that the vector comes to the ship. Calculate this distance.
  • If this distance is less than the radius of the ship and the bullet, there's a collision
Disclaimer: I may be horribly misrepresenting the notion of a vector when I refer to the "relative velocity" vector. But hopefully the idea is clear. The idea is that I'll run through these steps for each pair of objects that need a collision check. Eventually, I'll add some code to minimize the number of checks that need to be made (but I'll save that for another post).

Time to post these ideas to gamedev and make sure they make sense!


Friday, May 7, 2010

Phase 2: Complete

I'm pleased (and surprised) to announce that phase 2 is already complete. Now the ship moves around AND fires bullets.

I'm finding one major challenge with writing graphic-driven programs is that debugging isn't as simple as writing a bunch of text to the screen every step of the way. While I could still write log files if I wanted to, I'm going to use this as an opportunity to learn how to properly use a debugger. I'm using Microsoft Visual C++ 2008 Express, so there's already a solid debugger at my disposal. So far, it's already helped me work my way through a couple of potentially nasty bugs with relative ease, so I'm definitely feeling good about deciding to use it!

On another note, for some reason whenever I tried to use an STL iterator, I would get a bizarre Linker error:

"...error LNK2019: unresolved external symbol __imp___CrtDbgReportW referenced in..."

It took a little Google-ing for me to find that I needed to remove the _DEBUG; entry from my project properties:

Alt+F7 (Project Properties)->Configuration Properties->C/C++->Preprocessor->Preprocessor Definitions

After deleting _DEBUG; from this entry, the program compiled and linked without issues.

Phase 3, here I come...