Quantcast
Channel: GameDev Academy
Viewing all articles
Browse latest Browse all 351

Hypercasual Games – GameMaker Tutorial

$
0
0

You can access the full course here: CREATE A FULLY-FLEDGED HYPERCASUAL GAME IN GAMEMAKER

Introduction

Unleash your creativity and create a wildly addictive GameMaker hypercasual game that will dominate the charts and leave players hooked

In this tutorial, we will learn how to create essential game elements in GameMaker, focusing on player movement, a manager object, and bullets to form the foundation of a hypercasual shooting game. These foundations will help form foundational knowledge for working with GameMaker – and give you the base you need to expand any GameMaker hypercasual game!

The tutorial assumes basic familiarity with GameMaker, including its interface and key concepts such as sprites, objects, and events. Additionally, you can review our full course, Create a Fully-Fledged Hypercasual Game in GameMaker which covers these concepts in-depth.

Let’s dive in!

Project Files

To assist you, we have provided all necessary project assets used in this GameMaker hypercasual game tutorial. Download the files here: GameMaker Hypercasual Game Assets

CTA Small Image - Hypercasual Games - GameMaker Tutorial
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Player Movement

To start our GameMaker hypercasual game tutorial, we will learn how to create player movement in a game using GameMaker. We will start by creating a player sprite and a player object. After that, we will create a simple movement system where the player follows the mouse’s horizontal position. Finally, we will ensure that the player can’t move outside the visible game area by clamping its movement.

Creating the Player Sprite and Object

First, we need to create a player sprite and a player object. To do this, follow the steps below:

  1. Right-click in the Sprites folder and select “Create Sprite”. Name the new sprite “spr_player”.
  2. Next, right-click in the Objects folder and select “Create Object”. Name the new object “obj_player”.

When naming your assets, it’s important to follow a consistent naming pattern. For instance, you can shorten the asset type in the name, such as using “obj” instead of “objects” or “rm” instead of “room. The important thing is that you use the same pattern for every asset in your project.

Once you’ve created the sprite and the object, import the corresponding sprite for the player. Make sure to set its anchor point to the middle center. This will help with positioning the sprite on the screen accurately.

Setting Up the Player Object in the Game Room

Next, let’s add the player object to the game room:

  1. Go to the game room and in the Instances layer, drag and drop the player object.
  2. As the player object might be too big, scale it down to fit the game room. You can set the scale to 0.4 in both axes.
  3. Position the player object in the center of the game room horizontally. You can do this manually or by using the center alignment option.

Creating the Player Movement

The player movement we want to create is simple: the player should follow the mouse’s horizontal position. To implement this, we need to make the player’s x-coordinate equal to the mouse’s x-coordinate. We will do this when the left mouse button is being pressed.

Here’s how to set this up:

  1. Add a new event to the player object. Choose the “Mouse” event, then “Global Mouse”, and finally “Global Left Down”.
  2. In the event code, set the player’s x-coordinate to be equal to the mouse’s x-coordinate. This is done with the following line of code:
x = mouse_x;

After setting this up, test your game. You should be able to move your player horizontally by pressing and holding the left mouse button.

Clamping the Player Movement

As you may have noticed, the player can move outside of the visible game area. To prevent this, we will clamp the player’s x-coordinate to a certain range. This will ensure that the player’s x-coordinate can’t go below or above the specified range.

For instance, if we want to keep the player within the range of 40 to 500, we can use this line of code:

x = clamp(x, 40, 500);

This code should be placed in the “Step” event of the player object. This event is triggered every frame, so it will continuously check and adjust the player’s position.

Now, when you test your game, the player should not be able to move outside of the specified range, effectively staying within the visible game area. And with that, we have successfully created the player movement for our game.

Manager

With the player set up, in this part of our GameMaker hypercasual game guide we will be creating a manager object in our game development project. This object will act as a central store for various variables and events that affect the project from end to end. Such variables can include game over states, scores, and other values that need to be stored for the duration of the game. By using a manager object, we can keep our code organized and efficient, a practice that is commonly used in game development.

Creating the Manager Object

The first step is to create a new object, which we will call obj_manager. Unlike other objects in our game, the manager object will not have a sprite or collision, and it will not move on the screen. Its sole purpose is to contain and manage variables and events.

