Friday, 31 December 2021

LP's 12 Months of Games // Alien Invaders Part 1 [C++ & SFML]

Completed Independently

So the final game of "Beginning C++ Games Programming" by John Horton was a clone of "Space Invaders". I skimmed the first chapter of the project and he starts talking about Entity component systems, Factory class designs etc and I just completely zoned out and decided to make it myself. 

This took me a while as Back 4 Blood added an offline mode and there's nothing quite like hitting zombies with a baseball bat. Also the Witcher season 2 and Lost In Space season 3.

So anyway, I kept getting annoyed with myself whilst making this game; I was trying to make the code as beautiful as possible right off the bat; which is impossible unless your Bjarne or Scott Meyers or something. I asked many colleagues how they would go about implementing Space Invaders and amusingly, the more senior the engineer the more the answer became "just do it all in main, who cares?"

So, I've written some terribly hacky code that only gets worse as time goes on but I have a game! This is labelled part 1 because it's not finished however, there is a title screen, a game and a game over. It saves the high score between runs and loops after game over so it is a game...regardless of how finished.

I'm quite into the task now and the shields are ready to be implemented, as are the sounds. Then the flying saucer needs some attention as do the shot exploding animations but then I'll have a full Space Invaders clone!

I've given myself a few little extras that involve creating a CRT shader and making it look as though you're playing the game on an arcade machine.

Result:
Space Invaders Clone Using C++ and SFML

I'm extremely happy with what I've done so far. I'm really trying my best to make it look and feel exactly like the original. I'm going so far as implementing the same bugs using this site which comments all the assembly:

There are some issues which you may have already noticed; my game over text isn't displaying and the high score isn't updating. That will be fixed next but the code is in place.

I just really wanted to get something uploaded for this month and I've already learnt so much from attempting to do this by myself. I'm glad I ignored the book as this game is deceptively hard but a great place to start when making a complete game from scratch for the first time.

I almost gave up a couple weeks ago as I find it difficult to find the motivation to finish things. I have about 70 started projects but I thought to myself, the whole point of this challenge is to get better at making games and I won't get better if I don't at least try! So I managed to scrape the code together enough to call it a "game".

It also made me realise that I hate UI programming with a burning passion.

Code:


Friday, 24 December 2021

C++ & SFML // Creating The Disintegrating Shields in Space invaders

Whilst making a clone of Space Invaders, I got to the point where I had to make the shields. They are interesting as only parts of them get destroyed when hit by bullets:


The damage done to the shields is based on the type of bullet and where they hit. It reminds me of the old Worms and Lemmings games that have disintegrating terrain due to explosions.

The player's shot and 2 of the invader shots deal the same type of damage. However the "plunger" looking invader shot is the most powerful and deals more damage. Therefore, having the shields as sprites make no sense as you can't manipulate the pixels in a sprite, so I started looking into ways to draw and modify pixels in SFML as well as do per-pixel collisions.

I eventually came across this post:

This seems super long winded for what I want as it copies the image from the gpu into an array of pixels, then you modify those pixels and then send that array back to the texture. But it's also the closest to how the original game implements the shields (in a way).

I then found this after googling "sfml array of pixels":

I was able to write a program that can draw individual pixels to the screen:

This is more along the lines of what I wanted, as I could now simply create a vector of vertices in the shape of the shield. SFML already provides this type called VertexArray which can be passed directly to a RenderWindow's draw call.

Here's a simple program I wrote that uses a VertexArray to create a rectangle with a gradient fill:

In my version, the shields are 66x48 pixels, with each vertex needing 4 uint8's of data (RGBA), so that means I need to supply 12,672 uint8's and I don't really want to type that out. So I had to start looking for a way to read in that data from something. SFML does not provide a way to convert textures or images to VertexArrays. I can get the pixel colour data by using the first method and copying the texture to an image but that doesn't provide pixel positions (which a vertex wants). So I wrote a method to combine the two. 

It creates a temporary texture, copies the texture to an image then loops through every pixel, pushing back a new Vertex after all 4 pieces of the pixel have been collected. The positions are calculated using an offset from the top left hand corner. So after 66 vertices have been pushed back, the y co-ord is shifted down 1 pixel. However there is still a glaring problem with this method; I have 4 arrays containing 3168 elements.

So I went back to the drawing board and found this post:

Using the code from Laurent (the developer of SFML) I managed to write a program that creates a "mask" from a png and uses that to turn pixels transparent:

C++ & SFML // Creating The Disintegrating Shields in Space invaders

Armed with this knowledge I then set about creating a cannon that fires lasers at the doge image to destroy it:
C++ & SFML // Creating The Disintegrating Shields in Space invaders

The next issue to solve was the per-pixel collisions as the laser was still colliding with the bounding box of the sprite. I hackily solved this by writing a very simple collision check:

C++ & SFML // Creating The Disintegrating Shields in Space invaders

First, it only does a per-pixel check if the laser has collided with the bounding box of doge. Then, it checks to see if 3 spots on the laser have hit solid pixels. If they're all transparent then the laser can pass through.

This isn't perfect, but it's good enough.

Thursday, 16 December 2021

Chapter 22 // Exercise 15 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2019 and a modified version of the std_lib_facilities header found here.

Chapter 22 // Exercise 15

Write a program that, given a file of (name, year) pairs, such as (Algol,1960) and (C,1974), graphs the names on a timeline.


I finally did this exercise after much procrastination. I also hate Bjarne because the scattergraph class I made back in chapter whatever doesn't exactly fit this example.

Instead of continuing to procrastinate I decided to hack it together one night....it's not exactly a timeline but well I guess it is. There is a line and there are times...done.


I had a look for rotated text in FLTK and it looks like it's just been implemented in 1.3.8, which was released last month. I'm still on 1.3.7 but I'll update at some point as that would've made this much easier.