Thursday, March 10, 2016

February Game Part 1

February Game - "They Just Keep Getting Bigger"
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

Thursday, February 11, 2016

Amazon's Free Lumberyard Engine

So Amazon recently released a completely free 3D game engine called Lumberyard.

I've downloaded it (make sure you read the installation guide) but I haven't had any time with it yet. Once I do, if it's easy enough to work with, I might start also tracking my progress with it on here.

So, check it out and give it a whirl for yourself: http://aws.amazon.com/lumberyard/

Been away for a little bit

I haven't had much time with my desktop computer lately. I've still been working on my February Game for my Year of Games, but for now I can't show anything until I get enough time to do my write-ups and lessons.

But don't worry, I'll be back soon with a game that I'm almost done with, and I promise that the lessons will be easier to follow and understand.

Plus, next month I'm moving into my first apartment and I'm moving to an overnight shift on the 22nd of Feb, which will give me more time to work on both this site and anything else I want to do, so there's that.

<3
Frank

Sunday, January 31, 2016

Oh Jeeze It's The Patreon

Hey, I set up a patreon to help support myself through the fact that I'm getting my first apartment this week, and my current, 40-hour a week job can just barely pay for it, so I find myself in the position of asking for money.

I wrote out a stronger pitch here, but if you already feel like supporting me, you can find the patreon here: https://www.patreon.com/l1gd

Finished First Game (And Notes On Audio)

So, on Friday, something weird happened. I finished the game,

Yeah, I wasn't really expecting that. I had been expecting to be working on it forever until I died, like everything I do. 

But, yeah, the January Game, now known as "Fistful of Bullets: Low Noon" (I was really tired when I named it), is completed and on the Steam Workshop page for GameMaker: Studio. The GM:S itself is free, so if you can download that, you can play my game.
As well, I know that on the last post I was complaining of not being able to get the sound to work, but as it turns out, GameMaker once again has a checkbox that controls whether or not sounds work correctly ticked.

To fix it, go back to the resources tab and select Global Game Settings from the drop menu, just like how we fixed the color interpolation in the previous post.

This time, stick to the General tab of the GGS window, and uncheck the box next to "Use New Audio Engine".

This should fix most issues with calling in audio to play.

It feels awesome to have completely finished my first GameMaker game, beginning to end. It didn't hit me right away, but that's because I wasn't expecting how natural the progression to feel. All I did was take things one step at a time, and eventually I had a game.

Let me know if any of you have made your first games after checking out this site, I'd be glad to check them out!


- Frank

Wednesday, January 27, 2016

January Game - Nearing Completion

The month is drawing to a close and so the game I've been working on is nearing its own completion.

I've done a few things in the past day or two, namely updating the graphics and trying (yet failing) to implement sound.

I also made the game full screen.
When making a game full screen in Game Maker, there are two things you can do: Increase the size of the window but keep the sprites the same size, which both requires more coding and, in my opinion, looks worse. Or, you can do it the easy way, which scales the sprites with the size of the window.

I did this by making an invisible object, one that doesn't have a set sprite, and placing it in the room. In the Create event, I put this simple line of code in it: window_set_fullscreen(true)

This is a simple boolean (true or false) function that checks to see if you're setting the window size to fullscreen.

Now, if you were to throw that code into that object, place it in the room and boot it up, you might notice something wrong. Something... fuzzy.
So, you may have noticed all the blurryness of the image and the white artifacting around the bandit. For some reason, Game Maker has a setting that is toggled by default that does this whenever you scale a sprite in-game. This can be easily fixed.


First, go to the Resources tab, and on the drop down menu, select "Change Global Game Settings". On the window that pops up, select the "Windows" tab on the top and then the "Graphics" tab on the side. There's a checkbox for "Interpolate colors between pixels".

Do yourself a favor and uncheck this box. From now on, any in-game scaling will be pixel perfect.

As for the black bars around the sides image at the top of this article, this method of making the game fullscreen doesn't alter the paramaters you set for the view (to learn more about views, check out Tom Francis' tutorials on Game Maker. That link will take you to the specific video on views, also he discusses the other way of making games fullscreen). So, if the view you have for the game set to a different ratio than your own monitor, you'll get those very attractive black bars in order to make up for it.
As you'll see in this photo, I've also added clouds. Or, more specifically, their shadows. This doesn't exactly have much bearing on gameplay, but I thought it would be important to have some sort of slow moving ambiance. Some constant movement to keep it from being boring.

I simply made a sprite that had three frames, put it into an object, and set the image_speed to zero, so that the clouds wouldn't be constantly changing shape.

Here's the code that I've used in the Create event (any comments between /*   */ are not part of the code):

