Quantcast
Channel: Envato Tuts+ Game Development
Viewing all 728 articles
Browse latest View live

Envato Turns 10 Today!

$
0
0
Envato 10th birthday celebrations

Today marks the ten-year anniversary of the launch of our parent company, Envato, and we've got lots of celebrations planned—many of which involve giving away special discounts and other bonuses, so keep reading for details of those.

Where It All Began

Ten years ago today, Envato was launched with a simple goal: to build a space for creators to come together around a shared passion for creativity, learning, and design.

That small site has grown into a community of over seven million members to date. Find out more in this birthday message from Envato's co-founders, Collis and Cyan Ta'eed.

Special Offers

To celebrate our tenth anniversary, we've got some great limited-time offers:

More details on all those offers, plus more events like a special web-based tour of the Envato HQ, over on the Envato blog.

Learn More

There's lots more happening on the Envato blog today, so head over there to stay up to date. For example, you can:


Using a Texture Atlas to Optimize Your Game

$
0
0

Time. Months. Maybe years. You have spent your time (a lot of time) in order to create your game. Small or big, it doesn't matter. It's your game, and now you want to share it with the whole world—and maybe become famous and rich*. It's perfect: the art is good, and you are very proud of your idea inside the game. Your game.

But there is one last issue that you must resolve before the release. No, not a simple issue. The issue: the frame rate of your game is low. Very low. And that means only one thing: you need to find a way to fix it. You must. And you have no idea how.

Don't panic: there is a simple trick that can help you. It's called a "Texture Atlas".

* If you become rich thanks to this article, please remember me. Thank you so much!

What's a Texture Atlas?

If you are approaching the development of a 3D video game for the first time, you’ll begin to discover that 3D graphics are composed of several parts: 3D meshes, textures, particle systems, and many other elements that are usually drawn on the screen 30 times per second (in slang: 30 fps) during the rendering process, making the game’s world varied and lively.

Believe it or not, the first 3D video games I saw in my life had none of these elements. They were composed only of lines that formed objects or elements in 3D wireframe.

Elite - Masterpiece by David Braben and Ian Bell

Writing this is definitely making me feel old.

Back to us (indeed, to you) and to the important things, today we'll talk about the textures of the user interface (UI hereinafter) and, by extension, about all textures in the game.

In a 3D game, the UI is usually made of 3D elements (such as planes or boxes) with textures.

We mentioned before the rendering process: it’s the operation by which the elements in memory are physically drawn on the screen. It’s among the most complex and expensive processes that occur in a real-time 3D game. Then, any expedient to reduce the time taken by this process is welcome; less time spent in the rendering phase means a higher frame rate (i.e. if you reach the 60 fps you can render the image twice and then think of developing your game also for VR), or more screen elements (and then a richer game, more animated, more beautiful).

One of the means used to reduce the duration of the rendering process is a Texture Atlas: it’s nothing more than an image that contains many textures.

A Texture Atlas with some UI elements

How a Texture Atlas Works

Note: As mentioned in the previous paragraph, this article will discuss the Texture Atlas applied to the UI. However, many of the concepts explained here can also be applied to 3D models and their textures.

A Texture Atlas, we said, is a collection of textures inside a single image.

An Atlas is usually associated with a file descriptor, which indicates to the game where a texture is (in certain x and y coordinates), in order to retrieve it.

Depending on the system that you will use to generate and manage the Atlas, you will have more or less options, such as the distance between the images that compose it (reducing the risk of artifacts on the edges of the texture, caused by an overlap of two elements), or the ability to rotate the elements to optimize the space inside the Atlas (more optimized space means more images inside the same Atlas).

Different Ways to Create a Texture Atlas

There are different ways to create an Atlas. A complete development environment usually allows the internal management of the Atlas; there are also many external tools that provide a lot of additional options.

The choice of which system to use obviously depends on your personal preferences. Here we explain two of them: Sprite Packer, internal to Unity, and TexturePacker (a standalone tool, for a fee).

Sprite Packer

To open Sprite Packer, choose from the menu Window > Sprite Packer.

The management is really easy: the button Pack is used to create one or more Atlases (it depends on the number of your images and on the Atlas dimension that you want to use).

Now you can select an image to see where it is in the Atlas. If you add or remove images from your project, you must use the button Repack, to update the Atlas.

In order to configure the Sprite Packer, you can choose from the menu Edit > Project Settings > Editor; here you can disable the Atlas, activate it only for the game built, or always turn it on.

For more information about Sprite Packer, you can check the official guide.

Sprite Packer - Unity

Texture Packer

Texture Packer is a standalone tool used to manage Atlas.

You can add one or more folders from your project and Texture Packer will create the Atlas.

After that, you can choose the data format for the export. As you can see, there is also the option "JSON for Unity". This means that you can export your Atlas for your Unity project. But, in order to use them together, you must install a free editor extension from the asset store.

For more information about Texture Packer, you can check the official guide.

Texture Packer - Mac version

Why Is It Important to Use a Texture Atlas?

But why is it so important to collect multiple images into a single larger one?

Let's go back for a moment to the rendering process: if every element of the UI has a separate texture, it is drawn with a separated "draw call." This means that if in our interface we have the icon of hearts (representing the player’s energy) and the icon of the coins collected, we will have two draw calls.

Each draw call takes some time to complete, making the rendering process longer and longer. If there are five UI elements, instead of two as in the example above, there are five draw calls.

Do you begin to see the point?

More draw calls -> more time during the rendering phase -> less fps - > game with a low frame rate (with some frame drops) or fewer elements on the screen (then visually poor).

Wasting draw calls this way, unless there are special reasons, doesn’t really make sense, especially for the UI.

In fact, all the textures in an Atlas will be rendered together, in a single pass.

In Unity you can check your draw calls by the Stats button in Play Mode

Conclusion

In conclusion, especially if you're developing a game on a platform where performance is really important (such as a mobile platform):

  • You must pay attention to the number of draw calls: more draw calls means a higher rendering time (and a higher rendering time means the risk of having a low frame rate).
  • Generally, every object with a different texture can generate a single draw call (it's a generic statement: there are some exceptions, especially in the case of 3D objects).
  • One way to lower the number of draw calls is to use a Texture Atlas.
  • A Texture Atlas is basically a big texture with a group of different textures.
  • All objects that use the same Texture Atlas generate a single draw call.
  • Especially for the UI textures, the use of a Texture Atlas is a must-have to improve the performance of your project.

And... may the force be with you. And your code. Always.

Pokémon GO Style Augmented Reality With Vuforia

$
0
0

1. Introduction

Thanks to the wild success of Pokémon GO, augmented reality (AR) is getting a lot of attention in the mobile development world. The idea of augmented reality isn’t new, but only now is the technology finally getting close to maturity and commercial viability. But what is augmented reality exactly?

This a really broad concept that can take many different forms. The idea can be applied to entertainment, science, military, education, you name it. What these applications all have in common, though, is a real-time connection between the physical world and the digital.  

A live direct or indirect view of a physical, real-world environment whose elements are augmented (or supplemented) by computer-generated sensory input such as sound, video, graphics or GPS data. — Wikipedia

Concretely, AR is often realized in interactive experiences that overlay a camera feed with 2D or 3D objects, informed by some sensor data. 

However, creating an engaging augmented reality experience from scratch can be a real challenge. Fortunately, there are some solutions available that can make this job easier. One of the most solid augmented reality tools out there is Vuforia, an AR library that is compatible with Android, iOS, UWP, and some brands of smart glasses. 

In this tutorial we'll explore augmented reality using Vuforia. We'll explore Vuforia's features, possibilities, and challenges, and we'll also take a look at  how the SDK works and its main functions. We won't explore any code in this tutorial—future tutorials in this series will dig into coding in Vuforia, with step-by-step guides targeting all the library's main features.

2. Vuforia

Originally developed by Qualcomm and recently bought by PTC, Vuforia is on its sixth version. Its SDK is constantly evolving and is compatible with Android, iOS, UWP, and Unity. Unfortunately, Vuforia isn't open source, but its price range is reasonable, and there is no up-front cost for development or education. You can create almost any kind of AR experience on the most popular mobile platforms using Vuforia. 

2.1. How Does It Work?

Vuforia uses the device's camera feed combined with accelerometer and gyroscope data to examine the world. Vuforia uses computer vision to understand what it 'sees' on the camera to create a model of the environment. After processing the data, the system can roughly locate itself in the world, knowing its coordinates: where is up, down, left, right, and so on. What you do with this depends on your development goals.

There are multiple possibilities:

  • Using World coordinates: Any kind of object can be exhibited using some arbitrary reference, ignoring real obstacles but considering the World localization obtained. The object can be out of view and continue to "exist" in the same position. This is a system similar to the one used by Pokémon GO.
  • Recognizing targets: Vuforia can look for specific images as "targets". VuMarks, for example, a QR code-style image highly recognizable by the system, can be used as anchor points or references for any kind of object projected into the world. A magazine could be 'expanded' with this resource, with its pages opening rich interactions like videos, audio, and so on.
  • Recognizing simple objects:  Simple objects like boxes and cylinders can be recognized and used as anchor points. This method is useful for recognizing packages and making them interactive.
  • Recognizing complex objects: Vuforia can also look for complex objects, like toys, computer parts, gadgets, and so on. Those objects are previously scanned, conforming to specific requirements, and can later be recognized by the system. This functionality could be used, for example, to turn toys into live creatures, or to create interactive assistance for mechanics or service people.
  • Looking for words: English words can also be understood by Vuforia. The system can look for specific words and target some kind of interaction on them. This could be useful for learning tools for children or for language translation.
  • Recognizing the world's terrain: One of the most powerful features available on Vuforia is the ability to recognize the world as it is. Vuforia lets the user scan their surroundings and can do some hardcore processing to interpret the world by creating a 3D computer vision of the real world and its objects. Imagine a Pokémon GO-like game where the Pokémons can hide behind real objects. Wouldn't that be awesome?

2.2. Developing With Vuforia

Vuforia is compatible with multiple systems. Its software development kits (SDKs) are available for Android, iOS, UWP, and Unity. Once you download and install the SDK, you'll need to sign up for a developer account and create an app key before you can start to code.

Even though Vuforia is compatible with many systems, the easiest way to create engaging AR experiences using its SDK is definitely using Unity. Don't get me wrong, you can access almost everything that Vuforia offers when developing directly for Android or iOS. However, the process is much simpler when done using the prefabs offered on Vuforia's SDK for Unity.

3. Vuforia Targets

As mentioned before, Vuforia can seek 'targets' on the camera feed to create anchor points or references to be used by AR experiences. Those targets can assume many forms, and any file that has been previously processed by Vuforia target manager can be recognized. Targets can be created by the developer or created during execution by the user.

3.1

3.1. Image Targets

Any kind of image can be a Vuforia Image Target. However, the more detailed and intricate the image, the better it is to be recognized by the algorithm. A lot of factors will be part of the recognizing calculation, but basically the image must have a reasonable level of contrast, resolution, and distinguishing elements. A blue sky photograph wouldn't work very well, but a picture of some grass would work gracefully. Image Targets can be shipped with the application, created later and uploaded to the application through a cloud system, or directly created on the app by the user.

A image target being recognized on a application

3.2. VuMarks

VuMark works very similarly to a QR Code; however, it's much more versatile. It can assume many shapes and colors and adapt to a great number of environments. Its biggest advantage is that it's in total conformity with Vuforia's recognizing algorithm and will be easily 'found' by any Vuforia AR application. Vuforia also offers an Adobe Illustrator plugin that creates VuMarks.

3.3. Cylinder and Cube Targets

It's also possible to use cubes and cylinders as Image Targets. This is very appropriate to create engagement with product packages. Once recognized, the primitive object is used as an anchor point, and it seems to exist for the system's computer vision, allowing virtual objects to interact directly with the primitive. The virtual object could track the real object's position and orientation, for example.

Cylinder and Cube targets

3.4. Objects as Targets

One of the most interesting features of Vuforia is the possibility to recognize complex objects. A toy, a phone, a computer board, and other kinds of objects can be used as targets. 

To use this resource, you have to scan the object using the Vuforia Object Scanner tool, which runs only on Samsung Galaxy S6 and S7. The data scan is uploaded to Vuforia Target Manager, and the scanned object will be recognized by any compatible device using that data.

3.5. Managing Targets

There are multiple ways to create a target: 

  • The application can ship with a series of targets embedded.
  • The app can receive targets online through the cloud system offered by Vuforia.
  • The user themselves can use the device's camera to create a target. 

As a developer, you don't have much control about how the user will create their target; all that you can do is provide the user with some tips about how to chose an appropriate image as a target. However, the situation is different for the targets processed using the Target Manager.

Target Manager

Vuforia's developer portal provides us with the Target Manager tool to help manage all our apps' targets. The manager is very simple to use: you create a database to hold the targets, upload a file that corresponds to a target, and wait until the file is processed. The target will receive a unique ID and a score related to how recognizable it is and will then become part of the database, available for download or for storage in the cloud. 

There are three different types of target databases:

  • Device Databases are local databases of images or object targets that are stored on the user's device.
  • VuMark Databases are local databases of VuMarks that are stored on the user's device.
  • Cloud Databases are databases of Image Targets stored online and queried over the internet.

4. Smart Terrain

When developing a Vuforia app on Unity, there is a really exciting option available, the Smart Terrain. It allows an application to replicate 3D meshes of objects seen by the camera. 

The process works like some kind of scan, where the user uses the device's camera as a 3D scanner. As the camera scans through the ambient environment, the application creates 3D models of the recognized objects, giving the application the possibility to adjust the scenario to the real world, creating a deeply engaging experience.

5. Conclusion

There are hundreds of possibilities to explore with augmented reality, and we're just starting to scratch its surface. Many believe that AR will be a part of our future and that we'll use it on a day-to-day basis. This is a field that promises to grow a lot in the coming years, and Vuforia provides us with cool tools to create engaging experiences.

5.1 What's Next

In the following tutorials of this series, we'll work with some of Vuforia's most important tools. We'll develop a lot of small experiments to illustrate the SDK capabilities, and since Unity is the most AR-friendly environment available, everything will be developed on it. 

It won't be necessary to be a Unity expert to follow the tutorials—since our focus is the Vuforia SDK, I'll provide you with step-by-step guides that require only minimal previous experience with Unity.

If you want to learn a little more about Unity in the meantime, check out some of our other tutorials.

See you soon!

Amazon Lumberyard: UI Editor

$
0
0
Final product image
What You'll Be Creating

In this tutorial in our Amazon Lumberyard series, I'll show you how to use the UI Editor and its features. You will add and configure several elements such as background, text labels, and buttons. Then you'll learn how to create a user interface menu from scratch. Finally, you'll be faced with a challenge.

Note that you are advised to read the rest of the series in order to fully understand the notations from this part.

Who Should Read This Tutorial Series?

This tutorial series is primarily aimed at two groups of game developers: those who are completely unfamiliar with game engines at all, and those who are familiar with other game engines (such as Unity, Unreal Engine, or Cry Engine), but not with Lumberyard. I assume that you have some knowledge of computer graphics notation, so I won't exhaustively cover all notations.

The UI Editor

The UI Editor can be opened using two main ways; the first is through the Main menu using the link at View > Open View Pane > UI Editor.

UI Editor Menu

The second way is through the UI Editor icon available in the Editor toolbar.

UI Editor Menu Option 2

Open the UI Editor using one of the aforementioned options.

After the UI Editor opens, you will notice that it will be empty. When the UI Editor opens, by default it loads an empty canvas.

UI Editor UI

In order to better understand how the UI Editor is organized, we will open the Lumberyard UI canvas sample. To do so, click File > Open. Now navigate to the dev\SamplesProject\Levels\Samples\UIEditor_Sample\UI folder and select the UiSample.uicanvas file. Click Open. A shiny interface will appear as follows:

UI Editor with a loaded canvas

The UI Editor consists of the following panes:

  1. Main menu: Access to the main UI Editor features. 
  2. Toolbar: Contains commonly used features such as Select, Move, Rotate, local coordinates or UI canvas resolution.
  3. Viewport: Displays the UI elements available in the UI canvas. You can directly manipulate the UI elements inside the canvas.
  4. Hierarchy: Displays all elements inside the UI canvas using a hierarchical view. If you select an item inside the viewport, that same element will be highlighted inside the Hierarchy view.
  5. Properties: Displays the properties of each individual selected element. The properties are context sensitive, and it will display different properties for buttons, backgrounds, or text labels.
UI Editor with loaded canvas - Hierarchy and Properties pane

Note that you can increase or decrease the size (by zooming in and out) of the viewport by using the mouse wheel.

If you select the Background element inside the Hierarchy, the following Properties are presented:

UI Editor with loaded canvas - Properties pane

Likewise, if you select any of the buttons, the Properties menu will change accordingly (it is context sensitive).

UI Editor with loaded canvas - Properties pane - Button selected

Adding a Button to the UI Canvas

With the UI Editor opened, select the Background element in the Hierarchy pane. Right click on it and select New > Empty from prefab... > Button.

Add a new Button prefab

A new button should appear inside the viewport.

UI Canvas - the new Button element

You will notice that the new Button does not have the same appearance as the Play, Options, and Quit buttons.

Modify the Button Appearance

To start modifying the button appearance, let us first move the button to a new location. The new location should be under the Quit button. To perform this action, select the Button (using the viewport or the Hierarchy); then select the Move tool and finally, place it in the desired location.

UI Canvas - Button element new position

Next, you need to change the Button text. Select Text under the Button inside the Hierarchy pane. Notice that the Property pane changed accordingly. Change the Text property to About.

UI Canvas - Button properties

You can also modify the text Color, transparency (Alpha), Font path, Font size, or Font effects, and both Vertical text alignments and Horizontal text alignments. As mentioned above, these properties are context sensitive, so they change taking into consideration your chosen element. 

Now, change the Color to white and the Alpha value to 1. Then double click on the default Font path. Navigate to the fonts folder and select the notosans-regular.xml file. Finally, change the Font effect from drop_shadow to default. Your button configurations should be as follows:

UI Canvas - Button Text properties

Select the new Button inside the Hierarchy pane and modify the Sprite path. Navigate to SamplesProject\textures\UIEditor_Sample, select the ButtonNormal file, and click Open.

In order to hide the image, you need to change its Alpha. Change the ImageType to Stretched, the Color to white, and the Alpha to 0. The final configuration is:

UI Editor - Button ImageType

Set the Button's States

A button without user interaction is not a button. The next step is to add some interaction to the buttons. In Lumberyard, acting with a button is performed using the button's states. Modifying the states is a great way to send feedback to the user to let them know when they are manipulating a specific button inside the viewport.

Each button can have three states:

  1. Hover: Activated when you mouse over the button.
  2. Pressed: Activated when you click on a specific button.
  3. Disabled: Activated when you disable the button.
UI Editor - Button States

Let us start by changing the Hover state. Select the Sprite folder and change its value to ButtonNormal. By default, you should be at the last used folder. If not, navigate to SamplesProject\textures\UIEditor_Sample and select the ButtonNormal.

Now change the Pressed state by performing the same step as before, but now select the ButtonPressed file.

UI Editor - Button Sprites

At this moment, the next logical step was to test the interactions just created. However, we will leave that for a later step (in the next tutorial). For now, you will just believe that what you just performed work as intended.

Create a Button Prefab

When you need more than one type of element, you are advised to create, use and reuse prefabs. This can be very useful if you need to reuse your element across several canvases inside your project.

To save the button as a prefab, right click on it, and select Save asPrefab..

UI Editor - Button - Save as PreFab

Name the prefab CustomButton and click Save.

Button PreFab Save dialog

Now that you already created a prefab, you can delete the button from the Hierarchy.

How about the new prefab? How can we add it again? To add the prefab, you should click on the New... button and select Element from prefab > CustomButton.

UI Editor - Add the CustomButtom PreFab

Your button should appear exactly in the same place where it was previously configured.

Create a UI Canvas From Scratch

At this point you already know the basics of the UI Editor and its properties. Therefore, it is now time to create a UI Canvas from scratch.

Open the UI Editor and start by adding an Image prefab ( New... > Element from prefab > Image).

New and empty UI Canvas

A white square is placed inside the viewport. It is now time to configure it. Select the Image and double click on its name. Change it to Background.

With the Background selected, look at the Properties pane. Our objective is to fit the Background image into the complete viewport, so we must control its properties under the Transform2D properties.

Select the Anchor presets and choose the bottom right one. 

Empty UI Canvas - Anchor properties

By doing so, you are saying that the Image should cover the entire viewport. The Anchor specifies proportional positions within the parent element's rectangle.

Empty UI Canvas - Anchors - Description

Have you noticed the blue anchors that just appeared?

The blue anchors inside the white rectangle indicate the anchor points. Using the aforementioned configuration, the anchors will be automatically placed near the four corners.

However, you should already have noticed that the white rectangle size is different than the default resolution. To solve this issue, you must modify all Offsets to 0.

Empty UI Canvas - Offsets properties

Using that configuration, you can now change the viewport resolution to any given resolution and the background Image will change accordingly.

Background

Your next step is to add a pretty background image into the Background element. Download this image and place it inside your project folder (for example under the dev\SamplesProject folder). 

Note that, if you don't place the image file inside our project, Lumberyard will return a "Texture Missing Error". Proceed and select it from the Sprite path under the Image section of the Properties pane.

UI Editor - Image and background properties

Text

Add a Text prefab (New... > Element from prefab > Text). Change its Text name to "AWESOME gamedevelopment.tutsplus.com GAME" and its color to a light green. The Font size should be 60, and it should be positioned near the top.


UI Editor - Text properties

Multiple Buttons

You have a title, but you lack buttons for user interaction. Therefore, the next step is to create three buttons:

  1. Start Game: Button to load your first level.
  2. Options: to display the options canvas (more on this later).
  3. About: to display information regarding the game developers.

For each button, you will use different configurations.

  1. Start Game: You will use the Button prefab, and you don't need to modify the default configurations (only the Text name).
  2. Options: You should download this image and use it as your button. Don't forget to copy the image into your project folder (as mentioned before). 
  3. About: You should import the CustomButton prefab and change its Color to red.

What you are expected to create is something similar to the following:


UI Editor - Text description
If you have any issue in achieving the previous configuration, go to the next section and I'll walk you through it.

Buttons Configuration

You need to create three buttons with different properties. Let's start with the easy one, the CustomButton prefab. To import that button, you need to click on New... > Element from prefab > CustomButton. The button should appear. It is now just a matter of positioning it.

The second button should be Start Game. Add a Button prefab (New... > Element from prefab > Button) and change its Text name to Start Game. If you want, you can modify additional properties of this button. Is up to you to do so.

The third button, Options, is a bit trickier than the previous two. Start by adding another Button prefab (New... > Element from prefab > Button). Change its Sprite Path to the options_icon.png file. After this step, you will see the button image but with the wrong Height size. Proceed and change the Height value to 200.



UI Editor - Text Background and Buttons layout

Your last step is to save the UI canvas. Select File > Save as and name it MyCanvases.

To Be Continued

As previously mentioned, there are some steps that were not properly tested (like the button states and further user interaction). The main reason relates to the fact that you need to use FlowGraph to test those interactions. Therefore, the next tutorial in the series will be focused on FlowGraph, and we will come back to dissect this part.

Challenge

You are now challenged to create a new UI canvas for the About and Options buttons. In the next tutorial, you will be asked to connect everything.

Conclusion

This concludes this tutorial on Lumberyard. You learned how to use the UI Editor and its properties. You learned how to add and configure several UI elements as Image, Text, and Button. You are now able to create custom menus from scratch and configure its appearance. If you have any questions or comments, as always, feel free to drop a line in the comments.

Numbers Getting Even Bigger: The Growing Appeal of Incremental Games

$
0
0

Last year in a two-article series we took a look into the history and design of incremental games. In the intervening time, the genre has grown significantly in popularity, while also continuing to innovate and explore. In this follow-up piece, let's check in on the world of numbers getting bigger.

Continued Growth

The current boom in incremental games started in 2013 with games like Cookie Clicker and Candy Box, which were followed by a growing number of similar titles. These were still primarily “indie”-style games, though, typically modest and played for free in the browser, and rarely monetized other than with adjacent advertising on platforms like Kongregate. 

That was only just beginning to change last year, but now the most popular incremental games are seeing soaring numbers of players on various platforms. AdVenture Capitalist and Clicker Heroes, both of which released Steam versions in the spring of last year, each has more than 3 million owners and a 2-week active player count more than 250,000. Those are astounding numbers, and that’s just on a single platform! 

While concrete player numbers are hard to find across the variety of platforms that incrementals now appear on, the growth in popularity seems clear. As another bellwether, since the beginning of 2015, we can see the number of subscribers of the incremental games subreddit has nearly doubled too.

Sakura Clicker ownership stats
Ownership of Sakura Clicker, another popular incremental game (data via SteamSpy)

I don’t think this should surprise us much. In addition to the qualities we outlined last year, incremental games tend to excel at accessibility. They’re games that can be played for very short periods (such as while commuting, or at work or school), they are easy to start and stop playing, and they have systems that unfold gradually over longer periods. 

The ease of having one going on your phone, on a browser tab, or idling in the background makes for a low transaction cost of playing, which can be attractive to a number of people who play games. I think it’s telling that there are virtually no incremental games on game consoles, for example, since that’s an environment of dedicated play, and incremental games' strength is in interstitial play.

Moving to Mobile

One of the biggest changes, and sources of growth, has been a growing presence in mobile gaming. The majority of the most popular PC and browser incremental games now have iOS and Android releases. The two biggest incremental games on Steam I mentioned before, Clicker Heroes and AdVenture Capitalist, have more installs across iOS and Android than they do on Steam. 

Both major mobile platforms are replete with incremental games of all varieties. It seems reasonable to assume that the strong retention numbers Kongregate saw from incremental players would extend to mobile platforms as well. That’s beginning to attract attention and development from increasingly mainstream mobile game developers. Recently Bandai Namco released a Katamari game on mobile called Tap My Katamari that's a sort of endless runner (roller?) mixed with an idle clicker:

Tap My Katamari

Another recent breakout hit was Neko Atsume: Kitty Collector, which released in English last fall. Though it lacks a 'clicker' mechanic or the usual number aggregation, the fundamental gameplay loop is familiar. Cats are unlocked slowly over time in a manner largely autonomous to the player, leaving only the gradual unveiling of cute cats.

Increasing Innovation & Experimentation

I’ve been surprised by the diversity of new incremental games, and that was the original impetus for this follow-up. While the more popular incremental games show increasing refinement on their premise, there's also been a growing number of more experimental titles, adapting incremental mechanics in new ways. 

For example, Dreeps Alarm Playing Game is an idle RPG that you don't play at all. By reframing what it means to play an RPG, it becomes an essentially a non-ironic version of idle game urtext Progress Quest.

Dreeps Alarm Playing Game

Incremental games have shown an incredible capacity to subsume the tropes of other genres in their entirety. This happened first and most obviously with RPGs, but it turns out the incremental treadmill can assume the role of other game types as well. Sometimes these are more surface-level re-skins, like Time Clickers, which appropriates the visual conventions of FPS arena shooters. 

Others are more ambitious reductions, like Roguathia, a fully-automated roguelike where the player controls both the adventurers and the dungeon, endlessly upgrading both. Or Factory Idle, which cuts out all the choice and placement of building games, and leaves only the upgrade tree and sprawling cityscape:

Factory Idle

Another area of experimentation is in multiplayer-based mechanics. Games like Clicker Heroes and Idle Online Universe have optional multiplayer mechanics, where communal progress is made through collective clicking (similar to Steam's Monster community-based clicker from last summer). These somewhat call to mind Peter Molyneux's Curiosity - What's in the Box game experiment / ad from 2012, where players progressed collectively to unlock a prize (or, well, not).

Critical Inattention

Despite this proliferation and growing appeal, incremental games remain rarely discussed in games media and criticism. When articles discuss incremental games, they almost invariably describe them as mindlessly addictive or attribute their appeal to the fact that they just constantly reward the player. There are many reasons why this might be so, and it's likely due in no small part to a long-established prejudice against "casual" sorts of games. I suspect, though, that there's also an unvoiced fear of liking such naked examples of "grind" mechanics, which form the backbone of more game experiences than we often like to admit.

All that was the case a year ago as well, but a few designers are beginning to make a more critical appraisal of incrementals. There are more even-handed takes, like game designer Liz England's, who, in discussing an abandoned prototype for an incremental game, observed that

“There’s a lot of interesting design possibilities in this space. The good ones are economic systems that slowly reveal new possibilities over time, allowing for a sense of discovery." 

There’s even beginning to be formal academic interest; an upcoming paper at the Digital Games Research Association & Foundations of Digital Games conference notes how incremental games have gone from being parodies to a “rediscovered aesthetic” that “resulted in a sub-genre expanding rather than delimiting” what are considered games. 

I suspect we'll continue to see more in-depth examinations of incremental games. The game designer Frank Lantz, writing about Ian Bogost's Cow Clicker, observed back in 2011 that it is less of a joke game than it appears, and I think this view is still prescient here in 2016:

So why assume that these players for whom we are meant to feel such tongue-clucking pity were oblivious to the games satirical purpose? Maybe they didn’t get the joke the way Ian wanted them to, but then, why should they? 
He wanted them to get that a game this simple, a game this strict, a game this transparent and shallow couldn’t be playable, shouldn’t be played. And they didn’t get that part of the joke. 
But maybe it’s because that part isn’t true. They played it. They wanted to play with this ridiculous, simplistic system. Some of them mindlessly clicking it in synch with the master clock. Some of them mindfully mapping the exploitable tics (just like real gamers!) that emerge in any system, even one this featureless. 
Some of them harvesting clicks with automated scripts, and some indulging themselves in moral outrage at the transgressive heresy of the auto-clickers.

The Incremental Future

Although they can seem like reductio ad absurdum parodies of game mechanics, I think incrementals have a bright future, since there's simply something in human nature that makes us enjoy optimizing arbitrary systems. 

As a game designer, this excites me, because I think incremental games cleave away a lot of what seems to be necessary for a game. While it is hard for me to see the appeal in something like a Minecraftprison server, it's an under-studied area of design, and I'm excited to see the next year's worth of numbers getting bigger.

List of Games Mentioned

This isn't a comprehensive list of incremental games, of course (for that, IncrementalGame.com and AlmostIdle.com are good resources), but here are all the games mentioned in this article:

How to Build a Prince-of-Persia-Style Time-Rewind System, Part 2

$
0
0
Final product image
What You'll Be Creating

Last time we created a simple game where we can rewind the time to a previous point. Now we will solidify this feature and make it much more fun to use.

Everything we do here will build on the previous part, so go check it out! As before, you will need Unity and a basic understanding of it.

Ready? Let's go!

Record Less Data and Interpolate

Right now we record the positions and rotations of the player 50 times a second. This amount of data will quickly become untenable, and this will become especially noticeable with more complex game setups and mobile devices with less processing power.

But what we can do instead is only record 4 times a second and interpolate between those keyframes. That way we save 92% of the processing bandwidth, and get results that are indistinguishable from the 50-frame recordings, as they play out within fractions of a second.

We'll start by only recording a keyframe every x frames. To do this, we first need these new variables:

The variable keyframe is the frame in the FixedUpdate method at which we will record the player data. Currently, it is set to 5, which means every fifth time the FixedUpdate method cycles through, the data will be recorded. As FixedUpdate runs 50 times per second, this means 10 frames will be recorded per second, compared to 50 before. The variable frameCounter will be used to count the frames until the next keyframe.

Now adapt the recording block in the FixedUpdate function to look like this:

If you try it out now, you will see that the rewinding takes part in a much shorter time than before. This is because we recorded less data, but played it back at regular speed. Now we need to change that.

First, we need another frameCounter variable to keep track not of recording the data, but of playing it back.

Adapt the code that restores the player's position to utilize this the same way we record the data. The FixedUpdate function should then look like this:

When you rewind time now, the player will jump back to their previous positions, in real time!

That's not quite what we want, though. We need to interpolate between those keyframes, which will be a bit trickier. First, we need these four variables:

Those will save the current player data and the one from the recorded keyframe before that so that we can interpolate between those two.

Then we need this function:

This will assign the corresponding information to the position and rotation variables which we will interpolate between. We need this in a separate function, as we call it in two different spots.

Our data-restoring block should look like this:

We call the function to get the last and second to last information sets from our arrays whenever the counter reaches the keyframe interval we have set (in our case 5), but we also need to call it on the first cycle when the restoring is happening. This is why we have this block:

In order for this to work, you also need the firstRun variable:

And to reset it when the space button is lifted:

Here is how the interpolation works:

Instead of just using the last keyframe we saved, this system gets the last and the second-to-last and interpolates between them. The amount of interpolation is based on how far between the frames we currently are. 

This all happens via the Lerp function, where we add the current position (or rotation) and the previous one. Then the fraction of the interpolation is calculated, which can go from 0 to 1. Then the player is placed at the equivalent place between those two saved points, for example, 40% on the route to the last keyframe.

When you slow it down and play it frame by frame, you can actually see the player-character move between those keyframes, but in gameplay, it's not noticeable.

And thus we have greatly reduced the complexity of the time-rewinding setup and made it much more stable.

Only Record a Fixed Number of Keyframes

Now that we have greatly reduced the number of frames we actually save, we can make sure we don't save too much data.

Right now we just pile the recorded data into the array, which will not do long-term. As the array grows, it will become more unwieldy, access will take longer amounts of time, and the entire setup will become more unstable.

In order to fix this, we can institute code that checks if the array has grown over a certain size. If we know how many frames per second we save, we can determine how many seconds of rewindable time we should save, and what would fit our game and its complexity. The somewhat complex Prince of Persia allows for maybe 15 seconds of rewindable time, while the simpler setup of Braid allows for unlimited rewinding.

What happens is that once the array grows over a certain size, we remove the first entry of it. Thus it only stays as long as we want the player to rewind, and there is no danger of it becoming too large to use efficiently. Put this in the FixedUpdate function after the recording and replaying code.

Use a Custom Class to Hold Player Data

Right now we record the player positions and rotations into two separate arrays. While this does work, we have to remember to always record and access the data in two places at the same time, which has the potential for future problems.

What we can do, however. is create a separate class to hold both of these things, and possibly even more (if that should be necessary in your project).

The code for a custom class to act as container for the data looks like this:

You can add it to the TimeController.cs file, right before the class declaration starts. What it does is provide a container to save both the position and rotation of the player. The constructor method allows it to be directly created with the necessary information.

The rest of the algorithm will need to be adapted to work with the new system. In the Start method, the array needs to be initialized:

And instead of saying:

We can save it directly into a Keyframe object:

What we do here is add the position and rotation of the player into the same object, which then gets added into a single array, which greatly reduces the complexity of this setup.

Add a Blurring Effect to Signify That Rewinding Is Happening

We drastically need some kind of signifier telling us the game is currently being rewound. Right now, we know this, but a player might be confused. In such situations it is good to have multiple things telling the player that rewinding is happening, like visually (via the entire screen blurring a bit) and audio (by the music slowing down and reversing).

Let's do something similar to how Prince of Persia does it, and add some blurring.

A screenshot of the time-rewinding from Prince of Persia The Forgotten Sands
Time-rewinding from Prince of Persia: The Forgotten Sands

Unity allows you to add multiple camera effects on top of each other, and with some experimenting you can make one that fits your project perfectly.

Before we can use the basic effects, we need to import them. To do this, go to Assets > Import Package > Effects, and import everything that is offered to you.

View of the effects-menu in Unity 3D

Visual effects can be added directly to the main camera. Go to Components > Image Effects and add a Blur and a Bloom effect. The combination of those two should provide a nice effect for what we are going for.

View of the effects-inspector in Unity 3D
These are the basic settings. You can adjust them to better suit your project.

When you try it out now, the game will have this effect on all the time.

A screenshot of the effect in use

Now we need to activate it and deactivate it respectively. For that, the TimeController needs to import the image effects. Add this line to the very beginning:

To access the camera from the TimeController, add this variable:

And assign it in the Start function:

Then add this code to activate the effects while rewinding time, and have them activated otherwise:

When you press the space button, you now not only rewind the scene, but you also activate the rewind effect on the camera, telling the player that something is happening.

The entire code of the TimeController should look like this:

Download the attached build package and try it out!

Conclusion

Our time-rewind game is now much better than before. The algorithm is noticeably improved and uses 90% less processing power, it is much more stable, and we have a nice signifier telling us that we are currently rewinding time.

Now go make a game using this!

Amazon Lumberyard: How to Use the Flow Graph System

$
0
0
Final product image
What You'll Be Creating

In this tutorial, I'll show you how to use the Flow Graph System in Amazon Lumberyard. You will play with the visual scripting system to animate buttons and create interactions between the UI Canvas and your 3D scenes. Then, you will create another script to modify your 3D scene taking into consideration your avatar location. Finally, you'll be faced with a challenge.

Note that you are advised to read the rest of the series in order to fully understand the notations from this part.

Who Should Read This Tutorial Series?

This tutorial series is primarily aimed at two groups of game developers: those who are completely unfamiliar with game engines at all, and those who are familiar with other game engines (such as Unity, Unreal Engine, or Cry Engine), but not with Lumberyard. I assume that you have some knowledge of computer graphics notation, so I won't exhaustively cover all notations.

Flow Graph 

Flow Graph is a visual scripting system that allows you to implement complex game logic without the need to program a single line of code. All logic can be created, modified and removed with only a few UI interactions. Flow Graph is also useful for prototyping game-play scenarios, effects, and sounds.

At its core, Flow Graph consists of nodes and links. The former usually represent level entities or actions that may perform a specific action on a target entity. The latter are used to connect nodes and are represented as arrows that connect the inputs and outputs between nodes.

The Flow Graph can be opened in two main ways; the first is through the Main menu, using the link at View > Open View Pane> Flow Graph.

View - Open View Pane - Flow Graph

The second way is through the Flow Graph icon available in the Editor toolbar.

Open Flow Graph through the Editor toolbar

Open the Flow Graph using one of the available options.

Flow Graph after being opened for the first time

The Flow Graph editor is composed of the following components:

  1. Node graph: main window grid for displaying flow graph nodes and connections.
  2. Components: browser tree pane for all nodes that you can use.
  3. Flow Graphs: browser tree pane for graphs and entities; every flow graph created will be placed here.
  4. Properties: pane for showing node input and output properties.
  5. Search: pane for searching graphs and nodes.
  6. SearchResults: pane for displaying search results.
  7. Breakpoints: pane for displaying breakpoints; an excellent way to debug your game or prototype.

Flow Graph Scripts

Before jumping right into the action, you need to learn the basics of Flow Graph scripts.

Flow Graph scripts are organized into four different categories and contained in the Flow Graphs (number 3 in the previous image) folder tree in the Flow Graph Editor.

  • LevelThis directory contains scripts that are specific to the level that is currently open. It contains Entities, Components, and Modules. Entities files are the flow graphs created and associated with an entity currently available in the level. Components are similar, but now the flow graphs are associated with components of the level. Modules represent a list of modules that are specific to the level.
  • Global: Contains the UI Actions used to encapsulate UI logic for easy debugging and maintenance.
  • Prefabs: Similar to the entity prefab, you can also create graph prefabs. You can create an event inside a prefab, give it a name, and then reference the prefab instance as you normally do for an entity.
  • External Files: Represent a list of imported or created Flow Graph scripts.

Flow Graph Scripting: UI Canvas as the Default View

In the previous tutorial, you created a UI Canvas containing some buttons. You may also remember that it was not fully tested. It is now time to go back and finalize it.

The main idea behind the UI Canvas is the following:

  1. When you run your game (Control-G), the UI Canvas should be loaded (instead of the first level).
  2. When you click the Start Game button, two sequential actions occur:
  3. 1) The UI Canvas fades away.
  4. 2) You load your CompleteFirstLevel.

