Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

29. June 2017


Click here to go back to Part Two.


Next, we need to create a bowling ball.  Instead of importing a 3D mesh, we are going to create one.  Select Game Object->3D Object->Sphere.

clip_image002


Once created, rename it to BowlingBall.

clip_image004

While we are here, create a new Tag called Ball and assign it to our object.


Let’s create a material for our Bowling ball.  Right click assets panel, select Create->Material.  Rename the newly created material BowlingBall.  Pick the color of your bowling ball with the box to the right of Albedo.  For shine add a small amount of Metallic as well.

clip_image006

Now simply drag the newly created material over to our Bowling Ball in the scene.


We also need to attach physics to our bowling ball.  This time it’s using a Sphere Collider.  This is also a rigid body, but this time we increase the mass to 3.

clip_image008


We are going to be putting all of the logic in our bowling ball.  One thing we are going to need to do is play audio when our ball hit’s a pin. We will add this logic later, but the audio source needs to be somewhere, so why not the bowling ball. We actually covered this process earlier when we added audio to our title screen.  Simply add an Audio Source component to the ball then attach the Hit.wav file, like so:

clip_image010

Tick off the Play on Awake checkbox.


Now its time to add some scripting to our game to control input and to deal with physics collisions when they happen. Right click the Assets panel and create a new script like we did earlier. Rename it BowlingBall.cs and drag it onto our BowlingBall object.  Now double click our script and enter the following code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BowlingBall : MonoBehaviour
{
    public float force;
    // Use this for initialization
    private List<Vector3> pinPositions;
    private List<Quaternion> pinRotations;
    private Vector3 ballPosition;
    void Start()
    {
        var pins = GameObject.FindGameObjectsWithTag("Pin");
        pinPositions = new List<Vector3>();
        pinRotations = new List<Quaternion>();
        foreach (var pin in pins)
        {
            pinPositions.Add(pin.transform.position);
            pinRotations.Add(pin.transform.rotation);
        }

        ballPosition = GameObject.FindGameObjectWithTag("Ball").transform.position;
    }


    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyUp(KeyCode.Space))
            GetComponent<Rigidbody>().AddForce(new Vector3(0, 0, force));
        if (Input.GetKeyUp(KeyCode.LeftArrow))
            GetComponent<Rigidbody>().AddForce(new Vector3(1, 0, 0), ForceMode.Impulse);
        if (Input.GetKeyUp(KeyCode.RightArrow))
            GetComponent<Rigidbody>().AddForce(new Vector3(-1, 0, 0), ForceMode.Impulse);
        if (Input.GetKeyUp(KeyCode.R))
        {
            var pins = GameObject.FindGameObjectsWithTag("Pin");

            for (int i = 0; i < pins.Length; i++)
            {
                //collision.gameObject.transform.parent.gameObject.tag
                var pinPhysics = pins[i].GetComponent<Rigidbody>();
                pinPhysics.velocity = Vector3.zero;
                pinPhysics.position = pinPositions[i];
                pinPhysics.rotation = pinRotations[i];
                pinPhysics.velocity = Vector3.zero;
                pinPhysics.angularVelocity = Vector3.zero;

                var ball = GameObject.FindGameObjectWithTag("Ball");
                ball.transform.position = ballPosition;
                ball.GetComponent<Rigidbody>().velocity = Vector3.zero;
                ball.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
            }
        }
        if (Input.GetKeyUp(KeyCode.B))
        {
            var ball = GameObject.FindGameObjectWithTag("Ball");
            ball.GetComponent<Rigidbody>().velocity = Vector3.zero;
            ball.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
            ball.transform.position = ballPosition;
        }
        if (Input.GetKeyUp(KeyCode.Escape))
        {
            Application.Quit();
        }
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "Pin")
            GetComponent<AudioSource>().Play();
    }}

We publicly expose the Force value, which is the amount of energy to apply along the Z axis when we throw the ball.  Since it is public, it’s settable in the editor as a property in the script component.

clip_image012


And done!


The Video

Programming , , ,

26. June 2017


The Esenthel Game Engine has been under development for more than a decade and yet I had never actually tried it before now.  They recently released a Fantasy Tech Demo illustrating recent functionality added to the engine.  After trying out the demo, I decided to give Esenthel a shot.  The following video is a quick hands-on with the Esenthel Game Engine. Esenthel is a C++ powered/scripted game engine with a full editing environment as well as Visual Studio integration.


The Essenthel Engine has a free trial available for download and is available for Windows, Mac and possibly Linux.  The full version is a commercial subscription for 11.40$ a month or 114$ annually.  A source license costs double that amount.

Programming ,

6. June 2017


There are several game engines out there that present a code free option such as Stencyl and Construct.  Today we are looking at an open source alternative, GDevelop.  It is a cross platform, open source 2D game engine with a visual programming interface that requires no previous experience.  However there is also the ability to extend the engine using the C++ programming language if desired.  If you are new to the Closer Look series, it is a combination of game engine review and getting started tutorial helping you decide if a game engine is right for you.


As always, there is a video version of this tutorial available here and embedded below.


Without further ado, let’s jump into GDevelop.


Meet GDevelop

As mentioned above, GDevelop is an open source 2D game engine.  It is released under the MIT license for the core engine, while the editor is available under the GPL v3 open source license.  The code is available on Github.

Of course you don’t ever have to touch the source code to work with GDevelop.  You can download binaries for Windows, Mac, Linux as well as Browsers, iOS and Android in the form of GDevApp.  I will not be covering GDevApp today however.  GDevelop is able to compile native applications, HTML5 pages as well as Android applications, which is currently an experimental feature.

The vast majority of your time is going to be spent in the GDevelop editor, shown below.

image

The center of the screen is currently showing the Scene editor.  There is where you can compose scenes.  It is a tabbed view that can contain multiple open scenes as well as Events, the programming model of GDevelop, which we will discuss more shortly.

On the right hand side is the Objects Editor, which contain the building blocks of your game.  On the left hand side is the Project Manager containing the assets and scenes that make up your game.


Let’s walk through creating a sprite in a game.  In the Objects editor, right click objects and select Add an object.

image

This will show us a list of possible objects:

image


For every object except the Sprite you need to enable it before you can use it (thus why they are grayed out).  It’s as simple as double clicking a grayed out object to enable it however, like so:

image


In this case however we are going to use the Sprite object, which is already enabled.  Simply double click Sprite.  Double clicking the newly created object in the Object editor will open up the sprite editor screen:

image


At the top right corner of the editor window you will see the Images bank’s editor, click the plus icon and add the images you will use for your sprite.  Next drag the selected images down to the images section, like so:

GIF


You can rename and configure the animation (if any) under the Animations panel.

image


Now you can create an instance of your Sprite object by simply dragging it into the scene.

GIF2


As we saw earlier, there are several built in objects in addition to the Sprite object, including Admob integration, a Text object, a tiled sprite (spritesheet), etc.   Next lets move on to adding some logic to our newly created object.


Scripting in GDevelop

Logic in GDevelop are implemented using Events.  Let’s look at an example of moving the sprite around when the mouse moves.  Click on the Events tab.

image


In the Events ribbon, click Add an Event:

image


In this case we have no conditions, we want this to happen every single frame.  Hover over No actions, then select Add an Action.

image


This is where the building block aspect of GDevelop programming comes into play.  Select All Objects->Position->Position of an object.

image


Now we can set the parameters for positioning our object.  First select the object to modify, then set each parameter.  In this case we set the X and Y values to those of the mouse cursor, like so:

GIF3


Upon completion, you will see we now have an event defined:

image


In this particular case we have no condition, so our event will fire every pass through the event loop.  We could however have set a condition which causes our event to fire or not.  Here for example is a condition that will start playing some music once the scene is loaded.

image


Beyond conditions, there are other control structures you can add to events:

image


Link enables you to break link to another event sheet, enabling you to modularize your code.  It is also possible to define variables, both globally, to the scene and at the object level.  For example, right click the Project and select Modify Global Variables.

image


This now enables us to define new variables:

image


This can also be done at the object level, right click an object and select Other Properties.  Then in the resulting panel select Click to Edit...

image


While we are here, notice the Behaviors option?  This enables us to add new functionality to game objects.  Click the Add... button:

image


You will notice once again, by default all behaviors are disabled.  Double click a behavior to add it in.  Let’s go ahead and add Top-down movement as an example.  You can now edit properties of the new behavior in the same dialog:

image


This will instantly add arrow key navigation abilities to your object.  When you play your game, arrow keys will cause your object to move around screen.  Speaking of playing your game, hit the Preview button in the Scene ribbon to launch your game in your browser.

image


You can control application level settings of your project by right clicking your project and selecting Edit the property of the game.

image


This will bring up the next dialog.

image


Finally, if your project has Native extensions enabled, under the File menu you have the option to build a native version of your application.

image


Then simply click the Compile button.

image



Documentation and Community

GDevelop is reasonably well documented, with a Getting Started tutorial, several other tutorials and a decent number of starter templates to choose from.

image 


There is also a manual available online.  If you are intending to extend GDevelop using C++ however, the documentation is almost non-existent.  However being an open source project, all of the code is available.  All of the behaviors and objects we used in this example are available in source form on Github in the extensions folder:

image


GDevelop has a dedicated forum available here.  It is reasonably active with a decent sized community.  Forums are available in both English and French.


Conclusion

If open source, free and a visual programming interface are important to you, GDevelop is definitely an engine to consider.  The documentation is adequate, the engine is mostly feature complete, although annoyingly some features such as Tiled support are only available for native targets.  The entire thing is designed around extensibility and if you are willing to dive into C++, the sky’s the limit on what you can do.  My biggest complaint is a lack of polish on the UI layer, experiencing a few crashes, some UI glitches that went away on a reload and some buttons that simply do nothing.  Most annoyingly, the engine is basically unusable on a high DPI display.

It is however an easy engine to jump into and use if you are willing to deal with some UI warts.  An MIT license around the core engine is always an excellent feature.


The Video

Programming , , , ,

1. June 2017


Ever wish you could go back in time to the days of 8bit computing, when coding was simple and pixels were large?  Thanks to the rise of Fantasy Consoles, this process is easier than ever before.

So what exactly is a fantasy console?  Basically it’s a virtual console with a complete development environment.  The console is designed to be Pico3intentionally limiting, much like the primitive retro computers of the 8bit era.  Generally each also comes with a code editor, programming language (Lua), tile and world editor and some form of music composer.  This gives you a very focused, simple and constrained programming environment to work with.  You’d be surprised how striping away all the modern trappings enables you to focus on a single concept... fun.


So without further ado, let’s take a quick look at 4 virtual consoles available today.


PICO-8

PICO-8 is the application that seemingly launched the entire fantasy console movement.  The hardware it emulates provides a 128x128 pixel display, support for 4 channel audio, 128 8x8 sprites and 32k console/disk sizes.  It is PICO-8 illustrated in the image to the right.  In addition to the virtual machine, it also provides a code editor, sprite editor, map editor as well as music and sound editors.  It is available for $15 USD.


TIC-80

TIC-80, or Tiny Computer, is very similar in concept to PICO-8, with slightly less restrained virtualized hardware.  In this case it provides a 240x136 display, up to 256 8x8 foreground and 256 8x8 background sprites, 4 channels of audio and a 64kb disk/console size.  Tic is open source with the code available here.  TIC-80 also provides a VM, code editor, sprite editor, map editor and music/sound editors.


LIKO-12

Another open source option, LIKO-12 is heavily inspired by PICO-8, built on top of the LOVE game framework.   LIKO is currently less feature complete than the others, lacking many of the editors others provide.


PixelVision 8

Perhaps the most interesting of the options out there, certainly the most polished from a UI perspective, PixelVision 8 is heavily inspired by PICO-8 witha  major twist.  PixelVision aims to emulate the development experience of real world hardware such as the NES, Gameboy and SEGA Master System.  It also enables you to customize the capabilities of your target platform.  It also contains several built in editors for graphics, music and code.  Currently it is only available for purchase for $15USD, although a free version is in the works.


You can learn a bit more about fantasy consoles and go hands on with PICO 8 in this video, which is also embedded below.


Programming

30. May 2017


Back in Part One of our look at the PlayCanvas HTML5 3D game engine, we started creating our simple bowling game.  We already created our lane and pins.  Now it is time to continue on and create our bowling ball.  Attached to our bowling ball will also be the script the controls the majority of our game.  Let’s jump back in.


Creating the Bowling Ball

This time, instead of importing a model, we are simply going to use a built in procedurally generated mesh.  Simply right click the Root in the Hierarchy view, select New Entity then Sphere.

image

Scale the newly created ball down and position it accordingly.

image

Under the Entity properties, I renamed it from Sphere to BowlingBall.  Right now our ball doesn’t look all that great.  Let’s go ahead and make it a bit shiny.  Right click in the asset area, select New Asset->Material.

image

