Saturday, February 21, 2015

GoDot (Dont Touch Spikes)


Last time i basically explained what it felt like using the GoDot engine gui while i was creating the simple game of Dont' touch the spikes. In this post i will cover how i went about setting up the scene and issues i faced.

The Scene Setup

Coming from cocos2d-x i'm used to Layers, Scenes as container objects to setup a gameplay scene. In GoDot however i was unable to find any such nodes. Instead i just had to use a Node2D. This is pretty much the starting point of the game scene structure.

I then added a RigidBody2D named it Player. This was going to be the physics body for dealing with user inputs etc. I then added a Sprite to the RigidBody. If you have used unity you would start wondering where do i add the collisionbox component to the rigid body. Simple answer is .. you dont. You actually have to add a node called CollisionShape2D as a child to the RigidBody2D to be able to detect physics collisions in the simulations. So the Scene tree looks like this:
Player Setup
There are a bunch of things we need to start setting in properties panel corresponding to the Payer Object (RigidBody2D object) to be able to get callbacks for collisions when this body collides with static / kinetic physics bodies.
Options to set on RigidBody2D
The Mode is set to Character so that the rigidbody doesn't rotate on collision. It will just use the velocity and not the angular velocity. The Contacts Report and Contact Monitor ensure that we are able to get callbacks for collisions with kinetic objects and the static objects. There is a warning about this being performance drain but its' required in this case. Now let's get to adding some game logic / input handling with

Once this is done, I setup static objects for top wall, bottom wall, left wall and then the right wall. These help us keep the object inside. The spikes that are in game are added as KineticBody2D. The spikes setup is a little complicated, ill' cover it in detail when i cover the animation. The one important thing that we do for spikes is set their group name. This will help us in the collision callback.
Full Scene Graph
Roughly speaking each wall has spikes associated with it. The spikes on the leftWall and rightWall have the spikes that animate and so they look a little more complex than the Floor and Roof objects. The one additional feature i used for handling spikes is Group Name this will enable us handle the collisions easily across multiple objects.

Scripting



Adding a script to a Node is Easy
With a node selected, click on the Edit/Create the node Script button in the scene graph panel. Once you provide the details like filename, file path of the script, you will be taken to the scripting window.
Scripting Window with Stuff filled in
The above screenshot is way ahead in the development.. when you create a new script you will just see something like this
       
#the script associated with a RigidBody2D node.

extends RigidBody2D

# member variables here, example:
# var a=2
# var b="textvar"

func _ready():
    #initialization happens here
    pass


As you can see the _ready function is the initialization function that is created by default. its' like the OnStart function in unity behavior scripts. To get callbacks on each rendered frame i.e OnUpdate function from unity you have to call set_process(true) this will make sure that you get calls to a function named func _process(delta):  this will be the equivalent of the update functions in other engines like cocos2d-x or unity.
#the script associated with a RigidBody2D node.

extends RigidBody2D

# member variables here, example:
# var a=2
# var b="textvar"

func _ready():
    #initialization happens here
    set_process(true) 
    set_fixed_process(true) #callback on each physics update.
    set_process_input(true) #enables input handling
    pass

func _process(delta):
    #callback on each frame render
    pass

func _fixed_process(delta):
    #called after each physics update cycle.
    pass

func _input(event):
    #called on any input event.
    pass


Now that we have access to the update cycles and the input events, lets' have a look at how we handle the physics collision callbacks. This is done through node connections. It's basically a observer pattern implementation similar to the one seen in Toolkits like Qt.
Node Connections Button

There are a bunch of predefined signals for each node type in GoDot. You will be able to see them listed in the connections window when you click on the connections button in the scene graph panel.

Signal List
This window shows all the signals that the selected node can emit, once you click connect you are taken to another popup shown below.

Callback selection window
Here you select the body that will receive the signal and the function for callback when the signal happens. If you leave it default settings, the callback function will be automatically added to the script associated with the selected node. So now the modified script looks like this
#the script associated with a RigidBody2D node.

extends RigidBody2D

# member variables here, example:
# var a=2
# var b="textvar"

func _ready():
    #initialization happens here
    set_process(true) 
    set_fixed_process(true) #callback on each physics update.
    set_process_input(true) #enables input handling
    pass

func _process(delta):
    #callback on each frame render
    pass

func _fixed_process(delta):
    #called after each physics update cycle.
    pass

func _input(event):
    #called on any input event.
    pass

func _on_Player_body_enter( body ):
    #your implementation goes here. this is called whenever 
    #Player object collides with another object.
    pass

In this case i selected the body_enter(Object body)  signal from the Player node in the scene and connected it to the same node so i can handle the collision response in the same script.
This says that the signal will also emit an object of type body which is basically the handle to the object that is collided with.


Custom Signals

As i mentioned earlier, the signals / connection mechanism is very useful for communicating between multiple game objects. In this game i used it to notify the walls when ever there is a change in score to change difficulty. This enabled me to decouple the difficulty of spikes from the player handling / game handling code.
#the script associated with a RigidBody2D node.

extends RigidBody2D

# member variables here, example:
# var a=2
# var b="textvar"
var gameScore = 0

func _ready():
    ....
    #setting up signals supported by the object.
    var argument = { "score" : TYPE_INT }
    var ArgumentArray = Array()
    ArgumentArray.append(argument)
    #add the newly created signal to the list
    add_user_signal("ScoreChanged", ArgumentArray)
 
    #signal handling for bg color change based on score.
    connect("ScoreChanged", get_node("../backgroundColor"), "updateColor")

func _on_Player_body_enter( body ):
    #your implementation goes here. this is called whenever
    #Player object collides with another object.
    var name = body.get_name()
    if name == "LeftWall":
        gameScore += 1
        #trigger the signal that score has changed and send parameter.
        emit_signal("ScoreChanged", gameScore)
    elif name == "RightWall":
        print("Turn Left")
        gameScore += 1
        emit_signal("ScoreChanged", gameScore)

With all these things in place i was able to quickly develop the Dont' touch Spikes game in about two days' time. Most of the time i was just searching through the documentation and tutorials trying to understand the basics.

I've uploaded the code to github so you can directly download and try it out.
https://github.com/vkbsb/godot_dts



GoDot Engine

GoDot is an OpenSource 2D/3D game engine.
There isn't any shortage of game engines these days. It's just a matter of preference and getting the pipeline ready for that engine that takes a while. I've been using cocos2d-x for a while now for most of my 2D games.

GoDot Engine GUI
But Iv'e been thinking about using a GUI based integrated Game engines for future projects so the obvious choice was Unity engine. Its a pretty stable platform and has a bunch of plugins for every thing you want to do, and is pretty much the gold standard for mobile development. There are still a couple of things i still don't like about it.. which includes the lack of control and large build size.. well if something isnt' working.. there is no way for me to figure out if it was my code issue or something wrong in the engine. The community is almost always there to help but its' not a guarantee. I was still searching for an engine that would be easy to use and would give me the full control.. thats' when i came across the GoDot Engine.

Some of the features i love about GoDot Engine

  • Python based Scripting
  • C++ for core extending engine
  • exports to Html5
  • OpenSource
  • An integrated GUI env for game development.
Why not Unity?
As i tried to evaluate its' usability i quickly realised its' not yet ready for mobile game dev, let me explain.. integrating with 3rd party libraries like ad networks is pretty scare at the moment on godot engine. And there aren't many plugins available like there are for Unity.. so if you are ok with paying for the engine licence and need a stable dev platform for mobiles.. Unity is still the right choice. 

But i like the control that open source engines give and did i mention its' all free?.. it might be a little tricky to use but if i were able to use it for creating games and figure out how to do the integrations required, this could become the engine of choice for me.. So i soldered on to figure out how the engine works / learned the scripting over the weekend and tried to build a small game quickly.

The Game
The game of choice was ofcourse a popular game called Dont' touch the Spikes.
I am a big fan of the game and i figured it would be cool to try and use GoDot to create the game. So here goes the experience. 

The GUI
The gui is kinda hard to get used to at first but lucky for me there are a bunch of wiki pages explaining everything in detail and also some you tube video tutorials as well .
Here is the link to the youtube channel which helped me a lot.



The SceneGraph
GoDot has a scene graph structure similar to cocos2d-x, There are Nodes, Sprites, AnimatedSprites and so on. so if you have worked with cocos2d-x you should be able to pick up this engine pretty quickly.
Here is how a scene graph would look in the editor.. 
Scene Tree
If you are making a 2D game there is separate view from the 3D window, just like in Unity engine. 

The Scripting
The inbuilt scripting window is pretty cool, the amount of documentation is comparable to what unity has, this in combination with wiki on the project git hub page you will not have trouble getting through any scripting trouble you might face.. 
The Scripting Window
As you can see, the help is built right into the editor. With the auto complete in the editor and the documentation right there, scripting is a pleasant experience. For communication between objects, there are multiple ways
  • Call functions on objects just like in Unity
  • Signal / Connection method.
The Signal / Connection method should be familiar to anybody who has worked with Qt's Signal/Slot mechanism. Basically the observer pattern that is easy to use :) 

The Animation Editor

GoDot engine has a built in animation editor, with timeline and ability to creating multiple animations. This looks and feels primitive, but i was able to achieve the required animations for the game. There is a UI overhaul planned in future may be it will become easier to use then. 

I'll go through the tutorial of how i made the game next time .. :)