Skip to content
 

HEY LOOK!

Still got your sample project around from last week? Good. (If not, go back and make a new one – and hang on to it this time.) We’re going to make our very first steps toward building our Space Invaders game – we’re going to draw something on the screen. Granted, it may not SOUND like much of a step, but as per the title, you can flag someone down and yell “Hey look!”, with some proof that you’re finally making a step toward makign your first video game.

Save this image somewhere you can find it, and we’ll start our divergent paths…

  • TitleALLEGRO:

Copy the title.bmp file into your project directory, so it’s in the same place as everything else (like your main.cpp file). Then open your project, which should bring back our blue screen full of mystery code. Toward the top of our source, we’re looking for this section:

while (!key[KEY_ESC]) {
    /* put your code here */

}

Well hey, there’s that loop we talked about recently! We’re going to add a few lines to it – we’re going to LOAD that bitmap, then draw it on the screen every frame, then get rid of it after the loop. Change that section so it looks like this:

    BITMAP *titleBitmap;
    PALETTE gamePalette;
 
    int x = 180;
    int y = 150;
 
    titleBitmap = load_bitmap("title.bmp", gamePalette);
 
    while (!key[KEY_ESC])
    {
        clear(screen);
        blit(titleBitmap, screen, 0, 0, x, y, titleBitmap->w, titleBitmap->h);
    }
 
    destroy_bitmap(titleBitmap);

Whew! We added quite a bit there, but try compiling and running it: Hit F9 – and with any luck, you should now have a black screen that shows a logo! Shall we go over what each line we added does?

    BITMAP *titleBitmap;
    PALETTE gamePalette;

Remember “Storing Important Things”? Allegro has a useful collection of “important things” wrapped together in a BITMAP object. We’re making a new one of those, that starts as just an empty, 0×0 bitmap with nothing in it. They also have a PALETTE defined to store a collection of colors – Allegro insists that we have one of these for our display.

    int x = 180;
    int y = 150;

More “Storing Important Things” – this time, we’re making ourselves an X and Y location for our title. They’re picked somewhat arbitrarily – but most importantly, they have a NAME – every time we want to change them, we change them HERE, since everywhere else we can just use the name, and not have to change a number a zillion places (and always manage to forget one).

    titleBitmap = load_bitmap("title.bmp", gamePalette);

Allegro has a “function” called load_bitmap that takes two parameters – a filename, and a palette – and gives us back a bitmap object. We’ve already made the empty blank bitmap object above, so this loads our file and puts it in that “storage space”. Now whenever we type titleBitmap in our code, the program will know we’re talking about that particular “Star Attackers” image.

        clear(screen);
        blit(titleBitmap, screen, 0, 0, x, y, titleBitmap->w, titleBitmap->h);

The first one is relatively simple – Allegro defines “screen” as a special bitmap object, representing the game’s display (whether it’s in a window, or taking up the whole screen). We’re going to clear it (which clears to black by default).

Then comes a weird one. Blit (random trivia – it stands for BLock Image Transfer) is the command to take one bitmap, and stick it into another one. Blit takes 8 parameters:

  1. Source bitmap. We want to copy FROM our title image, so we use “titleBitmap” here.
  2. Destination bitmap. For this, we’ll just use (for now) the “screen” bitmap Allegro helpfully provides
  3. Source X – Where, in the source image, do we want to START copying from. This is useful if you only want to draw part of a bitmap. Since we want the whole thing, we’ll start at zero.
  4. Source Y – Same as above, only vertical position instead of horizontal.
  5. Destination X – Where, on the destination bitmap, do we want to PUT this image. Like I said, we chose ours arbitrarily, but we can adjust them as we see fit.
  6. Destination Y – Getting the hang of it?
  7. Width – How far across do we want to copy? We use a special notation here, titleBitmap->w, to indicate that we want the WIDTH (w) of titleBitmap – that is, draw the whole thing however wide it is. Don’t worry about that too much right now.
  8. Height – How far down we want to copy. Same as above.