Declaring Variables in the Manager Object

The manager object will contain various variables, which must be declared in the create event. These variables can be global or local, depending on their usage throughout the project.

For instance, we will declare a global variable called frame rate, which will store the game’s speed in frames per second. This variable will be useful for setting alarms and ensuring they trigger at the correct frequency, even if the game speed changes.

// Declare a global variable called frame rate
global.frame_rate = game_get_speed(gamespeed_fps);

We will also declare two variables related to the bullet in our game: global.fire_rate and global.bullet_speed. The fire rate variable will determine how often a bullet is fired, while the bullet speed variable will control the speed of the bullet. These variables are declared in the manager object for organization and ease of access.

// Declare global variables related to the bullet
global.fire_rate = 0.15;
global.bullet_speed = 8;

Conclusion

We have created a manager object and declared some initial variables. As we continue to develop the game, we will add more variables and functions to the manager object to manage various aspects of the game. The usage of a manager object is a common practice in game development for keeping the code organized and efficient.

Ready to unlock the full potential of GameMaker? Our GameMaker Academy provides in-depth tutorials, hands-on projects, and expert guidance to help you create hit games that engage and entertain.

Bullet – Part 1

Moving on in our GameMaker hypercasual game tutorial, we’ll be creating the bullet for our game. We will make use of some of the global variables that we have already set up in the manager. The bullet will require both an object and a sprite.

Creating the Bullet Sprite and Object

Start by right-clicking in the sprites section and create a sprite named spr_bullet. Similarly, in the objects section, create an object named obj_ullet. Once you have done this, you can open up the sprite and import the bullet image.

It’s recommended to keep the anchor of your sprites centered. This is because when you instantiate them in the room, it helps to avoid any positioning issues. For example, if you want to instantiate the bullet at the center of your player, having the anchor set to top left instead of center can cause the bullet to be instantiated a little to the left of the player. This is because the zero-zero point is calculated from the anchor, not the object itself.

To illustrate this, let’s load in the sprite by dragging and dropping. Having selected the instances layer, you can see that with the anchor centered, the bullet will be instantiated at the exact center of the player. However, if the anchor is set to top left, the bullet will be instantiated a bit to the left.

Instantiating the Bullet

Now that we have our bullet set up, we need to instantiate it into the room. We also need to account for the fire rate that we’ve defined. This means that every 0.15 seconds, a bullet should be instantiated. We will do this in the player object.

To do this, add an alarm in the player object and use the instanceCreateLayer method. This method allows you to instantiate any object into the room. You need to provide several arguments:

  • The X and Y coordinates: These are the positions at which the bullet should be instantiated. In our case, we want the bullet to be instantiated at the exact position where the player is, hence we use our X and Y coordinates.
  • The layer: Here we’re just going to be writing ‘layer’ which refers to the current layer in which the player object is. Our player is inside the instances layer, which will work fine for our purposes.
  • The object: This is the object we want to instantiate. In our case, it’s the obj_bullet that we created earlier.

Once you have instantiated the bullet, you will want to spawn the bullets repeatedly. This means that once a bullet is instantiated, after 0.15 seconds, another bullet should be instantiated, and so on. This is achieved by initializing the alarm again as soon as the alarm is called.

Here’s how you can do this:

// Shoot bullet
instance_create_layer(x, y, layer, obj_bullet);

It’s important to note that you need to start the alarm in the first place. You can do this in the create event of the player object:

// Initialize alarm
alarm[0] = global.framerate*global.fire_rate;

Handling Errors

If you try to run your game now, you might encounter an error. This is because the player is trying to access a global variable that hasn’t been created yet. The player is created before the manager, so it’s trying to access data that doesn’t exist yet. To fix this, you can change the instance creation order in the room game to create the manager first, then the rest of the objects.

Once you’ve done this, the bullet should be instantiated correctly. However, it won’t be moving yet, and it might be too big. In the next part, we’ll work on making the bullet move and adjust its size.

Bullet – Part 2

In this final part of our GameMaker hypercasual game tutorial, we are going to finalize the attributes of the bullet in our game. At present, the bullet is being instantiated in the game scene, however, it’s a bit larger than what we want and it’s not moving. Therefore, we will work on resizing the bullet and making it move.

Resizing the Bullet

There are two methods to resize the bullet:

  1. The first method involves using code in the create event, such as the ‘image X scale’ and ‘image Y scale’. The scale by default is one, so if we give it a value of 0.5 in both axes, it would have half of its initial size. This method works quite well, however, it requires writing code.
  2. The second method does not require any code. It might not be as accurate or straightforward as the first method, but it can be useful in certain scenarios. This method involves editing the image size directly. We can do this by clicking on ‘edit image’ and then ‘resize sprite’, which will open the sprite editor. In the editor, we can scale the images by modifying the width and height values. If we maintain the aspect ratio, the image will be kept as similar as possible. Although we lose some pixels, the sprite looks almost identical when viewed without zooming in.

You can choose the method that best suits your project. For this GameMaker hypercasual game, we will use the second method as it works quite well and does not require any code.

Moving the Bullet

Next, we want our bullet to move. In the create event, there is a built-in variable called ‘vSpeed’ (vertical movement) which is very useful for this purpose. We can modify the bullet’s vertical speed by assigning a value to the ‘vSpeed’ variable.

vspeed = -global.bulletSpeed;

In this case, we are assigning a negative value to ‘vSpeed’ to make the bullet move upwards. This is because in GameMaker, the (0,0) point is at the top left corner. As a result, positive Y values are downwards, and negative Y values are upwards. Therefore, if we want our bullet to move upwards, we need to assign a negative value to its speed.

Deleting Bullets Outside the Room

While our bullets are now moving and have the correct size, there is one more issue we need to address. When the bullets leave the room or our view, they still exist and GameMaker continues to render them. This can consume resources and affect the game’s performance, especially in larger projects where more bullets are being shot.

To avoid this, we can add an ‘outside room’ event to the bullet. This event is triggered when the bullet goes outside of the room. In this event, we can call the ‘instance_destroy()’ function to destroy the bullet.

instance_destroy();

Now, our bullets are destroyed as soon as they leave the room, freeing up resources and improving the game’s performance.

GameMaker Hypercasual Game Wrap-Up

Congratulations! You’ve successfully built the core mechanics of a hypercasual shooting game in GameMaker through this GameMaker hypercasual game course. By implementing player movement, a manager object, and a functioning bullet system, you’ve established a solid foundation for creating and expanding your game.

These essential techniques, like clamping movement, managing global variables, and optimizing performance by destroying unused objects, set you up to add new features such as enemies, power-ups, or scoring systems. However, these systems are beyond the scope, so don’t hesitate to explore more resources. For example, Zenva’s learning pathway GameMaker Academy is a fantastic resource that covers tons of different projects to get you industry-ready!

Regardless, now it’s time to experiment, expand, and let your creativity shine! GameMaker is a powerful tool, and you have the knowledge to bring your ideas to life. Happy game-making!

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FREE COURSES
Python Blog Image - Hypercasual Games - GameMaker Tutorial

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.

Transcript – Player Movement

Hello there and welcome to a new lesson. In this one, we are going to be creating the player movement. Of course, in order to create player movement, the first thing we need is to have the player sprite and the player object. So let’s go ahead and create these two. Right-click in the sprites folder, create a sprite named SPR_player, and then in the objects folder, create an object named OBJ_player.

Something I want to quickly explain is the fact that there are multiple patterns you can follow to name your assets. For instance, you can shorten the asset type, like writing “OBJ” instead of “object” or “RM” instead of “room.” There are multiple patterns and ways to name assets. What’s important is to follow the exact same pattern for every single asset in the project. You can’t have one asset named with lowercase letters and another using capital letters—it should be consistent.

It doesn’t matter which naming system you choose, as long as it is consistent. If you want to experiment with other naming patterns, go ahead; just make sure every single asset in your game follows the chosen pattern.

Now, inside the sprite player, let’s import the corresponding sprite. Click “Import.” I have it in my downloads, and here it is. Once imported, I will change its anchor to the middle center. This helps to move and position it on the screen more easily. It’s generally better to use the middle center to avoid positioning issues caused by anchor misalignment.

