HTML5 Games Most Wanted

Built the best HTML games.


Rob Hawkes, Russell Goldenberg, Gaëtan Renaudeau


278 Pages

20470 Reads

72 Downloads

English

PDF Format

24.9 MB

HTML Learning

Download PDF format


  • Rob Hawkes, Russell Goldenberg, Gaëtan Renaudeau   
  • 278 Pages   
  • 26 Feb 2015
  • Page - 1

    read more..

  • Page - 2

    read more..

  • Page - 3

    read more..

  • Page - 4

    read more..

  • Page - 5

    read more..

  • Page - 6

    read more..

  • Page - 7

    read more..

  • Page - 8

    read more..

  • Page - 9

    read more..

  • Page - 10

    The State of Open Web Games 5 HTML5 canvas (often referred to as simply “canvas”) is a JavaScript API and corresponding HTML element that allows for bitmap graphics to be created and edited within the browser. The plus points of canvas are that it’s speedy and that can produce pin-point pixel graphics without relative ease. The negative aspects to canvas are that read more..

  • Page - 11

    Chapter 1 6 The limitation of the HTML5 audio element is that its purpose is really to play single audio files, like background music within a game. It isn’t suitable for sound effects, particularly if they are fast paced and if there are many of them to play at once. To solve this, the Audio Data API (Mozilla) and Web Audio API (Chrome) have been introduced read more..

  • Page - 12

    The State of Open Web Games 7 web games today would, at worst, simply stop working as soon as an internet connection failed, and, at best, they would stop sending data to your server and saving player data. When your player refreshes the page that the game is on, they’ll just see a blank page and all their hard work achieved while offline will have been lost. read more..

  • Page - 13

    Chapter 1 8 the cursor and locking it in place so that it doesn’t hit the edges of the screen. This means that instead of relying on x and y coordinate values for mouse position in related to the top-left corner of the browser, you instead rely on x and y distance values from the position that the mouse was locked to. Console-like experience with the Gamepad read more..

  • Page - 14

    The State of Open Web Games 9 With much more on the way These technologies are really just scratching the surface when it comes to creating games on the web using open technologies. Mozilla and other companies are working hard to bring you these APIs and services to help make the web a better place for games. There are plenty of good open web games out there read more..

  • Page - 15

    Chapter 1 10 Figure 1-1. Screenshot from HTML5 Bejeweled Figure 1-2. Screenshot from HTML5 Angry Birds read more..

  • Page - 16

    The State of Open Web Games 11 Figure 1-3. Screenshot of the Robots Are People Too web site Figure 1-4. Screenshot from Runfield read more..

  • Page - 17

    Chapter 1 12 Figure 1-5. Screenshot from Brandon Jones’s TF2 WebGL demo Distribution and monetization options already exist Something that I touched on earlier in this chapter is the ability to distribute your games and make money from them, something that is necessary for the web to become a viable platform for games. The good news is that there are plenty of read more..

  • Page - 18

    The State of Open Web Games 13 The Chrome Web Store uses Google Checkout as the payment provider and they will take 5 percent of each transaction, which is significantly less than the rates on platforms like iOS. Facebook With over 800 million users, it made a lot of sense for Facebook to get into app distribution. The applications and games provided on Facebook read more..

  • Page - 19

    Chapter 1 14 browsers. If the open nature really is not an option to you, then perhaps open web gaming is not something to consider until you can justify the pros and cons that come with it as a platform. However, all of this doesn’t necessarily mean other platforms are more viable. For example, Flash isn’t developed for mobile devices any longer and other read more..

  • Page - 20

    15 Chapter 2 Complexity from Simplicity This chapter will take a look at game design to see how you can make a game fun at its most basic level. A case study of a game called “A to B” will be used to highlight some of the essential theories of design implementation. This chapter will also discuss the use of the JavaScript library, Processing.js in the read more..

  • Page - 21

    Chapter 2 16 Game design background Unlike many game designers, I have never been obsessed with gaming. As a child, I was not allowed to own a gaming console (PC not included) until I was in high school. However, like most game enthusiasts, I can recall the first moment games became an important part of my life. For me, it was when my babysitter brought me read more..

  • Page - 22

    Complexity from Simplicity 17 When the player presses Go, the ball is launched (at the same angle and velocity every time), and then is subjected to gravity. If the ball hits point B, the player receives points and moves on to the next level. If the ball goes off screen, the ball is returned to its original resting position and is allowed to go again until the read more..

  • Page - 23

    Chapter 2 18 At its core, A to B is influenced by the Atari classics that I mentioned earlier. At the start, I recognized that since I am new to gaming, I needed to keep it simple. Asteroids was in black and white and the player controlled a triangle, yet somehow it was one of the most compelling games I ever played. I decided that in order to enter read more..

  • Page - 24

    Complexity from Simplicity 19 Once I established the technology, I set up a list of deliverables and deadlines. Planning out a timeline for this is useful for project organization and motivation. Having certain deliverables due at a certain time not only made me stay on schedule, but prevented me from getting sidetracked. My initial goal was to finish the entire project read more..

  • Page - 25

    Chapter 2 20 activity, you should inform your players to use the “think aloud” method. This is a common practice in user interface prototyping. You instruct players to verbalize all of the decisions and thoughts that are going through their minds as best they can. This gives you insight into what everything in your game is triggering in players’ minds. If a player read more..

  • Page - 26

    Complexity from Simplicity 21 Figure 2-4. A to B high-score list Rules of simplicity A to B helped me learn a few valuable lessons for making a simple, yet compelling, game. Focus on the core mechanics. By keeping A to B stripped down and transparent, the player is able to participate directly with the core mechanics of the game. While I’m not saying read more..

  • Page - 27

    Chapter 2 22 not frustrating to learn how to play the game. It is important to immediately provide the tools for or instruction on how to play your game. Players should be able to participate and understand how the mechanics work right off the bat. This does not imply, however, teaching players how to solve the problems. You want to leave that to them, because read more..

  • Page - 28

    Complexity from Simplicity 23 Why A to B works Whether or not you care for the simple graphics, game play in A to B just works. This can be attributed to much of the theory that I read surrounding game development. First and foremost was Jesse Schell’s Art of Game Design: A Book of Lenses (Morgan Kaufmann, 2008). This book did a fantastic job breaking read more..

  • Page - 29

    Chapter 2 24 Additionally, Processing.js lacks power. In the original version, you can draw thousands of objects to the screen without sacrificing frame rate. With the JavaScript port, however, there is a significant disparity between the two. This is largely due to the constraints of using the HTML5 canvas; but with each browser update, we are seeing increased rendering read more..

  • Page - 30

    Complexity from Simplicity 25 In regards to the JavaScript version of Processing, the following is a rundown of the strengths and weaknesses of Processing.js: Strengths Excellent graphics library Don’t need to learn JavaScript Great forum and community Cross-browser compatibility Can write stand-alone or JavaScript integrated code It’s free! Weaknesses read more..

  • Page - 31

    Chapter 2 26 Basic Processing syntax If you are familiar with Processing or Java, this bit will look familiar to you. void setup(){ size(400,200); } void draw(){ background(0); fill(255,0,0); ellipse(mouseX,mouseY,50,50); } This is a very basic example of the Processing syntax. This code will create a canvas that is 400 × 200 pixels. It will then repeatedly draw an read more..

  • Page - 32

    Complexity from Simplicity 27 In-line processing For people like me, you may want more access to the code than this. Processing.js allows you to write your Processing code directly in the script tag. The processing.js file will automatically convert what you write into Processing. The following is what the same sketch would look like using this method. <html> read more..

  • Page - 33

    Chapter 2 28 size(400,200); } void draw() { background(0); fill(250); read more..

  • Page - 34

    Complexity from Simplicity 29 Importing and loading images For anyone out there that wants to make a game, it is quite likely that you will want to have some sort of images involved. In order to incorporate them in your Processing.js code, it is handled a bit differently than with building web sites. The following is a sample code that will import two images and read more..

  • Page - 35

    Chapter 2 30 $.post("highscorelist.php",{score: theScore, name: playerName},function(data){ result = data; } As long as you can do some simple PHP communication, you can easily implement any sort of data storage that you can envision. Summary By now you have hopefully witnessed the power of Processing.js and the benefits of keeping things simple. While games are becoming read more..

  • Page - 36

    31 Chapter 3 How to Make Multi-Platform HTML5 Games from Scratch Introduction Today, applications like Twitter, or games like Angry Birds, are available on many platforms. The number of different instances of an application can become huge. Such an application can target the number of platforms (mobile, tablet, desktop), the number of operating systems (iOS, Android, webOS, read more..

  • Page - 37

    Chapter 3 32 Figure 3-1. Various platform directions It’s almost unfeasible to develop so many instances and maintain them yourself. You want to fix bugs and add features once—and only once. Hence, what’s required is a common language to describe an application for multiple instances—and that’s exactly what the web proposes. We don’t need to learn new, read more..

  • Page - 38

    How to Make Multi-Platform HTML5 Games from Scratch 33 Throughout this chapter, we will examine the case study of Same Game Gravity (a game available on six platforms: iPad, iPhone, Android, web, Chrome Store, and Facebook; see http://github.com/gre/chess- game) and look at how we can apply these lessons to our own projects. Same Game Gravity is a mind-bending, ball read more..

  • Page - 39

    Chapter 3 34 stylesheets, and JavaScript scripts (to learn more about all available elements, see the Other Resources section). The most recently released version of the HTML specification is HTML4, but for several years the fifth version has been a work in progress and its release is imminent. But “HTML5” as a buzzword describes more than just the next version of HTML: read more..

  • Page - 40

    How to Make Multi-Platform HTML5 Games from Scratch 35 <script type="text/javascript" src="game.js"></script> </head> <body> <div id="pages"> <section id="menu" class="current"></section> <section id="game"></section> <section id="help"></section> </div> read more..

  • Page - 41

    Chapter 3 36 CSS, a descriptive stylesheet language CSS (Cascading Style Sheets) allows us to easily describe web application styles through a list of rules. CSS is often neglected or misunderstood in game development, but CSS—especially in its third version— is a very powerful tool that you should most certainly be interested in. With CSS, we can tersely describe styles read more..

  • Page - 42

    How to Make Multi-Platform HTML5 Games from Scratch 37 Some significant CSS properties If you want to learn some basic CSS properties, we recommend you follow some of the resources listed at the end of this chapter. For now, we’ll concentrate on some of the more advanced and indispensable features for games. Note Some of the upcoming features we’ll cover read more..

  • Page - 43

    Chapter 3 38 Transitions CSS Transitions are a way to easily add animations to a web page. Basically, it allows us to perform an animation between two given states. CSS properties will change CSS values, which will be animated smoothly over a specified duration. To use CSS Transitions, like in a state machine, we first need to identify states and actions. States are read more..

  • Page - 44

    How to Make Multi-Platform HTML5 Games from Scratch 39 #myel:hover { color: green; padding: 10px; /* transition-* are getted by inherence */ } CSS Transitions allows us to make degradable games because CSS interpreters are nice; if they meet unknown properties, they simply ignore them and keep working. So if a browser doesn’t support CSS Transitions, the read more..

  • Page - 45

    Chapter 3 40 (Ctrl+A). Moreover, on mobile and tablet, you usually want your application (your game) to look like a real native application. Imagine playing a real-time game and accidentally triggering the text select mobile user interface! It will rudely interrupt the game, most likely leading to a dead player and an angry user. Hence, you have to prevent the default read more..

  • Page - 46

    How to Make Multi-Platform HTML5 Games from Scratch 41 Stylesheet languages above CSS SASS (or SCSS) and LESS are both stylesheet languages that simplify writing and maintaining CSS source codes. They are compiled into regular CSS. We will use SASS in our examples (in fact, we’re using the “old SASS style,” which is just personal preference; both provide quite read more..

  • Page - 47

    Chapter 3 42 top: 0 left: 0 width: 100% height: 100% +box-sizing(border-box) #pages > section z-index: -1 opacity: 0 +translate3d(-100%, 0, 0) +transition-property((transform, opacity)) +transition-duration((1s, 0s)) +transition-delay((0s, 2s)) &.current z-index: 0 opacity: 1 +translate3d(0%, 0, 0) read more..

  • Page - 48

    How to Make Multi-Platform HTML5 Games from Scratch 43 This means that only the current page is in the viewport of the browser (and take the full space with the styles we defined), other pages are outside, so are effectively invisible. We define a 1-second transition duration to perform a smooth animation. The opacity transition is indispensable: it prevents pages read more..

  • Page - 49

    Chapter 3 44 continueGame: function(){ /* ... */ }, newGame: function(){ /* ... */ scene('newgame'); }, game: function(){ /* ... */ scene('game'); }, help: function(){ /* ... */ scene('help'); } } }(); Listing 3-8. Starting the Router Entry Point of the Game Controller $(document).ready(function(){ ns.Controller.init(); read more..

  • Page - 50

    How to Make Multi-Platform HTML5 Games from Scratch 45 rook | knight | bishop | queen | king | pawn indicates the type of the piece current means the piece on the square is selected by the user playable means the square is playable for the selected piece That’s everything to make the user interface work. We can now style it in CSS and read more..

  • Page - 51

    Chapter 3 46 #chessboard > div &.current, &.current.lighter background-color: #beb results in the following CSS: #chessboard > div.current, #chessboard > div.current.lighter { background-color: #bbeebb; } Game logic We will now implement the game logic in the game.js JavaScript file. Before writing it, we need to know some best practices for good code read more..

  • Page - 52

    How to Make Multi-Platform HTML5 Games from Scratch 47 } }(); // ... }(window)); Inside the first closure, we have defined a ns argument, which refers to the window variable because we pass it in argument at the end. This is how you can redefine an object access name. This ns argument is used as the “root” of all services we want to read more..

  • Page - 53

    Chapter 3 48 var c = String.fromCharCode(i+97); self.pieces.push( piece('white', firstRowTypes[i], c+'1') ); self.pieces.push( piece('white', 'pawn', c+'2') ); self.pieces.push( piece('black', 'pawn', c+'7') ); self.pieces.push( piece('black', firstRowTypes[i], c+'8') ); } read more..

  • Page - 54

    How to Make Multi-Platform HTML5 Games from Scratch 49 We want to be able to save a game, as shown in Listing 3-12, so that we can retrieve it between interruptions. Listing 3-12. Saving Game ns.Storage = function() { var gameKey = 'chessdemo_game'; return { saveGame: function(game) { localStorage.setItem(gameKey, JSON.stringify(game)); read more..

  • Page - 55

    Chapter 3 50 The result Figures 3-3 and 3-4 show how the chess game should appear. Figure 3-3. Menu display Figure 3-4. chessboard 4 read more..

  • Page - 56

    How to Make Multi-Platform HTML5 Games from Scratch 51 Mobile frameworks jQuery and Zepto jQuery is an awesome, widely-used JavaScript library that makes working with the DOM easier and offers an abstraction to support all browsers. Zepto is an alternative to jQuery that only targets WebKit browsers. Its usage is perfect for mobile and tablet platforms because they mostly read more..

  • Page - 57

    Chapter 3 52 Configuration of our chess game Listing 3-14 shows the config.xml we used to make our chess game: Listing 3-14. config.xml <?xml version="1.0" encoding="UTF-8"?> <widget xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0" id="fr.gaetanrenaudeau.chess" version="1.0.0"> <name>Chess</name> read more..

  • Page - 58

    How to Make Multi-Platform HTML5 Games from Scratch 53 Moreover, we need tools to make game development and maintenance easier. In fact, this tool quickly becomes essential to quickly spread (you can almost even say “compile”) the changes we made on a single source to different instances of the application. WebAppBuilder is just a configurable Makefile, which targets read more..

  • Page - 59

    Chapter 3 54 background.jpg: the background of the game icon.png: the icon of the game Chewy.ttf: the font used The following is an extract of an Android/Makefile: SRC_DIR = ../src DIST_DIR = assets RESOURCES = images Chewy.ttf background.jpg icon.png VIEWS = index.html=game.html:"{version:'1.0'}" SCRIPTS = game.min.js=!game.js lib.min.js=underscore-min.js,zepto.min.js STYLES = read more..

  • Page - 60

    How to Make Multi-Platform HTML5 Games from Scratch 55 To do this, we’ll inject translations in the DOM on page load with JavaScript. Our convention to identify a translation key is to have a i18n-{key} class on the DOM tag to replace the translation where {key} is the key of the translation (the key should only contain alphanum and _ characters to be read more..

  • Page - 61

    Chapter 3 56 updateDOM(); }, get: function(key) { var dict = dictionaries[lang] || dictionaries[defaultLang]; return ""+dict[key]; }, updateDOM: updateDOM } }(); $(document).ready(i18n.init); Pure DOM vs. canvas–based game There are mainly two ways to develop a game. The first read more..

  • Page - 62

    How to Make Multi-Platform HTML5 Games from Scratch 57 ctx.beginPath(); ctx.arc(.5, .5, .4*size, 0, Math.PI*2, true); ctx.fill(); // fill a disc with gradient ctx.restore(); // restore the last ctx state saved } Tip There is much more to explore with canvas; see www.w3.org/TR/html5/the-canvas- element.html. Solutions comparison: Canvas The problem with read more..

  • Page - 63

    Chapter 3 58 an acceptable fallback: the application should work even if some effects don’t occur (for instance, not supporting CSS Transitions will simply disable the transition animation). CSS transforms are very powerful and efficient (rotation, scale, skew, etc.) and are hard to make in canvas. You can mix both To summarize, canvas is awesome but should be used wisely. read more..

  • Page - 64

    How to Make Multi-Platform HTML5 Games from Scratch 59 Other resources The following web sites provide additional useful information on HTML5, the latest web technologies, and advanced JavaScript: www.w3.org: Web specifications are available at The World Wide Web Consortium (W3C), an international community that develops open standards to ensure the long-term growth of the read more..

  • Page - 65

    61 Chapter 4 Creating, Saving, and Loading Tracks This chapter will explain a few of the basics on structuring games in JavaScript as well as game play in general. We will also cover a few JavaScript tips and tricks. Who we are, what we will build, and why We are two of the five creators of Marble Run ( marblerun.at), a rather successful browser game. The read more..

  • Page - 66

    Chapter 4 62 Figure 4-1. Screenshot of application The application and the sense behind it The goal of Marble Run is to build the longest marble run in the world. Every player can build his own little marble run, also called a “track.” After saving this track, it will be appended to the existing tracks, forming a big, collaborative marble run. A track is built with read more..

  • Page - 67

    Creating, Saving, and Loading Tracks 63 Figure 4-2. Screenshot of Marble Run You see, Marble Run is very similar to what we plan to do in this chapter—and that’s not by accident. We get a lot of questions about the way we do this and that in Marble Run. So, our little application makes a great example of how you can store certain user data (such as read more..

  • Page - 68

    Chapter 4 64 Why levels are important We want to take a closer look at the different types of games and how they are built up. There are basically two kinds of game plays when it comes to browser games. The ones build on certain levels, created by the maker, such as all the jump-and-run games, or, for instance, Angry Birds. Then there is the kind with read more..

  • Page - 69

    Creating, Saving, and Loading Tracks 65 Figure 4-3. Screenshot of a creative track on marblerun.at Split the big thing into small components Now it’s time to get back to our little app. The first step with every application is to make a basic plan of how it’s going to be structured. Everything seems very easy at first, but it’s for sure that it will turn read more..

  • Page - 70

    Chapter 4 66 For the styling of the application, we need some CSS. So within the create-save-load-tracks folder, we create another folder named stylesheets. Now let’s add an empty style.css file to that folder for our CSS. But as you probably have already figured out, that is not enough. When writing a browser game you typically have to expect lots of JavaScript. read more..

  • Page - 71

    Creating, Saving, and Loading Tracks 67 <input id="track-name" type="text" placeholder="Track Name"/> </form> </section> The second section element holds a form with a lot of buttons, with each button representing a brick. Later these buttons will be used to select a specific brick type. <section id="bricks-container"> <form> read more..

  • Page - 72

    Chapter 4 68 Adding a little style When you open the HTML file in a browser, you will notice that things look a little shaken up. What we need is a basic CSS stylesheet to get all the parts of our application into the right places. To accomplish this, we link to our previously created style.css file. After adding the stylesheet link, the <head> block of read more..

  • Page - 73

    Creating, Saving, and Loading Tracks 69 margin-right: 50px; float: left; } section#bricks-container { width: 100px; margin-right: 50px; float: left; } section#tracks-container { width: 300px; float: left; } button#save, input#track-name { float: right; } section#tracks-container h1 { margin: 0; } The JavaScript structure After finishing read more..

  • Page - 74

    Chapter 4 70 Download (jQuery); button. Found it? Click it! In case your web browser doesn’t ask you where to save this page, right-click in the page and select “Save page.” Save the page as jquery.js into our javascripts folder. There are many ways to structure an application in JavaScript, but one rule always applies: make your code as modular as possible! read more..

  • Page - 75

    Creating, Saving, and Loading Tracks 71 the context is more the API of the canvas to be used with JavaScript. We will explain how to get the context of a canvas element later. In the last block, we declare four global variables. The store and grid are two instances of store.js and grid.js, the two modules that we talked about earlier. The two other variables read more..

  • Page - 76

    Chapter 4 72 means we have to be very aware of the order in which the elements are drawn onto the canvas. Once you draw something on it, you cannot draw underneath it. First things first. In this case, we want to draw the grid before we draw any bricks. This is why we decided to have everything drawn in a recursive sort of way. The application contains a read more..

  • Page - 77

    Creating, Saving, and Loading Tracks 73 Now, for the draw function. function draw() { clearCanvas(); context.translate(0.5, 0.5); grid.draw(context); } First we clear the canvas. The command context.translate(0.5, 0.5); moves the drawing context half a pixel to the right and bottom. We need this because we will draw a lot of 1-pixel lines and the read more..

  • Page - 78

    Chapter 4 74 for (var row = 0; row < numberOfRows; row++) { context.moveTo(0, row * this.cellSize); context.lineTo(gridWidth, row * this.cellSize); } context.stroke(); } Wow! That is a really big chunk of code. So, what do we do here? For the rectangle around the grid, we simply use the context.strokeRect() function. The rectangle starts in read more..

  • Page - 79

    Creating, Saving, and Loading Tracks 75 Figure 4-5. Screenshot of the application so far The bricks Now we get to a very interesting part: the first brick. First, we will have to create a new class in a new file. Since we are going to have a few different brick types, we might want to add a new folder, called bricks, in the javascripts folder (see read more..

  • Page - 80

    Chapter 4 76 Figure 4-6. Folder structure Square The first brick that we go over is a simple rectangle. var Square = function() { this.row = 0; this.column = 0; this.type = "Square"; this.rotation = 0; } We initialize the class with a row and a column attribute. We also need to know the type; that way we can easily find out read more..

  • Page - 81

    Creating, Saving, and Loading Tracks 77 To get our brick to the right position, we will translate the context to this point. context.translate(x, y) moves the coordinate system of the context by x and y. That means once you translated the context by (10, 10) you would start to draw at (10, 10), with a command like moveTo(0, 0). In our case, we move the read more..

  • Page - 82

    Chapter 4 78 context.restore(); } The first difference is the radius in the draw function. We need to calculate it so we can draw a proper circle. The radius is half the brick size. After calculating, we do the same context.save(), context.translate(), and context.restore() magic we know from the square brick. Only this time, we use a path to draw the brick; so, read more..

  • Page - 83

    Creating, Saving, and Loading Tracks 79 The first special part is as follows: context.translate(BRICK_SIZE / 2, BRICK_SIZE / 2); context.rotate(this.rotation * Math.PI / 180); context.translate(- BRICK_SIZE / 2, - BRICK_SIZE / 2); What do we do here? We know that every brick saves its rotation in its this.rotation attribute. Before we draw anything, we must rotate the read more..

  • Page - 84

    Chapter 4 80 context.beginPath(); context.fillColor = 0; context.moveTo(0, 0); context.lineTo(BRICK_SIZE, BRICK_SIZE); context.lineTo(0, BRICK_SIZE); context.closePath(); context.fill(); context.restore(); } Drawing the triangle is also pretty easy. We move our imaginary pencil to the top-left corner after we started a new path. The next line goes read more..

  • Page - 85

    Creating, Saving, and Loading Tracks 81 var mouseY = event.offsetY || event.layerY; var column = Math.floor(mouseX / BRICK_SIZE); var row = Math.floor(mouseY / BRICK_SIZE); } First we read the X and Y position relative to the top-left corner of the canvas element. Every mouse click triggers a certain event. This event contains a lot of information, including read more..

  • Page - 86

    Chapter 4 82 Grid.prototype.addBrick = function(brick, context) { this.bricks.push(brick); brick.draw(context); } It adds the brick to its container of bricks. And after that, we just have to draw the brick onto the grid. We don’t have to trigger the big draw function in the application.js. This would be what we developers call overkill! There is no need to read more..

  • Page - 87

    Creating, Saving, and Loading Tracks 83 function setBrick(buttonID) { if (currentButton) { currentButton.removeAttr("disabled"); } currentButton = $("#" + buttonID); currentButton.attr("disabled", "disabled"); switch (buttonID) { case "square-brick": selectedBrickClass = Square; read more..

  • Page - 88

    Chapter 4 84 var brick = new selectedBrickClass(); brick.column = column; brick.row = row; grid.addBrick(brick, context); } And that was all you had to do for that! Note We also added a safety drop out of the function. If the user didn’t select a brick type before clicking on the grid, the selectedBrickClass would be null; therefore, we read more..

  • Page - 89

    Creating, Saving, and Loading Tracks 85 Grid.prototype.getBrickAt = function(column, row) { for (var i = 0; i < this.bricks.length; i++) { if (this.bricks[i].column === column && this.bricks[i].row === row) { return this.bricks[i]; } } return null; } Very simple! We just loop through all the bricks, and if the column and the row read more..

  • Page - 90

    Chapter 4 86 Saving tracks Let’s walk through this step-by-step. First, we create a Store class. We add another new file named store.js to our includes and start out with something like this: var Store = function() { this.tracks = []; } The tracks array will resemble our database. That means we need a method that lets us add tracks to the array. What read more..

  • Page - 91

    Creating, Saving, and Loading Tracks 87 information. So, what do we need for re-creation later? Obviously the position on the grid, so let’s store the column and row properties in our values object. The brick.type property is also very important; without it we don’t know what type of brick we are talking about, so let’s save that too. The last important read more..

  • Page - 92

    Chapter 4 88 Once we have the JSON representing our track, we use the counter function to JSON.stringify, which is JSON.parse. This function will convert the argument string into a handy JavaScript object that we can work with. In our case, we get an array with all the brick value objects. This array now must somehow be converted into an array full of actual bricks. read more..

  • Page - 93

    Creating, Saving, and Loading Tracks 89 initUI(); draw(); }); The next step is adding functionality to the Save button. So let’s skip to the iniUI() function and add another click callback, as follows: $("#save-track").click(function(event) { event.preventDefault(); store.saveTrack(grid.bricks); }); As you can see, this one is really easy. We basically read more..

  • Page - 94

    Chapter 4 90 This might look a little complicated, but it’s actually very simple. First, we use jQuery to create an empty <p> tag and an <a> tag. We can leave the href of the <a> empty, but still set a href attribute. Why? That way the browser still marks it as a link. But we don’t want it to behave as a regular link and, therefore, read more..

  • Page - 95

    Creating, Saving, and Loading Tracks 91 You can get the complete code for this project from GitHub; just head over to https://github.com/stravid/create-save-load-tracks and download everything. If you like, you can even press the Fork button and surprise us by adding other bricks to the application! How does a wave- form brick sound? You get the idea, we are looking read more..

  • Page - 96

    93 Chapter 5 3D CSS Tutorial Harness the power of 3D CSS transformations to make a lightning-fast iPad game with creative JavaScript Introduction HTML5 canvas is, of course, brilliant. But it has to be said, its performance on iPads (and most other devices) leaves much to be desired. The GPU-accelerated canvas in iOS 5 is a definite improvement, but it’s possible to read more..

  • Page - 97

    Chapter 5 94 Our game has three main visual components: the puffer fish, the background layers, and the particles that occur when the fish explode (see Figure 5-1). Every graphical object is a DOM element—in fact, they’re all just divs with image backgrounds and I’m animating them by adjusting their CSS properties with JavaScript. Figure 5-1. The puffer fish, read more..

  • Page - 98

    3D CSS Tutorial 95 Game variables The following shows the game variables. // DOM elements var container = document.createElement('div'), layer1 = document.createElement('div'), layer2 = document.createElement('div'), // screen size variables SCREEN_WIDTH = 1024, SCREEN_HEIGHT = 768, HALF_WIDTH = SCREEN_WIDTH / 2, HALF_HEIGHT = SCREEN_HEIGHT / 2, // fish variables read more..

  • Page - 99

    Chapter 5 96 layer2.style.background = 'url(img/parallaxFront.png) transparent'; document.body.appendChild(layer2); container.className = "container"; container.style.webkitPerspective= "400"; container.style.webkitPerspectiveOrigin= HALF_WIDTH+"px "+HALF_HEIGHT+"px"; container.style.width = SCREEN_WIDTH; container.style.height = SCREEN_HEIGHT; Events and game loop timer The following read more..

  • Page - 100

    3D CSS Tutorial 97 Game loop overview The following is the main game loop. The comments should explain enough about what’s going on. We're adding more fish, updating the parallax layers, iterating through all the fish, and updating them all, then finally calling emitter.update(), which looks after the particles. function gameLoop() { // every 20 frames, make a read more..

  • Page - 101

    Chapter 5 98 Our Fish object handles the position, update, and appearance of our fish. The constructor parameters specify its 3D position, the image URL, and the image size. We’re creating an HTML div element and setting its CSS properties so it has a fixed size, absolute position, and a background image. function Fish(posx, posy, posz, imageSRC, imageWidth, imageHeight) read more..

  • Page - 102

    3D CSS Tutorial 99 styleStr, sx = Math.sin(counter*0.4)*0.04 + this.size, sy = Math.sin(Math.PI + counter*0.4)*0.04 + this.size; dom.style.webkitTransform = "translate3d("+this.posX+"px, "+this.posY+"px, "+this.posZ+"px) scale("+sx+","+sy+") rotate("+Math.sin(counter*0.05)*20+"deg)"; }; this.rotate = function(angle, useRadians) { // read more..

  • Page - 103

    Chapter 5 100 this.velY += this.gravity; // and the velocity to the position this.posX += this.velX; this.posY += this.velY; this.posZ += this.velZ; //rotate pos and vel around the centre counter++; this.rotate(2); }; As well as x, y, and z position, we also have an x, y, and z velocity. Velocity is how much it moves in each read more..

  • Page - 104

    3D CSS Tutorial 101 Cross-browser considerations For the sake of simplicity, we’re blatantly ignoring cross-browser issues, and only worrying about iOS and webkit. But is it possible to make this work across all browsers? Modern browsers pretty much all support these transforms, but they all use their own prefix. In our code, you see properties of the webkitTransform read more..

  • Page - 105

    Chapter 5 102 fishes.push(fish); // then add touch and mouseover events to the fish. fish.domElement.addEventListener("mouseover", fishMouseOver, true); fish.domElement.addEventListener("touchstart", fishTouched, true); container.appendChild(fish.domElement); } Setting the fish properties This is where we set each fish’s position to be in the middle bottom of read more..

  • Page - 106

    3D CSS Tutorial 103 Exploding the fish The following are the listeners that are called when you touch or mouse-over a fish. In either case, we need to find the fish object for the DOM element that fired the event. Note that the touchstart event has an array of touch objects; it may well be that you touched down with multiple fingers at once. function read more..

  • Page - 107

    Chapter 5 104 Particles Figure 5-3. Image of exploding fish particles We don’t have room in this tutorial to look at the particle system in detail, but rest assured that it’s a very similar system to the way that we manage the fish. The particle emitter has its own update loop, and each particle has a DOM element, position, and velocity. It just uses a read more..

  • Page - 108

    3D CSS Tutorial 105 The layer behind moves slower than the layer in front; in the following code, look where I’m multiplying counter by five for the back layer’s y position. Remember that counter increments every frame, so our back layer will move down five pixels per frame. The front layer moves twice as fast. We use the modulus of the screen height to read more..

  • Page - 109

    Chapter 5 106 Conclusion As programmers, playability and responsiveness lies squarely on our shoulders—so making a game playable and responsive are skills that we need to acquire. Anyone can program a character that runs along a platform, but it’s harder to adjust its speed, gravity, and control—to make it part of a game that feels fun. This is a creative skill read more..

  • Page - 110

    107 Chapter 6 Particle Systems Introduction Particle systems are used to create many different special effects like fire, rain, and smoke. They are used in virtually all video games, as well as in a lot of movie special effects. But what is a particle? In essence, a particle is something represented by a point in space, a dot. In practice, particles are often read more..

  • Page - 111

    Chapter 6 108 planning to simulate a galaxy, you will need to treat stars, or even clusters of stars as particles. If you are simulating rain, your particles will be individual raindrops. In this chapter, I will show you how to design and implement your own particle effects using HTML5 canvas. We will gradually build up the code by adding the features we need read more..

  • Page - 112

    Particle Systems 109 // The particle distance is 120 pixels from the left and 70 pixels // from the top var position = new Vec2(120, 70), // and in one second the particle moves // 10 pixels to the right and -5 pixels down (5 pixels up). velocity = new Vec2(10, -5), particle = new Particle(position, read more..

  • Page - 113

    Chapter 6 110 The updated example now looks like this: // 60 times per second window.setInterval (function(){ var td = 1.0/60; particle.position.iadd(particle.velocity.muls(td)); }, 1000/60); Adding checks In JavaScript, numeric errors lead to a special NaN (not a number) value. All operations done with a NaN as operand will result in another NaN. This read more..

  • Page - 114

    Particle Systems 111 There are drawbacks to using notNaN in production code, however. First, it doesn’t work in IE8 or older. Second, it makes your code slow. Luckily, you can simply disable it for use in production. var DEBUG = true; ... if(DEBUG) { notNaN(Vec2.prototype, ‘x’); notNaN(Vec2.prototype, ‘y’); } Random values To create varying read more..

  • Page - 115

    Chapter 6 112 Figure 6-1. Component overview Particles Every particle in the system needs to have at least a position and a velocity. Other properties can be added as needed; and may include, for example, the following: color image alpha age mass The update method of the particle updates its values for a single time step. function Particle(position){ read more..

  • Page - 116

    Particle Systems 113 this.position.iadd(this.velocity.muls(td)); } } Emitters Nothing comes from nothing. Unlike virtual particles in physics, our particles don’t pop into existence spontaneously; they are created by the emitter. The emitter gives particles their initial attributes, including their position. Note that the emitter is a purely abstract concept read more..

  • Page - 117

    Chapter 6 114 Renderer The job of the renderer is to visualize all the particles in a system. There can be different renderers for different targets and rendering techniques. The following are examples of rendering targets: canvas image canvas pixel WebGL HTML Different particles might require different renderer implementations to handle additional properties, like read more..

  • Page - 118

    Particle Systems 115 this.particles = alive; } }; Hello fireworks We have now covered all the basics necessary to create different particle systems. Now it’s time to get started with a simple example. Fireworks are definitely the “hello world” of particle systems. They look great, illustrate the concept well, and are fairly easy to create read more..

  • Page - 119

    Chapter 6 116 Figure 6-3. An individual spark It is important that no component of the color used for the spark is 0. If one component is zero it will not get brighter when additively blended. That’s because 0 * anything === 0 (except if anything is NaN!). Implementing the main loop The main loop for this example is very simple. For every frame, we update read more..

  • Page - 120

    Particle Systems 117 Implementing the emitter For our fireworks emitter, we want to pick a random point on the canvas. We then spawn 100 particles at that point and give them random velocities. This will make them fly off into different directions. function emit(system, width, height){ var position = new Vec2(Math.random()*width, Math.random()*height); read more..

  • Page - 121

    Chapter 6 118 In addition to gravity, we also want to simulate the air the fireworks are in. There are two interesting forces to do this: drag (air resistance) and wind. function dampingf(damping){ return function(particle, td){ particle.velocity.imuls(damping); }; } var drag = dampingf(0.97); function wind(particle, td){ read more..

  • Page - 122

    Particle Systems 119 We also need to add some code to the ParticleSystem to prune old particles. We will do this in a very simple way by using a new array for the particles that are still alive. This is not very efficient (it produces quite a bit of garbage), but it is very easy to implement and often good enough. The updated update() function will look read more..

  • Page - 123

    Chapter 6 120 With those changes in place, our fireworks look quite decent. Now it’s your turn to play with the code and make them even better looking. You could, for example, add more colors or shapes to make the fireworks more varied. Fire Another classic particle effect is fire. In this section, we will implement a big, hot fire using a lot of particles read more..

  • Page - 124

    Particle Systems 121 Figure 6-5. Individual flame textures Loading the textures In this example, we will need multiple images. In most cases, your application will already have a way of loading resources and you should use that one. For our examples, a very simple function will do. It takes an array of URLs and loads them as images. Once the images are all read more..

  • Page - 125

    Chapter 6 122 // fireworks example. Again, just because I find it looks better that way. radius = Math.sqrt(Math.random()+0.1)*100; // choose a random texture particle.image = choose(images); // make speed dependent on image size so the small spark will be faster // and the big filling texture slower read more..

  • Page - 126

    Particle Systems 123 ctx.globalAlpha = 0.6; renderCanvasImage(ctx, system.particles, 5); ctx.globalAlpha = 1.0; ctx.globalCompositeOperation = 'source-over'; }, 1000/30); } You can see the complete example in fire.0.html. It does already look like a fire, but something is still missing. It looks kind read more..

  • Page - 127

    Chapter 6 124 You can see the result of this change in fire.1.html. It is already looking much better. There is still a noticeable popping of the flames as they reach their end of life. We can improve this by slowly fading them out. Fading out of existence To make the particles fade out smoothly, we will increase their transparency as they get older. To do read more..

  • Page - 128

    Particle Systems 125 Figure 6-6. Smoke demo in action Creating the textures To create the 64 × 64 textures for the smoke particles, I have simply used some noise with a radial gradient as layer mask. The result is shown in Figure 6-7. Figure 6-7. Individual smoke sprites Implementing the emitter The emitter for smoke is very similar to the one we used read more..

  • Page - 129

    Chapter 6 126 particles faster is no longer needed. I increased the angularVelocity and maxAge a bit to match the behavior of smoke a bit better. The new emitter looks like this: function emit(system, images, x, y){ // emit the particle at the center of the canvas with some random // variation var position = new Vec2(x+fuzzy(5), read more..

  • Page - 130

    Particle Systems 127 ctx.globalAlpha = 1.0; ctx.globalCompositeOperation = 'source-over'; }, 1000/30); window.setInterval(function() { if(controls.hasFocus) { emit(system, images, controls.mouse.x, controls.mouse.y); } }, 1000/10); } loadImages('smoke.0.png smoke.1.png read more..

  • Page - 131

    Chapter 6 128 Please note that performance optimizations depend on the runtime environment. Optimizations that have a positive impact today can become useless, or even harmful, tomorrow. They will also severely impact the maintainability and readability of your code. Single particles If we want more particles, we will need to make the particles smaller to make them look read more..

  • Page - 132

    Particle Systems 129 Figure 6-9. Nesting of particles in a flat array. All the particles are packed into a single array. Removing particles from the middle of an array is very expensive. This is why we will leave dead particles ( age > MAX_AGE) in the array and just skip them when drawing. While this makes the system a lot slower when there is only one read more..

  • Page - 133

    Chapter 6 130 var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || wi ndow.mozRequestAnimationFrame || window.msRequestAnimationFrame || function(f){window.setTimeout(f, 5); } Micro optimizations We can gain some additional performance by tweaking details in the code. Very often, this means trading readability for a little more speed. This read more..

  • Page - 134

    Particle Systems 131 PARTICLES_LENGTH = MAX_PARTICLES * NFIELDS, // compatibility with legacy browsers Float32Array = window.Float32Array || Array, requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || function(f){window.setTimeout(f, 5); }, read more..

  • Page - 135

    Chapter 6 132 if(controls.hasFocus) { emit(controls.mouse.x, controls.mouse.y); } ctx.fillStyle = 'rgba(0, 0, 0, 0.4)'; ctx.fillRect(0, 0, width, height); var imgdata = ctx.getImageData(0, 0, width, height), data = imgdata.data; for(var i = 0; i < PARTICLES_LENGTH; i+= NFIELDS) { read more..

  • Page - 136

    133 Chapter 7 Beginning WebGL WebGL (Web-based Graphics Language) is a very exciting new technology that leverages the power of the Graphics Processing Unit (GPU) within the browser. In this chapter, we will discuss the history and capabilities of WebGL. As a prerequisite to programming games with WebGL, we need to cover the following: checking for WebGL support working read more..

  • Page - 137

    Chapter 7 134 WebGL Origins Version 1.0 of the WebGL specification was completed in March 2011 by the Khronos Group. WebGL is based on OpenGL Embedded Systems (ES) 2.0, which, in turn, is derived from OpenGL. In 1992, version 1.0 of OpenGL was released as a non-proprietary alternative to Silicon Graphics’ Iris GL. The GL Shading Language (GLSL) was introduced in 2004 read more..

  • Page - 138

    Beginning WebGL 135 Demonstrations There are many wonderful applications that show the power of WebGL. One of the best-known demos was Google Body, which is now at www.zygotebody.com. This demo displays an interactive 3D model of human anatomy. Another site with impressive applications is www.chromeexperiments.com/webgl and two of my favorites are a realistic water pool demo read more..

  • Page - 139

    Chapter 7 136 Ironically, Microsoft can help some old video cards work with WebGL on Windows machines. The ANGLE (Almost Native Graphics Layer Engine) project translates OpenGL ES 2.0 API calls to DirectX 9 API calls. The result is that graphics cards that only support OpenGL 1.5 (OpenGL ES 1.0) can still run WebGL. Testing for WebGL support There are several sites to read more..

  • Page - 140

    Beginning WebGL 137 Libraries Rather than reinvent functionality, there are several excellent matrix libraries available for use with WebGL. There are also many higher-level graphics engines and APIs available. Matrix libraries Matrix operations—addition, multiplication, inverse, and so forth— are essential in 3D graphics for calculating transforms. They are also used in image read more..

  • Page - 141

    Chapter 7 138 Debugging tools Before we begin coding, the reader should set up WebGL-Inspector from http://benvanik.github.com/ WebGL-Inspector/. It is currently available for Chrome and Safari and will soon be a Firefox extension as well. WebGL-Inspector lets you see the state of your buffers, texture information, individual frames, and other useful data. The Firefox web console read more..

  • Page - 142

    Beginning WebGL 139 Figure 7-2. Transforms of a translation (left), a rotation (middle), and a scale (right) Composing the scene view To set up a scene, you have to multiply the original coordinates by three separate matrices. These are the Model, View, and Projection (MVP) matrices. Model to world transform The model matrix performs scaling, transformation, and rotation of read more..

  • Page - 143

    Chapter 7 140 Figure 7-4. Diagram of world coordinates transformed to camera view Often, the model and view transforms are combined into one matrix. Projection transform Finally, the projection matrix transforms the camera view to the screen view. There are two ways of doing this—with a perspective or with an orthogonal/parallel projection, as shown in Figure 7-5. read more..

  • Page - 144

    Beginning WebGL 141 Figure 7-6. The screen on the right is a wide screen and the aspect ratio is stretched instead of maintained. GLSL Understanding GLSL is essential, as stated at the Khronos WebGL wiki ( www.khronos.org/webgl/wiki/ Tutorial#Creating_the_Shaders): “Nothing happens in WebGL without shaders.” If shaders frighten you, feel free to skip the next couple of read more..

  • Page - 145

    Chapter 7 142 In Figure 7-7, we start with raw modelspace vertex positions. The vertex shader then transforms the vertices, usually by multiplying with the MVP matrices. Vertices are assembled into appropriate primitive types, such as points, lines, and triangles. Next the primitives are rasterized into smaller pixel fragments and passed to the fragment shader. The fragment read more..

  • Page - 146

    Beginning WebGL 143 Listing 7-4. The Start of demo_1.html <!DOCTYPE html> <html> <head> <style> body{ background: gray; } canvas{ background: white; } </style> <script read more..

  • Page - 147

    Chapter 7 144 } if (!gl) { alert("Error trying to initialise WebGL"); } else { gl.clearColor(0.0, 0.4, 0.0, 1.0); } read more..

  • Page - 148

    Beginning WebGL 145 attachShaders(); gl.useProgram(shaderProgram); } function setupShaders(fragmentShaderSRC, vertexShaderSRC){ fragmentShader = makeShader(fragmentShaderSRC, gl.FRAGMENT_SHADER); read more..

  • Page - 149

    Chapter 7 146 Next we pass the sources to the setupShaders function. That function then calls makeShader, which is a helper function to create a shader, set the source, and compile it. This is done by calling the WebGL functions createShader, shaderSource, and compileShader. Once the individual shaders have been created, we create our shader program by calling read more..

  • Page - 150

    Beginning WebGL 147 GLSL types Description varying Vertex shader write, fragment shader read vecN Vector of size 1 × N matN Matrix of size N × N sampler Used for textures So the modelview and projection matrices are uniform throughout the vertex shader, while the position and colors are vertex attributes and change. The initBuffers method in Listing 7-8 read more..

  • Page - 151

    Chapter 7 148 Note More information on the RGBA color format can be found on Wikipedia at http://en.wikipedia.org/wiki/RGBA_color_space. Our final function of the example is drawScene, shown in Listing 7-9. Listing 7-9. The drawScene Function function drawScene() { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); read more..

  • Page - 152

    Beginning WebGL 149 Figure 7-8. The output of Listing 7-10, a shaded square This is a lot of work to draw a square. The good news is that advanced concepts and techniques incrementally build off of the same foundation we have just set up. We have deferred showing our shader source until now. Listing 7-10 shows the vertex shader. Listing 7-10. Our Vertex Shader read more..

  • Page - 153

    Chapter 7 150 Our fragment shader is shown in Listing 7-11. Listing 7-11. Our Fragment Shader <script id="shader-fs" type="x-shader/x-fragment"> varying highp vec4 vColor; void main(void) { gl_FragColor = vColor ; } </script> You can see in Listing 7-11 that we simply assigned the passed in vertex color to the final fragment read more..

  • Page - 154

    Beginning WebGL 151 alert(e); } if (!gl) { alert("Error trying to initialise WebGL"); } else { gl.clearColor(0.0, 0.4, 0.0, read more..

  • Page - 155

    Chapter 7 152 $.ajax({ async: false, url: 'shader.vs', success: function (data) { vertexShaderSRC = data.firstChild.textContent; read more..

  • Page - 156

    Beginning WebGL 153 gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer); gl.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.TRIANGLE_STRIP, 0, read more..

  • Page - 157

    Chapter 7 154 Figure 7-9. Wireframe of an octahedron with its eight faces and six vertex points As you can see from Figure 7-9, vertices A, B, C, and D of an octahedron lie on the same plane and form a square. Vertices E and F mirror each other. The line connecting EF intersects the middle of the square— the intersection of AD and BC to be precise. read more..

  • Page - 158

    Beginning WebGL 155 Listing 7-14. Keyup Handler $(document).keyup(function(evt){ if (evt.keyCode == 80) //'p' { paused =!paused; } }); read more..

  • Page - 159

    Chapter 7 156 Using a function like animLoop that calls itself again is essential to animate more than one frame. In our initWebGL function, we need to enable depth testing, as shown in Listing 7-17. Listing 7-17. Enable gl.DEPTH_TEST function initWebGL() { … if (!gl) { read more..

  • Page - 160

    Beginning WebGL 157 Listing 7-18. Calculating Our Translation and Rotation After Each Frame mat4.translate(mvMatrix, [3*x, y, -12.0 + 5*z]); if(!paused){ x = Math.cos(translationAngle); y = x; read more..

  • Page - 161

    Chapter 7 158 -1.0, 0.0, 1.0, 0.0, -height, 0.0, 1.0, 0.0, -1.0, -1.0, 0.0, -1.0, 0.0, -height, 0.0, read more..

  • Page - 162

    Beginning WebGL 159 18, 19, 20, 21, 22, 23 ]; octahedronVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, octahedronVertexIndexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new read more..

  • Page - 163

    Chapter 7 160 A: (-width, 0, -width) B: (width, 0, -width) C: (width, 0, width) D: (-width, 0, width) E: (0, height, 0) F: (0, -height, 0) We have chosen 1 for the width and the square root of 2 (1.41) for the height. Each buffer specifies the itemSize, which is the number of sub-elements per item. For vertex position, this is 3, corresponding to the three read more..

  • Page - 164

    Beginning WebGL 161 Listing 7-21. Defining Six Colors Instead of Twenty-four for(var i=0; i < 6; ++i){ var color = colors[i]; unpackedColors = unpackedColors.concat(color); } read more..

  • Page - 165

    Chapter 7 162 Planning Game: A simple dart game. Models: A 2D dartboard/target will be rendered in a circular shape using triangle primitives and a textured image. A 3D “dart,” an elongated tetrahedron, will be rendered. Input: We will use mouse events to throw the dart and an HTML form button to reset the dart. Collision Detection: The dart will stop when read more..

  • Page - 166

    Beginning WebGL 163 dartboardVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, dartboardVertexPositionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); dartboardVertexPositionBuffer.itemSize = 3; read more..

  • Page - 167

    Chapter 7 164 NUM_SHADERS = 2, shaderPrograms = [], fragmentShaders = [], vertexShaders = [], vertexPositionAttributes = [], vertexColorAttributes = [], textureCoordAttributes = [], Our shaders read more..

  • Page - 168

    Beginning WebGL 165 dataType: 'xml' }); $.ajax({ async: false, url: shaderFilenames[i] + '.vs', read more..

  • Page - 169

    Chapter 7 166 function setMatrixUniforms(i) { gl.uniformMatrix4fv(shaderPrograms[i].pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderPrograms[i].mvMatrixUniform, false, mvMatrix); } function getVertexAttributes(i){ read more..

  • Page - 170

    Beginning WebGL 167 } function drawDartboard(){ //draw dartboard gl.useProgram(shaderPrograms[TEXTURE_SHADER]); mat4.identity(mvMatrix); mat4.translate(mvMatrix, [0, 0, dartboard_z]); read more..

  • Page - 171

    Chapter 7 168 Drawing our dart Our dart will be a stretched version of the octahedron we rendered in our previous demo, using only two colors, gold and blue. ... octahedronVertexPositionBuffer = null, octahedronVertexColorBuffer = null, octahedronVertexIndexBuffer = read more..

  • Page - 172

    Beginning WebGL 169 -dartWidth, 0.0, -dartWidth, 0.0, -dartHeight * dartSkew, 0.0, dartWidth, 0.0, dartWidth, dartWidth, 0.0, -dartWidth, 0.0, read more..

  • Page - 173

    Chapter 7 170 (octahedronVertexIndices), gl.STATIC_DRAW); octahedronVertexIndexBuffer.itemSize = 1; octahedronVertexIndexBuffer.numItems = 24; } Now it is time for us to draw the dart, as shown in Listing 7-29. Listing 7-29. Drawing the Dart function drawDart(){ read more..

  • Page - 174

    Beginning WebGL 171 positionChange = [], timeChange = 0.0; $(document).ready(function(){ var canvasObj = $("#canvas") canvas = canvasObj.get(0); canvasObj.mousedown(function(e){ read more..

  • Page - 175

    Chapter 7 172 dart_x = Math.cos(angle) * dartboardDiameter; if(Math.random() < 0.5){ dart_x *= -1; } var velocity = ( read more..

  • Page - 176

    Beginning WebGL 173 Figure 7-14. Our completed dart game The full source of the program is available online in the file darts.html. The following are some improvements you could make to the game: More precise scoring. Calculating double and triple score areas and separating the two bull’s-eye areas. Making the throwing smoother and more realistic. Adding gravity read more..

  • Page - 177

    175 Chapter 8 CycleBlob: A WebGL Lightcycle Game I started learning JavaScript and WebGL for fun in my free time on evenings and weekends. For most of my career, I’ve programmed large enterprise applications in C++ and, on occasion, I’ve written some data visualizations using desktop OpenGL. 3D content on the web is something that I’ve been waiting for a while to read more..

  • Page - 178

    Chapter 8 176 teams to better their chances of winning. My version of the game takes place on a closed, 3D surface instead of a flat, walled arena. After two months of full-time work (between jobs), I came up with CycleBlob ( http://cycleblob.com), a full, 3D lightcycle game that runs in the browser using WebGL. What is WebGL? WebGL (Web-based Graphics Library) is read more..

  • Page - 179

    CycleBlob: A WebGL Lightcycle Game 177 With some minor exceptions, (until WebGL arrived) interactive 3D content has been largely confined to monolithic applications that the user downloads and runs on a desktop computer. Back in the ’90s, we had VRML, an XML-like language that described 3D models and worlds. VRML had very few mechanisms for interacting with the user and read more..

  • Page - 180

    Chapter 8 178 Working with this setup is similarly simple. You write the HTML and JavaScript using the editor, save them to your project folder, and double-click the HTML file to open it in the browser to see if it works. This setup is sufficient for the first few attempts at tinkering with web applications, but pretty soon, it becomes evident that it is not read more..

  • Page - 181

    CycleBlob: A WebGL Lightcycle Game 179 The latest versions of Chrome and IE contain a full debugger out of the box. It allows setting breakpoints in the JavaScript code, debugging it step-by-step, and examines variables in a watch window. For Firefox, there is an add-on called Firebug ( http://getfirebug.com) that is also a full debugger. It contains similar features read more..

  • Page - 182

    Chapter 8 180 A convenient and efficient way to represent a triangle mesh in a program is using three lists, as follows: Vertices list: Contains the 3D coordinates of all points where triangles meet. A point in a triangle mesh is usually a meeting point of three to six triangles. An edge between two triangles spans between two vertices. Triangles list: Contains an read more..

  • Page - 183

    CycleBlob: A WebGL Lightcycle Game 181 Figure 8-3. The tetrahedron model in 3D has four vertices, four faces, and six edges. Any point on the surface may have a normal, but only one is shown. From these JavaScript arrays, the code can directly construct the typed arrays that are sent to the WebGL API. From the typed arrays, WebGL constructs vertex buffer read more..

  • Page - 184

    Chapter 8 182 Models classification The geometric models in CycleBlob can be divided into three categories. Static “artistic” models that are simply moved around in the scene and are not manipulated in any way. The player bike and the bonus ball are such models. In a well-funded game produced by a game studio, such models are usually created by 3D-modelling artists. In read more..

  • Page - 185

    CycleBlob: A WebGL Lightcycle Game 183 Vertices are specified by lines starting with the letter “ v” and mesh faces are specified with “ f” lines that, as before, specify the vertices’ indices. In this format, the vertices are specified as one-based indices, not zero-based. The full .obj format specifies other types of lines for normal and texture coordinates. A read more..

  • Page - 186

    Chapter 8 184 The bike model in CycleBlob is made of not one, but several distinct meshes—each with a different color. The JSON file of this model contains the lists of vertices and triangles for each of the meshes, along with the definition of its color. One of the meshes has a special “placeholder” co lor that indicates that it needs to be displayed in a read more..

  • Page - 187

    CycleBlob: A WebGL Lightcycle Game 185 total, only six triangles are updated—every frame for each wall—and processing time is kept to a minimum. Geometric processing Downloading a complete model from the server can become an issue if the model is considerably large and download speed is slow. Common solutions to this problem, such using gzip compression in the http read more..

  • Page - 188

    Chapter 8 186 Figure 8-7. A grid rendered using thick lines. The rendered lines have a constant width regardless of the view point. This creates an unaesthetic “thickness” at the edges of the shape, as well as small gaps between adjacent lines. Writing a fragment shader that discards the inside of the rectangles, leaving only a frame for display (see Figure read more..

  • Page - 189

    CycleBlob: A WebGL Lightcycle Game 187 The direct approach. Rendering a model that explicitly looks like a grid with holes (see Figure 8-9). This option means that the displayed mesh is a plain, triangle mesh—no tricks or shortcuts. With this option, the edges of the grid are made of normal polygons so a multisampling implementation can work correctly to avoid read more..

  • Page - 190

    Chapter 8 188 Figure 8-10. The plain quad mesh passes through a pre-processing stage that generates the triangle mesh that’s going to be used for display. Table 8-1. Difference in Data Volume of the Two Grid Models No. of faces No. of vertices Size of model file Input quad mesh 384 386 16.7 KB Output triangle mesh with holes 2300 1536 127 KB For the read more..

  • Page - 191

    CycleBlob: A WebGL Lightcycle Game 189 Movement and positioning One of the key characteristics of a computer game is the mechanics of the movement and animation. Coming up with a natural and streamlined look and feel for a game is often as crucial as the basic concept and art design. Indeed, some common categories of games such as “first-person shooter” or read more..

  • Page - 192

    Chapter 8 190 Figure 8-11. (a and b) The bike and grid models with their coordinates axis. (c) Drawing both models in the same coordinate system. (d) Drawing with the coordinate base transformation. The coordinate base transformation is a 4 × 4 matrix that we build using the data from the scene by following a simple procedure. Given the following input: Point P: The read more..

  • Page - 193

    CycleBlob: A WebGL Lightcycle Game 191 Vector F = (Fx, Fy, Fz): The forward direction of the bike. This is the direction the bike moves in when no turns are taken. It’s a vector tangent to the surface at point P and is also perpendicular to N. (More on how to find this vector to come.) Both N and F need to be normalized to the length of 1. To read more..

  • Page - 194

    Chapter 8 192 Taking a cross product of the vectors induced by two edges of a triangle gives the direction of its normal (shown in Figure 8-12). For a triangle stretched between vertices a, b, and c, the normal would be: N = normalize( (b – a) × (c – a) ) = (b – a) × (c – a) / |(b – a) × (c – a)| Figure 8-12. Extracting a read more..

  • Page - 195

    CycleBlob: A WebGL Lightcycle Game 193 Figure 8-13. Calculating a normal for a vertex (purple) as the average of faces normals (green). If the mesh contains a large variation of triangle sizes, a better approximation is achieved by weighing the average by the area of the triangles. The resulting average normal would not generally be a length of 1.0, so another read more..

  • Page - 196

    Chapter 8 194 The vector F is now exactly perpendicular to N and is situated on the plane created by N and F’. It is better than F’ in that it is tangential to the smooth surface represented by the mesh. Vector R is perpendicular to F and N and, after normalization to the length of 1, is identical to the R vector mentioned earlier. Last, but not read more..

  • Page - 197

    CycleBlob: A WebGL Lightcycle Game 195 Center of view: What part of the scene should be displayed at the exact center of the screen? The obvious answer that comes to mind is that the player’s bike should be there. Although this sounds logical, it may often not be the best choice. The player’s bike is often found on corners and edges of the grid. Centering read more..

  • Page - 198

    Chapter 8 196 up vector is its right-hand side. When the bike moves towards the top of the screen, the up vector is its forward direction. With each turn the player makes in the game, this vector is updated. Taking the camera up vector to always be only the forward direction of the bike would have resulted in a camera that sticks to the bike rather than to read more..

  • Page - 199

    CycleBlob: A WebGL Lightcycle Game 197 Animation engine Smooth animation is a key factor in making a game look good and fun to play. If the animation is choppy or delayed or contains unaesthetic artifacts, the player is going to run out of patience fast, leave, and never return—even if the game concept is amazing in every other respect. Animation in CycleBlob occurs read more..

  • Page - 200

    Chapter 8 198 To clarify this procedure, let’s look at an example. We have indices A and B, which are the vertex indices of the edge the bike is currently on. T is being advanced from 0.95 to 1.1, which means that it passes over vertex B by 0.1 of the distance between A and B and that the bike should be displayed on the next edge. The next vertex, C, read more..

  • Page - 201

    CycleBlob: A WebGL Lightcycle Game 199 one of the four neighbors is acceptable. One of the neighbors of B is the vertex we just came from, A, and it can’t be reached again because the bike can’t turn 180 degrees on its axis. Knowing where neighbor A is, we can start going clockwise around B and find the vertex that we will turn to if the user turns read more..

  • Page - 202

    Chapter 8 200 Defining these sorts of relationships between measurements can become tricky, so it’s useful to establish a common basis for measurement that expresses every measurement. In CycleBlob, the common basis for all length- and size-related measurements is the average distance between two adjacent vertices of the grid. This distance, call it Dv, gives a good estimate read more..

  • Page - 203

    CycleBlob: A WebGL Lightcycle Game 201 The length of time between updates depends on the hardware being used, the workload of the system and browser at a given time, and many other variables. Setting a constant T assumes all these variables are constant. A value of, say 0.25, makes an implicit assumption on the frame rate in which the game is going to run. read more..

  • Page - 204

    Chapter 8 202 Figure 8-16. Possible timelines using setTimout() for frame-rate control. Calling setTimeout() at the end of tick() may cause the complete frame cycle to be longer than the required timeout and cause a frame-rate lower than expected. Another traditionally common option is using setInterval(func, timeout). This function is similar to setTimeout()—but with read more..

  • Page - 205

    CycleBlob: A WebGL Lightcycle Game 203 } function tick() { requestAnimationFrame(tick, 16); // do rendering, animation } This approach shifts the responsibility of determining the right frame rate for the game from the programmer to the browser. The browser is almost always more capable of estimating the different variables that this decision entails. read more..

  • Page - 206

    Chapter 8 204 Of course, a better solution would be to prevent these delays in the first place, but most of the causes for such delays are outside the control of the programmer. One can only hope that as browser technology progresses and WebGL becomes more robustly supported, the guarantees on frame rate will become more robust as well. Using requestAnimationFrame() to read more..

  • Page - 207

    CycleBlob: A WebGL Lightcycle Game 205 A link to the feedback page and a small Facebook “Like” button that is not used often enough by visitors of the site. Finally, a call to webGLStart() that occurs in response to the onload event of the page. This function is called automatically when all of the resources listed on the page are fully loaded and the code read more..

  • Page - 208

    Chapter 8 206 Figure 8-17. The static models of the explosion effect. The spark model is a collection of thin triangles in random lengths and orientation that are all on the same plane. The ring model is a just a round triangle strip. These models are generated in the initialization of the game. Initialization of the sound module with the files loaded by the read more..

  • Page - 209

    CycleBlob: A WebGL Lightcycle Game 207 some 3D content to be displayed. Stopping and restarting the calls to tick() would complicate the logic of the menu system with no consequential performance gains. The tick() function is where most of the real-time game play occurs. The following is an outline of the major blocks of this function. Frame rate mechanics: Calls read more..

  • Page - 210

    Chapter 8 208 All the efforts invested thus far in loading and generating models, animating them, and lighting them culminate into a single, rendered frame. This function tells WebGL to communicate with the graphics hardware and kick it into action. In most modern machines, this is where the majority of the time the tick() call is spent. Anything else the game does read more..

  • Page - 211

    CycleBlob: A WebGL Lightcycle Game 209 References to possible special-effect animation objects that may be occurring for the player. When an object exists here, it receives a call from the global tick() function with the amount of time that elapsed to update its animation state. An optional reference to an AI object that’s responsible for the decision making of read more..

  • Page - 212

    Chapter 8 210 More bonus options. Currently the only bonus in the game is to give the player one more life. Some of the more interesting options I’m considering are bonuses that allow one player to be faster than the others for a period of time, to allow him to break or jump over walls, or even shoot projectiles at other players. Maintaining the balance of the read more..

  • Page - 213

    CycleBlob: A WebGL Lightcycle Game 211 Symbols Definition Q (coordinates) The point to which the bike model is translated to; this point is slightly above P N (vector) The normal vector of the surface where the bike is situated; a vector perpendicular to the surface F (vector) The current forward direction of the bike, tangential to the surface where the bike is read more..

  • Page - 214

    213 Chapter 9 A Real-Time Multiplayer Game Using WebSockets In this chapter, we will walk through the creation of a simple multiplayer game. We will use the HTML5 canvas to display graphics to the user, WebSockets to facilitate communication with our server, and node.js to create the server. WebSockets are truly a boon to game development on the web. Before the read more..

  • Page - 215

    Chapter 9 214 Philosophy of netcode In a multiplayer game, nothing ruins the experience quite like somebody cheating. Unfortunately, there will always be somebody who tries to cheat at your game. Even more unfortunately, “cheating” in a JavaScript game, such as the one we will soon construct, is extremely simple. JavaScript is not even compiled! The raw source code is read more..

  • Page - 216

    A Real-Time Multiplayer Game Using WebSockets 215 smooth. This simple idea, simulating the game locally while the real game is being played on the server, is sometimes called “dead reckoning.” Ideally, we can share the code for the game logic between the client side (for responsiveness) and the server side (for actually running the game). That way, we don’t need read more..

  • Page - 217

    Chapter 9 216 With a little bit of clairvoyance, we begin the game engine, game.js, with the list of game properties that we’ll need (see Listing 9-1). These will, in the final product, apply simultaneously to the client and the server. There is certainly virtue in not having two such lists maintained separately. Listing 9-1. Global Properties of the Game var GP = read more..

  • Page - 218

    A Real-Time Multiplayer Game Using WebSockets 217 This type of collision detection, where we move the cars regardless of environment and then check for collisions, has some drawbacks. The only serious one that we will consider here is that two cars might pass each other in one time step with no collision registered. Say one car at x=0 is moving to the right read more..

  • Page - 219

    Chapter 9 218 // [ Index of first car, Index of second car, X impulse, Y impulse ]. var Impulses = []; for (var i = 0; i < Cars.length; i++) { // Move the cars. X and Y are the coordinates of the center of the car. Cars[i].X += Cars[i].VX; Cars[i].Y += Cars[i].VY; // Check for proximity to the read more..

  • Page - 220

    A Real-Time Multiplayer Game Using WebSockets 219 // Impulse 1 = -Delta * [ DX, DY ]. // Impulse 2 = Delta * [ DX, DY ]. var DX = Cars[j].X - Cars[i].X; var DY = Cars[j].Y - Cars[i].Y; read more..

  • Page - 221

    Chapter 9 220 Cars[i].VX *= GP.MaxSpeed / Speed; Cars[i].VY *= GP.MaxSpeed / Speed; } // Friction will act on the cars at all times, eventually bringing them to rest. Cars[i].VX *= GP.FrictionMultiplier; Cars[i].VY *= GP.FrictionMultiplier; } That’s all for the RunGameFrame method. In fact, that is all of the game logic, and there wasn’t very read more..

  • Page - 222

    A Real-Time Multiplayer Game Using WebSockets 221 </body> </html> Note This HTML file will be changed to point to client-multiplayer.js instead of client- local.js when we revisit the game client in a later section. Now, in client.js, we’ll define a few variables specific to the game client, as shown in Listing 9-8. Listing 9-8. Global Variables in read more..

  • Page - 223

    Chapter 9 222 ); document.addEventListener("keyup", function(E) { if (E.which == 38) KeysPressed &= ~1; // Up. else if (E.which == 37) KeysPressed &= ~2; // Left. else if (E.which == 39) KeysPressed &= ~4; // Right. } ); The & read more..

  • Page - 224

    A Real-Time Multiplayer Game Using WebSockets 223 Now, the only thing missing from this non-multiplayer client is to draw the game. Listing 9-12 is a straightforward exercise in using the canvas. Listing 9-12. DrawGame method function DrawGame() { // Clear the screen GraphicsContext.clearRect(0, 0, GP.GameWidth, GP.GameHeight); for (var i = read more..

  • Page - 225

    Chapter 9 224 Figure 9-3. The offline game client created in this section The game server To set up the game server, you will need access to some computer running node.js ( www.nodejs.org). This can be your own computer (there is a Windows port of node.js) or some remote server. We are going to run a WebSocket server on node.js. A WebSocket server can be read more..

  • Page - 226

    A Real-Time Multiplayer Game Using WebSockets 225 Note The WebSocket server add-on modules are sure to change in the future, especially once the WebSocket standard is finalized, but the code we write here will be largely agnostic of the module used. It should be easily adapted to any other module fulfilling the same purpose. Our server.js will need to establish read more..

  • Page - 227

    Chapter 9 226 Listing 9-16. Setting Up the WebSocket Server // Creates an HTTP server that will respond with a simple blank page when accessed. var HTTPServer = HTTP.createServer( function(Request, Response) { Response.writeHead(200, { "Content-Type": read more..

  • Page - 228

    A Real-Time Multiplayer Game Using WebSockets 227 do { Connection.ID = Math.floor(Math.random() * 100000) } while (Connection.ID in Connections); Connections[Connection.ID] = Connection; read more..

  • Page - 229

    Chapter 9 228 Size++; return Size; } The event handler for the player disconnecting is very simple. Notice that in Listing 9-18 we directed that event to a function called HandleClientClosure (see Listing 9-19). Listing 9-19. HandleClientClosure method function HandleClientClosure(ID) { if (ID in Connections) read more..

  • Page - 230

    A Real-Time Multiplayer Game Using WebSockets 229 try { Message = JSON.parse(Message); } catch (Err) { return; } if (!("Type" in Message && "Data" in Message)) return; // Handle the different types of messages we expect. var C = Connections[ID]; switch (Message.Type) { read more..

  • Page - 231

    Chapter 9 230 Notice that we again augmented, for the final time, the list of data stored per car. We’re now keeping track of the user’s handle (username) and it will be displayed on the cars once we revisit the game client. Caution Always perform strict data validation on any input received from users! It is very simple for a user to change the read more..

  • Page - 232

    A Real-Time Multiplayer Game Using WebSockets 231 The only remaining piece of server.js is the game loop (see Listing 9-23). We already constructed a game loop in client.js, and this one will be very similar. Listing 9-23. Setting up the Game Loop on the Server // Set up game loop. setInterval(function() { // Make a copy of the read more..

  • Page - 233

    Chapter 9 232 Listing 9-24. New Global Variables for the Client var Socket = null; var GameTimer = null; The first is our WebSocket and the second will be used to stop the game loop if the WebSocket connection is aborted. When the page loads, we’ll ask the player for a handle and then connect to the WebSocket server. So, in our window-load event handler, we read more..

  • Page - 234

    A Real-Time Multiplayer Game Using WebSockets 233 { // Send a handshake message. // Set up game loop. }; Socket.onmessage = function(E) { // Parse the car data from the server. }; The latter two event handlers require some more detail. When the read more..

  • Page - 235

    Chapter 9 234 Listing 9-28. WebSocket “message” Event Handler Socket.onmessage = function(E) { var Message; // Check that the message is in the format we expect. try { Message = JSON.parse(E.data); } catch (Err) { return; } if (!("MyIndex" in read more..

  • Page - 236

    A Real-Time Multiplayer Game Using WebSockets 235 Sending the data is as simple as calling the send() method on the WebSocket object. The WebSocket’s readyState property has the value 1 when it is open and functioning correctly. With those changes, we’re totally online-enabled! One last tweak to make is to draw player names above their cars. The DrawGame method read more..

  • Page - 237

    Chapter 9 236 Figure 9-4. The final game client, with three players online Conclusion WebSockets and the HTML5 canvas open up all sorts of possibilities to developers. These technologies are still brand new, but we should expect to see them really take off in the years ahead. In this chapter, we’ve created a prototype game and hopefully you will agree that it read more..

  • Page - 238

    A Real-Time Multiplayer Game Using WebSockets 237 Appendix: Setting up node.js Let’s walk through getting node.js up and running. We’ll do it first on Windows and then make some comments about doing it on a UNIX-based system. Windows Download the latest Windows version of node.js from www.nodejs.org. As of this writing, the version is 0.6.2. The installer unpacks read more..

  • Page - 239

    Chapter 9 238 After installing node.js, you will want to install the Node Package Manager (npm), by executing the following command: curl http://npmjs.org/install.sh | sh and then install the websocket module by running npm: npm install websocket If you have issues installing or using npm, you can perform a manual installation instead, as described in the Windows read more..

  • Page - 240

    239 Chapter 10 Hard-Pressed for a Choice of Technology Browser-based games have been around for as long as there have been browsers, and one can easily retrace the evolution of browsers by following the evolution of browser-based games. At first games were text-based—this was the evolution of multi-user dungeons. MUDs were mainly turn-based due to the limitations of HTTP, read more..

  • Page - 241

    Chapter 10 240 professionals from Zynga, Facebook, SixToStart, and many other companies serving as judges. My team’s project, FAR7, won the Best Technology category. As the CTO, I would like to discuss the crucial and most complicated stage of development, which is choosing the technology. Why the choice is so hard to make Being game developers, we must squeeze read more..

  • Page - 242

    Hard-Pressed for a Choice of Technology 241 Rendering We should start with the basics, as no game is possible without a graphical representation. In the past, the most widely-used option was simple layers, but since the advent of HTML5, developers have been able to choose between two higher-performance technologies: bitmap canvas and vector SVG. Both make high- quality graphics read more..

  • Page - 243

    Chapter 10 242 Listing 10-1. SVG image source with gradient, animated ellipse, and image <svg version="1.1" width="320" height="320" xmlns="http://www.w3.org/2000/svg"> <defs> <radialGradient id="planet"> <stop offset="0%" read more..

  • Page - 244

    Hard-Pressed for a Choice of Technology 243 An XML-based language, SVG provides a familiar DOM API on the page for accessing each element. What are the drawbacks of SVG? The main drawback stems from the fourth advantage. The more complex and larger the document, the slower the rendering—as with any other technology that uses DOM. Canvas The way of the read more..

  • Page - 245

    Chapter 10 244 { if (step == 'in') { w++; h++; read more..

  • Page - 246

    Hard-Pressed for a Choice of Technology 245 ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.setTransform(1, 0, 0, 1, read more..

  • Page - 247

    Chapter 10 246 The two-dimensional context has long been supported by every popular browser, with the exception of IE versions below 9.0. Google has created a product called Explorer Canvas, or excanvas, for these older IE versions. Simply by enabling one extra JavaScript file, you get fully functional canvas in the old versions of IE. What are the benefits of canvas? read more..

  • Page - 248

    Hard-Pressed for a Choice of Technology 247 One of the main challenges of integrating video and audio into browsers is the difference in codec selections in different browsers, which requires us store several copies of content; for example, Ogg Vorbis files for Firefox, Chrome, and Opera, and MP3 files for IE9 and Safari. Let us take a closer look at cases of using read more..

  • Page - 249

    Chapter 10 248 Connection Most games are sensitive to network latency. We developers are at a crossroads again today, given a choice of several technologies. Let us look at the advantages of each and figure out what to do about obsolete browsers that do not support them. I will provide a little background, so that we know what we are dealing with. Everybody read more..

  • Page - 250

    Hard-Pressed for a Choice of Technology 249 Long polling is the happy medium between simple AJAX and complex HTTP streaming, also known as HTTP server push or Comet (see Figure 10-4). Its key advantage is that the client creates only one connection, which it uses to receive data from the server in real time. Its drawbacks are complexities with implementation and read more..

  • Page - 251

    Chapter 10 250 To create multi-line messages, use one \n at the end of each line preceding the last one, and two, at the end of the final line, as shown in Listing 10-6. Listing 10-6. An example of a multi-line message used in JSON transmission data: {\n data: "msg": "hello server-sent event",\n data: "id": 42\n data: }\n\n Besides, SSE can read more..

  • Page - 252

    Hard-Pressed for a Choice of Technology 251 Table 10-3. Server-Sent Events: Method of continuously sending data from a server to the browser IE Firefox Safari Chrome Opera Two versions back 7.0 5.0 4.0 12.0 11.0 Previous version 8.0 6.0 5.0 13.0 11.1 Current 7.0 5.1 14.0 11.5 Near future 9.0 8.0 15.0 12.0 Farther future 10.0 9.0 6.0 16.0 12.1 What benefits do read more..

  • Page - 253

    Chapter 10 252 console.log('Server: ' + e.data); }; A study of the protocol’s security in the late November of 2010 revealed that when used with transparent proxy servers, the transmitted data cache can be replaced, and the user will receive a version of the data created by an intruder instead of the actual data. This quite serious issue prompted read more..

  • Page - 254

    Hard-Pressed for a Choice of Technology 253 sent to the server every time because of the way they work. The year 2009 saw the appearance of the Web Storage standard, often referred to as DOM Storage. Web Storage provides a convenient way to store up to 5 megabytes per domain in Firefox, Chrome, and Opera, and up to 10 megabytes in IE. Importantly, the standard read more..

  • Page - 255

    Chapter 10 254 Web fonts Implementation of original fonts on web pages was planned for a long time. In 1995, the HTML2 standard added the tag <font>, which allowed using a font installed on the user’s system, or falling back on a suitable font family if the user did not have any of the required fonts. The CSS2 specification with identical functionality came out read more..

  • Page - 256

    Hard-Pressed for a Choice of Technology 255 Conclusion We have examined the core stack of technologies used for development of modern browser-based games. It is now apparent that selecting the right combination is no trivial task. Every technology has its pros and cons. To achieve the perfect balance, you will have to compensate for the drawbacks of one technology with read more..

  • Page - 257

    257 Index A Almost Native Graphics Layer Engine (ANGLE), 136 Angry Birds game, 9, 11, 64, 93 Animation engine bike game, 197 clearInterval()method, 202 CycleBlob, 197 main() function, 201 mesh pre-processing stage, 198 pre-processing, 199 requestAnimationFrame()method, 202–204 setInterval(func,timeout), 202 setTimeout()method, 201–202 speed and measurements, 199 steps, 197 timing, 200–201 read more..

  • Page - 258

    INDEX 258 Basic game planning (continued) dart drawing. (see Dart drawing) dartboard image textured, 167 dartboard variables and buffer initialization, 162 drawDartboard function, 167 game, 162 input, 162 models, 162 mouse events, 170–172 parameterized shader functions, 164–165 scene and dartboard,drawing, 166 scoring, 162, 172–173 shader uniform and attributes, 165 texture, loading and read more..

  • Page - 259

    INDEX 259 life and death, 118–119 main loop implementation, 116 rendering, 119–120 spark designing, 115–116 HTML markup brick type, buttons, 67 <canvas> element, 66 CSS stylesheet and rules, 68 saved tracks, 67 snippets, 66 steps, 67 HyperText Markup Language (HTML), 33 J, K, L JavaScript bricks circle, 77 clear button implement, 85 createBrickAt(column, row) method, 81–83 read more..

  • Page - 260

    INDEX 260 Multiplayer game, WebSockets (continued) bumper.htm, 220 client.js,global variables, 221 DrawGame method, 223, 235 enabled keyboard handlers, 234 event handlers, 232 final game client, 236 game loop on window load, 222 handling keyboard input, 221 image preloading code, 221 KeysPressed variable, 221 local client with some cars, 223 message event handler, 234 MozWebSocket, 232 read more..

  • Page - 261

    INDEX 261 Runfield, 9, 11 tame the mouse, 7, 8 TF2 WebGL, 12 uncompiled and open code, 3 up-to-date browser, 4 W3C, 3 WebGL,3D graphics, 5 WebRT,OS application, 8 WHATWG, 3 write once, use anywhere, 2 P PAC-MAN game, 175 Particle systems components emitters and forces, 113 overview, 112 particles, 112–113 renderer, 114 system, 114–115 fire. (see Fire) hello fireworks read more..

  • Page - 262

    INDEX 262 Server-Sent Events (SSE) (continued) simple connection, 249 single-line message, 249 subscribing message, 250 time-out to 5 seconds message, 250 Store retrieving tracks, 87–88 save button, 89 saving tracks, 86–87 string-based data structure, 85 tracks list, saved, 89–90 T, U, V TF2 WebGL, 12 TrueType (TTF), 254 W, X, Y, Z Web Audio API (Chrome), 6 Web-based read more..

  • Page - 263

    INDEX 263 movement and positioning 4 × 4 transformation matrix, 191 animation, 194 animation engine. (see Animation engine) bike camera relation, 194 bike movement, 193 camera positioning, 194 center of view and coordinates, 195 coordinate base transformation, 190– 191, 193 cross-product vector, 192 disadvantages, 196 explosion model, 194 eye coordinates, 195 glLookAt() matrix, 196 read more..

  • Page - 264

    HTML5 Games Most Wanted Egor Kuryanovich Shy Shalom Russell Goldenberg Mathias Paumgarten David Strauß Seb Lee-Delisle Gaëtan Renaudeau Jonas Wagner Jonathan Bergknoff Brian Danchilla Rob Hawkes read more..

  • Page - 265

    ii HTML5 GAMES MOST WANTED Copyright © 2012 by Egor Kuryanovich, Shy Shalom, Russell Goldenberg, Mathias Paumgarten, David Strauß, Seb Lee-Delisle, Gaëtan Renaudeau, Jonas W agner, Jonathan Bergknoff, Brian Danchilla, and Rob Hawkes This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned, specifically the rights of read more..

  • Page - 266

    CONTENTS iv Contents About the Author .......................................................................................................xiii About the Technical Reviewer...................................................................................xv About the Cover Image Artist ...................................................................................xvi Introduction read more..

  • Page - 267

    CONTENTS v There are plenty of good open web games out there .................................................9 Bejeweled ...............................................................................................................9 Angry Birds .............................................................................................................9 Robots Are People read more..

  • Page - 268

    CONTENTS vi Embedding a sketch .................................................................................................26 In-line processing......................................................................................................27 Integrating JavaScript ...............................................................................................27 Using audio read more..

  • Page - 269

    CONTENTS vii PhoneGap Build........................................................................................................51 Configuration of our chess game ..........................................................................52 WebAppBuilder .........................................................................................................52 Makefile for of our chess read more..

  • Page - 270

    CONTENTS viii The Store .....................................................................................................................85 Saving tracks ............................................................................................................86 Retrieving tracks .......................................................................................................87 Implement the Save button read more..

  • Page - 271

    CONTENTS ix Forces .....................................................................................................................113 Renderer .................................................................................................................114 System ....................................................................................................................114 Hello fireworks read more..

  • Page - 272

    CONTENTS x Chapter 7: Beginning WebGL . ..................................................................................133 WebGL Origins............................................................................................................134 How does WebGL work?. ..........................................................................................134 Uses and limitations. read more..

  • Page - 273

    CONTENTS xi Basic collision detection ......................................................................................172 Scoring ................................................................................................................172 Summary ...................................................................................................................173 Chapter 8: CycleBlob: A WebGL Lightcycle Game read more..

  • Page - 274

    CONTENTS xii The game client, Part 1.............................................................................................220 The game server .......................................................................................................224 The game client, Part 2.............................................................................................231 Conclusion read more..

  • Page - 275

    xiii About the Authors Egor Kuryanovich is a web developer from Belarus living in Minsk. He goes by the name of Sontan on the web, and his game, Far7, won the Best Technology category of Google’s 2010 Game On competition. Shy Shalom is an Israeli software engineer living in Tel Aviv. While his day job consists of writing enterprise applications in C++, his read more..

  • Page - 276

    ABOUT THE AUTHORS xiv A sought-after speaker, his recent Creative JavaScript / HTML5 workshop series sold out within hours. He co-hosts the Creative Coding Podcast, his blog can be found at seb.ly and he tweets @seb_ly. Gaëtan Renaudeau (aka gre) is a web enthusiast studying towards a master’s degree in computer science in France. Since 2009, he has worked for Zenexity read more..

  • Page - 277

    xv About the Technical Reviewer Andrew Zack is the CEO of ZTMC, Inc. (www.ztmc.com), which specializes in search engine optimization (SEO) and internet marketing strategies. His project background includes almost 20 years of site development and project management experience and over 15 years as an SEO and internet marketing expert. Andrew has been very active in the read more..

  • Page - 278

    INTRODUCTION xvi About the Cover Image Artist Corné van Dooren designed the front cover image for this book. After taking a brief hiatus from friends of ED to create a new design for the Foundation series, Corné worked at combining technological and organic forms with the results now appearing on this and other book covers. Corné spent his childhood drawing on everything at hand, and then he began read more..

Write Your Review