Friday, March 17, 2017

Crafty Beyond the Basics: Collisions

Crafty Beyond the Basics: Collisions

It is very important in a game that you detect collisions properly. Nobody is going to play a game where things start exploding even when they are many pixels apart. Besides the graphics and sounds, this is one more thing that you should try to keep as accurate as possible.

In this tutorial, you will learn about detecting and debugging collisions in detail.

Detecting and Ignoring Hits

Before you can detect any collisions, you need to add the Collision component to an entity. This component will successfully detect a collision between any two convex polygons. This component has two events: HitOn and HitOff. The HitOn event is triggered when a collision occurs. It will not be triggered again unless collisions of that specific type cease. The HitOff event is triggered when a collision ceases.

If you are checking for collision with multiple components and all these collisions occur simultaneously, each collision will fire its own HitOn event. The data received from a collision event is only valid as long as the collision is still occurring.

You can use the .checkHits() method to perform collision checks against all entities with a specified component. Calling this method multiple times will not result in multiple redundant checks. 

Keep in mind that hit checks are performed upon entering each new frame. Let's say there are two objects which have not yet collided when the hit check is performed. Now, if one of the objects moves to a new location and overlaps with the second object later in the same frame, the hit events will not be fired until a collision check is performed again in the next frame.

If you have to detect only the first collision between different entities, you can use the .ignoreHits(String componentList) method. The componentList variable is a comma-separated list of components with which you no longer want to detect collisions. When no arguments are provided, it will stop collision detection with all entities. Here is an example:

You can see that Crafty not only starts detecting the HitOn event but also the HitOff event. That's why the color of the big box does not change back to black.

Another similar method called .resetHitChecks(String componentList) can be used to re-check for collision between specific components. This method will keep firing the HitOn event again and again as long as the collision is still happening.

Debugging Collisions

When entities are moving continuously, it is very hard to see if the collisions are being fired at the right time. In the above demo, it looks as if the HitOn event is firing slightly before the actual event. Crafty gives you the option of drawing hit boxes around entities so that you can actually see what's going on. 

There are two components that you can use for debugging purposes. These are WiredHitBox and SoldHitBox. 

The first component will allow you to use the .debugStroke([String strokeColor]) method, which will draw an outline around the entity with a given color. When no color is provided, the color red is used to draw the outline. 

Similarly, the second component is used to fill the entities with a given color using the .debugFill([String fillStyle]) method. When no color is provided, the color red is used. Here is a demo with the .debugStroke() method.

Creating a Custom Hit Box

You can also create a custom hit box for collision detection. This is helpful when you are using image sprites in your game that are not rectangular. The .collision() method that you can use to create a custom hit area accepts a single parameter that is used to set the coordinates of the new hit box. 

These coordinates can be supplied in the form of a polygon object, an array of x,y coordinate pairs, or a list of x,y coordinate pairs. The points of the polygon are marked in a clockwise manner, and they are positioned relative to the unrotated state of our entity. The custom hit area will automatically rotate itself when the entity rotates. 

There are a few things that you should keep in mind when using custom hit areas. The hit area that you define should form a convex polygon for the collision detection to work properly. For those who are unfamiliar with the term, a convex polygon is a polygon with all of the interior angles less than 180°. You might also see slight performance degradation when the hit area that you defined lies outside the entity itself.

The custom hit area that you defined won't have any effect unless you add the Collision component to every entity with which your hit area needs to detect a collision.

In the above demo, we have defined a custom hit box that lies outside the orange box. As you can see, the big block turns blue only when it collides with the triangle. The position of the orange box doesn't matter.

Let's take a look at another example which uses a spaceship by Gumichan01. The default hit box for the spaceship is the boundary of the sprite itself. In the current scenario, the top right corner of the spaceship touches the block first, but that space is actually empty. For users who are playing your game, this is a case of bad collision detection.

What you can do here is define your own hit area using a triangular shape like the following code. The custom hit box polygon that you define can have as many sides as you want. Just make sure that it is still a convex polygon.

Conclusion

After completing all these tutorials, you should now be able to create your own little games with great graphics, nice sound effects, scenes, and collision detection. I should remind you that I have used Crafty version 0.7.1 in this tutorial, and the demos might not work with other versions of the library. 

JavaScript has become one of the de-facto languages of working on the web. It’s not without it’s learning curves, and there are plenty of frameworks and libraries to keep you busy, as well. If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato marketplace.

