Asteroids, part 7

Turns out it wasn’t as difficult as I thought it would be. Granted, I made quick hacks rather than carefully plan out a more far-sighted approach. And so, I have completed a simple Asteroids-clone!

Here is the result; complete with scoring, hi-score, and asteroid-like feel:

asteroids_p7

Files

You can download the demo EXE from part 7’s folder here.

Reflection

Of course, this is an unpolished game that has room for a lot of improvement. Here are a list of things I could have done, but didn’t:

  • The ship spawns in the middle of the screen when it dies. If it “dies” in the middle, there is no “invincible” mechanism to prevent the ship from dying immediately after spawning.
  • The ship and rocks logically wrap around the edge, but visually only appear on one side of the screen.
  • There is no sound!

The next project shall be a revisit of Pong. But this time, I’ll be doing the following:

  • Object-oriented approach, better file/code separation
  • Add sound effect
  • 2-player mode

In the meantime, I’m going to try my hand at Famitracker to compose some music! The next weekend is something to look forward to.

Asteroids, part 6

I have added some quick collision detection code using the default SFML’s sf::Rect.intersects() method. It worked pretty well!

You can find the latest code in part 5 and 6 here. The only files I’ve updated were ivy_sprites.h and ivy_screens.h. You can find the other files in previous versions of the project. I’ve also included a demo EXE in the folder so that you don’t have to compile it. :)

The basic Asteroids mechanics are done! The next things to add are:

  • Gain score when asteroids are destroyed
  • Show and update the ship’s lives accordingly when hit by rock
  • When bullets hit a rock, depending on the size, split the rock into smaller versions

The last part sounds difficult because I have to dynamically spawn new smaller rocks when they’re destroyed. I’ll get to that eventually.

Asteroids, part 5

Today is Monday but it’s a holiday. I continue work on Asteroids clone.

The focus this time is the finish up the “enemy” of the game — the rocks. Here are some points I drafted while writing the code for the rocks:

  • There are 3 different sizes; small, medium, large
  • There are 3 different speeds, based on the sizes (a total of 3 x 3 combination of rock size/speed)
  • The size, speed and rotation direction are randomized

Because rocks inherit the base class’s movement code, I didn’t need to rewrite the screen-wrapping, movement and rotation logic. Phew!

asteroids_p5_1

This is the result after a few hours of tinkering; it was satisfying enough. There is a jarring problem with the result though, as seen in the screenshot above: The hitbox (red squares) are static. This means that it is possible to “hit” the rocks at the square edges even when it’s visibly rotated and logically should not cause collision.

I have decided to leave the “bug” alone. Rotating a hitbox is extra work, and calculating collision with rotated hitbox could possibly take longer time too.

Since the hitbox issue is ignored, the next task is to calculate collision. I’ll talk about it in the next update.

Asteroids, part 4

It is Saturday, so I resume work on the Asteroids clone. Today’s focus was on hitbox positioning, animation and bullet logic.

Hitbox

When a rock hits the ship, or when the bullet hits a rock, there needs to be a “believable” collision area for them. This area is known as hitbox. In most shmup games, the ship’s hitbox is usually pretty small;  The actual “body” of the ship that will cause it to explode upon collision is usually really small, as illustrated by the red square below:

asteroids_p4_1

I thought it was a reasonable size, but… the position seemed off. When I rotate it, it becomes:

asteroids_p4_3 asteroids_p4_2

… not centered at some angles, but looks ok in other angles. That’s because the hitbox begins from the ship’s center, but the origin is on top-left. So I had to make some minor adjustments by updating the hitbox position every update() cycle…

asteroids_p4_4

… and now it’s fixed! The hitbox is usually invisible and only used for collision logic, but I drew it out as a red box so I know which part of the ship’s body will actually cause it to explode.

The same methods should be applied to the bullets and rocks, although they will have different hitbox sizes.

Animation

