My first foray into C++ programming was for a class where we had to work in groups to create a program (in our case a video game) in C++. It was my first coding project where I had to directly integrate multiple pieces of code together with mine to make a final product. I really liked this project because it was easy to go home and show it off and play it with family.
The idea for this game came from the many tank games that you can play for free online. The difference here is that, in honor of the Halloween season in which this game was conceived, we swapped tanks with pumpkins, and a war zone environment with a creepy haunted house.
How to Play
The gameplay is split into 3 parts:
- Pre-Game Menu
Once the game is compiled, built, and run, the introductory animation will start. Once the animation sequence ends, the user will be requested to press ‘Enter’ to continue to game menu.
Navigation through the pre-game menu is accomplished through button mouse clicks. After the introductory animation, the menu screen appears, with options to read the instructions by clicking the “?” button, or pressing start and moving forward with character selection.
Once the characters are selected and the user clicks the start button, the program progresses to gameplay.
Based on the number of players chosen, the game map will be populated by the characters on a randomly generated terrain. The object of the game is to shoot the other players until they die and turn into pumpkin pie.
- To aim the gun, a player uses the left and right keys on the keyboard to change the angle of their gun.
- To shoot, the player presses the ‘spacebar’ key.
- A players turn ends when they shoot their gun or the time limit of 8 seconds runs out.
- Each player has 100. If a player is hit directly, they lose 25 and if they are hit indirectly, meaning that a projectile hits the environment close to them, they lose 15.
- Once a player defeats all other players (only player still alive), the winner is declared and the gameplay comes to an end. The application then closes. If the user would like to play another game, they must re-run the ‘Pumpkin Smash’ game.
Batman: As a kid Batman’s parents were killed by the joker gang, therefore, Batman holds a lifelong grudge against joker.
Joker: He’s just a mysterious guy. No one knows where he comes from. We just know he doesn’t like Batman.
Mr. Angry: Every year millions of pumpkins are killed in the name of Halloween. Angry pumpkin didn’t want to put up with it. That’s why he’s still alive and here today.
Mike Wazowski: Mike couldn’t make it as a scary monster, so when he was confronted about being a star in ‘Pumpkin Smash’, he couldn’t say no.
Captain: At one point in his life, Captain sailed the 7 seas. After retiring, he didn’t know what to do with his free time so he joined the game.
Casper: Like Mike Wazowski, Casper couldn’t make it as a scary monster, he was just too friendly. He’s the nicest guy in this game.
My Personal Contributions
Component Code – Environment
I worked on developing the “environment” in the game. This included the background, and the ground that the pumpkins (avatars) traverse on.
The first part of my code loads the background image. In this code, the picture used is a PNG file that was downloaded from Google. The size of the window used for gameplay is determined by the size of the PNG file.
The second part of the code creates and modifies the “ground” that the avatars use for gameplay. This was done first by creating a Vec class, which was based on code from class notes. This initialized x and y variables. Next, I created an Environment class, which created an array of the Vec variables. The x values correspond to the pixels along the width of the window. The y values were created based on a GenerateGround() function. This function generates a sine and cosine function, with an x-offset, amplitude, and frequency randomly chosen. These two functions are then added together, and are mapped to the x-values. Limits on the random variables were chosen such that the curve for the ground created fits appropriately within the player window.
After the x and y values are generated, the DrawGround() function draws the curve. The first part draws a line representing the function created in GenerateGround(). The second part of the code draws a translucent ground beneath the curve. This is accomplished by creating tiny rectangles of approximately one-pixel width (essentially integrating the sine/cosine function) and drawing them using the alpha blending feature in Open GL.
Finally, the ground curve updates if it detects collision. If the top of the ground is hit by a projectile, it recalculates the y-values and creates a crater in the ground. The more difficult hit test involved detecting hits from the side, because a vertical line is only represented by two points, top and bottom, whereas a horizontal line is represented by many more points. Even though the code can detect hits on these vertical walls, it does not create a crater with a radius. We simply assume that the ground in the game is not stable enough to support overhang features, and all of the ground above a hit from the side disappears.
This code was tested by visual inspection after running it. The GenerateGround() and DrawGround() functions worked as designed, as seen in the top-left of the figure below. HitTest() was tested by simulating a projectile’s center x and center y positions with a left-mouse click. If the radius of the projectile (specified in the main.cpp file) was within the range of the ground (a.k.a. if HitTest() detected a collision) the ground y values updated accordingly. The craters created from HitTest() can be observed in top-right of the figure below. The bottom two figures display collision detection from the side (a.k.a. a collision with a vertical line).
In addition to developing code for the environment, I also worked on integrating everyone’s code. This was almost, if not, as time intensive as generating my component code. This involved resolving pointers, figuring out and making sure scaling factors and orientations matched up, and a lot of back and forth between my group members. Fortunately, I had an awesome group and we were able to get everything together in time.
This project was a lot of fun and really easy to show off. Having to integrate all these pieces was a bit daunting, but didn’t end up being as difficult to do once I started (although definitely time consuming). I happy that I learned the programming skills needed for this project in the class, and I’m looking forward to applying them in future work.
A full video of the project can be found below: