Indie Programming https://indieprogramming.com Making your game a reality Fri, 27 Oct 2023 23:35:07 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.3 Creating Simple JavaScript Games https://indieprogramming.com/__trashed/ Fri, 27 Oct 2023 20:43:05 +0000 https://indieprogramming.com/?p=3104

How Easy Is it to Make a JavaScript Game?

Well if you are creating a basic game then you can create one in as little as 20 minutes, as we will see later in this article.

If you are looking to get into game programming or indie development then creating simple JavaScript games may be the way to go as JavaScript is a good entry-level programming language to learn.

Browser games are great for cross-platform compatibility and can enable you to reach a wider audience in a short amount of time.

Can I Make Games with JavaScript?

JavaScript works in tandem with HTML and CSS, together forming a trifactor that is more commonly used for creating webpages. Because of this association, some people consider this a limitation and don’t think it is possible to create a full game using this framework.

An advantage of using JavaScript to code your games is that they can be converted into hybrid apps that can be played on Android and Apple devices.

Software like Xamarin can be used to bridge this gap. Xamarin is part of the .net framework it allows you to code in different languages and then convert it into native code to be played on a device of your choice.

How do I make a game in JavaScript?

You can start by using a simple HTML document like below to house your game. The below markup simply creates a canvas element. With this, we can access the context of the canvas, which will in turn expose its API.

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Our Game</title>
	<link rel="stylesheet" href="ourGame.css" />
	<script src="ourGame.js"></script>
</head>
<body>
	<canvas id="gCanvas" width="600" height="400"></canvas>
</body>
</html>

With this, we can link two other files to our HTML document. The first one will be the CSS ( cascading style sheets ) and the second will be the JavaScript file.

What is the Simplest Game to Make With JavaScript?

Well, one of the simple games is probably pong the classic 1970s game involving block-to-block
warfare. Snake is another classic simple game that has you gobbling up food as it is randomly generated
on the screen.

How to Create HTML5 Games with JavaScript?

We are going to quickly build a simple game using the HTML5 Canvas. The game will involve controlling our play and moving them about the screen eating up the food before they disappear.

First, we take out the example boilerplate script from earlier and amend it slightly:

This is what the Mark up for our game will look like:

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Simple Game</title>
	<link rel="stylesheet" href="simple game.css" />
	<script src="simple game.js"></script>
</head>
<body>
	<canvas id="gCanvas" width="600" height="400"></canvas>
</body>
</html>

This file will provide the structure for our game environment and includes the Canvas element we are going to draw on. This file also provides links to the other two external files we need, this being the CSS file and the JavaScript.

This is what our external CSS file looks like:

body {
	
	background: #000;
}
canvas {
	background: #fff;
}

This file will control the document’s background color and the background of our canvas. This simple CSS setup is all we need for this example.

For browser games the CSS file can be used in lots of useful ways, one key use case would be using it to create all the UI elements of your game. This is quite simple to do and can save processing by turning off and on simple tag elements when needed.

A simple example of this would be displaying options on a menu screen or the game over and restart buttons when the player dies.

Now we have covered the HTML and CSS side, we now come to the more complex of the three files. The JavaScript file will hold all our game logic, including player movement and other behaviors.

All of the game logic will be contained within the window.onload() function

window.onload = function(){}

The next two statements will give us access to the canvas and its context

var canvas = document.getElementById("gCanvas");
var ctx = canvas.getContext("2d");

You can change the name of these variables to whatever you want, but it makes sense to create them with a name that makes sense.

I like to create my reference variable for the context as ctx, this saves time writing out context each time you need to use its methods.

Now we have access to the canvas API we can invoke the ctx.fillRect() method, Let’s test this by creating a simple rectangle and drawing it to the canvas.

ctx.fillRect(100,100,64,64);

This should create the following result:

This is great! But we want to create a constructor that we can use to create all our game objects. This is essentially a function that will create an object with parameters you feed into it at run time.

This is what the constructor will look like

var Asset = function(x,y,w,h,vx,vy){
	this.x=x;
	this.y=y;
	this.w=w;
	this.h=h;
	this.vx=vx;
	this.vy=vy;
	this.alpha = 1;
}
Asset.prototype.draw =function(){
	ctx.save();
	ctx.globalAlpha = this.alpha;
	ctx.fillRect(this.x,this.y,this.w,this.h);
	ctx.restore();
}
Asset.prototype.move = function(){
	this.x += this.vx;
	this.y += this.vy;
}

This looks quite complex but I will break it down:

We first start by creating the function names and their parameters. This argument will tell the function how to populate the properties and fields that lie within.

In this case, this includes the object’s X and Y positions, Width, Height Velocity and Alpha.

We then create the draw method that will draw the images to the screen, this will use the object’s custom values to set its Alpha, X and Y position and Size.

The last prototype function will change the position of our object when we need to move it around the screen.

We also create a simple variable called screenCenter, this will help set our game objects’ positions later on. We initialize it with the value 250;

var screenCenter = 250;

We then use our constructor to create our first two objects

var player = new Asset(screenCenter+10,150,64,64,0,0);
var container = new Asset(50,50,500,300,0,0);

Then we will now create our startGame function and our game loop

function startGame(){
	gameLoop();
}
function gameLoop(){
	window.requestAnimationFrame(gameLoop)
	ctx.clearRect(0,0,canvas.width,canvas.height);
	player.draw(ctx);
        player.move();
	container.draw();
	container.alpha =0;
}
	startGame();
}

The startGame() function will hold the things we want to initiate at the start of the game, in this case, it will simply start our game loop

The gameLoop function will do the heavy work with the window.requestAnimationFrame() looping through all our game objects.

We then use the clearRect() method to clear the canvas on each frame, this ensures the animation moves smoothly. If you leave this line out the image will smudge across the screen.

We then use the assets draw() method to draw the player and the container to the screen. We also set the container’s alpha to 0 as we don’t want to see it we just want to use it to set the bounds for the pickup we will create later.

The pickup will be an item the player has to collect.


We have created our player object but without any kind of interaction, it isn’t really a game. We now want to create an event listener to handle the player input.

window.addEventListener('keydown', function(e){
	var whatKey = e.keyCode
		if(whatKey == 65){//left
			player.vx =-2;
		}
		if(whatKey == 68){//right
			player.vx =2;
		}
		if(whatKey == 87){//up
			player.vy =-2;
		}
		if(whatKey == 83){//down
			player.vy =2;
		}
})

window.addEventListener('keyup', function(e){
	
	var whatKey = e.keyCode
		if(whatKey == 65){//left
			player.vx =0;
		}
		if(whatKey == 68){//right
			player.vx =0;
		}
		if(whatKey == 87){//up
			player.vy =0;
		}
		if(whatKey == 83){//down
			player.vy =0;
		}
})

These are the key-up and key-down functions, they will listen for a key event and set the player’s velocity accordingly.

We now add the player.move() method to the game loop so that we have a way to move our player object.

Refresh the screen and you should now have a block that you can move around the screen using the AWSD keys.

Next, we want to create a random number generator function. We will use this to create a random position for our pickup object.

function Random(){
	var random ={x:0,y:0}
	random.x = 40+Math.random()*container.w;
	random.y = 40+Math.random()*container.h;
	return random;
}

Within the random function we create a variable that holds an object with two properties X and Y. We then use the random.x and random.y properties to hold a random position within our container object. This will return the random number when the function is invoked.

Next, we will use the constructor again to create our pickup object, this will be what our playable character will collect.

var ran = new Random();
var pickUp = new Asset(ran.x,ran.y,32,32,0,0);

We also create a new Random object ran which we use to initialise our pickup object X and Y position. We then draw our pickup object to the screen by adding the draw method to the loop

pickUp.draw(ctx);

Now we have a character that moves around and a pickup that we can collect. The only trouble is nothing happens when we collide with our objects, we can change this by creating our collision function.

function collision(){
	if(!(player.x+player.w < pickUp.x) &&
	   !(pickUp.x+pickUp.w < player.x) &&
	   !(player.y+player.h < pickUp.y)&&
	   !(pickUp.y+pickUp.h < player.y)){
		   nRan = new Random()
		   pickUp.x = nRan.x
		   pickUp.y = nRan.y
	   }
}

So for this collision function, we will be using an inverse conditional statement which evaluates if the contents of the parenthesis are false.

This will evaluate whether the player’s position and the pickup position are overlapping, if all the conditions are false then the two objects are overlapping. This means the two objects have hit each other.

In this case, we want to reuse the pickup object and respawn it again at another location.

To do this we create a new random number and update the object’s positions, simple. We now just have to add the collision function to the main game loop.

If you run this now in your browser you should have a functional game, granted a very simple one. The aim is to collect the objects on the screen as they respawn in different locations.

Although this is a very simple game we have covered quite a lot. We made a constructor to instantiate the objects in our scene, this being the Player and Pickup objects. We dealt with grabbing user input via the keyboard to control our player object. We created a random number generator and then created some basic rectangle collision detection.


]]>
How to Make Hyper Casual Games in Unity https://indieprogramming.com/how-to-make-hyper-casual-games-in-unity/ Thu, 26 Oct 2023 20:02:07 +0000 https://indieprogramming.com/?p=3212


Unity is one of the most popular game engines around, not just with indie developers, but also with bigger game studios too.

With engines like Unity, it’s very easy for the lone developer to gain traction and produce quality, commercially viable games that can compete with bigger studios.

There is also an abundance of smaller independent companies that are making very stylistic games that cater to much smaller audiences.

Games can now be made for niche groups of gamers rather than the masses.

These people are more interested in playing a game that can create a unique original experience rather than the usual trappings of something like the Call Of Duty franchise.

Unity is great for these types of indie games, it’s also great for making Hyper Casual Games.

Under the cover Unity is a very powerful 3D graphics engine that can create very complex 3D environments.

It also has no trouble creating simple 2D games, much like the ones you find in this Casal game sub-genre.

The following are some examples of hyper-casual games made in Unity 3D:


Crossy Road

Crossy Road, made in Unity


Crossy Road is an addictive game that was produced in Unity, the aim of the game is to make it across the busy road and traverse many different obstacles on the way.

The graphics are very blocky and create a very stylistic retro-level design.

This game is essentially the classic game Frogger. This game came out at the start of teh 80’s and is considered a golden oldy. This game has pretty much the same concept but has an isometric, stylized veneer.

In Frogger you had to guide a little frog across a busy road, carefully navigating oncoming cars and lorries as you did so. Finally, you had to jump on lily pads as they floated along past you to reach the end of the level. Timing your jumps was key to reaching the end goal.

Taking concepts from old games and updating them with a twist can be a recurring pattern in a lot of popular hyper-casual games.


Monument Valley 2


Inspired by the drawings of M. C. Escher, Monument Valley 2 is another game that was made in Unity.

Monument valley 2

The level design is based on the ambiguity of impossible objects. Structures that logically don’t make sense and simply wouldn’t exist in the real world.

This makes for interesting puzzle solving when traversing the illusory, labyrinthian levels. These simple isometric levels make for an immersive eye-pleasing visual feast.


Alto’s Adventure

Alto Adventure


Alto Adventure is a fluid downhill skiing game that captures the excitement and peacefulness of high-altitude skiing with an ambient minimalist soundtrack.

The Creator cited hours of playing Tony Hawks Pro Skateboarder as a major influence on the game. As you traverse these beautiful monochromatic vistas you can perform a multitude of tricks and spins that can increase your score.

The gameplay is very smooth and really draws you into the world. Just the sounds of the skis gliding through the snow are very hypnotic.


Glitch Dash

Glitch Dash


Glitch Dash is a 3D endless runner that has you jumping dodging and spinning your way past various objects and pitfalls.

The trance-like soundtrack has you jumping in time with the glitch-style rhythms. This makes for an addictive, but deviously hard time-based mechanic.

This is a simple idea that works very well in 3D making it infinitely more immersive than many 2D runners.


Hole Down

Hole Down is a very simple game that has you hooked right from the start with its stupidly charming visuals and gameplay.

The aim is to get to the core of the different planets by shooting small balls at a host of pleasingly beveled blocks. The blocks are numbered to signify how many times they need to be hit.

You have a limited amount of shots, which means you have to choose the most effective route that can cause the most damage.

you can take advantage of rebound damage by bouncing your balls off the walls to maximize the impact.

This game is very minimal when it comes to graphics, but has a great puzzle element that makes it very fun to play.

Simple graphics look simple by design and are pleasing to look at, just like high-quality graphic-driven games are. Remember there is beauty in simplicity

This kind of graphic style is quite prevalent in many top charting games in the app stores. Developers like Voodoo and Ketchup create slick simple games that play well.

The advantage of this stylish but minimal graphics style is that assets can be made very fast with the emphasis on simple graphics, but addictive gameplay.

]]>
Game Dev Books https://indieprogramming.com/game-dev-books/ Thu, 26 Oct 2023 19:46:07 +0000 https://indieprogramming.com/?p=3196

“The only HTML5 books you will ever need!”

So you want to create a simple browser game and you are looking for some fundamentals in game programming. Well, the following 3 books will teach you 90% of what you need to know to build and structure your game.

Utilizing HTML5 as your weapon of choice is a great idea. You can make fast multi-platform scale-able games very quickly.

HTML5 can be a bit of an ambiguous term, when people say HTML5, in reference to creating games, they usually mean a framework consisting of HTML5, Javascript, and CSS. These three make up the structure, style, and behavior of browser our games.

So there are only 3 books that I have listed here because I believe these three books have pretty much everything you need to know about making simple HTML5 games, or at least get you most of the way.

These three books that I am recommending are also ones that I own, and ones that I reference all the time (as you could probably tell by the condition they are in, see pics)

Another thing I like about these three books is each one is almost a continuation in difficulty level from 1 -3, presenting a similar structure and familiarity in their workflow.

These books will cover the whole gamut of games out there, including scrolling space games, Endless Runners, fully scalable RPGs, and even 2D physic-style games.

Here are the 3 best game dev books I own:

APRESS – HTML5 Canvas

Rob Hawkes has been an early advocate of HTML5 and regularly preaches about the far-reaching capabilities of the Canvas element and its cohorts.

This was one of the first HTML5 books I bought and is a great introduction to web game development.

Visit Rawkes site here www.rawkes.com

This book takes you by the hands and guides you through the first steps in interacting with the Canvas and its Context.

It shows you how to draw different shapes and images on the canvas and the many different ways of manipulating them.

