Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
13. August 2015

 

Paradox ships with a full 3D editor named Paradox Studio.  In this tutorial we are going to take a look at what it can do and how it works. 

 

Once again, there is an HD video version of this tutorial available.

 

Paradox Studio Introduction

 

This is Paradox Studio:

image

 

This is where you can import assets, create entities, add components and instantiate them into scenes.  In a nutshell, it’s where you can visually compose the elements of your game.  Using Studio is strictly optional ( as is using Visual Studio ) but it can make your life a great deal simpler.

 

The majority of panels are configurable, can be minimized or re-docked in whatever pattern you prefer:

image

 

I am going to cover each panel one at a time.

 

Scene Graph

image

This is where you compose the entities that make up your game.  All game elements are entities, which in turn are containers for components, that can themselves consume or use assets.  Don’t worry, we will cover this in more detail later.  Just think of it this way… the Scene Graph is the stuff that composes your world, and all the “stuff” in your game is ultimately an Entity.  In the above screen shot, you can see the default scene created when you create a new project, it consists of a Scene that has a Sphere(Mesh), Ground(Mesh), Camera(Camera), Directional Light(Light) and Skybox(Light) entities.

 

If you create multiple scenes (I’ll show you how shortly), they will appear across the top in tab form.

image

 

This is only panel that cannot be minimized or moved, although it can be resized.  I suppose I should point out that the Scenegraph and 3D view are actually the same window, but they serve very different functions, so I will treat them as a separate windows for this tutorial.

 

You can create new entities using the imageicon, which will drop down the following menu:

image

 

Remember, an Entity is simply a container for Components, all of which have a default component called Transform, that allows them to be positioned in the world.  This means you can create the equivalent of a Point light entity by creating an Empty entity and adding a Light component to it.  We will see the component options later on.  When you create a new entity, it will be created (and automatically selected) in the 3D view:

image

 

Clicking the small magnifying glass beside the entity will automatically focus the 3D view on that entity, zooming in on it.

 

One last important concept to understand is parenting.  If you create a new entity with an entity selected, the new entity will be parented to the selected entity, like so:

Scenegraph_CreateNew

 

The newly created light will now inherit transforms applied to it’s parent, but can also be transformed independently.  The inheritance only goes down the genealogy, not up.

Scenegraph_Parent

 

Solution Explorer

 

image

The ultimate file format for a Paradox project is actually an sln file, in other words, a Visual Studio Solution file.  On top of that, Paradox provides a format for bundling codes and assets together, the package ( pdxpkg file extension ).  The Solution Explorer is where you manage the contents and dependencies of your project.

 

You can create sub folders to better organize your assets:

image

 

Even create entire new packages:

image

 

You can also create new assets directly from the Solution explorer:

image

 

Asset View

 

image

 

The asset view shows you the assets in the currently selected folder from the Solution View.  You can select an Asset (to edit it’s properties in the Property Grid, which we will cover shortly) by left clicking it. 

You can create new assets, or import existing ones, using these two toolbar buttons:

image

You can also import an asset using drag and drop from Windows Explorer:

AssetImport

 

You can also drag and drop Assets to the 3D view to create new Entities.  Here for example is dragging and dropping a 3D model asset.

AssetDragToInstantiate3DView

 

Asset Preview / History / References

These three panels are all actually separate, but by default appear together and are pretty straight forward, so I will cover them as a single entity.  Much of the functionality in these panels requires you to select an asset in the asset view.

Action History

image

Simply a stack of actions you’ve performed.  You can undo/redo using the typical CTRL+Z | CTRL+Y hotkey.  In all honesty, not sure why you would use this panel.  It’s display only, you cant change anything.

 

Asset Preview

image

A handy quick preview of how an asset would look.  The above screenshot is with a material asset selected, you can then pick a geometric shape to apply your material to.  For 3D models, it instead loads a simple model viewer.  Can be controlled via the mouse, scroll wheel zoom, right button pans and left button orbits the camera.

 

References

image

There are two modes of operation for this panel, References and Referencers.  It’s a great way to see what assets/entities use an asset, and in turn, what assets an asset depends on.  The above example is the Referencers tab with the default Sphere material selected, you can see that the Sphere Procedural Model uses this asset.

 

Property Grid

image

 

This is probably the most important panel in Paradox Studio.  The contents are entirely dynamic, depending on what you have selected in the editor.  The above example shows the properties with a Material asset select.  As you can see, numerous material properties can be configured here.  The settings vary from asset type to asset type.  Below for example shows a Model asset selected:

image

 

This nicely illustrates the relationship between assets.  Remember earlier when I selected the Sphere Material and it showed the Procedural Model as a Referencer?  Well this is where that reference was set.  You can see that the material attached is a Sphere Material ( the example I showed earlier in the Property Grid ).  You can easily select these relationships by clicking the Hand icon:

image

 

This will in turn bring up the Asset Picker dialog, and show compatible assets:

image

 

As you can see, you can access the entire solution, in case your asset exists in a different folder or package entirely.

 

The Property Grid functionality changes completely however if you have an Entity from the Scenegraph selected instead of an Asset, like so:

image

 

This is where you can both configure existing, or add new components to your entity.  As I said earlier, Entities are simply containers for components.  The above example is a camera, which you can see is composed of a Transform component and a Camera component.

You can also add new components to an entity using the Add Component button.

image

 

I will cover the entire process in more detail later, including how to do this all using code instead.

 

3D View

image

Finally we have the 3D view ( which technically is the same panel as the Scene graph as mentioned earlier ).  This is a 3D representation of your game world.  As we saw earlier, we can create new instances of an asset by dragging and dropping.  You can also easily select and transform assets in your scene.  If you are comfortable with a 3D application like Max or Maya this concept should be immediately comfortable to you.

 

You can move, rotate and scale using the toolbar across the top. 

image

Or using the following hot keys:

  • Q – Select
  • W – Translate/Move
  • E – Rotate
  • R – Scale

When you select an object, a 3d manipulator widget is displayed, like this one for rotating:

image

Each color corresponds with a particular axis, so the blue circle rotates around the Z axis, green around the Y and red around the X.  You can also use the grey ball in the middle to transform along all 3 axis at the same time.

You can also use these control bar buttons:

image

To configure which coordinates the manipulator should work on, world space, local space, or camera.

 

Misc

image

Across the top of the application is the above toolbar.  The icon on the far left opens the project in Visual Studio.  The grayed out button syncs changes between the two.  The next button enables you to compile your code, Visual Studio is not required.  The play icon enables you to run your game and it will run for the platform selected in the drop down to the right.  The final button enables live scripting, something we will talk about later.

 

image

Using the View menu you can toggle the visibility of every single panel we just discussed.

 

image

Pressing Ctrl + Shift + D or Help Menu->Show Debug Window, brings up the above invaluable tool.  It contains the various logs and handy debugging details as your game runs.  If something goes wrong, this is the first place you should go for details.

 

The Video

 

Programming


14. July 2015

 

Since picking up the Humble Bundle a few days back, I’ve been playing around with Stencyl ( expect more later ) a little bit.  While Stencyl provides a drag and drop programming interface, it ultimately enables you to generate Haxe code ( more seamlessly than you probably expect ).  My preferred Haxe editing environment is the IntelliJ IDE.  This tutorial looks at configuring one to work with the other.

 

First go download and install the community version of IntelliJ IDEA if you haven’t already.

Next run IntelliJ, we need to configure the Haxe plugin.  With IntelliJ loaded, select Configure->Plugins:

image

Click Browse Repositories

image

 

Type Haxe into the search field, select Haxe plugin and click Install plugin

image

 

Click yes when prompted, the plugin will be downloaded, then click Close/OK and let IntelliJ IDEA restart.

 

Now load Stencyl if you haven’t already.  Click File->Preferences or Alt+Enter:

image

 

Click the Editors tab, drop down the combo under Code Editor and select Choose Application… and navigate to the idea.exe:

image

 

Next Apply Changes.

 

Next we need some code to edit.  One easy way is to create a new Behavior.   From the Dashboard, select Actor Behaviors, Create New

image

 

Fill in the resulting dialog like so (Select Code Mode and name it), then click Create:

image

 

You new behavior will be created and opened in the built in code editor.  Now click Open In External Editor:

image

 

This will open in IntelliJ, but you wont have any code completion or intellisense.  Let’s fix that now.  To do this we need to configure the Haxe SDK.  To do so, right click the generated project name and select Open Module Settings or hit F4 with the project selected.

image

 

Click SDKs, then + then Haxe toolkit

image

 

Then navigate to the Stencyl install directory, then plaf/haxe and click OK.

image

 

Finally we want to add the additional libraries so IntelliJ knows about them.  Select ClassPath, then + and add /lib.