After importing, let’s load the sprite. You can either drag and drop it or look for it manually, but in most cases, dragging and dropping is easier. Once this is done, let’s go to the game room. Inside the instances layer, drag and drop the player. It is currently too big, so let’s scale it down to 0.4 on both axes. Then, make sure the player (our spaceship) is horizontally centered. Turn off the grid, select the player, and center it vertically as well. For now, position it approximately 80 pixels from the bottom of the screen. We can adjust this alignment later as needed.

To make our player move, we’ll implement a simple system where the player follows the mouse. The player will have a constant Y position, while only the X position changes. The X of our player should match the mouse’s X position, allowing movement like this. This is straightforward to implement: we just check when the left mouse button is pressed and make the player’s current X position equal to the mouse’s X position.

To do this, add a mouse event (global mouse, left down). Remember, “left down” is triggered continuously while the button is held, whereas “pressed” is triggered only once when the button is initially pressed. Since we want continuous movement, we use “left down.” Also, make it global so the event triggers regardless of whether it happens inside the player.

In the “left down” event, set the player’s X to the mouse’s X using this code: x = mouse_x;
This will make the player follow the mouse horizontally. When we run the game, the player will move with the mouse as long as the left button is pressed. However, one issue remains: the player can exit the screen boundaries, which we need to fix.

To restrict movement, determine the minimum and maximum X positions the player can have. For example, moving left to the screen edge might set the minimum X to 40, while moving right might set the maximum X to 500. These values will ensure the player remains visible on the screen.

To clamp the player’s movement, add a “Step” event, which is called every frame. In this event, use the following code to limit the player’s X: x = clamp(x, 40, 500);
Here, clamp ensures the X value stays between 40 and 500. When we test this, the player will stop at the screen edges, preventing it from going out of bounds. With this, the player movement system is complete.

Transcript – Manager

Hello there and welcome to a new lesson. In this one, we are going to be creating the manager object.

This object will allow us to have one entity containing many variables and events that will affect the project from end to end. This includes variables such as the game over status, the score, and other values that need to be stored in an object dedicated solely to existing and holding those values.

While we could declare these variables in the player object, that approach would mix functionalities. The player moves, collides, and performs other actions, but the OBJ Manager’s sole purpose is to contain and organize data. It won’t move on the screen, it won’t be visible in the scene, and it won’t have a sprite or collision properties.

Understanding this concept is crucial because such a manager object is widely used in game development to keep projects organized. It’s also a best practice, helping developers code more efficiently and save time by keeping everything structured.

The first step is to create the object. Let’s create a new object called objManager. As mentioned, this object won’t have a sprite or collision. Instead, it will contain variables, which should be declared in the create event. While the manager will eventually include many variables as the course progresses, we’ll start by declaring a few that were used in previous lessons. This gives us a foundation to work with.

To declare global variables, which are accessible in any object at any time, we begin with frameRate. This variable is set to gameGetSpeed with gameSpeedFPS as the parameter. This global variable will be useful when creating alarms to ensure they trigger consistently, regardless of game speed changes due to project settings or device differences.

Next, we define variables related to bullets, such as global.fireRate and global.bulletSpeed. Initially, bullets will fire every 0.15 seconds. Declaring these variables in the manager rather than a bullet-specific object ensures that adjustments—like progression alarms to increase fire rate or bullet speed—are centralized and organized.

These variables are enough to get us started. As the game develops, the manager object will grow, containing more variables and functions to handle increasing complexity. This method keeps everything in one place and simplifies the development process.

That’s all for today’s lesson. In the next one, we’ll begin creating the bullet. Until then, bye-bye!

Transcript – Bullet – Part 1

Okay, in this lesson, we are going to be creating the bullet. We’ll use some of the variables we created as global variables in the manager. Let’s get started. This object will have both an object and a sprite. First, we’ll create the sprite, naming it SPR_bullet, and the object, naming it objBullet. Then, we’ll import the bullet sprite and keep the anchor centered. Centering the anchor ensures that the sprite aligns properly when instantiated, avoiding positional offsets. If the anchor were set to the top-left corner, the bullet would appear slightly to the left of where it should be. Centering eliminates the need for unnecessary adjustments.

