Making an HTML5 version of the Game Pente: Part 1
Recently I decided to help a very special 11 year old with a class project to write a video game. It takes me back to when I was 11 and wrote my first games. Of course back then I wrote in BASIC on my Timex Sinclaire 1000 and did my best to save the code to a cassette recorder. Today we are going to write the game using HTML5 with WebMatrix and source control systems. Instead of targeting a 13" black and white TV there are a variety of consumption devices we need to target as well as modern touch interfaces. This means we need to have a solution that will work well on a phone, tablet, desktop and beyond. Fortunately HTML5 offers us the ability to start mobile/touch first and scale upward.
We decided we would write an online version of Pente that would work across multiple platforms and devices. I was first introduced to Pente in college when one of my good friends wrote a version of it to help him learn Turbo Pascal one weekend. Since he did it in one weekend back in the early 90s I figured I could do it over several weeks investing 2-3 hours each week.
Pente is a relatively simple game. The goal is to either get five of your stones in a row or 'capture' 5 pair of your opponents stones. The game board is made of a 12x12 square grid. Users take turns placing stones on line intersections. Each player tries to get 5 stones in a row either horizontally, vertically or along a diagonal while blocking their competitor from doing the same. If a player surrounds a pair of opponents stones, those stones are captured and removed from the board. Capturing 5 pairs of stones will also win the game.
In this blog post we are going to create the basic playing surface, a 12x12 grid. Since this game requires some basic drawing techniques I chose to use the Canvas element. Canvas is a new HTML5 element that provides a rich surface to dynamically draw, add images and perform animations common to just about any game. In this initial step I am going to set the canvas dimensions to a fixed 800x800 pixel size. I will make this more dynamic in the next step, but I wanted to simplify things to get it started.
< canvas id= "PenteBoard"></canvas >
You can set the height and width by specifying the values in attributes, but because I know this will need to be more dynamic based on the device and browser size I chose to set this in the JavaScript. In the following code below I set the height and width in the jQuery.ready method. I chose to go a little old school by using the getElementById method instead of a jQuery selector. So you can see once I get a reference to the canvas element I get its 2d context by calling the getContext method passing the "2d" parameter.
$ (document ).ready (function
() {var
canvas = document.getElementById ("PenteBoard"
),
context = canvas.getContext ("2d"
),
blockSize = 800 /12 ;
canvas.height = 800 ;
canvas.width = 800 ;//more stuff goes here
});
Next I define a blockSize variable I will use in the next step. I am getting what each block's dimension should be by dividing the 800 pixels used for the canvas by 12, the number of blocks across and down the playing surface. Next I set the canvas' actual height and width to 800 pixels.
After setting the canvas size its time to add the grid lines. Since the playing surface is a 12x12 cell grid we need to draw 11 vertical and horizontal lines. This means we need to employ 2 for loops that will count from 12 to 0. Why backwards you may ask? Well evidently counting backwards is faster in for loops than forwards, and I am always searching for performance tweaks. This trick was pointed out to me during a talk at the Dallas Day of .NET, and I have seen a few other references to this since then, so let's go with it ;).
Before executing the for loops, you should set the context's strokeStyle and lineWidth because these values will be use by each of the lines. To draw a line on a Canvas you call the context's begingPath method. Then you call the moveTo method supplying the x & y coordinates. This designates the point to start the line. For a vertical line this should be some variable x value and 0 y value. The moveTo call is followed by a lineTo, also passing x & y coordinates. This time the y coordinate should be 800 or the canvas' vertical height. Finally call the stroke method to complete the line drawing.
var
i = 12;
context.strokeStyle ="#000"
;
context.lineWidth = 0. 99;for
( i = 12 ; i > 0 ; i --){
context.beginPath ();var
x = blockSize + ( 12 - i ) * blockSize ;
context.moveTo (x + 0. 5 , 0);
context.lineTo (x + 0. 5 , 800);
context.stroke ()
}for
( i = 12 ; i > 0 ; i --){
context.beginPath ();var
y = blockSize + ( 12 - i ) * blockSize ;
context.moveTo ( 0. 5, y + 0 .5 );
context.lineTo ( 800, y + 0 .5 );
context.stroke ()
}
To create the horizontal lines repeat the for loop, but this time the x coordinates will be fixed and the y coordinates vary.
I chose to style the background color using a CSS rule and chose a green. This can be replaced with any color or image. I will explore more options here in a later post as well.
In the next post I will review how to draw a circle to represent a players stone's. Hopefully by the end of the May we will have a fully functional game to share with everyone as well as learning some basics of using the HTML5 canvas control and basic of AJAX gaming techniques.