Select the newly created material from the assets tab.  In the Material panel, I rename it to BowlingBallMaterial.  What I want to do is make the bowling ball a bit shiny.  I am going to leave it white, but if you want to change the color, do so under the Diffuse tab.  Next head on down to the Specular tab.  I used the following settings

image

Finally we need to apply the material to our bowling ball.  In the Hierarchy view, select the BowlingBall entity, under the Model panel, select our newly created Material.

image

Our bowling ball also needs to have a Collision shape and Rigid Body attached to it.

image

image

Be sure to set the Collision object to a Sphere and size the radius to be only slightly larger than our bowling ball model.


Now we have all the pieces needed for our game.  The pins, the lane and the bowling ball.  Now all we need to do is add some logic to the game.  This is done by attaching scripts to entities within our game.  In this case we are going to attach the logic to our bowling ball.


Scripting

With our BowlingBall entity active, add a component and select Script.

image


Scroll down to the Script panel, select Add Script->New Script.

image

Enter a name for the script.

image

Now click Edit Script to launch the script editor.

image

Now enter the following script:

var BallScript = pc.createScript('ballScript');

BallScript.attributes.add('speed', {
    type: 'number',
    default: -8
});

BallScript.prototype.initialize = function() {
    this.entity.collision.on('collisionstart', this.onCollisionStart, this);
    this.app.keyboard.on('keydown', this.onKeyDown, this);
    
    var pins = this.app.root.findByTag("Pin");
    this.startingPositions = [];
    this.startingRotations = [];
    for(var i = 0; i < pins.length; i++){
        this.startingPositions.push(pins[i].getLocalPosition().clone());
        this.startingRotations.push(pins[i].getLocalRotation().clone());
    }
    
    this.ballPosition = this.app.root.findByName("BowlingBall").getLocalPosition().clone();
    this.ballMoving = false;
};

BallScript.prototype.onCollisionStart = function (result) {
    
    if (result.other.rigidbody) {
        if(result.other.name == "BowlingPin")
            this.entity.sound.play("Hit");
    }
};

BallScript.prototype.onKeyDown = function(e) {
    if(e.key == pc.KEY_SPACE || e.key == pc.KEY_W){
        this.entity.rigidbody.applyImpulse(0,0, this.speed);
        this.ballMoving = true;
    }
    if(e.key == pc.KEY_R){
        var pins = this.app.root.findByTag("pin");
        for(var i = 0; i < pins.length; i++){
                pins[i].rigidbody.teleport(this.startingPositions[i],this.startingRotations[i]);
                pins[i].rigidbody.linearVelocity = pc.Vec3.ZERO;
                pins[i].rigidbody.angularVelocity = pc.Vec3.ZERO;
        }
        // now the ball
        this.entity.rigidbody.teleport(this.ballPosition);
        this.entity.rigidbody.linearVelocity = pc.Vec3.ZERO;
        this.entity.rigidbody.angularVelocity = pc.Vec3.ZERO;
        this.ballMoving = false;
    }
    if(e.key == pc.KEY_B){
         // Just the ball
        this.entity.rigidbody.teleport(this.ballPosition);
        this.entity.rigidbody.linearVelocity = pc.Vec3.ZERO;
        this.entity.rigidbody.angularVelocity = pc.Vec3.ZERO;
        this.ballMoving = false;
    }
    if(e.key == pc.KEY_LEFT || e.key == pc.KEY_A){
        this.entity.rigidbody.applyImpulse(-0.2,0,0);
    }
    if(e.key == pc.KEY_RIGHT || e.key == pc.KEY_D){
        this.entity.rigidbody.applyImpulse(0.2,0,0);
    }    
};

// update code called every frame
BallScript.prototype.update = function(dt) {
};


One thing you may notice in the script above is the definition of the speed attribute.  This exposes this variable back to the editor, like so:

image


You may notice the line of code in the script for playing audio when we collide with a pin:

    if (result.other.rigidbody) {
        if(result.other.name == "BowlingPin")
            this.entity.sound.play("Hit");
    }

Now we need to add this audio asset to our bowling ball.  First add the audio file as an asset.  Simply click add asset –> Upload, then upload a WAV file.  Now we need to add a sound component to our BowlingBall entity. 

image


Now scroll down to Slot 1 and add the asset you just uploaded and be sure to set name to Hit.

image


And done.  A complete, rather simple but fully functioning 3D bowling game in just a few minutes.


The Video

Programming , , ,

Month List

Popular Comments