Once the sprite is ready, we’ll instantiate bullets in the room. The bullets need to appear at specific intervals based on the fire rate we defined—every 0.15 seconds. We’ll handle this using an alarm. In the player object, we’ll create an alarm named shootBullet. Using the instanceCreateLayer method, we’ll instantiate the bullet at the player’s position on the instances layer. This ensures the bullets spawn directly from the player’s location.

To make the bullets fire repeatedly, the alarm resets itself after it triggers. We calculate the reset interval using the global frame rate multiplied by the fire rate. This approach ensures consistency, even if the game speed changes. The alarm must also be initialized in the player’s create event to start the firing cycle.

Now, let’s test this setup by dragging the manager object into the room. However, you may encounter an error. This happens because the player tries to access a global variable before the manager is created. To fix this, we adjust the instance creation order in the room, ensuring the manager initializes first. With this change, there’s no error, but the bullet doesn’t move and appears too large. Additional adjustments are needed to refine the bullet’s behavior.

In the next lesson, we’ll focus on making the bullet move, resizing it appropriately, and addressing other fine details to ensure the bullet functions correctly.

Transcript – Bullet – Part 2

Hello there and welcome to a new lesson.

In this one, we will finish up with the bullet itself. Right now, it is indeed instantiating the scene, but first of all, it is a little bit big. Also, it isn’t moving. So, there are some things that we still have to adjust.

The first thing that I will discuss is making the bullets smaller. There are actually two methods that we could follow. The first one will be in the creative end, doing something like image X scale. The scale by default is one, so if we give it something like 0.5 in both axes, it would have half of its initial size. If we did this, it will actually work quite well. As you can see, maybe it is a little bit too small, but anyway, it works.

However, there is another method that I also want to show. The main thing about this method is that you need no code. The main advantage of this second way is that it requires no code, but it isn’t as accurate or as straightforward as just two lines of code. Still, I wanted to showcase it anyway, and then you can choose which one to implement in your project.

Basically, for this method, we’ll click “edit image.” Actually, I meant to click “resize sprite,” which opens the sprite editor. Here, I want to scale the images. For example, in the width, I’ll set it to 20. As “maintain aspect ratio” is on, it ensures the image is kept as similar as possible. Writing something like half of the size, applying it, and looking at the result, we lose some pixels, and the sprite is slightly modified. However, when viewed without much zoom, it looks nearly identical.

There you have the main differences between the two methods. I’ll leave this method because it works quite well. But for more complex projects or if you have tons of sprites, you could write the scaling directly in the code using image X scale and image Y scale. This is another way of modifying a sprite’s size that I thought was worth mentioning. In-game, the result will be exactly the same.

Now that the sizing is correct, the next issue is that the bullet isn’t moving. It should be moving up. In the creative end, there’s a built-in variable called vSpeed for vertical movement. Here, we’ll assign this value to -global.bulletSpeed. It needs to be negative because we want the bullet to move up. When this is done, the bullet moves, creating the effect of shooting.

Let me explain why the speed is negative. In GameMaker, the coordinate system places (0, 0) at the top left. Moving right increases positive X values, and moving down increases positive Y values. Conversely, moving left or up results in negative X and Y values. So, to make the bullet move up, we set a negative speed. If we wanted to move it down, it would be a positive number.

Another advantage of resizing the sprite directly rather than in code is that the smaller size is reflected in the room view without additional modifications.

We’ve resolved the movement issue, but there’s another problem. When bullets leave the room, they continue to exist. GameMaker still calculates their speed and movement, consuming resources unnecessarily. While this may not seem like an issue in small projects, in larger ones with more bullets, it could lead to performance problems.

To avoid this, we’ll use the “outside room” event, which is under “Other.” When the bullet goes outside the room, we destroy it. Another way would be to verify the bullet’s Y position in the step event and delete it if it’s out of bounds. However, since GameMaker provides the “outside room” event, it’s more straightforward to use it for destroying objects that leave the screen. This ensures we don’t waste resources on unnecessary calculations.

This approach ensures a safer and more efficient way to manage bullets. With this, we’ve addressed the bullet’s size, movement, and existence outside the room. That’s all for this lesson. I’ll see you in the next one. Bye-bye.

Interested in continuing?  Check out our all-access plan which includes 300+ courses, guided learning pathways, new courses monthly, and more!


Viewing all articles
Browse latest Browse all 351

Trending Articles