It then introduces you to the concept of a game loop, a fundamental step in creating any type of game.

It also shows you how to create boundaries for your game objects and what to do when they exceed the limits of your canvas. This includes respawning objects and screen wrapping

There are examples of capturing user interaction to move a player object around the screen to avoid incoming enemies.

There is talk on the canvas composite effects and how to use them.

There are also chapters on how to simulate movement and deal with object collisions. From basic collision between two or more objects and more advanced billiard-style ball physics.

Towards the latter half of the book, Rob Hawkes takes you through the stages of creating two space-themed games. One is a space bowling game the other is an asteroid avoidance game.

This book creates a great foundation for your future projects and gives you a solid understanding of HTML5 and the canvas element.

APRESS – Game Design with HTML5 & Javascript

Written by Rex van der Spuy – Who has written many books on making games with Flash, has distilled his knowledge and converted it over to the popular HTML5 framework.

This book builds on what we have already learned and introduces more concepts like game states, tile-based level construction using arrays, and scrollable levels.

This book will have you creating many different games, from simple text-based games to parallax-style platform ones.

This takes a more program-by-example approach and involves creating a lot of mini-games. This covers quite a lot of examples, more than the other two books do.

The book also introduces you to a tile-based approach to creating your levels. This is often used as a clean and conservative way to make multiple levels quickly. Also covering Sprites and Sprite sheet optimization.

You are shown how to make basic sprite animations and how to create behaviors for your game objects, triggered by certain responses like a timer or user interaction.

You are shown how to organize your files and how to structure your images in your sprite sheet. Then use these images in conjunction with a 2-dimensional array to populate your levels

The concept of creating sprite sheets and atlases to help minimize the memory footprint for your games is a very powerful and widely used technique.

In particular, this is still popular with mobile platforms where 2D graphics processing can still be limited. Also old-style retro games where pixel graphics and tiling are prevalent themes to the overall look of the game.

APRESS – HTML5 Animation with Javascript

This book was written by Billy Lamberta who converted the successful book
“Foundation ActionScript Animation” makes it compliant with JavaScript.

Interestingly, one of the technical advisers for this book is Rob Hawkes, who was the author of the first book on this list.

This book will increase your understanding of game development fundamentals introducing you to more complex forms of animation using physics and trigonometry functions.

It’s comprehensive but never gets overly complicated. This book takes what you already know about the canvas element and builds upon it.

This book is definitely a step up from the last two, but subjects are broken down and are easily understandable.

You get a rush course in trigonometry and other maths-related functions. All these methods are clearly detailed with examples.

Rather than creating fully realized games, this book will touch on examples that you can use in larger projects. It also covers more advanced Javascript topics than the previous books.

You also get a more in-depth look into different collision detection methods and more diverse movement using angular velocity, easing, and springing. It also has a whole chapter on forward kinematics.

The latter half of the book introduces concepts for creating pseudo-3D games using a 3rd dimension to scale your objects.

If you are interested in creating games for browsers or mobile phones then these three books are a must-have. They cover pretty much everything you need to know for making small but addictive games.

When you have finished and have your polished game, you may decide it’s ready to launch. At this point, you will probably want to upload it to your portal of choice.

It’s very easy to take your web-based creation and use software to create a hybrid application. This hybrid will then work on Android or Apple devices, much like a native app.

Now the native language for most Android apps is actually Java, which is a more complex programming language than Javascript.

Phonegap, Xamarin, or Cordova provide a wrapper around your application making it work on all modern Android, Apple phones, and other devices.

There you have it, these are the books I recommend and still use to this day. There are plenty more out there, but these three work just great together.

]]>
Klik N Play https://indieprogramming.com/klik-n-play/ Tue, 24 Oct 2023 22:35:33 +0000 https://indieprogramming.com/?p=3170

Back in 1994, there was a piece of software called Klick N Play, this was a pioneering program that introduced the art of game creation to the world of the non-programmers.

It was quite revolutionary at the time with its canvas style editing and visual event coding, very similar to many visual editors existing today.

Klick ‘n’ Play was inspiring many game designers to dip their toes into the world of game creation.

It was also fine-tuning the skills of many future indie developers of the time, with its fluid visual editing style which made it easy to create simple games and demos.

I too, as a youngster, remember using it to make many games myself. At the time there were very few tools that would allow for such visual freedom when creating simple games and weird interactive nightmares.

I was recently surprised after watching Indie Game: Life After, a sequel to Indie Game: the movie that the guys behind games such as Spelunky and Meat Boy also used to make games with it.

One of the most popular pieces of software for indie developers Nowadays is Unity.

Unity can be used to create lavishly stylized games, either by small teams of developers or the lone indie dev. Never before has it been so easy to create games with engines like Unity.

Here are some other popular engines used by indie developers:

  • Unreal
  • Godot
  • Game Maker
  • Impact
  • Construct
  • Multimedia fusion

Today we are spoilt but back in the 90’s it wasn’t quite as easy.

At the time there didn’t seem to be an entry point for the artist-come game developer for creating their own titles. Most game creation would inevitably involve a good understanding of coding.

What were games programmed with during the 90s?

The first Doom was released in 1993 and was written in Objective C and many other games after this were C++ the reason for this is because of its highly optimized and strong type format.

The SNES was very popular in the nineties with the games being mostly written in Assembly code and maybe C, mostly being loaded completely from the cartridge and not from RAM.

The PlayStation was a massive leap forward in console technology, but games were still mainly in C with a sprinkle of Assembly code.

The consensus in the mainstream would be mainly C or C++, but a lot of bedroom programmers were writing in Basic or some derivative of it.

BASIC (Beginners’ All-purpose Symbolic Instruction Code) was an easier language to learn, more so than C, and could provide a stepping stone into more complex languages.

Here are some derivatives of the BASIC programming language for the Amiga and Atari ST:

  • AMOS ( Advance Amiga version )
  • STOS  ( Atari ST Version )
  • Blitz Basic ( for Amiga and eventually Windows)

You can still find a community using this software to create fan-made games like these here:

http://www.indieretronews.com/2016/06/dizzy-seymour-dark-wizard-retro.html

Worms is probably one of the greatest examples of a successful game made with one of these derivatives.

Worms was created by Andy Davidson back in 1995, it was made in Blitz basic, it wasn’t completely finished but, the main gameplay and level design were blocked out.

Andy approached Team 17 at a game trade show with his unfinished game in hand, this would have been a floppy disk at the time.

Team 17 had a look at the contents of the disk and were interested straight away, soon after this time the game was published.

Back in the 90s finding a publisher for your game would be paramount in getting your games to the masses, as the publishers would have to pay all the overheads of producing a physical copy and the act of distributing the games to the shops

Nowadays we are spoilt with the ability to self-publish our game to a variety of popular indie game sites and networks.

What about creating 3D games in the ’90s

A lot of 3D software at the time would have been in-house proprietary software and wouldn’t have been available for free use.

If there were any they would have been pretty hard to code and not easy for the average 3D artist to use.

One exception was a piece of software from 1991 called 3D Construction Kit. This toolset allowed anyone with a creative mind to create 3D worlds and script adventures that were limited only by their imagination.

You can see examples here  http://www.3dconstructionkit.co.uk/

So the ’90s had its fair share of game creation tools, but none of them came close to the kind of drag-and-drop style environments we are accustomed to today.

Francis Lionet, who was responsible for programming the hugely popular Basic derivative STOS and AMOS, teamed up with Yves Lamoureux and Francis Populain in 1994 to create a simple click-and-drag game editor called Klick n Play.

KNP was an advanced event-based game creation tool and was very much a foundation for many other similar knockoffs.

This advanced event-based system allowed you to create simple games by dragging and dropping game elements onto a canvas.

Once you had done this you could then decide on how these objects would interact with each other and their environment. 

You could create a playable character by adding controls to a “player” object which then allowed you to move the object around the playing area.

You could then add behaviors to objects to allow them to act like enemies, you could also add path movements to give your enemies some life.

After this, you could create basic collision detection that would react when one or more objects collided with each other.

You could also animate your graphics or sprites, making a simple walk cycle or, perhaps, animating a rocket ship’s afterburner.

This would make your sprites more realistic rather than just static and lifeless, giving them a more professional polish.

The overall goal of software like Klick N Play was to make it easy and quick to create games, one moment you could have an idea for a game the next you would have a fully functioning mock-up you could share with your friends.

All this without touching a line of code.

There were iterations of Klick N Play these include:

  • Games Factory
  • Games Factory 2
  • Click N Create
  • Multimedia Fusion

Were there any professional games made with these engines?

It wasn’t until Multimedia Fusion that games could be made and distributed freely for profit, with previous versions it was illegal to sell any games made with their software.

An example of a successful game made with Multimedia fusion would be Friday Night At Freddy’s, this is a popular horror game that was at the top of the paid app store for weeks.

Here is a good interview with the creator: https://www.clickteam.com/clickteam-blog?p=interview-of-the-author-of-a-top-paid-game-in-appstore

You will notice that the developer talks about how he used to make games in Klik N Play before he went on to eventually create his game in MMF.

Many of the games created with the earlier versions of the software, such as KNP, couldn’t really be distributed commercially because many of the components were Copyrighted.

People would get around this by downloading the KNP games made by the developers and compiling the best ones to a CD. These could then be distributed around to other hobbyist game devs

So I mentioned earlier about famous indie developers using Klick n Play, but who are they?

Edmund Macmillan co-creator of Meat Boy and creator of Binding of Isaac has often talked about using Klik N Playback in 1996.

You can see this from the response to this Twitter feed:

There’s also footage in the Indie Game: Life After film where he talks about KNP being an early game creation tool he used.

I recently shelled out £70 to buy Multimedia Fusion 2.5 and found some old KNP games that I created about 20 years ago. 

To my surprise, after loading it up in multimedia fusion they worked almost perfectly. 

Not sure if this means that the current version is still running pretty much the same interface and tools it did all those years ago, or just that it has impressive backward compatibility. 

If you used Klik N Play I would suggest getting Multimedia Fusion just to revisit the old games you created all those years ago. 

I also suggest checking out Glorious Train Wrecks https://www.glorioustrainwrecks.com/

This site showcases and celebrates the art of creating, often terrible, games that can range from, the crazily addicted, to the downright abstract and bizarre!

There was a kind of art, at this time, in kitbashing games together using various images you found online.

You could quickly combine these assets with simple gameplay mechanics and go on to create strangely interactive and pleasing experiences.

KNP was my stepping stone into creating games and, even though I haven’t used it lately, it gives me a feeling of melancholy whenever I think about it.

Soon I will be starting a regular section where I will be creating simple game tutorials using MMF. watch this space.

]]>
Hyper Casual Games https://indieprogramming.com/hyper-casual-games/ Tue, 24 Oct 2023 22:07:39 +0000 https://indieprogramming.com/?p=3144

What are Hyper casual games and why are they so popular?

With the rise of our pocket computers or ” Smartphones” the term “Casual Games” has become more prevalent in our gaming lexicon.

You have probably heard of a game called “Color Switch”, created by David Reichelt who was working a 9 to 5 job before he came up with the idea.

The basic premise is to guide your colored ball through obstacles with the same color, you have to match up the color of your ball with the obstacle you are colliding with.

If you collide successfully with the right color you will pass on through, if you collide with an opposing color it is game over.

This is a simple gameplay mechanic that is fun and addictive over time…

David had a simple idea of a game and used a program called Build Box to realize it. David was able to, by himself, quickly create a rough mock-up of the game that was ready and playable in about a week.

Although he eventually found success with Color Switch, it took him 40 other attempts before he found his hit idea.

If you are interested in Build Box for creating your games then you can find out more about it here:

https://signup.buildbox.com/

I think one of the earliest casual games, in terms of uncomplicated gameplay and a repetitive endless runner-style environment, is Flappy Bird.

Flappy Bird is a simple affair by which you tap the game screen at specific times to navigate some awkwardly placed piping (The green pipes were obviously ripped straight from Mario by the way!)

It was super successful mainly down to its combination of cute retro graphics, which appealed to both new and old players, and its ridiculously ruthless learning curve.

I didn’t know many people who could get through 30 pipes or more, perhaps the difficulty level was what made people come back to this game over and over again.

Despite Flappy Bird’s success, Nguyen said he wasn’t happy. “My life has not been as comfortable as It was before,” he said. “I couldn’t sleep.” Dong Nguyen.

The creator of Flappy Bird Dong Nguyen admitted feeling guilty about the success of Flappy Birds and wasn’t used to all the media attention he had after its success.

Flappy Bird, like most casual games, involves simple gameplay mechanics, specifically, taping the screen at specific intervals to navigate some kind of peril.

Hyper casual games have this pattern of being addictive, and fluid, but devilishly hard.

The hardcore players would play it over and over again whereas conversely others would pick it up and play it for much smaller intervals.

Hypercasual games are very simple in their graphics style and the control system, most distilling the control functions down to just a simple finger tap.

This kind of simple style of gameplay, often just a tap on the screen, creates instant gratification and instant gameplay, anyone can pick it up and get to grips very easily.

The visuals are interesting and colorful enough to bolster the experience further.

HCG games shoot for a wide audience, often to maximize ad clicks, and have pretty generic simple, but kinda beautiful, modular graphics.

This ambiguity ensures a graphics style that can’t be pinned down increasing its popularity with a wider demographic.

The Impossible Game is a fast addictive game that has very stylistic graphics that perfectly match the fast-paced gameplay.

It’s about tapping the button at the right moment to navigate your rotating cube across the spike-filled, colorful, levels.

Although it is called the impossible game it is generally quite intuitive and can be mastered once you get used to the simple times-based jumps.

Although this game walks a fine line between being difficult and satisfying it rarely becomes frustrating.

The level design and changing colors create a pleasing and engaging experience.

Hypercasual games are about fluid gameplay and immersive visuals that you don’t really have to think too much about.

When people download a hyper-casual game they don’t want some complicated story-driven narrative, they want it to have a minimal, if any, storyline and an easy and consistent difficulty curve.

Making them too high concept might make playing them too confusing and overwhelming.

Remember this is a casual experience! Making them too difficult will also break the flow of our game, and this will cause people to stop playing.

So why would you want to play a game that you don’t have to think about?

Hyper casual games are more about a gentle cascade, a feeling of continuous motion that creates an almost semi-automated hypnotic experience, often only requiring minimal input from the player.

They can be quite rhythmic with their time-based perils, which keep you playing almost to a beat, this can heighten the experience and make the game very satisfying to play.