y = random(200) /* this places the instance of the cloud somewhere randomly on the y-axis between 0, the top of the screen, and 200, which is lower on the screen */
image_speed = 0 /* this stops the sprite from looping through its frames */
image_index = random(5) /* this sets each instance of the cloud to a random frame. I chose five because it was more than the number of frames I made. */
image_xscale = 0.2 + random(1.2) /* this will change the width of each instance of the cloud between a fifth of its size to two fifths bigger */
image_yscale = image_xscale /* this scales the height of the cloud equally with the width */

Once the clouds are in the game, they need to move. Originally I had them moving in both directions; left to right and right to left. But this made things difficult and also didn't make any sense. Clouds move in the same direction. 

Now I have them moving right to left. In order to save on memory, once they leave the room, the sprites are destroyed, but not before creating another one to replace it.

Here's the code that I used in the Step event:

x -= 0.7 /* this makes the cloud move from right to left */

if x <= 0 { /* this checks to see if the cloud has left the room. 0 is the leftmost border of any room. */
instance_create(room_width+1000,random(200),oDust) /* before I destroy this instance, I create a new one, outside of the room. The parameters in the parenthesis are x, y, and the name of the object you are creating. Room_width+1000 places the cloud 1000 pixels to the right of the room, random(200) has the same function it does in the Create event, and oDust is what I named my cloud object */
instance_destroy() /* This destroys the instance of the cloud that has exited the room */
} /* always make sure to close your "if statements". */

I've also been thinking about making the game more about an inevitable death rather than a simple win or lose situation.

It's something I'll tinker with, but I'm planning on making it so that the game doesn't end when the bandit shoots their gun and misses the "coward". The clock will keep going and going until the bandit kills him. I'll possibly increase the speed of the timer each turn, as well.

Finally, I've learned how to create a title that fades into the game. Before now, I've only worked with a single room. But as it turns out it's a very simple concept.
When the game starts, you are greeted by this, telling you my information; my twitter and both of my blogs. After a few seconds, it fades out and the game begins.

Here's the code for the object that I created with that text as the sprite:

Create Event
x = room_width/2
y = room_height/2
RoomTimer = 0 /* this is a variable I created. */

Step Event
RoomTimer += 1 /* as soon as the information appears on screen, this timer begins */

if RoomTimer >= 100 { /* It's good practice to use > or < before the = on most if statements. This way, it'll still work if you go past your goal */
image_alpha -= 0.1 /* begin to fade */
}

if image_alpha <= 0 and RoomTimer >= 150{
room_goto(1) /* once the object is completely transparent, it moves to the next room */
}

if keyboard_check(vk_enter) {
room_goto(1) /* or, alternatively, if you press enter, it'll just skip to the next room */
}

Importantly, Game Maker will always start with the room that is highest on the room list, like this:
Sorry, but the tumbleweed isn't making it into the final cut of the game.
Room0 will always be the room that Game Maker starts with, not because it's a lower number, but because it's on top.

Also, Game Maker numbers always start with 0. Room0, even if it was named room15, would be classified as the zeroth room. The first image on roll of sprite frames would be number zero and the second would be number one.

That's all I have for now, thanks for reading!

Monday, January 18, 2016

January Game - What I Have Done So Far


This is the first game that I'll be working on this year. It has no name at the moment, other than the uncreative project working title, "January Game".

I decided to keep it a small windowed game where two players, using the same keyboard, have a set amount of time to change their positions (by pressing the keys represented by the signs) before the gunman fires.

The gunman's goal is to shoot the other guy, and the other guy (whom I have named in my programming as the coward for some reason) is trying his best to avoid that fate.

I hope that it creates a sort of game of chicken in the last few seconds of the timer, where players are trying to gauge each other's intentions and deciding whether or not they should move at the last second.
In Game Maker, a popular method of adding rules to the system is to make a spriteless object that can be placed invisibly into the level. Here you can see that it sets up some variables in the Create event (in a Create event, the code in here is only submitted to the game one time per loading of that object. The Step event, on the other hand, will be submitted and re-submitted to the game a set number of times per second. The Create event is where you will be putting things you only want to be established once and the Step event is where you want things that will be changing).

In the Step event, you can see that I have conditions (known as "if statements") that determine what happens when you press four buttons. For example, when the 'Q' key is pressed, it sets one variable to true and another to false. Lower on the page it checks to see if one variable is true and if it is, to move the object 'oGunner' to a position thirty pixels down from the top of the room.
Here you can see the code for the clock hand. I decided to dump this code into here because the hand of the clock is a trigger for many events; when it starts moving, the game has started, and when it stops moving, the game ends.

You can see that it checks for when the variable Ticking is true. If so, than the angle of the clock hand begins rotating by negative one degrees, thirty times per second (which is the game's framerate).

Once the clock hand's angle is less than or equal to three-hundred and sixty (a full circle), then the game ends, a white screen object I made earlier enters the room and (in the white screen's own code) fades out. Before the white screen fades out, it replaces the coward's sprite with another, depending on the outcome of the duel.