Fader Component

Open Lumberyard Editor and then the UI Editor. Click Open and open your MyCanvases.uicanvas.

Under the Hierarchy pane, select the Background element. Now, under the Properties pane, click Add Component... and then select the Fader component.

Add a Fader component into our Background element

Below the Image properties; a new property called Fader will be displayed.

The Fader component added to our Background element

This Fader property will be used to fade out the UI Canvas when you load your level.

Flow Graph Scripting

Start by opening the CompleteFirstLevel and then open the Flow Graph Editor. An empty Flow Graph should appear.

Empty Flow Graph

Under the Components pane, select the graph Start, under the Game category.

Components  Game  Start Graph

Note that you can also use the Search Keyword to search specific nodes (when you know what to search).

Components  Game  Start Graph using the Search Keyword

Now, click on File > New to create a new node graph. The default name is Default, and it's placed under the External files section in the Graphs pane.

Add a new default graph node

Now, drag the Start node into the node graph (center of the screen).

Node graph with the Start node

The Start node is the default node that is executed when you launch your game using the Switch to Game option. Therefore, normally most of the node graphs will start at this node.

Before adding the necessary nodes to display your UI Canvas, you need to learn additional information regarding the node graph and its nodes properties.

Flow Graph Nodes Description

A node is represented in Flow Graph as a box with inputs and outputs.

MovementMoveEntityTo node graph - A complex node

A node consists of input ports on the left side for receiving information and output ports on the right side for transmitting information. Output ports are activated depending on the function of the node. Ports can have the following different data types.

Data TypeColorDescription
AnyGreenUnspecified, any data type can be received
BooleanBlueTrue or False
EntityIDGreen/RedA unique value that identifies any entity in a level
FloatWhiteA 32-bit floating point value
IntRedA 32-bit positive or negative number
UInt64
n/aA 64-bit positive or negative number
StringTurquoiseAn array of characters used for storing text
Vec3YellowA 3D vector consisting of three floating-point values. Can be used to store positions, angles, or color values
Voidn/aUsed for ports that do not accept any value but are instead triggered to pass the flow of control through a flow graph

Taking into consideration the previous image:

  • The text with blue background represents the node name.
  • The text with red background represents the target entity.
  • The arrows on the left part of the node represent the input ports of the MoveEntityTo node.
  • The arrows on the right part of the node represent the output ports of the MoveEntityTo node.

To consult a complete documentation regarding the Flow Graph nodes, you should read the official documentation.

Flow Graph Scripting: Finishing the UI Canvas

When the game starts, you want to load your UI canvas. Fortunately, Lumberyard has a node for that. Select the Load node under UI > Canvas and drag it into the node graph.

Node graph with the UICanvasLoad node

This node has two main properties:

  1. Activate: it is automatically triggered when this node is called.
  2. CanvasPathname: represents the path name to your UI Canvas. Here you should put the name of the UI Canvas created in the previous tutorial (MyCanvases.uicanvas).

Select the Load node and under the Properties pane, change the CanvasPathname property to MyCanvases.uicanvas.

UICanvasLoad changing the CanvasPathname

When you press Enter key, the property CanvasPathname inside the Load node should change accordingly.

UICanvasLoad with the new CanvasPathname

This Load node is almost complete. Your next step is to connect the Start node into the Load node. This is performed by dragging a link (or arrow) from the Start output into the Load Activate input.

Connecting the Start node to the Load node

If you make a mistake when connecting an arrow, you can easily fix that. You must use the right mouse button to click on the arrow and Remove it. Note that you can also choose other options like Disable, Delay, or Any. I won't explain them in this tutorial since they're not important for what we want to accomplish.

Selecting an arrow to show its options

Since we want to use a button to trigger one action, we need to add one ActionListener node. Under the UI> Canvas, drag the ActionListener into the node graph.

Adding the ActionListener into the node graph

The ActionListener has three very important properties:

  1. CanvasID: Represents a unique integer identifier of the canvas to listen to. In other words, it relates to the canvas that is loaded in the previous node. Therefore, it must have the same identifier as the MyCanvases.uicanvas.
  2. ActionName: Represents the name of the action that the ActionListener will listen. This action name is passed when the user clicks a button.
  3. OnAction: It triggers the correct output when the canvas sends the action; it sends an order to be performed.

I'm not covering the Activate again since I explained it earlier.

The first step is to connect the OnLoad to the ActionListener Activate. Then, to pass the canvas id, you must connect both CanvasID output and input. Note that when you connect them the CanvasID = 0 changes to CanvasID.

The ActionName is not as simple since we must first define an action for our button. The idea is to add one Action click to the Start Game button.

Open the UI Editor, and open the MyCanvases.uicanvas. Select the Start Game button, and under the Properties pane, add the string NewGameClick to the Click Action.

Add an Action Click into the Start Game button

Save the MyCanvases.uicanvas and go back into the Flow Graph editor. Select the ActionListener node and change the ActionName property to NewGameClick.

ActionListener with the ActionName property configured

The ActionListener is now configured. What remains now is to configure the action performed when this ActionListener is triggered. Recall the Fader component added earlier. It is now time to use it.

For that, you need to add the Animation node inside the UI > Fader tree into the graph node.

UI Fader Animation node representation

The new properties to look at are:

  1. ElementID: Represents the unique integer identifier of the Fader element.
  2. StartValue: Represents the value for the Fader to start; it ranges from 0 to 1.
  3. TargetValue: Represents the value for the Fader to end; again, it ranges from 0 to 1.
  4. Speed: Represents the seconds taken by the Fader to fade; 1 represents 1 second, 2 would be twice as fast. 0 represents an instant action. 
  5. OnComplete: Triggers the output when the Fader is complete.

The first step is to verify the ElementID from the Fader component. For that, open the UI Editor, load your canvas, and select the Background component. Inside the Properties pane, take a look at the number inside the Id element. 

Background with Element id and Fader component highlighted

Note that you selected the Background element, since it is the one that has the Fader component. Close the UI Editor and change the ElementID of the Animation node to 2.

Next, change the StartValue to 1 and the TargetValue to 0. Leave the Speed value as default.

Animation node configured

Now, connect the OnAction (ActionListener) to the Activate input (Animation). Once again, connect the CanvasID together (Load node to the Animation node).

This Flow Graph is almost complete. To understand what is missing, play the game (Control-G). What do you see? Your menu with the correct action inside the Start Game button, but no mouse cursor to assist you. Let's fix that, then.

Look for the MouseCursor node inside the Input tree and add it to the graph node. This node only has two inputs (Show and Hide). Both are self-explanatory, right?

Connect the Start output (Start node) into the Show input (MouseCursor node). Then, connect the OnAction output to the Hide input.

MouseCursor node configured

You can now run the game and test if everything is OK. You will realize that it is.

However, we will perform one additional performance step. Since we don't want to create games with memory leaks, we should get into the habit of doing things correctly. After the fade animation ends, we should unload the canvas.

Add the Unload node (UI> Canvas) as your final node into the node graph. Connect the OnComplete (Animation) output into the Activate node (Unload). Finally, connect the CanvasID together (Load node to the Unload node).

The complete flow graph is:

The complete mygraphdemo flow graph

Save your flow graph and name it mygraphdemo.

More Flow Graph Scripting

The next step of this tutorial is to create another flow graph. However, this time, you will directly interact with the objects within your 3D scene to construct the graph. The main idea is to use the player location to interact with a proximity trigger to switch on a lamp.

In the RollupBar, select Entity> Triggers and drag a Proximity Trigger into the 3D scene.

Add a Proximity Trigger Entity

Place the Proximity Trigger near a lamp. The yellow 3d box represents the trigger area.

The Proximity Trigger at the right location

Right click the Proximity Trigger and select the Create Flow Graph option.

Proximity Trigger selected to create a new flow graph

Name it TriggerGraph and click OK. The Flow Graph editor should open. You will notice that this time the graph will be placed inside the Level > Entities section.

The representation of the Level  Entities graph

Now, rearrange your interface in order to see the Proximity Trigger, the lamp (Light1) and the Flow Graph Editor at the same time. 

Dual interface options with the Proximity Trigger and the Flow Graph

Select the Proximity Trigger and, inside the graph node, use your right mouse button and select the Add Selected Entity option.

Proximity Trigger added into the node graph

A new ProximityTrigger node will appear.

ProximityTrigger node inside the flow graph

The only properties that we will use will be the Enter and Leave outputs. The first is triggered when the player enters the Proximity Trigger area, while the second is triggered when the player leaves the Proximity Trigger area.

Next, select your Light1 element and deselect the Active option inside the Entity Properties pane.

Light1 with the Active option not selected

With the Light1 selected, inside the Flow Graph use the right mouse button and select Add Selected Entity again.

Light node inside the flow graph

Now you must connect the ProximityTrigger node with the Light node. Connect the Enter output into the Enable input. Finally, connect the Leave output into the Disable input.

ProximityTrigger node connected to the Light node inside the node graph

Save the flow graph and name it TriggerGraph. It is now time to run the game and validate your new flow graph. Everything should work as expected.

Challenge

In order to test the knowledge you've acquired so far, you are now challenged to recreate the default Lumberyard getting-started-completed-level. For that, you will need to play with the brushes, lighting, materials, textures, terrains, and flow graphs. In short, apply everything that you've learned so far. Your final level should look like the following:

Complete level for the challenge

Conclusion

This concludes this tutorial on Lumberyard. In this tutorial, I've shown you how to use the Flow Graph System. You have played with the visual scripting system to set up the UI Canvas as your default view, and have created interactions between the UI Canvas and your 3D scenes. Then, you created a script to modify your 3D scene, taking into consideration your player location and a proximity trigger. If you have any questions or comments, as always, feel free to drop a line in the comments.

Animating a MakeHuman Character in Blender, Part 1

$
0
0
Final product image
What You'll Be Creating

Welcome to part one of the MakeHuman and Blender tutorial. In this two-part series, I'll provide you with the fundamentals of creating and animating an exportable humanoid character. Both Blender and MakeHuman serve as great assets to have in your programming arsenal. You can create game-ready 3D characters, animate them, and export your characters into most game engines. Blender and MakeHuman are both open source, which allows you the opportunity to learn at your own pace. Today we will create a character in MakeHuman, export it to Blender, and discuss rendering and compositing.

Downloading the Programs

Let's get started by downloading the programs we will need. Go to makehuman.org and click the appropriate download button for your system. It is important to note that MakeHuman is Python-based, so we will need to tweak some settings in the menu to get it to work properly with Windows. MakeHuman is compatible with Windows, OSX, and Linux.

Now let's download Blender by visiting Blender.org. Blender is a great program that you can use for animating characters, creating short films, and editing video. Blender is very popular, with many studios of all sizes using it for their games and movies, including Pixar!

Download Make Human
Downloading Blender

The MakeHuman Interface

Make Human Interface

MakeHuman is one of the easiest and most fun programs to use. You can create diverse characters that can be used on many different platforms.

Tip:When you first open MakeHuman, it notifies you that characters are anatomically correct, which means both male and female characters have all of their parts. Keep this in mind if you have children around or are easily offended.

The Menu

Modeling: Let's start with modeling; here you can change the models gender, age, race, and body proportions. Moving the bar all the way to the left creates a female character, and all the way to the right creates a male character.

Geometries: Allows you to add clothing and add features to a character. Choose the clothes you like by clicking them. If you want to change your choice, press it again to avoid overlap. If you intend on animating your character, make sure to add teeth, eyelashes, and a tongue. 

Topologies: Choose either a male or female top mesh. We will explain this feature later in detail in the mesh portion of this tutorial. 

Tip: At first it will seem that adding a topology deforms your character. While it does change the mesh, your character will look perfectly normal.

Materials: Here you can change your character's skin and eye color.

MakeHuman Menu

Pose & Animate: Here you will add a rig. There are different types, and in general using Humanik is perfect since it adds fingers and bones in the eyes for winking. I'll explain more in the Blender portion.

Render/Viewer/Scene: For the purpose of animation, you can leave this menu on default.

Settings & Utilities: You should also leave these settings on default.

Help: This will pull up the MakeHuman manual and other information that would be good to read.

Top Menu: Changes your character view. If you place your mouse over the top menu boxes, you will see Load-->Save-->Export-->Undo-->Redo-->Refresh-->Smooth-->Wireframe-->Background--> You can also change the view to left, right, and back.

Save: Saves your character.

Export: We need to save our mesh format as Blender (mhx). When you choose Blender, the menu on the right changes, You can leave feet on the ground checked and leave the other menus on default. Make sure you create a folder where you can easily find your character.

Voila! You made your very own character. Now let's get them moving!

Blender Interface & Settings 

Blender is a versatile program. You can model and create objects from scratch, animate them, and create fully animated movies. At first glance, it can be quite overwhelming. We will discuss shortcuts and the basics to get you started with editing and animating your character. The mouse is an important tool in Blender; you will use it to zoom in and out, to edit, and to look at your character in 360.

In order to use Blender on your personal computer, you have to change the original settings. Let's open up the program and go to User Preferences in the bottom right. See the example below.

User Preferences

Once you click User Preferences, you will see a few tabs: Interface, Editing, Input, Add-ons, Themes, File, and System. Go to the Interface tab and check the box by Python

Python Menu

Now let's head to the Add-on tab and search for the MakeHuman add on. This ensures that we can import and use MakeHuman files.

User Settings

Look for the left-hand search box and type MakeHuman. Once you see the dialog box open, check the box on the right (see the above example). This will allow you to import and export a MakeHuman character. Click Save User Settings in the bottom left, and then click the icon next to User settings with the wrench, and switch back to 3D View.

Blender has three different render settings. For animation and character editing, we will use the Cycles Render settings. On the top menu bar, next to theScene tab, you will see Blender Render. Click the arrow and change it to Cycles Render. 

Cycles Render

Now let's delete the cube in the opening scene. In the below example, you will see the Outliner tab to the right of the screen. This is where you choose your objects, edit, etc. Let's choose the Cube by clicking it, and you will see the cube change to the color orange in real time. Right-click and choose delete. 

Object Settings

Importing Our Character

Importing Our Character

Go to File > Import > MakeHuman (mhx). Browse through the folder where you saved your character and double-click your character. At first, your character will appear all white—this is because objects import without any textures. The textures are saved in a different folder, located where you saved your character. Let's save the file. You can name it anything you want. I named mine after my character: Micheal.blend

TIPRemember to save your file, because Blender does not do it automatically.

Where Are His Eyes? Compositing in Blender

On the Outliner tab (on the far right), you will now see your character and his/her connected objects. In order to make editing our character more convenient, let's hide his bone rig for now. I'll discuss bone rigs in more detail in part two of this tutorial. 

Next to their name you will find a +. Click it and you will see a list of objects associated with your character. Directly across from your character's name is an Eye (see below example). Click the eye and the bone rig will become invisible. It remains there, but for editing purposes, you can temporarily remove it from the real-time view.

Hiding Bone Rig

Time to add materials to our character. This needs to be done in the Compositing view. Click the down arrow on the Default menu and choose Compositing. See the example below.

Composting view

You should now see three split views. On the bottom right we see our character. On the bottom left we need to change the view to Outliner, and on the top center we will see the Node editor. We also need to change from the Object view (white circle) to the Materials view, to show our textures as we edit them. See the example below.

Let's also make sure that in the Node editor window we have the Use Nodes box checked.

Setting up Compositing View

To add materials to our character, we will choose them from the textures folder MakeHuman created for us when we exported our original mhx file. 

Now that we have our Outliner view open in the bottom left-hand window, we need to click the plus sign to show our character's properties. Textures are added one by one, so let's start at the beginning by clicking Body and then Add > Image Texture. Browse for your textures folder where your character is saved, and choose your skin texture. It should be a png image with either male_diffuse or female_diffuse on the end of the extension. 

Adding textures

You will see other textures in the folder as well, such as eyes, eyebrows, teeth, etc. You will need to repeat the above step until all of your character's textures are added.

Textures Folder

Hair Texture

After we include the eyebrows and eyelashes for our character, there are extra shaders we need to add to make it look like realistic hair texture. Therefore, once you are finished adding all of the other textures, let's go back to the Eyebrows.

Hair Shaders

We need to add a Transparent and Mix Shader and connect them via the circles on the shader boxes. Go to Add > Shader > Mix Shader and now move the box with your mouse between the Diffuse and Material Output boxes. The lines should automatically connect. Let's now add the Transparent Shader and place it close to the Mix Shader. Follow the above diagram for best results. You will see your character's hair texture change in real time. 

Smile! Time to Render

Rendering is an essential part of Blender's interface. Rendering allows you to view your final character and see the end result of an animation sequence. Rendering speed is determined by your PC's capabilities. It is not uncommon to render for hours or even days depending on how complicated your scene is. For the purpose of this tutorial, we will render on low pixels. I'll discuss rendering in more detail in part two of this tutorial.

It's time to change from the Compositing view back to our Default view. You should now see your character with all of their assigned materials. Check the eyes, lips, eyelashes, skin, etc. If you notice a material missing, repeat the above steps. On the bottom toolbar, choose View > Camera (you can also click the zero on your number pad). At first, you will only see your character's feet because the camera is out of focus. 

Initial Camera Settings

The Camera is an object like any other. It can be moved and have its properties changed. You can choose any object in the real-time window by right clicking it. It will change to a pink/orange color. Once it's clicked, you will see a red, green and blue arrow appear. Move the camera in front of your character. To confirm your position, go back to View > Camera.

Camera Settings

You can also change the camera settings under the Outliner tab by clicking the video camera icon on the bottom right. Once you have your camera positioned to your liking, let's render our character. 

There are three very important things we need to do. First, go to the Camera icon (see below example).

1. Go to Output and select a destination. This will be where your rendered object will be saved. If you don't assign a place, it will save under a Blender folder. You can save your image as a png, jpeg, bmp, or many other extensions. 

2. Under Sampling you will see Render and Preview. The higher the number, the clearer the picture/animation will be. Keep in mind that, also, the higher the number, the slower it will be to render. The preview section is how it will display on your screen while you are rendering. It is a good rule of thumb to keep this number low when you are testing your scene. You can tweak these numbers until you are comfortable with your final product.

3. Once you think your character is ready for the spotlight, click Render. You will see your scene rendering slowly as well as seeing a progress bar on the top. Once it's complete, open your file destination and view your final image.

Rendering Settings
Rendering Image

Congratulations! You have successfully imported and edited your MakeHuman character in Blender. Now our character is ready to come to life. Stay tuned for part two of this tutorial, which will show you how to animate your character.


Now Available: Web Templates on Envato Elements

$
0
0
Envato Elements website templates now available

Web Templates Now Available on Envato Elements

Envato Elements launched last month with a simple offer: download unlimited fonts, illustrations, brushes and other design assets for a single monthly fee.

But the best part is that although the price stays the same each month, you get access to more and more items all the time. And today, Elements has added a whole new category: web templates.

What that means is that you can download as many professionally designed website templates as you want, and then customise them for your own needs. It's perfect for web designers, developers, or anyone else who needs a ready-to-use portfolio of website templates to start from.

And it's not just website templates, either. You can also download responsive email or newsletter templates, landing page templates, and more. 

How It Works

If you sign up for Envato Elements, you can download as many items as you like, all for a single monthly price of just $29 a month.

That includes web templates, graphics, fonts, brushes, layer styles, presentation templates, and more. The library already includes more than 6,000 items from independent designers, hand-picked and curated by the Envato team to ensure the highest quality. And we're adding more every month.

There are no credits or download limits to worry about, and no complex individual licensing either. There's a single license that covers every item and gives you broad commercial rights. So you can use everything you download with confidence in all your projects.

The regular price for all of this will be $49 a month, but right now, you can get a special promotional price of $29 a month. That price will be going up soon, but if you sign up now, you lock in that launch price for life. So if you're thinking about signing up, make sure you lock in your discount today.

What Do These Templates Look Like?

I encourage you to check out the Envato Elements site and browse the full selection of web templates, but if you want a quick preview, here are some of my favourites.

1. Shopaholic - Responsive Multipurpose ECommerce Template

Shopaholic - Responsive Multipurpose ECommerce Template

Shopaholic is a Bootstrap-based responsive multipurpose eCommerce HTML5 template. It's suitable for any type of shopping website, and it works nicely on smartphones, tablet PCs, and desktops. 

It gives you:

  • 78 fully responsive HTML files
  • 11 home-page variations
  • 11 slider styles
  • 28+ shortcode page elements
  • and much more

Shopaholic is a simple, minimal and powerful website template. It's well documented and comes with access to a support forum, and of course it's SEO optimised.

2. VSApp - Ultimate App Landing Page

VSApp is a professional HTML landing page for your mobile application. It features:

  • 5 HTML files
  • 40+ elements
  • BEM methodology
  • Ready-to-use Gulp tasks
  • Ready for unlimited color customization
  • Well-organized source code
  • Ridiculously simple to implement and customize

There's much more, too—check out the VSApp page for more details.

3. Ela - Business | BS Template

Ela - Business  BS Template

Ela is a clean, simple corporate site template, perfect for startups and software companies. It's a sophisticated site that features:

  • Bootstrap
  • Flex slider
  • Responsive
  • SEO Optimized
  • Animate CSS
  • Flat Browser PSD
  • Mockups

4. Mail Pack - Responsive Email Template

Mail Pack - Responsive Email Template

This template offers more than 18 unique modules and a stunning design. You'll get free lifetime updates and support, and it's fully responsive. It's compatible with the following email services:

  • MailChimp
  • Campaign Monitor
  • Aweber
  • iContact
  • FreshMail
  • and more

If you're looking for a beautifully designed, fully functional email template, Mail Pack is for you.

5. Adminto - Responsive Admin Dashboard

Adminto is a Bootstrap-based premium admin template. It has a clean user interface, customizable components and widgets, and three different color schemes. It is fully responsive and easy to customize. The code is easy to understand and gives power to any developer to turn this theme into real web application.

The features include:

  • Fully responsive design
  • Created using Bootstrap 3.3.7
  • Clean and intutive design
  • Fully documented
  • Rich form, widgets, validation, and wizard
  • 55+ pages
  • LESS support

6. Finch – Photography & Magazine Site Template

Finch is a responsive photography and magazine HTML5 template with various portfolio and blog options. It's suitable for artists, photographers, digital studios, personal freelancers, and any business owners that would like to showcase their portfolio beautifully. 

Finch was built with Twitter Bootstrap v3, and it features 32 cool HTML5 pages with 8 color, 3 header, 5 home layout, 5 slider and 2 layout options. Since it is responsive, the layout will adapt to different screen sizes, making your website compatible with any device such as smart phones, tablets, or desktop computers.

7. VSResume - Online CV / Resume Template

VSResume is the most advanced and original CV template on the market. The creators analyzed over 500 existing resumes on the web and implemented all the best parts in VSResume.

Its features include:

  • 2 predefined examples
  • 20+ elements
  • Keyboard navigation
  • Easy-to-use API
  • Ready for unlimited color customization

If you want a well-designed online CV/resume template that you can easily customise, check out VSResume.

Learn More

You can find out more about Envato Elements and view the full selection of web templates and other items by visiting the website. Don't forget that the current $29 monthly price will expire soon, so sign up now to lock in that low price for life.

Help! How to Fix Your Overheating Media-Making Mac

$
0
0

Apple computers are great for all sorts of media applications, and most of the time they work perfectly. Sometimes, however, problems crop up. One of the most common ones you might encounter with your media-making mac is overheating. Luckily, this problem is usually easy to fix!

Overheating has variety of symptoms. The most obvious signs are that the Mac’s aluminum body is hot to the touch, and the fans are noisily spinning as fast as they can. In extreme cases, the mac might even shut down midway through heavy workloads.

Before running out to return your Mac, there are some simple fixes to try. Let’s have a look at them.

MacBook or Mac?

After a few months of use, it’s pretty normal for a MacBook to gather some dust. This is just the result of being thrown in rucksacks, used in dusty libraries, taken outdoors, and, if you’re anything like me, generally just worked with in places no one sane would take their computer. When you put the Mac under a heavy processing load, say editing video, exporting RAW images, or rendering a complex animation, the dust can prevent it from properly cooling down.

On the other hand, if your iMac, Mac Mini or Mac Pro is overheating something major may be wrong. Although they’ll also gather some dust (more if you have furry pets), it should be no where near as much as a MacBook. They’ve got better ventilation and aren’t taken out to weird locations. An iMac, even under heavy load, shouldn’t be overheating at all.

With that said, whether you’re using a MacBook or a Mac, the tips in this tutorial will help you address some common causes of overheating.

Check the Surface It’s Resting On

The first thing to check is the surface the Mac is resting on. On any recent MacBook, the air vents are beneath the screen hinge and along the underside of the edges. If the Mac is resting on a soft surface—like the duvet in your bed—it can block cool air from entering and hot air from leaving. If you put the Mac under a heavy workload, it could start overheating. Don’t edit video in bed!

Dont edit video on your Macbook in bed
Don't edit video like this! The vents are partially blocked by the duvet.

Instead, if you’re doing processor intensive tasks on your MacBook, make sure it is resting on a hard surface like a desk with plenty of room between the screen and anything behind it. This give the MacBook’s air vents plenty of room to play.

The work surface also matters for Macs, though in a different way. Dust gathers low to the ground and in corners. Underneath a desk is basically the worst place you can put a computer. There’s no room for the fans to work, and when they do, they’re just sucking in all the dust that’s there. 

Ideally, you want to place a Mac on a firm desk with plenty of airspace. This isn’t much of an issue for iMacs because the computer is integrated with the screen, but it’s important for Mac Pros and Mac Minis.

Kill Unnecessary or Runaway Background Processes

When you’re using a Mac, there’s a lot going on in the background. Updates might be downloading, photo libraries syncing, backups running, and so on. Most of the time this isn’t an issue because Macs have plenty of processing power to spare. If, however, you need every last CPU cycle you can get, it’s time to kill some unnecessary background processes. Having too much going on could be responsible for your Mac overheating.

The other way background processes might affect your Mac is if they crash. A crashed background process can cause runaway CPU use. When you kill it, your Mac should go back to normal.

To check what’s going on in the background, open Activity Monitor. You can find it in Applications > Utilities.

activity monitor
All my Mac's processes sorted by CPU use.

Click on the CPU tab and then the CPU column to sort all the running processes by CPU usage. If any are using a crazy amount, say 120%, and it’s not Lightroom or Premiere, then a process has probably crashed. 

Unwanted background processes won’t be as over the top; they’ll probably take up between 10% and 30% of CPU power. 

quitting a process
Quitting a process I don't need.

Regardless of why you need to kill a background process, the method is the same. Select the process and click the black X button in the top left corner. A confirmation dialogue box will pop up so click Quit—or, if the process has crashed, Force Quit—to kill it. 

Clean Out the Air Vents

With the two simplest fixes out of the way, it’s time to address the issue of dust clogging the fans. You’ll need to purchase a can of compressed air. Any hardware or office supply store will sell them. 

Start by holding the can of compressed air about six inches (15 cm) from the Mac’s vents and gently start the stream. Pan from left to right, top to bottom and make sure to get both sides of the vent. You should see some dust get blown clear.

mac vents
The Mac's air vents are on the screen hinge and the curved area of the side. 

If just clearing the dust from the vents doesn’t work, you will need to open the Mac and clean the internal fans with compressed air. This is a bit more involved, and only really possible with MacBooks.

If you feel confident enough to do it, get a pentalobe P5 screwdriver (included in most computer repair kits) and remove the bottom plate from your MacBook. Be careful to note where each screw goes. Gently use the can of compressed air to clear dust from the fans and vents. Hold the fans still when you’re blowing on them so they don’t rotate too quickly. Reattach the bottom plate to finish.

 

If dust was the issue, it should now be fixed.

Take Control of the Fans

One of the best ways to stop a Mac from overheating is to start cooling more, earlier. Macs only spin their fans quickly when they’re under a heavy load so as to run as quietly as possible. If you’re not concerned about noise, you can use fans more actively to keep the whole computer operating at a lower temperature.

By default, there’s no way to control a Mac’s fans so you need to use a third-party app like Macs Fan Control.

macs fan control
Macs Fan Control shows you the temperature of every component.

With Macs Fan Control you can see the temperature of all the major components. You can use this to create a custom profile for when the fans speed up. You can also just set a constant value.

To take control of the fans, open Macs Fan Control and click on the Custom button for the fan you want to manage. Either enter a custom value or select Sensor-based Value. You can then select the component you want to use to determine fan speed. I’d recommend one of the CPU or GPU options.

macs fan control
Creating a custom profile in Macs Fan Control.

By ramping up fan speed earlier, all the components in the Mac will be kept cooler. This should hopefully prevent them from ever getting hot enough to overheat.

Take it to the Professionals

If all else fails, it’s time to take the Mac to the professionals. 

Apple has generally reliable customer service. If you’re not able to prevent your Mac from overheating with the tips in this article, bring it to them and they’ll be able to provide a better diagnosis and potentially fix it.


Animating a MakeHuman Character in Blender, Part 2

$
0
0

Blender can be used to animate pretty much anything, from exporting a character into a game system to creating a fully animated movie. It's an excellent tool to learn. 

In part one of this series, you learned how to create and import a MakeHuman character into Blender. In this tutorial, you will learn how to animate your character and export an animation into a movie file.

Let There Be Light

An essential part of a good render is lighting. Good lighting can produce an intriguing, life-like scene, while bad lighting can do the complete opposite. In part one we discussed how, just like the Camera, the Lamp is also an object that can be edited. Let's learn about lighting in the Blender world. 

Lighting in Blender

Choose the Lamp from the Hierarchy window on the right. Once chosen, a Lamp/Lightbulb icon will appear in the properties window on the bottom right, as shown in the above photo. Click Use Nodes to change your lamp settings to shine brighter, change the color, and choose between a Spot, Area, and Point light. Most animations will be a combination of all of the above to capture the best lighting for your scene. 

Lighting in Blender Two

The Animation View 

In part one we briefed on the subject of rendering an image. Animation scenes are rendered individually as images. In order to render an animation in Blender, we will need to save our images as separate clips, which are then combined to create an animated scene. Blender provides a video editor that combines the images.

Let's begin by changing our view from Default to Animation.

Animation Window

Time to get familiar with the animation view. In part one we made our character's bone rig invisible. In order to animate our character, we will need to make it visible. If you look to the far right, across from your character's name, you will see the Eye icon. It will seem grayed out, and once we click the Eye, the bone rig will instantly appear.  

On the left side of the screen, we have the Dope Sheet, which will show you all of your animations. Underneath, we have the Graph Editor, which allows you to edit animations individually. Along the bottom is our timeline, where you can play, rewind and edit your scene's length. Hang tight—you'll see all of the above windows in action once we create our first animation. 

Animation Screen

Our character is shown on the main screen. On the top right, you will see a smaller version of your character in a grid format. Blender allows you to open numerous windows at the same time. If you look at the corner of your current window you will see 3 diagonal lines. You can expand the window by dragging your mouse over it. To remove it, drag it back.

Expanding The Window

Attention!

To bring our character to life, we will need to be in Pose Mode. You can move any bone on your character by right-clicking on the bone and using the toggle arrows to rotate and move them. 

We want to place our character in a more relaxed position. Choose his right upper arm bone and rotate it by choosing the Rotate tool. Slowly rotate it closer to his body. Now let's move his legs, head, and back by repeating the above process until you are comfortable with his idle position. 

Rotating the characters arm in Pose Mode

Remember to save your project. If you make a mistake, no worries—you can reset his position by selecting all the bones by choosing Bone Groups in the Hierarchy and press Control-G, Control-R to start over. This will put your character back in T-pose.

Are You Winking at Me?

Our first animation will be fun and simple. We will make our character blink and turn his head. We need to right click on our character's Upper lid bone, starting with the left. To choose two bones at once, hold the Shift key and click on the second Upper lid bone. The chosen bones will be highlighted in yellow. You will also see the name on the top right screen as shown below.

Upper Eyelid Bonew

Important to Note

To make sure we start our animation correctly, let's double check that you have your Start Frame at the beginning, which should be 1. The End Frame is where your animation will end. The number to the right of that is your Current Frame; let's shorten it by typing 20 in that box. When animating, you will use all three frames repeatedly. 

To the right, you will see a red Record button; when pressed, your animations will record automatically. Next to the record button are two keys; let's scroll down and choose LocRot. This will change an object's location while rotating.

Those are the basics to get any animation started, and highlighted below are the items to keep in mind.

Important Things To Note

Let's begin by pressing the record button. It is a good time to save your project. You should have your Frame rate at 1 and both bones of your character's eyelids chosen. Type the number 3 in your Current frame. Click on the Rotate tool. Rotate your character's eyelids closed. 

You will see an alert on the top right informing you that AutoKeying is on. You should now see a yellow line on your timeline; this is your first recorded keyframe. Move your Current Frame to 5. Time to open his eyes, so gently rotate them open. Don't get nervous if you destroy his eyes on your first try. That's why it's important to save your file. Animation is mastered by trial and error. 

You can now see your Dope Sheet, Graph Editor, and Timeline at work.

The Dope Sheet Graph Editor and Timeline at work

At this point, we should have a blinking animation. Click on the rewind button so that you are at Frame1 and press Play. Congratulations—you created your first animation! Let's repeat the above process three more times, both opening and closing your character's eyes. Skip ahead three or four frames. Remember to save your file!

One of the great things about the Blender animation timeline is that you can add other unrelated animations as well. After we are all done with a couple of blinking cycles, let's go to Current Frame 5. This should have no animation (no yellow line). We are going to tilt our character's head a bit. 

Choose your character's neck bone and tilt it a bit to the right with the rotation tool. This time, we will type I to insert a keyframe. You will see a yellow line appear. Skip ahead to frame 8 and rotate his neck a little more. Continue making small movements by inserting a keyframe and skipping ahead two or three frames until you get to frame 20.

Time to Render

Now it's time to render our animations as images. Let's take this opportunity to create a specific folder in our file titled Image Clips. It will keep our files organized. Go to your Default view, and just as we did in part one, we will render our images, except this time we are rendering numerous images: 20 to be exact. 

Double check that your Output folder and image settings are correct. This time, we will choose Animation instead of Render. Depending on your system, this may take anywhere from 20 minutes to two hours.

The Video Editor

Blender has a basic video editor that will help you turn your animation images into a video clip. The video editor is easy to use and can be used for adding images, music, and other videos. 

For the purpose of this tutorial, I will show you the basics of turning images into a video. On the bottom bar you will have the Video Sequence Editor, which is where you add videos, images, and sound. On the top left, we need to change our view to Properties. 

The Video Editor
The Video Editor screen 2

On the bottom bar, choose Add > Images. Go to the Images folder where you stored all of your rendered animation images and Select all then Add. You will now see a clip. If you hit Play, your images have now turned into a video. It will play very fast, and this is where your frame rate comes into play. The higher the number, the faster the scene will be. You will have to test them until you are completely satisfied. 

Let's choose Custom and type in 10 FPS. Now scroll down and under Output choose your folder. You will also see different video formats under Output. What has been proven to work best is H264. You can leave the default to AVI. This will save the video in your default video player. There is no sound so we are pretty much done with settings. Let's click Render Animation. After rendering is complete, you will see a movie file in your folder. Voila! You have created your first animated scene.

Tips & Shortcuts

  • You can only select and move bones in Pose Mode.
  • Click F12 for an instant render to check position, lighting, etc.
  • You can switch to Pose Mode by pressing Control-Tab
  • The higher your Frame Rate, the faster the scene will play.
  • Shift + mouse scroll will move your whole character up and down.
  • Press I to record a Keyframe.
  • To start over, select all of your character's bones and press Control-R, Control-G to go back into T-pose.
  • Control-Z will undo your last action.

Above I've added some tips and tricks to help you create your next masterpiece. I hope you enjoyed this Blender animation tutorial. 

Building a Beat 'Em Up in Game Maker, Part 1: Player Movement, Attacks, and Basic Enemies

$
0
0

In the days of the neighborhood Arcade and the early days of console gaming, Beat ’Em Up games were one of the most popular genres. Born from the marriage of the platformer and the Fighting Game, Beat ’Em Ups were combo-based action games where the player fought off hordes of enemies while progressing through mostly horizontal environments. 

In modern gaming, Beat ’Em Up classics like Turtles In Time and X-Men the arcade game have been replaced by 3D Brawlers like Shadow of Mordor and Arkham Knight, the AAA evolution of these quarter-guzzling classics. 

In this article series, we‘re going to look back and explore how to make a classic Beat ’Em Up game.

Getting Ready

Before moving forward, let’s talk about the skills necessary for the tutorial. The game we’re making will be built in Game Maker Studio Pro, which is available for free from the YoYo Games website

You should also have at least a basic understanding of GML, Game Maker’s built-in coding language. While I will be taking the time to explain how the code works and what everything does, we will be talking about some moderately advanced programming concepts, including AI, so it’ll be easier to understand if you already have a strong foundation to work from. 

Also make sure you download the Part 1 Assets zip file that’s included at the top of this article, since it includes the graphics and sounds you'll need to complete this article This zip file also includes a completed Game Maker project for this part of the series, so you can refer to it if you run into any issues.

Now open Game Maker, and let’s get started.

Importing Graphics

In this article we’re going to create a player object and an enemy object we can kill, and we'll give the player the ability to move around and attack. Before we can do any of that, though, we need to add some graphics we can use for the player and the enemy. Let’s start with the Player Idle animation. 

  1. Right-click the Sprites folder and choose Create Sprite. 
  2. Name the sprite SPR_PlayerIdle.
  3. Use the Load Sprite option, and navigate to the image files you downloaded for this tutorial.
  4. Choose Assets > Images > Player > PlayerIdle.png. This is the only frame we’ll need for this animation.

Now that the image is imported, we need to set the origin. If you take a look at all of the player animations, you’ll notice that the images are not all the same size. This means that the character’s position is not the same in each image either. If we used these images together as-is, it could cause the character to shift position as they animate, and throw off our bounding boxes. In the image below, you can see the first frames of three different player animations, and how their positioning compares.   

The first frame from three of the animations overlaid on top of each other for comparison

If we transitioned between these animations without adjusting the origins, the player’s position would clearly change from one to the next. To resolve this, we can manually set the origin so that it’s in roughly the same position for every animation, and the Player won't shift.

When doing this, it helps to have a reference point on the character to use as a guide so you can easily tell if the origin needs to be adjusted. For all of the character graphics, I will be using the large spot on the chest as my reference point. I’ll position the origin at the very bottom of the image and on the left side of the spot. I've increased the saturation on the image below so you can easily see what I'm referring to.

An exampleof how the origin should be setup for the images incldued with the tutorial

For the Idle animation, the origin will be at x = 40, y = 117.

Now we need to import the rest of the sprites we’ll use in this article. Use the table below to see which images to import, what to name the sprite, and where the origin should be located.

Sprite NameImagesOrigin
SPR_PlayerWalking
PlayerWalking1.png,
PlayerWalking2.png,
PlayerWalking3.png,
PlayerWalking4.png,
PlayerWalking5.png,
PlayerWalking6.png
X = 43, Y = 117
SPR_PlayerBasicPunch
PlayerPunchA1.png,
PlayerPunchA2.png,
PlayerPunchA3.png,
PlayerPunchA4.png,
PlayerPunchA5.png
X = 55, Y = 122
SPR_PlayerStrongPunch
PlayerPunchB1.png,
PlayerPunchB2.png,
PlayerPunchB3.png,
PlayerPunchB4.png,
PlayerPunchB5.png
X = 60, Y = 124
SPR_PlayerHit
PlayerHit.png
X = 43, Y = 117

We also need to import some of the Enemy graphics. We can do this the same way. These images will be found in the Assets > Images > Standard Enemy folder.

Sprite Name

Images

Origin Position

SPR_EnemyIdle

RedEnemyIdle.png

X = 40, Y = 117

SPR_EnemyWalking

RedEnemyWalking1.png, RedEnemyWalking2.png, RedEnemyWalking3.png, RedEnemyWalking4.png, RedEnemyWalking5.png, RedEnemyWalking6.png

X = 45, Y = 117

SPR_EnemyHit

RedEnemyHit.png

X = 46, Y = 117

Creating Our First Game Objects

Now that we have all the graphics we’ll need, we’ll start building our game by creating a Player object and an Enemy object. 

  1. Right-click the Objects folder and choose Create/Insert Object.
  2. Name the new object OBJ_Player.
  3. Set the object’s sprite to SPR_PlayerIdle.
  4. Use Add Event > Create.
  5. Under the Control tab, add an Execute Code action.
  6. Add the following code:

The code we have above is setting some basic variables for our Player object. As we develop our game further we’ll add more variables, but let’s look at what we have so far. 

Speed is the movement speed of the player, while SpeedMod will modify the player’s speed based on powerups, and debuffs.XSpeed and YSpeed will be used to actually set the Player's speed in each direction when they're moving. IsAttacking and IsHit tell us whether the player is attacking or hit so we can stop him from moving, and AttackType tells us what attack he’s using. Finally, MaxHP and CurrentHP keep track of the player’s health.

You should also notice the OnGround and GroundY variables. These variables aren't as important now, but they'll be used later when we add things like Knockback.

The last thing this code does is set the image_speed, which controls how quickly our animations will play.

While we're at it, let's make the Enemy object too.

  1. Right-click the Objects folder and choose Create/Insert Object.
  2. Name the new object OBJ_Enemy.
  3. Set the object’s sprite to SPR_EnemyIdle.
  4. Use Add Event > Create.
  5. Under the Control tab, add an Execute Code action.
  6. Add the following code:

As you can see, our Enemy is currently very similar to our player, and uses many of the same variables. The one one extra variable is SideMod, which we will eventually use for our Enemy's AI.

Adding a Room

With our basic enemy and player objects set up, let’s add a room to our game for them to run around in.

  1. Right-click the Rooms folder and choose Create/Insert Room.
  2. Leave the room size as is for now.
  3. Go to the Objects tab.
  4. Select the OBJ_Player and add it to your room on the left side.
  5. Select the OBJ_Enemy and add a few enemies on the right side.

Below you can see what the basic room could look like, but it’s alright if you make yours slightly different than mine.

Towards the end of this series we will make a more interesting level, but this should do for now.

An example of a possible layout for the room

Adding Shadows

Before we add movement, let’s see if we can improve the look of the game a bit. Right now, things look very flat since the characters are standing in front of a uniform gray background. We can fix this by adding shadows under the characters to simulate depth and make it look as if the characters are standing in an environment, rather than a blank gray room.

  1. Open the Player object and choose Add Event > Draw > Draw.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

All this code does is draw a slightly transparent, dark grey circle under the player character. It’s very simple, but when we see it in-game, it will do a lot to make the character feel as if he’s standing on the ground. When you go in-game, the character should now look like this:

The player character with a shadow implemented

Much better!

Now that the player character looks good, though, we should do the same for the Enemies. Follow the same steps to add a shadow for the enemy characters.

When you’re done, if you test your game, it should look like this:

All of the characters with shadows enabled in-game

Little changes like this can really improve a game and help it feel much more interesting. In this case the shadows did a lot to help "sell" the environment and give it depth, even if it's not perfect.

Now that our game is a bit more interesting looking, we can add some actual gameplay.

Player Movement

So far we’ve set up our characters, but we haven’t actually told them how to move or attack. Since our player can’t attack the enemy from all the way on the other side of the field, we’ll start with movement. This is a pretty long piece of code, so we’re going to make it incrementally and add it in piece by piece. Let’s add the first piece.

  1. Go to the Player Object.
  2. Use Add Event > Step > Step.
  3. Under the Control tab, add an Execute Code action.
  4. Add the following code:

All this code does is check that the player’s HP is greater than 0. If it’s not, the player is destroyed.

Now add this chunk of code into the if part of the statement:

This portion of code checks whether the A or D keys are being pressed, and sets the XSpeed of the Player accordingly. If the A key is down the Player's XSpeed is negative, meaning they move backwards, and if the D key is down, it's positive, meaning they move forward.

We can't just move forward and back, though. We need to be able to move up and down as well, so let's add another piece of code to handle W and S.

Add this chunk of code into the if part of the statement, after the previous chunk:

This code does the same thing as the previous one, except with the YSpeed.

You might be thinking to yourself, "This is great, my character is ready to move." In reality, though, all we've done so far is set their speed, and we still need to actually move them. Since the next block of code is a bit longer, we are going to again break it into smaller chunks. Let's start out by adding a stubbed version so you can see what it will do.

Add this chunk of code into the if part of the statement, after the previous chunk.

So as you can see, we are going to do three things. 

First, we physically move the player using the XSpeed and YSpeed variables; however, we ignore the YSpeed if the Player is not on the ground. 

Next, we change the direction of the Player's sprite based on the direction that the Player is moving in. This way if the Player is moving left, they are facing to the left, and if they're moving right, they are facing to the right. 

Finally, we animate the Player so that they are using the Idle sprite when they're not moving and the walking sprite when they are.

Let's replace these comments one at a time. Replace the comment //If the player is on the ground... with the following code:

The main if statement for this code checks whether the Player is on the ground. If they are, it then has an interior if statement that determines whether the Player is moving diagonally, and slows them down to prevent them from moving further than they were if they moved in one of the cardinal directions. If the player is not on the ground, only their X movement is considered.

Next, replace the //Change the direction of... comment with the following code:

This code is much simpler than the last block. All it does is set the Xscale of the player's sprite based on the direction they're moving. The reason we check whether XSpeed is equal to 0 is that if we didn't the Player would be 0 pixels wide whenever they weren't moving.

Finally, replace the //Animate the Player... comment with the following code:

This is another pretty simple piece of code. If both the XSpeed and YSpeed of the Player are 0, and the player is on the ground, it must mean that the Player is not moving, and it sets their animation to Idle. Otherwise, if the XSpeed or the YSpeed is not equal to 0, the player is on the ground, and they are not already using the Walking sprite, it sets their animation to Walking.

The one really important part about this code is that we verify they are not already using the walking animation before we set it as their animation. If we didn't do this, then every frame the Player is moving this code would come back as true, and it would constantly try to restart the walking animation. By checking to make sure they're not already using that animation, we avoid this issue and allow the animation to loop normally.

The very last thing we need before our basic movement is complete is to add this code to the very end of the Step event, after the if/else statement:

This code sets the GroundY for the player and sets their depth on the screen based on their GroundY. The GroundY value will be used when the player gets knocked back or thrown to keep track of where the player’s shadow is on the ground and what height they started at. This variable also helps the player character keep track of how high they are and when they should hit the ground.

The depth statement after that makes it so that the higher on the screen the player gets, the further back they will be drawn. This way, when the player is running past enemies and moving around the field, they are always drawn correctly relative to other objects/characters.

If you go in-game and start testing, you should now be able to run around the game area with the player. You may notice some issues, though, when you walk up to enemies. 

An example of bad depth drawing

The reason the depth isn’t working as I described above is because we need to add a similar statement to the Enemy’s code so that their depth is set correctly as well. 

  1. Open the Enemy object and choose Add Event > Step > Step.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

Now if you go into the game, you’ll see that the depth is working correctly. When you move around near the enemies, you should pass in front of and behind them correctly.

The corrected depth drawing

Preparing for Attacks: Layers

Now that our initial movement code is complete, we can move on to attacking. Before we can get to the actual attack object, though, we need to add two things. 

First, we need a new constant which tells us how close characters must be to hit each other. In a Beat 'Em Up like this, we are simulating 3D depth. We do this in a few ways, and one way is by keeping track of player depth using the depth variable as we did above. The other way we'll do this is by defining how far apart two objects can be on the Y-plane, before they can no longer interact. This way, even if the sprites overlap/collide, the collisions will only count if the characters are close enough in the game space to allow that interaction and the perspective won’t cause any problems. 

If you’re still not sure what I mean, take a look at the image below:

A collission that should not be considered valid for an attack

In this image, the player and enemy are technically colliding, but you can tell from the perspective that they are not really close enough to interact. By creating a constant called LayerSize, we can set the maximum vertical distance to allow before two objects can no longer interact.

  1. On the sidebar under Macros, choose All Configurations.
  2. In the very first macro, enter the name LayerSize and set the value to 35.
  3. Press Okay.

This was a value I came up with over time which I thought worked well, but if you'd like you can play around with increasing or decreasing this value to find something that works better for your game.

As we make our attacks, this constant will help determine whether the attacks hit.

Preparing for Attacks: Stunning Enemies

The other thing we need to do before making any attacks is set up the enemy's hit animation, so that they will react when we attack them. For this we will use the EnemyHit animation, which we imported earlier, and the IsHit variable.

First, we’ll go into the step event and modify the code so that the hit animation gets used. 

  1. Open OBJ_Enemy.
  2. Select the Step event, and open the code action.
  3. Add the following code to the beginning of the event:

Just to make sure this code works, go into the Enemy's create event and change their IsHit variable to true. Then go in-game, and take a look at the Enemy's animation. You should see something like this:

The Enemy Hit animation

While the Hit animation is definitely working, you'll probably notice that it never ends. The reason for this is because we don't have any code that resets the Enemy's IsHit state after a certain amount of time. So once we set it to true, it stays that way forever.

To make this work, we are going to set up an alarm which will reset the IsHit variable, and make the enemy Idle again when it goes off. Then, whenever the enemy gets hit, each attack will contain a statement that tells the Enemy how long they should be stunned before returning to idle, and will start the alarm with that amount of time.

  1. Go to the OBJ_Enemy and choose Add Event > Alarm > Alarm 0.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

All it needs to do is reset IsHit, and the Step event will take care of the rest. 

You can’t really test this to make sure it works yet, but if you add the code below to the end of the Create event, you should briefly see what we just set up in action when the game first starts. Make sure you remove this code, though, and set IsHit back to false, before you move on.

Creating the Attack Object

Now that we have all that prep work out of the way, we can start on the actual attack objects.

First, we’ll need to make a parent Attack Object to contain all of the attack’s stats, such as how much damage it does, what the hitbox looks like, what particle effects should be used, etc. Making a unique object for each attack is better practice than forcing the Player or Enemy objects to store all the relevant information, and having a parent object makes doing that much easier. It also makes the attack code more versatile, and allows us to program a single attack which can be used by multiple characters.

To make the first attack object, follow these steps:

  1. Right-click the Objects folder and choose Create/Insert Object.
  2. Name the new object ATK.
  3. Use Add Event > Create.
  4. Under the Control tab, add an Execute Code action.
  5. Add the following code:

The very first line of code sets the Attack's depth the same way we set the depth for the Player. The rest of the code, though, establishes some important variables for the Attack. Let’s look at what these variables do. Damage is how much damage the attack does. StunLength is the number of frames that the enemy will be stunned for with the IsHit variable. Owner is who made the attack. This can be either the Player or Enemy, and prevents enemies from hurting each other. DMGFrame allows us to say when the attack will deal damage. 

In Beat ’Em Ups, timing is important, and attacks should only deal damage if they hit at the right time. Take a look at this attack:

An example attack from an Enemy we will implement in a later tutorial

If you took damage before the enemy’s hand came down, you’d feel cheated, since it would look as if it shouldn’t have hurt yet. The DMGFrame variable tells the attack object which frame should deal damage, so that collisions during every other frame are ignored. Things like this form the basis for all timing-based combat games, from Turtles in Time to Dark Souls, and make it possible to “read” your opponents' attacks and dodge before they hit.

Now let’s add the collision code for the attack so it deals damage when it hits.

  1. In the Atk object, go to Add Event > Collision > OBJ_Enemy.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

The code we have above fires whenever the attack collides with an enemy object, and uses a simple if statement to determine whether the attack hits. The if statement tests four things: 

  1. Is the current frame equal to the damage frame?
  2. Is the difference between the depth of the attack and the depth of the enemy less than the LayerSize?
  3. Do the attack and the enemy have close Y values? In other words, are they both on the ground, or both close to each other in the air?
  4. Was the attack made by the Player? Since this event applies to collisions with enemies, we check to make sure the Player made the attack. You could remove this check if you want enemies to be able to hurt each other.

If all of these conditions are true, then the attack was successful, and the enemy takes damage and gets stunned.

We also need to do something similar for collisions with the Player. 

  1. In the Atk object, go to Add Event > Collision > OBJ_Player.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

This is the same code as the Enemy collision, except that it checks if the attack was made by the Enemy, rather than the Player, and prevents the Player from taking damage from their own attacks.

Now we need to make a hitbox for the attack as well. Hitboxes are the portion of the sprite that is considered "collidable", and they are used to ensure that only certain portions of the sprite cause a collision and cause the character to get hurt. For example, if I go back to the Yellow character's attack, I would only want a small portion, outlined in red below, to be collidable.

The portion of the Enemys attack which should damage the Player

If anything other than that arm caused the Player to take damage, they'd feel upset and the game would seem unfair. To solve this problem, I can use a hitbox that only registers that portion of the sprite and ignores everything else. 

You can import the hitbox for our attack using the table below. Then assign the hitbox as the ATK object’s sprite once you're done.