image

 

Finally we need to tell IntelliJ that this project is a Haxe project.  Still in settings (F4 to go back if you’ve closed it), go to Project and select Haxe as SDK.

image

 

In the future, this last step should be the only one you have to perform, unless you change your Stencyl install.

 

Now your code in IntelliJ should have full autocomplete:

image

 

Now when you save in IntelliJ, it will automatically sync in Stencyl.

Programming


27. May 2015

 

So today I fired up Steam to finally pull the trigger on Pillars of Eternity and what do I see….

 

image

It seems that Degica games, the makers of the popular RPG Maker series of game building tools are having a sale today.  Their flagship product RPG Maker VX Ace ( … quite the name ) is currently on sale for 80% off.

 

On top of RPG Maker Vx Ace, RPG Maker XP and RPG Maker 2003 are all also discounted, 80% and 50% respectively.  What perhaps caught my eye most of all however wasn’t the RPG Maker line of products, but Spriter is also on sale for 75% off.   Spriter was a successfully kickstarted project made by BrashMonkey, I had no idea Degica was now the publisher.

 

About Each Program

 


RPG Maker

 

 

This is a program that has been around for a very long time, first released in 1988.  As the title suggests, it’s a game building tool for making RPG’s, generally of the classic jRPG format.

 

That said, this is a proper game building application, a number of commercially shipped games were created using the various iterations of RPG Maker.  RPG Maker was mentioned as an option in my guide to getting kids started in game development.  Bundled with a ton of premade assets, it is a good way to get your hands wet in game development.  In addition to world, character, dialog, etc… building tools, there is also a programmatic layer using the Ruby programming language. 

 


Spriter

 

Perhaps of most interest to GameFromScratch readers is Spriter.  Spriter is essentially a modular 2D animation system.  You basically cut your sprites up into multiple independent pieces which in turn can be animated.  You can also apply an IK chain ( inverse kinematics… think skeleton ) that controls the animation for you.  You can then export the resulting animation as a sprite sheet, sequence of images or as an animated gif.

 

Most likely though you will want to use the Spriter API, or one of the pre-existing plugins, and use the Spriter animations directly in your game engine, such as Construct, Unity or LibGDX.

 

Truth is, I did a pretty lousy job there describing Spriter, so I will just show their video instead…

 

 

Both are on sale until May the 29th. 

 

Oh, and as I finish typing this up, the Steam page for the sale now appears to be broken…

News


29. April 2015

 

Well this one came somewhat out of the blue for me.  Microsoft just released a cross platform ( Windows, Mac, Linux ) code editor called Visual Studio Code.  It’s not a full blown (and bloated!) IDE like Visual Studio, more of a streamlined code focused editor like Sublime Text or Brackets.  It is of course a preview release, so expect issues. 

 

In Microsoft’s own words:

 

Why Visual Studio Code?

Visual Studio Code provides developers with a new choice of developer tool that combines the simplicity and streamlined experience of a code editor with the best of what developers need for their core code-edit-debug cycle. Visual Studio Code is the first code editor, and first cross-platform development tool - supporting OSX, Linux, and Windows - in the Visual Studio family.

 

Visual Studio Code run's on Max OSX, Linux and Windows

 

At its heart, Visual Studio Code features a powerful, fast code editor great for day-to-day use. The Preview release of Code already has many of the features developers need in a code and text editor, including navigation, keyboard support with customizable bindings, syntax highlighting, bracket matching, auto indentation, and snippets, with support for dozens of languages.

 

For serious coding, developers often need to work with code as more than just text. Visual Studio Code includes built-in support for always-on IntelliSense code completion, richer semantic code understanding and navigation, and code refactoring. In the Preview, Code includes enriched built-in support for ASP.NET 5 development with C#, and Node.js development with TypeScript and JavaScript, powered by the same underlying technologies that drive Visual Studio. Code includes great tooling for web technologies such as HTML, CSS, LESS, SASS, and JSON. Code also integrates with package managers and repositories, and builds and other common tasks to make everyday workflows faster. And Code understands Git, and delivers great Git workflows and source diffs integrated with the editor.

 

But developers don't spend all their time just writing code: they go back and forth between coding and debugging. Debugging is the most popular feature in Visual Studio, and often the one feature from an IDE that developers want in a leaner coding experience. Visual Studio Code includes a streamlined, integrated debugging experience, with support for Node.js debugging in the Preview, and more to come later.

 

