Tutorials section expanded!

We have just revamped the tutorials page to include many more code samples of functionality with PlayCanvas. These include common use cases such as creating an Orbit Camera around an Object, Load Assets with a Progress Bar and more.

orbit-camera

To make it even easier to find the what you need, we have also added a filter to help narrow down the search. So if you are looking at moving a camera via user input? We have it covered!

tutorial-filter

 

The tutorial section will grow as we write more samples so if there is anything you would like to see, let us know on our developer forums!

PLAYHACK December – Collecting Presents

PLAYHACK is our fun monthly game building session. Throughout the month I’ll be posting tips and tricks to help you get a game made by the end of the month. Don’t forget, these are just examples. You can make any game you like. Read more about this month’s PLAYHACK.

PLAYHACK_clearxmas

We’ll be following on from last time’s tutorial this time, so make sure you’ve followed that one before attempting this! As always, you can check out all the up to date code in this project.

Use W and S to move the sleigh.

In this tutorial, we’re going to do two things – delete the presents as they go off-screen, and find out when the presents collide with Santa. How are we going to do all this? The answer: Trigger Volumes!

Adding an Offscreen Trigger Volume

At the moment, when presents go offscreen, they just keep going on and on forever and ever. We don’t need the presents anymore after they’ve gone offscreen, so it doesn’t hurt (and may even help) us if we delete them. So, we need a way to test when a present has left the screen. We can do that with a Trigger Volume placed just offscreen.

DEC-PLAYHACK-TUT3-2

 

You may be thinking – what is a trigger volume?! A trigger volume is simply an entity with a collision component added to it (but without a rigidbody – we’ll get to that later). They allow us to test when rigidbodies enter and leave them – which is perfect for testing when a present goes off-screen.

So, to add the off-screen trigger volume, simply right click on “Santa” in the Pack Explorer and add a new Entity. I called mine “offscreen”. Then, add a collision component to your new offscreen entity – a small blue cube should appear in the editor. Now, all we need to do is move it off-screen, and resize it so it catches all the presents. You can move it with the translate tool, and to make it big enough, you can edit the “half-extents” of the collision component until it covers the whole of the edge of the camera.

DEC-PLAYHACK-TUT3-3

Now, let’s write some code to delete the presents that come off-screen. Add a script component to the offscreen entity, and add a new script – I called the script “offscreen.js” (creative name, I know).

Whenever a rigidbody enters the trigger volume, the collision component will fire an event that we can listen to. Or, in simple terms, we can tell the collision component to call a specific function any time it comes into contact with a rigidbody. Put the following code in the initialize function of your new script:

    this.entity.collision.on('triggerenter', this.onTriggerEnter, this);

This tells our collision component that when the “triggerenter” event happens (i.e. something enters the trigger volume), call the function “onTriggerEnter“, in the scope of this (so we have access to all our variables and functions). Let’s write that function now:

    onTriggerEnter: function (other) {
        other.destroy();
    }

Pretty simple huh? The onTriggerEnter function gets called with one argument, which is the entity it collided with. We simply destroy that entity, and it’s gone!

Setting up the present

DEC-PLAYHACK-TUT3-1

 

If we run the game now though, the presents still won’t get deleted even if they go off-screen! That’s because trigger volumes only check for collisions with rigidbodies, so we’ll need to add some more components to the present. We need to add a collision component and a kinematic rigidbody component. Together, these will allow us to check when the present passes through our trigger volumes.

So, add those components to the Gift. Make sure you change the “type” attribute of the rigidbody component to Kinematic – we don’t want it to be Static, because then we couldn’t move the presents, and we don’t need it to be Dynamic because then our present would get affected by gravity and physics and we don’t need that. Kinematic allows us to move our present in code, but not have it affected by physics. You can fiddle around with the half extents of the collision box until it fits around the present too.

You’ll also notice the collision box isn’t centred on the present model. To fix this, you can removed the model component from Gift and add a model entity child instead, which you can then translate without affecting the position of the collision box.

One last thing – it’s very important that you uncheck the Enabled attribute of the Gift. If the original gift goes off-screen and collides with the off-screen Trigger Volume, it will get deleted, and we won’t be able to make any copies of it. We can make sure that never happens by disabling the present – now the original present won’t do anything, but it will still be there for us to clone and make more presents.

If you test the game now, the presents should be getting deleted after they go off-screen! You can test that it’s actually working by moving the off-screen Trigger Volume on-screen a bit – the presents should then disappear just before they go off-screen.

Santa Trigger Volume

But the present going offscreen isn’t the only thing we want to check for – we also need to check when it collides with Santa! Luckily, this is very similar to the offscreen trigger volume.

Like before, we need to add a collision component – so right click on Santa and add one. There’s a clever thing we can do here: instead of messing around with the half-extends of the collision box, trying to get it to match Santa, we can simply tell the collision component to match the size and shape of the Santa Model. Change the type attribute of the collision component to Mesh, and select the Santa_sleigh model for the Asset. Now, the collision will only check for exactly the right size of Santa.

(Wondering why we can’t use a Mesh for the collision component of Gift? Checking for collisions between two Meshes is a lot more computationally expensive compared to comparing collisions with simple geometry. Therefore, checking for a collision between two Meshes isn’t allowed, and since our present is basically a cube, we’re using a cube for the collision volume of the present.)

Now we just need to add a small amount of code to Santa so we know when presents collide with him.

    this.entity.collision.on('triggerenter', this.onTriggerEnter, this);

Put that line in the santa_controller.js script – it does exactly the same thing as before. We’re going to write a simple onTriggerEnter function for now, and actually write the functionality we want next time.

    onTriggerEnter:function(other) {
        if(other.name == "Gift") {
            other.destroy();
            //we'll be adding score incrementation and other stuff here...
        }
    }

All we’re doing here at the moment is the same as the offscreen trigger volume – destroying the present when it comes into contact with Santa.

And that’s it for this time! Next time we’ll be looking at adding a GUI to the game so you can see how many presents you’ve collected!

PLAYHACK December – Creating Presents

PLAYHACK is our fun monthly game building session. Throughout the month I’ll be posting tips and tricks to help you get a game made by the end of the month. Don’t forget, these are just examples. You can make any game you like. Read more about this month’s PLAYHACK.

PLAYHACK_clearxmas

We’ll be following on from last time’s tutorial this time, so make sure you’ve followed that one before attempting this!

… 

PLAYHACK November – Turrets and shooting bullets

As this is our first PLAYHACK we thought it would be sensible to start with a few tips and tutorials to get you going. We’ll follow up with more of these throughout the week. Don’t forget, these are just examples. You can make any game you like.

PLAYHACK_designer

Rotating Turret

In the previous blog posts we set up keyboard controls to move the tank by apply forces to the rigidbody. Now we going to add separate controls to rotate the tanks turret. You try this project for yourself by running this pack.

initialize: function () {
    this.turret = this.entity.findByName("Tank_gun_turret");
    this.bullet = context.root.findByName("Bullet");
    this.barrel = context.root.findByName("Barrel");
},

update: function (dt) {
    // Rotate the turret left and right using A and D
    if (context.keyboard.isPressed(pc.input.KEY_A)) {
        this.turret.rotate(0, this.speed * dt, 0);
    } else if(context.keyboard.isPressed(pc.input.KEY_D)) {
        this.turret.rotate(0, -this.speed * dt, 0);
    }
    
    if (context.keyboard.wasPressed(pc.input.KEY_S)) {
        this.shoot();
    }
},

This is the code in turretcontrols.js. It’s very simple. In the initialize function we find the Entity called Tank_gun_turret. This Entity is the separate model for the gun turret. Then each frame we check to see if the A or D key is pressed and we rotate the turret to the left or right using the rotate() method on the Entity.

Shooting Bullets

shoot: function () {
    var bullet = this.bullet.clone();
    context.root.addChild(bullet);
    bullet.setPosition(this.barrel.getPosition());
    bullet.enabled = true;
    
    this.force = new pc.Vec3();
    this.force.copy(this.turret.forward);
    this.force.scale(-this.impulse);
    
    bullet.rigidbody.applyImpulse(this.force);
}

Take a look at the shoot() function above. This is called when the player presses the S key. It introduces a few different concepts:

Entity.clone()

The clone() method on Entities creates a complete copy of the Entity and it’s components. When you clone an Entity it is created but not added into the scene hierarchy so you have to call the addChild() method and add it to the parent of your choice. In this case, we’re just adding it to the root.

Enabling and Disabling Entities

The bullet Entity we are cloning from is disabled in the Designer because we don’t want this extra bullet in the scene. After we have cloned the Entity we want to enabled the bullet which means that the model component is enabled (it start’s rendering) and the rigidbody is enabled (it starts simulating/colliding).

To fire the bullet, we clone it, add it into the hierarchy and set it’s position to the location of the gun barrel entity. After we’ve enabled the bullet, we apply an impulse to kick it off in the direction of the turret.

Target Practice

PLAYHACK_boxes

Finally we’ve just added some boxes for target practice. The boxes are simply Entities with a dynamic rigidbody and a collision component. Don’t forget you try this project for yourself by running this pack.

PLAYHACK

PLAYHACK is our monthly game jam. We’ll give you a starting point and you have a month to build a game. The winner is featured on our frontpage and wins fame and glory everlasting!

Not started work on your PLAYHACK game yet? What are you waiting for go fork this project!

button

 

PLAYHACK November – Camera types

As this is our first PLAYHACK we thought it would be sensible to start with a few tips and tutorials to get you going. We’ll follow up with more of these throughout the week. Don’t forget, these are just examples. You can make any game you like.

Camera Types

This blog post is going to cover a few different types of camera. We’re also going to cover Script Attributes, which lets you expose values into the Designer.

Try running the Follow Camera Pack in this Project to see all this code in action. Use the arrow keys to move the tank and press the Spacebar to cycle between the different camera types.

PlayCanvas

Fixed Follow Camera

The fixed follow camera is a type of third-person camera which follows the target at exactly the same distance and angle at all times. This type of camera is very easy to implement. In fact you could set it up just by setting the Camera entity as a child of the tank. We’re going to show you how to do it in code though.

updateFixedFollow: function (dt) {
    this.entity.setPosition(this.target.getPosition());
    this.entity.setRotation(this.target.getRotation());
    this.entity.rotateLocal(this.elevation, 0, 0);
    this.entity.translateLocal(0, 0, this.distance);
},

This function sets the camera to be at the same position and rotation as the target (the target in our code is the player’s tank). Then we rotate by the ‘elevation’ value and move the camera backwards (backwards is along positive z axis) by the ‘distance’ value.

Try at home: Try modifying the elevation and distance to setup up and overhead camera like the one in the picture.

Trailing Follow Camera

The trailing follow camera is a slightly more advanced form of third-person camera which follows the target, but it is always trying to catch up to where the fixed follow camera would be. This gives a smoother motion, but can lead to the camera loosing the player if it trails too much.

updateTrailingFollow: function (dt) {
    var pos = new pc.Vec3();
    var rot = new pc.Quat();
    
    // store initial position and rotation
    pos.copy(this.entity.getPosition());
    rot.copy(this.entity.getRotation());
    
    // set entity to be at target position and rotation
    this.entity.setPosition(this.target.getPosition());
    this.entity.setRotation(this.target.getRotation());
    this.entity.rotateLocal(this.elevation, 0, 0);
    this.entity.translateLocal(0, 0, this.distance);
    
    // interpolate start pos/rot to target pos/rot
    pos.lerp(pos, this.entity.getPosition(), this.positionFactor);
    rot.slerp(rot, this.entity.getRotation(), this.rotationFactor);
    
    // Set to interpolated position
    this.entity.setPosition(pos);
    this.entity.setRotation(rot);
}