Sprite Name

Images

Origin Position

SPR_BasicPunch_Hitbox

BasicPunchHitbox1.png,

BasicPunchHitbox2.png,

BasicPunchHitbox3.png,

BasicPunchHitbox4.png,

BasicPunchHitbox5.png

X = 55, Y = 122

When the Player attacks, they will set their sprite accordingly, but using the hitbox sprite for the ATK's sprite ensures that only that portion of the attack animation will register the collision.

The last thing we have to do for the attack is make sure it is destroyed when the attack is over. If we don't destroy it, the attack will continue running infinitely and kill our enemy almost right away. To ensure this doesn't happen, we are going to use an Animation End event.

  1. Go to the ATK object and choose Add Event > Other > Animation End.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

With this event, the attack object will immediately destroy itself once it’s finished running, and it won’t stick around to cause us more issues later.

Now you just have to uncheck the Visible checkbox on the ATK Object so that the hitbox can’t be seen.

That completes our base Attack object, but we still need to build our first actual attack by extending the base object. Using the ATK object as a base for other attacks makes it easy to quickly build a large variety of unique attacks.

  1. Make a new Object called ATK_BasicPunch.
  2. Set the Parent to the ATK object.
  3. Assign the Sprite SPR_BasicPunch_Hitbox.
  4. Use Add Event > Create.
  5. Under the Control tab, add an Execute Code action.
  6. Add the following code:

The Basic punch is now technically complete since it extends the ATK object and inherits all of the properties laid out in the Create event. If you wanted your basic punch to be more powerful or stun for a longer period of time, though, you could change those properties by setting them again here. 

For example, you could use:

This would make the attack deal more damage, but stun for fewer frames. 

You could also use:

This code would deal less damage, but stun the enemy longer.

You can feel free to modify the base variables Damage, StunLength, and even DMGFrame (make sure that this number is no more than 5, since the attack is only 5 frames long) however you want, and make many different variations on the same type of attack. No matter what you do, though, make sure that your new attack has the ATK object set as the Parent, and has the event_inherited() line at the beginning of any event that the Parent class also utilizes.

Making the Player Attack

Now that our attack is finished, our player needs to be able to use it. For our combat system, we are going to utilize three possible control schemes to accommodate many different players. 

We are going to let players use IJKL, the numpad's 4856 keys, and even the arrow keys, as possible layouts for the attack buttons. This gives players the ability to use any setup they prefer based on their keyboard size/layout. On top of that, since all three of those sets have the same basic layout, it’s easy to make them all work. J, 4, and Left Arrow will be light attacks, I, 8, and Up Arrow will be strong attacks, K, 5, and Down Arrow will be Grabs, and L, 6, and Right Arrow will be Specials.

  1. In the Player object, choose Add Event > Key Press> Any Key.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

First, this code checks if the Player is pressing any of the valid Light Attack buttons we discussed before, the Left Arrow, the 4 key on the numpad, or the J key. If so, it sets the Player's AttackType to a Basic Punch. After determining the AttackType, it checks to make sure the user is on the ground, and calls the Attack event if they are.

The Attack event will create the attack object based on the attack the player used. It may seem strange that we’re making this a separate event, since our code is so simple, but as we add more attacks, and eventually implement combos, it’ll make our code much easier to manage if these elements are separated.

  1. In the Player object, choose Add Event > Other > User Defined > User 2.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

This code is actually pretty simple, even though it looks complex at first. 

First, we make a temporary object to store the attack itself. Then, as long as the player hasn’t just been hit, and they’re not Dead, we determine which attack is being used, set the animation, and make an attack object of that type. Finally, if an attack object was created, it sets the player to be attacking, sets the direction and speed of the attack to match the player’s, and sets the Owner value of the attack appropriately. 

At this point, we can go into the game and test this attack. If you walk up to the Enemy and use one of the light attack buttons, you should see the player attack and the Enemy get hit. 

You may notice an issue, though. No matter how long you wait, the Player’s animation never switches off the attack animation, even though the Enemy is no longer taking damage. You'll also notice that you can no longer move.

This is the same issue we dealt with earlier with the Enemy and their hit animation. Just like with the Enemy, we need to set up a system that resets the Player's IsAttacking variable when the attack completes. We’re going to do this with another Animation End event.

  1. Go to OBJ_Player and choose Create Event > Other > Animation End.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

Now when you go in-game, the attack should work exactly as you expected, and the animation should end when it's supposed to.

Adding Sound

Our attack works well in-game, but it doesn’t do a good job of drawing the player in. Part of the problem is that we don’t have any sound effects to give the player feedback when they hit or miss with an attack. Let’s resolve this issue before we call the Attack object complete.

We’ll need to import two sounds for the attack, a Hit sound and a Miss sound. Follow these steps to import the first sound.

  1. Right-click the Sounds folder, and choose Create Sound.
  2. Set the Name to SND_BasicPunch1.
  3. Import the sound file LightPunch1.wav from the project’s assets.
  4. Set the Sample Rate to 48000.
  5. Set the Bit Rate to 320.
  6. Press Ok to save your sound.

Great work! You’ve now imported your first sound effect.

Now we’ll do the same thing for the Miss sound.

  1. Right-click the Sounds folder, and choose Create Sound.
  2. Set the Name to SND_MissedPunch.
  3. Import the sound file Miss.wav from the project’s assets.
  4. Set the Sample Rate to 48000.
  5. Set the Bit Rate to 320.
  6. Press Ok to save your sound.

Now that we’ve imported our sounds, we need to add some new variables to our attack object so it can use the sounds correctly.

  1. Go into OBJ_Attack and open the Create Event.
  2. Add the following code to the end of the Execute Code action:

These three variables are pretty simple. The HitSound and MissSound variables allow us customize the hit and miss sounds for each attack in their create event, the same way we can customize the other properties of each attack we create. The Hit variable allows us to check whether the attack was successful before playing the Miss sound.

With the variables in place, we need to implement them. First we’ll implement the Hit sound.

  1. With OBJ_Attack, open Collision with OBJ_Enemy.
  2. Add the following code to the end of the if statement that confirms the collision is valid:

All this code does is play the HitSound and set the Hit variable to true when the attack collides with an Enemy.

We can use the same code for the Player collision event as well.

  1. With OBJ_Attack, open Collision with OBJ_Player.
  2. Add the following code to the end of the if statement that confirms the collision is valid:

Finally, we need to play the Miss sound if the attack does not hit anything. Unlike the Hit sound, which plays at the moment of collision, the Miss sound will only play if the Attack object is destroyed without hitting anything, so this sound will need to be played in a Destroy event.

  1. With OBJ_Attack, choose Add Event > Destroy.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

As you can see, all that this code does is play MissSound if Hit is equal to false.

You can now go in-game and test your attack one last time, and the sound effects should work perfectly.

Making a Strong Attack

Now that our Basic attack is done, let’s make one more attack type, a Strong Attack. For this attack, use the table below to set up the hitbox:

Sprite Name

Images

Origin Position

SPR_StrongPunch_Hitbox

StrongPunchHitbox1.png,

StrongPunchHitbox2.png,

StrongPunchHitbox3.png,

StrongPunchHitbox4.png,

StrongPunchHitbox5.png

X = 60, Y = 124

We should also import a unique HitSound for this attack since it's supposed to be more powerful than a standard attack. 

  1. Right-click the Sounds folder, and choose Create Sound.
  2. Set the Name to SND_StrongPunch1.
  3. Import the sound file HeavyPunch1.wav from the project’s assets.
  4. Set the Sample Rate to 48000.
  5. Set the Bit Rate to 320.
  6. Press Ok to save your sound.

Now that we have all of the assets ready, let's make the actual attack object.

  1. Make a new Object called ATK_StrongPunch.
  2. Set the Parent to the ATK object.
  3. Uncheck the Visible checkbox.
  4. Assign the Sprite SPR_StrongPunch_Hitbox.
  5. Use Add Event > Create.
  6. Under the Control tab, add an Execute Code action.
  7. Add the following code:

Now go back to the Player object, and add this code into the Keyboard Press > Any Key event after the Light Attack if so that it can also detect when the player uses the Strong Attack:

Finally, go into User Defined 2, and add this code at the end of the if statement that makes the Light Attack object, so it can also make the Strong Attack. Make sure that it is contained within the if that checks if the Player is Dead:

Your code should now look like this:

The updated attack code for the Player

Now if you go into the game, you should be able to use a Light Attack and a Strong Attack on an enemy. As you can see, while the two attacks are essentially very similar, they are differentiated by the animation associated with them, their hitboxes, and their basic properties.

Conclusion

You should now be able to freely edit and remix these attacks as you see fit. In the next article we will look at giving the Enemies the ability to fight back, and create more advanced features for the camera.

Building a Beat 'Em Up in Game Maker, Part 2: Combat and Basic Enemy AI

$
0
0

In the last article we discussed how to make the player move and integrated some basic combat mechanics. It was a good start, but we still have a few more things to do before this starts to feel like a real game. 

This article will focus on creating a dynamic camera, making BattleRegions or areas for combat to take place, and giving the enemies the ability to start fighting back.

Just like in the last article, make sure that you download the Asset pack for this article before you get started.

Creating the Camera

Game Maker uses Views to control how the camera behaves. Normally we could tell our view to follow the Player and leave it at that, but eventually our camera will need special behaviors like a shake effect after big attacks. If the camera’s attached directly to the player, this can be very challenging to implement. Instead, we’re going to make a camera object that the view will follow, and program the special behaviors directly into it.

First let's import the Camera sprite. It is located in the Assets folder you downloaded for the Tutorial under Images > SPR_Camera.png

Sprite NameImagesOrigin
SPR_CameraSPR_Camera.pngX = 14, Y = 12

Even though the camera will be invisible, the view will have issues following it if it doesn't have a sprite associated with it, so that's why we imported this image.

Now let’s make the actual camera object.

  1. Right-click the Objects folder and choose Create Object.
  2. Name the object OBJ_Camera.
  3. Uncheck the Visible attribute.
  4. Click Add Event > Create.
  5. Add the Action Control > Code > Execute Code.
  6. Add the following code:

All this code does is set up the camera object for us. First it tells the view to follow the camera object. Then it sets the Vborder and Hborder values, which determine how close the camera object can get to the edge of the view before the view starts scrolling with the level. If you want the camera/player to stay in the center of the screen, the Vborder should be half the game screen’s height, and the Hborder should be half the width. Finally, setting view_visible to true makes this view active within the game.  

After setting those values, we place the camera at the same position as the Player, and create the TargetX and TargetY variables. These variables will be used to direct the movement of the camera and tell it where to go. Then we have the State variable which will be used to control the camera's behavior. Finally, MoveSpeed determines how quickly the Camera moves to the Target position.

Now we’ll add movement basic code to the Step Event.

  1. With the Camera object selected, Add Event > Step > Step.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

This step event tells the camera to follow the player. First it sets the target position to the player's position. Then, if the distance to the target position is greater than the Camera's move speed, it starts moving towards the target; otherwise, it snaps to the target position and stops.

That's all the Camera needs to do for now, so let's make the camera object in-game and start testing it. We could just drop the camera in the room with the player ourselves, but we’re going to have the Player object create the camera instead. Since the camera relies on the Player to function, having the Player create the camera prevents us from forgetting the camera in the future, and ensures there are no issues with the order the objects are created in.

  1. Go to the player object OBJ_Player.
  2. Open the code for the Create event.
  3. At the very end of the code, add this line of code:

Finally, we need to enable Views within the room, otherwise the Camera won't work.

  1. Go into room0, the room we made in the last tutorial.
  2. Go to the views tab.
  3. Check Enable the use of Views.
  4. Then select View 0 from the View list, and check the box that says Visible when room starts

If you test the game now, things will look the same as before since the room perfectly fills the view. To see these changes in action, we need to make the room wider or taller than it is now.

  1. Go into room0, the room we made in the last tutorial.
  2. Go to the settings tab.
  3. Set the Width = 3000.

Now when you go in-game, and you try to walk past the Enemies, you should notice that the room scrolls with the player as they move. Technically it’s scrolling with the camera, but it looks as if it’s following the Player since that's what the camera is doing.

You can also try increasing the Height of the room, and you should see a similar effect.

Battle Regions

In classic beat ’em ups, combat is generally restricted to an area that is one or two screens large at a time. When a fight begins, the camera and player become locked to the area where the combat is occurring, and can’t leave it until the fight is over. This makes enemy encounters easier to control, AI easier to build, and makes fights more focused. If you’re still not sure what I’m talking about, take a look at this Let’s Play of Castle Crashers, and watch what happens when they enter combat.

When combat begins, their movement becomes restricted, and in some cases the camera behaviors will even change. It's a little hard to notice when you're not looking for it, but the camera tends to "snap" slightly to the area of combat once the battle begins. To create this effect in our game, we’ll add a BattleRegion object that will act as a sort of arena for the battle to take place in. Once the player enters the BattleRegion, it will take over the camera and restrict their movement until the battle ends.

First we need a Sprite for our Battle Region.

  1. Right-Click the Sprites folder and choose Create New Sprite.
  2. Name the sprite SPR_BattleRegion.
  3. Click Edit Sprite.
  4. Go to File > New.
  5. In the New dialog, set the image size to 1024x768, and press OK. I chose this image size because that is our game’s actual resolution. Since BattleRegions will be resizable, having the default size be the size of the screen will be very convenient for quickly designing encounters.
  6. Double-click the new image to open up the image editor.
  7. Use the Paint Bucket to fill the entire image with a single color. Battle Regions won’t be visible in-game, so you can choose any color you'd like here. Just make sure you choose a color that will be easy to see and obvious when editing the level. I chose bright blue.
  8. Use the Checkmark to save the sprite.
  9. Center the pivot point.
  10. Press OK to save the sprite and exit the sprite editor.

Next we’ll make the Battle Region object.

  1. Right-click the Objects folder and choose Create Object.
  2. Name the object OBJ_BattleRegion.
  3. Set the sprite to SPR_BattleRegion.
  4. Uncheck the Visible checkbox.
  5. Click Add Event > Create.
  6. Add the Action Control > Code > Execute Code.
  7. Add the following code:

This is our creation code. The IsActive variable tells us whether the BattleRegion has been activated. In other words, it tells us whether the battle has begun, and whether the enemies in the region are still alive. It starts out false, but will become true when the player enters and stay true until they kill all of the enemies. RegionHeight and RegionWidth give us variables to access the size of the BattleRegion, while the four variables after that tell us exactly where the edges are. 

We will end up needing these values a lot, so being able to easily reference them, without doing the math every time, will be a huge help later. Finally, HasEnemies is a simple Boolean that will tell us whether the region has any living enemies left. Once the BattleRegion activates, it will not be able to deactivate unless this variable is false.

Next we’ll add some code to activate the BattleRegion when the player enters.

  1. In the OBJ_BattleRegion, click Add Event > Collision > OBJ_Player.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

While the if statement in this code is quite long, it’s actually only testing two things. First it tests if the Player is within the bounds of the BattleRegion, but it ignores a small buffer of about 20 pixels on the inside edge of the BattleRegion. It does this to make sure the player is fully inside the region, and isn’t standing on the very edge, before it activates. The second thing it checks is whether HasEnemies is true. If both are true, it activates the BattleRegion. 

Finally we need to deactivate the BattleRegion when combat ends, and make sure that HasEnemies is set to true when there are Enemies in the region. We can do this in the Step Event.

  1. In the OBJ_BattleRegion, click Add Event > Step.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

This code checks if there are any enemies remaining in the room, and if there are any enemies located within the BattleRegion. If both are true, it sets HasEnemies to true; otherwise, it sets it to false and deactivates the BattleRegion.

The last thing you should do is add the BattleRegion into the level, and test the game to see what happens. When you add it, make sure that the enemies you placed are within the bounds of the BattleRegion. You can also have multiple BattleRegions, but you should make sure they don't overlap. You can see how I set up my BattleRegion below:

The Battle Region

Restricting Player Movement

If you went in-game to test your BattleRegion, you probably noticed that nothing happened when you entered the BattleRegion. That’s because none of the movement or camera code changes when the BattleRegion is active. Right now, activating the BattleRegion is essentially a useless action because we never tell any of the other objects to do anything about the fact that it's active. To fix this, we need to adjust the Player and the Camera objects so they account for the bounds of the BattleRegion when it's active. 

For the Player, we want to make sure that they cannot leave the BattleRegion until all their enemies are defeated. To do this, we need to modify the movement code itself.

  1. Go to OBJ_Payer.
  2. Go to the Player's Step event.
  3. At the very beginning of the Player's Step event, add this code:

This code stores the nearest BattleRegion in a variable so the Player can easily reference it within the movement code.

  1. Still in OBJ_Player's Step event.
  2. Add the following code at the very beginning of the IsAttacking if statement, before any of the existing code in that if statement:

While this code looks long, it’s really very simple. First it checks whether the BattleRegion is active. If it is, it then looks at the Player's potential X position based on their XSpeed. If their current speed would put them outside of the BattleRegion, or cause them to collide with an object marked Solid, it sets the XSpeed to 0. Then it does the same check for the YSpeed.

If you go in-game and test this new code, your movement should become restricted to the confines of the BattleRegion until you kill all of the Enemies.

Camera Behaviors: Introduction to Finite State Machines

Things still aren't perfect, though. Even though the Player can't go outside the BattleRegion, the camera can. Because of this, if we go to the edge of the BattleRegion, it’s clear the Player hits an invisible wall in the middle of the screen, and can’t move any further, but the outside of the BattleRegion is still visible.

The visible Battle Region

Obviously it would be better if the camera was restricted in the same way as the Player, and it couldn't move to a location where you'd see past the edges of the BattleRegion. To do that, we’re going to set up a Finite State Machine, or FSM, which will allow us to dictate how the camera behaves based on the current state of the game.

Finite State Machines let you separate each of an object’s behaviors into discrete portions of code called States. Then, using a Switch Statement, you can check what state the object is in, and run only the relevant code. This makes your code easy to follow and incredibly versatile. It also makes expanding the code easy, since we can create new States whenever a new behavior is needed, rather than complicating our existing if statements and code-base.

For our camera, we are going to make two States: Player and Region. Player will follow the Player as closely as possible when they are not in Battle, and will do basically everything our camera does now. Region will take over when the player enters an active BattleRegion, and will make sure the camera cannot move past the bounds of the region, while keeping the player in view at all times.

We already have the State variable in the Camera, from when we created it earlier, so we can move straight into building the actual FSM.

  1. Go to OBJ_Camera.
  2. Open the Step event code.
  3. Replace the code that sets TargetX and TargetY with the following:

This code lays out the basic structure of the new Step Event. First the camera finds the nearest BattleRegion and stores it in a variable called MyBR, just like the Player. Then the switch statement looks at the state and runs the appropriate code.

While this is a fairly simple switch statement, and we could accomplish something similar with an if statement, eventually we’ll need more states, so it’s good to think ahead and make the switch statement now.

First, let’s add the code for the Player case. Add this code in place of the comment in the Player case:

This code behaves exactly the same as the code we replaced with the switch statement, and sets the Target position to the Player's position. After that it checks whether the BattleRegion is active. If it is, it switches to the Region state. Finally, we have a break; statement, which is used in switch statements to end the code and prevent any other states from being processed.

Next, we’ll add the behaviors for the Region state. The goal of this state is to keep the camera within the bounds of the BattleRegion at all times and ensure that no matter where the Player goes within the region, they will be visible. To do that, we will determine the minimum and maximum X and Y positions the camera can go to before the outside of the BattleRegion becomes visible. 

Then, if the Player is within that minimum/maximum area, the camera will follow them the way it normally would, and if the Player goes out of that area, to the edges of the BattleRegion, the camera will still be able to see them when it hits those minimum/maximum bounds.

Replace the Region state comment with the code below:

First this code sets the minimum and maximum X and Y positions for the camera, by taking the edges of the BattleRegion and adding a buffer that is half the screen height and width on all sides. This buffer allows the camera to get as close as possible to the edge of the region, without making anything outside of the BattleRegion visible. You can see what I mean in the image below.

Camera Placement

In this case the blue areas represent a BattleRegion, and the box with the red outline represents the camera. The dark blue area is the buffer, whereas the light blue area is the area that the camera can move around freely in. As you can see, the center of the camera perfectly bumps up against the edge of the buffers when it is at the edge of the BattleRegion.

After that, the camera uses a clamp function to set the TargetX and TargetY based on the Player's position, the minimum, and the maximum. Finally, it tests to see whether the BattleRegion is still active, or whether the camera has gotten outside of the BattleRegion's bounds, and sets the state back to Player if either is true.

Now if you go in-game to test the BattleRegion, it should behave exactly the way we want and smoothly transition between the different states when the BattleRegion becomes active or inactive.

The best way to see the Camera in action, though, would be to make the width or height of the BattleRegion greater than the width or height of the screen. If you don’t resize the BattleRegion, and leave it the same size as the camera view, then the camera will not move at all while the BattleRegion is active since the BattleRegion is exactly the size of the screen.

Once you’re done testing the camera behaviors, you should go back into OBJ_BattleRegion and uncheck the Visible checkbox. This way the BattleRegion won’t be visible in-game.

Basic Enemy AI

Beating up on defenseless enemies is fun, but our game needs more than glorified punching bags to be interesting. At the very least, we should give them the ability to hit us back.

For our AI, we’re going to use another Finite State Machine. Our enemies’ states could include Wandering/Patrolling when they don’t have a target, Queueing when they're getting ready to attack, or Idle when they’re doing nothing at all. The States we’ll be starting today are Idle, PositionFront, and PositionBehind.

PositionFront and PositionBehind won’t be completed today, but they will be used in a later article to determine what direction the enemies will approach the Player from.

Before we start building these States, we’ll need to import two new animations that we’ll use for the Enemy Attacks. One will be for the Basic Attack, and one for the Strong Attack. Create two new sprites as laid out below:

Sprite NameImagesOrigin Position
SPR_EnemyBasicPunch

RedEnemyBasicPunch1.png,

RedEnemyBasicPunch2.png,

RedEnemyBasicPunch3.png,

RedEnemyBasicPunch4.png,

RedEnemyBasicPunch5.png

X = 55, Y = 122
SPR_EnemyStrongPunch
RedEnemyStrongPunch1.png,

RedEnemyStrongPunch2.png,

RedEnemyStrongPunch3.png,

RedEnemyStrongPunch4.png,

RedEnemyStrongPunch5.png
X = 60, Y = 124

We also need to give the Enemy a State variable, and a SightRange variable so we know how close they'll have to be to the Player to “notice” them.

  1. Go to the Create event for the Enemy.
  2. Add these variables at the end of the code:

You should notice that the initial state for the enemy is Inactive. This State will essentially act as an "off" state for the Enemy. By not including a case for it in the switch statement, we will guarantee that until the Enemy switches to one of their "Active" states, they won't take any actions. In this instance, they will switch to an active state when the Player enters a BattleRegion that they are inside of.

The Switch Statement

Next we will add a Switch statement, similar to the one for the Camera, to the Enemy’s Step Event.

Follow these steps:

  1. Go to the Step event for the Enemy.
  2. After the if statement that checks to make sure the enemy isn’t dead, replace the code that sets the enemy sprite with the following code:

This is a basic shell of our switch statement which we will expand over time; however, it still gives us a good idea of how the final switch statement will work. Right now a lot of this code is just comments, but we will replace it soon, as we've done previously.