Although people do list similarities between casual games and ones from the 8-bit and 16-bit eras, they can be quite different beasts.

Whereas the older games were limited by the hardware of the time, a lot of mobile-centric games are simple by design.

Back in the day you could easily pick up a Nintendo or Sega game and get fully immersed in a world of cartoon-style graphics and addictive gameplay.

Although these games have simple gameplay mechanics Like HCG what separates them is the difficulty and frustration of level design.

This frustration is the antithesis of what casual gaming is about. Frustration and confusion are the enemy when creating this kind of game, it’s all about continuous flow – a fluid experience.

You definitely wouldn’t have got a game like a cookie click on your SNES or Mega drive. The cookie clicker pretty much consisted of just tapping a cookie over and over again.

The simplistic nature of cookie clicker meant you didn’t even have to look at your phone whilst playing, you could just blindly tap the screen even if it was in your pocket.

So you have these very simple addictive games that have ruled the top of the app charts.

They bring elements of the old-style games including some graphics and simple gameplay mechanics.

They also include an arching immersive casual experience that is seamless and almost infinite.

The company Voodoo is probably the most well-known producer of HCGs, gaining millions of downloads and also earning hundreds of millions in profit.

One of Voodoo’s most popular games is Hex Jump.

The aim of the hex jump is to get the softball through the holes to the bottom of the level whilst dodging red or multicolored hot spots that instantly kill you.

You control the 360 rotation of the spindle-style platform that you have to navigate through.

Turning the platform around at the right moments will allow you to guide your ball through spaces in between.

Move it right and you will drop through to the safe ground, make a wrong move and you will die on the hazardous red platforms (Red equals bad)

This simple idea of controlling the rotation of the platform rather than the player itself creates a very pleasing gameplay mechanic.

Quite often the success of HCGs can mean taking a simple established game and adding a twist to it.

This is why so many popular games are very much a variation on a theme and are similar in fashion to old games of the past.

The trick is to give the game a hook that makes it different enough to increase its lasting appeal.

If you are interested in creating a Hyper Casual Game – Follow my article on Creating your own Hyper Casual Game.

You will be taken step-by-step through creating this simple game using JavaScript, HTML5, and CSS, a popular framework for creating scale-able games.

When finished you can play the finished result in your browser.

]]>
Sound Effects For Games https://indieprogramming.com/sound-effects-for-games/ Sun, 01 May 2022 20:26:47 +0000 https://indieprogramming.com/?p=3040

If you are creating you own games as a solo indie developer you know how hard it is to create a project through to the end, let alone create you own sounds and music too.

You can find lots of free sound effects on the internet from sources like opengameart.org Freesound.org, even Youtube has its own royalty free audio library.

A more exciting option and more personal approach to sound design would be to create the sounds yourself using hardware and soft synths.

This post is more geared towards sound effects for simple 2D games so I won’t touch on anything as complex as chords and scales, just basic sounds that you can create easily yourself.

How to Make Sound Effects for Games

To start with I am going to be using the mighty Bfxr which is a remake of the original Sfxr software. The Sfxr software synth was created in 2007 for making simple sounds effects for the 10th instalment of the Ludum Dare challenge.

The Ludum Dare Game jams are a series of contests hosted through out the year with the main challenge being April. This is considered the de-facto of game jams and has seen many big games created as a result.

Find out more about Ludum Dare here:

https://ldjam.com/

So the Bfxr is a simple noise generator that can produce pleasing sounds effects reminiscent of classic 2D games of the past.

It consists of a simple interface that you can play with and an export function to save your sounds out in various sound formats. The best way to see it in action is to download it and play with it yourself, its free and you can find it here:

https://www.bfxr.net/

You can use Bfxr to create loads of simple effects using the various synth waveforms available, these are selected on the top middle of the interface.

You can start off by clicking on one of the pre-sets on the left of the screen, this will give you a source sound to build upon. You can then manipulate the many sliders to change the characteristics of each sound.

Changing the various sliders you can customize the pre-set further, each time you click on a new sound it will create a new instance.

If you edit or change any of the sliders it will mark that instance with an asterisk indicating its been modified, if you are not happy with the sound you can delete it using the “X” button to the side of each sound instance.

When you have finished creating your sound and are happy with the result select it from the list and then export as a wave.

Here are some of the sounds I created using Bfxr for this tutorial:


The next program we are going to be using is a soft synth called WebSID.

WebSID is a web based soft synth that you can use to create effects an music for your game, again it is more suited towards a 2D style aesthetic

It can be found at the following link:

https://www.igorski.nl/application/websid/

If you were born the in the eighties you may have owned a Commodore 64 this is what the WebSID synth is based on. The SID chip was the sound chip that the C64 used and was very popular, and still is, for creating chip tune music and sound effects.

WebSID provides a keyboard UI that you can use, either by triggering with the mouse, or by using the keys on your keyboard and associated numbers displayed on the screen UI.

It is also enabled for touch screen so if you run the web app from a touch screen enabled device, such as mobile phone or tablet, it becomes a lot easy to create tunes using you fingers to create chords, trigging multiple keys at once.

You can use it to create simple sounds or more complex melody variations depending on your needs.

You can also change the amplitude and filter envelopes to change the texture of you sounds over time, also you can add echo to add even more texture and space to your effects.

Here are some sounds I created using WebSID:

You can save your music and effect and share the link through the web app, but i found it easier to simple record straight to my computer using Audacity.

Audacity is a great free program which is a lot like Adobe Audition and many other DAWs. It allows you to record and edit audio and export in various formats including WAV and MP3.

You can find Audacity here:

audacityteam.org


Classic Video Game Sound effects

For the next example I will be using a cheap Casio keyboard I picked up from a local charity store and use it to create my sound effects for my game.

The Keyboard I am using is the classic Casio SA-1

This is a very affordable keyboard and I found it for a mere £10

I am also using a Mixer that I own which cost me £70, you don’t need this and can just plug the auxiliary lead straight into your computer. Having the mixer just allows me to add external compression and equalisation to the sound source.

Using the Casio in combination with Audacity lets you create some pretty call sounds. The advantage of having and external keyboard like this is you can get very tactile and instantly access a plethora of 80’s style retro sounds.

Many of these old keyboards already sound great right out of the box and are often very usable from the get go.

Having a soft synth combined with a midi keyboard you can emulate this set up with plugins, but I like using external keyboards as sometimes they have there own character and timbre.

Here are some of the sounds I created using the Casio SA-1

Compressing Your Sounds

When creating a sound for your game you may want to think about compression. In audacity you can export to MP3 and OGG both provide advantages for compressing sound, although many believe OGG to be superior in sound.

You can also change the sample rate of the sound, this is sometimes used to emulate a specific sound quality from and older game rather than and option for saving memory, but it will still have the result of reducing the files memory size too.

How do I Add Sound to Unity?

By now you probably have some sound effects you have created with one of the options we have laid out above. You probably now want to take those sounds and add them to your game.

For this example we are going to be using Unity:

Start by opening a new Unity project and create a new folder in your asset folder called Sound Effects.

Now you can simply drag the files from the original folder view over into the sound effects folder in your Unity project and hey presto they are now part of your asset library.

Hope you enjoyed this short tutorial on creating you own sound effects for your games, there are many options out there for creating you own sound effects, this was just a small selection.

Another option we didn’t explore was to record you own ambient sound effects using a microphone using real world objects and items to create your effects with.

For now I will leave it here, hope you enjoyed this tutorial. If you found it useful in any way please take a look at some of my other tutorials below.

]]>
Using Blender For Asset Creation https://indieprogramming.com/using-blender-for-asset-creation/ Thu, 28 Apr 2022 20:31:12 +0000 https://indieprogramming.com/?p=2973

So if you are an indie developer and are considering using blender to create your 3D assets, the question you are probably wondering is, can I use blender for my game? And will I get good results that are comparable to other software like Studio max, Cinema 4D and Maya.

The answer to that question is a resounding yes.

This discussion may have been different a few years ago when Blender was still busy trying to catch up to it competitors, but now with the last few iterations it has enough features, tools and options of its own to directly match its mainstream siblings.

So in a nut shell Blender is more than capable of creating asset for games, movies or any other projects you need it for.

Is Blender Free

Blender is 100% free and will remain this way forever. The GNU license (General Purpose license ) states that you are able to circulate, copy an use Blender in any of your own projects.

Blender has a large and supportive community that is filled with free tutorials, assets and guidance, you’ll find it through the main site here Blender.org

Blender market place is another great place to pick up free and premium tutorials projects and addons.

https://blendermarket.com/

Can I use Blender to Create my Games Assets?

The answer to this is as you have already figured out is yes and many people are already doing it, I would say that a big chunk of indie developers have used it, past and present, to create their titles.

Blender is used increasingly within the game and movie industry whether you are a small indie studio or a big studio on a budget, nowadays it is ubiquitous in the indie scene.

To find a list of games that have been made using blender, take a look at the “Made With Blender” itch.io page below:

https://itch.io/games/made-with-blender

How do you Create Assets in Blender

It super easy to create something in blender especially since the release of Blender 2.8 and its super shiny interface. Currently as writing this the newest version is Blender 3.0.1

Start off by downloading Blender at Blender.org and start grouping some primitive shapes, combining them to make a simple character. It doesn’t have to be complex it can be as simple as you like.

When you open a new scene in Blender you can choose to use the default cube to create your asset, or you can delete it using the x button and then select another mesh of your choosing using the Shift A shortcut menu.

From here you can choose from a list of primitives and use them as the base for your character design.

You can create quite complex shapes and meshes by editing these primitive shapes further, but in this case we are just going to group the shapes together to form a simple game asset.

You will see in the below picture how I grouped the primitive shapes together.

Even though the above mesh may look pretty basic, if you are looking at it far away in a scene it may just do the job perfectly.

This design could be perfect for a simple mobile game where the camera is above and at an angle.

It may be that your core gameplay mechanic is the hook and the graphics can be left simple, this is prescient in a lot of casual games that are based on physics and don’t rely on pretty graphics.

Quick character creation can also be very useful for templating scenes, gameplay mechanics or physics simulations.

Blender to Mixamo


Now we have a simple asset we need a simple way to animate our character and enable it to respond to the user input.


A great free browser app for doing this is Mixamo you can find it below:

https://www.mixamo.com/#/

Mixamo allows you to import your game mesh and quickly rig and animated you object, then afterwards you can export them back out to a game engine or back into Blender.

You start off by saving the game object in blender and exporting it in an .obj format, you can then load it in to mixamo ( You do need to create an account first )

To create a simple rig you just drag the circles over your mesh, making sure to line them up with the appropriate body part, then all you do is click on next. The browser software will then process the control points and auto rig the mesh.

After this you can export the model back into blender which now has a rig associated with it, you can skip this part and load it straight into Unity or Unreal, if you wanted to make any other edits to the mesh you can import back into blender.

For this example I have imported it back into Blender to test the animation.

Now you can animate the object by pressing play in the dope sheet or space bar shortcut if set up.

Can Blender Open OBJ Files

Yes you can open them by using the file menu, then just import in as a Wavefront (.obj).


You should then see the object in the project view:

Whats is the Difference Between OBJ and FBX

An .obj file is more simpler than an FBX and keeps the main important stuff like the position of each vertex, UV texture co-ordinates, and vertex normals.

The FBX file will hold those and extra things like scene data, including cameras and lighting.

If you are using a game engine such as Unity or Unreal you can import both FBX and OBJ files.

Blender to Unity

Now most indie developers work primarily with the Unity game engine, this is because it has a user friendly interface and options for both C# and event scripting.

To export you mesh object into Unity you can save you model as either an FBX or OBJ, in this instance we are going to be exporting as an OBJ

Before you do this its an idea to check you model to make sure its ready for exporting, first you want to make sure the normals are facing in the right direction.

The reason you want your normals facing in the same direction is so the shading on your mesh is consistent, if you look at your mesh after rendering and see issues then its probably time to fix your normals.

To do this select the overlay menu and then the face orientation, see below:

As you can see some of the faces are red and some are blue, the blue means they are facing outwards when they are displayed as red they are facing inwards.

So some of my faces are pointing inwards, this can be down to many reasons. In this example i would reason it was down to how I modified the mesh during the editing process. I may have moved and scaled it in a direction or somehow inverted the faces unintentionally.

We can remedy this by tabing into edit mode and selecting normals/ recalculate outside from the mesh menu.

Now they are all pointing the same way, you can see this in the above image as they all appear as blue now. This is a good visual way of checking you mesh.

So as mentioned before we will export out our model as a Wavefront OBJ file ( its called this because the original file structure of the OBJ file was created by Wavefront technologies )

Now be sure to select the mesh we are working on, you can do this by selecting “selection only” tick box ( see below ) in the export screen.

Now open up your version of unity and create a new game and scene, from here we can simply drag our obj file directly into our asset folder like so:

From here you can drag it into the scene, as you can see all our normals are facing the right way and there is no warping or bad geometry present in the mesh.

This is a very simple workflow for create a character in blender and exporting it to other programs such as Mixamo and Unity.

You can make very complex characters and take more time exporting and animating your designs, but this tutorial just showcases a few of the options available and some of the things to look out for when importing and exporting your meshes.

Hope you enjoyed this tutorial and look out for some more of my blog post below.

]]>
Making Games Using Html5 with JavaScript https://indieprogramming.com/making-games-using-html5-with-javascript/ Sun, 15 Aug 2021 21:33:12 +0000 https://indieprogramming.com/?p=2485
HTML5 Asteroid Game

In this tutorial we are going to be using HTML5 with JavaScript to create the classic asteroid game from the late 1970s.

Now even if you weren’t around during its release in 1979 you would have probably still heard of Asteroids or at least understood the impact it had at the time of release.

The game gives you control of a small ship surviving in an asteroid belt destroying as many asteroid waves as possible.

Asteroids as a game is very simple, but at the same time hugely addictive and fun to play, it has it has a satisfying game mechanic and capitalizes on it.

Many casual games today rely on a similar methodology to create there games, for example voodoo, one of the biggest mobile game producers in the world, often tells its creators to “keep it simple”.

If you are into creating simple but addictive games for mobile devices it would be wise to keep this in mind in you own endeavors.

So for this tutorial we will be re-creating this classic using the popular trio of HTML, CSS and JavaScript. Lets begin…


How do I make a game with HTML

In order to make our HTML5 game we will need the following:

  • Notepad/++, TextEdit ( or equivalent )
  • Basic understanding of HTML and CSS
  • Intermediate understanding of JavaScript
  • Web browser, preferably Chrome

We will start by creating our directory and folder structure for our game.

We first create a folder called Asteroids, within this folder we will have the three files we need and another folder for our images.

The three files within this primary folder will be our HTML file, our CSS file and our JavaScript file, each will need to be saved with the appropriate extension.

  • HTML (.html)
  • CSS (.css)
  • JavaScript (.js)

This is what our folder structure will look like:

The images folder will contain all the sprites we need for our game, it is wise to keep the images separate as they can soon clutter up the main folder if you don’t.

Here are the four images we have in our images folder:

We have an asteroid that we will use for all our asteroid game objects, we have a flame for the ship engines, we have our ship and finally our space background.

Here are the files:


The HTML5 Canvas

We will start of creating the container for our game, this is just a simple HTML document that holds the minimal amount of HTML markup to make it a compliant web page, plus a canvas element within the body of the document.

This looks like the following, notice the links to our other external CSS and JavaScript files.

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Asteroids</title>
	<link rel="stylesheet" href="asteroids.css" />
	<script src="asteroids.js"></script>
</head>
<body>
	<canvas id="gCanvas" width="512" height="512"></canvas>
</body>

</html>

The main star of the show is this line <canvas id=”gCanvas” width=”512″ height=”512″></canvas>

Most of the work we will do in the following JavaScript to come will be manipulating this one element.

We save this file as asteroids.html

The next file to look at will be our CSS file:

body {
	background:#000;
}
canvas {
	background: #fff;
}

This will be the smallest of the files, containing just two selectors, one for styling out document body and the other styling our canvas element.

We use it to make our document background color black and out canvas white. This will change later but we just want to make sure our CSS file is connected to our HTML file once the browser loads.

We save this file as asteroids.css

The last file, our JavaScript, will be the most important, it is where we will be creating all the behavior for our game, for now we will just initialize it with the following code:


window.onload = function(){
 
    window.alert("Hello from your computer")
}

This uses the windows method window.onload() this will simply make sure the document has loaded before it runs the code inside the function.

We then call the window.alert() function which will display an annoying window pop up when we load out HTML file.

Open up the HTML file in your browser and you should see the greeting from you computer, you should also see that the canvas is white an the background is black.

This shows us that all our files are linked, great!

If you are having problems check that you have put the two links to the files in the header of you HTML file, see below:

<link rel="stylesheet" href="asteroids.css" />
<script src="asteroids.js"></script>

Now we have the canvas setup we want to start drawing to it, this is relatively quick and easy to do with the following code in the JavaScript file.

var canvas = document.getElementById("gCanvas");
var ctx = canvas.getContext("2d");

We place these first two statements in the window.onload function and these give us access to the the canvas and its context.

I save the reference to the 2d context within the variable called ctx, you could name the variable anything but ctx works fine and saves you having to type context each time.

We can now test the drawing context works by drawing a little square in the center of the canvas:

ctx.fillRect(canvas.width/2-25,canvas.height/2-25,50,50); 

We get the canvas width and height properties and divide it by two and minus half the squares width and height from it, we then draw the width and height of the square at 50 pixels.

Open up the browser and you should get a square centered in the middle of the screen.

Now this is fine and dandy, we have a square that has a position on the screen and a size but we cant really do anything with it.

We need to be able to create a character with parameters and values that we can change over time.

We will do this by creating a constructor which will contains properties for our character that we can initialize at runtime.

Here’s what the code looks like:

 function Ship(x,y,w,h){
        this.x=x;
        this.y=y;
        this.w=w;
        this.h=h;
        }             
                
    Ship.prototype.draw=function(ctx){
        ctx.save();
        ctx.strokeRect(this.x,this.y,this.w,this.h); 
        ctx.restore();     
    }  

We create a constructor called Ship that will take an x, y, w and h parameter as arguments.

Using this we can create a ship of any size or position we want by adding it in the functions arguments.

We then add a prototype method to the constructor call draw() this will be in charge of drawing the ship to the screen, taking the ctx as an argument.

At the moment this is just a square, but later on it will be our ship object.

We use the this keyword in the constructor to reference back to the object we are creating and the properties within it.

We can now use this constructor to create our game objects with two simple statements:

var ship = new Ship(canvas.width/2-25,canvas.height/2-25,50,50);

ship.draw(ctx);

We create a variable to contain a new instance of the ship object, we call this ship.

We then feed in the arguments like before to center the object in the middle of the screen.

Now we can simple call the draw method inside that object to draw it to the screen.

Refresh the browser and you should see another square object this time using the strokeRect() method rather than fillRect().


Simple JavaScript Animation

So the next thing we want to be able to do is make our player, or square, move.

We will do this by first creating a game loop, then we will animate the square moving it from one side of the screen to the other by manipulating its x and y coordinates.

 function update(){
        window.requestAnimationFrame(update);
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ship.draw(ctx);
        ship.x+=1;
    }

    update();

So the above code is the update function, this will be used to iterate through our game scene.

We use the window requestAnimationFrame() method and simply provide the update function as argument.

The requestAnimationFrame() with be integral for creating and calculating all movement for our game objects.

We use the ctx.clearRect() method to clear the canvas on each frame, we provide the canvas origin followed by the canvas.width and canvas.height.

We take the ship.draw() call and put it inside the update function, after this we move the square with the following statement.

ship.x+=1;

This is taking the ship.x property and adding 1 pixel to it on each frame iteration.

Lastly just at the bottom of our code we add the call to the update() function.

Now if you reload the browser you should see the square move from one side to the other.

Adding the Ship Image

We are now going to swap out our square for our space ship image. To do this we make a few changes to our draw method:

We start by creating a reference to our ship image:

 var shipIMG = new Image();
 shipIMG.src="images/ship_side.png";

We use the new Image() method to create our image object, we then set the image URL to point to our images folder and its respective image.

Make sure to include the image type of you file after the name, in this case its a PNG.

Next we make a change to the draw method adding drawImage() rather than the fillStroke() method we used before.

Ship.prototype.draw=function(ctx,image){
        ctx.save();
        ctx.drawImage(image,this.x,this.y,this.w,this.h); 
        ctx.restore();     
};

We add the image argument to the method and feed it our ship image in the call to the ship.draw() in the update function.

ship.draw(ctx,shipIMG);

Also for now we want to take out the ship.x+=1; statement so it doesn’t move, don’t worry as soon we will be controlling the movement based on player input.

Refresh the browser and you should see our space ship, a lot better than our square I’m sure you will agree.

Lets change the size of the ship making it 64 by 64 pixels in size.

 var ship = new Ship(canvas.width/2-32,canvas.height/2-32,64,64);

Now we want to create the background for our game, this will include creating a new image object and drawing it using the context draw Image method within the update function.

First reference the image:

var spaceIMG = new Image();
spaceIMG.src="images/space.png";

Then we draw it in the update function, we aren’t going to create a constructor or object for the background as it will just be static and doesn’t really need any properties other than just to be drawn to the screen.

ctx.drawImage(spaceIMG,0,0,canvas.width,canvas.height)

Adding Player Input

Now we are going to create some simple rotational movement, later we will add thrust, but for now we will focus on rotation.

We will start by creating a global variable called rotationalVelocity and initialize it to 0.

var rotationalVelocity =0;

Next we also add 3 more properties to our constructor function:

this.hw = this.w/2;
this.hh = this.h/2;
this.rotation=rot;

We add a half width and half height properties which just take the current width and height and divide it by 2. We then also add a rotational property to our ship constructor.

We then also add the rot parameter to the functions argument list.

function Ship(x,y,w,h,rot)

We also add the rotation value when initializing our ship object.

Ship(canvas.width/2-32,canvas.height/2-32,64,64,0);

Next we modify the draw method to allow us to rotate our sprites, we use the ctx.translate canvas method to move our drawing context to the current sprite’s position, in this case our ship.

ctx.translate(this.x+this.hw,this.y+this.hh);
ctx.rotate(this.rotation);
ctx.translate(-(this.x+this.hw),-(this.y+this.hh));

Ordinarily the origin is set at the top left of the canvas, we will move it to the center of the ship image by referencing the ships x position plus its halfwidth and its height plus its half height. this will give us the center of our image.

Next we use the rotate method and feed it this objects rotation property value, then we reverse the translate to put the drawing context back to the origin.

This ensures our ship pivots round its center point first and then returns the origin to the canvas when drawing the image.

Next we want to listen for player input, we do this with the following:

window.addEventListener('keydown', function(event){
        switch (event.keyCode){
            case 37: //left
            rotationalVelocity =-3;
            break;
            case 39: //right
            rotationalVelocity =3; 
            break;
           }
        }, false);
            window.addEventListener('keyup', function(){
            rotationalVelocity =0 
        }, false);

We use the window.addEventListener() method and set it to listen for a ‘keydown’ event, the second argument is and anonymous function which will fire as soon as we trigger the event.

Inside the anonymous function’s argument we add a reference to the event array using the keyword ‘event’

'keydown', function(event){

Inside this event listener we add a switch statement, the switch statement will test for each of our key down events. Inside the switch argument we reference the event array and find the keycode which was fired.

switch (event.keyCode){

We check it on a case by case basis, adding extra ones depending on what keys we want to check for, to start with we will be checking for keycodes 37 and 39.

These keys relate to the left and right arrow keys, these will either add 3 or minus 3 to our rotationalVelocity variable.

Lastly we add the corresponding key up event which will set our rotational velocity to 0 stopping our ship rotating when we release the key.

Now we have done all this we now want to create a function that will actually move the ship.

var Move = function(obj){
    	obj.rotation += rotationalVelocity * Math.PI /180;
    	var angle = obj.rotation;
}

This function will take in an object(obj), in this case our ship game object, and we add the rotational velocity to our objects rotation property.

Lastly we add the move ships function call in the update function:

Move(ship);

Now you should be able to rotate your ship all the way round.

Enhancing our Game Movement

Now we can rotate our ship 360 degrees we have the ability to shoot at the asteroids coming from all sides of the canvas.

This is great, but the original asteroids allowed you to move out of your center point and fly around the screen using your thrusters.

Lets have a look at how we can add thrusters to our ship to allow us to do just this.

We will start by creating two new global variables

var thrust =0;
var thrustsOn =false;

We also add a few more properties to our constructor function. these will be:

 this.vx=vx;
 this.vy=vy;
 this.ax=ax;
 this.ay=ay;

These properties refer to the Velocity (vx, vy) and the Angular Acceleration (ax, ay) of our ship. We will use use these properties for controlling the thrust direction of our player.

The Velocity and Angular Acceleration will be a vector, with thrust being a scaler value that we will add to it on each frame.

Then we also add the corresponding arguments to our ship constructor object:

function Ship(x,y,w,h,vx,vy,ax,ay,rot){}

This also means we also have to add the the parameter when we create the new object, for the time being we will initialize the Velocity and Acceleration to 0.

var ship = new Ship(canvas.width/2-32,canvas.height/2-32,64,64,0,0,0,0,0);

We want to now modify the key down and key up listeners.

We want to turn on the thrusters when the player pushes the up arrow key and turn the thrusters off when they release the key.

We add the following code to our keydown and keyup event listeners:

 case 38:  //thrust
 thrust =0.05;
 thrustsOn = true;
 break;
window.addEventListener('keyup', function(){
       rotationalVelocity =0; 
       thrust=0;
       thrustsOn = false;
}, false);

We firstly add a case to the switch statement which listens for the up arrow key which is mapped to value 38.

This will add 0.05 to our thrust variable on each frame that it is pressed, we also turn the thrustsOn Boolean variable to true.

On the key up listener we turn the Boolean flag to false and set the thrust variable to 0.

Now we have to have a way to translate our key up thrust input into an angular velocity that can move us forward, this will be done in our Move() function.

Forward is going to be relative to which way we are facing at the time we press it, we can’t just add some arbitrary value as this won’t work.

We start by getting the angle of our ship witch, we already know from our ships current rotation value.

This is based on our global rotationalVelocity variable, as we are setting this value when we hit our left and right keys and then setting it to the ships rotation on each frame.

obj.rotation += rotationalVelocity * Math.PI /180;

We want to take this angle and use it to define the angular acceleration we then want add this to our velocity x and velocity y properties. This is done with the following code:

var Move = function(obj){//
    obj.rotation += rotationalVelocity * Math.PI /180;
    let angle = obj.rotation;
    obj.ax = Math.cos(angle) * thrust;
    obj.ay = Math.sin(angle) * thrust;
    obj.vx+=obj.ax;
    obj.vy+=obj.ay;
    obj.x+=obj.vx;
    obj.y+=obj.vy;
}

You may notice this function has got a lot bigger, lets break it down and have a look at what’s happening.

Firstly as before we add the rotationalVelocity value to the objects rotation, in this case our ship, we then create a block scope variable using the let keyword.

Using let rather than just a var means it can’t be referenced outside of the curly braces its defined in.

Next we use two JavaScript math functions to get the cosine and sine values based on the angle we feed into them.

This will return a fraction that we can then multiply by our scaler thrust variable, this is all assigned to our obj.ax and obj.ay properties on each frame.

By referencing the angle on each frame the value will change because we are changing the value of our rotation on each frame using our arrows keys.

This will mean each time the cosine and sine functions are calculated the fraction will also change, therefore matching our angle of rotation.

This will also mean that the up arrow key will always thrust our ship forwards based on the angle set by the left and right arrow keys.

So lastly we want to add the angular acceleration to the velocity and then the velocity to the x and y positions of our ship.

obj.vx+=obj.ax;
obj.vy+=obj.ay;
obj.x+=obj.vx;
obj.y+=obj.vy;

Reload the browser and you should be able to turn in any direction and then thrust forward in the direction you are facing.


Check Boundaries

We now have a ship that we can fly around the screen, trouble is once we fly off screen we can no longer see the ship, and have no way of navigating it back to our canvas.

In order to keep it in bounds we want to create a rule to push the ship back on to the canvas in some way each time it hits the corner of our game screen. Here is the code:

var ShipBounds =function(obj){
       if(obj.x > canvas.width){
               obj.x = 0-obj.w;
       }
       if(obj.x+obj.w < 0){
               obj.x = canvas.width;
       }
       if(obj.y > canvas.width){
               obj.y = 0-obj.h;
       }
       if(obj.y+obj.h < 0){
               obj.y = canvas.width;
       }
}

This function takes an object as an argument, it then checks for when the ship is leaving the boundaries of our game field.

It first takes our objects x value and checks if its more than the canvas width, if it is it with change the ships x position to be the far left of the canvas, minus the ships width.

Then we check if the ship x value and its width are less than 0, if they are we push the ships position over to the far right of our screen

We then repeat these same calculations for the y position dealing with the vertical position (y) rather than the horizontal (x)

Now you should be able to fly off any side of the canvas and appear over on the opposite side, this is also faithful to the original Asteroid game.

We mustn’t forget to add the function call to our update loop:

ShipBounds(ship);

Adding Flames to our Thrusters

Next we will be adding an on and off flame effect that will appear when we press the up arrow key. This will be set to display when the thrustsOn Boolean variable is true.

Lets add the flame image object to our code;

var flameIMG = new Image();
flameIMG.src="images/flame.png";

We already have the thrustsOn variable setup and in place so all we need to do is slightly modify the draw method.

ctx.drawImage(image,this.x,this.y,this.w,this.h);
     if(thrustsOn){
            ctx.drawImage(flameIMG,this.x-20,this.y,20,20);
            ctx.drawImage(flameIMG,this.x-20,this.y+this.h-    20,20,20);
                }   
ctx.restore();  

We create an if statement that checks for the thrustOn Boolean, this will allow us to either display the flame or not depending on the state of the Boolean value.

We then create two draw image calls and add the same flame image to both of them, we offset the positions of the flames to appear behind the ship, next to were our engines would be.

Refresh the browser and you should now have a very simple animation of some thrusters.

You can create particles system in JavaScript but sometimes just a simple effect like this can be enough to get the point across.


Creating the Asteroids

Now it wouldn’t be a remake of the classic game if it didn’t include any asteroids. Tts all very well being able to fly around the screen, but with out a purpose our game will get boring very quickly.

So the original Asteroids game had you shooting at asteroids flying in from different angles of the screen, when you shoot them they then separate into smaller steroids that then fly off in their own directions.

Using these parameters we can set up our asteroid field fairly simply.

We will start by creating our asteroid array and a variable to hold the number of asteroids we want to display to the screen at one time.

var numberAsteroids =5;
var asteroids =[];

We are also going to create our Asteroid constructor:

function Asteroid(x,y,vx,vy,radius,rotation,angle){
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.radius=radius;
        this.ax=0;
        this.ay=0;
        this.rotation=rotation;
        this.angle=angle;
 }       
 Asteroid.prototype.draw=function(ctx){
        ctx.save();
        ctx.translate(this.x,this.y);
        ctx.rotate(this.rotation);
        ctx.translate(-(this.x),-(this.y));
        ctx.beginPath();
        ctx.fillStyle="white";
        ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
        ctx.fill();
        ctx.fillStyle="black";
        ctx.moveTo(this.x,this.y);
        ctx.lineTo(this.x+this.radius,this.y)
        ctx.stroke();
        ctx.restore();     
 }   

So most of the above shouldn’t look too different from the player object we created earlier, there are a few differences though.

We have a couple of extra properties, these being the radius and angle property.

The draw prototype method is going to be using the context’s arc() method as we are going to be drawing a circle for the asteroid to start off with and then adding the image later.

The reason for this is that it will easier to set the rotation of the circle as its origin is the center point and also where its from drawn.

We use the ctx.beginPath() to create a closed arc.

This method has a lot of parameters similar to the drawImage() method, but also contain a few more of its own.

The first arguments are the x and y coordinates, this is where want the center point of the circle to start, next is the radius, this will control the size of the circle.

Next we set the arcs starting point to 0 and extend the arc a full circles circumference, to do this we use the Math function Math.PI and times it by two.

2*Math.PI

This just so happens to be a complete circle.

We also create a line from the center of our circle out to its radius, this will better show our rotation when we apply them.

This takes care of our constructor now want to create our asteroids.

To do this we will make our createAsteroids() function, this will run once at the start to set the initial start game state:

 var createAsteroids = function(){
                for(var i =0; i <numberAsteroids; i++){
                        asteroids.push(new Asteroid (Math.random()*canvas.width,Math.random()*canvas.height,
                                0,0,50,0,0));
                }
        }

This function will iterate a set amount, in our case we feed it our numberAsteroids variable. As we set the variable to 5 it will iterated 5 times through creating 5 asteroids.

On each iteration it will load a new Asteroid object in to the asteroids array.

We feed it a random position on both the x and y within the confounds of the canvas area, we leave the vx an vy values at 0 add a radius of 50 . For now we leave the rotation to 0.

This function needs to run once at the start of the game outside of the loop, because if we run it within the loop it will continue to populate the asteroid array repeatedly on every frame.

This will end up crashing the game.

In order for this to run once we will want to create a separate function called start() this will first load our createAsteroids() function then after that will kick off the update() function.

function start(){
    createAsteroids();
    update();                      
}

This will allow anything that is in the initial setup to be loaded first.

We then replace the call to the update() function at the bottom of our code and change it to the start() function.

We then create the drawAsteroids() function to draw all of our asteroids to the screen, for the moment this will just be our circles.

var drawAsteroids = function(obj){
       for(var i =0; i <obj.length; i++){
            obj[i].draw(ctx);
       }
}

This function will simply loop through out obj which in this case will be our asteroid array and draw each asteroid object to screen.

drawAsteroids(asteroids);

Now we just have to add the call to the drawAsteroids() function inside the update function.

You should see something like the above, each time you refresh the browser the asteroids will be created in different random position.

You will see the lines representing the angle of our asteroids are all current the same, this will change later when each has it own starting angle set.

So that’s great we have the asteroids appearing in random positions covering the width and height of our canvas.

Now we want them to move with angular velocity applied and we also want them to rotate around their center point, this will make them look more like rotating asteroids.

So we have our Asteroids ( white circles ) we now want to be able to move them around the canvas.

We will do this with the MoveAsteroid() function, this is what that looks like:

var moveAsteroids = function(obj){
        for(var i =0; i <obj.length; i++){
             obj[i].ax = Math.cos(obj[i].angle) * 0.5;
             obj[i].ay = Math.sin(obj[i].angle) * 0.5;
             obj[i].vx=obj[i].ax;
             obj[i].vy=obj[i].ay;
             obj[i].x+=obj[i].vx;
             obj[i].y+=obj[i].vy;
             obj[i].rotation +=0.01;
        }
}

So we iterate through each element in the obj array and set the angular velocity using the Math cosine and sine function, adding the result to ax and ay on the way.

We will hardcode the speed scalar value of the asteroids to an arbitrary number of 0.5, for now we will just give all the asteroids the same speed.

We then the add the value to the velocity then the velocity to the position on each frame, we also iterate the rotation of the asteroids to spin it round as it moves.

Lastly we add the moveAsteroids() function to the update() call list.

moveAsteroids(asteroids);

So now when you refresh the browser you will see that they indeed do move, and they rotate like we hoped they would.

The next problem to solve is, how do we get them to rotate at different angles? You can see by the radius line that they are all spinning from the same angle.

To change this we will first create a simple function call randomAngle()

var randomAngle = function(){
      return Math.random() * Math.PI * 2;
}

So this function will return a random value between 0 and PI *2, in effect this will give us pretty much any angle in 360 degrees.

We will now use this to set our asteroid’s starting angle in the CreateAsteroid() function, this is where we originally initialize out asteroids.

asteroids.push(new  Asteroid(Math.random()*canvas.width,Math.random()*canvas.height,
                0,0,50,randomAngle(),randomAngle()));

So we plug this function call into the rotation and angle parameter we use to control the rotation and angle of velocity.

This instantly changes things, when you reload the browser you now have asteroids going of in different directions and each with a different start angle.

The radius line on each circle gives you a good indication of each asteroids rotational angle.

Now although they are all rotating in the same direction the different starting angle is providing some variation.

You can if you wish add more asteroids to the playing field by simply adjusting the numberAsteroids variable.

Asteroid Boundaries

So lets create a function to flip the asteroids when they move off screen, much like we did with the ship object.

var AsteroidBoundaries = function(obj){
            for(var i=0; i<obj.length; i++){
                if(obj[i].x + - obj[i].radius > canvas.width){
                        obj[i].x = 0 -obj[i].radius;
                }
                    if(obj[i].x + obj[i].radius < 0){
                        obj[i].x = canvas.width + obj[i].radius;
                }
                    if(obj[i].y + - obj[i].radius > canvas.width){
                        obj[i].y = 0 -obj[i].radius;
                }
                    if(obj[i].y + obj[i].radius < 0){
                        obj[i].y = canvas.width + obj[i].radius;
                }
            }
    }

This is almost identical to the ship boundaries function, the only difference is its referencing the array object and also deals with the radius rather than the width and height of the object.

Add this call to the main loop and you should have floating asteroids with boundary rules applied.

AsteroidBoundaries(asteroids);

Adding the Asteroid Images

We can actually now just add some images to our asteroid objects simply by creating another draw method that will draw an image over the top of it.

We already have all the positional information for the asteroid including its velocity and rotation from the object properties.

By drawing them over the top we can still utilize the information from the ship object and all the changes applied through draw() and move() function calls that we applied.

We start by adding another image object to our code:

var asteroidIMG = new Image();
asteroidIMG.src="images/asteroid.png";

We then add another method to the Asteroid object this time it is a drawImage() method.

Asteroid.prototype.drawImage=function(ctx,image){
        ctx.save();
        ctx.translate(this.x,this.y);
        ctx.rotate(this.rotation);
        ctx.translate(-(this.x),-(this.y));
        ctx.drawImage(image,this.x-this.radius,this.y-          this.radius,this.radius*2,this.radius*2);
        ctx.restore();     
} 

Much like the draw method this translates to the center of our object and then reverts back and draws the image to the canvas

In the drawAsteroids() function we add the call to the drawImage() method this will draw the image to the screen.

Update the browser again and you should see some asteroids drawn over the top of our circles, you can now just comment out the original draw method and now you will just see the asteroid images on there own.

 //obj[i].draw(ctx);
   obj[i].drawImage(ctx,asteroidIMG);

Adding Lazers to our Ship

Now we have our asteroid and our ship we want to be able to fire something at the asteroids to destroy them. This is were our Lazer object comes in.

We want to create a lazer that will move forward from our ships location when we strike the space bar.

We will do this by first introducing two more global variables, these are:

var fire = false;
var lazers =[];

The first variable will keep track of whether or not our lazer has been fired, this will be trigged in our key listener along with the other key input.

Now we want to add the Lazer constructor:

function Lazer(x,y,vx,vy,radius,rot){
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.radius=radius;
        this.ax=0;
        this.ay=0;
        this.rotation=rot;
        }
        Lazer.prototype.draw=function(ctx){
        ctx.save();
        ctx.translate(this.x,this.y);
        ctx.rotate(this.rotation);
        ctx.translate(-(this.x),-(this.y));
        ctx.beginPath();
        ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
        ctx.fillStyle="yellow";
        ctx.fill();
        ctx.restore();     
        }   

Next we want to add one more case in the key down switch statement, this will check for the space button being pressed.

break;
case 32: //space 
fire =true;
break;

This will simply change the fire Boolean variable to true. We must remember to put the inverse statement in the key up switch.

fire = false;

Now we have these variables set up we want to use them to add our lazer objects to out lazers array.

var shoot = function(obj){
            if(fire){
                    if(lazers.length <1){
                            lazers.push(new Lazer(obj.x+obj.w/2,obj.y+obj.h/2,0,0,5,obj.rotation));
                    }
            }
}

This shoot function checks first if the fire variable is set, then it checks if the lazers array length is less than 1.

This will mean we can only shoot one lazer at a time, don’t worry this is all we will need.

Once these two if statements have been met we will push a new Lazer object into he lasers array.

The thing that will do most of the work will be the following updatesLazers() function:

  var updateLazers = function(){
            for(var i=0; i<lazers.length; i++){
              
                lazers[i].ax = Math.cos(lazers[i].rotation) * 0.3;
                lazers[i].ay = Math.sin(lazers[i].rotation) * 0.3;
                lazers[i].vx+=lazers[i].ax;
                lazers[i].vy+=lazers[i].ay;
                lazers[i].x+=lazers[i].vx;
                lazers[i].y+=lazers[i].vy;
          
                lazers[i].draw(ctx);
            }
    }

This is very similar to our Move() function, it loops trough the lazers array and then calculates its movement based on its rotation, this rotation is set when it created in out shoot function.

The rotation is based on the ships current rotation at that time.

We add all the positional data together finally adding it to the x an y position, in this instance we also combine the draw method call in this function too.

We then make sure to add the calls, as before, to the update function

 updateLazers();
 shoot(ship);

We want to add the updateLazers() function call before the call to the ship.draw() method, this will make sure the bullet is drawn underneath the ship sprite.

So now we can shoot a single bullet from our ship, trouble is when the lazer travels of screen it will carry on going and because of the way the if statement is set up we can only have one bullet on screen at once.

Lets create the destroyLazers() function:

 var destroyLazers = function(obj){
            for(var i=0; i<lazers.length; i++){
                    if(obj[i].x > canvas.width ||    obj[i].x+obj[i].radius < 0 || 
                            obj[i].y > canvas.width || obj[i].y+obj[i].radius < 0){
                            lazers.splice(i,1);
                    }  
            }
}

This function is simply a boundary check, this time rather than changing the objects position it will splice the object from the lazers array, this essentially means deleting the element from the array.

The first argument in the splice method take the position of the element in the array, this will be the element indicated by the current index, the second is how many elements its going to affect, in this case 1.

Add the destroyLazers() function to the update method and refresh the browser, you should now have a fully function ship with lazers.

 destroyLazers(lazers);

When the lazers go of screen you are able to fire again, recycling game elements like this saves on memory and therefore will optimize you game.

Destroying Asteroids

So we have the ability to shoot, but our lazers goes straight through the asteroids having no effect on them.

We want to create a hit test that checks for a circle based collision between the lazer object and our asteroids.

As we are going to be creating small asteroids once the bigger asteroids are destroyed we will start by creating a smallAsteroids[] array to hold them in.

var smallAsteroids =[];

This is what the collision function looks like:

var asteroidBulletCollision = function(asteroid,lazer){
         for(var i=0; i<asteroid.length; i++){
            for(var b=0; b<lazer.length; b++){
                var dx = asteroid[i].x -  lazer[b].x;
                var dy = asteroid[i].y -  lazer[b].y;
                var distance = Math.sqrt((dx * dx) + (dy * dy));
                if(distance < asteroid[i].radius + lazer[b].radius){
                    if(asteroid[i].radius <12){
                        asteroid.splice(i,1);
                    } else if(asteroid[i].radius >6) {
                        smallAsteroids.push(new Asteroid(asteroid[i].x,asteroid[i].y,0,0,asteroid[i].radius/2,randomAngle(),randomAngle()));
                        smallAsteroids.push(new Asteroid(asteroid[i].x,asteroid[i].y,0,0,asteroid[i].radius/2,randomAngle(),randomAngle()));
                        asteroid.splice(i,1);
                    }
                        lazer.splice(b,1);                 
                }
            }
        }
    }      

We loop first though the asteroid array then immediately after the lazer array this will check each asteroid against every lazer one by one.

We then get the vector between each asteroid, this will be the distance from the asteroid to the bullet.

We then create an if statement which will check if the distance between them is less that the radius of both circles combined.

If the distance is less than the combined value they are colliding if it isn’t they aren’t colliding.

Next we have another if statement that will check if the radius is less than 12, this will stop the asteroids getting too small.

If they are smaller than 12 they will simple be spliced from the array, if not we will spawn two smaller asteroids half the size at the asteroids last position.

We also then destroy the asteroid and the lazer.

We have to make sure we add all the calls to the update method, this will include all the new calls to create and update the asteroids and the smaller asteroid when they are created.

This is how all our function calls are stacking up:

function update(){
        window.requestAnimationFrame(update);
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.drawImage(spaceIMG,0,0,canvas.width,canvas.height)
        updateLazers();
        ship.draw(ctx,shipIMG);
        shoot(ship);
        Move(ship);
        ShipBounds(ship);
        drawAsteroids(asteroids);
        drawAsteroids(smallAsteroids);
        moveAsteroids(asteroids);
        moveAsteroids(smallAsteroids);
        AsteroidBoundaries(asteroids);
        AsteroidBoundaries(smallAsteroids);
        destroyLazers(lazers);
        asteroidBulletCollision(asteroids,lazers);
        asteroidBulletCollision(smallAsteroids,lazers);
        
    };

We are now able to shoot our asteroids and watch it split into two smaller asteroids, shoot them again and they split off again each with its own trajectory.

Shooting Asteroids

The reason for testing for the radius is so the asteroids don’t get two small, as we are dividing them by two if we didn’t have a test condition they would keep dividing until we couldn’t see them anymore.

Destroying our Player

So we have most of the elements for our asteroid game. We are able to shoot, avoid and fly around the screen.

The one thing that’s missing is collision between our ship and our asteroids, we want to be able to crash our ship into the asteroid and cause a game over event.

We want to be able to kill our player because if there’s no risk in our game then there will be now reward.

Lets create a global variable that can control the state of our game, this will be our gameOver variable

var gameOver = false;

We are going to be creating another circle collision test between our ship and the asteroid.

You might be saying to yourself, “Hey the ships bounds are rectangular and not circular”. This is right and you can test collisions between rectangle and circles if you wanted.

But I’m going to show you a different method of creating a circle hit region that will surround our ship, we can then test this hit region against the asteroids hit region.

So we are going to create another object called CollisionCircle, lets create the constructor:

function CollisionCircle(x,y,radius){
        this.x=x;
        this.y=y;
        this.radius=radius;
        }
        CollisionCircle.prototype.draw=function(ctx){
        ctx.save();
        ctx.beginPath();
        ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
        ctx.fillStyle="yellow";
        ctx.fill();
        ctx.restore();     
        }   

This is nothing new and looks exactly like our other constructors.

We will use this object to create a bounding circle that will surround our ship and enable us to collide with other objects.

So we will create a new instance of this object called shipCircle just underneath where we create the ship object itself.

Next we initialize the collision circle with the ships position and radius of 40, you can test this circle radius size yourself, if you want to make the detection more sensitive you can make the hit radius bigger or visa versa.

var shipCircle = new CollisionCircle(ship.x+ship.hw,ship.y+ship.hh,40);

Next we will create the drawHitCircle() function, this will simply draw our circle at the ships coordinates, matching it on both the x and y location.

 function drawHitCircle(){
        shipCircle.draw(ctx);
        shipCircle.x = ship.x+ship.hw;
        shipCircle.y = ship.y+ship.hh;
    }

Don’t forget to add the function call to the update loop, but Make sure its before the ship.draw() method other-wise it will appear over the top of the ship rather than underneath.

drawHitCircle();

Now refresh the browser and you will see a bright circle surrounding your ship, this doesn’t react with the asteroid currently but will shortly.

To make the hit circle receive collision we will create another hit function, this function will be similar to our lazer versus asteroid collision function, with just a slight difference.

Here is the collision function:

 var asteroidPlayerCollision = function(asteroid,player){//
            for(var i=0; i<asteroid.length; i++){      
                    var dx = asteroid[i].x -  player.x;
                    var dy = asteroid[i].y -  player.y;
                    var distance = Math.sqrt((dx * dx) + (dy * dy));

                if(distance < asteroid[i].radius + player.radius){
                    gameOver = true;
                }    
            }
    }

This will calculate the same distance logic but rather than destroying asteroid it will just simple set the game over variable to true.

Now in order for this to work we need to wrap the update function in a condition. this if condition will simply check whether the game over variable is true or false.

function update(){
       if(!(gameOver)){
        window.requestAnimationFrame(update);
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.drawImage(spaceIMG,0,0,canvas.width,canvas.height)
        updateLazers();
        drawHitCircle();
        ship.draw(ctx,shipIMG);
        shoot(ship);
        Move(ship);
        ShipBounds(ship);
        drawAsteroids(asteroids);
        drawAsteroids(smallAsteroids);
        moveAsteroids(asteroids);
        moveAsteroids(smallAsteroids);
        AsteroidBoundaries(asteroids);
        AsteroidBoundaries(smallAsteroids);
        destroyLazers(lazers);
        asteroidBulletCollision(asteroids,lazers);
        asteroidBulletCollision(smallAsteroids,lazers);
       }
    };

This is an inverse if statement that checks if the game over isn’t set to true, if it isn’t then run what ever is in the update function, if not then don’t run the following statements.

Lastly add the following calls to the update function:


  asteroidPlayerCollision(asteroids,shipCircle);
  asteroidPlayerCollision(smallAsteroids,shipCircle);

Now we should have collision detection between the asteroid and the player.

We can change the circle hit region of the ship slightly as the collision is to sensitive, lets change it from 40 to 20 pixels

var shipCircle = new CollisionCircle(ship.x+ship.hw,ship.y+ship.hh,20);

Lastly, like with the asteroid, we can get rid of the original draw call as we don’t want to see the hit region unless we are debugging our game.

//shipCircle.draw(ctx);

Now we should be able to collide with our asteroids.

Creating our Game Over State

We need to extend out game over state to include some game over text and a restart button.

Now we can do this in JavaScript, but we can also do it more simply in our HTML file using tags.

We will need to add the following to the HTML script:

<h1 id="gameover">Game Over</h1>
<button id="reset">Reset</button>

This will simply add two more elements to the body of our document, one is a header tag that will display the game over text, the other a button which we will use to reset our game.

Make sure to add these tags just above the canvas element in the document.

We also need to add the following to our CSS file to style and position our elements in place.

#gameover{
	position: absolute;
	margin:  220px 0 0 160px;
	padding: 10px;
	color:  red;
}
#reset{
	position: absolute;
	margin:  280px 0 0 220px;
	padding: 10px;
}

Now this will add the text and button to our game, problem is its permanently positioned on top of everything, regardless of whether the game over state is true or false.

We can add the following to each of the CSS selectors to set its display property to none as default.

display: none;

Now the element won’t appear when the document first loads.

We will now jump into the JavaScript to add some behavior to these elements to make them display when the game over state is true.

Next we need to create some references to our game over and reset elements within our HTML document, to do this we will use the getElementById() method.

var gameover = document.getElementById("gameover");
var reset = document.getElementById("reset");

This will hold a reference to each of the elements within the game over and reset variable.

Next we need to think about when we want to display the game over screen, well this will obviously be when the game state is set to true, right?

So we have wrapped up our animation loop within an if statement that checks if the game over variable is true or not, we could just tweak this slightly and add an else statement directly after it.

This will display the game over and reset elements when the game over state is true:

 } else {
        gameover.style.display="inline";
        reset.style.display="inline";
 }

Now refresh the screen and you should now see the game over text and button appear if you hit an asteroid.

That’s all good but we want to now reset our game using the button, so how are we going to do this?

We will add a “click” event listener to our reset button like so:

reset.addEventListener('click', function(){
        gameover.style.display="none";
        reset.style.display="none";
        resetGame();
});

This will make the two elements disappear when we click them, as we don’t want them displaying during play, and then call the resetGame() function, this we will create next.

 var resetGame = function(){
      gameOver=false;
      asteroids=[];
      ship.x =canvas.width/2-32;
      ship.y=canvas.height/2-32;
      ship.vx = ship.vy =0;
      start();
    }

The reset function will set our gameOver variable back to false, clear our asteroids array, reset our ship, both position and velocity, and then kick off the start function again.

Now when you die you have a way of restarting the game.

You may have notice a bug whilst creating this, whenever we reset or refresh our game, and our asteroid’s random position matches that of our ship, it causes a collision before the game has even started.

Now you can if you wish create asteroids randomly excluding the very center of the canvas, or make the ship invincible for the first few seconds of play, but this I’ll leave up to you to figure out.

For now we can just simply reset using the button and this will work fine for the scope of this tutorial.

Thank you for following along with this tutorial and if you like it please take a look at some of my other posts.

Keep creating and don’t give up on making your game ideas a reality.

]]>
How to Make a JavaScript Game with HTML5 Canvas https://indieprogramming.com/how-to-make-a-javascript-game-with-html5-canvas/ Tue, 20 Jul 2021 23:57:46 +0000 https://indieprogramming.com/?p=2311
Pull and Release Game

Creating games with HTML5 using the canvas element can be fairly simple if you know just a little JavaScript.

Here are 4 things you need to create you game:

  • Notepad/ Notepad++
  • A browser ( preferably Chrome)
  • knowledge of HTML,CSS, JavaScript
  • Uploading and showcasing your game on sites like itch.io, newgrounds

HTML5 allows you to create games that you can easily share online, it also gives you the ability to release on multiple platforms using a web browser as a wrapper.

This is how small indie companies can make a mobile game with JavaScript and get it to work on most mobile phones.

HTML5 is also used by many game companies to create web versions of their games that can be easily shared and itself used as a promotion tool.

You don’t need any complex developing environments, everything you need to create games is at you finger tips.

With the basic windows notepad or text edit (Mac) you can create your code and launch the results in your browser. The browser will interpret the code.


A simple JavaScript game

I am going to show you how to make a fun little JavaScript game, using a fairly small amount of code. The game is going to be a pull and release style game.

We will have a ball/circle that will be propelled up the screen using the mouse, this will be done through a simple click and drag operation.

Our game will involve shooting a ball to hit a target that has three different hit regions. Hit the outer green region and you get 10 points, hit the yellow region you get 20 and the bullseye 30.

All the hit regions will be colored and in our case will flick on and off depending on if the ball has come into contact with them or not.

For this tutorial you will need a basic understanding of the web framework mentioned at the start, but even if you don’t I’m sure over time you will get the concepts.

Now we have all that sorted lets get on and create our game.


We will be creating three files, first the HTML, secondly the CSS and lastly the JavaScript.

We will create a folder for our files called pull&release, this will contain out Html, CSS and JavaScript files of the same name.

First we will be looking at how to get you setup up using the HTML5 canvas, this will involve first creating the container in HTML.

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>x</title>
	<link rel="stylesheet" href="pull&release.css" />
	<script src="pull&release.js"></script>
</head>
<body>
	<canvas id="gCanvas" width="512" height="728"></canvas>
</body>

</html>

The HTML above is all you need to form the container for the game, the important part is the canvas element which we include in the main body of our html.

The CSS file is even more sparse only containing the following few lines:

body {
	background:#000;
}
canvas {
	background:#fff;
}

The CSS just consists of a body selector and a canvas selector each setting their respective elements to black and white;

So this was the easy part, we now need to create the behavior for our game. This will contain out game loop, physics and logic and anything else we need for our game to run.

We will start by calling the window.onload method, this will be the wrapper for all our code and will run when all elements are fully loaded.

window.onload = function(){code here}

Then we create a reference to our canvas element and its context.

var canvas = document.getElementById("gCanvas");
var ctx = canvas.getContext("2d");

The canvas variable will contain the reference to canvas element gCanvas and the ctx variable gives us access to the canvas API.

With this we can now draw something to the screen.

window.onload = function(){
 
var canvas = document.getElementById("gCanvas");
var ctx = canvas.getContext("2d");

ctx.fillRect(100,100,100,100);

}

We create a rectangle using the ctx method fillRect(), we then tell it to draw the rectangle at 100 on the x and 100 on the y from the origin ( top left of the canvas ).

The second two arguments in the parentheses will be the size we want to draw it, 100 pixel in width and 100 pixels high.

Open up the html file in your browser and you should see the following:

This is how powerful the canvas is, with just three statements you have drawn a square to the screen. It actually only takes a little more code to make the square move.

First we will draw the square a slightly different way, we are going to create a constructor that we will use to instantiate an object called block.

  function Block(x,y,w,h){
    this.x=x;
    this.y=y;
    this.w=w;
    this.h=h;
  }
  Block.prototype.draw = function(ctx){
  ctx.fillRect(this.x,this.y,this.w,this.h);
  }

  var block = new Block(100,100,100,100);

  block.draw(ctx);
  

The above code is called a constructor we can use it create a block object.

We create a function called block which takes the arguments x,y,w,h this is going to be the x and y coordinates and the width and height of the block,

Once we instantiate the object we use the this keyword to assign the arguments to the object’s properties.

When the this keyword is used it will always reference the object it is sitting in. In this example it will represent the object being instantiated.

We then create a prototype method that all the instantiated objects will inherit from, this will be called draw(), we will use this method to draw the square to the screen.

We then instantiate a new object called block of type Block using the new keyword. The new keyword will create and object from the constructor.

After that we reference the object draw method to draw the object to the screen.

Now this may seem like a lot more work than before and there is a lot more code here than just three statements, but creating an object like this is so much more useful.

