Learning Kyra: Hit Detection

The Learning Kyra series to date:

  1. Learning Kyra
  2. Learning More Kyra
  3. Learning Kyra: Attack of the Clones
  4. Learning Kyra: Tiles and Z-Ordering

I covered collision detection already, but it was in a limited capacity in Attack of the Clones. Basically, I checked if a sprite was colliding with a specific object. But what happens when I want to check for collisions with objects that have been added dynamically and prevent me from anticipating them at compile time?

The code below creates a number of sprites from the same resource. Kyra comes with the Grinning Lizard Utilities, so those are prefaced with Gl. I think that it makes it confusing if you want to mix your code with OpenGL, but whatever. One of the utilities is GlDynArray, which acts very much like the C++ Standard Library’s vector class. While it is in the provided demo code, I couldn’t find any mention of it in the documentation. I simply followed along with the demo in shooter.cpp. I created an array and added 10 ghost sprites to it. In the code below, MAX_GHOSTS is equal to 10. I also add those sprites to the tree.

KrSpriteResource* ghostRes = engine->Vault()->GetSpriteResource(GHOST_ghost);
GLASSERT( ghostRes );

KrSprite* ghost = new KrSprite( ghostRes );
ghost->SetPos( GHOST_START_X, GHOST_START_Y - 64);
engine->Tree()->AddNode( midgroundTree, ghost );

GlDynArray< KrImage* > otherGhost;
for (int i = 0; i < MAX_GHOSTS; ++i)
otherGhost.PushBack( new KrSprite( ghostRes ));
for (int i = 0; i < (int)otherGhost.Count(); ++i) {
otherGhost[i]->SetPos( GHOST_START_X, GHOST_START_Y );
engine->Tree()->AddNode( midgroundTree, otherGhost[i] );

So now I have a bunch of ghosts bunched up in the center, which is where GHOST_START_X, GHOST_START_Y sets them. I placed the player’s ghost about two tiles higher. Since I was going for simplicity, and I mostly hacked out this code without designing it first, I just made the sprites in otherGhost move around randomly. Another utility is GlRandom, which provides random number generators that are superior to rand() provided by C++. The following code demonstrates how I used it:

GlRandom random;

//the following is in the main loop
for (int i = 0; i < otherGhost.Count(); ++i) {

otherGhost[i]->SetPos( otherGhost[i]->X() + (random.Rand(3) - 1) * moveSpeed , otherGhost[i]->Y() + ( random.Rand(3) - 1) * moveSpeed);


So now each of the sprites in otherGhost move in random directions. I move the original ghost much the same way as I moved my clone sprite in previous Learning Kyra entry. Well, there is movement for the player and other objects, but what about collision?

if (engine->Tree()->CheckSiblingCollision(ghost, &hit, 0) ) {
for (int i = 0; i < (int)hit.Count(); ++i) {
int j = otherGhost.Find(hit[i]);
if (otherGhost.Count() < 1 )
done = true;

Very simply, if the main ghost collides with any of the other ghosts, those ghosts disappear. When the last one disappears, the main loop ends, and since I hacked this out instead of designing it, so does the program. Still, it is game-like. I experimented with other options to see what else I could do.

Instead of removing the ghosts from the tree, you could make them stationary, sort of like in Freeze Tag. As they get hit, I remove them from the otherGhost vector to keep them from moving about, but I also added the following to fade them a bit:

KrColorTransform color = hit[i]->CTransform( 0 );
color.SetAlpha( 50 );
hit[i]->SetColor(color, 0);

While it isn’t fun or polished in any way, I don’t think I can expect too much more from this specific project, at least not without struggling through painful changes. I didn’t set specific goals so the project simply evolved. I’ll consider this project complete and move on to a new project that will benefit from my new experience and some better design. You can download the project as it stands from one of the links below:

Kyra Source in .tar.gz format
Kyra Source in .zip format

NOTE: You will need Kyra v2.0.7 to use this code. Also, the comments in the code weren’t all updated to reflect the fact that I’ve changed it. It is licensed under the GPL or LGPL as specified.