Spacecrash day 2 of 7: core gameplay
First thing: you want to start playing as soon as possible, to get a feel of the gameplay experience. It’s less important to have great sound & graphics feedback, you can easily imagine that. But you need the core control & game result. In this game, I’ve implemented crashing into obstacles and a life/energy bar as soon as possible. After that, it starts to be a game, since you can die!
One concern I have with this design is that, since content generation will be random, it will be quite difficult to control. I will try to use patterns and pattern sequencing to control this better (for example: define a level by sections, and manually control parameters controlling the random generation of each section). But still, you don’t have all control. To me, this means it’s better to make a game which is somewhat “forgiving”: crashing into an obstacle shouldn’t finish the game, since we won’t even be sure we won’t generate situations where it is impossible not to crash into something.
Here are the changes I have done in the basic support:
1) I added a function to normalize a vector in base.h:
2) I have added an “rgba” type to hold color, and a few functions to use random number generation more easily. Also, I’ve added extra parameters to the function that draws a rectangle with a given texture. See the changes in core.h:
Now, let me show you the new version of CORE_RenderCenteredSprite() and show it to you (the rest of core.cpp doesn’t change from yesterday’s version):
This function accepts two new parameters that the one yesterday didn’t. The first one, it accepts a color. We send this color over to OpenGL with the glColor4f() call, and what this does is it multiplies each color component of each pixel by the global color we have set (the color we are setting is 0.0 to 1.0 in each component). If we set color to all 1.0f, then this will not affect anything at all. But if we set all components to 0.5f, it will divide all R,G,B,A by half, and thus draw something darker (half as light), and also with alpha = 0.5, which is probably semi-transparent.
This parameter allows a very nice trick for drawing shadows: if you draw a sprite with color (0,0,0,0.5) (that is, RGB to 0 and alpha to 0.5), you will be drawing it completely black, but half transparent. If you draw this a few pixels below a sprite, it works as a cheap but cool shadow of the sprite, and it can help make the scene look much more integrated and solid.
The other parameter that this function accepts is a boolean saying whether it should be draw additively or not. It sets OpenGL’s blending function to use a different combination. What this does is it adds the pixel that is being drawing to whatever there is on the screen, rather than replacing it. So, wherever the image being painted is black, it won’t change anything (it’s adding 0 for all components), and all other colors will actually only “lighten” what there is behind. This is typically used for efects, overlays, etc… and we will use it for the energy bars and other effects down the road. Have a look at how the UI looks in additive form:
See how the two bars above look (the yellow one on the left is for energy, the blue one on the right is for fuel). They are drawn in “additive” mode, and thus it seems as if they “lighten” the background.
There are no more changes in the “core” code, all the rest are in game.cpp. Here is the list of things I have added today:
- Making rock obstacles float and move around a bit
- Detecting collisions between the rocks and the ship, and reacting a bit (rebound, energy)
- Inertia and controls for the main ship. Even if pixelated, the Tyrian graphics look cool!
- An UI with energy and fuel bars, and a bar of “pearls” to display your advance in the level (ugly yet!)
- A global “game state”, allowing the game to start, continue, and end whether with success or failure
- Entities project shadows on the floor now
- Added a “nice” effect to the succesful completion of the level
You will need to download a new set of graphics and copy them to the “data” subdirectory:
And here is the new game.cpp code that implements all the new functionality:
The game is in dire need of several things: adjusting collision boundaries, sound effects, nicer graphics and effects, more variety of game elements (shooting, collecting fuel, other obstacles…), and some gameplay balance so that playing is challenging in a more controlled fashion. Still in its current form, with the above parameters, I haven’t been able to beat the level (but I’m going to keep playing to see if I can get to the end!). Let me know how you fare yourself too! 🙂
The code above is not the cleanest, but it should be straightforward to understand. It needs improvements in organization, sprite management, etc… we’ll do so in the next few days. My main concern today was to get some gameplay out of this, and I’m starting to see some.
And here is a video clip from a gameplay session:
I’m happy for where we are on day 2, it’s starting to take shape. Hope you like it. Feel free to ask any questions regarding the things above, or anything at all. I’d also be happy to hear your thoughts about how the series is progressing and its instructional value, and how you think it could be improved.
And if you want to be notified when new articles to help you become a games developer are ready, just fill in the form below: