icon-image
Welcome to Innominds Blog
Enjoy our insights and engage with us!

Playing With UI Events & Game Design: How I Developed my First HTML5 & JS Based Game

By Deepak Tiwari,

I have been working as a UI Architect for the last three years building and architecting Data Science portfolios for clients. Once, during a team lunch with client, they asked me to build a gamified learning application, simulating a user’s journey through a system that can be used as induction/preparatory platform for new joiners to create better learning/training outcomes.

Even after working on HTML5 for two years, I still felt that I lack knowledge of few aspects of HTML5, which are focused towards UI Events and Browser Interfacing. In my sessions with UI engineers from various backgrounds, I found that many still struggle to understand HTML5, UI Events and Browser Events, and how to write their codes. These UI & Browser Events are basic building blocks for any JS Animation and games.

In this blog, I will show you how I started building a basic Drag & Drop Code to understanding JS Animations and then moved towards writing more powerful code using KiwiJS to leverage amazingly fast WebGL rendering and other tools to make good quality games. In the end, I was able to build a Mario like journey game with learning & educational theme using HTML5 Canvas and WebGL API.

UI Events

The following are the basic UI Events:

  • Mouse Events
  • Moving the Mouse: Mouseover/out, Mouse enter/leave
  • Drag ’n’ Drop with Mouse Events
  • Keyboard: Keydown and Keyup
  • Scrolling

Drag 'n' Drop With Mouse Events

Drag 'n' Drop is a great interface solution. It is a very common and useful use case, which can be found from copying and moving documents (as in file managers) to ordering (dropping items into a cart).

Problem: Build a goal and football and simulate a goal by dragging the ball to goal, which is your droppable.

Drag 'n' Drop event in a game Dragging the ball to goal using Mouse Events in a game

Solution: The key components of Drag ‘n’ Drop are as follows:

  1. Events Flow:
    ball.mousedown → document.mousemove → ball.mouseup (remember to cancel native ondragstart)
  2. On drag_start – note the initial shift of the pointer relative to the element i.e shiftX/shiftY and save it while dragging
  3. Detect droppable elements under the pointer using document.elementFromPoint

We can lay a lot on this foundation.

  • On mouseup, we can intelligently finalize the drop, change data and move elements around
  • We can highlight the element that we’re dropping over
  • We can limit dragging by a certain area or in a direction
  • We can use event delegation for mousedown/up

Output & Code is mentioned below:
https://plnkr.co/edit/VlXedRzqPuUkIgKnii1s?p=preview

JS Animations

JavaScript animations can handle things that CSS can’t. For example, time dependent functions are best use cases for complex path scenarios.


1. Using setInterval

Using asynchronous functions like setInterval to move sequence of frames. The pseudo-code can look like this:

let timer = setInterval(function() {
	if(animation complete) clearInterval(time);
    else increase style.left by 2px;
},20);
//change by 2px every 20ms, about 50 frames per second

Car_Animation

Code Snippet can be found here :
https://embed.plnkr.co/iAqrKDTe9kI4qwWbNTeq/


2. Using requestAnimationFrame

But how do we know in JavaScript that CPU is overloaded and redraw is required more often and how to balance this situation?

requestAnimationFrame function addresses all these issues and even more.
The syntax:

let requestId = requestAnimationFrame(callback)

callback function gets executed on need by browse to run animation. The below code shows the use for requestAnimationFrame. Usually it’s 10-20ms.

let prev = performace.now();
let times = 0;

requestAnimationFrame(function measure(time){
    document.body.insertAdjacentHTML("beforeEnd", Math.floor(time - prev )+ "");
    prev  = time;
	if(times++ < 10) requestAnimationFrame(measure);
})


3. Timing Functions

I am ignoring Linear Function and sharing code for frequently used Functions.

3.1 Bounce Function

Simulates bouncing of a ball when dropped from top.

function bounce(timeFraction){
	for(let a =0,b=1, result; 1; a+= b,b /=2 ) {
		if(timeFraction >= (7 - 4 * a) / 11){
			return -Math.pow(( 11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2);
		} 
    }
}

See it in action here : https://en.js.cx/article/js-animation/bounce/

3.2 Elastic Function

“elastic” function takes an additional parameter x for the “initial range”.

function elastic(x, timeFraction){
	return Math.pow(2, 10 * (timeFractoin  - 1)) * Math.cos(20 * Math.PI * x / 3 * timeFraction)
}
WebGL API’s to build amazing graphics

Game Development Using KiwiJS

After having learned and played with HTML5 Canvas and JS Animations, I decided to move to learning advanced concepts in Animation using HTML 5 i.e Game Development in HTML5 using WebGL API’s to build amazing graphics.

I decided to go with KiwiJS as my framework for building my first educational prototype game. Kiwi.js is HTML5 game framework for making HTML5 browser/mobile games.

For further and detailed study, please refer here : http://www.kiwijs.org/documentation/tutorials/creating-a-basic-kiwi-js-game/

There are three important aspects to any game:

  1. The Game Loop: It keeps repeating a process, so that the game won’t stop unless you call the function to stop
  2. Rendering: Taking cues from the back end works along with showing sprites on the front end (using canvas, in this case)
  3. Updating: Updating the positions of the sprites according to the specified moves

Algorithm to Setup Your Basic Game

Step 1: Create an index.html page. Put a copy of kiwi.js beside it.

Step 2: Create a new JavaScript file called gettingStarted.js. This is where we will write the Kiwi.js game.

Step 3: The first thing we need to do is create a new Kiwi.Game Object. The game object will be responsible for booting the required managers and handling the game loop.

Step 4: Our game is going to require one game state, which will contain the logic for creating the sprites, animations, and controlling updating and input. Create a new variable called myState and use the Kiwi.State constructor to create your new state. Give it a unique name for usage, preferably the same name as the variable.

var myState = new Kiwi.State( "myState" );

stateName.functionName = function () {
	Kiwi.State.functionName.call( this );
	....
}

Step 5: Each state has a preload method which will load in our assets for us. It’s all done under the hood so no need to worry about how it works. The preload method is called as soon as the state is initialized.

myState.preload = function () {
	Kiwi.State.prototype.preload.call(this);
	this.addSpriteSheet( 'characterSprite', 'character.png', 150, 117 );
	this.addImage( 'background', 'jungle.png' );
}

Step 6: The create method is called once the preload method has finished loading our assets. Therefore, it is a good time to create our entities. For this game, we will need a StaticImage for the background image, and a Sprite for the character. Also, we should create our animation key objects at this time.

myState.create = function(){
	Kiwi.State.prototype.create.call( this );
	this._bg = new Kiwi.GameObjects.StaticImage( this, this.textures.background, 0, 0 );
	this._actor = new Kiwi.GameObjects.Sprite( this, this.textures.characterSprite, 350, 330 );
	this.leftKey = this.game.input.keyboard.addKey( Kiwi.Input.Keycodes.A ); 
    this.rightKey = 	this.game.input.keyboard.addKey( Kiwi.Input.Keycodes.D );
	this.downKey = this.game.input.keyboard.addKey( Kiwi.Input.Keycodes.S );
}

Step 7: Adding Animations

this.character.animation.add( "idleright", [ 0 ], 0.1, false );
	this.character.animation.add( "moveright", [ 2, 3, 4, 5, 6, 7 ], 0.1, true );
	this.character.animation.add( "idleleft", [ 8 ], 0.1, false );
	this.character.animation.add( "moveleft", [ 15, 14, 13, 12, 11, 10 ], 0.1, true );
	this.facing = "right";
	this.character.animation.play( "idleright" );
	this.addChild( this.background );
	this.addChild( this.character );
}

Step 8: Update Method

In every game loop cycle, the game will call the update function of the active state. In our case, the update function will be responsible for checking keyboard input, moving our character, and switching animations. Under the hood, the game will be updating variables, rendering images and working out the animations.

myState.update = function() {
	Kiwi.State.prototype.update.call( this );
	if ( this.downKey.isDown ) {// rest goes here………….
}

This is all about Game Building tutorial using KiwiJS. It is also mentioned on their website and I didn’t take much pain to copy the content.

Steps for Game Design – How to Start

  1. Choose a Background Image
    Game Design Background Image
  2. Choose a Hero Sprite
    Hero Sprite - Steps for Game Design
  3. Setup Banner Points and Sign Boards
    Game Setup Banner Points and Sign Boards
  4. Go Through Algorithm and Start Writing Code
    Game design Algorithm and  Code
  5. Prepare First Basic Version of Game With Hero Moving On Canvas
    DAVE-KIWIJS-NORMAL
  6. Prepare the Platform for Camera Shifting Support

    Camera shifting is a mechanism, which gives player an illusionary motion effect and they feel that the environment is moving relative to them. It gives a perception of depth, texture and movement on a larger landscape.
    DAVE-KIWIJS

    if(!gameInit && !levelEndFlag) {
    	this.game.cameras.defaultCamera.transform.x = this.game.state.height * 0.5 - (playerOffsetX);
    }

Conclusion

This completes our basic setup for a Mario kind of game that we can build upon by converting it into a gamified version with features like coins, rewards and lives. There can be many ideas conceptualized on this basic setup and we can make interesting games and learn good programming techniques.

The source code can be found by accessing the following URL: https://github.com/Deepak003/educationGameKiwiJS

Coding games are a fun way of practicing programming. Games have helped me learn programming in an entertaining way and I think this is the best way to learn anything new.

About Innominds

Innominds is a leading Digital Transformation and Product Engineering company headquartered in San Jose, CA. It offers co-creation services to enterprises for building solutions utilising digital technologies focused on Devices, Apps, and Analytics. Innominds builds better outcomes securely for its clients through reliable advanced technologies like IoT, Blockchain, Big Data, Artificial Intelligence, DevOps and Enterprise Mobility among others. From idea to commercialisation, we strive to build convergent solutions that help our clients grow their business and realise their market vision.

To know more about our offerings, please write to marketing@innominds.com

Topics: Design UX & UI

Deepak Tiwari

Deepak Tiwari

Director - Software Engineering

Subscribe to Email Updates

Authors

Show More

Recent Posts