For this simple game, the only thing I can think of animating is the bullet. I have a 2-frame animation of the bullet, so here is the flow of how I implemented animation:

main

  • In the spritesheet I used above, the starting position is at [40, 24] (40 pixels from left, 24 pixels from top).
  • The bullet size I’ve set is 4×4 pixels.
  • Keep track of which is the “starting frame” of the animation.
  • Keep track of how long the current frame has “displayed”.
  • After a certain amount of time has passed, cycle to next frame by offsetting the x-position by the bullet width.
  • Keep track of how many total frames there are, and loop to first frame if the last frame is reached.

As such, the first frame is at [40,24] and the 2nd frame is [44,24]. I have also made it animate at a rate of 5fps (5 frames per second). So every 200milliseconds, I will offset the sprite position so that it will display the next frame.

For a more thorough explanation of how frame animation works, you can read LazyFoo’s article. SDL Gamer’s article also talks about frame animation, but it is hard-coded. That means when you have more sprite animations, you need to edit more code to accommodate the changes.

Bullet

After all that, I finally managed to start working on bullet logic. Thanks to the generic code I used for the ship’s rotation and movement, I didn’t really need to add much code to the bullet class. All I needed to do was:

Keep track of which state the bullet is: READY or ACTIVE.

  • READY mean they’re not visible in screen, and ready to be used by the ship.
  • When the shoot key is pressed (e.g. Spacebar), get the ship’s current angle and apply it to the bullet, then set the state to ACTIVE
  • ACTIVE means the bullet is being shot, and is moving at a fixed speed/angle.
  • when the bullet has travelled a max distance, reset the state to READY
  • If max bullets have been shot (ACTIVE state), don’t shoot anymore (my current max is 6)

So then I have this as result!

asteroids_p4_5

Files

You can download the latest code sample from this link here.

Asteroids, part 3

