How to Get Started with HTML5

Published September 05, 2013 by Maksim Mikityanskiy, posted by mmik005
Do you see issues with this article? Let us know.
Advertisement
The following article will be a very minimalist and straightforward guide to getting started with HTML5. While it is targeted at beginners, some coding experience is preferable since I won't bother with explaining Javascript basics. I'll leave that to other online tutorials or a Intro to Compsci course. This also is not platform specific in any way. It should run equally well on Linux, Windows or MacOS.

The HTML

Since this will be a web game, an HTML file is required. This is not a proper web page; it's just enough to make it work. [html] [/html] The first line specifies which HTML version to use, specifically 5.
Some older versions of Internet Explorer force compatability mode on certain web domains which is impossible to override from the web page. This may have been fixed since I last used Internet Explorer. It isn't an issue when testing, but if you try to put your code into a blogspot for example, HTML5 features like canvas may not work for that reason.
The second line is a dependency. JQuery does a lot of very useful things, but I will only be using it for mouse input in this article. The third line is a link to the script containing game logic. The background color is not necessary but I find it useful. Finally, you have the HTML5 canvas. The only unusual thing here is the onContextMenu; it returns false when the user right clicks on the canvas and as a result, no menu pops up.

The Game Logic

Declarations

Now to the game logic that goes in game.js. First come the declarations: var canvasID, context; var cursorX = 0, cursorY = 0; var canvasX = 0, canvasY = 0, canvasW = 800, canvasH = 600; var playerScore=0, aiScore=0; canvasID is the canvas itself. The context is an object specific to the canvas that contains all the drawing functionality. The cursor location is self explanatory. The canvas position is necessary in order to calculate the cursor position relative to the canvas. Canvas dimensions as variables also allows for greater flexibility while coding.

Mouse Code and Initialization

These two things need to be done first, which is the only reason why they are lumped together: function OnMouseMove(e){ cursorX = e.pageX-canvasX; cursorY = e.pageY-canvasY; } $(document).ready(function(){ canvasID = document.getElementById("gameCanvas"); canvasID.addEventListener("mousemove", OnMouseMove, false); context = canvasID.getContext('2d'); var rect = canvasID.getBoundingClientRect(); canvasX = rect.left; canvasY = rect.top; canvasW = rect.right-canvasX; canvasH = rect.bottom-canvasY; }) The OnMouseMove function takes an Event Handler as an argument. The event handler has the cursor position relative to the upper left corner of the page, not of the canvas. This is where canvasX and canvasY come in. The next bit is JQuery magic. When the document is ready (everything is loaded) the function is executed. Fetching the canvasID is straightforward. The next line is the last of the mouse input code. It adds an event listener that calls OnMouseMove when the mouse is moved. There are also mousedown and mouseup for mouse button presses and releases. e.which in the event handler specifices which button was pressed. Context fetching is simple. Next is where we find the actual location and dimensions of the canvas. getBoundingClientRect() returns the space which is taken up by the client. Getting the location is trivial. The rect right and bottom are the sum of the y position & height and the x position & width.

The Update Loop

function Run(){ context.fillStyle="black"; context.clearRect(0,0, canvasW, canvasH); context.fillRect(0,0, canvasW, canvasH); } setInterval(Run,20); Run will be the update loop. This is where everything that needs to be executed repeatedly will be put. setInterval tells the browser that it needs to be executed every 20 ms (or whatever you specify). Now to the drawing code. fillStyle and strokeStyle specify the color which you will be working with. The former is for filling shapes, and the latter is for drawing lines. clearRect empties the canvas of data. This doesn't really matter when you're starting out but it becomes important when you deal with transparency and compositing. The arguments are x, y, width and height. fillRect should be self explanatory; it takes the same arguments.

Drawing the Score

function DrawScores(){ context.fillStyle = "white"; context.font = "16px sans-serif"; context.fillText(aiScore, 30,30); context.fillText(playerScore, canvasW-50,30); } We have already worked with fillStyle. The font is specified as a string containing size and typeface. A couple of other valid typefaces are serif and monotype. fillText takes a string, x coordinate and y coordinate as arguments. strokeText will draw an outline around the text; just be sure to specify strokeStyle instead. Finally, call it in the Run function after you clear the canvas. function Run(){ context.fillStyle="black"; context.clearRect(0,0, canvasW, canvasH); context.fillRect(0,0, canvasW, canvasH); DrawScores(); }

The Classes

Javascript doesn't have classes like most other programming languages do, but they work. The only two things really necessary for a ping-pong game are the ball and the paddles. The Ball function Ball(){ this.radius = 8; this.x = canvasW/2; this.y = canvasH/2; this.vx = 5; this.vy = 0; this.Draw = function(){ //...\\ } this.Update = function(){ //...\\ } } The above code includes everything the ball will need; radius, position, and velocity. It will also need a Draw function and Update function. The Draw function is the simplest: this.Draw = function(){ context.fillStyle = "white"; context.beginPath(); context.arc(this.x, this.y, this.radius, 0, 3.1416*2); context.closePath(); context.fill(); } The only slightly unusual thing about drawing circles in HTML5 is the fact that the context doesn't have a function for explicitly drawing them. Instead, one can create an arc path. First call the beginPath function, then create an arc of angle 2?, and finally close the path. The arguments are x position, y position, radius, start angle and end angle. More complicated paths are possible, but that is beyond the scope of this article. Now to the next function: this.Update = function(){ this.x += this.vx; this.y += this.vy; //move the ball if(this.x > playerPaddle.x - playerPaddle.w/2 - this.radius){//check if the ball has traveled //far enough to the right to possibly interact with the right paddle. if(this.y >= playerPaddle.y - playerPaddle.h/2 && this.y <= playerPaddle.y + playerPaddle.h/2){ //check if it actually hit the paddle this.vy = (playerPaddle.y-this.y)*-0.4; //change the y velocity depending on which part //of the paddle the ball hit. this.x = playerPaddle.x - playerPaddle.w/2 - this.radius; //moves the ball out of the paddle this.vx*=-1; //make the ball bounce off }else{//if the player misses the ball, incriment the ai score and reset the ball. aiScore++; this.vy=0; this.x = canvasW/2; this.y = canvasH/2; } aiPaddle.AIChangeOffset();//AI thing, will make sense later. } if(this.x < aiPaddle.x + aiPaddle.w/2 + this.radius){//same thing if(this.y >= aiPaddle.y - aiPaddle.h/2 && this.y <= aiPaddle.y + aiPaddle.h/2){ this.vy = (aiPaddle.y-this.y)*-0.2; this.x = aiPaddle.x + aiPaddle.w/2 + this.radius; this.vx*=-1; }else{ playerScore++; this.vy=0; this.x = canvasW/2; this.y = canvasH/2; } } if(this.ycanvasH-this.radius){ this.vy*=-1; this.y=canvasH-this.radius;} //have the ball bounce off the top and bottom of the screen. } There's nothing HTML5-specific here, just ordinary arithmetic and algebra. I didn't comment the aiPaddle code because it's pretty much the same thing. The Paddle Start with the simplest things; variable declarations and the Draw function: function Paddle(){ this.x=0; this.y = canvasH/2; this.w = 32; this.h=64; this.aiv=9; //the maximum velocity with which the ai paddle can move this.aiOffset = 0; //how far off center the paddle will be when the ball reaches the end this.Draw = function(){ context.fillStyle="white"; context.fillRect(this.x - this.w/2, this.y - this.h/2, this.w, this.h); } This includes all the relevant physical properties, and a pair of AI-related properties. this.FloorAndCeiling = function(){ if(this.y < this.h/2) this.y = this.h/2; if(this.y > canvasH-this.h/2) this.y = canvasH-this.h/2; } The above makes sure that the paddle is not outside the boundaries of the screen. It puts a floor and a ceiling on the y position. The syntax may seem unusual but it works just the same. this.PlayerUpdate = function(){ this.y = cursorY; this.FloorAndCeiling(); } The above sets the paddle's y position equal to the cursor's y position. this.AIUpdate = function(){ if(ball.vx < 0){//0.1 if(ball.y + this.h*this.aiOffset > this.y -this.aiv){//1.0 if(this.y+this.aivball.y + this.h*this.aiOffset) this.y-=this.aiv; else this.y=ball.y + this.h*this.aiOffset; } this.FloorAndCeiling(); //3.0 } } The AI code is a little more difficult to understand conceptually, so the lines are labeled. 0.1 tells the AI to only do stuff if the ball is moving towards it. This isn't absolutely necessary and the game will work fine without this line. 1.0 checks where the ball is relative to the paddle. It's true specifically when the ball is above the paddle. + this.h*this.aiOffset simulates error by changing where the center of the paddle actually is. aiOffset is a number between -0.45 and 0.45 so the new "center" will always be on the paddle. 1.1 checks if the y distance between the paddle "center" and the ball is greater than the maximum velocity at which the AI can move the paddle. If it is, it moves the paddle by that amount. Otherwise, 1.2 the ball is "within range" so instead of overshooting, it just moves to the ball's y position. 2.0 is pretty much the same thing just in the other direction. 3.0 makes sure that the AI doesn't actually move the paddle off screen. this.AIChangeOffset = function(){ this.aiOffset = (Math.random()-0.5)*0.9; } } Finally, just declare that last function which changes the offset. If you remember, it is called every time the ball bounces off the player's paddle. Remember to close all curly braces!

Variable Initialization

var ball = new Ball(); var aiPaddle = new Paddle(), playerPaddle = new Paddle(); playerPaddle.x = canvasW; //move the paddle to the other side of the screen Here we create the ball and paddles.

The Game Loop

Finally, update the Run function; function Run(){ //NEW CODE PT 1 aiPaddle.AIUpdate(); playerPaddle.PlayerUpdate(); ball.Update(); //Update all the game objects //END NEW CODE PT 1 context.fillStyle="black"; context.clearRect(0,0, canvasW, canvasH); context.fillRect(0,0, canvasW, canvasH);//clear the context //NEW CODE PT 2 ball.Draw(); aiPaddle.Draw(); playerPaddle.Draw(); DrawScores();//Draw it all //END NEW CODE PT 2 } Everything here is quite straightforward. Just call all the Update and Draw functions in the objects, and draw the score. The only important thing here is to Update before Drawing, and to clear the context before Drawing as well.

Conclusion

This is perhaps the simplest functioning game that one can make. It has a little bit of everything: graphics, input, physics, and AI. It doesn't use any advanced features, but it's a good starting point.
Cancel Save
0 Likes 9 Comments

Comments

EDI
EDI

Great article, thanks for promoting HTML5 games!

As an example of a more complex HTML5 game have a look at http://edigames.com/revelimmortal

its a work in progress large scale RPG we're developing.

-Raymond

September 05, 2013 02:15 PM
Kaptein

I really needed this :)

I hope there's more to come

September 05, 2013 04:26 PM
ravenking99

I studied html and javasrcipt. Thanks for the interesting article!

September 06, 2013 08:51 PM
lee101

Nice article! Making games like pong, snake, pacman, space invaders ect is a great way to learn.

Checkout this open source word puzzle game i made with html5 Word Smashing Word Puzzle Game

The source code is on github, it uses JQuery, Twitter Bootstrap and Python for storing high scores/achievements.

--Lee Penkman

Addicting Word Games

September 07, 2013 07:25 AM
Krohm

Nice! How are you with Object Oriented JavaScript? It was my understanding you were meant to add object properties to Ball.prototype instead of doing that in the constructor using this.

September 09, 2013 05:58 AM
Ronnie Mado Solbakken

Nice read, as I'm learning HTML5 myself. I've just finished the basic with Bucky Roberts from The New Boston, and once I'm done TheCherno's Java Game Programming, I'm gonna go more in-depth with HTML5. Mostly for general web design, but I do want to design some HTML5 games as well.

Also, to all you newbiew. Notepad++ might be a good programming tool, but personally I've just downloaded Sublime Text 2 and it's very similar to Notepad++ but seems MUCH better.

http://youtu.be/EjDMqr8PC7c

September 09, 2013 11:37 AM
mmik005

Thanks for the positive feedback everyone!

@Krohm while you are technically right, I think that using the prototype would add too much complexity to this game. There is no need for more advanced OOP, so just using this does the trick.

However I am not an expert in Javascript by any means. I will look further into it to see if maybe I did indeed miss something.

September 12, 2013 03:46 AM
lvendrame_br

Thanks for this article.

I implemented and published it on my github with some modifications.

https://github.com/lvendrame/Html5CanvasPong

December 31, 2013 12:31 AM
hafo

Hi, thanks for the article,

however for game creators that don´t have programming skills and want to create HTML5 games we have created a drag&drop tool for creating HTML5 games: WiMi5

Have a look to it :)

December 11, 2014 03:53 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!

A minimalist guide to getting started with HTML5 and Javascript by making a 2D table tennis game.

Advertisement

Other Tutorials by mmik005

mmik005 has not posted any other tutorials. Encourage them to write more!
Advertisement