Before the Switch statement actually runs, the Enemy checks whether they should switch to a different state from the one they're currently on. Then, we move on to the switch statement itself.

The first State is the Idle state, which basically just animates the Enemy and checks whether they should randomly try to attack. So if the Player happened to run by them, there's a chance they will attack as the Player passes. The second and third states are our real attack modes. These states tell the Enemy to position either in front of or behind the player and prepare to attack. 

Right now our States don’t do anything since they are just comments, but if you take a close look at the comments, you should notice something interesting. Some of the actions, like “animate the enemy” and “check to see if the enemy should attack”, are repeated by multiple states. Since these blocks of code will be needed multiple times, we are going to make custom events to handle these actions for us. This way we don't have to retype the same thing over and over.

Choosing a New State/Behavior

The very first thing our step event does is check to see if the Enemy should change their behavior, so the first thing we'll do is make an Event that can look at the Player's current state, and the state of the game, to see what the Enemy should be doing. 

To get an idea of how the Enemy will determine what to do next, take a look at the State diagram below:

State Diagram of the Enemy AI

This diagram explains how the first iteration of our Enemy AI will work. To put it simply, the Enemy will start off in the Idle State once battle begins. If the Enemy is within SightRange of the Player, they will randomly switch to either PositionBehind or PositionFront.

This is pretty simple AI, but we will expand on it as we get further into the series.

To make the event, follow these steps:

  1. In the OBJ_Enemy, choose Add Event > Other > User Defined > User 0.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

As you can see, this event is using a switch statement to accomplish what I explained above. First it generates a random variable called MyAction which it will use to select a new State in situations where there are multiple valid options. Then, in the switch statement, if the Enemy's State is Idle, and the Player is within SightRange, they have a 50% chance of switching to PositionBehind, and a 50% chance of switching to PositionFront.

For now, that's all we need to do.

Now go into the Step event again, and replace the comment that says //Choose a new state based on... with the following code:

We're very close to having working code, but we still need to add the code that activates the enemies in the BattleRegion when the battle begins. Follow these steps to do so:

  1. In the OBJ_BattleRegion, choose Add Event > Collision > OBJ_Enemy.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

This code runs whenever there's a collision between an enemy and a BattleRegion, and it checks whether the BattleRegion is Active, and whether the enemy is Inactive. If both of those things are true, it activates the enemy by setting their state to Idle. 

If you go in-game now, the code will technically work, but it won’t have any visible effect. This is because the actual States are still just comments explaining what they do, and not actual code.

To verify that it’s working, and see it in action, we will temporarily add this debug code to the end of the Enemy’s Draw Event.

This code will write the Enemy's State below their Sprite in-game, and make it immediately clear what is happening.

Now when you enter a BattleRegion, you should see the enemy’s state change from Inactive, to Idle, and then immediately to PositionFront or PositionBehind. 

Attacking

Choosing a state is a good start, but fighting back requires the enemy to check whether they’re within range of the player, and whether they’re ready to attack. For this we’ll use a variable called AttackRange, and one called Aggressiveness. AttackRange just tells us how close the enemy needs to be to execute an attack, whereas Aggressiveness will start at 0, and slowly increase based on the Enemy's state. The higher it gets, the more likely the Enemy is to attack, and to use more powerful attacks when they do. 

To add these variables, go back into the Enemy’s Create Event, and add this code to the end of the event:

Now, to make our attacks work, we need to add three more events to the Enemy: one event which determines when to attack, one event that performs the attack, and one event that resets the enemy’s state after the attack. Let’s start with the event to check whether they should attack:

  1. In the Enemy object, choose Add Event > Other > User Defined > User 1.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

This event is very simple. First it checks whether the enemy is on the ground, since they don't have any air attacks. Then it checks whether the player is close enough to attack based on the distance between them, and whether they are on the same Layer. If they are close enough to attack, and the enemy is on the ground, their aggressiveness increases, and they have a chance to attack.

Now let's make the attack event itself, so that we have an event to call when the Enemy does decide to attack.

  1. In the Enemy object, choose Add Event > Other > User Defined > User 2.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

For this event, as long as the player isn’t dead, the code generates a random number called AttackChance. This number is used with the enemy's Aggressiveness to determine whether the enemy should use a light attack or strong attack. If the Aggressiveness and the AttackChance are both relatively high, the enemy uses a Strong Attack; otherwise they use a Light Attack. 

After that, it sets the enemy speed to 0 so that they're not moving while they attack, sets the enemy's state to Attacking, resets their aggressiveness, and matches the basic properties of the attack to the corresponding properties of the enemy.

Before we go any further, let’s see how things work so far. Go into the Step Event for the enemy and replace all instances of the comment //Check to see if the enemy should attack with the following code:

Now go into the game, and stand near an enemy for a few seconds. Get right up against them and see what happens. They should eventually begin attacking, and, once they do, you should keep an eye on their State and their animation. If you're not sure how close you should be to them, use this picture as a reference:

The position of the enemy

You should notice that once the enemy starts attacking, they never seem to stop. The animation seems to go on forever, and their State never becomes Idle again. This is because the enemy’s animation and State never get reset after the attack begins; it's similar to an issue we had with the Player. If you think about how the code is processed, then the last thing we did with the enemy’s animation was choose one of the two attacks, and the last thing we did with their State is set it to “Attacking”. Even though our Attacks work right now, without the third of the events I mentioned above, the Enemy never “neutralizes” and resets back to Idle.

The easiest way to reset the Enemy is by adding an Animation End event. This event will run whenever an animation completes, and will check if the Enemy's state is set to Attacking. If so, it’ll mean they should switch back to a default state, and switch animations. So in our above scenario, the moment their first attack animation ends, it will run this event and reset everything so that the loop doesn’t restart.

  1. In the Enemy object, choose Add Event > Other > Animation End.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

As I said, the code checks if the Enemy’s State was “Attacking”, and if so it resets their State to Idle.

Now go into the game again, and see what happens when you do the same thing as before. You should now see the State reset if you watch the text under the Enemy, but the animation will still loop forever. The problem is that we still haven’t added any code to animate the Enemy based on their State. That's what we'll do next.

Animating the Enemy

The only animation we need right now is for the Enemy to switch back to the Idle sprite after their attack ends. While we could just add this code to the Animation End event, or even to the Idle case in the Step Event, we will eventually need more precise control over the Enemy’s animation. 

Because of this, we are going to make another new Event specifically to handle animation. In fact, if you look back at our Step Event, you’ll see in the commented code that we already have a couple of places to put this animation event once we make it.

  1. In the Enemy object, choose Add Event > Other > User Defined > User 3.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

Right now, all this code does is set the Enemy's animation to Idle no matter what their state is. Eventually, though, we will add code which sets up the Walking Animation when they're moving, and even some specialty animations that only apply to specific events.

Now we just need to go back to the Step Event, and replace all instances of the comment //Animate the enemy with the following code:

If you go back into the game at this point, you should see that our animation issue is solved, and the enemy is switching states correctly.

Adding a Health Bar

Right now our Enemy attacks seem to be working, but you might notice an issue if you let them hit you multiple times. No matter how long you stand next to the enemy and let them hit you, you don’t seem to die. On top of that, we don’t even know whether you’re losing health yet. Since this is pretty important for verifying that enemy attacks work, this is what we'll do next.

Before we can figure out why you’re not dying, we need to know whether you’re even getting hurt, so let’s add a Health Bar for the player. To do this, we are going to give the Player a Draw GUI event. 

  1. In the Enemy object, choose Add Event > Draw > Draw GUI.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

This code does not do very much, but it should give us a basic health bar for our character. First it draws a simple black rectangle to use as an outline for the Health Bar. After that, it draws a maroon rectangle to act as a background when the Player has lost some health. Finally, if the player still has health, it draws a green bar for the health itself. 

The width of the green bar is set by multiplying the health bar's maximum width of 242 pixels by the fraction CurrentHP/MaxHP. This way the Green health bar will always be sized proportionately based on the amount of health the player has left.

If you go in-game now, you should see the Health bar in the top-left corner:

The HealthBar in the top-left corner of the dashboard

If you go up to an Enemy again and start getting attacked, it should now be clear that you're taking damage.

Resetting the Player's IsHit

Despite the fact that we know the Player is being hit, things still aren't perfect. Go in-game, and try attacking an Enemy or moving after you get hit by one of their attacks. Even though your controls worked perfectly before being hit, the moment you take damage you're no longer able to move or attack.

This happens because the Player's attack code in User Defined 2, and their movement code in the Step event both require IsHit to be false. You can see User Defined 2 below:

IsHit in the Attack Event

Unlike with our Enemy, though, after the Player gets hit, we never reset their IsHit variable. So let's add an alarm event to do that.

If you look back at OBJ_ATK's collision code for the Player, you'll see that we already have some code in place to run an alarm event and stun the Player.

Existing StunLength code

So the only thing we have to do at this point is add some code to reset IsHit, and give the Player an IsHit animation.

  1. With OBJ_Player, choose Add Event > Alarm > Alarm 3.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:
  1. With OBJ_Player, go to the Step event.
  2. Open the code for the Step event.
  3. Add this else statement to the end of the if statement that runs the Player's movement code.

Your Movement code should now look like this, with the new portion outlined in red:

Updated Player Movement code

Now when you go in-game, you shouldn't have any issues attacking or moving, after you get attacked.

Killing the Player

Now that the Player is getting damaged, the game is really starting to come together, but we still have one more issue to deal with. If you stand in front of the enemies too long, eventually you'll run out of health, and when you do, you'll probably see an error like this one:

Error Message show on Player Death

Decoding error messages can be a bit of an art, but this one is actually pretty clear. This error refers to the OBJ_Camera's step event, and specifically it's saying that the step event is having trouble gaining access to the OBJ_Player object. This happens because the Player object no longer exists. If you look back at our Player's step event, you'll see that the Player immediately calls instance_destroy() when the CurrentHP is less than 0. 

Existing Death Code

That means that the moment the Player dies, the Player object is destroyed, and the Camera is no longer able to follow it. 

So let's add some code to resolve this error and give the Player the ability to retry when they die.

To fix the Camera issue, we're going to set the Camera's state to "Dead" when the Player dies. This way, none of the camera's other states will run, and the camera will not try to access any of the Player's variables. We could just as easily destroy the camera when we destroy the Player, but doing that would prevent us from manipulating the camera after the Player dies, so I find it's better to have an actual Dead state, in case we want to add cool animations or effects later on.

  1. In OBJ_Player, go to the Step event.
  2. In the code for the Step event, replace the code in the else statement highlighted above with the following code:

Now if you go in-game and let the Player die, you shouldn't have any error messages. On the other hand, though, when they do die the Player immediately disappears, and it becomes impossible to do anything, since the player never revives, and we don't have a Game Over screen. 

To fix this, we're going to give the player a death animation, and set up a basic alarm that will restart the game 3 seconds after the player dies. This will be a bit more interesting, and allow the game to continue. Eventually we will add a Game Over screen and even improve the death animation, but for now, this should be a good alternative.

First let's import the sprite.

Sprite NameImagesOrigin Position
SPR_PlayerDead

PlayerDead.png

X = 72, Y = 67

Now we'll make one last change to the event that kills the Player.

  1. In OBJ_Player, go to the Step event.
  2. In the code for the Step event, replace the instance_destroy() code with the following:

The last thing we need to do for this is create the alarm event that will restart the game.

  1. In OBJ_Player, go to Add Event > Alarm > Alarm 1.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

Now when you go in-game and let yourself get killed, you should see the Player's death "animation" play, and the game should restart after 3 seconds. It's not perfect, but it's a good start.

The Players Death Animation

Fixing the Enemy Hit

The very last thing we’re going to do is fix a problem that was created by the addition of the Switch Statement to the Enemy Step Event. If you go in-game and attack the Enemy, you’ll notice that they no longer get stunned when they’re hit. When we added the switch statement, we overwrote that code, and so we removed this effect. Thankfully, though, the animation event we made a few minutes ago will make this very easy to add back in.

Rather than coding an entirely new system, or modifying the FSM to handle the IsHit variable we created in the last tutorial, we are going to make a new State, and replace this variable with that State. The first thing we’ll do is remove the IsHit variable from the Create event, since we will no longer need it.

Delete this line of code from the Create Event.

Next, we’ll go into the Attack object and edit it so that it sets the State to Hit, rather than making IsHit true.

  1. Go to the ATK object.
  2. Open the OBJ_Enemy collision event.
  3. Replace the line of code that sets IsHit = true; with the following line of code:

Now we need to make some small changes to the Enemy object. First we need to modify the alarm code which resets the Enemy’s status, so that it resets the State instead of the IsHit variable.

  1. Go to the Enemy object.
  2. Open the Alarm 0 event.
  3. Replace the code with the following:

We also need to add the “Hit” state to the switch statement in the animation event.

  1. Go to the Enemy object.
  2. Open User Defined 3.
  3. Add a new case to the Switch statement with the following code:

Finally, we need to add the Hit case into the Step Event’s switch statement as well, so that the animation event will run when the enemy is in the Hit state.

  1. Go to the Enemy object.
  2. Open the Step event.
  3. Add a new case to the Switch statement with the following code:

After all of that, if you go back into the game, the enemies should get stunned again when you attack them.

Conclusion

While our combat still needs lots of work, since the Player will eventually need their own stun Event, and the enemies will need to be able to move around, it’s a good start. 

In the next tutorial, we will tackle enemy movement and combo attacks.

Building a Beat 'Em Up in Game Maker, Part 3: Combo Attacks, More AI, and Health Pickups

$
0
0

In the last article, we started setting up combat, gave our Player a health bar, and gave our enemies the ability to attack the Player. This was a good start, but our enemies still can't move towards the Player to attack, or walk around the Battlefield. Obviously, this isn't going to cut it, so let's take some time to build up our AI a bit more.

Just like in the last article, make sure that you download the Asset pack for this article before you get started.

Movement

The first thing we'll do is give our Enemy the ability to move towards a target destination. To set this up, we'll need a FindTarget event, which determines where the Enemy needs to go, and a Move event which tells the Enemy to start moving there. 

This will be similar to how we move our camera since we will use TargetX and TargetY variables as we did there. You can see where these events will be placed in the Step event if you look at the PositionFront and PositionBehind cases.

The comments that we will eventually replace with the targetting and movement code

First, we'll add our target variables.

  1. In the OBJ_Enemy object, open the code for the Create Event.
  2. Add the following code to the end of the event:

Next, we will add the FindTarget event. For now, this event will find a random position near the Player, and set the Enemy's target to that position. Once we know the Move event works, we can implement more sophisticated targeting with a switch statement.

  1. In the Enemy object, choose Add Event > Other > User Defined > User 4.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

As I said, this code chooses a random position near the Player, in this case within a 10 pixel radius around them, and sets the Enemy's target position to that point. It also uses an if statement to check whether the Player is still in AttackRange of the target position, or whether the distance between the TargetY and the Player's y is greater than the LayerSize. This way, if the Player hasn't moved since the last target position was found, the target position will not get changed for no reason.

Now we need to make the movement code. 

  1. In the Enemy object, choose Add Event > Other > User Defined > User 5.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:   

This code checks how close the Enemy is to their target position. If the distance to the target is further than their move distance, the Enemy moves towards the target position; otherwise, they stop.

Before we can test this in-game, we need to add these events to the Step event in the locations I highlighted earlier.

In the Enemy's Step event, replace the //Find Target position comments with the following code:

Then replace the //Move there comments with the following code:

Now when you go in-game, the enemies should start moving towards you the moment you enter the BattleRegion.

The movement itself seems to work well, aside from the fact that there's no animation, but you may notice something strange when you attack the Enemies. If you attack the Enemy while they are moving, they do not stop moving while they are in the Hit state. This is because the move_towards_position script changes the object's built-in speed variable (notice the lowercase s), which moves them forward at a constant rate until we tell the speed to change. So even after the Enemy is hit, their speed continues moving them, since we haven't told them to stop.

This issue is the same reason we have to manually set the speed to 0 when they reach their target. If we didn't tell them to stop, they would never stop on their own. We can fix this by modifying the Step event so that their Hit case sets their speed to 0.

  1. In OBJ_Enemy, go to the Step Event.
  2. In the code, find the Hit case for the switch statement, and replace it with this code:

Now when you go in-game and attack Enemies, they will not move during their Hit animation.

Adding Basic Animation

We're definitely off to a good start, but there are still some obvious issues with the movement. First and foremost, the Enemies do not animate at all—they just sort of slide around the battlefield towards the Player. This doesn't look very good, so let's go into the Animate event we made in the last tutorial to improve it.

  1. In OBJ_Enemy, go into User Defined 3.
  2. Replace the existing "PositionFront" and "PositionBehind" case in the switch statement with this code:

In this new code, the first thing we do is set the image_xscale based on the direction the Enemy is moving in. So if they are moving left, they will face left, and if they're moving right, they'll face right. Then, if their speed does not equal 0, it sets their animation to the walking animation, and if it does, it sets their animation to idle.

It should now look much better when you test it in-game.

PositionFront vs. PositionBehind

At this point, you may be thinking "Why do we need PositionFront and PositionBehind if they do all the same things anyway?" Well if you look at our current Enemy movement, you'll see there's a lot of room for improvement. 

Having two separate states allows us to have each enemy approach from different sides, rather than having all the Enemies attack from the same location. This will make battles more challenging, and tougher to escape from.

To implement this, we need to modify the FindTarget code so that it takes the state into account when choosing the target position. Rather than adding an if statement or a switch statement, we'll do this using the SideMod variable. 

SideMod is actually a variable we've had in place from the very beginning. If you look back at the Create code, and the switch statement in the Enemy's Step event, you'll see that we've already started using SideMod.

PositionFront and PositionBehind with SideMod being used

SideMod will act as a modifier that will offset the Enemy's target position, relative to the Player's position. So if SideMod is positive, the Enemy's target will be PlayerX + position range, and if it is negative the Enemy's target will be PlayerX - position range. This way, both states can use the same targeting code, but end up with different results.

To see this in action, let's edit the Find Target event.

  1. In OBJ_Enemy, go to User Defined 4.
  2. Replace the if statement with the following code:

This code improves on the original code in a few important ways. For the targeting itself, the targeting code now includes a 60 pixel buffer between the Player and the Enemy, to prevent the Enemy from moving to stand on top of the Player. On top of that, the targeting code now uses SideMod to determine which side of the Player the Enemy should be on. If SideMod is positive, the Enemy's position would be PlayerX + PositionRange, and if it's negative, it would be PlayerX - PositionRange.

We also made some changes to the if statement. The if statement now checks if the Enemy is too close to the Player, as well as too far, to maintain the buffer distance we added. The if statement also now checks whether the Enemy is on the wrong side of the Player in case the Player moved. So if the Enemy's State is PositionFront, and the Player moves so that the Enemy ends up behind the Player, they will find a new target position.

If you go in-game now, the Enemies should behave in a much more interesting way when they try to surround the Player.

Better Enemy Behavior

Facing the Player

That was a pretty big improvement, but there are still some issues. One of the clearest ones is obvious if you let the Enemies surround you a few times, and it can be seen in the image above. Essentially, Enemies do not adjust the direction they're facing relative to the position of the Player. So if the Enemy is facing left, and the Player is to the right of them, any attacks they use will go in the wrong direction. This is a pretty simple issue to fix, though.

  1. In OBJ_Enemy, go to User Defined 3.
  2. In the code, replace the PositionFront/PositionBehind case with the following code:

With the original code, the Enemy would always face in the direction of their Target position. With the new code, the Enemy faces towards their target position when they are far away, and begins facing towards the Player once they are within a short distance of their target. This ensures that once the Enemy is in attacking range, they will start facing the Player instead of the target position itself.

You should now see a major improvement when you go in-game.

The Basic Queueing State

Things should be starting to come together, but we still have one nagging problem. Right now, our Enemies do not change their behavior based on the number of Enemies attacking, or where other Enemies are standing. 

This makes it easy for Enemies to surround the Player and overwhelm them. The Player can generally manage three to four Enemies as we have now, but anything more than that will quickly get out of hand. To resolve these issues, we're going to add a new state called Queueing. 

The Queueing state will act as a temporary state for the Enemy while they're waiting for an opening to attack. While the Enemy is Queueing, they will stay relatively close to the Player, but they will not get close enough to actually attack until one of the attacking enemies dies, or switches to a different state. If you take a look at the video below, you can see something like this in action:

In the video above, pay close attention to the behavior of the Enemies before they begin attacking the Player. As you can see, the Enemies do not all approach the Player until the Player has killed or knocked back the Enemy they are currently fighting. This is the behavior we want to emulate in our game.

You can see a general idea of how our new State will work in the State diagram below:

The Enemy State Diagram with Queueing

To make this system work, we need to have a queue, or list, of enemies that are currently attacking. Then, when an Enemy gets within a certain range of the Player, they can look at the list and see how many Enemies are on it. If the list has already maxed out, they will switch to the Queueing state, and wait their turn. If the list is not full, they will add themselves to the list of attackers, and continue approaching the Player.

So the first thing we'll need is the queue itself. I am going to use a ds_list and add it to the Player object.

If you’ve never used a ds_list object before, you can learn about it here. To put it simply, though, a ds_list is a more flexible version of an array that gives you more built-in functions like ShuffleSort, and Insert, and it can make certain operations a bit easier.

  1. With OBJ_Player, go to the Create event.
  2. Add the following code to the end of the create event code:

Now we need to make sure that Enemies are referencing this list when they get ready to attack. To do this, we will add an if statement at the end of the Move event that checks whether the enemy list is full when they are within range to add themselves. If it is, they will switch states, and if it's not, they will add themselves to the list.

  1. With OBJ_Enemy, go to User Defined 5.
  2. Add the following code to the end of the Move Event:

This if statement checks three things before adding an Enemy to the list. First, it checks whether the Enemy is less than 200 pixels away. Then it checks to make sure the list has less than two Enemies in it already. Finally, it checks to make sure that they are not already on the list. If all three of those things are true, the Enemy gets added to the list.

At this point, we also need to go into the State change event and make sure that an Enemy will switch to the Queuing State if they cannot attack.

  1. With OBJ_Enemy, go to User Defined 0.
  2. Add the following case to the switch statement:

This if statement checks the same things as the one we added to the previous event, except that it does check the distance, since they are already in the PositionFront/PositionBehind state. If the if statement is true, it sets the Enemy's state to "Queueing", and sets their speed to 0. 

Now try going in-game, and see what happens when you get the attention of all three Enemies. It should start out the same way as before, but after a few seconds, one of the Enemies should stop approaching the Player. This is because they've switched to the Queueing state, and are no longer being told to move towards their target position.

Animating the Queuing State

This is a good start, but there are some glaring issues we should address. First of all, if you look at the Enemy that switched to the Queueing state, you'll notice that their walk animation will continue playing even after they stop moving.

The Queueing state in action without a unique animation event

This issue occurs because the Queuing state doesn't have any animation code of its own. So whatever animation it was running when the Queuing state began is the animation it will stay in until the state changes to one that does trigger the animation code.

We can fix this by adding animation code for our new state, and by adding the Queueing state to the switch statement in the Step event.

  1. In OBJ_Enemy, go to User Defined 3.
  2. Go to the code event, and add this case to the switch statement:

Aside from one small change, this animation code is exactly the same as the code we have for PositionFront and PositionBehind. The difference is that this code causes the Enemy to start looking at the player from a further distance than the other two states. This makes it clearer that the Enemy is focusing on the Player, and is not just moving around randomly.

Finally, we need to add a Queueing case to the switch statement in the Step event so that we can make sure the animation code gets used.

  1. In OBJ_Enemy, go to the Step event.
  2. Go to the code event, and add this case to the Switch statement.

All this code does is run the animate event every step.

Now if you go in-game, the Enemy should stop completely the moment that they switch to the Queueing state.

Resuming the Attack

The next issue we have will come up if you try killing either of the attacking Enemies. No matter what happens, the Queuing Enemy never switches back to PositionFront or PositionBehind states. Even if you kill both of the attacking Enemies, and begin attacking the remaining Queuing Enemy, they will continue to do nothing.

This problem is caused by several factors. First, Enemies never get removed from the list of attackers, even when they die. So even after all the Enemies are killed, the Queuing Enemy will never see an opening to start attacking. On top of that, even if the Enemies did get removed from the list, we don't have any code in the change state event to deal with the Queuing state. Let's tackle these issues one at a time.

First let's start removing Enemies from the attacker list after they die. We can do this with a Destroy event that runs the removal code when the Enemy is killed.

  1. Go to the OBJ_Enemy object.
  2. Choose Add Event > Destroy.
  3. Choose Control > Execute Code.
  4. Add the following code to the code event:

This code checks to see if the Enemy is in the list of attackers. If they are, it removes them from the list.

The second thing we have to do is get the Enemy looking for openings. We can do this by adding code for the Queueing state into the Change State event. The code we're going to add will look at the list of attackers, and determine how many Enemies are on it. If the list is not full, the Enemy will add themselves to the list, and switch to either "PositionFront" or "PositionBehind", depending on where they are relative to the Player.

  1. In OBJ_Enemy, go to User Defined 0.
  2. Go to the code event, and add this case to the switch statement:

This code does exactly what I said above. If the Enemy list is not full, the Enemy will add themselves, and choose the best state based on their position.

Now if you go in-game you should see the Queueing enemy behaving correctly.

Separating the Enemies

While our Queuing State is just about finished for now, there's one last thing we need to do. If you play the game for a little while, you may notice something like this happen when multiple Enemies are trying to attack you:

The issue with the Enemy positioning

The problem here is that both enemies randomly chose the PositionBehind state, and ended up with very similar Target positions, so they're now basically on top of each other. This makes it hard for the Player to see how many enemies they are fighting, and it makes it easier for the Player to try and escape or just kill both Enemies simultaneously. Ideally, one Enemy would approach from the left, and one would approach from the right.

To solve this problem, we are going to add one more piece of code to our Change State event.

  1. With OBJ_Enemy, go to User Defined 0.
  2. Add the following code to the beginning of the PostionFront, PositionBehind case.

Your code should now look like this, with the new code outlined in red:

The new positioning code for our Enemy

This code does two things. First, it checks whether there are any other Enemies that are located at/near the target destination. If there are, it switches from PositionFront to PositionBehind, or vice versa.

The important thing to notice about this check is that the if statement also verifies that the instance it is finding is not itself. This is because the script we're using, instance_position(), does not have the ability to exclude itself from the results.

Make sure that this code comes before the code that checks whether the Enemy should be Queueing.

Now if you go in-game to test it, you should no longer see multiple Enemies attacking from the same side.

While our Queueing state is still a little incomplete, and our Enemy AI needs a few more adjustments, I think we should switch gears for the rest of this article, and focus on something a bit more exciting.

Combo Attacks

Combo attacks are a staple of every classic action game. Stringing together multiple attacks, and combining attacks in unique ways, keeps combat interesting through many levels. So, before we start adjusting the AI anymore, let’s build a combo system.

Before we can implement any combos, there are two primary combo types you should understand: AB combos and A+B combos. 

AB combos are combos which occur when the player uses two or more attacks in a specific order, within a limited amount of time. A light punch, then a heavy punch in quick succession would be an AB combo. 

A+B combos are combos where the player uses two different attacks simultaneously. A light punch and a heavy punch at the same time would be an A+B combo. 

These can also be combined into a third combo type, AA+B, where an A+B combo is used as one of the steps in an AB combo. A light punch, then a simultaneous light punch and heavy punch would be an example of this third type.

We’re going start by making an A+B combo.

Making the New Attack

To get our combo working, we’ll need a third attack for the player. This attack will be the Uppercut, and it will need two new sprites, the attack sprite, and the hitbox sprite. Add two new sprites to the game, as laid out below:

Sprite Name

Images

Origin

SPR_PlayerUppercut

PlayerUppercut1.png, PlayerUppercut2.png, PlayerUppercut3.png, PlayerUppercut4.png, PlayerUppercut5.png

X = 45, Y = 128

SPR_PlayerUppercut_Hitbox

PlayerUppercutHitBox1.png, PlayerUppercutHitBox2.png, PlayerUppercutHitBox3.png, PlayerUppercutHitBox4.png, PlayerUppercutHitBox5.png

X = 45, Y = 128

Let's also import a new sound for use with the Uppercut attack.

  1. Right-click the Sounds folder, and choose Create Sound.
  2. Set the Name to SND_Uppercut.
  3. Import the sound file HeavyPunch2.wav from the project’s assets.
  4. Set the Sample Rate to 48000.
  5. Set the Bit Rate to 320.
  6. Press Ok to save your sound.

Next, we need to make the new Attack object. Follow these steps to make the Uppercut Attack Object:

  1. Right-click on the Objects folder and choose Create Object.
  2. Name the object ATK_Uppercut.
  3. Set the object’s sprite to SPR_PlayerUppercut_Hitbox.
  4. Set the parent for the object to OBJ_ATK.
  5. Uncheck the Visible checkbox.
  6. Click Add Event > Create.
  7. Add the Action Control > Code > Execute Code.
  8. Add the following code:

Right now, the only difference between this attack and the strong attack is that the uppercut stuns the enemy for slightly longer. Eventually, though, this attack will be made more unique with knockback effects.

You can close this object.

Modifying How We Attack

Now that we have an attack for our combo to trigger, we need to start detecting when the combo is used. To do this, we’re going to modify the press <any key > event we made in the first tutorial.

The original Press Any Key event

In case you don’t remember, the current code tests to see if you’re pressing any of the basic attack buttons, or any of the strong attack buttons, and then sets your AttackType accordingly. Then, if you’re on the ground, it calls User Event 2 to execute the actual attack.

Right now we’re only detecting one button press at a time, but we need to detect multiple buttons to handle A+B combos. We could do this by making another if that says “if you press one of the strong attack buttons, AND one of the basic attack buttons, use uppercut”, but that would quickly get out of hand. As we added more attacks, these checks would become more complex, harder to read at a glance, and we would have a number of repeat checks for buttons used in multiple combos.

So, instead of checking for the button combinations themselves, every button that’s pressed will be added to a string of text. Then we’ll have an if statement at the bottom which says, “If the string says 'Up + Basic Attack', use option A, and if it says 'Up + Strong Attack', use option B, etc." This way, we can check each button once, and the code will be much easier to read.

To do this, we’ll need to make a couple of changes. First, we need to add a string which will store our list of buttons. We’re going to call this variableButtonCombo

  1. Go to OBJ_Player and open the press <any key> event.
  2. Add this line of code to the very beginning of the event:

Next, in the first if, change the code to this:

And change the code within the second if to this:

Finally, add this code before the if statement which checks whether the player is on the ground:

Your code should now look like this:

The updated Press Any Key event

Overall this code is basically the same as what we had before. The difference is, instead of having the if statements set the AttackType directly, all they do is append a unique string for each button that's pressed to the end of the ButtonCombo string. Then, the AttackType is set based on the final ButtonCombo string. By doing it this way, the final ButtonCombo string that gets evaluated is a combination of all the buttons that are being pressed, and the attack is based on that, rather than it being just a static attack type based on which individual button is pressed.

We also have a string_delete statement before the if statement that sets the AttackType. This statement deletes the + sign from the beginning of the ButtonCombo string to improve the readability.

Making the A+B Combo

With this new system, if you press multiple buttons that the event checks for, all of them will show up in the string. So all you have to do to add an A+B combo is add a new else/if block which checks for the new attack to the end of the if statement that determines the AttackType. For example, add the following code to the end of if/else that sets the AttackType to implement an A+B combo for the Uppercut:

Your code should now look like this:

The new ButtonCombo code with Uppercut

Before we can actually execute the Uppercut, though, we also need to go into User Defined 2 and add this block of code to the end of the if statement that checks what the Player's AttackType is set to.

Your code should now look like this:

The modified attack creation code with Uppercut added

If you did everything right, you can go into the game, and use the Uppercut by hitting the Basic Punch and Strong Punch buttons at the same time.

Making an AB Combo

Unlike A+B combos, AB combos require us to know the history of attacks the Player used, rather than just the most recent one. 

To keep track of which moves have already been used, we will create what I call the Command List. The Command List will be a ds_list object that keeps track of the last X ButtonCombo strings. Every time we use a move, all we have to do is look at the most recent commands in the list, and check if they match any of our combos. This is similar to what we do now, only we’ll be looking at the past couple ButtonCombo strings, instead of just the most recent.

So before we can set up our new Combo, we need to create a new Attack object. Import the following assets for the new attack:

Sprite NameImagesOrigin
SPR_PlayerTriplePunchPlayerTriplePunch1.png, PlayerTriplePunch2.png, PlayerTriplePunch3.png, PlayerTriplePunch4.png, PlayerTriplePunch5.pngX = 46, Y = 129
SPR_PlayerTriplePunch_HitBoxPlayerTriplePunchHitBox1.png, PlayerTriplePunchHitBox2.png, PlayerTriplePunchHitBox3.png, PlayerTriplePunchHitBox4.png, PlayerTriplePunchHitBox5.pngX = 46, Y = 129

Let's also import a new sound for use with the new combo.

  1. Right-click the Sounds folder, and choose Create Sound.
  2. Set the Name to SND_TriplePunch.
  3. Import the sound file LightPunch2.wav from the project’s assets.
  4. Set the Sample Rate to 48000.
  5. Set the Bit Rate to 320.
  6. Press Ok to save your sound.

Finally, we need to make the new Attack object. This new attack will be called the triple Punch:

  1. Right-click on the Objects folder and choose Create Object.
  2. Name the object ATK_TriplePunch.
  3. Set the object’s sprite to SPR_PlayerTriplePunch_Hitbox.
  4. Set the parent for the object to OBJ_ATK.
  5. Uncheck the Visible checkbox.
  6. Click Add Event > Create.
  7. Add the Action Control > Code > Execute Code.
  8. Add the following code:

So this attack will be slightly stronger than a standard light attack, and stun for a longer period of time.

Now that we have our new attack, we can start modifying the attack code to implement the Command List. To start, we need to add the CommandList object. 

  1. With OBJ_Player, go into the Create Event.
  2. Add the following code to the end of the event:

That’s all we need to do to create our list.

Next we need to integrate the list into our combat system. 

  1. With OBJ_Player, go to the press <any key> event.
  2. Replace the string_delete line, and the if/else if statement which sets the AttackType, with the following code:

This code is very similar to what we had before. First, it adds the ButtonCombo string to the CommandList. Then, since I’m limiting my max combo length to seven commands, it checks to make sure that the command list is less than or equal to seven items long, and deletes any extra items on the list. Finally, the if statement looks at the most recent item in the list the same way it looked at ButtonCombo, and determines the AttackType.

If you test your game now, it should work exactly the way it did before we added the CommandList.

Keep in mind that you can use any number you want for the max combo length. I chose seven because it seemed like a good choice to me, but if you want your game to have 10, 20, or even 100 action combos, you can do that, and the code will work fine. Personally, I suggest you increase it as needed when you make new combos, rather than trying to anticipate what you’ll need in advance.

Now all we have to do to make an AB combo is create a check that looks at multiple items in the list, instead of just one. So let’s say I want to add my triple punch and make it so that you need to do three LightPunches in a row to execute it. To make that work, you would need to append this code block to the beginning of the if/else if statement that sets the AttackType:

When adding this check to your game, make sure you put it at the beginning of the if/else if statement. If you don't, and you leave it at the end, one or both of the individual button checks will evaluate to true before it gets to the AB combo check, and the combo will never succeed. So your modified if/else if should look like this:

The updated code to detect AB combos

So remember, when you’re making new AB combos, the more buttons that are needed to execute the combo, the earlier it should be in the if/else if statement. If you put an AB combo at the bottom, it will almost never get executed.

Also remember that ButtonCombo strings are added to the list at the end. This means that the most recent command to be used is the last item in the list, not the first. So if the combo was LAtk, SAtk, LAtk would be in position Size-2, and SAtk would be in position Size-1.

Finally, we need to go back into User Defined 2 and add the statement to create the Triple Punch. Go into User Defined 2, and add this block of code to the end of the if statement that checks what the Player's AttackType is set to.

Now if you go in-game and use three Light Punches in a row, you should successfully execute a Triple Punch.

Clearing the Command List

Finally, we need to clear our Command List if the player takes too long to continue the combo. Right now, as long as you use three basic punches in a row, you will execute a triple punch. Even if there is a multi-second pause between each punch, it won't make any difference. This greatly reduces the skill required to execute powerful combos, so we need to add a system which resets the CommandList after a certain period. We’ll use an Alarm to accomplish this.

To create the Alarm, follow these steps:

  1. In OBJ_Player, go to Add Event > Alarm > Alarm 0.
  2. Add the Action Control > Code > Execute Code.
  3. Add the following code:

All this code does is clear the CommandList completely when the Alarm goes off.

Next, we need to go to the press <any key> event, and add code to trigger this alarm after the code which adds the ButtonCombo string to the CommandList, but before the While statement. You can see exactly where it should go in the picture below:

The position where you should place the Alarm code

Add the following code to that location in the press <any key> event:

This code starts the alarm and sets it to 10 steps, or game cycles. If 10 steps pass before the player presses a new button, the CommandList clears; otherwise, the combo can continue.

If you go in-game and test the combo now, you’ll see that it only works if you press the buttons in a relatively quick succession.

Increasing the number of steps will make comboing easier, and decreasing it will make comboing harder. I think 10 is a good choice, but you need to find the right level of challenge for your game. Your combos may be very complex, so you may decide you want to give the player more time to finish them. If you really want to decrease the time, you can do that as well, but your game will become substantially more challenging for the average player with each step you subtract.

Creating Pickups

The final thing we'll look at in this article is Pickups. No brawler or platformer is complete without power-ups and health pickups. When the player is in a dire situation there is nothing they love more than to get that random food pickup, or to stumble upon a secret power-up. Creating a basic pickup is actually very easy, but before we can do that, we'll need to import a sprite to use for our pickup.

This cheery sprite will be used for the parent pickup object and the food pickup we'll create later on.

Sprite Name

Images

Origin Position

SPR_Food_Cherry

FoodCherry.png

X = 13, Y = 47

Let's also import a new sound for when the Player gets the food pickup.

  1. Right-click the Sounds folder, and choose Create Sound.
  2. Set the Name to SND_FoodPickup.
  3. Import the sound file FoodPickup.wav from the project’s assets.
  4. Set the Sample Rate to 48000.
  5. Set the Bit Rate to 320.
  6. Press Ok to save your sound.

Next we will make our Pickup parent object.

  1. Right-click the Objects folder and choose Insert Object.
  2. Name the new object OBJ_Pickup.
  3. Set the object’s sprite to SPR_Food_Cherry.
  4. Use Add Event > Create.
  5. Under the Control tab, add an Execute Code action.
  6. Add the following code:

This code sets the pickup’s depth in the game world the same way that we set the Player and Enemy depth previously. It also adds a variable to store the sound that will be made when we collect food, the same way we have a variable to store the hit and miss sounds of attacks.

Next, we’ll add a collision event so the Player can actually get the pickup in-game.

  1. With OBJ_Pickup, use Add Event > Collision > OBJ_Player.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

This if checks whether the pickup and the player are close enough to interact in almost the same way that we check for collisions with attack objects. If they are, the pickup runs User Event 0 and destroys itself. User Event 0 is where we’ll put the code that applies whatever effect the pickup has. By putting the code for the pickup's effect into a separate event, we can easily modify the effect of any new pickups we add later, without having to modify the collision code.

Now we just need to add some placeholder code for User Event 0, and the pickup should work perfectly.

  1. Use Add Event > Other > User Event 0.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

This code is purely a placeholder since the base pickup doesn’t actually do anything.

If you place the pickup in your level and go in-game, you should see it disappear, and hear the pickup audio, when you collide with it.

While we could move on to the first actual pickup right away, let’s give the base pickup a shadow just like we did for the Player and Enemy. This way it fits well into the existing visual style of the game.

  1. Use Add Event > Draw.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

This code does the same thing as our shadow code for other objects. First, it sets the alpha to .6 and sets the color to dark gray, then it draws an ellipse for the shadow. After that, it draws the pickup’s actual sprite.

Making the Food Pickup

Now that our basic pick-up works, let’s make the food version.

  1. Right-click the Objects folder and choose Insert Object.
  2. Name the new object PKP_Food.
  3. Set the object’s sprite to SPR_Food_Cherry.
  4. Set the Parent to OBJ_Pickup.
  5. Use Add Event > Create.
  6. Under the Control tab, add an Execute Code action.
  7. Add the following code:

This code inherits the properties of the base class to set its depth, and it creates a HealAmount variable which determines the strength of the pickup’s healing ability.

Now we’ll go into User Event 0, and add the code that actually heals the Player when they get the food.

  1. Use Add Event > Other > User Event 0.
  2. Under the Control tab, add an Execute Code action.
  3. Add the following code:

All this does is add the HealAmount to the Player’s HP.

Before you test this out, make sure you delete the original pickup in the level and replace it with the food object. 

Now go in-game to test the Food Pickup, and you should see something interesting. While the pickup does heal the player, it actually pushes his health past the edge of the health bar. This happens because we didn’t do anything to prevent the Player’s CurrentHP from exceeding their MaxHP. 

Go back to User Event 0 in the food pickup, and replace the existing line of code with the following code:

The difference between this version and the original version of the code is that this one uses a min statement to set the Player's health to the lower of the two values. So if CurrentHp+HealAmount is less than their MaxHP, it will set their CurrentHP to that; otherwise, it will set it to their MaxHP, and prevent it from going over that value. 

To test this new version out, you should wait until the Player has taken damage to use the pickup. Try letting yourself get hurt by the enemies before getting the food, and seeing what happens. You should see that no matter how little damage you've taken, or what you set the HealAmount to, your HP never goes beyond the Maximum.

Making the Cherry Pickup

Finally, let’s turn the PKP_Food object into a parent class as well, by making a Cherry pickup. This way, you can have as many different food pickups as you want, by continuing to extend the base class with new objects.

  1. Right-click the Objects folder and choose Insert Object.
  2. Name the new object PKP_FOOD_Cherry.
  3. Set the object’s sprite to SPR_Food_Cherry.
  4. Set the Parent to PKP_Food.
  5. Use Add Event > Create.
  6. Under the Control tab, add an Execute Code action.
  7. Add the following code:

Now you can replace the generic food pickup with the cherry we just created, and it should work perfectly in-game.

Conclusion

With that complete, we are going to stop for the day. Make sure you return for the next article, where we will finalize the Enemy and Player movement, and implement a few new features.

In the meantime, don't hesitate to ask me any questions or leave any comments in the feed below.

Hey, Students! Save 50% on a Yearly Envato Tuts+ Subscription

$
0
0

If you're a student, you're in luck. For a limited time, you can save 50% on a yearly Envato Tuts+ subscription. That means you pay just $45 for a whole year of learning. 

Details of the Student Discount

Envato Tuts+ is all about learning, so we already give students heavily discounted subscriptions—the regular student price is $90 a year, instead of the regular $180. What we're offering now is even better—just $45 for your first year of learning, if you sign up before 10 November 2016. 

What you can learn on Tutsplus

Here's what's included in the subscription:

  • 900+ premium courses that you can either watch online or download from our library and take with you.
  • 22,000+ ad-free tutorials so that you can read, research and revise distraction-free.
  • 5 eBooks every month that you can download from our library and read whenever and wherever you want.

Our courses, tutorials and eBooks will teach you all aspects of web design, code, design, illustration, photography, video, and more. Take a look at some of our most popular courses.

You can also choose to learn in the way that works best for you: video or written, short or long, fast or steady, online or offline. Our huge library of learning content has you covered, and it's updated with fresh material almost every day.

Here's a sample video from our recent course on Flexbox, which takes you through six practical CSS projects for everyday use.

 

And here's one from a quick Coffee Break Course on building a desktop app with Electron.

 

Join Us Today

The special $45 price is available today, and the offer expires on 10 November 2016. So sign up now and grab your first year of value-packed digital learning at an incredible price!


Create Clothing for a Character With Blender

$
0
0

Blender is an open-source 3D modeling and animating platform. It is versatile and easy to use. We will be using Blender to import and create animated clothing for our character. You can also use Blender to export your character into pretty much any game engine, specifically Unity.

Downloading Blender

If you don't already have Blender, let's download it by going to the Blender website. Blender can be used for rigging, modeling and animating your character and other objects. The Blender interface can be intimidating at first glance, but once you understand it you can unleash the power of its many tools for developers. 

Standard Layout

Go ahead and open Blender. The standard layout is five windows, like the example above. We need to change from Blender Render to Blender Cycles. On the top bar to the right, you will see a tab where you can change your current view to Cycles. 

Importing Your Character

Along with modeling your character from scratch, Blender allows you to import different types of file extensions. We used MakeHuman to create a ready-made character. You can learn more about MakeHuman in my previous tutorial. Go to File > Import, and then choose your character's file type. 

Importing Your Character

All About the Mesh

Every character or object contains a mesh. This is a universal part of an object which is understood by editing and game platforms. To be exact, a mesh is a collection of vertices, edges, and faces that describe the shape of a 3D object, according to Wikibooks. It is important to note that any object with a large number of vertices will slow down an animation or gameplay. Once you import your character, you can view your vertex count on the top bar.

Editing Our Mesh

There are a couple of different ways to create clothing for your character. For the sake of this tutorial, it is important to save your original character in Blender. After we edit the mesh you cannot change it, so save two files: one with your original character, and the other with your character with clothes—for example, Tom_with_a_Cool_suit, etc. 

Editing Mesh

After importing your character, go into Edit Mode. When you are in Edit Mode, your vertices will appear black. In this mode, you can choose, resize and delete vertices on the mesh. To edit your mesh, you will use the point, line and box editing/vertex mode as highlighted above. You must hold Shift to choose multiple vertices. 

Editing Vertices

To highlight the clothes, we will need to press C in Edit Mode. A circle will appear. You can make the circle larger or smaller by using the wheel on your mouse. To highlight, scroll over the vertices with the left mouse button held down. Be careful with clicking the right mouse button as it will delete your chosen vertices in the circle range. You will be using the right and left mouse buttons to do all of your detailed work around the neck and arms. 

Choosing Mesh
Mesh Detail

Grid View

A shortcut to choose a large area on both sides of your mesh is to go into Grid View (see the sample below). The allows you to quickly make pants and shirts. Be aware that if you choose a very large area, you might mistakenly choose an unwanted section of the mesh. Therefore double check before you separate the mesh.