The last strange line of code we added was this:

    destroy_bitmap(titleBitmap);

The way we made out titleBitmap was a little weird (did you notice the crazy asterisk * symbol?) – It’s a side effect of the way things work in C++ called a “pointer”. We’ll take our time getting to those – the important part is, when we’re done with it, we need to get rid of it. Don’t worry, all the rest of the stuff goes away automatically. So when we’re outside of our loop, and don’t need to draw that bitmap anymore, *POOF* It’s gone.

And Ta-Da! You now have a working “game”. It even has its own title screen! If it looks a little flickery, don’t fret, we’ll re-address that problem in tomorrow’s post. Show somebody! And remember, Al Lowe Says… (save early, save often.)

  • XNA

Got your project open? XNA and Visual Studio have a few different steps to accomplish the same thing. We don’t need to manually copy over our title image into our project directory – but we do have to add it to our project. Right click on the “Content” folder in your project, pick “Add…”, then pick “Existing Item”.

AddContentNavigate to wherever you saved the image, and select it. Once it’s been added, select it in the content folder above – that should show you it’s properties. Make a note of the “Asset Name” – we’ll need this shortly.

AssetNameTime to get our hands dirty with some code! Near the top, find the section that looks like this:

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

We want to add lines immediately after those:

        Texture2D titleBitmap;
        Vector2 titlePosition;

This makes our container to store the title image, and a Vector2 (two decimal numbers, X and Y) for a place to put it. Now we have to find a place to load the image into that container… How about this function called LoadContent()? It looks something like this:

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
 
            // TODO: use this.Content to load your game content here
        }

Let’s add us some lines in there, right after that // TODO line…

            titleBitmap = Content.Load("Title");
            titlePosition = new Vector2(260f, 230f);

For that last “Title”, the one in quotes, use whatever your Asset Name was earlier. (Told ya we’d need it!) This loads that bitmap into our titleBitmap container, ready to do whatever we please with. Then we set a position of 180 x and 150 y (The “f” after both numbers tells the compiler it’s a “floating-point” or “fixed-precision” number). Now what’s left… Oh yeah! We need to put it on the screen. If only we had some sort of Draw() function in place already, at the bottom of our code…

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
 
            // TODO: Add your drawing code here
 
            base.Draw(gameTime);
        }

Well what do you know! I think this would be a good place to add our title drawing, and while we’re at it, change our color scheme a little bit. Replace that function with this strikingly similar one:

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
 
            // TODO: Add your drawing code here
 
            spriteBatch.Begin();
            spriteBatch.Draw(titleBitmap, titlePosition, Color.White);
            spriteBatch.End();
 
            base.Draw(gameTime);
        }

We added three lines (above and beyond changing our color to something less… blue.) They all revolve around the “spriteBatch” object – this is a useful object in XNA for drawing things onto the screen. Basically, you call spriteBatch.Begin() – you must do this before you can draw anything. After all the drawing is done, you call spriteBatch.End() – and this signals that it’s safe to draw everything. Any calls you make in between are (invisibly) stored in order somewhere, and executed one at a time when you call spriteBatch.End(). The middle line there is the important one:

            spriteBatch.Draw(titleBitmap, titlePosition, Color.White);

Draw() has a number of different “sets” of parameters it can take, but this is one of the simplest – it takes a bitmap object to draw, which we loaded earlier (titleBitmap). Then it takes a screen position to place this object (titlePosition). Finally, it takes a “tint color” – feel free to experiment with this to see how you can make it look a little different. Color.White draws the bitmap exactly how it is, no tinting.

It’s time to  hit F5 – see if it comes up! You should now have a black screen with the Star Attackers logo emblazoned proudly in the middle. Show your friends! Or your enemies! We’re that much closer to getting a good working game together.

Until next time, have a little fun – draw some new images, put ‘em other places on the screen, change up your logo – it’s your project after all. And remember, Save Early, Save Often.

Leave a Reply