Architecturally, Visual Studio Code combines the best of web, native, and language-specific technologies. Using the GitHub Electron Shell, Code combines web technologies such as JavaScript and Node.js with the speed and flexibility of native apps. Code uses a newer, faster version of the same industrial-strength HTML-based editor that has powered the “Monaco” cloud editor, Internet Explorer's F12 Tools, and other projects. And Code uses a tools service architecture that enables it to use many of the same technologies that power Visual Studio, including Roslyn for .NET, TypeScript, the Visual Studio debugging engine, and more. In future previews, as we continue to evolve and refine this architecture, Visual Studio Code will include a public extensibility model that lets developers build and use plug-ins, and richly customize their edit-build-debug experience.

 

We are, of course, still very early with Visual Studio Code. If you prefer a code editor-centric development tool, or are building cross-platform web and cloud applications, we invite you to try out the Visual Studio Code Preview, and let us know what you think!

 

I’ll be sure to check it out and get back to your with my opinion.  Cross platform tools are always nice.  This new Microsoft…  wow they impress me with some of their moves.

News


12. October 2014

 

The following is a guest tutorial written by Guntis at MightyEditor showing how you can easily use MightyEditor and Phaser to create a game.

 

 

This article will give you an example on how to use popular HTML5 game development framework Phaser and editor based on top of it - MightyEditor. This tutorial will take about an hour and only ~90 lines of actual code. Following game development aspects will be introduced: sprites, sprite animations, physics, collision, game states, player death/revival.

 

Requirements

 

You should use the newest version of Google Chrome. Other browsers should work, but are not tested.

 

Creating a project

 

In this tutorial we will create a coin collecting-spike avoiding platformer.

Go to http://mightyeditor.mightyfingers.com/ and click on "Create New Project". Enter the name of your game. In this tutorial, our game will be called "SockMan"

 

1

 

Next, locate the settings panel in the bottom-right and change the worldHeight, worldWidth, viewportHeight, and viewportWidth values to 1026x578, as shown in the image below. Viewport is the size of the in-game camera, but we won't be dealing with camera controls in this tutorial. 

 

2

 

Uploading game assets

 

Next up - game assets. First, download the assets and extract them. Then locate the asset manager in the upper-right corner and either select the Upload File/Upload Folder options or simply drag and drop the files from your file explorer straight to the manager panel.

 

3 

 

Creating the world

 

Select the stamp icon, then, in the asset panel, click on the image you want to place, bg_wall.png, for now and then click on the map grid to  place the asset on the map. Note, that the dark grey area represents the world/viewport. CTRL-click snaps the image to grid and you can move the image around afterwards by selecting the arrow tool in the left side menu. More accurate placement is possible by using the 'settings' menu in bottom-right. Next, place the 'grass_tile.png' asset like described above and you should you get a world like in the picture below.

 

4

 

Next up - grouping the placed objects together. Locate the objects panel in the middle-right and either select Add Group and then select and drag the objects in the newly created group or select the objects and then click on Group Selected Objects (SHIFT-click selects multiple objects). After that, rename the group to "bg" (double-click on group name) and your project should look like the image below.

 

 5

 

Note: it can be useful to lock (small lock icon on the right side) the background and any other groups/objects in place, so they become unclickable and don't mess with placing other objects.

 

Adding foreground objects

 

After placing background, we will add (almost) the rest of the objects to the game world - boxes, grass tiles, chest and spikes. To do that, simply use the stamp tool to place each object on the map (remember about CTRL to snap to grid) and group them accordingly - boxes and grass in "objects", spikes in "spikes" group and leave the chest 'groupless'. Everything should look similar to the image below, but feel free to create your own layout.

 

6

 

As for the actual character and coins, things get a little different, because there are multiple frames per image for animations. Select the character.png asset and in the Settings panel set its frameWidth and frameHeight values to 100px,the anchorX to 0.5 and anchorY values to 0.7.

 

7

After that just place the character sprite on the left side of the map by using the usual stamp tool. Repeat these step with the coin spritesheet, only changing the frameWidth to 113px and frameHeight to 71px. Both anchors are 0.5. Place multiple coins on the map and group them together in a 'coins' group. Finally, select the the text icon (big T) in the toolbar and place a "0" in the top right corner of your game world. In the objects panel, rename it to "gold". Now your game world should look like this and we can turn to actual coding.

 

8 

 