I actually wrote part 2 last week and scheduled it to publish on the next day (September 1) but I mistakenly set the date to (October 1) which explains why it wasn’t published yet. :(

Anyway, I spent the whole Saturday today to continue work on Asteroids-clone project. Here are the list of things I did:

  • Used global constant variables for the menu highlight glow duration
  • Defined the math PI number
  • Moved the timer to main, making all time-crucial operations use the same variable through each loop.
  • Spent most of the day just figuring out how to move the ship

Movement

I took 6 hours just to figure out the basic movement for the ship. I have forgotten all my Trigonometry, so I had a lot of trial-and-error testing and studying math here and there. Here is the formula I came up with (variable names modified to make it readable in general context):


new_x  = origin.x + (destination.x - origin.x) * cos(-radians) + (destination.y - origin.y) * sin(-radians);

new_y  = origin.y + (destination.x - origin.x) * sin(-radians) + (destination.y - origin.y) * cos(-radians)

Granted, I have no idea what the formula does, but it worked eventually.

The resulting movement however, was wrong! I spent 6 hours doing the wrong thing. Here are a few things about the ship:

  • When the ship accelerates, it moves in the given direction
  • When the ship doesn’t accelerate, it still moves in the original trajectory because there is no friction in outer space
  • When the ship turns while not accelerating, it should still move in the original trajectory.
  • When the ship accelerates at a different direction, the original trajectory must be modified with the current movement to produce a NEW trajectory.

I was doing it wrong because the ship moves like a car, such that:

  • When the ship accelerates, in moves in the given direction
  • When the ship turns, regardless of acceleration, it moves in the new trajectory based on the turned angle

As such, whenever I turn my ship, its trajectory automatically changes (even though I didn’t accelerate anymore), which is not intended.

So I spent another few hours, and eventually came up with another formula. The rough idea is:

  • Have a variable that keeps track of the ship’s current trajectory
  • Make the ship’s rotation independent of the trajectory
  • Only when accelerating, take the current ship’s rotation, get a new trajectory, and add it to existing trajectory. In Trigonometry, it’s known as “adding two vectors”.

The formula above is re-used, but in a different way. It’s difficult to explain. Perhaps you can look into the source code and understand better.

Files

There are no screenshots for this post because it’s exactly the same as part 2, but now the ship has movement. However, in part 3, I have included the exe program! Just copy out the “Release” folder and you should be able to run the .exe inside. Don’t worry, there’s no viruses. I’m not that capable of writing malicious code. :P

You can find the project files in the repository here.

Asteroids, part 2

Despite the ample amount of time in the weekend, I couldn’t begin on the actual Asteroids-clone’s game logic yet. I have not filled in the logic for the Menu Screen, Score Screen. I also have not written code to transition between screens.

So, in this update, I have added the following code (rough description only):

  • Add variables to store current_score and high_score in “global.h”
  • Add Sprite base class
  • Add derived Sprite classes – for ship, bullet and rocks
  • Add logic for Main Menu Screen
  • Add logic for Game Over (Score Screen) Screen
  • Add loadResource methods for each Screen to initialize variables/resources before starting

I realized after a while, that I forgot to use structs. It could be useful in some cases, especially in returning an list of properties belonging to a particular Sprite. Perhaps I’ll modify it next time, but I’ll leave it as is for now.

Spritesheets

One thing I forgot to mention from previous projects is spritesheets. A good example is the Tic-Tac-Toe project I worked on, a few blog posts ago. I could have used one Image to represent the “X” and another image to represent the “O” icons. Instead, I used one spritesheet that contained all the images within the game. Then, using coding, I “clip” out a particular part of the image to be used.

Why are spritesheets useful? A good example is sprite animation. Imagine having a hero character that has the following states:

  • IDLE
  • RUN
  • WALK
  • JUMP
  • SHOOT

Now, imagine that each state has an animation of maybe… 3 frames each. Having them in separate files would mean ( 5 states x 3 frames = 15 images). Now multiply this by the amount of different characters in the game… and you’d probably have too many images to even know how to name the files.

For this blog post, however, I only used a spritesheet to store all the images for each object. There is no animation, thus there is almost no code to animate the images. I used TexturePacker Lite to compile the images into a compact spritesheet, it is an amazingly handy tool.

Conclusion

Now that I wrote a Sprite class that can be used to create/destroy game objects (ship, bullets, rocks), and completed the Screen Manager flow, I can finally begin writing the actual gameplay code for the Asteroids-clone. I also spent some time on making the images for the spritesheet. My next step is to begin coding the main game logic. I will discuss the design in the next part.

Screenshots

asteroids_p2_1

Files

You can get the latest project files from the Bitbucket Git repository here. The files can be found in the “asteroids_p2″ folder.

Asteroids, part 1

Yesterday was a holiday, so I thought I could start early on my next game attempt, an Asteroids clone. But, instead of copy-pasting the code from previous projects Pong/Tic-Tac-Toe, I decided to write the Screen Manager logic to allow me to dynamically add/remove screens in the future.

There is an older post here I wrote last month that linked to a sample of Game State Management for C# XNA Library. Instead of just talking about it, it’s best to learn by doing.

Design

The basic idea is to have Screen Manager object to handle the game screens for you. The manager should be able to do the following:

  • Add a new screen to a list of screens
  • Update each screen in the list
  • Draw each screen in the list
  • Remove a screen from the list of screens

Screens

Screens are game states that are logically separate from one another, but can be stacked on top of each other. Imagine a scenario where a game is paused:

  • There is a main screen that shows the actual game
  • There is a “pause” screen on top of the main screen that is semi-transparent, showing a “pause/resume” menu.
  • The main screen is visible — it is drawn but not updated.
  • The “pause” screen is visible and actively updated to show the menu’s highlight glow.

In the scenario above, there are two screens updating/drawing at the same time. When we unpause the game, the “pause” screen is deleted, then the main screen will resume updating.

How should the Screen Manager be able to freely manipulate a Screen? Here are some points:

  • A Screen should have a unique identifier, maybe an integer-based ID (so we can find and delete a screen easily).
  • Each screen has its own states, to list a few I used:
    • INIT
    • TRANSITION_IN
    • ACTIVE
    • INACTIVE
    • TRANSITION_OUT
    • DEAD
  • Each state will (optionally) handle update/draw differently. Example for a “Menu Screen” would be:
    • In INIT, we only load resources
    • In TRANSITION_IN, we only update the screen’s fade-in effect
    • In ACTIVE, we need to listen for keypresses, update the menu highlight, and highlight glow effect.
    • In DEAD, we tell the manager to delete the “Menu Screen”, then open a “Game Screen” after that.

In writing the Screen Manager, I have used some techniques absent from my previous two game projects:

  • Classes (object-oriented programming)
  • Derived classes (Inheritance)
  • Polymorphism
  • Vectors
  • Iterators

You can learn more about the above mentioned techniques from C++ Tutorials website. You can also read about vectors and iterators there.

Conclusion

Now that I have the Screen Manager set up, all I need to do is create new screens by deriving from a base “Screen” class, e.g. “Screen_Menu” and “Screen_Play”. In future updates, I can even add “Screen_Pause” or “Screen_Minigame” to handle different parts of the game.

I will begin writing the game logic for Asteroids in the next article, part 2. Because there is math involved (and I’m weak at math), it won’t take just 6 hours this time. :P

Files

You can get the latest project files from the Bitbucket Git repository here. The files can be found in the “asteroids_p1″ folder.

Pong

Today is a Sunday, and for most of the afternoon I had no plans. I didn’t want to procrastinate so I thought, maybe I can make another game! The next game was the classic Pong.

This time, I didn’t spend too much time on design. The flow is very similar to the previous project Tic-Tac-Toe; The Menu Screen and Score Screen is almost the same. The only big difference is the Game Screen.

Here are the differences between Tic-Tac-Toe and Pong:

  • Tic-Tac-Toe
    • Listens for UP/DOWN/LEFT/KEY press to navigate the board.
    • Listens for ENTER/RETURN key to pick a slot for “X” or “O”
    • Enemy AI just fills an empty slot whenever it sees one.
    • Game ends when either player wins, or when the board is full.
    • Only animate the highlighter icon
  • Pong
    • Listens for UP/DOWN press to move your pong slider.
    • If the game just started, the ball doesn’t move.
    • Listen for ENTER/RETURN key to start moving the ball.
    • Enemy AI follows the ball with a slightly slower speed than ball, so there is a chance for enemy to lose.
    • Game ends when the ball goes behind either player’s pong slider.
    • Need to update and animate the pong sliders and ball movement.

After I outlined the code changes I need to make for Pong, I started to…

Code

Here are the list of things I needed to do for the game logic in Pong:

  • If UP/DOWN key is pressed, move player’s pong slider up or down
  • If pong slider went outside the playing area, re-position the slider.
  • If the game hasn’t started…
    • If ENTER/RETURN key is pressed, set the game to “started”
  • If the game has started…
    • Update the position of the ball based on X/Y velocity
    • If the ball hit a pong slider, invert the X-velocity
    • If the ball hit the top/bottom side of the board, invert the Y-velocity
    • If the ball moves behind a pong slider, check who won the game
    • Update the enemy’s pong slider so that it follows the ball
    • Make the enemy’s movement slower so that there is a chance for player to win

Because the game’s code is very similar between Tic-Tac-Toe and Pong, I decided to throw in a new concept into the project, which is known as…

Namespace

Namespaces are like a container that distinguishes a section of your code from other parts of the code. To put in layman’s terms, if there is already a function called “getGameName()” written in another library, if I define my own “getGameName()” in the same scope, things may break. When you give the function a new scope, a.k.a. namespace, you can call the functions with the same name as long as they exist in different namespaces.

Example:

namespace foobar{
    int x = 10;
    int getGameName(){
        return "Foobar";
    }
}
namespace ivy{
    int x = 50;
    int getGameName(){
        return "Pong";
    }
}

int main(){
    foobar::getGameName(); // returns "Foobar"
    ivy::getGameName(); // returns "Pong"

    foobar::x; // returns 10
    ivy::x; // returns 50

    return 0;
}

The reason I like to use namespaces is that I can freely declare my own functions without ever having to worry if it conflicts with existing libraries. Or, if I ever write libraries that are mutually exclusive, then as long as they have different namespace, I don’t have to worry about accidentally writing functions with the same name.

A very common namespace is the STL (Standard Template Library)’s “std”. You may have seen something like this in the top of a C++ code:

#include <iostream>

int main(){
    std::cout << "Hello World";
    return 0;
}

OR

#include <iostream>
using namespace std;

int main(){
    cout << "Hello World";
    return 0;
}

In Pong, I used the namespace “ivy” to group my game’s code together. So whenever I need to use any game-specific code, I am forced to remember to use ivy::<variable> or ivy::<function name>. It also makes it easier for me to identify where the code belongs to.

More information on namespace can be found here.

Files

You can download the project’s code from the repository here.

Screenshots

pong_1 pong_2 pong_3

Tic Tac Toe

Being a programmer who is not proficient in C++ and has never made any games seriously, it was not easy to get started. I procrastinated on many occassions; but this weekend I managed to dedicate the whole day to writing a game as quickly as possible. My first game is Tic Tac Toe! It took about 6 hours to finish. When I started, I actually had difficulty in figuring out where to start. The first step in making a game is …

Design

I can’t make a game if I don’t know what the user experience flow is like. Since this is a quick game hack, I think of the most basic functions, with ZERO polishing. Here are what I could think of:

  • Start Screen
    • Show “Play Game” and “Exit” options.
    • “Play Game” goes to the Tic Tac Toe game.
    • “Exit” closes the program.
  • Game Screen
    • There are two turns – Player and AI.
    • Player starts first.
    • Navigate using arrow keys
    • Press ENTER/RETURN to place “X” or “O” on the slot.
    • Check if player has won the game.
    • If game isn’t over, switch to the other player.
    • If game is over, go to Score Screen.
  • Score Screen
    • Depending on who won, show the appropriate message.
    • Show “Replay” and “Back to Menu” options.
    • “Replay” goes back to Game Screen.
    • “Back to Menu” goes back to Menu Screen.

Now that we have a rough idea how the game will work, I started to…

Code

Since this is a quick unorganized hack, I wrote all the code in one file, “main.cpp”. I used SFML as my game library. I wanted to use SDL2 but I forgot to download it. This game was written with only Visual Studio 2010 and SFML library with its offline documentation. I had no internet access because I wasn’t at home. Hence, if I could write a game out without researching, it either means I’m just too pro (which I’m clearly not…) or the game is so simple that there’s no need for additional research. Please assume the latter.

There are only minimal code snippets below, just explain a rough idea of how I worked on the code. You can download the project files from the link at the end of this post. I separated the code into the following sections:

  1. Global variables
  2. Menu Screen functions
  3. Game Screen functions
  4. Score Screen functions
  5. Main function

Global variables

I wrote variables that were used solely for each Screen of the game. This is also where I load resources such as Texture (“X” and “O” spritesheet) and Font (I used georgia.ttf). For example, for the Menu Screen, I needed a variable to store the following:

  • Track which menu item I’m currently highlighting
  • Current menu item’s alpha value (I want to animate the glow effect)
  • Current menu item’s alpha direction (flag to indicate the highlight glow darker or brighter)

Main function

Before writing the other functions, the game loop needs to happen in the main body. Commonly, game loops are like this:

  1. Get key/mouse events
  2. Update variables
  3. Draw onto screen
  4. Repeat Step 1 ~ 3

Since we have 3 different screens (Menu, Game, Score), for each section, we need 3 different ways to handle it, as such:

while (window.isOpen())
    {
		// update game
		switch( state ){
		case Menu:
			update_menu( &window );
			break;
		case Game:
			update_game( &window );
			break;
		case Score:
			update_score( &window );
			break;
		case Quit:
			window.close();
			break;
		default:
			break;
		}

        // clear screen
        window.clear();

		// draw to screen
		switch( state ){
		case Menu:
			draw_menu( &window );
			break;
		case Game:
			draw_game( &window );
			break;
		case Score:
			draw_score( &window );
			break;
		default:
			break;
		}

        // render screen
        window.display();
    }

Menu Screen functions

  • Update
    • Get key events for UP, DOWN, ENTER only.
    • UP and DOWN keys will change the highlight position of the menu – “Start Game” and “Exit”
    • ENTER will execute the appropriate code based on which menu item is highlighted.
    • Every loop, animate the alpha value of the highlighted menu item to simulate a “glow” effect.
  • Draw
    • Draw the menu item text “Start Game” and “Exit”
    • Highlighted item – has glow effect, is RED color
    • Non-highlighted item – no glow effect, WHITE color

Game Screen functions

  • Update
    • Update the highlighter’s alpha value (to simulate glow effect)
    • If current turn is PLAYER:
      • Get key events for UP, DOWN, LEFT, RIGHT, ENTER
      • If keypress is UP/DOWN/LEFT/RIGHT, move the highlight position accordingly.
      • If keypress is ENTER, check:
        • If current slot is already filled with “X” or “O”, do nothing
        • If current slot is empty, fill it with “O” (player’s icon)
    • If current turn is AI:
      • NO artificial intelligence logic at all because it’s time-consuming.
      • For now, just pick an empty slot and fill it with “X”.
    • Check if either player won:
      • If either player wins, go to Score Screen and show “Win” or “Lose” message
      • If nobody wins this turn, do nothing
    • Check if all slots are filled:
      • If there’s still empty slots, do nothing
      • If all slots are filled, go to Score Screen and show “Stalemate” message
  • Draw
    • Draw each slot’s square position to indicate the tic-tac-toe’s game area
    • Check the game board data and draw “X” and “O” in the correct slots
    • Check the current highlight position and draw the highlight rectangle in the correct slot.

Score Screen functions (similar to Menu Screen)

  • Update
    • Get key events for UP, DOWN, ENTER only.
    • UP and DOWN keys will change the highlight position of the menu – “Start Game” and “Exit”
    • ENTER will execute the appropriate code based on which menu item is highlighted.
    • Every loop, animate the alpha value of the highlighted menu item to simulate a “glow” effect.
    • Set the score message based on the Win/Lose/Stalemate status from Game Screen.
  • Draw
    • Draw the menu item text “Start Game” and “Exit”
    • Highlighted item – has glow effect, is RED color
    • Non-highlighted item – no glow effect, WHITE color
    • Draw the score message, e.g. “You won!”

Now that I know what to do in each Update and Draw functions for each screen, I spent the next 5 hours coding!

Conclusion

Knowing what code to write is not as important as know how to write it. Therefore, design the game first! Plan out a list of tasks. Draw a flowchart if you want to visualize it better. Yes it’s a lot of work before you actually start coding… but it’s easier to code with a guideline than just doing it impromptu.

I only had one difficulty when writing this game in C++. I forgot how to declare arrays. YES it’s a very basic thing and yet I struggled with it. I was so used to Javascript’s way of creating arrays, that I forgot how C++’s arrays work.

You can download the project files from here. I included instructions on how to setup SFML for Microsoft Visual Studio 2010, and a small readme file in the project.

Screenshots

ss_tic_tac_toe_1

ss_tic_tac_toe_2

ss_tic_tac_toe_3

SDL2 is out!

SDL2 is out, and I can’t wait to try it out. I hope there’s ample documentation for it though.

Follow

Get every new post delivered to your Inbox.