Grid View

Separating the Mesh

Once you have outlined the outfit that you want, we need to separate it from the rest of your character. While your vertices are selected, click P on the screen while in Edit Mode. A box will appear. Choose Separate from Selection. If you look under the Hierarchy, you will see a replica of your body, for example, Chest001. Go to Object Mode and select this new object, and you will see it outlined on your character. Let's rename it; if it's a shirt, name it accordingly.

Separate By Selection

Once you separate the mesh, you can edit it to your liking. By pressing A and selecting all of the vertices, you can change the size and shape by using your toggle keys. In my case, I wanted my character to wear a skirt, so I created a shirt and then used the Line Vertex Mode to drag down the shirt. 

Adding a Texture

To make clothes look like clothes, we need to add a realistic texture to them. There are tons of textures you can find online. For example, for leather, search for a leather texture. Then save it in a folder you can access with your character. 

In Edit Mode, go to Material in your bottom right window. Make sure that you have selected the piece of clothing you would like edited. Click Add, as in the sample below. Browse for your texture, choose the texture, and rename. Hit Assign. 

Adding A Material

Adding a Modifier

Add A Modifier

At times, we would like to change the look of our clothing. For example, we would like a jacket to be thicker than the jeans or a cape to look heavier. We can achieve this by adding a Solidify Modifier. Go to Tools > Add Modifier and choose Solidify Modifier. You can then edit the number. The higher the number, the thicker the material. Try not to go overboard. 

Quick Tools & Shortcuts

  • Press A to select all.
  • Press F12 for a quick render.
  • Use the Grid View for faster editing.

Fabric Animation

Adding animation to your fabric is not as difficult as it sounds. Blender allows you to add a Cloth physic to your objects. Before we begin, we will need to add a pinning group. If we don't add a pinning group (which holds up the fabric), the cloth will fall straight to the ground. 

In Edit Mode, choose the Vertices Point menu as highlighted below. Depending on your clothing, you will need to choose points where you need the fabric to hold up. If you created a cape, choose points where the fabric meets the shoulders. In my skirt sample below, you can see I chose points by the waist.

Pinning Group

To create a pinning group, choose multiple points in your fabric by holding select and right-clicking the points. Then go into Vertex Groups, click Add, and name it PinGroup. You will see it added into your Hierarchy.  

Add Vertex Group

Go back to Physics, and you will now see pinning underneath the Damping section. Click it and choose PinGroup. Go back to Object Mode and click Play. You will slowly see your fabric move. 

Now we will need to do two things. The first is to add a Wind Field, and the second is to add Collision to your character, as you may notice the fabric is probably going through it. 

Tip: To make it easier to see, it may be a good idea to make other parts invisible by clicking the Eye in the Hierarchy.

Select your character's body in the Hierarchy, or by going to Object Mode and clicking the body in the viewport. Go to Physics and choose Collision.

Let's add a Wind effect. Go to the bottom bar and choose Add > Field > Wind. Move the object in front of your character and hit Play. If you don't like the wind effect, you can change it in the physics menu under Wind. 

Conclusion

The more you use Blender and the tools provided above, the easier it will be. Remember that you can edit any vertex on your character. 

Congratulations! You have now created clothing for your character. 

Using Displacement Shaders to Create an Underwater Effect

$
0
0

Despite their notoriety, creating water levels is a time-honored tradition in the history of video games, whether that's to shake up the game mechanics or just because water is so beautiful to look at. There are various ways to produce an underwater feeling, from simple visuals (like tinting the screen blue) to mechanics (like slow movement and weak gravity). 

We're going to look at distortion as a way to visually communicate the presence of water (imagine that you're standing at the edge of a pool and peering at things inside—that's the kind of effect we want to recreate). You can check out a demo of the final look here on CodePen.

I'll be using Shadertoy throughout the tutorial so you can follow along right in your browser. I'll try to keep it fairly platform agnostic so you could implement what you learn here on any environment that supports graphics shaders. At the end, I'll provide some implementation tips as well as the JavaScript code I used to implement the example above with the Phaser game library.

It might look a little complicated, but the effect itself is only a couple of lines of code! It's nothing more than different displacement effects compounded together. We'll start from scratch and see exactly what that means.

Rendering a Basic Image

Head over to Shadertoy and create a new shader. Before we can apply any distortion, we need to render an image. We know from previous tutorials that we just need to select an image in one of the bottom channels on the page, and map it to the screen with texture2D:

Here's what I picked:

A basic shader to render an image unmodified

Our First Displacement

Now what happens if instead of just rendering the pixel at position uv, we render the pixel at uv+vec2(0.1,0.0)?

It's always easiest to think in terms of what happens on one single pixel when working with shaders. Given any position on the screen, instead of drawing the original color in the texture, it's going to draw the color of a pixel to its right. That means, visually, everything gets shifted left. Try it!

Shifting every pixel by the same value

By default, Shadertoy sets the wrap mode on all textures to repeat. So if you try to sample a pixel on the right of the rightmost pixel, it will simply wrap around. Here, I changed it to clamp (which you can do from the gear icon on the box where you selected the texture).

Challenge: Can you make the whole image move slowly to the right? How about move back and forth? What about in a circle? 

Hint: Shadertoy gives you a running time variable called iGlobalTime.

Non-Uniform Displacement

Moving a whole image isn't very exciting, and doesn't require the highly parallel power of the GPU. What if instead of displacing each position by a fixed amount (such as 0.1), we displaced different pixels by different amounts?

We need a variable that's somehow unique for every pixel. Any variable you declare or uniform you pass in will not vary between pixels. Luckily, we already have something that varies like this: the pixel's own x and y. Try this:

We're vertically offsetting each pixel by its x value. The leftmost pixels will get the least offset (0) while the rightmost will get the maximum offset (1).

Shifting every pixel by a changing value

Now we've got a value that varies across the image from 0 to 1. We're using this to push the pixels down, so we get this slant. Now for your next challenge!

Challenge: Can you use this to create a wave? (As pictured below)
Creating a wave by cycling through our displacement values

Hint: Your offset variable goes from 0 to 1. You want it to periodically go from -1 to 1 instead. The cosine/sine function is a perfect choice for that.

Adding Time

If you figured out the wave effect, try making it wiggle back and forth by multiplying by our time variable! Here's my attempt at that so far:

I multiply uv.x by some big number (25) to control the frequency of the wave. I then scale it down by multiplying by 0.06, so that's the maximum amplitude. Finally, I multiply by the cosine of the time, to have it periodically flip back and forth.

Note: If you really want to confirm that our distortion is following a sine wave, change that 0.06 to a 1.0 and watch it at its maximum!

Challenge: Can you figure out how to make it wiggle faster?

Hint: It's the same concept we used to increase the frequency of the wave spatially.

While you're at it, another thing you can try is applying the same thing for uv.x as well, so it's distorting on both the x and y (and maybe switch out the cos's for sin's).

Now this is wiggling in a wave motion, but something's off. That's not quite how water behaves...

A Different Way to Add Time

Water needs to look as if it's flowing. What we have right now is just going back and forth. Let's examine our equation again:

Equation for a standing wave Does not look like it moves

Our frequency isn't changing, which is good for now, but we don't want our amplitude to change either. We want the wave to stay the same shape, but to move across the screen.

To see where in our equation we want to offset, think about what determines where the wave starts and ends. uv.x is the dependent variable in that sense. Wherever uv.x is 1, there will be no displacement (since cos(1) = 0), and where uv.x is around pi/2, that will be maximum displacement.

Let's tweak our equation a little bit:

Equation for a natural flowing wave

Now both our amplitude and frequency are fixed, and the only thing that varies will be the position of the wave itself. With that bit of theory out of the way, time for a challenge!

Challenge: Implement this new equation and tweak the coefficients to get a nice wavy motion.

Putting It All Together

Here's my code for what we've got so far:

Now this is essentially the heart of the effect. However, we can keep tweaking things to make it look even better. For example, there's no reason you have to vary the wave by just the x or y coordinate. You can change both, so it varies diagonally! Here's an example:

It looked a bit repetitive so I switched the second cos for a sin to fix that. While we're at it, we can also try to vary the amplitude a bit:

And that's about as far as I've gotten, but you can always compound and combine more functions to get different results!

Applying It to a Section of the Screen

The last thing I want to mention in the shader is that in most cases, you're probably going to need to apply the effect to just a part of the screen instead of the whole thing. An easy way to do that is to pass in a mask. This would be an image that maps which areas of the screen should be affected. The ones that are transparent (or white) can be unaffected, and the opaque (or black) pixels can have the full effect.

In Shadertoy, you can't upload arbitrary images, but you can render to a separate buffer and pass that in as a texture. Here is a Shadertoy link where I apply the effect above to just the bottom half of the screen.

The mask you pass in doesn't need to be a static image. It can be a completely dynamic thing; as long as you can render it in real time and pass it to the shader, your water can move or flow throughout the screen seamlessly.

Implementing It in JavaScript

I used Phaser.js to implement this shader. You can check out the source in this live CodePen, or download a local copy from this repository.

You can see how I pass in the images manually as uniforms, and I have to also update the time variable myself.

The biggest implementation detail to think about is what to apply this shader to. In both the Shadertoy example and my JavaScript example, I only have one image in the world. In a game, you're probably going to have a lot more.

Phaser lets you apply shaders to individual objects, but you can also apply it to the world object, which is a lot more efficient. Similarly, it might be a good idea on another platform to render all your objects onto some buffer, and pass that through the water shader, instead of applying it to every individual object. That way it functions as a post-processing effect.

Conclusion

I hope going through composing this shader from scratch gave you some good insight into how a lot of complex effects are built by layering all these different little displacements!

As a final challenge, here's a sort of water ripple shader that relies on the same sort of displacement ideas we saw. You could try to take it apart, unfold the layers, and figure out what each piece does!

Teaching Millions Worldwide: 3,000 Tuts+ Translations Published!

$
0
0

Around two and a half years ago we started translating our tutorials–in all languages imaginable–with the aim of teaching everyone, not just those fluent in English. Today we’ve published over 3,000 translations and that milestone is entirely thanks to the Tuts+ community! This post will take a look at the Translation Project, what it’s achieved, and where it’s headed.

Top Languages

Let’s jump straight in and check out some numbers!

We’ve published translations in 42 different languages, from obvious players like French and Russian, to less well-known languages like Telugu and Tamil (which, by the way, boasts some stunning typography):

Tamil type
Tamil

We’ve posted over 100 translations in each of the following languages:

Spanish657
Portuguese521
Russian330
French219
Indonesian215
Italian192
Croatian141
Polish126
Chinese (Simplified)117
Vietnamese115

Top Translators

A massive 664 community members have published translations on Tuts+ (thank you all!)

Two people have been leap-frogging each other at the top of the table since the project began; Erick Patrick (currently with 219 Portuguese translations) and Javier Salesi (currently with 214 Spanish translations). Incredible effort!

Top Posts

So which translations have resonated with our global audience? In the last couple of months, these have been the most visited:

Note: you may see flags below; flags aren’t the best way to show languages, they more accurately represent nations, but I couldn’t resist using some emojis.

Right, so that’s a fairly convincing performance from Spanish! This makes complete sense, given that there are an estimated 470 million native Spanish speakers worldwide, and Spanish has official status in over 20 countries.

Ignoring Spanish for a Moment

It actually wasn’t Spanish which took the number one spot in our most visited translations, that accolade goes to 10個阻擋你進步的繪圖迷思 (the Traditional Chinese version of “10 Drawing Myths That Block Your Progress”). With almost 250,000 pageviews this translation has seen more traffic than most other single pages, including English originals, in the last year. Amazing!

對於無法理解的技術,這是唯一理解它的魔法。

If we remove Spanish from the equation altogether, the most visited languages are a lot more diverse, including Korean, Russian, German, Portuguese, Polish, and Indonesian.

Most Translated Posts

Some tutorials seem to grasp the imagination of visitors from a particular region of the world, others appeal to everyone. The following tutorials have been translated into the most number of languages:

Where in the World

Visit our interactive map; click on a language and you’ll see some countries turn green. The darker the green, the more traffic comes from that area. Portuguese translations, for example, see more visitors from Brazil than Portugal itself:

Then again, Brazil is the fifth most populous country in the world, with 208 million people living there compared to Portugal’s 10 million. Given that Brazil has a higher proportion of younger people, and enjoys an internet connectivity only 10% lower than Portugal, the extra traffic makes sense. Read more on findthedata.com.

Miscellaneous

Allow me to introduce ZCOOL, a Beijing-based team whose “Design Article Translation Squad” curates design tutorials from around the world, translates them into Chinese, and republishes them on their platform. Residents in some areas of China often struggle to gain access to western websites, so we publish ZCOOL’s Tuts+ translations on both platforms. Check out the Envato Tuts+ page on their website:

艺云台 (Envato)

For more on what we’re doing to push translation in China reach out to Kendra, or follow us on WeChat!

Envato on WeChat
Scan it

More Ways to Connect

Our Twitter channels @tutsplus_es (sooo nearly 1,000 followers!) and @tutsplus_pt, for Spanish and Portuguese respectively, are used as a way of broadcasting new translations. Follow them!

Over 5,000 people have subscribed to the Translation Project newsletter–sign up, and you’ll receive regular updates about what we’re doing, plus inspiration if you’re interested in getting involved and translating something yourself:

The Future

So what lies ahead for the Translation Project? We’re working on two major plans which we think will take things to the next level (and way beyond):

Payment for Translators

The Tuts+ community has expressed a number of motives for being part of this project; giving back, helping others learn, improving their own learning through translation, but we’d like to take that further. In partnership with Native we’re currently working on a system for paying translators; a reward scheme which allows people to earn while they translate. This idea is still in the early stages, but stay tuned for more news before the year’s out!

Native UI
This project wouldn’t have been possible without Native

Localisation of Tuts+

Much of our non-English traffic comes from organic search, but those visitors struggle to use the Tuts+ platform beyond that first page. Visitors who aren’t fluent in English typically find it difficult to find more relevant content in their own language, so we want to rectify that. A fully localised Tuts+ platform is an ambitious prospect–it will have to take cultural as well as linguistic differences into account–but it’s something we feel will be worth pursuing. 

Thank You

3,000 published translations is a fantastic milestone, we’re so happy that this endeavour is proving popular. And there’s plenty more room to grow. Please leave your thoughts and feedback below to help the translation project live up to its full potential!

All Courses Reduced to $3 for Cyber Monday!

$
0
0

This Cyber Monday, instead of stocking up on material things, why not invest in learning some valuable new skills?

You can do that by buying any course on Envato Tuts+ for just $3 on Monday, 28 November 2016. You can choose as many as you want from our library of almost 1,000 courses on design & illustration, code, web design, photography, and more.

Cyber Monday promotion

The discount is available from 12:00am November 28, 2016 to 8:59pm November 29, 2016 AEDT (that's Australian Eastern Daylight Time). No further discounts, coupons, or offers can be used in conjunction with this promotion.

More Details About Our Courses

We offer hundreds of in-depth video courses on Envato Tuts+ across a range of different topics, and we publish several new ones every week. So if there's a new design, code, web design, or photography skill you want to learn, we've probably got a course teaching it.

The courses range in length, too, so you can choose the right ones for your own schedule. Our quick Coffee Break Courses teach a new skill in just ten minutes, while some of our longer courses go into a lot of depth and last more than two hours.

Here are some examples of recent courses we've published:

Build a Blog With Craft CMS

Craft CMS is a system which is rapidly becoming the “go to” for web professionals. With it, you can create robust, flexible and customizable websites that are secure and simple for clients to use.

In this course you’ll learn how to turn Craft CMS into one of the most widely used types of site: a blog. In 15 detailed videos, you'll get a thorough grounding in using Craft CMS to create a blog, and you'll learn how to set up all the most common features you’re used to from popular blogging platforms.

 

Angular Testing Inside Out

Unit testing is a key tool for ensuring the correctness of our software, and Angular apps are no exception! In fact, part of what makes Angular so amazing is that it's a framework written from the ground up with testing in mind.

In this course, Envato Tuts+ instructor Dan Wellman will show you how to test every part of your Angular app, including directives, filters, services, and components. You'll see how to write tests using the popular Jasmine and Sinon library, as well as how to write end-to-end tests with Protractor.

 

A Quick Guide to Color in Digital Painting

In digital painting, unlike traditional painting, you can easily create as many colors as you want. That's both a blessing and a curse. It's great to have access to more colors than you'll ever need, but if you don't understand how color works, the colors you choose will simply look wrong. 

To manage your colors properly, you need to understand their components: Hue, Saturation, Brightness, and Value. This very short Coffee Break Course will teach you the fundamentals of color that every digital artist should know.

 

How to Color Grade Video

The art of color grading sometimes feels as if it's shrouded in mystery—the secret sauce that filmmakers use to get that magic “cinematic” look. Grading might seem a big, intimidating, costly process, but it doesn't have to be that way anymore. Just a little bit of grading can go a long way to creating a compelling look in projects of all sizes, without breaking the budget!

In this course you will learn the secrets of color grading. You'll learn how color enhances and shapes perception. You will learn how to push colors away from the accurate and neutral into something that has more pop and punch. You will learn how to create some specific looks and how to use vignettes, grain, and more!

 

Don't Forget the Discount

Remember, this sale runs for just 24 hours, so make sure you take advantage of it by visiting our Cyber Monday page and setting a reminder. When Monday rolls around, that same page will display all the details of the offer and how you can secure your discount. Enjoy!

Redesign Your Display List With Spatial Hashes

$
0
0

In any 2D game, you have to know what order to draw your sprites in. You usually draw from the back of the scene to the front, with the earlier objects being covered by the later ones. This is the standard Painter's Algorithm used to represent depth on a canvas (digital or otherwise).

In the Painters Algorithm distant objects are drawn first
By Zapyon - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=14256921

The most straightforward way to keep track of this is by putting all your objects into one big array, sorted by their depth. So in the above scene, your array would look something like: [Mountain, Ground, Tree1, Tree2, Tree3, ... ]

The Problem With a Single Big Array

The problem with one central display list is that there's no easy way to find out which objects are on screen at any given moment. To do that, you need to loop through the entire array and check every single object. This mostly becomes an issue if you have a large game world where many objects exist outside the screen and shouldn't be rendered or updated.

A spatial hash is a way of storing your objects to avoid this problem. The neat thing about using a hash is it always takes a constant time to figure out which objects are on screen, regardless of how huge the game world might be!

Now most game engines won't actually let you play around with how they structure their objects internally, but if you're programming in an environment where you're in control of the draw calls (such as your own OpenGL engine, a pure JavaScript game, or more open frameworks such as LÖVE), this could be something worth implementing.

The Alternative: Spatial Hashes

A spatial hash is just a hash table where each key is a 2D coordinate and the value is a list of game objects in that area.

Imagine that your world is split into a grid such that each object belongs to at least one cell. Here's how you would look up something at position (420,600) if you had this implemented in JavaScript:

It's that easy! You can immediately know what's in that position. The key is a string concatenation of the X and Y coordinates, but it doesn't have to be a string, nor does it need a comma in the middle; it just has to be unique for each pair of X and Y.

To see why this is so convenient, consider how you would get the objects at this position using one big array:

We're checking every single object, even if most of them are very far away to begin with! This can greatly cripple your performance if you're doing many lookups like this and your gameObjects array is huge.

A Concrete Example

If you're not yet convinced of how useful this is can be, here's a demo written in pure JavaScript where I try to render a million objects in the game world. In both cases, only the objects on screen are actually rendered.

One Big Display List

Click to see the live demo running!

Spatial Hash

And the live spatial hash version.

The single array version is painfully slow. Even if you save which elements are on screen so you don't have to check every frame, you still have to check the whole array again when the camera moves, leading to severe choppiness.

Just changing the way we store our game objects can make all the difference between a smooth experience and an unplayable game.

Implementing a Spatial Hash

A spatial hash should be really easy to implement in any language (in fact, going from the first example to the second above only took an extra 30 lines of code!)

There are four steps to implementing this as your rendering system:

  1. Set up the hash table.
  2. Add and remove objects in the hash.
  3. Collect objects in any given area.
  4. Sort objects by depth before rendering them.

You can see a functional implementation in JavaScript on GitHub as a reference.

1. Set Up the Hash Table

Most languages have some sort of built-in hash table/map. Our spatial hash is just a standard hash table. In JavaScript you can just declare one with:

The only other thing to mention here is that you have some leeway with picking the cell size. In general, having your cells be twice as big as your average object seems to work well. If your cells are too big then you'll be pulling in too many objects with every lookup. If they're too small then you'll have to check more cells to cover the area you want.

2. Add and Remove Objects in the Hash

Adding an object to the hash is just a matter snapping it to a cell, creating the cell array if it doesn't exist, and adding it to that array. Here's my JavaScript version:

There's a caveat, though: What if your object spans multiple cells, or is too big to fit in one cell?

An object in multiple cells

The solution is just to add it to all the cells that it touches. This guarantees that if any part of the object is in view then it will be rendered. (Of course, then you also need to make sure you're not rendering these objects multiple times.)

I haven't implemented a remove function in my example, but removing an object is just a matter of taking it out of the array(s) it's a part of. To make this simpler, you can have each object keep a reference to which cells it belongs to.

3. Collect Objects in Any Given Area

Now here's the core of this technique: given an area on screen, you want to be able to get all the objects in there.

All you need to do here is start going through all the cells based on where your camera is in the game world, and collect all the sub-lists together into one array to render. Here's the relevant JavaScript snippet:

4. Sort Objects by Depth Before Rendering Them

You might have realized by now that giving up on the big display list idea also means you give up on the convenient depth sorting. We grab objects from our grid based on their location, but the array we get is not sorted in any way. 

As a final step before rendering, we have to sort our array based on some key. I gave each object a depth value, and so I can do:

Before finally rendering everything:

This is one of the drawbacks to this method, that you have to sort what's on screen every frame. You can always speed this up by making sure all your sub-lists are sorted, so you can merge them while you concatenate to maintain the order.

That's it! You should now have a (hopefully much faster) working rendering system!

Other Uses & Tips

This can be a really useful technique, but as I said in the introduction, you can only do this in a game engine or framework that gives you control over the draw calls. Still, there are things you can use spatial hashes for besides rendering. In fact, they're more commonly used to speed up collision detection (you can skip any collision checks for objects you know are far away or are not in the same cell).

Another technique that's similar to spatial hashes, but a little more complicated, is using a quadtree. Whereas a spatial hash is just a flat grid, a quadtree is more of a hierarchical structure, so you don't have to worry about cell size, and you can more quickly get all the objects in a given area without having to check every little cell.

In general, you should keep in mind that a spatial structure is not always going to be the best solution. It's ideal for a game that has:

  • a large world with many objects
  • relatively few objects on screen compared to the world size
  • mostly static objects

If all of your objects are moving around all the time, you'll have to keep removing and adding them to different cells, which might incur a significant performance penalty. It was an ideal rendering system for a game like Move or Die (almost doubling the fps) since levels were made up of a lot of static objects, and the characters were the only things that moved.

Hopefully this tutorial has given you an idea of how structuring data spatially can be an easy way to boost performance, and how your rendering system does not always have to be a single linear list!

Viewing all 728 articles
Browse latest View live