In this function we store the current position and rotation, calculate the position of the fixed follow camera and then use `lerp()` and `slerp()` to interpolate the position. `lerp` and `slerp` stand for Linear intERPolation and Spherical Linear intERPolation. This is a way of moving between two values by supplying a value between 0 and 1. In this case we use the positionFactor and rotationFactor as the input to the interpolation.

Finally we update the position and rotation to the final values.

This a very simple implementation of a trailing camera. There are all kinds of ways you can implement one. Another method is to use a spring simulation to attach the camera to the target point. Then you can adjust the stiffness of the spring to modify how much the camera trails.

Look At Camera

The final type of camera is a static look at camera. The camera never moves but just aims at the target.

updateLookAt: function (dt) {
    this.entity.lookAt(this.target.getPosition());
},

This code needs no explanation.

Script Attributes

The final tip to share is how to use script attributes to expose values your code needs into the Designer.

pc.script.attribute("elevation", "number", -30);
pc.script.attribute("distance", "number", 5);
pc.script.attribute("positionFactor", "number", 0.2);
pc.script.attribute("rotationFactor", "number", 0.2);

This code at the top of the camera script, tells the designer to expose four values `elevation`, `distance`, `positionFactor` and `rotationFactor` and show them as editable numbers in the Designer.

Back in the Designer, we need to load the script attributes from the script using the Entity -> Refresh Script Attributes menu item. Then we’ll see this attribute block appear on the script component.

PLAYHACK_Camera

Modifying these values will directly update the script live when it is running from the Designer. So you can tweak values with the live game running in a separate tab. This can really accelerate your development.

That’s it for now. Don’t forget you can try running the Follow Camera Pack in this Project to see all this code in action. Use the arrow keys to move the tank and press the Spacebar to cycle between the different camera types.

PLAYHACK

PLAYHACK is our monthly game jam. We’ll give you a starting point and you have a month to build a game. The winner is featured on our frontpage and wins fame and glory everlasting!

Not started work on your PLAYHACK game yet? What are you waiting for go fork this project!

button

PLAYHACK November – Adding Tank Controls

PLAYHACK_clear

As this is our first PLAYHACK we thought it would be sensible to start with a few tips and tutorials to get you going. We’ll follow up with more of these throughout the week. Don’t forget, these are just examples. You can make any game you like.

Tank Controls

Our first snippet of code is going to get you controlling your tank. This will give you an little introduction into the PlayCanvas physics system as well as reading keyboard input.

tank

Setting up the Physics

The pack you started with has a tank entity set up. To add physics we need to add a rigidbody and a collision component. It’s not quite that simple though, as we need to make sure that geometry lines up in the center of the collision body.

Here is one way to set up the hierarchy:

PLAYHACK_hierarchy

The Tank entity is setup with rigidbody and collision components. The Geometry entity is a container for the models and the light. We can position the Geometry entity so that it lines up in the center of our collision.

PLAYHACK_attributes

Here is the attribute panel for the Tank entity. You  can see we’ve set the collision shape to be a sphere, the rigidbody is dynamic and we’ve set angular factor to [0,1,0] which means the sphere can only rotate around the y-axis.

We’ve also added a ground collision box so the tank doesn’t fall through the floor. After that, the only thing left to do is read the keyboard input.

Keyboard input

pc.script.create('tankcontrols', function (context) {
    // Creates a new Tankcontrols instance
    var Tankcontrols = function (entity) {
        this.entity = entity;
        this.force = new pc.Vec3();
    };

    Tankcontrols.prototype = {
        // Called once after all resources are loaded
        initialize: function () {
        },

        // Called every frame, dt is time in seconds since last update
        update: function (dt) {
            if (context.keyboard.isPressed(pc.input.KEY_LEFT)) {
                this.entity.rigidbody.applyTorque(0, 1, 0);
            }
            if (context.keyboard.isPressed(pc.input.KEY_RIGHT)) {
                this.entity.rigidbody.applyTorque(0, -1, 0);
            }
            if (context.keyboard.isPressed(pc.input.KEY_UP)) {
                this.force.copy(this.entity.forward).scale(10);
                this.entity.rigidbody.applyForce(this.force);
            }
            if (context.keyboard.isPressed(pc.input.KEY_DOWN)) {
                this.force.copy(this.entity.forward).scale(-10);
                this.entity.rigidbody.applyForce(this.force);
            }

        }
    };

    return Tankcontrols;
});