Now we have and object with a set of given parameters, it has an x and y values and a width and height value.

Using these we can control our object over time….


Now in order to have interactivity we want to create some kind of interaction between the player and what we seen on screen.

The building block for this can be a simple animated sprite, animation can be seen as simply movement over time.

In order for this to happen we want to create a game loop that will update our objects each frame.

We create two functions one called startGame() and Update();

function startGame(){
    Update();
  }
  function Update(){
    window.requestAnimationFrame(Update,ctx);
    ctx.clearRect(0,0,canvas.width,canvas.height)
    block.draw(ctx);
    block.x+=1;

  }
  startGame();

The startGame() function will kick of our game loop, it will then be the game loop that will hold all our other functions.

This update function will update and effect our game objects in some way, either by adding velocity, checking for collision or drawing our sprites to the screen.

Inside the update function we use the requestAnimationFrame() method to loop through the update function at a controlled frame rate.

To do this we add the update function as the first argument and the canvas ctx as the second argument.

We then use the ctx.clearRect() method to clear the canvas on each loop so that we have a fluid animation. the parameters for this method will be the coordinates to start the rectangle and the width and high you want to influence.

If you forget to add the clearRect() method then all the frames will be drawn on top of each other to from one long line.

You can test this by leaving out the clear function to see exactly what mean.

We then move the block.draw() method into the update loop, so that we can update the canvas on each frame and then move the block by referencing the blocks x position.

By using the block.x +=1 we can move the block 1 pixel on each frame. This is the equivalent of saying block.x + block.x =1.

This takes the position from before and then adds 1 to it on each frame over and over again, This will create movement.

Finally outside the function update at the bottom of the window.onload function we add the call to the startGame() function.

This will call the function, which in turn will call the Update() function which will keep looping until otherwise told not to.

Open the browser and you should have a block that moves from left to right of the screen.

This is the code we have so far:


window.onload = function(){
 
var canvas = document.getElementById("gCanvas");
var ctx = canvas.getContext("2d");

  function Block(x,y,w,h){
    this.x=x;
    this.y=y;
    this.w=w;
    this.h=h;
  }
  Block.prototype.draw = function(ctx){
  ctx.fillRect(this.x,this.y,this.w,this.h);
  }

  var block = new Block(100,100,100,100);


  function startGame(){
    Update();
  }
  function Update(){
    window.requestAnimationFrame(Update,ctx);
    ctx.clearRect(0,0,canvas.width,canvas.height)
    block.draw(ctx);
    block.x+=1;

  }
  startGame();

}

The reason for creating a constructor is that we can instantiate a game object with properties that we can use in our game

We could also create multiple instances of the block object each with different values.

If we wanted to give our player (block) energy we could simple add another property call energy, then within the constructor argument we could set this property to a specific value when we create it.


Creating our Player Object

From here we want to make a few changes to our constructor:

function gameObject(x,y,vx,vy,radius,fillColor){
      this.x=x;
      this.y=y;
      this.vx=vx;
      this.vy=vy;
      this.radius=radius;
      this.dist =0;
      this.hit = false;
      this.fillColor=fillColor;
      this.rotation=0;
  };     

We are going to create out player object, from the gameObject constructor. The player object will have an x and y position and now also a velocity x and y named vx and vy.

this.vx=vx;
this.vy=vy;

Velocity will be represent by a vector which we will later calculate by getting the distance between to points, this will be added with a scaler value that we will later represent as the property speed.

We also add a radius property to allow us to create other game objects including the hit circles, all by using the same constructor.

this.radius=radius;

We then create a dist property that we can use measure the distance between objects and use that for other calculations we will need for moving the objects around the screen.

Next we create a Boolean property called hit, this will tell us when the player’s circle has hit the other circle’s hit regions on the score board.

We create these variables in the constructor using the this keyword rather than separate global variables, this is so that each object will have its own properties and values built in.

We have a fillcolor property which will allow us to create different colored objects based on what game objects we are creating, this will become helpful later when we are creating out different color hit regions.

this.fillColor=fillColor;


Updated Canvas Drawimage

So now we are dealing with circles and rotations we need to make some amendments to our game objects draw method.

Here’s what that looks like

 gameObject.prototype.draw=function(ctx){
      ctx.save();
      ctx.beginPath();
      ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);  
      ctx.stroke();
      ctx.restore();
 }

We start by using the ctx method called save() this will save the state of our canvas when we are drawing on to it.

This is what allows us to save and restore states when we are applying changes to the canvas, including colors, positions and translations.

ctx.save();
ctx.restore();

Next we draw the object with these four statements:

ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
ctx.stroke();

As the player is a circle we can create it with the ctx.arc method this allows us to not only draw circles but arcs with various circumferences.

We first have to state where we begin the path, then in the arc method we enter the x and y position of the circle’s center on the canvas, then its radius, its start angle and lastly its end angle.

By using 2*Math.PI we are saying 3.14 (PI) x 2 which just so happens to be a complete circle.


Now we have created the constructor there are few more things we need to do before drawing our player to the screen.

First we are going to create a global Array called drawArray[] this will be used to contain all our game objects.

var drawArray=[];

We create our player with it positioned at 100 pixels on the x and 100 on the y, we then set both the vx and vy to 0, the radius to 20 and just some empty quotes for fillcolor.

We use the JavaScript array push method to push the player object into the array.

var player = new gameObject(100,100,0,0,20,"");
drawArray.push(player);

Next we create the draw function, we will use this to draw all our game objects to the screen.

function draw(array,ctx){
    for(var i=0; i<array.length; i++){
      array[i].draw(ctx)
    }
  }

We then feed the array into the function with the second argument being the ctx we use to draw with.

We then create a for loop that iterates through the array drawing each element of the array to the screen. The bigger the array the more game elements will be drawn.

As before we then create the startGame() and Update() method.

function startGame(){
    Update();
  }
  function Update(){
    window.requestAnimationFrame(Update,ctx);
    ctx.clearRect(0,0,canvas.width,canvas.height)
    draw(drawArray,ctx);
  }
  startGame();

The only difference here is we use the draw function with the draw array parameter to draw the game object.

Here is the result when you load the browser:

Here is all the code so far:


window.onload = function(){
 
    var canvas = document.getElementById("gCanvas");
    var ctx = canvas.getContext("2d");
    var drawArray=[];


  function gameObject(x,y,vx,vy,radius,fillColor){
      this.x=x;
      this.y=y;
      this.vx=vx;
      this.vy=vy;
      this.radius=radius;
      this.dist =0;
      this.hit = false;
      this.fillColor=fillColor;
      this.rotation=0;
  };     

  gameObject.prototype.draw=function(ctx){
      ctx.save();
      ctx.translate(this.x,this.y);
      ctx.rotate(this.rotation);
      ctx.translate(-(this.x),-(this.y));
      ctx.beginPath();
      ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);  
      ctx.stroke();
      ctx.restore();
 }
  var player = new gameObject(100,100,0,0,20,"");
    drawArray.push(player);

  function draw(array,ctx){
    for(var i=0; i<array.length; i++){
      array[i].draw(ctx)
    }
  }
  function startGame(){
    Update();
  }
  function Update(){
    window.requestAnimationFrame(Update,ctx);
    ctx.clearRect(0,0,canvas.width,canvas.height)
    draw(drawArray,ctx);
  }
  startGame();
}

Now this seems like a lot just to create a circle on the screen, but we now have the ability to create and draw all our sprites we need for our game.

Now we just need to add interactivity and movement…


JavaScript Mouse Events

So we want to create some kind of interaction between the user and the game object, you can do this in many ways on this occasion we are going to be using the mouse for our input.

We first create three global Boolean variables to keep track of what our mouse is doing, these are:

var mouseUp = false;
var mouseDown = false;
var mouseMove = false;

We are also going to use three JavaScript mouse events these are:

  • onMouseDown()
  • onMouseUp()
  • onMouseMove()

We want to be able to click on the circle, drag it and release it, once we do we want the object to travel up the screen towards the target.

We start by adding an event listener to the canvas, this allows us to subscribe to all mouse events that originate from the canvas.

 canvas.addEventListener('mousedown',onMouseDown,false);

We then add the following functions and mouse events:

  function onMouseDown(){
          mouseDown = true;
          canvas.addEventListener('mouseup', onMouseUp,false);
          canvas.addEventListener('mousemove', onMouseMove,false);
          console.log("mouse down " + mouseDown);
  }
  function onMouseUp(){  
          mouseUp =true;
          canvas.removeEventListener('mouseup', onMouseUp,false);
          canvas.removeEventListener('mousemove', onMouseMove,false);
          console.log("mouse up " + mouseUp);
  }       
  function onMouseMove(e){
          mouseMove = true;
          console.log("mouse move " + mouseMove);
  }

So we start with the onMouseDown() function which we will use to switch the mouseDown variable to true.

We then add the mouseup() event and the mousemove() event method as we only want to be checking for these events whilst the mouse is down.

We can check both the mouse position and whether not the mouse is up within this one event.

In the onMouseUp() function we then flag the mouseUp variable and remove both the mouseup and and mousemove event.

In the onMouseMove() function we switch the mouseMove variable to true, also in each of the functions we log the results to the console.

The (e) in the OnMouseMove function stands for event, this holds information about the event, for example the mouse’s x and y position.

In Chrome you can log the results to the browsers console window by holding CTRL SHIFT and J. Other browser you should be able to get there by pressing F12

If you load the browser now and open the console window you can click on the canvas and drag the mouse, then release the button.

You will see the output of the variables like so:

So now we have some output, but how do we map this to our player object?

We can start by creating a mouse object that can hold a reference to our mouse’s x and y positions.

We declare the mouseC object under the mouseMove variable at the top of our code.

var mouseC ={x:0,y:0}

So to get the position from the event array we use the clientX and clientY window property, minus the offset of the canvas. We then save it to the new mouseC object.

We add the following code and update the onMouseMove() function:

mouseC.x = e.clientX - canvas.offsetLeft;
mouseC.y = e.clientY - canvas.offsetTop;
player.x=mouseC.x;
player.y=mouseC.y;

We then add the mouse’s position to the player position. Refresh the browser and you should be able to click and move the circle around.


Next we will create a line that will trail out from behind the ball as we drag it.

To do this we want to create two vector objects, one called vectorStart the other called vectorEnd.

 var vectorStart ={x:0,y:0};
 var vectorEnd ={x:0,y:0};

We will use this to draw a line between the start click to where the ball is dragged and then released.

Next we want to draw the line:

function createLine(ctx){
            ctx.save();
            ctx.beginPath();
            ctx.moveTo(vectorStart.x,vectorStart.y);
            ctx.lineTo(mouseC.x,mouseC.y);
            ctx.stroke();
            ctx.restore();
  }

We use a similar drawing method as before, this time we are drawing a path. We move to the vectorStart position and then draw to the mouse position.

Then we initialize the vector within the player position within the onMouseDown function, this will be where the line starts.

vectorStart.x = player.x;
vectorStart.y = player.y;

Its in the onMouseUp function where we provide the vector with the new player position after being dragged.

vectorEnd.x = player.x;
vectorEnd.y = player.y; 

To finish we create a function called moveObjects()

function moveObjects(ctx){
    if(mouseMove){    
              createLine(ctx);
      }
  }

In the function we use an if statement to check whether or not the mouse is being held down, if it is we call the line function which will then draw the line.

The last thing is to add the function to our loop:

moveObjects(ctx)

Now you should see a line extending from the vector start point ( where you click ) to the circle where you drag it to.


So now we have a draggable circle or ball, we now want to be able to shoot it forward when its released, but what is forward?

Forward in this case isn’t hardcoded into our game, it changes depending on where you drag the circle from.

Forward will be calculated using the start vector, the end vector and the angle created between them.

The line that we draw when we drag the ball will help us understand this.

So the line drawn represents the vector we are using to push the ball forward, the start vector is the position where we click, the end vector is the point we drag the ball to, this is also the center of our circle.

To spring the ball forwards we want to first create two new global variables:

var springAngle;
var speed = 0.1;

We will also be creating two new functions, one to get the angle between two points and another to get the distance between to points.

The getAngle() will be used in our calculation to get the angle of our velocity, the getDistance() will be used to calculate our collisions.

Here are the two functions fleshed out:

function getDistance(a,b){
       		dx = a.x - b.x;
       		dy = a.y - b.y;
       		return  Math.sqrt(dx * dx + dy * dy);
  }
  function getAngle(a,b){
       		dx = a.x - b.x;
       		dy = a.y - b.y;
       		springAngle = Math.atan2(dy,dx);
  }

These two functions are quite similar as they both get the vectors between the two points a and b, and applies a calculation to them.

They deal with the result slightly different, getDistance() returns the square root of the sum of dx and dy. This essentially gives us the length or magnitude of the vector between the two points.

GetAngle() on the other hand uses the arc tangent function to get the angle between the two points based on this magnitude

We then use these functions in the onMouseUp() function to calculate the angle and distance when we release the ball.


JavaScript Move Element

To start getting some movement into our code we add the following statements to our onMouseUp() function:

player.dist = getDistance(player,vectorStart);
getAngle(vectorStart,vectorEnd);

We utilize the player.dist property and save the result of the getdistance() function to it, feeding in the player and vector position data.

We also call the getAngle() function which will save the angle to the global springAngle variable. For this we feed in the vector start and vector end values as parameters.

Lastly we add another if(mouseUp) statement to our moveObject() function along with the extra argument obj.

function moveObjects(obj,ctx){
  	if(mouseUp){ 
	        obj.vx = Math.cos(springAngle) * obj.dist * speed;
	        obj.vy = Math.sin(springAngle) * obj.dist * speed;
		obj.x += obj.vx;
		obj.y += obj.vy;//
	}
    if(mouseMove){    
              createLine(ctx);
    }
  }

If the mouse is up this is when we want the ball to launch.

So with the angle and the distance calculated on the click down event, the mouse up will take these and calculate our velocity.

The drag and release of the ball will be different depending on the length of the the vector.

In other words the further back we drag it the further it will go, the less we drag the shorter the distance it will travel.

The obj is a reference to the object we feed into it, in this case the player object.

We get the angle of the velocity on the vx and vy by using the Math.cos and Math.sin functions respectively. This will give us a value of the opposite and adjacent sides being divided by the length of the magnitude.

The angle for each of these is the springAngle we calculated earlier. We take the the object distance and times it by a fraction held in the variable speed.

We then add this to the object’s x and y coordinates.

