By: Frank Blunt
February, 2016
So in this game you are stationary, have a gun that follows the mouse (which is represented by that big red cursor), and shoot incoming enemies. Every one that you kill is slightly bigger and faster than the last, so eventually you'll have something that's just too much for you.
Now, getting into the nitty-gritty, how did I do this?
Well, I started by dividing the character up into several parts: a torso, a head, an arm, and a gun. The arm and the gun do not need to be separate for this, but I thought I would be able to add multiple weapons for this game, and that was a bit out of my league.
I wanted to have the head and the arm/gun track the movement of the mouse, but before I get into that, I want to create a custom mouse cursor.
Chapter 1 - The Mouse Cursor
Simple enough. Just big red cross-hairs, lowered opacity to taste, and I was good to shove it in the game.
Next came the object of the mouse cursor. I wanted it to be easily noticeable, so I had it constantly rotate. I wanted it to remain the same relative size, so I tied its scale to the size of the window. Finally, I made sure it matched the exact position of where the mouse was.
In the Create Event for the cursor, which is where you put code that will only run once as the object is created in a room, I set the horizontal scale of the sprite to be the room's width divided by 500. The vertical scale would always equal the horizontal scale, so I just made sure the code knew that.
In the Step Event, which runs several times per second (in my game it runs sixty times per second), I made it track where the mouse pointer's x and y coordinates were at all times and to adjust the location of the object based on that. The oCursor's x variable will always equal the mouse's x variable.
I then had it rotate at a speed of -3 degrees per step. This would've been smarter to tie the rotation to the room's speed, like having "image_angle -= room_speed / 10", but I cut a corner there.
Finally, you don't want your mouse's actual cursor to show up and ruin the illusion, so GameMaker helpfully has a checkbox for "Display the cursor", located in the Global Game Settings (under the Resources drop-down menu) under the Windows tab.
Now just drop it in the room and presto, you have a custom cursor!
Chapter 2 - Aiming
Back to having your head and gun track the mouse, there is a very simple way of doing this, but to have it look right, things get a bit tricky.
First of all, you want the variable known as image_angle, which determines which angle between 0 and 360 degrees your object's sprite is facing (0 degrees is always to the right; it's the angle all objects start out at). Then, if your mouse is on the left side of your character, you want their sprite to face left.
Here's the code I put in oPlayerArm:
As you can see in the Create Event, ignoring that 'Kaboom' boolean variable (it might've been some function that I gave up), you can see that I placed it on the torso, object oPlayer, in a very specific spot.
The image origin; what GM considers to be its center. |
When FaceRight = true, the arm is twelve pixels to the left of the torso's center. The y-coordinate still matches up with the torso's, though.
Now, in the Step Event, you'll see a couple of 'if statements'. The first two of which handle the FaceRight variable from the Create Event.
If the FaceRight variable is true, the image's angle will be facing towards where the cursor is. But if it's false, which happens if the cursor is to the left of the player, the image's angle gets inverted, accomplished by changing the variables in the point_direction function to negatives.
As a side note, the point_direction function simply states a direction between two points, going from the origin (in this case, the arm's own x/y coordinates) to the end point (in this case, the variables mouse_x and mouse_y).
How does it know that the mouse is on the left or the right, and what changes the variable FaceRight to either true or false? The following 'if/else statement' handles that.
An 'if/else statement' is just like any other 'if statement', except that it covers both true and false statements. You write down what do do in the case that something happens in the 'if' part, and then after that segment, you set what happens when the 'if' is not happening.
Example: if Jerry has three or more apples, then Jerry must throw them at Kyle's face. Else, Jerry keeps collecting apples. In this statement, it means that Jerry will keep collecting apples until he has at least three (its a good idea to have the 'or more' in there, just in case the number exceeds your limit), and then throws them at Kyle's face. Treat punctuations like the comma as an open bracket, "{", and periods as a closed bracket, "}".
In the game proper, the code is written like this (removed unnecessary code):
if oCursor.x < room_width / 2 {
image_xscale = -1
x = oPlayer.x + 12
FaceRight = false
} else {
image_xscale = 1
x = oPlayer.x - 12
FaceRight = true
}
This states simply that if the object oCursor, which I made to be exactly where the mouse is, is on the left side of the player (the player is stuck at the middle of the room, which is room_width / 2), then the image_xscale variable, which determines it's horizontal size, get's flipped (multiplying anything by -1 will flip it form one side of the number line to another. For example, -55 times -1 equals 55). Once the image_xscale is flipped, it now faces the opposite direction. Then it places it twelve pixels to the torso's right, and sets the FaceRight variable to false, which will trigger the above 'if statements' so that the arm will still follow the mouse, but not in a backwards way.
After the Else statement, it declares that if the oCursor isn't on the left half of the screen, then the oPlayerArm will face the right, gets placed on the torso properly, and FaceRight = true.
I applied this code to the head and the gun as well to have it accurately track the mouse cursor. For the torso, since that only needed to track which direction it was facing and not the exact angle, only needed the code that flipped it.
End of Part 1
That's all I have set aside for now. Don't know when the next part of this will be out, but don't expect me to take too long.
As well, the game for March will be much simpler so that I can cover its progress quickly before the month is out, and then be able to cover the April Game as I'm making it.
Thank you for reading!
- Frank