This script is attached to the Tank entity. It’s pretty self-explanatory. Each frame, update() is called. This function checks to see if the any of the arrow keys on the keyboard have been pressed. If they have a force or torque is applied to the rigidbody attached to the entity.

Here is the Pack with this already set up for you to try. Run the pack and use the arrow keys to control the tank.

PLAYHACK

PLAYHACK is our monthly game jam. We’ll give you a starting point and you have a month to build a game. The winner is featured on our frontpage and wins fame and glory everlasting!

Not started work on your PLAYHACK game yet? What are you waiting for go fork this project!

button

Platform Game Starter Kit

Our new hero

Our new hero

Today we’re pleased to introduce the updated, all new and fancy Platform Game Starter Kit. We’ve worked hard with the talented artist  from SWOOOP to provide a complete set of code and assets for you to build your own platform games.

From today, when you choose to create a new project you’ll be given the option to start using the new Platform Game Starter Kit. Your new project will contain a short, but full, platform game.

 

Contents

The Starter Kit contains the following assets:

  • Our hero Playbot – a fully rigged and animated robot character for you to use.
  • Idle, Run, Jump and Die animations for Playbot
  • A set of platforms in various shapes and sizes from 1×1 upto 4×4
  • Spike, our dumb and stupid AI bot
  • Punch, still pretty dumb, but don’t get too close or he’ll shoot.

We’re also supplying all the code for the game:

  • Platform Character Controller – the player
  • Enemy – a simple enemy AI
  • Enemy Punch – a simple enemy AI which can shoot at you
  • Mover – a moving platform
  • Goal – the target for the level
  • Damagable – add health and damage to an Entity

We’ll be writing more about the Platform Game Starter Kit in the next week to give you tips and challenges so that you can make the best use out of it. But before they arrive, create a new project using the kit, try it out and dig into the code to see how it was made.

Have fun, and look out for Punch!

Punch - the bad guy

Punch – the bad guy

 

Publishing HTML5 Games on the Chrome Web Store

If you’re building HTML5 games, chances are that you want as many people to play your game as possible and, in an ideal world, you’ll make some money in the process. Monetization on the web is harder than it is on mobile app stores, where payment processing is standardised and credit card details are stored. But there are still a number of options. One great platform you should consider for your game is the Chrome Web Store.

It’s a carefully curated app store for the desktop version of Chrome (available on Win, Mac, Linux and Chrome OS). Publishing your game here will expose it to a wider audience and offer you a simple mechanism for taking payments. In this article, I won’t cover the options for charging money for your game (a story for another day). Instead, let’s step through the process for publishing a free game.

So what are the options? Google lets you publish your game as a hosted app or a packaged app.

Hosted Apps

Hosted apps are essentially vanilla websites with a little extra metadata. Why are hosted apps good?

  • Your game will be discoverable by Chrome Web Store users.
  • Chrome Web Store users can install your hosted app to their Apps page in Chrome which is really just a beefed up bookmark for your game. This will be synched across the different devices on which you use Chrome (if you’re signed in).

So this sounds great. More people will be installing and playing your game. PlayCanvas has published a hosted app; a game called Dungeon Fury.

dungeonfury_promo_920x680

Check it out on the Chrome Web Store here.

To get started, hit the cog icon at the top right of the landing page for the Chrome Web Store and select Developer Dashboard. Sign in and click the button labelled ‘Add New Item’.