In trigonometry we can plot the points of two objects and use these legs to calculates the hypotenuse which will be the distance between them.

Before you refresh the browser we can make a quick change to the objects start position. We can do this where we first create our player object:

var player = new gameObject(canvas.width/2,canvas.height-130,0,0,20,"");

The above arguments will set the ball at the bottom middle of the screen with a suitable drag region.

Also at this point we want to remove the mouse down event so that we can’t drag the ball again once it is in motion. This is done within the mouse move if statement within the mouseMove() function.

if(mouseMove){    
        createLine(ctx);
        canvas.removeEventListener('mousedown', onMouseDown,false);
}

Phew that was a lot of vector math and trigonometry, but you now should have a draggable player object that you can propel in any direction 360 degrees.

Try it yourself, you should now be able drag the ball around till you hearts content.

For now you will have to refresh the browser after each go, but we will soon rectify this problem in the next section.

Download the save point below if you are having trouble with you code.


Resetting the ball

We have a ball that launches, but how do we stop it?

We can do it with the following code placed within the mousUp If statement in the moveObjects() function:

if(speed >0){
        speed-=0.0008;
     } else {
	speed=0;
}

The above logic states that if the ball’s speed is more than 0 we take away 0.0008 on each frame, other wise the ball isn’t moving so the speed will be set to 0.

So when we are resetting the ball we need to tell if its still moving, we do this by creating another global variable called isMoving and initialize it to true

var isMoving = true;

This stopped the ball but we need it to reset again, this can be done as follows:

if(obj.vx || obj.vy > 0.1){
	    isMoving = true;		
        } else {
	    isMoving = false;
        }
	if(isMoving == false){
	    resetMovement();
}

If the vx or the vy is more than 0.1 then we flag isMoving to true if not its false. Then we have another check that will initiate a resetMovement() function which will do the following:

function resetMovement(){
       		      canvas.addEventListener('mousedown',onMouseDown,false);
       mouseDown = false;
       mouseMove = false;
       mouseUp = false;
       player.x =250;
       player.y = 600;
       speed =0.1;
 }

Within the reset function we re-add the mouse down event as this was removed after the mouse move event was fired. We then set all the mouse Booleans back to false, change the player position back to the start and set the speed back to 0.1.

We now have a player object that resets on each go.


Is the Game Object Outside Canvas

We have the object resetting when it stops, but we also want it to reset when it goes out of bounds, this is when it goes off the screen to the top, right, bottom or left.

We do this with the following code:

function boundaries(obj){
       if(obj.x - obj.radius > canvas.width || obj.x + obj.radius <0
      || obj.y - obj.radius > canvas.height || obj.y + obj.radius <0)
       resetMovement();
  }

The function takes an object for an argument, we take this object and check if the objects x position minus it radius is more than the canvas width.

We then check whether the objects x position + its radius is less than 0.

We also do a similar calculation with the y value of the object, except we reference the y position instead of the x position and the height instead of its width.

This means now when the player goes off screen it will reset back to its origin.

Remember we have to add the function call to the Update() function.

boundaries(player);

Something to Aim For

Now its all very well pulling and shooting a ball around the screen, but we should have something that we can shoot at right?

So for this set up we are going to create three circle hit regions, we also want to be able to score points depending on where the ball lands on these hit regions.

So we are going to create three more circles using our constructor, as we have set up all the properties we need to create out games objects all we need to do is the following:

var ten = new gameObject(canvas.width/2,120,0,0,120,"green");
var twenty = new gameObject(canvas.width/2,120,0,0,80, "yellow");
var fifty = new gameObject(canvas.width/2,120,0,0,30, "red");

So we position all these objects with same center point, but each with a different radius, we are also going to make use of the fillcolor property to make one green, one yellow and one red.

We also have to add these new object to our drayArray[]

drawArray.push(player,ten,twenty,fifty);

Circle Collision

Now we have all the elements on the board we want them to react in some way to each other.

In order for them to interact we need to detect when they collide, so for this we need to create a function that tests for circle collisions.

We first have to add another method to our constructor:

gameObject.prototype.getBounds = function(){
        return {
            x: this.x,
            y: this.y,
            radius: this.radius
        }
  };  

This method will return the bounds of our game objects, in this case the x, and y positions and their radius.

Next we want to create our collision function:

 function circleCollision(player,circle){
       	if(getDistance(player.getBounds(),circle.getBounds()) 
       		< (player.radius-30 + circle.radius)){
   		  circle.hit =true;
   		  console.log("true");
       	} else {
       		  circle.hit =false;
       		  console.log("false");
       	}
  }

So in the above code we feed in the two objects we want to test for, this is the player and the circle (although the player is a circle too).

Next we create an If statement that uses the getDistance() function combined with the player.getbounds() method. This tests if the distance between the two circles is less than the combination of both of the radius’s.

If it is then they are colliding, if not they are not colliding.

We just have to add the circleCollision() call to the update function like so:

    circleCollision(player,ten);
    circleCollision(player,twenty);
    circleCollision(player,fifty);

We then want to signify the collision by setting the individual objects hit property to either true or false.

We then can also log this to the console, open up the browser with the developer console and launch your ball.

Once the ball hits the circle it will flag up true, when it leaves the boundary of the circle it will switch to false.

You may notice the player.radius-30 property in the if statement is set to the radius by minus 30 pixels, this is because most of the ball will have to be within the circle before it is consider a collision.

If you didn’t do this then you could gain points even if the smallest amount of the ball was in the hit region, we want most of the ball to be in the hit region before we are given the points.

using -30 as a value seem to work quite nicely.

Adding Colors to the Canvas

We are going to add colors to our circles when the ball collides with them, this is where we use the fillcolor property for each of our hit regions.

We need to amend our draw method in our constructor to add the following:

   ctx.stroke();

--
    if(this.hit){
      ctx.fillStyle = this.fillColor;
      ctx.fill();
    } else {
      ctx.stroke();
    }
--
      ctx.restore();

So here we have added a simple If statement that checks whether the circle’s hit property is set to true or false, if it is add the fill color, if not leave it clear

This gives us some reaction for when the circles are hit, adding some nice color to our canvas, you can of course change these to any colors you like.

There is a problem though, the ball seem to go behind the hit regions when they change color. This is just because of the order in which we are drawing the elements to the canvas.

We just need to remember to always draw the ball in front of the hit circles, we do it by changing the order the objects appear in the drawArray[] like so:

 drawArray.push(ten,twenty,fifty,player);

What’s the point?

Lastly we want to add some kind of point system, we first do this with a global points variable.

var points =0;

We then add the following to the moveObjects() function


if(ten.hit ==true && speed <0){
		points +=10;
	}
if(ten.hit ==true && twenty.hit ==true && speed <0){
		points +=10;
	}
if(ten.hit ==true && twenty.hit ==true && fifty.hit ==true && speed <0){
		points +=30;
	}

These if statements test if the circle boundary is hit and if the speed is less than zero, if it is the points will be added to the points variable.

Now this may be confusing as the points don’t seem to add up.

Ten is ten, that’s fine, but when ten and twenty are hit it is also 10, and when all three circles are hit its only 30 points.

Well it becomes quite obvious because when you are hitting the first circle its adding 10 points, when you are on the second circle you are actually colliding with both the first and the second circle so it adds 10 and 10 to make 20.

And finally when you are colliding with the middle circle you are actually colliding with all three circle at the same time meaning it adds 10-10 and 30 making 50.

We finally add the following statements to the update function.

 ctx.font = "20px serif"
 ctx.fillText(points,450,50);

We use the context font and fill text methods to print the point value to the screen.

Just before we finish we can go back through our code and take out all the console.log calls, this doesn’t have a major effect on performance, but its always best to do so.


Well that’s it, you made it to the end and you have created an simple but addictive game that you can challenge your friends to.

Even though the code got heavy at times we have covered a lot of fundamentals that will come in useful for your future coding.

JavaScript is a fun language to learn and can be very powerful when combined with the canvas element.

Have fun making games and if you enjoyed this tutorial please check out some of my others below.

]]>
How to Make Sprites for Games in Krita https://indieprogramming.com/how-to-make-sprites-for-games-in-krita/ Sat, 13 Feb 2021 13:23:24 +0000 https://indieprogramming.com/?p=2118

You can easily create game sprites and other game ready assets in a free program called Krita.

Krita is a versatile sketching and panting program that can be utilized in your pipeline, you will be able to create high quality 2D assets for any style of game you can dream up.

If you create 3D models for your games then Krita can also be used to create 2D textures to wrap around your 3D geometry.

Here I am going to show you how to create four simple game assets that can be taken and used for a retro style game, I am going to be using a tablet to draw and sketch my designs with, this is optional and not essential.

If you are interested in a good cheap tablet then I would recommend a simple Wacom graphics tablet, mine cost me around £70 and works great!

Wacom tablets are great but there are also many other tablets out there to choose from.


Now before we start you will need to download Krita, you can find it by following this link: https://krita.org/en/

Krita is a free program that you can use at no cost to you, if you wish you can donate some money to aid the further development of this fantastic software.

Once you have installed Krita open it up and you should see a screen much like the following:

As you can see if you have used Adobe Photoshop before it has a similar interface and setup.

On the left of the screen you have a list of tools ordered horizontal and on the right you have your brush settings, colors and layer options.

To start off with I created some quick rough sketches using the basic-5 brush, at this point I wasn’t too worried about how my designs were looking I was just quickly creating shapes and adding bits as I went along.

Here are the results from the quick sketches I made:

Now I want to take these initial freehand sketches and clean them up to make four different finished game assets, I do this by separating each image onto their own layers.

I put the initial sketch on its own layer and will be creating a different layer for each of the assets, we also have a base layer which will be filled white.

The layer setup will look as follows:

We want to adjust how transparent the sketch layer is by first selecting the layer and then adjusting the opacity bar at the top setting it to around 40%:

Now when you draw assets in Krita it can be useful to mirror your object horizontally or vertically, saving you time when drawing and producing a better balanced result.

This works very well when creating symmetrical assets like spaceships, cars, submarines, planes etc. This symmetry is often found in a lot of really world objects you see around you.

To turn on the mirror tool click on the horizontal or vertical mirror icon in the menu bar at the top of the screen like so:

You can drag the line across the image to define the exact position of the mirror line, this is the intersection point were the two halves will meet.

When we draw on top of the image now the brush stroke will mirror perfectly to the other side.

Mirroring makes the whole process much quicker and provides symmetry to all your assets, making them look more professional.

When creating assets, in particular hard surface assets like space ships, cars, houses and boats, it is vital you create a good symmetrical design, if they are uneven or the proportions are wrong your designs may seem amateurish.

With all the designs outlined, and with a few modifications made to some of the original sketches, here is what they look like now:

We have now successfully taken our original digital sketches and created a strongly outlined symmetrical version of our designs to build our final design on.

Next we want to take our designs and find an interesting color pallet for them.


We now want to pick one of the designs and start to fill out the base colors, to see what color work.

We are going to first focus on the bottom right design first, this is a kind of under water pod that, in our game, traverses the ocean depths, for some reason or another.

So you can choose you own color scheme from the color wheel on the top right or you can choose palettes from other online sources.

A great place for color palettes is a site called Lospec, this is were I usually go as the site provide loads of interesting palettes to choose from.

You can find the web site and the palette list here https://lospec.com/palette-list

In this case I’m not going to download a color palette online I’m just simply going to create my own and just test what looks right as I go along.

We are now going to create a color layer that is going to sit just under our outline layer, we will also combine the outline layer with this new color layer and create a new group for them to occupy.

We do this by highlighting both of the layers and then press CTRL G to group them, we will then name this group underwater pod.

on the color layer I use the brushes to fill out the colors for each part of the sprite.

This is the result after I have added the color layer, as you can see because I put the color layer under the outline layer we keep all of our line work in tact.

The resolution of our sprite is quite low, but because this sprite is going to be pretty small anyway I’m not worried too much.

Next we want to create two more layers, one is going to be for the light reflections and other highlights, the other is going to be for our shadows.

Now you could do this a few ways, you could if you wish just color pick the original color and change the brightness and darkness levels, darker for the shadows and brighter for the highlights.

However I am going to create my highlights and shadows by using two different layers with two different blend modes.

Now I create another layer within the same group and I’ll call it pod_multi, multi stand for multiply, I then go to the top of the Layer tab and select the drop down menu sitting just above the opacity bar.

From here I select multiply from the drop down menu, now this layer is a multiply layer, this means that it will add a dark color to an area relative to the color on the layer below it.

Next we create another layer called pod_screen and then select it and add a screen blend mode in exactly the same way.

The screen layer will lighten parts of the image, again relative to the layers below.

Before you go any further you want to make sure that the multiply layer is above the base color layer, the screen layer should then be above the multiply layer with the outline layer on the very top of the stack.

The individual group should now look like this:

Now when you create highlights and shadows you first want to use the color picker to get the color and then adjust the brightness up or down slightly depending whether you are on the multi_layer or the screen_layer.

So when you are doing a multiply layer i.e. shadow layer you will pick the color and then adjust the brightness down slightly, for the screen layer you would do the same but shift the brightness up.

Sometimes in can be helpful to adjust the hue slightly, shifting the color position on the color wheel, this is called a hue shift and can give greater texture to your shadows and highlights, making them warming or colder.

Now you can see with the Shadows added ( Multiply Layer ) and the highlights added ( Screen Layer ) the image pops and gives the 2D asset more form and presence.

Given a 2D image shadow and highlights makes it appear more 3 dimensional, mimicking the shadow and light hitting the surface of a real world object.

Now even though our shadow and light may seem fairly crude when compared to other designs it still gives our asset more life and presence in our scene.


Now I’m going to take this process and the layering structure and repeat it for the other three assets.

This means creating a group for each asset, inside each of these groups we will include four layers, an outline, a color, a multiply and a screen layer.

The result, after repeating the process, produces four decent looking game assets that we can now export out to our games.

Separating your color layer from you outline layer and having separate layers for highlights an shadows will enable you to more effectively create usable assets for you desktop or mobile games.

If you wanted you could go into greater detail by creating more layers for fine details like scratches, holes and other imperfections.

By then adding multiply and screen layers to each individual group you could control the shadows and highlights for each of them, this will change in complexity depending on how much detail you want to add to your designs.

Anyway I hope you found this tutorial useful and consider using this Krita workflow in your future designs.

If you liked this post then please consider taking a look at some of my other posts below.

]]>