Switching to source editor

 

You can switch to the source editor in the top-left of the screen. Editor keyboard shortcuts can be found here.

 

9

 

Game states

 

Coding is done by using the Phaser development framework (homepage and documentation). There are different states (separate parts of the game like intro, menu, gameplay etc.). The MightyEditor gives you four states by default: boot, load, menu and play, but, in this tutorial, we will only be coding in the play state and without any menus, so we should just go straight to the play state. Switch to the 'menu.js' file and call the switch to the play state.

window.SockMan.state.menu = {
        create: function() {

            this.game.state.start("play");
        },

 

You can now click on the Open Game button in the top panel and the game will load... to a blank screen. The graphics must be initialized beforehand. To do that, we will switch to the play.js state. We need to use the mt.create function in the create method like this:

 

create: function() {
    this.bg = mt.create("bg");
    this.character = mt.create("character");
    this.spikes = mt.create("spikes");
    this.chest = mt.create("chest");
    this.objects = mt.create("objects");
    this.coins = mt.create("coins");
    this.gold = mt.create("gold");
},

 

This initializes and creates the game sprites and sprite groups. Now, when opening the game, the visuals will be there, but the image is static.

 

Adding Physics

 

To add movement, first we must enable physics on the character. To do that, head back to the Map Editor and select your character sprite. In the bottom-right, use the Physics panel to enable it. Set these values:

  • enable: 1
  • immovable: 0
  • size-width: 40
  • size-height: 70
  • gravity-allow: 1
  • gravity-y:1000
  • collideWorldBounds: 1

 

10

 

In the end, everything should look like this:  Note: the size parameters are for the physics body, so the game interacts only with the area you want, not the blank parts or the sprite. Your character should now fall through the floor and stay on the edge of the game (that's what collideWorldBounds is for). To fix that, we must enable collision for the objects group.  To do that, just change the physics enable parameter of the group and add this piece of code in your update method (a function, looped 60 times per second):

 

this.game.physics.arcade.collide(this.character, this.objects.self, function(character, object) {
            console.log('Collision detected');
        }, null, this);

And all should be well. The collision detection's first two arguments check for interaction between two entities - the character sprite and a group of objects - and the third argument is a function which does something when these two objects (the character and a separate object of the group) do collide. Congratulations! Your character no longer falls through the floor tiles (grass/boxes).

 

Movement

 

But we need to move. To do that, the keyboard controls must be enabled beforehand. Simply put these two lines in the create method:

 

this.cursors = this.game.input.keyboard.createCursorKeys();
this.space = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

 

The keyboard.createCursorKeys() method initializes the arrow keys. Other keys, like SPACEBAR, SHIFT or CTRL must be initialized like shown above. After that, define actions to do when a key is pressed in the update method:

 

if (this.cursors.left.isDown) {
    this.character.body.velocity.x = -200;
} else if (this.cursors.right.isDown) {
    this.character.body.velocity.x = 200;
} else {
    this.character.body.velocity.x = 0;
}
if (this.space.isDown || this.cursors.up.isDown) {
    this.character.body.velocity.y = -550;
}

 

Arrow keys control your character, alternatively you can jump with SPACEBAR. Or maybe we should say - fly! But we only want to jump, not fly. To do that, one must enable the character to jump only if it is standing on the ground. Delete the current piece of jump code (the one with space and cursors.up) and instead place this in your collision detection function, so it looks like this:

 

this.game.physics.arcade.collide(this.character, this.objects.self, function(character, object) {
    if (this.space.isDown || this.cursors.up.isDown) {
        if (object.body.touching.up) {
            this.character.body.velocity.y = -550;
        }
    }

}, null, this);

 

Adding Character Animations

 

Animations, just like mostly everything, must first be initialized. In the create method, add these lines of code:

this.character.animations.add('stand', [0, 1, 2, 3], 10, true);
this.character.animations.add('run', [6, 7, 8, 9, 10, 11], 10, true);
this.character.animations.add('jump', [12, 13], 10, false);
this.character.animations.add('die', [18, 19], 10, false);
this.character.animations.play('stand');

 

These lines describe animations for your character. The first argument is the 'key' of the animation, the second - an array of frames which this particular animation uses, the third - frames per second and the last argument describes whether the animation should loop. The last line starts an animation when you launch the game. The rest of the animations is played according to situation, when certain condition is met, like a button press. The rest is added in the update method like this:

 

if (this.cursors.left.isDown) {
    this.character.body.velocity.x = -200;
    this.character.animations.play('run');
    this.character.scale.x = -1;
} else if (this.cursors.right.isDown) {
    this.character.body.velocity.x = 200;
    this.character.animations.play('run');
    this.character.scale.x = 1;
} else {
    this.character.body.velocity.x = 0;
    this.character.animations.play('stand');
}

 

And for jump animation, update your collision detection function with this:

 

this.game.physics.arcade.collide(this.character, this.objects.self, function(character, object) {
    if (this.space.isDown || this.cursors.up.isDown) {
        if (object.body.touching.up) {
            this.character.animations.play('jump');
            this.character.body.velocity.y = -550;
        }

    }
}, null, this);

 

At this point you might be wondering why you can't see a jump animation. It's because it gets overwritten by the 'run' or 'stand' animations since their conditions are met as well. We must invent another variable which tells the animations whether the character is in the air. Long story short, after putting this variable in, all of the update method will look like this:

 

update: function() {
    var standing = false;
    this.game.physics.arcade.collide(this.character, this.objects.self, function(character, object) {
        if (object.body.touching.up) {
            standing = true;
        } else standing = false;
        if (this.space.isDown || this.cursors.up.isDown) {
            if (object.body.touching.up) {
                this.character.animations.play('jump');
                this.character.body.velocity.y = -550;
                standing = false;
            }

        }
    }, null, this);

    if (this.cursors.left.isDown) {
        this.character.body.velocity.x = -200;
        if (standing) this.character.animations.play('run');
        this.character.scale.x = -1;
    } else if (this.cursors.right.isDown) {
        this.character.body.velocity.x = 200;
        if (standing) this.character.animations.play('run');
        this.character.scale.x = 1;
    } else {
        this.character.body.velocity.x = 0;
        if (standing) this.character.animations.play('stand');
    }
}

 

Collecting Coins

 

Before you are able to collect coins, their physics must be enabled, the physics body size set to 24x24 and offsetY to 10.

 

 

Next, we initialize the animation:

 

this.coins.self.callAll('animations.add', 'animations', 'collect', [7, 8], 10, false);

 

Note the difference between this line and those used to initialize the character's animations. Since the character was a lone sprite but the coins are all in a group, we must use the callAll method which initializes the animation for each and every child of the group separately. The first argument of the method is the method you would normally use, the second is the context and the rest is identical to adding animations as usual. After animating, we determine overlapping between the character and coins, making the coin disappear  when touch ends and the animation is done playing, and adding +1 to the counter in the upper-right corner:

 

this.game.physics.arcade.overlap(this.character, this.coins.self, function(character, coin) {
    coin.body = null;
    var coinCollect = coin.animations.play('collect');
    coinCollect.killOnComplete = true;
    var newPoints = parseInt(this.gold._text) + 1;
    this.gold.setText(newPoints);
}, null, this);

 

The coin.body is set to null, disabling the physics body. Otherwise the points would be added as long as the animation is still playing. since the character overlaps the animation.

 

Spikes, Life and Death

 

Next up is being able to kill the character when it touches the spikes. To do this, you must enable the physics of your 'spikes' group and set the body height to 20px and the offsetY parameter to 44px - this changes the Y coordinate from which the body is calculated. Pretty much an alternative to anchorY. After that comes the now usual collision detection:

 

this.game.physics.arcade.collide(this.character, this.spikes.self, function(character, spike) {
    if (character.alive) character.animations.play('die');
    character.body.velocity.x = 0;
    character.body.velocity.y = 0;
    character.alive = false;
}, null, this); 

 

The only problem now is that, after dying, you can still move. To avoid this, check if the character.alive is true before movement:

 

var standing = false;
this.game.physics.arcade.collide(this.character, this.objects.self, function(character, object) {
    if (object.body.touching.up) {
        standing = true;
    } else standing = false;
    if ((this.space.isDown || this.cursors.up.isDown) && character.alive) {
        if (object.body.touching.up) {
            this.character.animations.play('jump');
            this.character.body.velocity.y = -550;
            standing = false;
        }

    }
}, null, this);
if (this.character.alive) {
    if (this.cursors.left.isDown) {
        this.character.body.velocity.x = -200;
        if (standing) this.character.animations.play('run');
        this.character.scale.x = -1;
    } else if (this.cursors.right.isDown) {
        this.character.body.velocity.x = 200;
        if (standing) this.character.animations.play('run');
        this.character.scale.x = 1;
    } else {
        this.character.body.velocity.x = 0;
        if (standing) this.character.animations.play('stand');
    }
}

 

And finally, we add the ability to revive and send your character to start position by pressing SPACEBAR (set the character coordinates to your starting coordinates, viewed in the Map Editor):

 

if (this.space.isDown && !this.character.alive) {
    this.character.revive();
    this.character.x = 68;
    this.character.y = 452;
}

 

Achieving the Goal

 

One last thing - making the game do something when touching the big chest. This time we won't be using physics but check for overlapping differently (viable for single sprites only, not groups). First, add this checkOverlap function after the update method (don't forget to add a coma after the ending brace of the update method):

 

checkOverlap: function(spriteA, spriteB) {
    var boundsA = spriteA.getBounds();
    var boundsB = spriteB.getBounds();
    return Phaser.Rectangle.intersects(boundsA, boundsB);
}

 

And finally - call this function from within update:

 

if (this.checkOverlap(this.character, this.chest)) {
    this.game.state.start("play");
}

 

In this case, the 'play' state is restarted as soon as you touch the chest.

 

Congratulations!

 

Your game is now be fully playable and the code should closely resemble this:

 

"use strict";
window.SockMan.state.play = {
    create: function() {
        this.bg = mt.create("bg");
        this.character = mt.create("character");
        this.spikes = mt.create("spikes");
        this.chest = mt.create("chest");
        this.objects = mt.create("objects");
        this.coins = mt.create("coins");
        this.gold = mt.create("gold");

        this.cursors = this.game.input.keyboard.createCursorKeys();
        this.space = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

        this.character.animations.add('stand', [0, 1, 2, 3], 10, true);
        this.character.animations.add('run', [6, 7, 8, 9, 10, 11], 10, true);
        this.character.animations.add('jump', [12, 13], 10, false);
        this.character.animations.add('die', [18, 19], 10, false);
        this.character.animations.play('stand');
        this.coins.self.callAll('animations.add', 'animations', 'collect', [7, 8], 10, false);
    },

    update: function() {
        var standing = false;
        this.game.physics.arcade.collide(this.character, this.objects.self, function(character, object) {
            if (object.body.touching.up) {
                standing = true;
            } else standing = false;
            if ((this.space.isDown || this.cursors.up.isDown) && character.alive) {
                if (object.body.touching.up) {
                    this.character.animations.play('jump');
                    this.character.body.velocity.y = -550;
                    standing = false;
                }
            }
        }, null, this);
        if (this.character.alive) {
            if (this.cursors.left.isDown) {
                this.character.body.velocity.x = -200;
                if (standing) this.character.animations.play('run');
                this.character.scale.x = -1;
            } else if (this.cursors.right.isDown) {
                this.character.body.velocity.x = 200;
                if (standing) this.character.animations.play('run');
                this.character.scale.x = 1;
            } else {
                this.character.body.velocity.x = 0;
                if (standing) this.character.animations.play('stand');
            }
        }

        this.game.physics.arcade.overlap(this.character, this.coins.self, function(character, coin) {
            coin.body = null;
            var coinCollect = coin.animations.play('collect');
            coinCollect.killOnComplete = true;
            var newPoints = parseInt(this.gold._text) + 1;
            this.gold.setText(newPoints);
        }, null, this);

        this.game.physics.arcade.collide(this.character, this.spikes.self, function(character, spike) {
            if (character.alive) character.animations.play('die');
            character.body.velocity.x = 0;
            character.body.velocity.y = 0;
            character.alive = false;
        }, null, this);

        if (this.space.isDown && !this.character.alive) {
            this.character.revive();
            this.character.x = 68;
            this.character.y = 452;
        }

        if (this.checkOverlap(this.character, this.chest)) {
            this.game.state.start("play");
        }
    },

    checkOverlap: function(spriteA, spriteB) {
        var boundsA = spriteA.getBounds();
        var boundsB = spriteB.getBounds();
        return Phaser.Rectangle.intersects(boundsA, boundsB);
    }
};

 

Full game project: http://mightyeditor.mightyfingers.com/#pe45-copy

Final game: http://mightyeditor.mightyfingers.com/data/projects/pe45/phaser/index.html

The end result:

 

Click here to open in a new window.

Programming


GFS On YouTube

See More Tutorials on DevGa.me!

Month List