If you have any questions, let me know in the comments.


How to Create a Western Text Effect in Adobe Illustrator

How to Apply a Halftone Effect to Your Images With a Photoshop Action

Thursday, March 16, 2017

RSVP for Events With These WordPress Plugins

Photoshop in 60 Seconds: Create a Pearl Necklace With the Mixer Brush in Photoshop

How to Use IFTTT With Google Sheets

Crafty Beyond the Basics: Sounds and Scenes

Crafty Beyond the Basics: Sounds and Scenes

Just like images or sprites, sound also plays a vital role in games. The right background music can set the mood for the game. Similarly, including sound effects for things like a crash or gunfire will make the game much more interesting.

You can also add scenes to your game to make it more organised. For example, instead of directly showing the game screen to users, you can first show them the home screen where they can choose a difficulty level for the game or increase/decrease the volume of background music. 

In this tutorial, you will learn how to add sounds and scenes to your games using Crafty.

Adding Sounds

The process for adding sounds to a game is similar to adding sprite sheets. You need to create an asset object and then supply an array of audio files for different sound effects. Crafty will then load the first file that is supported by the browser. Here is an example:

Once you have added the audio files, you can play them using Crafty.audio.play(String id, Number repeatCount, Number volume). The first parameter is the Id of the file we want to play. To play the background music, you can pass "back_music" as Id. 

You can control how many times an audio file is played using the second parameter. When this parameter is not specified, the file is played only once. You would probably want to continuously keep playing some sounds. One such example is the background music of a game. This can be achieved by setting the second parameter to -1. 

The third parameter controls the volume of the given audio file. It can have any value between 0.0 and 1.0. This is the code to play background music:

You can also play audio files based on some events like collision between entities or a key press.

Keep in mind that you need to add the Keyboard component to your hero before it can detect the KeyDown event. The above code binds the KeyDown event to the hero and checks if the key was pressed using evt.key. If the Up Arrow key is pressed, a jumping animation is played for the hero once. A gunshot sound is played as well.

Try pressing the Up Arrow key in the following demo and you will see it all in action. I have commented out the line that plays the background music, but you can just uncomment it while playing with the demo. 

The background music in the demo has been created by Rosalila, and the gunshot sound is by Luke.RUSTLTD.

There are a lot of other methods that you can use to manipulate the sounds played by Crafty. You can mute and unmute all the audio files that are being played in the game by using .mute() and .unmute() respectively. You can also pause and resume audio files based on their Id by using the .pause(Id) and .unpause(Id) method.

There is a limit on the maximum number of sounds that can be played simultaneously in Crafty. The default limit for this value is 7. Each of the different sounds playing simultaneously is a channel. However, you can set your own value by using Crafty.audio.setChannels(Number n). You can also check if a given audio file is currently playing on at least one channel using the .isPlaying(string ID) method. It will return a Boolean indicating if the audio is playing or not.

Scenes in Crafty

The game screen is generally not the first thing that you see in a game. Usually, the first screen that you see is the loading screen or the main menu screen. Then, once you have set different options like audio or difficulty level, you can click the play button to move on to the actual game screen. Finally, when the game is over, you can show users a game over screen.

These different game screens or scenes make your game more organized. A scene in Crafty can be created by calling Crafty.defineScene(String sceneName, Function init[, Function uninit]). 

The first parameter is the name of the scene. The second parameter is the initialization function, which sets things up when the scene is played. The third parameter is an optional function which is executed before the next scene is played and after all the entities with 2D component in the current scene have been destroyed.

Here is the code for defining the loading screen:

In the above code, I have defined a "loading_screen" scene. The initialization function set the background color to orange and shows some text to give the user some information about what's coming next. You can include a logo and some menu options in an actual game here. Pressing any key while the canvas is in focus will take you to the actual game screen. The .enterScene(String sceneName) method has been used here to load the "game_screen". 

In the following demo, you can press the UP key 10 times to go to the final screen.

Conclusion

After completing this tutorial, you should be able to add a variety of sound effects to your game and be able to control the audio output. You can now also show different screens to a user in different situations. I should remind you that I have used Crafty version 0.7.1 in this tutorial, and the demos might not work with other versions of the library. 

In the next and final tutorial of this series, you will learn how to improve collision detection in Crafty.