Here’s a little checklist of things that you’ll need to publish a hosted app:

  • A zip file containing a manifest and a 128×128 icon for your game. Google supplies a reference for the manifest file format and guidelines for creating icons (and other images related to your submission).
  • A description for your game. Make it fun and exciting! Remember, you’re trying to persuade somebody to install your game so make it sound amazing.
  • A number of screenshots and YouTube links to give potential users an idea of what your game is like to play.
  • A number of images that Google can use to promote your game in the Web Store. Depending on how successful your game becomes, it may be displayed in a small, medium or large (marquee) tile. Spend time ensuring that you provide all of these images. A great game can be let down by uninspiring promotional images!
  • Verification that you own the URL of your hosted app. You should do this using Google’s WebMaster Tools.

There are a few other options that cover Google Analytics, game category, regions where your game will be listed and so on. When you’re done, hit ‘Publish’. Note that Google spends a little time (no longer than 60 minutes but should be much faster) to scan your upload before it is made live in the store.

Packaged Apps

So hosted apps are great, but they have some problems:

  • Users may think you’ve been lazy! ‘Hey! This is just a link to their web-site! Grrr!’. Users expect a little more from something that is being installed to their browser.
  • Hosted apps won’t run offline (unless you make clever use of the browser’s local storage).
  • Hosted apps are just web pages and don’t feel like applications.
  • If your game consists of a large quantity of data and doesn’t do any caching, load times can be long.

Enter packaged apps! These are essentially apps that are fully installed to Chrome, can run offline and launch in there own window minus Chrome’s browser decoration (although this can be added if you wish). And because they’re loaded from local storage, they start up extremely quickly.

PlayCanvas has also published an example of a packaged app in the Chrome Web Store. It’s a game called SWOOOP:

SWOOOPbann_440x280

Check it out for yourself here.

Generating a packaged app from a PlayCanvas game takes a little more effort than a hosted app. Here’s a run down of the steps required to package and publish a game like SWOOOP:

  • Download the most recently exported version of the game from the Exports tab of the Project Dashboard.
  • Unzip the contents.
  • In the index.html, there are two externally referenced resources: the PlayCanvas engine (playcanvas-0.144.3.min.js and PLAY_FLAT_ORANGE3.png). Download these resources and change the paths so they are relative to the index.html file.
  • Create a manifest.json file . For SWOOOP, it looks like this:
    {
      "name": "SWOOOP",
      "description": "Loop and swoop your bi-plane around the magical island. What's your highscore?",
      "version": "1.0",
      "app": {
        "background": {
          "scripts": ["background.js"]
        }
      },
      "icons": { "16": "swooop16.png", "48": "swooop48.png", "128": "swooop128.png" }
    }
  • Create background.js that contains the following to configure how the game is launched:
    chrome.app.runtime.onLaunched.addListener(function() {
     chrome.app.window.create('index.html', {
       'bounds': {
         'width': 1280,
         'height': 720
       }
     });
    });
  • Create the icons referenced from the manifest and place them in the same folder as the index.html.
  • Transfer any script tag blocks of JavaScript in index.html into externally referenced JS files (there are two). This is because Chrome treats this as a security threat.
  • Remove the following statement (which causes another security error in Chrome) from playcanvas-0.144.3.min.js (search for ‘unload’):
    window.addEventListener("unload", function() {
      o.disconnect();
      o = null
    });
  • Check to see if your game uses the LocalStorage HTML5 API. Packaged apps can’t use this API, although they can use a Chrome specific alternative.
  • We’re done! Zip up the game’s files again and upload to your new item in the CWS Developer Dashboard. Fill out the rest of the form as you would for a hosted app (although you now don’t need to show ownership for a hosted app URL since there isn’t one any more).

So hopefully this gives some insight into how simple it is to publish your game to the Chrome Web Store. Whether you choose to publish a hosted or packaged app is up to you and, as we’ve shown, both have their advantages and disadvantages. My recommendation to you is to experiment. It’s an awesome publishing platform that anyone can start to use today, so try it out for yourself!