Building JavaScript Games for Phones, Tablets, and Desktop

This book is for anyone who has an interest in learning how to create your own games. If you have no prior (JavaScript) programming experience, don’t worry. This book teaches you all you need to know.


Arjan Egges


422 Pages

34884 Reads

33 Downloads

English

PDF Format

6.89 MB

Java Script

Download PDF format


  • Arjan Egges   
  • 422 Pages   
  • 23 Feb 2015
  • Page - 1

    COMPANION eBOOK US $ 49.99Shelve inGraphics/Game ProgrammingUser level:Beginning–Intermediate www.apress.comBOOKS FOR PROFESSIONALS BY PROFESSIONALS®Building JavaScript Games teaches game programming through a series of engaging, arcade-style games that quickly expand your JavaScript and HTML5 skills. JavaScript is in the top ten most-used programming languages world wide, and is the basis for applications that can run in any modern browser, on any device from smart phone to tablet to PC. read more..

  • Page - 2

    For your convenience Apress has placed some of the front matter material after the index. Please use the Bookmarks and Contents at a Glance links to access them. read more..

  • Page - 3

    v Contents at a GlanceAbout the Author ��������������������������������������������������������������������������������������������������������������� actionGoTo:418,xixAbout the Technical Reviewer read more..

  • Page - 4

    viContents at a GlanceChapter 11: Organizing Game Objects ■ ���������������������������������������������������������������������������actionGoTo:147,143Chapter 12: Finishing the Painter Game ■ read more..

  • Page - 5

    xxvii IntroductionWith the emergence of the HTML5 standard, web-based application development is becoming very popular. More and more game companies are switching to developing games in JavaScript, because currently it’s the only truly platform-independent approach that works on the variety of devices we have nowadays, ranging from desktop computers to smartphones and tablets. In this book, you learn how to make your own games. At the same time, you learn in depth one of the most popular read more..

  • Page - 6

    xxviiiIntroductionPart IThis part provides an overview of the JavaScript programming language, along with an introduction to its main features. I introduce the most important game programming structure—the game loop—and I show you how to implement it in JavaScript. I illustrate the game loop with a very simple JavaScript application using an HTML5 canvas object. You learn about variables and data structures that are useful for representing a game world, and you see how to include game read more..

  • Page - 7

    xxixIntroductiongame (a penguin, a seal, a shark, or an iceberg) or drops from the playing field, in which case the penguin falls into the water and is eaten by hungry sharks. Throughout the different levels of the game, you introduce new gameplay elements to keep the game exciting. For example, there is a special penguin that can match any other penguin, penguins can get stuck in a hole (meaning they can’t move anymore), and you can place penguin-eating sharks on the board. I introduce the read more..

  • Page - 8

    xxxIntroductionNote This book has an accompanying web site where you can download all the example programs, the accompanying game assets (sprites and sounds), as well as other extras. The URL is actionURI(www.apress.com/9781430265382):www.apress.com/9781430265382. Go there and follow the instructions to get the extra materials.Getting and Installing the ToolsIn order to develop computer games in HTML5 and JavaScript, a few tools can be useful to install on your computer. Obviously, you need read more..

  • Page - 9

    xxxiIntroductionAs you can see, there are quite a few different files pertaining to this particular example. A simpler example can be seen if you go the folder belonging to the Chapter 1, where you find a few very basic examples of HTML5 applications with JavaScript. You can run each of the examples by double-clicking its HTML file.Contacting the AuthorIf you have any questions regarding the book, please feel free to contact me directly at the following e-mail address: read more..

  • Page - 10

    1 Part IGetting StartedThe first part of this book covers the basics of developing game applications in JavaScript. You see a number of simple examples that combine HTML with JavaScript. I give you an introduction to the HTML5 standard and the new HTML elements that come with it, notably the canvas. This part covers core JavaScript programming constructs such as instructions, expressions, objects, and functions. In addition, I introduce the game loop and how to load and draw sprites (images). read more..

  • Page - 11

    3 Chapter 1ProgrammingThis chapter talks about how programming languages have evolved over time. Since the rise of the Internet in the 1990s, a lot of languages and tools have been developed to support it. One of the best-known languages is HTML, which is used to create web sites. Together with JavaScript and CSS style sheets, it allows the creation of dynamic web sites that can be displayed by a browser. I discuss HTML and JavaScript in detail in this chapter, and you see how to create a simple read more..

  • Page - 12

    4CHAPTER 1: ProgrammingThe main task of the processor is to execute instructions. The effect of executing these instructions is that the memory is changed. Especially with my very broad definition of memory, every instruction a processor executes changes the memory in some way. You probably don’t want the computer to execute only one instruction. Generally, you have a very long list of instructions to be executed—“Move this part of the memory over there, clear this part of the memory, read more..

  • Page - 13

    5CHAPTER 1: ProgrammingProgramming such games was done in an Assembler language. Assembler languages were the first imperative programming languages. Each type of processor had its own set of Assembler instructions, so these Assembler languages were different for each processor. Because such a limited amount of memory was available, game programmers were experts at squeezing out the last bits of memory and performing extremely clever hacks to increase efficiency. The final programs, though, read more..

  • Page - 14

    6CHAPTER 1: ProgrammingC is still used quite a lot, although it’s slowly but surely making way for more modern languages, especially in the game industry. Over the years, games became much larger programs, and they were created by teams rather than individuals. It was important that the game code be readable, reusable, and easy to debug. Also, from a financial perspective, reducing the time programmers had to work on a game became more and more essential. Although C was a lot better in that read more..

  • Page - 15

    7CHAPTER 1: ProgrammingHTML pages. HTML is a document formatting language, and it’s an abbreviation of HyperText Markup Language. Its goal is to provide a way to structure documents according to a set of tags that indicate different parts of a document, such as a title or a paragraph. HTML was invented in the late 1980s by physicist Tim Berners-Lee, who was working at CERN in Switzerland at the time. He wanted to provide a way for the CERN researchers to easily use and share documents. So, in read more..

  • Page - 16

    8CHAPTER 1: ProgrammingJavaScript soon gained widespread success as a script language that allowed web sites to become more dynamic. Microsoft also included it in Internet Explorer 3.0 but named it JScript because it was a slightly different version from the one Netscape originally defined. In 1996, Netscape submitted JavaScript to the ECMA standardization organization, which renamed the language ECMAScript (although everyone still calls it JavaScript). The version that was finally accepted in read more..

  • Page - 17

    9CHAPTER 1: ProgrammingModern game engines provide a lot of functionality to game developers, such as a 2D and 3D rendering engine, special effects such as particles and lighting, sound, animation, artificial intelligence, scripting, and much more. Game engines are used frequently, because developing all these different tools is a lot of work and game companies prefer to put that time and effort into creating beautiful environments and challenging levels.Because of this strict separation read more..

  • Page - 18

    10CHAPTER 1: ProgrammingSmall Scale: Edit-Interpret-RunWhen you want to build a game in JavaScript, you need to write a program that contains many lines of instructions. With a text editor, you can edit the script(s) you’re working on. Once you’re done writing down these instructions, you start the browser (preferably a recent version of a commonly used browser program) and try to run the program. When all is well, the browser interprets the script and executes it.However, most of the time, read more..

  • Page - 19

    11CHAPTER 1: ProgrammingWhen the game specification is finished, you can start the implementation phase, which generally means going through the edit-interpret-run cycle a couple of times. After that, you can let other people play your game. In many cases, you’ll realize that some ideas in the game design don’t work that well. So, you begin again by changing the design, followed by changing the specification and finally doing a new implementation. You let other people play your game again, read more..

  • Page - 20

    12CHAPTER 1: ProgrammingOnce you’ve created an HTML document, you can apply a style to it. For example, you might want to change the layout of the various parts of an HTML document, or you might want to use a different font or apply a background color. The style can be defined as a part of the HTML document, or you can define a style using a CSS (Cascading Style Sheet) file. Although we do not cover style sheets (CSS files) in this book in detail, I make limited use of them for correctly read more..

  • Page - 21

    13CHAPTER 1: ProgrammingYou can also change the style in the HTML document itself rather than using CSS files to define the style. This is done by setting attributes of a tag. For example, the body of the following HTML page has an attribute tag style that is set to change the background color to blue (see Figure actionGoTo:21,1-3 for the page that is displayed): <!DOCTYPE html><html><head><title>BasicExample</title></head><body read more..

  • Page - 22

    14CHAPTER 1: ProgrammingIf you look at the contents of the body, you see that it contains two parts. Each part is enclosed in div tags, which are div used to divide an HTML document into divisions. You can apply a different style to each division. In this example, the first division has a blue background and a font size of 40 pixels, and the second division has a yellow background and a font size of 20 pixels (see also FigureactionGoTo:22, 1-4).Figure 1-4. A web page consisting of two read more..

  • Page - 23

    15CHAPTER 1: ProgrammingThe page shown by the browser looks exactly the same as the first example (shown in FigureactionGoTo:20, 1-2), but there is a crucial difference between using JavaScript to do this as opposed to adding an attribute to the body tag: the JavaScript script changes the color dynamically. This happens because the script contains the following line: document.addEventListener('DOMContentLoaded', changeBackgroundColor); Inside a JavaScript application, you have access to all the read more..

  • Page - 24

    16CHAPTER 1: ProgrammingThis kind of dynamic interaction is possible because the browser can execute JavaScript code. If you want to program games, being able to define how the player should interact with the game is crucial.The HTML5 CanvasA nice thing about the new HTML standard is that it provides a couple of tags that make HTML documents a lot more flexible. A very important tag that was added to the standard is the canvas tag, which allows you to draw 2D and 3D graphics in an HTML read more..

  • Page - 25

    17CHAPTER 1: ProgrammingIn the changeCanvasColor function, you first find the canvas element. This the HTML document element on which you can draw 2D and 3D graphics. Having this element ready in your code is useful, because then you can easily retrieve information about the canvas, such as its width or height. In order to perform operations on the canvas (such as drawing on it), you need a canvas context. The canvas context provides functions for drawing on the canvas. When you retrieve the read more..

  • Page - 26

    18CHAPTER 1: ProgrammingThe JavaScript file BasicExample.js then contains the following code: changeCanvasColor = function () { var canvas = document.getElementById("mycanvas"); var context = canvas.getContext("2d"); context.fillStyle = "blue"; context.fillRect(0, 0, canvas.width, canvas.height)}document.addEventListener('DOMContentLoaded', changeCanvasColor); In many cases, it’s desirable to do this. By separating the script code from the HTML read more..

  • Page - 27

    19 Chapter 2Game Programming BasicsThis chapter covers the basic elements of programming games and provides a starting point for the chapters that follow. First, you learn about the basic skeleton of any game, consisting of a game world and a game loop. You see how to create this skeleton in JavaScript, by looking at various examples such as a simple application that changes the background color. Finally, I talk about clarifying your code by using comments, layout, and whitespace in the right read more..

  • Page - 28

    20CHAPTER 2: Game Programming BasicsPlayers never see the internal representation of the game world, but game developers do. When you want to develop a game, you also need to design how to represent your game world internally. And part of the fun of programming your own games is that you have complete control over this.Another important thing to realize is that just like the real world, the game world is changing all the time. Monsters move to different locations, the weather changes, a car read more..

  • Page - 29

    21CHAPTER 2: Game Programming BasicsThe second collection of tasks is related to displaying the game world to the player. In the case of the Pac-Man game, this means drawing the labyrinth, the ghosts, Pac-Man, and information about the game that is important for the player to know, such as how many points they’ve scored, how many lives they have left, and so on. This information can be displayed in different areas of the game screen, such as at the top or the bottom. This part of the display read more..

  • Page - 30

    22CHAPTER 2: Game Programming BasicsAs you can see, there are a couple of different functions in this script. The start function is called when the body of the HTML document has loaded, because of this instruction: document.addEventListener('DOMContentLoaded', start); In the start function, you retrieve the canvas and the canvas context; you store them in variables so you can use them in other parts of the program (more about that later). Then, you execute another function called mainLoop. This read more..

  • Page - 31

    23CHAPTER 2: Game Programming BasicsThe Structure of a ProgramThis section talks about the structure of a program in more detail. In the early days, many computer programs only wrote text to the screen and didn‘t use graphics. Such a text-based application is called a console application. In addition to printing text to the screen, these applications could also read text that a user entered on the keyboard. So, any communication with the user was done in the form of question/answer sequences read more..

  • Page - 32

    24CHAPTER 2: Game Programming BasicsFunctionsRemember that in an imperative program, the instructions are doing the actual job of the program: they’re executed one after the other. This changes the memory and/or the screen so the user notices that the program is doing something. In the BasicGame program, not all lines in the program are instructions. One example of an instruction is the line context.fillRect(0, 0, canvas.width, canvas.height); which instructs the canvas to draw a rectangle on read more..

  • Page - 33

    25CHAPTER 2: Game Programming BasicsNote The phrase “all your base are belong to us” comes from the opening cut-scene of the video game Zero Wing (1991, Sega Mega Drive) as a poor translation of the original Japanese version. Since then, the phrase has appeared in my articles, television series, movies, websites, and books (such as this one!).functionname{}instructionfunction expressionparameter(),Figure 2-2. The syntax diagram for a function expressionAn interpreter can check the syntax of read more..

  • Page - 34

    26CHAPTER 2: Game Programming BasicsDo you need to know which instructions are grouped together in the fillRect function in order to use it? No, you don’t! This is one of the nice things about grouping instructions in functions. You (or other programmers) can use the function without knowing how it works. By smartly grouping instructions in functions, it’s possible to write reusable program pieces that can be used in many different contexts. The fillRect function is a good example of this. read more..

  • Page - 35

    27CHAPTER 2: Game Programming BasicsIt’s useful to place comments in your code to explain groups of instructions belonging together, the meaning of parameters, or complete classes. If you use comments, do it to clarify the code, not to write the code again in words: you can assume the reader of your code knows JavaScript. To illustrate this, the following comment line adds to the clarity of the instruction: // Set the background color to green.canvasContext.fillStyle = read more..

  • Page - 36

    28CHAPTER 2: Game Programming BasicsBut apart from this, extra spaces are allowed everywhere. The following are good places to put extra whitespace:Behind every comma and semicolon (but not before).Left and right of the equals sign (=). You can see an example of this in the instruction canvasContext.fillStyle = "blue";.At the beginning of lines, so the bodies of methods and classes are indented (usually four positions) with respect to the braces enclosing the body.Most read more..

  • Page - 37

    29 Chapter 3Creating a Game WorldThis chapter shows you how to create a game world by storing information in memory. It introduces basic types and variables and how they can be used to store or change information. Next, you see how to store more complicated information in objects that consist of member variables and methods.Basic Types and VariablesThe previous chapters discussed memory a couple of times. You have seen how to execute a simple instruction like canvasContext.fillStyle = read more..

  • Page - 38

    30CHAPTER 3: Creating a Game WorldThe number passed as a parameter would simply be converted to text. In this case, of course, there is no canvas with ID 12, so the program would no longer correctly. But if you were to replace the canvas ID as follows, then the program would work just fine: <canvas id="12" width="800" height="480"></canvas> The browser automatically converts between text and numbers.Most programming languages are a lot stricter than read more..

  • Page - 39

    31CHAPTER 3: Creating a Game WorldHere you declare five different variables that you can now use in your program. When you declare these variables, they don’t yet contain a value. In this case, these variables are considered undefined. You can assign a value to a variable by using an assignment instruction. For example, let’s assign a value to the variable red, as follows: red = 3; The assignment instruction consists of the following parts:The name of the variable that should be assigned a read more..

  • Page - 40

    32CHAPTER 3: Creating a Game WorldIn the fourth line of this example, you see that it’s possible to declare multiple variables in one declaration. You can even perform multiple declarations with assignments in a single declaration, as can be seen in the sixth line of the example code. On the right side of the assignment, you can put other variables or mathematical expressions, as you can see in the last two lines. The instruction c = d; results in the value stored in variable d being stored read more..

  • Page - 41

    33CHAPTER 3: Creating a Game Worldthat variable for you without you realizing it. If you happen to use a variable with the same name somewhere else, your program may display behavior you don’t expect because that variable already exists. In addition, if you use a lot of different variables, you have to keep track of these global variables as well. But an even bigger problem is shown in the following example: var myDaughtersAge = 12;var myAge = 36;var ourAgeDifference = myAge - mydaughtersAge; read more..

  • Page - 42

    34CHAPTER 3: Creating a Game Worldare method calls and assignments, as you saw in the previous section. Instructions often use expressions. Here are some examples of expressions: 16numberOfBananas2a + 4numberOfBananas + 12 - a-3"myCanvas" All these expressions represent a value of a certain type. Except for the last line, all the expressions are numbers. The last expression is a string (of characters). In addition to numbers and strings, there are other kinds of expressions. I discuss read more..

  • Page - 43

    35CHAPTER 3: Creating a Game WorldPriority of OperatorsWhen multiple operators are used in an expression, the regular arithmetic rules of precedence apply: multiplication before addition. The result of the expression 1+2*3 therefore is 7, not 9. Addition and subtraction have the same priority, and multiplication and division as well.If an expression contains multiple operators of the same priority, then the expression is computed from left to right. So, the result of 10-5-2 is 3, not 7. When read more..

  • Page - 44

    36CHAPTER 3: Creating a Game WorldSo what is the difference between this way of defining a function and the way you have already seen? function someFunction () { // do something} Actually, there isn’t much of a difference. The main thing is that by defining a function in the traditional way (not using a variable), the function doesn’t have to be defined before it can be used. When the browser interprets a JavaScript file, it does so in two stages. In the first stage, the browser read more..

  • Page - 45

    37CHAPTER 3: Creating a Game WorldYou can execute all those instructions by calling the mainLoop function. The instructions that belong to the function are grouped by using braces. Similar to grouping instructions, you can also group variables into a bigger variable. That bigger variable then contains multiple values. Have a look at the following example: var gameCharacter = { name : "Merlin", skill : "Magician", health : 100, power : 230}; This is an example of read more..

  • Page - 46

    38CHAPTER 3: Creating a Game WorldAs you can see, you can access the variables that are a part of gameCharacter by writing their name after a dot. JavaScript even allows you to modify the structure of a composite variable after you have declared and initialized it. For instance, look at the following code: var anotherGameCharacter = { name : "Arthur", skill : "King", health : 25, power : 35000}; anotherGameCharacter.familyName = "Pendragon"; The read more..

  • Page - 47

    39CHAPTER 3: Creating a Game Worldhow the variables were related to each other or what you could do with them. By grouping variables in objects and providing methods that belong with these objects, you can write programs that are much easier to understand. In the next section, you use this power in a simple example that moves a square around the canvas.The MovingSquare GameThis section examines a simple program that moves a square over the canvas. Its purpose is to illustrate two things:How the read more..

  • Page - 48

    40CHAPTER 3: Creating a Game WorldGame.start = function () { Game.canvas = document.getElementById("myCanvas"); Game.canvasContext = Game.canvas.getContext("2d"); Game.mainLoop();}; document.addEventListener('DOMContentLoaded', Game.start); Game.update = function () {}; Game.draw = function () { Game.canvasContext.fillStyle = "blue"; Game.canvasContext.fillRect(0, 0, Game.canvas.width, Game.canvas.height);}; Game.mainLoop = function () { read more..

  • Page - 49

    41CHAPTER 3: Creating a Game WorldNow the only thing you need to do is calculate what the x-position of the rectangle should be. You do this in the update method, because changing the x-position of the rectangle means you’re updating the game world. In this simple example, let’s change the position of the rectangle based on the time that has passed. In JavaScript, you can use the following two instructions to get the current system time: var d = new Date();var currentSystemTime = read more..

  • Page - 50

    42CHAPTER 3: Creating a Game WorldThe only thing you have to do is make sure to call this method before update and draw are called. You do this in the mainLoop method: Game.mainLoop = function() { Game.clearCanvas(); Game.update(); Game.draw(); window.setTimeout(Game.mainLoop, 1000 / 60);}; Now the example is complete! You can run this program by double-clicking the MovingSquare.html file in the folder belonging to this chapter. Figure actionGoTo:50,3-8 shows what it looks read more..

  • Page - 51

    43CHAPTER 3: Creating a Game WorldScope of VariablesThe place where you declare a variable has consequences for where you’re allowed to use the variable. Look at the variable d in the MovingSquare program. This variable is declared (and assigned a value) in the update method. Because it’s declared in the update method, you’re only allowed to use it in this method. For example, you aren’t allowed to use this variable again in the draw method. Of course, you could declare another variable read more..

  • Page - 52

    45 Chapter 4Game AssetsThe previous chapters have shown you how to make a very basic game application by writing your own game loop methods as a part of an object called Game. You have seen which instructions in JavaScript retrieve the canvas as well as the canvas context, which is used to perform operations on the canvas. You have seen a few simple examples where you changed the background color. You also made a rectangle move over the screen by using the current system time in combination read more..

  • Page - 53

    46CHAPTER 4: Game AssetsLocating SpritesBefore a program can use any kind of assets, it needs to know where to look for those assets. By default, the browser acting as interpreter looks for sprites in the same folder as the JavaScript file. Look at the SpriteDrawing example belonging to this chapter. You see a file called spr_balloon.png in the same folder as the HTML file and the JavaScript file. You can load this sprite and draw it on the screen.Loading SpritesLet’s now look at how you can read more..

  • Page - 54

    47CHAPTER 4: Game AssetsThis is much easier than having to type in all the content a variable should have. The expression new Image() basically does that work for you. By using types, you now have an easy way to create objects, and you can be sure these objects always have the same structure. When an object is constructed that has the structure as dictated by the Image type, you say that this object is of type Image.You didn’t yet indicate what data should be contained in this variable. You read more..

  • Page - 55

    48CHAPTER 4: Game AssetsDrawing SpritesLoading a sprite and storing it in memory doesn’t mean the sprite is drawn on the screen. For that to happen, you need to do something in the draw method. To draw a sprite on the canvas somewhere, you use the drawImage method that is a part of the canvas context object. In JavaScript, when an image is drawn at a certain position, that position always refers to the top-left corner of the image. Here is the instruction that draws a sprite in the top-left read more..

  • Page - 56

    49CHAPTER 4: Game AssetsYou use braces to define an object literal that has x and y components. As you can see, it’s allowed to define an object in the instruction that calls a method. Alternatively, you can first define an object, store it in a variable, and then call the drawImage method using that variable: var balloonPos = { x : 100, y : 100};Game.drawImage(Game.balloonSprite, balloonPos); This code does exactly the same thing as the preceding call to drawImage, except it’s much read more..

  • Page - 57

    50CHAPTER 4: Game AssetsMoving SpritesNow that you’re able to draw a sprite on the screen, you can use the game loop to make it move, just like you did with the square in the MovingSquare example in Chapter 3. Let’s make a small extension of this program that changes the balloon’s position based on the passed time. In order to do that, you have to store the balloon position somewhere. You need to calculate this position in the update method and draw the balloon at that position in the read more..

  • Page - 58

    51CHAPTER 4: Game AssetsAlso, in the draw method, there are now two calls to the drawImage method instead of one: Game.draw = function () { Game.drawImage(Game.backgroundSprite, { x : 0, y : 0 }); Game.drawImage(Game.balloonSprite, Game.balloonPosition);}; The order in which these methods are called is very important! Because you want the balloon to appear on top of the background, you first have to draw the background, and then you draw the balloon. If you did it the other way around, read more..

  • Page - 59

    52CHAPTER 4: Game AssetsAgain, pay attention to the order in which you draw the sprites.You can also draw multiple moving sprites at the same time. For each balloon, you can define its own position variable, which is updated in the update method: Game.update = function () { var d = new Date(); Game.balloonPosition1.x = d.getTime() % Game.canvas.width; Game.balloonPosition2.x = (d.getTime() + 100) % Game.canvas.width; Game.balloonPosition3.x = (d.getTime() + 200) % read more..

  • Page - 60

    53CHAPTER 4: Game AssetsIn JavaScript, it’s very easy to play background music or sound effects. To use sound, you first need a sound file that you can play. In the FlyingSpriteWithSound program, you play the file snd_music.mp3, which serves as background music. Similar to storing and using sprites, you add a variable to the Game object in which you store the music data. So, the Game object is declared and initialized as follows: var Game = { canvas : undefined, canvasContext : read more..

  • Page - 61

    54CHAPTER 4: Game AssetsThe volume member variable is generally a value between 0 and 1, where 0 means no sound, and 1 plays back the sound at full volume.Technically, there is no difference between background music and sound effects. Normally, background music is played at a lower volume; and many games loop the background music so that when the song ends, the audio is played from the beginning again. You see later how to do that. All the games you develop in this book use both types of read more..

  • Page - 62

    55 Part IICreating Colorful GamesIn this part, you develop a game called Painter (see FigureactionGoTo:62, II-1). While you’re developing this game, I also introduce a few new techniques that are very useful when programming games, such as organizing instructions in classes and methods, conditional instructions, iteration, and much more.Figure II-1. The Painter gameThe goal of the Painter game is to collect three different colors of paint: red, green, and blue. The paint falls from the sky in read more..

  • Page - 63

    56shoot by using the R, G, and B keys on the keyboard. You can shoot a paint ball by left-clicking in the game screen. By clicking further away from the paint cannon, you give the ball a higher velocity. The place where you click also determines the direction in which the cannon shoots. For each can that lands in the correct bin, you get 10 points. For each wrongly colored can, you lose a life (indicated by the yellow balloons at top left on the screen). You can run the final version of this read more..

  • Page - 64

    57 Chapter 5Knowing What the Player Is DoingIn this chapter, you start to create a game called Painter. In this game, you need to show sprites that move on the screen. You’ve already seen a few examples of loading and displaying sprites. Also, you’ve seen that it’s possible to use the current time information to change the position of a sprite. You build on these examples to begin creating Painter. Furthermore, you learn how to deal with player input in your game. You see how to retrieve read more..

  • Page - 65

    58CHAPTER 5: Knowing What the Player Is Doing The position you calculate is stored in the variable balloonPosition. Now you want to create a program where instead of being calculated based on the passed time, the balloon position is the same as the current mouse position. Getting the current mouse position is very easy using events. In JavaScript, you can handle many different kinds of events. Examples of events are the following:The player moves the mouse.The player left-clicks.The read more..

  • Page - 66

    59CHAPTER 5: Knowing What the Player Is Doing Now, every time the mouse is moved, the handleMouseMove function is called. You can put instructions in this function to extract the mouse position from the evt object. For example, this event-handler function retrieves the mouse’s x-position and y-position and stores them in the variable balloonPosition: function handleMouseMove(evt) { Game.balloonPosition = { x : evt.pageX, y : evt.pageY };} The pageX and pageY member variables of the evt read more..

  • Page - 67

    60CHAPTER 5: Knowing What the Player Is Doing You can see in Figure actionGoTo:67,5-2actionGoTo:67, that the balloon doesn’t appear centered under the very tip of the pointer. There’s a reason for that, and the next section tackles the issue in detail. For now, just remember that the sprite is treated as a rectangle. The upper-left corner is aligned with the pointer tip. The balloon appears misaligned because the balloon is round and doesn’t extend to the corners of the rectangle.Instead read more..

  • Page - 68

    61CHAPTER 5: Knowing What the Player Is Doing Changing the Origin of a SpriteWhen you run the Balloon1 example, notice that the balloon is drawn such that the top-left corner of the sprite is at the current mouse position. When you draw a sprite at a certain position, the default behavior is that the top-left corner of the sprite is drawn at that position. If you execute the following instruction Game.drawImage(someSprite, somePosition); the sprite named someSprite is drawn on the screen such read more..

  • Page - 69

    62CHAPTER 5: Knowing What the Player Is Doing By subtracting the origin from the position, the sprite is drawn at an offset such that the position somePosition indicates the center of the sprite. Instead of calculating the position relative to the origin yourself, the drawImage method from the canvas context also has a way to specify the origin offset. Here is an example: Game.canvasContext.save();Game.canvasContext.translate(position.x, position.y);Game.canvasContext.drawImage(sprite, 0, 0, read more..

  • Page - 70

    63CHAPTER 5: Knowing What the Player Is Doing It would be much nicer if you could write something like this: var pos = somePosition - origin; Unfortunately, this isn’t possible in JavaScript. Some programming languages (such as Java and C#) support operator overloading. This allows a programmer to define what should happen when, for example, two objects are “added” to each other using the plus operator. However, all is not lost. It’s possible to define methods that perform these read more..

  • Page - 71

    64CHAPTER 5: Knowing What the Player Is Doing In the draw method, you can now calculate the origin and pass it along to the drawImage method, as follows: Game.draw = function () { Game.drawImage(Game.backgroundSprite, { x : 0, y : 0 }, { x : 0, y : 0 }); Game.balloonOrigin = { x : Game.balloonSprite.width / 2, y : Game.balloonSprite.height }; Game.drawImage(Game.balloonSprite, Game.mousePosition, Game.balloonOrigin);};Using the Mouse Position to Rotate the read more..

  • Page - 72

    65CHAPTER 5: Knowing What the Player Is Doing You also add a parameter to the drawImage method that lets you specify the angle at which the object should be rotated. This is what the new version of the drawImage method looks like: Game.drawImage = function (sprite, position, rotation, origin) { Game.canvasContext.save(); Game.canvasContext.translate(position.x, position.y); Game.canvasContext.rotate(rotation); Game.canvasContext.drawImage(sprite, 0, 0, sprite.width, sprite.height, read more..

  • Page - 73

    66CHAPTER 5: Knowing What the Player Is Doing You can calculate the length of the opposite and adjacent sides by calculating the difference between the current mouse position and the position of the cannon barrel, as follows: var opposite = Game.mousePosition.y - Game.cannonPosition.y;var adjacent = Game.mousePosition.x - Game.cannonPosition.x; Now you have to calculate the arctangent using these values. How do you do this? Fortunately, JavaScript knows a Math object that can help. The Math read more..

  • Page - 74

    67 Chapter 6Reacting to Player InputIn this chapter, you see how your game program can react to button presses. In order to do this, you need an instruction called if that executes an instruction (or a group of instructions) when a condition is met. You also learn to structure your code a bit more into objects and methods.Objects in GamesUntil now, all the example programs have had one big object called Game. This object consists of a number of variables for storing the canvas and its context, read more..

  • Page - 75

    68CHAPTER 6: Reacting to Player Inputposition or its rotation. You can group related variables into different objects to make the fact that these variables are related clearer in the code. For example, look at this example: var Canvas2D = { canvas : undefined, canvasContext : undefined}; var Game = { backgroundSprite : undefined,}; var cannon = { cannonBarrelSprite : undefined, position : { x : 72, y : 405 }, origin : { x : 34, y : 34 }, rotation : 0}; var Mouse = { read more..

  • Page - 76

    69CHAPTER 6: Reacting to Player InputLoading SpritesNow that you have different objects in your game, where do you load the sprites? You could load all the sprites in the start method of the Game object, but another option is to add a similar method to, for example, the cannon object and load the sprites belonging to the cannon there. Which approach is better?There is something to say for loading the sprites belonging to the cannon object in an initialization method of that object. That way, read more..

  • Page - 77

    70CHAPTER 6: Reacting to Player InputHandling a Key-Down EventIn the previous chapter, you saw how to use an event handler to read the current position of the mouse. In a very similar way, you can react to the event that the player holds down a key on the keyboard. Again, you do this by defining an event handler. You need to store the key that is held down so you can access it later and do something with that information. The easiest way to store which key was pressed is to use key codes. A key read more..

  • Page - 78

    71CHAPTER 6: Reacting to Player InputWhen the variable is initialized, it contains a keyDown variable that contains the value -1. This value represents that the player currently is not pressing any key. When the player presses a key, you have to store the key code in the variable Keyboard.keyDown. You do so by writing an event handler that stores the currently pressed key. Here is what that event handler looks like: function handleKeyDown(evt) { Keyboard.keyDown = evt.keyCode;} As you can read more..

  • Page - 79

    72CHAPTER 6: Reacting to Player InputYou need to load three extra sprites, one for each colored ball. This is done with the following three instructions: sprites.cannon_red = Game.loadSprite(spriteFolder + "spr_cannon_red.png");sprites.cannon_green = Game.loadSprite(spriteFolder + "spr_cannon_green.png");sprites.cannon_blue = Game.loadSprite(spriteFolder + "spr_cannon_blue.png"); You add an initialize method to the cannon object, in which you assign values to read more..

  • Page - 80

    73CHAPTER 6: Reacting to Player InputAs you can see, you have two position variables: one for the cannon barrel and one for the colored sphere. Furthermore, you add a variable that refers to the current color of the sphere that should be drawn. Initially, you assign the red sphere sprite to this variable.In order to make a clear separation between the objects, you can also add a draw method to the cannon object. In this method, you draw the cannon barrel and the colored sphere on top of it: read more..

  • Page - 81

    74CHAPTER 6: Reacting to Player InputThe condition is always placed in parentheses. A block of instructions follows, enclosed by braces. In this example, the background is drawn only if the mouse’s x-position is larger than 200. As a result, if you move the mouse too far to the left on the screen, the background isn’t drawn. You can place multiple instructions between the braces if you want: if (Game.mousePosition.x > 200) { Canvas2D.drawImage(sprites.background, { x : 0, y : 0 }, 0, read more..

  • Page - 82

    75CHAPTER 6: Reacting to Player InputComparison OperatorsThe condition in the header of an if instruction is an expression that returns a truth value: yes or no. When the outcome of the expression is yes, the body of the if instruction is executed. In these conditions, you’re allowed to use comparison operators. The following operators are available:< Less than<= Less than or equal to> Greater than>= Greater than or equal to=== Equal to!== Not equal toThese read more..

  • Page - 83

    76CHAPTER 6: Reacting to Player InputLogic OperatorsIn logical terms, a condition is also called a predicate. The operators that are used in logic to connect predicates (and, or, and not) can also be used in JavaScript. They have a special notation:&& is the logical and operator.|| is the logical or operator.! is the logical not operator.You can use these operators to check for complicated logical statements so that you can execute instructions only in very particular cases. read more..

  • Page - 84

    77CHAPTER 6: Reacting to Player InputIn this case, if the expression isAlive evaluates to true, the body of the if instruction is executed. You might think this code would generate a compiler error and you need to do a comparison of the Boolean variable, like this: if (isAlive === true) // do something However, this extra comparison isn’t necessary. A conditional expression as in the if instruction has to evaluate to true or false. Because a Boolean variable already represents one of read more..

  • Page - 85

    78CHAPTER 6: Reacting to Player InputAiming the Barrel at the Mouse PointerIn the previous sections, you’ve seen how to use the if instruction to check whether the player has pressed the R key. Now, suppose you want to update the angle of the cannon barrel only if the left mouse button is down. In order to handle mouse button presses, you need two more event handlers: one for handling the event that the user presses a mouse button, and another for handling the event that the user releases the read more..

  • Page - 86

    79CHAPTER 6: Reacting to Player InputSuppose you want to have the angle reset to zero after the player releases the left mouse button. You could add another if instruction, like this: if (!Mouse.leftDown) cannon.rotation = 0; For more complex conditions, this kind of solution will become harder to understand. There is a nicer way of dealing with this situation: by using an if instruction with an alternative. The alternative instruction is executed when the condition in the if instruction is read more..

  • Page - 87

    80CHAPTER 6: Reacting to Player InputA Number of Different AlternativesWhen there are multiple categories of values, you can find out with if instructions which case you’re dealing with. The second test is placed after the else of the first if instruction so that the second test is executed only when the first test fails. A third test could be placed after the else of the second if instruction, and so forth.The following fragment determines within which age segment a player falls, so that you read more..

  • Page - 88

    81CHAPTER 6: Reacting to Player InputThe additional advantage here is that using this layout, it’s a lot easier to see which cases are handled by the instructions. You can also see that the example code uses multiple alternatives to handle the three different color cases in the update method of the cannon object: if (Keyboard.keyDown === Keys.R) cannon.currentColor = sprites.cannon_red;else if (Keyboard.keyDown === Keys.G) cannon.currentColor = sprites.cannon_green;else if read more..

  • Page - 89

    82CHAPTER 6: Reacting to Player InputHere you also see an example of a nested if instruction, meaning the body of an if instruction contains one or more if instructions itself. You can now write the code needed to toggle the cannon barrel’s behavior by writing an if instruction that checks whether the left mouse button has been pressed: if (Mouse.leftPressed) cannon.calculateAngle = !cannon.calculateAngle; In the body of the if instruction, you toggle the calculateAngle variable. This is a read more..

  • Page - 90

    83 Chapter 7Basic Game ObjectsIn this chapter, you start organizing the source code of the Painter game a bit more. This is necessary because the source code of a game contains many lines of code. In the previous examples, you began grouping variables over different objects (such as Canvas2D or cannon). In this chapter, you continue structuring your code by using more objects and by splitting the code over separate files.Using Separate JavaScript FilesOne thing you’ve probably noticed is that read more..

  • Page - 91

    84CHAPTER 7: Basic Game ObjectsUnfortunately, you run into trouble if you try to take this approach of adding more and more script elements. Because the JavaScript files are retrieved from a server somewhere, there is no way to know for sure which JavaScript file will be finished loading first. Suppose the first file the browser can load is Painter.js. The browser can’t interpret the code in this file because the code refers to code in other files (such as the Canvas2D object). And this holds read more..

  • Page - 92

    85CHAPTER 7: Basic Game ObjectsLoading Game Assets the Wrong WayPreviously, I talked about the browser loading files in an arbitrary order because these files have to be retrieved from a server. The same rules apply to loading game assets such as sprites and sounds. This is the method you’ve used up until now to load game assets: var sprite = new Image();sprite.src = "someImageFile.png";var anotherSprite = new Image();anotherSprite.src = "anotherImageFile.png"; // and read more..

  • Page - 93

    86CHAPTER 7: Basic Game ObjectsHere, you call the random function that is defined as a part of the Math object, and you store its result in the variable n. Apparently, random provides a result value that can be stored. The Canvas2D.drawImage method on the other hand doesn’t provide a result that you can store in a variable. Of course, the method does have an effect of some sort, because it draws a sprite on the screen, which could also be considered a result of the method call. However, when read more..

  • Page - 94

    87CHAPTER 7: Basic Game Objectschange the color of the cannon if the mouse is in the left part of the screen. You can achieve that as follows: cannon.handleInput = function () { if (Mouse.position.x > 10) return; if (Keyboard.keyDown === Keys.R) cannon.currentColor = sprites.cannon_red; else if (Keyboard.keyDown === Keys.G) // etc.}; In this method, you first check if the mouse x-position is greater than 10. If that is the case, you execute the return read more..

  • Page - 95

    88CHAPTER 7: Basic Game ObjectsLoading Game Assets the Right WayIn order to make sprite loading a little bit easier, let’s add a method loadSprite to the Game object: Game.loadSprite = function(imageName) { var image = new Image(); image.src = imageName; return image;} The code for loading the different sprites now becomes much shorter: var sprFolder = "../../assets/Painter/sprites/";sprites.background = Game.loadSprite(sprFolder + read more..

  • Page - 96

    89CHAPTER 7: Basic Game ObjectsNow the spritesStillLoading variable accurately represents how many sprites still have to be loaded. You can use this information to wait on starting the main loop until this variable contains the value 0. In order to do this, you create two loop methods: an asset-loading loop and a main game loop. In the asset-loading loop, you simply check if there are still sprites that have to be loaded. If that is the case, you call the asset-loading loop again. If all the read more..

  • Page - 97

    90CHAPTER 7: Basic Game ObjectsYou use the || operator here to determine which method the window.requestAnimationFrame name refers to. If the first option isn’t defined (for example, if you’re dealing with an older browser), you check any of the older names. If none of the optimized game-loop methods are available, you let requestAnimationFrame point to a function that calls the window.setTimeout method. In JavaScript, the window variable is a container of the global namespace. This means read more..

  • Page - 98

    91CHAPTER 7: Basic Game Objectsthe sprite-loading code, you simply have to include the source file containing the code into your new game application, instead of sorting through the Painter game code to find what you need. Another reason to do this is to enable you to more quickly create similar games later. You might find yourself developing a game that is similar to a game you developed earlier. By organizing code in this way, you can produce your new game more rapidly while also not read more..

  • Page - 99

    92CHAPTER 7: Basic Game Objects Game.gameWorld.draw(); Mouse.reset(); requestAnimationFrame(Game.mainLoop);}; As a result, you have nicely separated the generic game code (in Game.js) and the game-specific code, which consists of loading the sprites and initializing the game (Painter.js) and updating and drawing the Painter game objects (PainterGameWorld.js). Any other game objects specific to Painter are each defined in their own script file (such as Cannon.js).Adding a Ball to the read more..

  • Page - 100

    93CHAPTER 7: Basic Game ObjectsIn the games you develop in this book, most of the objects have a position and a velocity. Because the book is only concerned with 2D games, both the position and the velocity are always variables that consists of an x and a y variable. When you update these game objects, you need to calculate the new position based on the velocity vector and the time that has passed. Later in this chapter, you see how to do that.In order to be able to use the ball object, you read more..

  • Page - 101

    94CHAPTER 7: Basic Game ObjectsHere you can see a nice way of making the sprite-loading calls more readable in JavaScript. You declare a local variable loadSprite that refers to a function. This function takes as a parameter a sprite image name and calls the Game.loadSprite method. As a parameter to that method, you pass along the folder path of the sprite plus the name of the sprite. Finally, the function returns the result of the Game.loadSprite method.Creating the BallLet’s get back to the read more..

  • Page - 102

    95CHAPTER 7: Basic Game ObjectsYou can see in the body of this method that you use the return keyword to draw the ball only if it isn’t shooting. Inside the painterGameWorld object, you have to call the game-loop methods on the ball. For example, this is the draw method in painterGameWorld, from which the ball.draw method is called: painterGameWorld.draw = function () { Canvas2D.drawImage(sprites.background, { x : 0, y : 0 }, 0, { x : 0, y : 0 }); ball.draw(); read more..

  • Page - 103

    96CHAPTER 7: Basic Game ObjectsBecause the ball is now moving, you need to give it a velocity. This velocity is a vector in the direction of the place where the player clicked. You can calculate this direction by subtracting the ball position from the mouse position. Because the velocity has an x component and a y component, you need to do this for both dimensions: ball.velocity.x = (Mouse.position.x - ball.position.x);ball.velocity.y = (Mouse.position.y - ball.position.y); Calculating the read more..

  • Page - 104

    97CHAPTER 7: Basic Game ObjectsInside ball.update, you need to define the ball’s behavior. This behavior is different depending on whether the ball is currently shooting. This is the complete method: ball.update = function (delta) { if (ball.shooting) { ball.velocity.x = ball.velocity.x * 0.99; ball.velocity.y = ball.velocity.y + 6; ball.position.x = ball.position.x + ball.velocity.x * delta; ball.position.y = ball.position.y + ball.velocity.y * delta; } read more..

  • Page - 105

    98CHAPTER 7: Basic Game ObjectsThis way of calculating the past time in a game loop is called a fixed timestep. If you have a very slow computer that is not able to execute the game loop 60 times per second, you still tell your game objects that only 1/60 of a second has passed since the last time, even though that may not be true. As a result, game time is different from real time. Another way to do it would be to calculate the actual passed time by accessing the system time. Here is how you read more..

  • Page - 106

    99CHAPTER 7: Basic Game ObjectsThe current position of the ball is updated by adding the velocity to its x and y components. Here are the instructions that do this: ball.position.x = ball.position.x + ball.velocity.x * delta;ball.position.y = ball.position.y + ball.velocity.y * delta; As you can see, this is where the delta variable is used. You calculate the new position of the ball based on the velocity and the time that has passed since the last update. You multiply each velocity dimension read more..

  • Page - 107

    100CHAPTER 7: Basic Game Objectsthe ball based on the barrel orientation. Using the sine and cosine functions, you calculate the new position as follows: cannon.ballPosition = function() { var opp = Math.sin(cannon.rotation) * sprites.cannon_barrel.width * 0.6; var adj = Math.cos(cannon.rotation) * sprites.cannon_barrel.width * 0.6; return { x : cannon.position.x + adj, y : cannon.position.y + opp };}; As you can see, you multiply the opposite and adjacent sides with a value of 0.6 so read more..

  • Page - 108

    101CHAPTER 7: Basic Game ObjectsIn the isOutsideWorld method, you use the Game.size variable to determine whether a position is outside the game world. The body of the method consists of a single instruction using the keyword return to calculate a Boolean value. The logical or operation is used to cover the different cases in which the position is outside the game world: return position.x < 0 || position.x > Game.size.x || position.y > Game.size.y; As you can see, you don’t mind if read more..

  • Page - 109

    103 Chapter 8Game Object TypesIn the previous chapters, you’ve seen how to create a game world that contains a few different game objects, such as a cannon and a ball. You’ve seen how to let game objects interact with each other. For example, the ball object updates its color according to the color of the cannon. In this chapter, you add falling paint cans to the game world. However, before you can do that, you have to reexamine how to create and manage objects in JavaScript. I introduce the read more..

  • Page - 110

    104CHAPTER 8: Game Object TypesSuppose you want to be able to shoot three balls at the same time in the Painter game. If you did this the way you created objects until now, you would create two variables, ball2 and ball3, and copy the code you used for the ball object twice. This isn’t a very nice solution, for several reasons. For one, copying code means you have to deal with version-management problems. For example, what if you find a bug in the update method code? You have to make sure you read more..

  • Page - 111

    105CHAPTER 8: Game Object TypesThe nice thing is that you can now create lots of dogs that can bark, but you only have to define the bark method once: var max = new Dog();var zoe = new Dog();var buster = new Dog();max.bark();zoe.bark();buster.bark(); Of course, the goal of this book is not to show you how to become a dog breeder, but how to create games. And for games, the prototype concept is very powerful. It allows you to separate the actual objects that are used in your game from how they read more..

  • Page - 112

    106CHAPTER 8: Game Object TypesYou can actually shorten the code you’ve written a little. Why add an initialize method when Ball itself already is a function that is called? You can simply perform the initialization in that function, as follows: function Ball() { this.position = { x : 0, y : 0 }; this.velocity = { x : 0, y : 0 }; this.origin = { x : 0, y : 0 }; this.currentColor = sprites.ball_red; this.shooting = false;} Now when you create balls, they’re initialized on read more..

  • Page - 113

    107CHAPTER 8: Game Object TypesHave a look at the Ball.js file in the Painter5 example belonging to this chapter. You can see the Ball class and all its methods. Note that I didn’t add any functionality to the balls; I only applied the prototype principle to define the blueprint for balls.The concept of classes and objects is extremely powerful. It forms the basis of the object-oriented programming paradigm. JavaScript is a very flexible language, in that it doesn’t oblige you to use read more..

  • Page - 114

    108CHAPTER 8: Game Object TypesIn the update method of the ball, you need to retrieve the current color of the cannon so you can update the ball’s color. Here is how you did this in the previous chapter: if (cannon.currentColor === sprites.cannon_red) ball.currentColor = sprites.ball_red;else if (cannon.currentColor === sprites.cannon_green) ball.currentColor = sprites.ball_green;else ball.currentColor = sprites.ball_blue; When defining a class using the JavaScript prototype read more..

  • Page - 115

    109CHAPTER 8: Game Object TypesAs you can see, this class is capable of constructing the Game object that was used in the previous chapter. The Game_Singleton class has an initialize method, where the game world object is created: Game_Singleton.prototype.initialize = function () { this.gameWorld = new PainterGameWorld();}; Okay, you’ve discovered where the game world is constructed. But where is the instance of the Game_Singleton object constructed? You need this instance in order to read more..

  • Page - 116

    110CHAPTER 8: Game Object TypesWriting a Class with Multiple InstancesNow that you can construct multiple objects of the same type, let’s add a few paint cans to the Painter game. These paint cans should be given a random color, and they should fall down from the top of the screen. Once they have fallen out of the bottom of the screen, you assign a new color to them and move them back to the top. For the player, it seems as though different paint cans are falling each time. Actually, you need read more..

  • Page - 117

    111CHAPTER 8: Game Object TypesDealing with Randomness in GamesOne of the most important parts of the paint-can behavior is that some aspects of it should be unpredictable. You don’t want every can falling at a predictable speed or time. You want to add a factor of randomness so that every time the player starts a new game, the game will be different. Of course, you also need to keep this randomness in control. You don’t want one can to take three hours to fall from top to bottom while read more..

  • Page - 118

    112CHAPTER 8: Game Object TypesHumans aren’t really any better than computers at understanding “true” randomness. This is why your MP3 player in shuffle mode sometimes seems to keep playing the same songs over and over. You perceive naturally occurring streaks to be non-random when in fact they are random. This means programmers sometimes have to create a function that appears random to humans—even though it’s not truly random.In games, you have to deal very carefully with randomness. read more..

  • Page - 119

    113CHAPTER 8: Game Object TypesThis example combines Math.random and Math.floor to generate a random number that is 0, 1, or 2: var randomval = Math.floor(Math.random() * 3); Using this approach, you can calculate a random value and then use an if instruction to select a color for the paint can. This task is done by the calculateRandomColor method. Here is what the method looks like: PaintCan.prototype.calculateRandomColor = function () { var randomval = Math.floor(Math.random() * 3); if read more..

  • Page - 120

    114CHAPTER 8: Game Object TypesNow that you’ve initialized the can and updated its position, you need to handle the special cases. For the paint can, you have to check whether it has fallen outside the game world. If so, you need to reset it. The nice thing is that you already wrote a method to check whether a certain position is outside the game world: the isOutsideWorld method in the PainterGameWorld class. You can now use that method again to check whether the position of the can is read more..

  • Page - 121

    115CHAPTER 8: Game Object TypesRepresenting Positions and Velocities as VectorsYou’ve seen that classes are a valuable concept because they define a structure for objects, as well as behavior to modify those objects through methods. This is particularly useful when you need multiple similar objects (such as three paint cans). Another area where classes can be very useful is for defining basic data structures and methods to manipulate these structures. A common structure that you’ve already read more..

  • Page - 122

    116CHAPTER 8: Game Object TypesYou can now create an object as follows: var position = new Vector2(0,0); It would be nice if somehow you could initialize a vector without having to pass both parameters all the time. One way to do this is to check whether x and/or y is undefined. If that is the case, you simply initialize the member variable to 0, as follows: function Vector2(x, y) { if (typeof x === 'undefined') this.x = 0; else this.x = x; if (typeof y === 'undefined') read more..

  • Page - 123

    117CHAPTER 8: Game Object TypesYou can also define a few basic operations such as adding, subtracting, multiplying, and dividing vectors. First, let’s define a method for adding a vector to an existing vector: Vector2.prototype.addTo = function (v) { this.x = this.x + v.x; this.y = this.y + v.y; return this;}; You can use this method as follows: var position = new Vector2(10, 10); // create a vector (10, 10)var anotherPosition = new Vector2(20, 20); // create a vector (20, read more..

  • Page - 124

    118CHAPTER 8: Game Object Types else if (v.constructor === Number) { this.x = this.x + v; this.y = this.y + v; } return this;}; The addTo method adds a vector to an existing vector. You can also define an add method that adds two vectors and returns a new vector. To do that, you can reuse the copy and addTo methods: Vector2.prototype.add = function (v) { var result = this.copy(); return result.addTo(v);}; You can now do the following: var position = new Vector2(10, read more..

  • Page - 125

    119CHAPTER 8: Game Object TypesBecause of the assignment instructions inside the method body, you will still create a valid Vector2 object even if you don’t pass any parameters when you call the constructor method. If the parameters x and y are not defined, default values are used. You can use this situation to your advantage, because relying on default values can lead to much simpler code writing. To give an example, this is the instruction that draws the background image on the screen: read more..

  • Page - 126

    121 Chapter 9Colors and CollisionsBy now, you’ve implemented quite a large part of the Painter game. You’ve seen how to define game object classes by using the prototype mechanism. By using these classes, you gain more control over how game objects are structured and how you can create game objects of a certain type. You separate these class definitions over different files. That way, when you need a cannon or a ball with the same behavior in a future game you’re working on, you can simply read more..

  • Page - 127

    122CHAPTER 9: Colors and CollisionsYou did a similar thing in the Ball class, except you let the variable of the same name point to colored ball sprites. Although this works fine, it’s slightly inconvenient when the color of a ball needs to change according to the color of the cannon: if (Game.gameWorld.cannon.currentColor === sprites.cannon_red) this.currentColor = sprites.ball_red;else if (Game.gameWorld.cannon.currentColor === sprites.cannon_green) this.currentColor = read more..

  • Page - 128

    123CHAPTER 9: Colors and Collisionscomponents can be defined in a similar way. #808080 is gray, #800080 results in a purple color, and #FF00FF is magenta.Here is a part of the Color variable: var Color = { aliceBlue: "#F0F8FF", antiqueWhite: "#FAEBD7", aqua: "#00FFFF", aquamarine: "#7FFFD4", azure: "#F0FFFF", beige: "#F5F5DC", bisque: "#FFE4C4", black: "#000000", blanchedAlmond: read more..

  • Page - 129

    124CHAPTER 9: Colors and CollisionsHowever, this isn’t ideal. You now store redundant data, because the color information is represented by two variables. Furthermore, you might introduce bugs this way if you forget to change one of the two variables when the color of the cannon changes.Another way to do it would be to not store a reference to the current sprite. This would be the constructor: function Cannon() { this.position = new Vector2(72, 405); this.colorPosition = new read more..

  • Page - 130

    125CHAPTER 9: Colors and CollisionsRead-Only PropertiesFollowing the prototype-based programming paradigm, you want to be able to add properties to classes. JavaScript has a handy method called defineProperty that allows you to do this. This method is part of an object, elusively called Object. Object has a couple of other useful methods as well, as you learn later. The defineProperty method expects three parameters:The prototype to which the property should be added (for example, read more..

  • Page - 131

    126CHAPTER 9: Colors and Collisions var adjacent = Math.cos(this.rotation) * sprites.cannon_barrel.width * 0.6; return new Vector2(this.position.x + adjacent, this.position.y + opposite); } }); Just as you do with methods, you use the this keyword to refer to the object the property belongs to. The Painter7 example belonging to this chapter adds properties to different classes. For example, the Ball class also contains a center read more..

  • Page - 132

    127CHAPTER 9: Colors and Collisionsif instruction to find out which color to return. Just as for a method that has a return value, you use the return keyword to indicate what value the property should return: Object.defineProperty(Cannon.prototype, "color", { get: function () { if (this.currentColor === sprites.cannon_red) return Color.red; else if (this.currentColor === sprites.cannon_green) return Color.green; read more..

  • Page - 133

    128CHAPTER 9: Colors and CollisionsThis is an example of a property that can be read from and written to. You add a color property to all the colored game-object types: Cannon, Ball, and PaintCan. The only difference in the code in the get and set parts is the sprites used to represent the colors. For example, this is the color property of the Ball class: Object.defineProperty(Ball.prototype, "color", { get: function () { if (this.currentColor === read more..

  • Page - 134

    129CHAPTER 9: Colors and Collisionsthe center of game objects, let’s use them to calculate the distance between the ball and a paint can, as follows: var ball = Game.gameWorld.ball;var distance = ball.position.add(ball.center).subtractFrom(this.position) .subtractFrom(this.center); Now that you’ve calculated this vector, you have to check whether its length in both the x- and y-directions is smaller than some given value. If the absolute value of the x-component of the distance vector is read more..

  • Page - 135

    131 Chapter 10Limited LivesIn this chapter, you make the Painter game more interesting by giving the player a limited number of lives. If players miss too many paint cans, they die. The chapter discusses how to deal with that and how to display the current number of lives to the player. In order to do the latter, you learn about a few programming constructs for repeating a group of instructions several times. Maintaining the Number of LivesTo introduce some danger and incentive to work hard in read more..

  • Page - 136

    132CHAPTER 10: Limited LivesBefore you can do this, you have to extend the PaintCan class so that PaintCan objects know that they need to have a target color when they fall out of the bottom of the screen. Painter8 passes along this target color as a parameter when you create the PaintCan objects in PainterGameWorld: this.can1 = new PaintCan(450, Color.red);this.can2 = new PaintCan(575, Color.green);this.can3 = new PaintCan(700, Color.blue); You store the target color in a variable in each read more..

  • Page - 137

    133CHAPTER 10: Limited LivesIndicating the Number of Lives to the PlayerObviously, players would like to know how they’re doing. So, you have to indicate somehow on the screen how many lives the player has left. In the Painter game, you do that by displaying a number of balloons in the upper-left corner of the screen. Using the knowledge you have, you could use an if instruction to do that: if (lives === 5) { // Draw the balloon sprite 5 times in a row} else if (lives === 4) { // Draw read more..

  • Page - 138

    134CHAPTER 10: Limited LivesAt that point, the condition is evaluated, but it’s no longer true. Therefore, the repeating instruction comes to an end. So, after this piece of code is executed, the variable val contains the value 1. In fact, what you’ve programmed here is integer division using the while instruction. Of course, in this case it’s easier to simply use the following single line of code that achieves the same result: var val = 10 % 3; If you want to draw the player’s number read more..

  • Page - 139

    135CHAPTER 10: Limited LivesA Shorter Notation for Incrementing CountersMany while instructions, especially those that use a counter, have a body that contains an instruction for incrementing a variable. This can be done with the following instruction: i = i + 1; As a side note, especially because of these kinds of instructions, it’s unwise to express the assignment as “is”. The value of i can of course never be the same as i + 1, but the value of i becomes the old value of i, plus 1. read more..

  • Page - 140

    136CHAPTER 10: Limited LivesThere is a similar notation for other basic arithmetic operations, for example: i -= 12; // this is the same as i = i – 12i *= 0.99; // this is the same as i = i * 0.99i /=5; // this is the same as i = i / 5i--; // this is the same as i = i – 1 This notation is very useful, because it allows you to write shorter code. For example, the following code: Game.gameWorld.lives = Game.gameWorld.lives – penalty; ...becomes: Game.gameWorld.lives -= read more..

  • Page - 141

    137CHAPTER 10: Limited LivesThis is a very compact instruction that increments the counter and draws the sprite at different positions. This instruction is equivalent to the following while instruction: var i = 0;while (i < this.lives) { Canvas2D.drawImage(sprites.lives, new Vector2(i * sprites.lives.width + 15, 60)); i = i + 1;} And here’s another example: for (var i = this.lives - 1; i >=0; i--) Canvas2D.drawImage(sprites.lives, new Vector2(i * read more..

  • Page - 142

    138CHAPTER 10: Limited LivesIn this case, the body of the while instruction isn’t executed—not even once! Therefore, in this example, the variable x retains the value 1.Infinite RepeatOne of the dangers of using while instructions (and, to a lesser extent, for instructions) is that they might never end, if you’re not careful. You can easily write such an instruction: while (1 + 1 === 2) x = x + 1; In this case, the value of x is incremented without end. This is because the condition 1 read more..

  • Page - 143

    139CHAPTER 10: Limited LivesNested RepeatsThe body of a while instruction or a for instruction is an instruction. This instruction can be an assignment, a method call, a block of instructions delimited by braces, or another while or for loop. For example: var x, y;for (y=0; y<7; y++) for (x=0; x<y; x++) Canvas2D.drawImage(sprites.lives, new Vector2(x * sprites.lives.width, y * sprites.lives.height)); In this fragment, the variable y counts from 0 to 7. For each of read more..

  • Page - 144

    140CHAPTER 10: Limited LivesThe first line in this shape contains zero balloons. The reason is that the value of y is still 0 at that point, which means the inner for instruction is executed zero times.Restarting the GameWhen the player has lost all their lives, the game is over. How do you deal with this? In the case of the Painter game, you would like to show a Game Over screen. The player can press the left mouse button, which will then restart the game. In order to add this to the game, you read more..

  • Page - 145

    141CHAPTER 10: Limited LivesFinally, in the draw method, you draw the game objects, and the Game Over screen if the player has no lives left. This results in the following structure: PainterGameWorld.prototype.draw = function () { // draw the game world ... for (var i = 0; i < this.lives; i++) { Canvas2D.drawImage(sprites.lives, new Vector2(i * sprites.lives.width + 15, 60)); } if (this.lives <= 0) { Canvas2D.drawImage(sprites.gameover, read more..

  • Page - 146

    142CHAPTER 10: Limited LivesNote You can use the (lack of) transparency of overlays to control what the player is seeing. In some cases, you might want things obscured (such as a “pause” screen in a time-sensitive game) or able to be seen (such as the Game Over screen in Painter).What You Have LearnedIn this chapter, you have learned:How to store and display the number of lives a player currently hasHow to repeat a group of instructions using the while or for instructionHow to read more..

  • Page - 147

    143 Chapter 11Organizing Game ObjectsYou’ve seen in the previous chapters how you can use classes to group variables that belong together. This chapter looks at the similarities between the different types of game objects and how you can express these similarities in JavaScript.Similarities between Game ObjectsIf you look at the different game objects in the Painter game, you can see that they have a lot of things in common. For example, the ball, the cannon, and the paint cans all use three read more..

  • Page - 148

    144CHAPTER 11: Organizing Game ObjectsThe code is exactly the same, but you have to copy it for both classes. And every time you want to add a different kind of game object, you probably need to copy these properties again. In this case, these properties are fortunately not that complicated, but in the application you’re copying around a lot of other things as well. For example, most game object classes in the Painter game define the following member variables: this.currentColor = some read more..

  • Page - 149

    145CHAPTER 11: Organizing Game ObjectsInheritanceUsing prototypes in JavaScript, it’s possible to group these similarities together in a sort of generic class and then define other classes that are a special version of this generic class. In object-oriented jargon, this is called inheritance, and it’s a very powerful language feature. In JavaScript, inheritance is made possible by the prototype mechanism. Consider the following example: function Vehicle() { this.numberOfWheels = 4; read more..

  • Page - 150

    146CHAPTER 11: Organizing Game ObjectsWhat happens here is that the Vehicle constructor is called, using the same object that is created when the Car constructor is invoked. In essence, you’re telling the interpreter that the Car object (this) you’re currently manipulating is actually also a Vehicle object. So you can see the two important aspects of inheritance:There is a relationship between objects (a Car object is also a Vehicle).A class that inherits from another class copies its read more..

  • Page - 151

    147CHAPTER 11: Organizing Game ObjectsLet’s look at this ThreeColorGameObject class in more detail. You put into this class the member variables that are commonly used by the different types of game objects in the game. You can define a basic skeleton of this class as follows: function ThreeColorGameObject() { this.currentColor = undefined; this.velocity = Vector2.zero; this.position = Vector2.zero; this.origin = Vector2.zero; this.rotation = 0; this.visible = true;} Each read more..

  • Page - 152

    148CHAPTER 11: Organizing Game ObjectsThe update method of the class contains a single instruction that updates the current position of the game object: ThreeColorGameObject.prototype.update = function (delta) { this.position.addTo(this.velocity.multiply(delta));}; Finally, you add a few convenient properties for getting and setting the color, and retrieving the dimensions of the object. For example, this is the property for reading and writing the object’s color: read more..

  • Page - 153

    149CHAPTER 11: Organizing Game ObjectsBecause Cannon inherits from ThreeColorGameObject, you need to call the constructor of the ThreeColorGameObject class. This constructor expects three parameters. Because you’re creating a Cannon object, you want to pass the colored cannon sprites to that constructor. Fortunately, you can pass along these sprites in the call method, as follows: ThreeColorGameObject.call(this, sprites.cannon_red, sprites.cannon_green, sprites.cannon_blue); Second, you read more..

  • Page - 154

    150CHAPTER 11: Organizing Game ObjectsFor cannons, this method doesn’t do exactly what you want. You want to draw the color of the cannon, but you also want to draw the cannon barrel. Replacing a method is very easy. You simply redefine the method as a part of the Cannon prototype: Cannon.prototype.draw = function () { if (!this.visible) return; var colorPosition = this.position.subtract(this.size.divideBy(2)); Canvas2D.drawImage(sprites.cannon_barrel, this.position, read more..

  • Page - 155

    151CHAPTER 11: Organizing Game ObjectsThe Ball ClassYou define the new Ball class in a fashion very similar to the Cannon class. Just as in the Cannon class, you inherit from the ThreeColorGameObject class. The only difference is that you have to add an extra member variable that indicates whether the ball is currently shooting: function Ball() { ThreeColorGameObject.call(this, sprites.ball_red, sprites.ball_green, sprites.ball_blue); this.shooting = false; read more..

  • Page - 156

    152CHAPTER 11: Organizing Game ObjectsYou might be a bit puzzled by these two figures and the structures they present. Later, this chapter discusses memory structure in a bit more detail. For now, assume that complicated objects consisting of multiple member variables (such as Cannon or Ball instances) are stored differently than simple numbers or Booleans. What that means and how you should properly deal with it in your code are covered at the end of the chapter.The update method in the read more..

  • Page - 157

    153CHAPTER 11: Organizing Game Objects else { this.color = Game.gameWorld.cannon.color; this.position = Game.gameWorld.cannon.ballPosition .subtractFrom(this.center); } if (Game.gameWorld.isOutsideWorld(this.position)) this.reset();}; Look at the first instruction in this method. You’re accessing the prototype object of ThreeColorGameObject, which contains an update function. You call this update function while passing the this object, so the Ball read more..

  • Page - 158

    154CHAPTER 11: Organizing Game ObjectsHierarchies of ClassesYou’ve seen several examples in this chapter of classes inheriting from a base game-object class. A class should inherit from another class only if the relationship between these two classes can be described as “is a kind of.” For example: a Ball is a kind of ThreeColorGameObject. In fact, the hierarchy doesn’t end there. You could write another class that inherits from the Ball class, such as BouncingBall, which could be a read more..

  • Page - 159

    155CHAPTER 11: Organizing Game Objectsin different subclasses: motorized or not motorized. You could choose to do this the other way around. For some classes, it isn’t entirely clear where in the hierarchy they belong: do you say that a motorbike is a special type of bike (one with a motor)? Or is it a special kind of motorized vehicle (one with only two wheels)?What is important is that the relationship between the classes themselves is clear. A sailboat is a boat, but a boat isn’t always read more..

  • Page - 160

    156CHAPTER 11: Organizing Game ObjectsLooking at the previous example using the number type, you would expect that there are now two Cannon objects in memory: one stored in the variable cannon1, and one stored in cannon2. However, this isn’t the case! Actually, both cannon1 and cannon2 refer to the same object. After the first instruction (creating the Cannon object), the memory is shown in Figure actionGoTo:160,11-8.cannon1Cannon...© Springer-Verlag Berlin Heidelberg 2013Figure 11-8. A read more..

  • Page - 161

    157CHAPTER 11: Organizing Game Objectsand now the following instructions: var someNumber = 10;square(someNumber); After executing these instructions, the value of someNumber still is 10 (and not 100). Why is this? Because when the square function is called, the number parameter is passed by value. The variable f is a local variable in the method that initially contains the value of the someNumber variable. In the method, the local variable f is changed to contain f * f, but this doesn’t read more..

  • Page - 162

    158CHAPTER 11: Organizing Game ObjectsIn this example, you check whether the variable is equal to null (not pointing to an object). If so, you create a Cannon instance using the new keyword, after which the situation in memory is changed again (see FigureactionGoTo:162, 11-11).anotherCannonCannon...Figure 11-11. Final situation in memoryIt’s up to you to decide when you would like to use null and undefined. Not all programmers do this the same way. We suggest that you use undefined to read more..

  • Page - 163

    159 Chapter 12Finishing the Painter GameIn this chapter, you finish the Painter game by adding a few extra features such as motion effects, sounds, and music, and maintaining and displaying a score. Finally, you learn about characters and strings in a bit more detail.Adding Motion EffectsIn order to make the game more visually appealing, you can introduce a nice rotational effect in the movement of the paint cans to simulate the effect of wind and friction on the falling motion. The Painter10 read more..

  • Page - 164

    160CHAPTER 12: Finishing the Painter GameCREATING SPRITESEven if you’re not an artist, it helps to be able to make simple sprites yourself. It enables you to quickly make a prototype of the game—and maybe find out there also is an artist inside you. To create sprites, you first need good tools. Most artists use a painting program like Adobe Photoshop or a vector drawing program like Adobe Illustrator, but others work with such simple tools as Microsoft Paint or the more extensive and free read more..

  • Page - 165

    161CHAPTER 12: Finishing the Painter GameIn addition to the constructor, you add a method called play. In this method, you load the sound, and you set an attribute called autoplay to true. The result of this is that the sound will immediately start playing after it’s loaded. If the sound doesn’t need to loop, you’re done and can return from the method. If you do require the sound to loop, you need to reload and play the sound again after it has finished playing. The Audio type allows you read more..

  • Page - 166

    162CHAPTER 12: Finishing the Painter GameAnd here is how you load the relevant sounds, using the Sound class that you just created: var loadSound = function (sound, looping) { return new Sound("../../assets/Painter/sounds/" + sound, looping);}; sounds.music = loadSound("snd_music");sounds.collect_points = loadSound("snd_collect_points");sounds.shoot_paint = loadSound("snd_shoot_paint"); Now it’s very easy to play sounds during the game. For example, read more..

  • Page - 167

    163CHAPTER 12: Finishing the Painter GameThe player starts with a score of zero. Each time a paint can falls outside the screen, the score is updated. If a can of the correct color falls out of the screen, 10 points are added to the score. If a can isn’t the right color, the player loses a life.The score is a part of what is called the economy of a game. The game’s economy basically describes the different costs and merits in the game and how they interact. When you make your own game, read more..

  • Page - 168

    164CHAPTER 12: Finishing the Painter Gamebe changed outside the class they’re a member of. For example, here is the modified constructor of the Canvas2D_Singleton class that follows this rule: function Canvas2D_Singleton() { this._canvas = null; this._canvasContext = null;} You also add a new method to the class, drawText, which can be used to draw text on the screen at a certain position. The drawText method is very similar to the drawImage method. In both cases, you use the canvas read more..

  • Page - 169

    165CHAPTER 12: Finishing the Painter GameUsing Single and Double QuotesWhen using string values and combining them with other variables, you have to be careful which type of quotes you use (if any). If you forget the quotes, you’re not writing text or characters anymore, but a piece of a JavaScript program! There is a big difference betweenThe string "hello" and the variable name helloThe string '123' and the value 123The string value '+' and the operator +Special read more..

  • Page - 170

    166CHAPTER 12: Finishing the Painter GameAs you can see, you may use single quotes without a backslash in a string delimited by double quotes, and vice versa. The syntax diagram for representing all these symbols is given in FigureactionGoTo:170, 12-2.character‘“\rtbn\digitsymbolFigure 12-2. The syntax diagram for symbolsString OperationsIn the Painter game, you use string values in combination with the drawText method to draw text of a certain color in a desired font somewhere on the read more..

  • Page - 171

    167CHAPTER 12: Finishing the Painter GameIf you want to convert a string value to a numerical value, things get a bit more complicated. This isn’t an easy operation for the interpreter to perform, because not all strings can be converted to a numerical value. For this, JavaScript has a few useful built-in functions. For example, this is how you can transform a string into an integer number: var x = parseInt("10"); If the string passed as a parameter isn’t a whole number, the read more..

  • Page - 172

    168CHAPTER 12: Finishing the Painter GameWHO PLAYS GAMES?You might think that games are primarily played by young males, but that isn’t true at all. A huge percentage of people play games. In 2013 in the United States there were 183 million active gamers, which is more than half the total population (including babies). They play games on many different devices. 36% of the games play games on their smart phone and 25% play games on their wireless device (source: the Entertainment Software read more..

  • Page - 173

    169 Part IIIJewel JamJewel Jam is a puzzle game in which you try to find combinations of jewels (see Figure actionGoTo:173,III-1). Watch out, though: the jewel cart is slowly moving away. Once this cart is off the screen, your time is up! The playing board consists of ten rows and five columns. The jewels on the playing field differ according to three properties: color (red, blue, or yellow), shape (diamond, sphere, or ellipse), and number (one, two, or three jewels).Figure III-1. The Jewel Jam read more..

  • Page - 174

    170The player can shift rows to the left or to the right using the mouse or the touch screen (if the game is played on a phone or a tablet). The goal is to find matching combinations of three adjacent jewels in the middle column. A combination of three jewels is valid if each of the properties is either the same for all objects or different for all objects. For example, a yellow single-diamond object, a blue single-diamond object, and a red single-diamond object form a valid combination, read more..

  • Page - 175

    171 Chapter 13Adapting to Different DevicesThis chapter deals with adapting games to different devices. Until now, you’ve been developing examples that will only work on devices that have a keyboard and a mouse, such as laptop or desktop machines. One of the nice things about JavaScript programs is that they also run on smartphones and tablets, which currently is a booming market. Making your games run on such platforms will result in a lot of extra players for your games. In order to play read more..

  • Page - 176

    172CHAPTER 13: Adapting to Different Devicesto define what elements of a web page should look like. Different HTML pages can then use the same style sheet to ensure a uniform design. This is the style sheet for the example games: html, body { margin: 0;}#gameArea { position: absolute;} #mycanvas { position: absolute; width: 100%; height: 100%;} Discussing what is possible with style sheets in depth isn’t in the scope of this book, but if you want to learn more about that, you read more..

  • Page - 177

    173CHAPTER 13: Adapting to Different DevicesThe native resolution of the Jewel Jam game is big (1440 × 1080), so scaling is definitely necessary if you want the game to run properly on all smartphones and tablets. You also pass along the name of the div element containing the canvas. The reason is that you change the margin of this div so the game is displayed nicely in the middle of the screen, in case the screen ratio differs from the game-size ratio (see Figure actionGoTo:177,13-1).Figure read more..

  • Page - 178

    174CHAPTER 13: Adapting to Different DevicesNow, whenever the window is resized, the resize method is called. Finally, you explicitly call the resize method: this.resize();By calling this method, the right scale is calculated according to the browser window size when the game is started.Resizing the GameThe resize method is called whenever the window is resized. When that happens, you need to calculate two things:The desired scale at which the sprites should be drawnThe margins of the game read more..

  • Page - 179

    175CHAPTER 13: Adapting to Different DevicesThe other case is that the new ratio is smaller, meaning the browser window is too high. In that case, you need to recalculate the height: newHeight = newWidth / widthToHeight; Now that you’ve calculated the correct width and height, you first change gameArea div so it has this height and width. You do that as follows, simply by editing the style of the element: gameArea.style.width = newWidth + 'px';gameArea.style.height = newHeight + 'px'; In read more..

  • Page - 180

    176CHAPTER 13: Adapting to Different DevicesRedesigning Mouse-Input HandlingAfter doing all this, you’ve moved around the div and canvas elements quite a bit. In the Painter game, you assumed that the canvas was always drawn at top left on the screen. Here, this is no longer the case. If you want to detect mouse clicks on the screen, you need to take the position of the canvas on the screen into account when calculating the local position of the mouse on the game screen. Furthermore, because read more..

  • Page - 181

    177CHAPTER 13: Adapting to Different DevicesIn the event-handler functions, you’re changing the values of the member variables. In the handleMouseMove event-handler function, you have to calculate the mouse position. This is also the place where you make sure the mouse position is scaled and moved according to the scale and offset applied to the canvas. Here is the complete handleMouseMove function: function handleMouseMove(evt) { var canvasScale = Canvas2D.scale; var canvasOffset = read more..

  • Page - 182

    178CHAPTER 13: Adapting to Different DevicesFinally, at the end of each game-loop iteration, the Mouse object is reset. The only thing you need to do here is set the pressed variables to false again: Mouse_Singleton.prototype.reset = function () { this._left.pressed = false; this._middle.pressed = false; this._right.pressed = false;}; By setting the pressed variables to false after each game-loop iteration, you make sure a mouse or key press is handled only once.ArraysYou can also read more..

  • Page - 183

    179CHAPTER 13: Adapting to Different DevicesThis walks through all the elements in the array and adds 10 to each. So, after this code is executed, intArray refers to [14, 23, 25, 26, 33, 52, 7].In addition to initializing an array in the way you just saw, there is another way to create an array, as follows: var anotherArray = new Array(3); This example creates an array of size 3, which you can then fill: anotherArray[0] = "hello"; You can even create multidimensional arrays in read more..

  • Page - 184

    180CHAPTER 13: Adapting to Different DevicesHandling Keyboard Input Using ArraysLet’s see how you can use arrays to deal with keypresses more efficiently. Because you now have the ButtonState class, you can use it to handle keyboard input as well and store a ButtonState instance for each key state. So, in the constructor of Keyboard_Singleton, create an array that contains all the possible key states, as follows: this._keyStates = [];for (var i = 0; i < 256; ++i) read more..

  • Page - 185

    181CHAPTER 13: Adapting to Different DevicesBefore you can start writing JavaScript code, you need to take care of a few things in the HTML page. The reason is that tablets and smartphone devices define default touch behavior on web pages, such as the ability to scroll or zoom in a web page. Those interactions would interfere with playing the game, so you want to switch them off. This can be done in the header of the HTML file by adding the following tag to the header: <meta read more..

  • Page - 186

    182CHAPTER 13: Adapting to Different Devicesvariable changedTouches. For each element in that array, you add the touch event data to the _touches array. Because these are new touches, you also add true values to the _touchPresses variable. This is the complete method: function handleTouchStart(evt) { evt.preventDefault(); var touches = evt.changedTouches; for (var i = 0; i < touches.length; i++) { Touch._touches.push(touches[i]); Touch._touchPresses.push(true); }} read more..

  • Page - 187

    183CHAPTER 13: Adapting to Different Devices var id = Touch.getTouchIndexFromId(touches[i].identifier); Touch._touches.splice(id, 1); Touch._touchPresses.splice(id, 1); }} Finally, in handleTouchMove, you have to update the touch information for the touches that have changed. This means you have to replace an element in the array. The splice method accepts a third parameter in which you can indicate a replacement element. Have a look at the code belonging to this read more..

  • Page - 188

    184CHAPTER 13: Adapting to Different DevicesIn the method body is a for loop that checks, for each touch in the array, whether its position falls inside the rectangle. You reuse the getPosition method defined earlier. Depending on the outcome, the method returns either true or false. Also add the following property to Touch: Object.defineProperty(Touch_Singleton.prototype, "isTouchDevice", { get: function () { return ('ontouchstart' in window) || read more..

  • Page - 189

    185CHAPTER 13: Adapting to Different Devices } else if (Touch.touching && !Touch.containsTouch(rect)) { var opposite = Touch.position.y - this.position.y; var adjacent = Touch.position.x - this.position.x; this.rotation = Math.atan2(opposite, adjacent); }}; First you retrieve the rectangle that represents the part of the cannon you can touch to select a different color. You add a simple property for calculating this rectangle. Then you check whether the read more..

  • Page - 190

    187 Chapter 14Game Objects in a StructureIn the previous chapter, you saw how you can use arrays to represent lists of things. For example, you used an array to keep track of the locations where the player is touching the touch screen, or how many keys the player is currently pressing on the keyboard.Arrays can be used in a lot of other situations as well. You can use them to store more complicated objects such as the ball or the paint cans in the Painter game. In general, it’s useful to read more..

  • Page - 191

    188CHAPTER 14: Game Objects in a StructureFirst let’s look at a simplified case where you want to draw a background sprite and, on top of that, a grid of ten rows times five columns, where each location in the grid is filled with a sprite. The program that does this is called JewelJam2, and you can find it in the example code folder belonging to this chapter.Creating a Grid of SpritesThe previous chapter showed how to create arrays. Let’s put this feature to use in the next example to read more..

  • Page - 192

    189CHAPTER 14: Game Objects in a StructureAs you can see, you simply apply the trick explained in the previous chapter. Initially, you fill the grid randomly with one of the three jewel sprites you loaded. You could do this as follows: for (var i = 0; i < this.rows * this.columns; i++) { var randomval = Math.floor(Math.random() * 3) + 1; if (randomval === 1) this.grid[i] = sprites.single_jewel1; else if (randomval === 2) this.grid[i] = sprites.single_jewel2; else read more..

  • Page - 193

    190CHAPTER 14: Game Objects in a StructureDrawing the GridNow that you have a grid of randomly chosen jewel sprites, you’re ready to draw the grid on the screen. The challenge here is that you need to calculate the position at which each jewel should be drawn. This position depends on the row and column index of the jewel you want to draw. So, you use a nested for loop to go through all the rows and columns and then draw the jewel at each row and column index. To retrieve the jewel, you use read more..

  • Page - 194

    191CHAPTER 14: Game Objects in a StructureGrid OperationsBecause you’ve organized part of the game world in a grid, you can now use for loops in a smart way to add behavior to the grid. In this example, you add a feature that moves each row down one row. This means the last row disappears and you need to generate new (random) values for the first row. Let’s add a method called moveRowDown that does this. What does it mean to “move down” a row? Basically, you simply have to copy the read more..

  • Page - 195

    192CHAPTER 14: Game Objects in a StructureThe outer for loop iterates from row 0 until this.rows - 1. This means the last row doesn’t move downward. And this is what you want, because there is no row below the last row! The inner for loop iterates over the columns (from 0 until this.columns) and copies the value at location (x, y) to location (x, y + 1). After this inner for loop has finished, the contents of row y have been copied to row y + 1. However, if you try to run this for loop, read more..

  • Page - 196

    193CHAPTER 14: Game Objects in a Structuredifferent operations on a grid like this. These operations can be useful for many different games. For example, removing a row from a grid is an operation that is used a lot in Tetris games. A game like Bejeweled needs operations that can remove a number of items from a row or a column and fill the grid again. In addition to the operations you can perform on grids, you also have to think about the items the grid contains. In this example, you used a read more..

  • Page - 197

    194CHAPTER 14: Game Objects in a Structureyou have to let go of the basic premise that a game object is a three-colored sprite. But then, what is a game object? In a sense, a game object can be anything you want. So you could define the following class to represent a game object: function GameObject() {} Okay, this may be going a bit too far. For now, let’s assume that any game object has a position and a velocity, but how the game object appears (if it appears) is something you don’t yet read more..

  • Page - 198

    195CHAPTER 14: Game Objects in a StructureLocal vs. Global PositionsAs you know, each game object has a variable containing its position. Until now, each game object was directly positioned in the game world. Although this approach works fine, it may not be the ideal solution. Consider the playing field game object. In order to align the playing field to the background sprite, you want to place it at position (85,150). However, all the child objects (the jewels in the grid) probably also have read more..

  • Page - 199

    196CHAPTER 14: Game Objects in a StructureLayers of Game ObjectsWhen you want to draw a game object, you can use the worldPosition property as a convenient way to find out where to draw the game object on the screen. The only problem is that you don’t have any idea of order in which the game objects in the hierarchy should be drawn. Looking at the Jewel Jam game, you clearly want the background to be drawn before the playing field is drawn; otherwise, the player will only see the read more..

  • Page - 200

    197CHAPTER 14: Game Objects in a Structurethe worldPosition property to calculate the actual position of the sprite on the screen. Here is a simplified version of the SpriteGameObject class: function SpriteGameObject(sprite, layer) { GameObject.call(this, layer); this.sprite = sprite; this.origin = Vector2.zero;} SpriteGameObject.prototype = Object.create(GameObject.prototype); SpriteGameObject.prototype.draw = function () { if (!this.visible) return; read more..

  • Page - 201

    198CHAPTER 14: Game Objects in a StructureSo, GameObjectList itself doesn’t define any behavior; it simply manages the behavior of the game objects it contains. For the update method, you don’t care about the order in which the game objects update themselves. For the draw method, you do care, because you want to draw the game objects with the lowest layer numbers first. The most robust way to do this is to sort the list of game objects at the beginning of each call to the draw method. read more..

  • Page - 202

    199CHAPTER 14: Game Objects in a StructureBecause you ensure that the game objects are added at the right positions, the draw method simply consists of a for loop: GameObjectList.prototype.draw = function () { if (!this.visible) return; for (var i = 0, l = this._gameObjects.length; i < l; ++i) this._gameObjects[i].draw();}; This way, your drawing operation stays very efficient because you don’t sort the list of game objects every time! There is a slight disadvantage to read more..

  • Page - 203

    200CHAPTER 14: Game Objects in a StructureNow take a look at the following code fragment: function JewelJamGameWorld(layer) { GameObjectList.call(this, layer); this.add(new SpriteGameObject(sprites.background, ID.layer_background)); var rows = 10, columns = 5; var grid = new JewelGrid(rows, columns, ID.layer_objects); grid.position = new Vector2(85, 150); grid.cellWidth = 85; grid.cellHeight = 85; this.add(grid); for (var i = 0; i < rows * columns; i++) { read more..

  • Page - 204

    201CHAPTER 14: Game Objects in a StructureBecause you can use a regular array to represent two-dimensional structures, the GameObjectGrid class is a subclass of GameObjectList. You need to do a few additional things to make the GameObjectGrid class behave the way you want it to. First, you need to be able to calculate anchor positions, which means you need to know the size of a single element (cell) in the grid. Therefore, you also add two member variables to store the size of a single cell in read more..

  • Page - 205

    202CHAPTER 14: Game Objects in a StructureAs you can see in this example, you calculate the row and column indices from the target location in the array. Then you push the game object on the array, set its parent, and, using the calculated row and column indices, determine its position. For convenience, add another method that allows you to add a game object at a specific row and column index in the grid: GameObjectGrid.prototype.addAt = function (gameobject, col, row) { read more..

  • Page - 206

    203CHAPTER 14: Game Objects in a StructureIn addition to moving the leftmost element to the rightmost column and shifting all the other elements, you change the position of the object that was changed from being the leftmost object to the rightmost object. You take into account any existing position offset of the first element by storing it in a local variable before you perform the shifting operation and then adding that offset to the new position. The result of this positional change is a read more..

  • Page - 207

    204CHAPTER 14: Game Objects in a StructureThe only other thing you need to change in this game object is the update method, because drawing the sprite is already properly handled in the base class. What needs to be done in the update method? First you need to call the original version of the update method so the position of the object is always updated according to its velocity: SpriteGameObject.prototype.update.call(this, delta); Then you need to find out the anchor position of this game read more..

  • Page - 208

    205CHAPTER 14: Game Objects in a Structureoutside it. In the latter case, you don’t need to do anything. In the former case, you need to store some information related to where the player is dragging. Here is the complete code: if (Mouse.left.down && !this.dragging) { var rect = new Rectangle(this.worldPosition.x, this.worldPosition.y, this.columns * this.cellHeight, this.rows * this.cellWidth); if (Mouse.containsMouseDown(rect)) { this.dragging = true; read more..

  • Page - 209

    206CHAPTER 14: Game Objects in a StructureSimilarly, you check whether the rightmost object has been dragged more than half the cell width to the right. If that is the case, you shift the row to the right: var lastObj = this.at(this.columns - 1, this._dragRow);if (lastObj.position.x > (this.columns - 1) * this.cellWidth + this.cellWidth / 2 && newpos - this._draggingLastX > 0) this.shiftRowRight(this._dragRow); Finally, you update the last dragging position so it contains read more..

  • Page - 210

    207CHAPTER 14: Game Objects in a StructureBecause of the hierarchy of game objects that you created, the game-loop calls are automatically propagated to all the game objects in the hierarchy. Another nice thing you can do because of this hierarchical structure is modify the position of a parent object, after which the child objects are automatically moved accordingly. For example, try to place the grid object at another position: grid.position = new Vector2(300, 100); The result of this change read more..

  • Page - 211

    208CHAPTER 14: Game Objects in a StructureWhat You Have LearnedIn this chapter, you have learned:How to organize game objects in a scene graphHow to create structured collections of game objects, such as grids and listsThe difference between local and global positionsHow to make the scene graph an integral part of the game by using it to draw and update the game objectsHow to define dragging behavior for both mouse and touch input read more..

  • Page - 212

    209 Chapter 15Gameplay ProgrammingThis chapter looks into the gameplay programming of the Jewel Jam game. First it talks about interaction between game objects. Then it introduces a few new game objects that are used in the game. Finally, you tackle the main gameplay element of this game: finding combinations of jewels and handling them properly.Interaction between Game ObjectsThis section looks at how game objects communicate with each other. Before game objects can do that, you first need a read more..

  • Page - 213

    210CHAPTER 15: Gameplay ProgrammingAssigning Identifiers to Game ObjectsWhen you want to find game objects, it’s helpful to assign identifiers to them. Not all objects need identifiers; generally only the ones that interact with other objects do. You use the same kind of identifiers that you used for layers earlier. For example, here you can see a few identifiers that will be useful for the Jewel Jam game: ID.title = 1;ID.help_frame = 2;ID.jewel_cart = 3;ID.grid = 4;ID.game_over = 5;ID.score read more..

  • Page - 214

    211CHAPTER 15: Gameplay ProgrammingFinding Game ObjectsAlthough assigning identifiers to game objects may be a good idea, it’s only useful if you also provide a way to find these game objects. To see how this can be done, let’s add a method find to the GameObjectList class that looks through the list of game objects to see if any of them have the requested identifier. If the game object is found, the method returns a reference to this game object; otherwise, it returns null. The header of read more..

  • Page - 215

    212CHAPTER 15: Gameplay ProgrammingBefore the instanceof keyword, you put the object to be checked; and after the keyword you place the type. If the object is of the given type, then the expression yields true. If not, the result is false. Therefore, you can use it in an if instruction as in the previous example. If you know the object is of type GameObjectList, you can try to find the game object you’re looking for in the game-object list represented by that object. The following code does read more..

  • Page - 216

    213CHAPTER 15: Gameplay Programmingwhich is either null or a game object) are sent back through the return values. Finally, the first caller of the method gets the object (if it was found somewhere in the tree), or null if no object carrying the requested ID was found. This kind of search strategy is also called depth first, because you call the find method on the child object before examining the rest of the objects in the list.When a method calls itself, this is called recursion. Recursion is read more..

  • Page - 217

    214CHAPTER 15: Gameplay ProgrammingTherefore, you can easily retrieve the game world by walking through the list of parents to get to the root. You add a property called root to the GameObject class that does this, and it relies on recursion: Object.defineProperty(GameObject.prototype, "root", { get: function () { if (this.parent === null) return this; else return this.parent.root; } }); The code in the property read more..

  • Page - 218

    215CHAPTER 15: Gameplay ProgrammingThe ordering of the jewels in the image file is important in this case, as you see later. When you create a Jewel instance, you randomly choose which jewel to represent by storing a random number between 0 and 26 (to cover the 27 varieties) in a member variable variation. Therefore, the Jewel constructor becomes function Jewel(layer, id) { SpriteGameObject.call(this, sprites.jewels, layer, id); this.variation = Math.floor(Math.random() * 27);} Because read more..

  • Page - 219

    216CHAPTER 15: Gameplay ProgrammingAs a result, the higher the variation index, the further to the right the rectangle is moved. Finally, a call to the Canvas2D.drawImage method draws the jewel on the screen. Here is the complete draw method: Jewel.prototype.draw = function () { if (!this.visible) return; var imagePart = new Rectangle(this.variation * this.height, 0, this.height, this.height); Canvas2D.drawImage(this.sprite, this.worldPosition, 0, 1, this.origin, read more..

  • Page - 220

    217CHAPTER 15: Gameplay ProgrammingHow do you calculate the size of text? There isn’t really an easy way to do this in HTML. This code uses a simple trick: you dynamically add the text to the HTML page, calculate its size when it’s drawn, and remove it again. Here is the function that does this work for you: function calculateTextSize(fontname, fontsize, text) { var div = document.createElement("div"); div.style.position = "absolute"; div.style.left = -1000; read more..

  • Page - 221

    218CHAPTER 15: Gameplay ProgrammingNow you define a ScoreGameObject class that inherits from the Label class. The score is represented by the text content. The nice thing is that JavaScript will automatically transform an integer number into text when drawing. So, you simply set the text to 0: function ScoreGameObject(fontName, fontSize, layer, id) { Label.call(this, fontName, fontSize, layer, id); this.text = 0; this._align = "right";}ScoreGameObject.prototype = read more..

  • Page - 222

    219CHAPTER 15: Gameplay ProgrammingYou assign the score game object to the layer ID.layer_overlays, so it’s drawn on top of the background and the score frame. You also choose appropriate positions for the frame and the score. Finally, you assign an ID ID.score to the score game object, so that other objects can retrieve it when needed.A Moving Jewel CartTo make the game a bit more exciting, you can add a feeling of pressure for the player. In the Jewel Jam game, this is done by drawing a read more..

  • Page - 223

    220CHAPTER 15: Gameplay ProgrammingDealing With Combinations of JewelsWhenever a player has constructed a valid combination in the middle column by dragging rows, the game checks whether the combination is valid. If so, the game adds points to the score, pushes the jewel cart back, removes the combination of jewels from the grid, and adds new jewels. The JewelGrid class has a handleInput method where the row dragging is handled. In the update method of that class, you need to determine whether read more..

  • Page - 224

    221CHAPTER 15: Gameplay Programminga bit easier, let’s encode each jewel by using three integers from 0 to 2. Let’s say the first integer represents the color (yellow, blue, or red), the second integer the shape (diamond, oval, or round), and the last integer the number of jewels (one, two, or three). Using this encoding scheme, you can, for example, encode the blue oval-shaped single jewel as (1,0,0). The yellow round single jewel is defined as (0,2,0), and the red oval-shaped triple jewel read more..

  • Page - 225

    222CHAPTER 15: Gameplay Programmingfor (var i = 0; i < 3; i += 1) { if ((Math.floor(curra / divider) + Math.floor(currb / divider) + Math.floor(currc / divider)) % 3 !== 0) return false; curra = curra % divider; currb = currb % divider; currc = currc % divider; divider = Math.floor(divider / 3);}return true; First you retrieve the value that represents which jewel you’re dealing with, using the variation member variable of each jewel. Then you define a divider read more..

  • Page - 226

    223CHAPTER 15: Gameplay Programming var jewel = new Jewel(); this.addAt(jewel, x, 0); jewel.position.y = newYPosition;}; In the update method, you call removeJewel three times to remove the three jewels that form a valid combination: this.removeJewel(middleCol, i, -this.cellHeight);this.removeJewel(middleCol, i + 1, -this.cellHeight * 2);this.removeJewel(middleCol, i + 2, -this.cellHeight * 3); As the grid is updated, the position difference between the jewel objects and their target read more..

  • Page - 227

    225 Chapter 16Game StatesIn the previous chapter, you programmed the main gameplay elements of the Jewel Jam game. However, the game as it stands is far from complete. For example, nothing happens when the jewel cart disappears from the screen. Also, when you start the program, the game immediately begins without any warning. What is still needed is a way to incorporate menus and overlays in the game so the player can change settings, get help, or start playing the game. When the player is, for read more..

  • Page - 228

    226CHAPTER 16: Game Statesa few instructions to the handleInput method to distinguish between two states: the state in which you show the title screen and the state in which you’re playing the game: var titleScreen = this.root.find(ID.title);if (titleScreen.visible) { if (Mouse.left.pressed || Touch.isPressing) titleScreen.visible = false; return;}GameObjectList.prototype.handleInput.call(this, delta); Looking at the if instructions, you can see that if the title screen is read more..

  • Page - 229

    227CHAPTER 16: Game StatesAdding a Button to Show a Help FrameThis section explains how to add a button to a game, which you use to display a help frame. To do that, you add another class, Button, to the program. You inherit from the SpriteGameObject class and add some simple behavior that checks whether the player pressed a button. In the Button class, you declare a boolean member variable that indicates whether the button was pressed. Then you override the handleInput method to check whether read more..

  • Page - 230

    228CHAPTER 16: Game StatesIn the Button class, you use these methods to determine whether the button is down and/or pressed. Here is the handleInput method of Button: Button.prototype.handleInput = function (delta) { var boundingBox = this.boundingBox; this.pressed = this.visible && (Touch.containsTouchPress(boundingBox) || Mouse.containsMousePress(boundingBox)); this.down = this.visible && (Touch.containsTouch(boundingBox) || read more..

  • Page - 231

    229CHAPTER 16: Game StatesFinally, you have to make sure the game isn’t updated when the help frame is displayed. You can do that in the update method by updating the game objects only if the help frame isn’t visible: var helpFrame = this.root.find(ID.help_frame);if (!helpFrame.visible) GameObjectList.prototype.update.call(this, delta); One more thing you have to take care of is that by pressing the help button, the player pauses the game. If you keep showing the jewel grid, this read more..

  • Page - 232

    230CHAPTER 16: Game StatesOverlaysA very common way of presenting information to the player is to use overlays. Overlays are basically images that can be displayed on top of the game world to present information or to provide a user interface such as a menu, a mini map, status information, and more. The help frame introduced in the previous section is another example of an overlay.Overlays can present an entirely new game state (such as a “game over” overlay), or they can supplement the read more..

  • Page - 233

    231CHAPTER 16: Game StatesObject.defineProperty(SpriteGameObject.prototype, "screenCenterY", { get: function () { return (Game.size.y - this.height) / 2 + this.origin.y; } }); Now let’s extend JewelJamGameWorld to display the “game over” overlay when needed. First you add a method that checks whether the jewel cart is outside the screen: JewelJamGameWorld.prototype.gameOver = function () { var jewelCart = this.root.find(ID.jewel_cart); return read more..

  • Page - 234

    232CHAPTER 16: Game StatesDESIGNING GAMESAlthough on game-development teams the programmer normally isn’t responsible for the design of the game, it’s still very useful to have a basic understanding of this process. The programmer must turn the game design into code and must be able to advise the designer about what will work and what will be difficult to achieve. For this collaboration to be successful, everyone has to speak the same language.Designing a game primarily consists of defining read more..

  • Page - 235

    233CHAPTER 16: Game StatesLevel design is sometimes done by special level designers, but in smaller teams it’s often the responsibility of the game designer. Careful level design leads to a good learning curve. It keeps the player challenged and motivated, and it should result in pleasant surprises.Many books have been written about game design, and you’re strongly encouraged to read some of them. You can also find lots of information on all aspects of game development on sites read more..

  • Page - 236

    235 Chapter 17Finishing the Jewel Jam GameIn this chapter, you finish the Jewel Jam game. As a first step, you give the player extra points when multiple combinations of three jewels happen. Second, you add a nice visual effect by showing glitters on the jewels in the game. Finally, you add sound and music.Extra Points for Multiple CombinationsYou want to give the player extra points when multiple combinations occur. Whenever the player makes a combination of three jewels, new random jewels are read more..

  • Page - 237

    236CHAPTER 17: Finishing the Jewel Jam GameYou also want to show the player a message that they got extra points in the case of a double or triple combination. To do so, you can show an overlay for a couple of seconds. As a first step, let’s load two overlays for that and add them to the game world in the JewelJamGameWorld class: var doubleOverlay = new SpriteGameObject(sprites.double, ID.layer_overlays);doubleOverlay.position = new Vector2(800, 400);this.add(doubleOverlay);var tripleOverlay read more..

  • Page - 238

    237CHAPTER 17: Finishing the Jewel Jam Gameproblem can be solved by keeping track of whether the game is paused. Basically, you need to maintain a time offset that increases while the game is paused. Many first-person shooters follow this strategy because in those kinds of games, it’s crucial to have a high framerate so the player can interact naturally with the game world. And with first-person shooters, chances are the players are completely involved in the game, and they wouldn’t dream read more..

  • Page - 239

    238CHAPTER 17: Finishing the Jewel Jam GameNow you can use the VisibilityTimer class to control the visibility of the double and triple combination overlays in the Jewel Jam game. When you create overlay objects, you also create VisibilityTimer instances with these overlays as their target: var doubleOverlay = new SpriteGameObject(sprites.double, ID.layer_overlays);doubleOverlay.position = new Vector2(800, 400);var doubleTimer = new VisibilityTimer(doubleOverlay, ID.layer_overlays, read more..

  • Page - 240

    239CHAPTER 17: Finishing the Jewel Jam GameFigure 17-1. The rectangles indicate where you would like to add glitters in the gameThe ConstructorLet’s create a GlitterField class that allows you to add glitters to game objects. This class inherits from the GameObject class, so you can easily attach it to the scene graph. The constructor of the GlitterField class has several parameters. Here is the header and part of the body of the constructor: function GlitterField(density, width, height, read more..

  • Page - 241

    240CHAPTER 17: Finishing the Jewel Jam GameAdding GlittersA glitter field is a rectangle containing multiple glitters, depending on the desired density. Therefore, you need an array to maintain where these glitters should be drawn. This is done in the member variable positions, which is an array that is initialized in the constructor: this.positions = []; You fill this list with a number of randomly generated positions. To randomly generate a position within the field, you can add a method read more..

  • Page - 242

    241CHAPTER 17: Finishing the Jewel Jam GameThe first variable specifies the maximum scale for the glitters (1 is the original size). The second variable, _scaleStep, indicates how fast the scale should increase or decrease.You don’t want to begin increasing each glitter’s scale at the same time—you want the glitters to appear randomly. So, in the update method, you iterate through all the glitter positions and scales in the list and, depending on the value of a random number, start read more..

  • Page - 243

    242CHAPTER 17: Finishing the Jewel Jam GameThen you add a for instruction that traverses all the glitter scales and positions. You still need to calculate the real scale value based on the scale value stored in the array in the update method. If that value is between zero and the maximum scale, you don’t have to do anything (scale is increasing). If the value is between the maximum scale and twice the maximum scale, you need to convert that value into a decreasing scale. This is done using read more..

  • Page - 244

    243CHAPTER 17: Finishing the Jewel Jam GameFinally, you add a GlitterField instance to the playing field, as follows: playingField.add(new GlitterField(2, columns * grid.cellWidth, rows * grid.cellHeight, ID.layer_overlays_1)); Note that you place the glitter field in the overlay layer, so it’s drawn on top of the jewel grid.Let’s also add a few glitters to the jewel cart. This example does that a little differently, to show you the various possibilities for attaching game objects to read more..

  • Page - 245

    244CHAPTER 17: Finishing the Jewel Jam GameAdding Music and Sound EffectsJust like in the Painter game, you want to add music and sound effects to the game to make it more attractive. As you’ve seen, playing music and sounds is very easy in JavaScript. You can use the Sound class that you created earlier for Painter. This is another good example of reusing code: you created the Sound class once, and you’re using it for all the games in this book! Many of the classes designed for Jewel Jam read more..

  • Page - 246

    245CHAPTER 17: Finishing the Jewel Jam GameWhen the game is started, you begin playing the background music as soon as the assets are loaded, as follows: sounds.music.volume = 0.3;sounds.music.play(); And when you get a valid combination of jewels (single, double, or triple), you play different sound effects (see the JewelGrid class): if (nrCombis === 1) { sounds.combi.play();}else if (nrCombis === 2) { score.score += 50; var doubleTimer = this.root.find(ID.double_timer); read more..

  • Page - 247

    246CHAPTER 17: Finishing the Jewel Jam GameLEADERBOARDSWhy do games contain leaderboards and high-score lists? Early games didn’t have them because there was no semi-permanent storage available in the game consoles. So, nothing could be remembered between playing sessions. That was also the reason there was no Save Game option, which in turn had an important effect on game mechanics: a player always had to start again from the beginning, even if they were experienced.Once storage became read more..

  • Page - 248

    247 Part IVPenguin PairsIn this part of the book, you develop the game Penguin Pairs (see Figure actionGoTo:248,IV-1). I introduce a few new techniques for programming games, such as sprite sheets, better game-state management, storing game data between sessions, and more.Figure IV-1. The Penguin Pairs game read more..

  • Page - 249

    248Penguin Pairs is a puzzle game in which the goal is to make pairs of penguins of the same color. The player can move penguins by clicking or tapping them and selecting the direction in which the penguin should move. A penguin moves until it’s stopped by another character in the game (this can be a penguin, a seal, a shark, or an iceberg) or it drops from the playing field, in which case it falls into the water and is eaten by hungry sharks. Throughout the different levels of the game, read more..

  • Page - 250

    249 Chapter 18Sprite SheetsIn this chapter, you start building the first elements of the Penguin Pairs game. This game is quite a bit more complicated than the previous games. You can see this by looking at the number of game assets it uses. Just as you did in the Jewel Jam game, you use images containing several different sprites. This technique is used in many games. In the Jewel Jam game, you used it to store a strip of jewels in a single sprite. However, using strips isn’t always a good read more..

  • Page - 251

    250CHAPTER 18: Sprite SheetsTo get started more easily, you can copy a few classes from the previous game. First you need the GameObject class and the GameObjectList class. You also need the basic classes you wrote for programming games, such as Keyboard, Touch, Mouse, Game, Canvas2D, Vector, and so on. You modify the SpriteGameObject class so it can deal sheets of sprites. Just as in the Jewel Jam game, a class represents the game world; in this case, the class is called PenguinPairsGameWorld. read more..

  • Page - 252

    251CHAPTER 18: Sprite SheetsNote If you download example code or open source code and related assets, you may find naming conventions for files similar to those used in this chapter. These naming conventions may seem arbitrary, but they may be programmatically based. Be sure to analyze any new code for the type of trick used here. Renaming files might seem harmless, but it could break more than you thought.In a SpriteSheet instance, you have to load the image as you did before, and you have to read more..

  • Page - 253

    252CHAPTER 18: Sprite SheetsThe first thing you need to do with the file name is remove the path information from it. In order to do that, you split up the string, using a slash (/) as the delimiter. You then take the final element from the array, which should contain the full file name: var pathSplit = imageName.split('/');var fileName = pathSplit[pathSplit.length - 1]; The next step is removing the file extension. This means you have to call the split method using a period (.) as the read more..

  • Page - 254

    253CHAPTER 18: Sprite SheetsNote You have seen how to analyze string contents by using, among others, the split method. There are many more ways to manipulate string data in JavaScript. For a more complete overview, visit actionURI(http://www.w3schools.com/js/js_strings.asp):www.w3schools.com/js/js_strings.asp, which is an excellent tutorial on JavaScript strings.Managing the Sprite SheetYou have already seen in the Jewel Jam game how to deal with a strip of sprites. You had to change the read more..

  • Page - 255

    254CHAPTER 18: Sprite Sheetsstep, you need to convert this index value to column and row indices in the sheet. You calculate the column index as follows: var columnIndex = sheetIndex % this._sheetColumns; Basically, you can see the sheet index as a value that passes through all the elements in the sheet from left to right, top to bottom. By applying the modulus operator on the sheet index, you “throw away” the rows that come before the row the element is in, which leaves you with the column read more..

  • Page - 256

    255CHAPTER 18: Sprite Sheets set: function (value) { if (value >=0 && value < this.sprite.nrSheetElements) this._sheetIndex = value; } }); Look at the SpriteGameObject.js file in the PenguinPairs1 example to see a few other examples of properties you can add. The final method of SpriteGameObject is draw, which is simple because most of the work has already been done in the SpriteSheet class: SpriteGameObject.prototype.draw = function () { read more..

  • Page - 257

    256CHAPTER 18: Sprite SheetsBecause you handle all the sprite-sheet aspects in the SpriteSheet class, it’s straightforward to draw the penguin exactly in the middle of the screen, as follows: this.penguin.position = this.penguin.screenCenter; This will work for any sprite sheet of any dimension! Try the PenguinPairs1 program, and play around with the code to see how it works.What You Have LearnedIn this chapter, you have learned:How to use the split method to analyze stringsHow to handle read more..

  • Page - 258

    257 Chapter 19Menus and SettingsIn the Jewel Jam game, you saw a few basic examples of adding GUI elements to a game such as a button or a frame. In this chapter, you add a few more GUI elements to the Penguin Pairs game, such as an on/off button and a slider button. You also see how to read and store game settings, such as music volume and whether hints are allowed.Setting Up the MenuWhen thinking about menus, you may think of a pull-down menu (like File or Edit) or buttons at the top of an read more..

  • Page - 259

    258CHAPTER 19: Menus and SettingsAdding an On/off ButtonThe next step is adding an on/off button that shows a hint (or doesn’t) during game play. Later in the chapter, you see how the value of this button is used. Just as you did for the Button class in the Jewel Jam game, you make a special class for on/off buttons, called (not surprisingly) OnOffButton. The class is a subclass of SpriteGameObject, and it expects a sprite strip containing two sprites: one for the off state and one for the on read more..

  • Page - 260

    259CHAPTER 19: Menus and SettingsNote that you only handle input if the button is visible. In the PenguinPairsGameWorld class, you add an OnOffButton instance to the game world, at the desired position: this.onOffButton = new OnOffButton(sprites.button_offon, ID.layer_overlays);this.onOffButton.position = new Vector2(650, 340);this.onOffButton.on = GameSettings.hints;this.add(this.onOffButton); In this example, you’re using a variable GameSettings, in which you store any settings related to read more..

  • Page - 261

    260CHAPTER 19: Menus and SettingsIn the upper part of the fraction, you calculate how far to the right the front sprite has been moved. You calculate this locally to the back position plus the left margin. You then divide this by the total length that the slider can move. This return instruction forms the get part of the value property. For the set part of the property, you need to convert a value between zero and one to the front slider x-position. This amounts to rewriting the previous read more..

  • Page - 262

    261CHAPTER 19: Menus and SettingsThe final step is updating the slider position if the player is currently dragging. The first step is retrieving the position where the player is touching the screen: var touchPos = Touch.getPosition(this.draggingId); Next you calculate what the x-position of the slider should be. Because the touch position is in world coordinates, you subtract the world position of the back sprite from it to get the local position of the slider. You also subtract half the width read more..

  • Page - 263

    262CHAPTER 19: Menus and SettingsFinally, in the update method of the PenguinPairsGameWorld class, you retrieve the current value of the slider and use it to update the volume of the background music: sounds.music.volume = this.musicSlider.value;Note Most games contain some menu screens. With these screens, the player can set options, choose levels, watch achievements, and pause the game. Creating all these additional screens can be a lot of work that doesn’t contribute to the actual game read more..

  • Page - 264

    263CHAPTER 19: Menus and SettingsIn the options menu, you make sure the value of this variable is always the same as the state of the Hints button. This is done in the update method of PenguinPairsGameWorld, and you use the on property that you added to the button: GameSettings.hints = this.onOffButton.on; This completes the options menu. FigureactionGoTo:264, 19-2 shows what it looks like.Figure 19-2. A screenshot of the PenguinPairs2 exampleWhat You Have LearnedIn this chapter, you have read more..

  • Page - 265

    265 Chapter 20Game State ManagementNormally, you don’t immediately start playing when a game application starts. For example, in the Jewel Jam game, you see a title screen before playing. More complicated games have menus for options, menus for selecting different levels, screens to display the high score after finishing a level, a menu to select different characters and attributes, and so on. In Jewel Jam, adding a title screen wasn’t that difficult, because the title screen itself had very read more..

  • Page - 266

    266CHAPTER 20: Game State ManagementIn the examples you’ve seen until now, there was always some kind of game world class; it was called PainterGameWorld, JewelJamGameWorld, or PenguinPairsGameWorld, depending on the game you were building. Looking at it from the view of game states, each of these worlds represents a single (playing) game state. You need to define such a class for each different state. The nice thing is that you already have a lot of code in place that helps you do this. The read more..

  • Page - 267

    267CHAPTER 20: Game State ManagementAs you can see when you look at the last instruction in the method, you return the index of the game state in the array. You do this because later it will provide you with a simple way to find the game state you added. You store this index as an identifier value in the ID variable. For example, adding a title menu state and storing its ID after you add it can be done in a single line of code, as follows: ID.game_state_title = GameStateManager.add(new read more..

  • Page - 268

    268CHAPTER 20: Game State ManagementAdding States and Switching Between ThemNow that you have your game-state manager, you can start adding different states to it. A very basic game state is the title menu state. In the PenguinPairs3 example, you added a class TitleMenuState to the application that represents this state. Because this state contains a couple of different game objects, you let it inherit from the GameObjectList class. In the constructor of this class, you add the game objects read more..

  • Page - 269

    269CHAPTER 20: Game State ManagementThe help and option menu states are set up in a fashion similar to TitleMenuState. In the class constructor, you add your game objects to the game world, and you override the handleInput method to switch between states. For example, both the help and option menu states contain a Back button that returns you to the title screen: if (this.backButton.pressed) GameStateManager.switchTo(ID.game_state_title); Have a look at the HelpState and OptionsMenuState read more..

  • Page - 270

    270CHAPTER 20: Game State ManagementFinally, you add a text label drawn on the belly of the penguin, so the player can see which level each button refers to: var textLabel = new Label("Arial", "20px", ID.layer_overlays_1);textLabel.text = levelIndex + 1;textLabel.position = new Vector2(this._levelSolved.width - textLabel.width, this._levelSolved.height - textLabel.height + 50).divideBy(2);textLabel.color = Color.black;this.add(textLabel); In the handleInput method, you read more..

  • Page - 271

    271CHAPTER 20: Game State Managementbelonging to the first button that was pressed. If the player didn’t press any button, the method returns -1. Here is the complete method: LevelMenuState.prototype.getSelectedLevel = function () { for (var i = 0, j = this.levelButtons.length; i < j; i += 1) { if (this.levelButtons[i].pressed) return this.levelButtons[i].levelIndex; } return -1;}; You can then use this method in the handleInput method: read more..

  • Page - 272

    272CHAPTER 20: Game State ManagementDealing with ErrorsBefore you finish this chapter, let’s talk a little more about dealing with errors in JavaScript. Particularly when games get more complex, you need to think about what happens when an error occurs. To give a concrete example, in the get method of the GameStateManager class, you return a game state only if the identifier passed as a parameter falls in the range of the elements in the array: GameStateManager_Singleton.prototype.get = read more..

  • Page - 273

    273CHAPTER 20: Game State ManagementYou do this because otherwise, the user of the game-state manager could accidentally access the array outside its range. However, the way you do it here probably isn’t the most robust approach. For one thing, when the index is too large or too small, you return null. This means the code using this method needs to be aware that the method might return null. As a result, that same code has to check this in an if instruction, to make sure you aren’t trying read more..

  • Page - 274

    274CHAPTER 20: Game State ManagementThis code handles a variety of cases before actually accessing the array. If id is out of range or isn’t an integer number (in other words, the floor function of the number doesn’t return the number itself), the method stops execution and throws an exception (which in this case is a string value). To do something with the error, you can call the get function in a try-catch block: try { var myGameState = GameStateManager.get(someId); // do something read more..

  • Page - 275

    275CHAPTER 20: Game State ManagementIn this example, the finally part saves you from copying code. Regardless of whether there was an error while communicating with the server, you need to close the connection when you’re done.To conclude, Figure actionGoTo:275,20-2 shows a syntax diagram for the expressions related to exceptions. Try to think of other examples in the games you’ve seen until now where exceptions could be read more..

  • Page - 276

    277 Chapter 21Storing and Recalling Game DataMany games consist of different levels. Especially in casual games such as puzzles and maze games, a game may have several hundreds of levels. Until now, your games have relied on randomness to keep the gameplay interesting. Although randomness is a powerful tool to achieve replayability, in a lot of cases game designers want more control over how a game progresses. This control is generally achieved by designing levels. Each level is its own game read more..

  • Page - 277

    278CHAPTER 21: Storing and Recalling Game DataThis variable describes a Tic Tac Toe game status for two players. The first player has won two games, and the second player only one. The current state of the game is stored in an array of strings. Finally, the player who places the x marks has their turn. By editing this variable, you can very easily change the score or the current state of the game. You could even decide to make the board bigger, by adding columns and rows to the currentStatus read more..

  • Page - 278

    279CHAPTER 21: Storing and Recalling Game DataIn this level definition, a number of different blocks are defined. An iceberg (wall) tile is defined by the # sign, a penguin by an r character, a background tile by a . character, and an empty tile by a space character. Now you can write a method that uses this information to create the tiles and store them somewhere (probably in a GameObjectGrid instance). This means you need different types of tiles: a normal tile on which a penguin can stand, a read more..

  • Page - 279

    280CHAPTER 21: Storing and Recalling Game DataThe number of pairs to be madeThe location and direction of the hint arrowSo, you can define a complete level in a variable as follows: var myLevel = { locked : true, solved : false, hint : "Don't let the penguins fall in the water!", nrPairs : 1, hint_arrow_x : 3, hint_arrow_y : 1, hint_arrow_direction : 2, tiles : read more..

  • Page - 280

    281CHAPTER 21: Storing and Recalling Game Data nrPairs : 1, hint_arrow_x : 4, hint_arrow_y : 3, hint_arrow_direction : 3, tiles : ["#########", "#.......#", "#...r...#", "#.......#", "#.......#", "#.......#", read more..

  • Page - 281

    282CHAPTER 21: Storing and Recalling Game DataThe IGameLoopObject interface forms the basis of all objects that have game-loop methods. You can change the existing classes in the example to follow this approach. For example, the GameObject class now also inherits from IGameLoopObject: function GameObject(layer, id) { IGameLoopObject.call(this); // initialize the game object...}GameObject.prototype = Object.create(IGameLoopObject.prototype); Have a look at the classes in the PenguinPairs4 read more..

  • Page - 282

    283CHAPTER 21: Storing and Recalling Game DataCreating the Level InstancesIn the Level constructor, you have to create the different game objects belonging to that level. As a first step, you retrieve the level data and store it in a variable called levelData: function Level(levelIndex) { GameObjectList.call(this); var levelData = window.LEVELS[levelIndex]; this.levelIndex = levelIndex; // to do: fill this level with game objects according to the level data} You also need to keep read more..

  • Page - 283

    284CHAPTER 21: Storing and Recalling Game DataYou first create a GameObjectGrid instance and set the width and height of a cell in that grid to a given size. Then you start reading the characters containing the tile information.Now, depending on the character you get from the expression levelData.tiles[row][col], you need to create different kinds of game objects and add them to the grid. You could use an if instruction for that: if (levelData.tiles[row][col] === '.') // create an empty read more..

  • Page - 284

    285CHAPTER 21: Storing and Recalling Game DataThe switch instruction has a few handy properties that make it very useful for handling different alternatives. Have a look at the following code example: if (x === 1) one();else if (x === 2) { two(); alsoTwo();} else if (x === 3 || x === 4) threeOrFour();else more(); You can rewrite this with a switch instruction as follows: switch(x) { case 1: one(); break; case 2: two(); alsoTwo(); break; read more..

  • Page - 285

    286CHAPTER 21: Storing and Recalling Game Dataof instructions, as you did in the example with cases 3 and 4. The syntax of the switch instruction is part of the instruction syntax diagram. FigureactionGoTo:285, 21-1 shows the part of that diagram belonging to the switch instruction.Loading Different Kinds of TilesYou can use the switch instruction to load all the different tiles and game objects. For each character in the levelData.tiles variable, you need to perform a different task. For read more..

  • Page - 286

    287CHAPTER 21: Storing and Recalling Game DataBecause penguins need to move around on the playing board and you need to interact with them, you create a class Animal to represent an animal such as a penguin or a seal. Later in this section, you see what this class looks like. To keep track of which animals are in the game, you maintain an array as a member variable of the Level class, as you’ve seen before: this.animals = []; In the switch instruction, you then create a normal tile and a read more..

  • Page - 287

    288CHAPTER 21: Storing and Recalling Game DataYou convert the character to lowercase so the instruction works for both normal and boxed penguins. To complete the Animal class, you add a few convenient methods to check whether you’re dealing with a special case such as a multicolored penguin, an empty box, or a seal. For the complete Animal class, see the example program PenguinPairs4 belonging to this chapter.Finally, you also have sharks in the Penguin Pairs game. Sharks are relatively read more..

  • Page - 288

    289CHAPTER 21: Storing and Recalling Game DataMaintaining the Player’s ProgressTo complete this chapter, this section shows you a nice way to keep track of the player’s progress over different sessions. You want the game to remember where the player was when they last played the game. There are several ways to do this. One way would be to let the player do this job and simply open all the levels to the player by default. This is a solution, but it doesn’t really motivate the player to read more..

  • Page - 289

    290CHAPTER 21: Storing and Recalling Game Datawindow.localStorage, the value is retained over different sessions. The latter is a very useful option. For example, you can do the following: window.localStorage.playerName = "Bridget"; The next time you start the game, you can read the value of the variable and surprise (or freak out) the player by remembering her name. However, there are some strings attached to using local storage. First, it’s very easy to accidentally clear the read more..

  • Page - 290

    291CHAPTER 21: Storing and Recalling Game DataYou call the loadLevelsStatus method in the constructor of PlayingState so the updated level information is used from local storage when the game starts. Whenever the player finishes a level, you call the writeLevelsStatus method. That way, the next time the player starts the game, the game will remember which levels the player has already completed.An an exercise, try to extend the PenguinPairs4 example by storing more information. For example, read more..

  • Page - 291

    293 Chapter 22Pairing the PenguinsIn this chapter, you program the main gameplay for the Penguin Pairs game. You learn how to move penguins around on the board and what to do when a penguin collides with another game object such as a shark or another penguin.Selecting PenguinsBefore you can move penguins around, you need to be able to select a penguin. When you click an animal such as a penguin or a seal, four arrows should appear that allow you to control the direction in which the animal read more..

  • Page - 292

    294CHAPTER 22: Pairing the PenguinsNote There is no particular reason I chose to use two sprites to implement the hover status. You could also place the eight arrow images on a single sprite sheet and use that instead of the two sprite sheets used here.Because an Arrow instance more or less reacts like a button, it inherits from the Button class. In the constructor, you first create the superclass part of the instance by calling the constructor of the superclass. This loads the first arrow read more..

  • Page - 293

    295CHAPTER 22: Pairing the PenguinsThe Animal SelectorThe animal selector uses the Arrow class to display four arrows when the player clicks an animal (see Figure actionGoTo:293,22-2). These four arrows are stored as member variables in the AnimalSelector class. Because the selector controls a particular animal, you also have to keep track of which one it controls. Therefore, you also add a member variable selectedAnimal, which contains a reference to the target animal. In the constructor read more..

  • Page - 294

    296CHAPTER 22: Pairing the PenguinsIn the handleInput method, you first check whether the selector is visible. If not, it doesn’t need to handle input: if (!this.visible) return; You then check whether one of the arrows was pressed. If so, you calculate the desired animal velocity: var animalVelocity = Vector2.zero;if (this._arrowdown.pressed) animalVelocity.y = 1;else if (this._arrowup.pressed) animalVelocity.y = -1;else if (this._arrowleft.pressed) animalVelocity.x = -1;else if read more..

  • Page - 295

    297CHAPTER 22: Pairing the PenguinsThe final case you need to cover is if the player touched or clicked the animal but the animal selector was already visible. In that case, you don’t have to do anything, and you can return from the method: var animalSelector = this.root.find(ID.animalSelector);if (animalSelector.visible) return; Now that you’ve handled all the cases, you can make the selector visible, set its position, and assign the animal as the selector’s target animal. These are read more..

  • Page - 296

    298CHAPTER 22: Pairing the PenguinsThe outcome of this question depends on the order in which input is handled for each game object. If the penguin handles the input before the penguin selector, then the penguin selector will move to the other penguin. If the selector’s handleInput method is called first, then the selected penguin will move to the left. Generally, when you develop programs, you want to be in control of the program’s behavior. This means you have to choose in which order you read more..

  • Page - 297

    299CHAPTER 22: Pairing the PenguinsUpdating AnimalsInteraction between animals and other game objects is done in the update method of the Animal class. The main reason for doing this in the Animal class is that then each animal handles its own interaction. If you add multiple animals to the game (as you’re doing here), you don’t have to change anything in the code that handles the interaction. As a first step, you don’t have to update the animal if it isn’t visible or if its velocity is read more..

  • Page - 298

    300CHAPTER 22: Pairing the PenguinsThe next step is finding out what kind of tile the animal is moving into. To do that, you have to add a few methods to the tile field. To do this properly, you add a class called TileField that inherits from GameObjectGrid, and you add a few methods to that class. One method checks whether given x and y indices are outside of the tile field. This method is called isOutsideField, and it’s straightforward: TileField.prototype.isOutsideField = function (pos) { read more..

  • Page - 299

    301CHAPTER 22: Pairing the Penguinsto move in either the x or y direction and not diagonally, you end up with a vector (1, 0) in the first example and (0, -1) in the second example. So you set the position of the animal to the position of the tile it just moved out of, as follows: var tileField = this.root.find(ID.tiles);this.velocity.normalize();var currBlock = this.currentBlock;this.position = new Vector2(Math.floor(currBlock.x - this.velocity.x) * tileField.cellWidth, read more..

  • Page - 300

    302CHAPTER 22: Pairing the PenguinsFirst you check whether there is a shark at the tile the animal is moving into. To do that, you retrieve the level and use the findSharkAtPosition method from the Level class to find out whether there is a shark: var s = this.root.findSharkAtPosition(target);if (s !== null && s.visible) { // handle the shark interaction} The findSharkAtPosition method is straightforward; have a look at the method in the example code belonging to this chapter. If a read more..

  • Page - 301

    303CHAPTER 22: Pairing the PenguinsYou also have to display an extra pair at top left on the screen, but you deal with that in the next section. Finally, in all other cases, the penguin stops moving: else this.stopMoving();Maintaining the Number of PairsIn order to maintain the number of pairs and draw it nicely on the screen, you add another class called PairList to the game. The PairList class inherits from the SpriteGameObject class. It consists of a frame, on top of which is drawn a read more..

  • Page - 302

    304CHAPTER 22: Pairing the PenguinsYou also add a method addPair to the class, which finds the first occurrence of the value 7 in the array and replaces it with the index that was passed along as a parameter: PairList.prototype.addPair = function (index) { var i = 0; while (i < this._pairs.length && this._pairs[i] !== 7) i++; if (i < this._pairs.length) this._pairs[i] = index;}; This example uses a while instruction to increment the i variable until you find read more..

  • Page - 303

    305CHAPTER 22: Pairing the PenguinsAnd in the Animal class, you add a pair to the list if an animal encounters another penguin of the same color or one of the two animals is a multicolored penguin: else if (a.sheetIndex === this.sheetIndex || this.isMulticolor() || a.isMulticolor()) { a.visible = false; this.visible = false; this.root.find(ID.pairList).addPair(this.sheetIndex);} For the complete example, see the PenguinPairs5 program belonging to this chapter. In the next chapter, read more..

  • Page - 304

    307 Chapter 23Finishing the Penguin Pairs GameIn this chapter, you finalize the Penguin Pairs game. The first step is to reorganize your code a bit so parts of it can be used more easily by other programs. Then you finish the game by extending the user interface and adding sound effects.Separating Code into Different ModulesEspecially when developing more complex applications, it makes sense to group related classes together. For example, if you’re developing a complex game, there will be read more..

  • Page - 305

    308CHAPTER 23: Finishing the Penguin Pairs GameVariables as NamespacesNamespaces are commonly used in programming languages to provide some structure for where classes belong. Many programming languages have namespace support baked in the language specification. JavaScript isn’t one of those languages, but it’s very easy to use the existing functionality in the language to set up something similar.You’ve seen in the example code that variables are groups of objects. These objects can be read more..

  • Page - 306

    309CHAPTER 23: Finishing the Penguin Pairs GameThe design pattern for putting classes in namespaces uses a JavaScript mechanism that lets you define and call a function at the same time. Perhaps you recall using this before, when defining the function to request the next game-loop iteration: var requestAnimationFrame = (function () { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || read more..

  • Page - 307

    310CHAPTER 23: Finishing the Penguin Pairs Gameis filled with all the classes that are supposed to be in the powerupjs namespace. You can make this even nicer by using smart JavaScript syntax. Consider the following class definition: var powerupjs = (function (powerupjs) { function Vector2(x, y) { this.x = typeof x !== 'undefined' ? x : 0; this.y = typeof y !== 'undefined' ? y : 0; } // etc. powerupjs.Vector2 = Vector2; return powerupjs; })(powerupjs || {}); Here read more..

  • Page - 308

    311CHAPTER 23: Finishing the Penguin Pairs GameThis example shows the definition of the GameStateManager class, which is a singleton. The fact that this is a singleton can be seen by the fact that you assign an instance of the class to powerupjs.GameStateManager instead of the class definition itself. What is really nice is that the class definition is now encapsulated by the namespace—it’s no longer possible to access GameStateManager_Singleton in other JavaScript files, thus ensuring read more..

  • Page - 309

    312CHAPTER 23: Finishing the Penguin Pairs GameFinishing the User InterfaceIn this section, you finish the user interface. First you see how to add a hint mechanism to the game. Then you see how to reset and move on to the next level. You complete the game by adding sound effects.Showing HintsNow that you’ve reorganized your code, there are a couple more features to add to the Penguin Pairs game. As a first step, you want to be able to show a hint when the user clicks a button. The hint read more..

  • Page - 310

    313CHAPTER 23: Finishing the Penguin Pairs GameIn order to temporarily display the arrow, you reuse the VisibilityTimer class from the Jewel Jam game. You create an instance of this class and add it to the game world as well: this.hintVisible = new VisibilityTimer(hint);playingField.add(this.hintVisible); You also add a button that the player can click to display the hint on the screen: this.hintButton = new powerupjs.Button(sprites.button_hint, ID.layer_overlays);this.hintButton.position = new read more..

  • Page - 311

    314CHAPTER 23: Finishing the Penguin Pairs GameThanks to the proper implementation of the reset method everywhere throughout the game object classes, resetting a level to its initial state is now really easy. You have to call the reset method on all the game objects, and then you deal with resetting things in the Level class itself. The only thing you need to do there is set the firstMoveMade variable to false so the player can view a hint again: Level.prototype.reset = function () { read more..

  • Page - 312

    315CHAPTER 23: Finishing the Penguin Pairs GameYou want to display the overlay on top of the playing state, but you don’t want the playing state to be able to process input anymore (otherwise the player could still move penguins around). Therefore, you only call the update and draw methods, and not the handleInput method, on the playingState object.In the handleInput method of LevelFinishedState, you check whether the player has pressed the mouse button or tapped the screen. If so, you set read more..

  • Page - 313

    316CHAPTER 23: Finishing the Penguin Pairs GameHow does the nextLevel method work? It has to deal with two possibilities. The first possibility is that the player finished the last level. In that case, you go back to the level menu state. In all other cases, you increment the current level index, and you unlock the next level for the player. Finally, because you changed the level status, you write it to the local storage so that the next time the player starts the game, the game remembers which read more..

  • Page - 314

    317CHAPTER 23: Finishing the Penguin Pairs GameTutorials work best when they naturally integrate into the game story. For example, the game character might start running around in their safe home town, learning the basic movement controls. Next the character practices fighting together with a few friends. And after, that the player goes into the woods to try to shoot some birds with a bow. This will provide all the practice needed for the fights later in the game.You should make sure your read more..

  • Page - 315

    318CHAPTER 23: Finishing the Penguin Pairs GameAt some point, designing the game became a separate job. Game mechanics were tuned to the interests of user groups and were more and more based on principles from psychology and educational sciences. This required separate expertise. Stories assumed a crucial role, leading to the inclusion of writers. And the teams were extended to include producers, sound engineers, composers, and many other types of people. Today, teams for top games can consist read more..

  • Page - 316

    319 Part VTick TickThe previous chapters have shown you how to build several different types of games. In this part, you build a platform game with animated characters, physics, and different levels. The name of the game is Tick Tick (see FigureactionGoTo:316, V-1), and the story revolves around a slightly stressed-out bomb that will explode within 30 seconds. This means each level in the game should be finished within 30 seconds. A level is finished if the player collects all the refreshing read more..

  • Page - 317

    320This platform game includes a number of basic elements that are found in many other games as well:It should be possible to play different levels.These levels should be loaded from a separate file so they can be changed without having to know how the game code works.The game should support animated characters for both the player and the enemies.The player should control the actions of a player character that can run or jump.There should be some basic physics in the game to manage read more..

  • Page - 318

    321 Chapter 24The Main Game StructureIn this chapter, you lay out the framework for the Tick Tick game. Because of all the work you’ve done for the previous games, you can rely on a lot of preexisting classes. In fact, you build the game on the classes you grouped in the powerupjs namespace/library in the previous chapter. This means you already have a basic design for handling game states and settings, a hierarchy of game objects, and more. You extend the powerupjs library later by adding read more..

  • Page - 319

    322CHAPTER 24: The Main Game StructureThe PlayingState class maintains the current level and deals with loading and saving level status (solved/locked), just as in the Penguin Pairs game. The playing state creates Level objects, each of which contains a tile-based game world, again very similar to the way Penguin Pairs is structured.The Structure of a LevelLet’s first look at what kind of things can be in a level in Tick Tick. First, there is a background image. For now, you display a simple read more..

  • Page - 320

    323CHAPTER 24: The Main Game StructureNext to the actual tiles, you also store a hint together with the level definition. Here you can see the instruction that stores the first level in the LEVELS global variable: window.LEVELS.push({ hint : "Pick up all the water drops and reach the exit in time.", locked : false, solved : false, tiles : ["....................", ".................X..", read more..

  • Page - 321

    324CHAPTER 24: The Main Game StructureWater DropsThe goal of each level is to collect all the water drops. Each water drop is represented by an instance of the WaterDrop class. This class is a SpriteGameObject subclass, but you want to add a little behavior to it: the water drop should bounce up and down. You can do this in the update method. First you compute a bounce offset that you can add to the current position of the water drop. This bounce offset is stored in the member variable _bounce, read more..

  • Page - 322

    325CHAPTER 24: The Main Game StructureThe += operator adds the bounce value to the y-position (see Chapter 10 for more about these types of operators). However, simply adding the bounce value to the y-position isn’t correct, because this is a bounce offset—in other words, an offset with regard to the original y-position. To get the original y-position, you subtract the bounce offset from the y-position in the first instruction of the update method: this.position.y -= this._bounce; This read more..

  • Page - 323

    326CHAPTER 24: The Main Game StructureThe Level ClassThis section shows how the Level class is designed in Tick Tick. It’s done in a way very similar to Penguin Pairs. In the constructor of the Level class, you do a couple of things:Create the background sprite game object.Add a Quit button.Create the tile-based game world from the level data.The first two are straightforward. Have a look at the Level class in the example code to see how they work. Creating the tile-based game world read more..

  • Page - 324

    327CHAPTER 24: The Main Game StructureFigure 24-2. The game world belonging to the first level of Tick TickThis particular example creates a WaterDrop instance and positions it in the center of the tile. You place each water drop 10 pixels higher than the center so it doesn’t bounce over the tile below it. Look at the Level class to see how to create the various tiles and objects in each level. Figure actionGoTo:324,24-2actionGoTo:324, shows a screenshot of the objects in the first level read more..

  • Page - 325

    329 Chapter 25AnimationIn this chapter, you see how to add animations to your game. In the games you’ve developed until now, game objects could move around on the screen, but adding something like a running character to a game is slightly more challenging. In this chapter, you write a program that contains a character walking from left to the right on the screen. The character is controlled by the player pressing the left and right arrow keys. You don’t add touch-interface control in this read more..

  • Page - 326

    330CHAPTER 25: AnimationIn a similar fashion, you can draw a walking or running character. In addition to moving the sprite, you draw a slightly different sprite every time. By drawing a sequence of sprites, each of which represents part of a walking motion, you can create the illusion that a character is walking on the screen. An example of such a sequence of sprites is given in Figure actionGoTo:326,25-1.Figure 25-1. A sequence of images representing a walking motionANIMATIONS IN GAMESThere read more..

  • Page - 327

    331CHAPTER 25: Animationthe animation to get a continuous walking motion. Not all animations should be looped, though. For example, a dying animation shouldn’t be looped (that would be very cruel to the character). Here is the complete constructor of the Animation class: function Animation(sprite, looping, frameTime) { this.sprite = sprite; this.frameTime = typeof frameTime !== 'undefined' ? frameTime : 0.1; this.looping = looping;}An Animated Game ObjectThe Animation class read more..

  • Page - 328

    332CHAPTER 25: AnimationAs mentioned, the AnimatedGameObject class is a subclass of SpriteGameObject. That means when this object is drawn on the screen, it tries to draw the sprite sheet that the member variable sprite points to. However, note that you pass null as a parameter when you call the base constructor in the AnimatedGameObject constructor: function AnimatedGameObject(layer, id) { powerupjs.SpriteGameObject.call(this, null, layer, id); ...} You need to assign the sprite read more..

  • Page - 329

    333CHAPTER 25: AnimationNow you can calculate the index of the frame that should be shown. For this, you use a while instruction: while (this._time > this._current.frameTime) { this._time -= this._current.frameTime; this._sheetIndex++; if (this._sheetIndex >=this.sprite.nrSheetElements) if (this._current.looping) this._sheetIndex = 0; else this._sheetIndex = this.sprite.nrSheetElements - 1;} What happens here? The while instruction continues as read more..

  • Page - 330

    334CHAPTER 25: AnimationBecause the idle animation only contains a single sheet element, you don’t need to specify the frame time. For the running animation, you specify that each frame should be shown for five hundredths of a second. When the application starts, the character’s idle animation should play: this.playAnimation("idle"); You also change the player’s origin. If you want to draw animated characters moving on a floor, it’s useful to use a point on the bottom of the read more..

  • Page - 331

    335CHAPTER 25: AnimationNext you have to translate and rotate the canvas context while taking the sprite’s mirrored state into account. That isn’t covered in detail here, but you can have a look at the Canvas2D class to see how it’s done. To conclude the input handling, you set the mirror status according to the velocity if the player is moving: if (this.velocity.x != 0) this.mirror = this.velocity.x < 0; In the update method, you select which animation to play based on the read more..

  • Page - 332

    336CHAPTER 25: AnimationOne way around this behavior of being able to walk off the edge of the screen is to implement wrapping: if the character walks off the right side of the screen, it reappears on the left, and vice versa. You can implement wrapping quite easily by adding an if instruction to the code that checks the current position of the character and, depending on that position, chooses to move the character to the other end of the screen. Can you change the example yourself to add read more..

  • Page - 333

    337 Chapter 26Game PhysicsIn the previous chapter, you saw how to create an animated character. You also saw how you can load levels and level status from the local storage and how to build a tile-based game world. One of the most important aspects is still missing: defining how the character interacts with the game world. You can make a character move from left to right, but if you simply place the character in the level, it can only walk on the bottom of the screen. This isn’t enough. You read more..

  • Page - 334

    338CHAPTER 26: Game Physicsof the valid indices in the grid. For example, it would be fine to ask for the tile type of the tile at position (-2,500). By using an if instruction in this method, you check whether the x index is out of range. If so, you return a normal (wall) tile type: if (x < 0 || x >= this.columns) return TileType.normal; If the y index is out of range, you return a background tile type so the character can jump through the top of the screen or fall down a hole: if read more..

  • Page - 335

    339CHAPTER 26: Game PhysicsNote that you use the width and height of the tiles and multiply them by the x and y indices of the spot where the character should be located. The cell width is multiplied by x + 0.5 so the character is placed in the middle of the tile position, and the cell height is multiplied by y + 1 to place the character on the bottom of the tile. You can then create the Player object and add it to the game world: this.add(new Player(startPosition, ID.layer_objects, read more..

  • Page - 336

    340CHAPTER 26: Game Physicstiles (which are the only tiles that the character can stand on). Let’s assume for now that your yet-to-be-written collision-detection algorithm will take care of this and keep track of whether the character is on the ground by using a member variable: this.onTheGround = true; Sometimes it’s necessary to sketch out a class in English (as opposed to JavaScript) before it’s written to allow you to write other parts of a game. This is also true in the case of read more..

  • Page - 337

    341CHAPTER 26: Game PhysicsThis is a very nice example of how you can automatically adapt the interface of your game to different devices. The buttons are added only when a touch display is available. Another option would be to use built-in sensors in the device, such as an accelerometer. Doodle Jump is a good example of a game that uses such sensors to control the character.… And FallingThe only place where you’re currently changing the y-velocity is in the handleInput method, when the read more..

  • Page - 338

    342CHAPTER 26: Game Physicsrepresenting game objects with basic shapes such as circles, and you check whether they collide with each other by verifying that the distance between the centers is smaller than the sum of the radii of the circles.So this is a first, simple example of doing collision checking in games. Of course, this isn’t a very precise way of checking collisions. The ball may be approximated by the shape of a circle, but the paint can doesn’t look like a circle at all. As a read more..

  • Page - 339

    343CHAPTER 26: Game PhysicsThe first case is the simplest one. The only thing you need to do is check whether the distance between the two centers is smaller than the sum of the radii. You’ve already seen an example of how to do that.For the case where a circle intersects a rectangle, you can use the following approach:1. Locate the point on the rectangle that lies closest to the circle’s center.2. Calculate the distance between this point and the center of the circle.3. If this distance is read more..

  • Page - 340

    344CHAPTER 26: Game PhysicsLet’s say you want to know whether rectangle A collides with rectangle B. In that case, you have to check for the following conditions:A.left (A’s smallest x-value) <= B.right (B’s greatest x-value)A.right (A’s greatest x-value) >= B.left (B’s smallest x-value)A.top (A’s smallest y-value) <= B.bottom (B’s greatest y-value)A.bottom (A’s greatest y-value) >= B.top (B’s smallest y-value)If all these conditions are met, then read more..

  • Page - 341

    345CHAPTER 26: Game Physicsbut the images aren’t actually colliding. This can happen because parts of the sprites that you draw can be transparent. As a result, if you want to do precise collision detection, you need to look at the pixel level if there is a collision. A collision at the pixel level happens only if at a given position in the rectangle where sprites overlap, both sprites have a non-transparent pixel. Figure 26-2. Example of two sprites that don’t collide but whose bounding read more..

  • Page - 342

    346CHAPTER 26: Game PhysicsThen you use the canvas context to draw the sprite: var ctx = powerupjs.Canvas2D._pixeldrawingCanvas.getContext('2d');ctx.clearRect(0, 0, w, h);ctx.save();ctx.drawImage(this._image, 0, 0, w, h, 0, 0, w, h);ctx.restore(); The canvas context has a method getImageData that retrieves the color data for each pixel and stores it in an array. So, let’s retrieve all the pixels currently displayed on the canvas: var imageData = ctx.getImageData(0, 0, w, h); The imageData read more..

  • Page - 343

    347CHAPTER 26: Game PhysicsAs parameters, the method expects the x and y pixel coordinates, the sheet index, and whether the sprite is mirrored. The first thing to do is check whether there is a collision mask associated with this sprite sheet, because not all sprites have such a mask. If there is no collision mask, you simply return the value 255 (fully opaque): if (this._collisionMask === null) return 255; Then you calculate the column and row indices corresponding to the current sheet read more..

  • Page - 344

    348CHAPTER 26: Game PhysicsFor convenience, you also add a getAlpha method to SpriteGameObject that calls the getAlpha method from SpriteSheet with the right parameters: SpriteGameObject.prototype.getAlpha = function (x, y) { return this.sprite.getAlpha(x, y, this._sheetIndex, this.mirror);}; Note Not all browsers always allow you to access pixel color data. For example, Chrome and Firefox don’t allow this access if you open the HTML page as a local file on your computer. Internet Explorer read more..

  • Page - 345

    349CHAPTER 26: Game PhysicsNow you can calculate the position and size of the overlap rectangle and return it from the method: return new powerupjs.Rectangle(xmin, ymin, xmax - xmin, ymax - ymin); In the collidesWith method in SpriteGameObject, you store the overlap rectangle by calling the intersection method from the Rectangle class: var intersect = this.boundingBox.intersection(obj.boundingBox);Checking the Pixels in the Overlap RectangleThe overlap rectangle’s coordinates are expressed in read more..

  • Page - 346

    350CHAPTER 26: Game PhysicsIn this nested for instruction, you check whether both pixels are not transparent at these local positions. If that is the case, you have a collision. You use the getAlpha method to check this for both pixels: if (this.getAlpha(Math.floor(local.x + x), Math.floor(local.y + y)) !== 0 && obj.getAlpha(Math.floor(objLocal.x + x), Math.floor(objLocal.y + y)) !== 0) return true; Now that your basic collision-detection methods are implemented, you can check read more..

  • Page - 347

    351CHAPTER 26: Game PhysicsAs you can see, you don’t directly access the Tile objects. The reason is that sometimes, the x or y index can be negative because the character is near the edge of the screen. Here you see the advantage of using the getTileType method you added to the TileField class. You don’t care if you’re really dealing with a tile: as long as you know its type and bounding box, you can do your job.In the nested for instruction, you also see a new keyword: continue. This read more..

  • Page - 348

    352CHAPTER 26: Game PhysicsNow you can calculate the difference between the minimum allowed distance and the actual distance, to get the intersection depth. If you look at the actual distance between the two centers, there are two possibilities for both dimensions (x and y): the distance is either negative or positive. For example, if the x distance is negative, this means rectangle rect is placed to the right of rectangle this (because rect.center.x > this.center.x). If rectangle this read more..

  • Page - 349

    353CHAPTER 26: Game Physicsonly case where you want to move the character to correct a collision is when it’s colliding with a wall tile (TileType.normal). In that case, you move the character by adding the x depth value to the character position: if (tileType === TileType.normal) this.position.x += depth.x; If you want to correct the character position in the y direction, things become slightly more complicated. Because you’re dealing with movement in the y direction, this is also a read more..

  • Page - 350

    355 Chapter 27Intelligent EnemiesAs the next step in developing the Tick Tick game, let’s introduce some peril to the player by adding dangerous enemies. If the player touches an enemy, the player dies. The enemies generally aren’t controlled by the player (that would make it too easy). Therefore, you need to define some kind of smart (or stupid) behavior. You don’t want these enemies to be too smart: the player should be able to complete the level. After all, that is the goal of playing a read more..

  • Page - 351

    356CHAPTER 27: Intelligent Enemies "...--........W.--...", "r..W........--.W....", "...--..........--...", "....W...........W..R", "...--..........--...", ".1..................", "######..####..######"]}); A lowercase r means the rocket should fly from left to right, and an uppercase R means it should fly from right to read more..

  • Page - 352

    357CHAPTER 27: Intelligent EnemiesLet’s look at the first case. If the rocket is waiting to be spawned, you simply subtract the time that has elapsed since the last update call from the spawn time: if (this.spawnTime > 0) { this.spawnTime -= delta; return;} The second case is slightly more complicated. The rocket is moving from one end of the screen to the other. So, you set the visibility status to true, you calculate the rocket velocity depending on the direction it’s moving, and read more..

  • Page - 353

    358CHAPTER 27: Intelligent EnemiesA Patrolling EnemyThe rocket is a type of enemy that basically has no intelligent behavior. It flies from left to right or vice versa until it flies out of the screen, and then it resets itself. You can also add enemies that are slightly smarter, such as a patrolling enemy. Let’s set up a few different types of patrolling enemies that you can add to the game.The Basic PatrollingEnemy ClassThe PatrollingEnemy class is similar to the Rocket class. You want the read more..

  • Page - 354

    359CHAPTER 27: Intelligent EnemiesIn the constructor of the PatrollingEnemy class, you load the main animation for the patrolling enemy character (an angry-looking flame, as shown in Figure actionGoTo:354,27-2). Initially, you set a positive velocity so the enemy starts walking to the right. You also initialize another member variable called _waitTime that keeps track of how long the enemy has been waiting on one of the edges of the platform it’s walking on: this._waitTime = 0;this.velocity.x read more..

  • Page - 355

    360CHAPTER 27: Intelligent EnemiesThe turnAround method simply inverts the velocity and mirrors the animation: PatrollingEnemy.prototype.turnAround = function () { this.mirror = !this.mirror; this.velocity.x = 120; if (this.mirror) this.velocity.x = -this.velocity.x;}; If the enemy currently is walking, not waiting, you need to find out whether it has reached the edge of the platform it’s walking on. It has reached an edge in two cases: either there is a gap, so the enemy read more..

  • Page - 356

    361CHAPTER 27: Intelligent EnemiesFor example, you can create an enemy that is a bit more unpredictable by letting it change direction once in a while. At that point, you can also change the enemy’s walking speed to a random value. You do this by defining a class UnpredictableEnemy that inherits from the PatrollingEnemy class. So, by default, it exhibits the same behavior as a regular enemy. You override the update method and add a few lines of code that randomly change the direction in which read more..

  • Page - 357

    362CHAPTER 27: Intelligent EnemiesThis class defines an enemy that follows the player if the player is moving. This is done by checking whether the enemy is currently walking in the direction where the player is standing (only taking the x direction into account). If not, the enemy turns around. You place a limitation on the enemy’s intelligence by doing that only if the player isn’t moving in the x direction (in other words, the player’s x velocity is zero).You should never make enemies read more..

  • Page - 358

    363CHAPTER 27: Intelligent EnemiesSparky is the final enemy type that you add to the game. Just like the other enemies, Sparky has two states (see FigureactionGoTo:358, 27-4). Sparky is a very dangerous, electricity-loving enemy. He hangs quietly in the air until he receives a bolt of energy. When that happens, he falls down. While Sparky is hanging in the air, he isn’t dangerous; but as soon as he falls, don’t touch him! Have a look at the Sparky class to see the code.Figure 27-4. Sparky read more..

  • Page - 359

    364CHAPTER 27: Intelligent Enemiescase 'T': return this.loadTurtleTile(x, y);case 'A':case 'B':case 'C': return this.loadFlameTile(x, y, tileType); Loading an enemy is straightforward. You simply create an instance of the enemy you would like to add, set its position, and add it to the _enemies list of game objects. For example, here is the method for loading a turtle enemy: Level.prototype.loadTurtleTile = function (x, y) { var tiles = this.find(ID.tiles); var enemy = new read more..

  • Page - 360

    365 Chapter 28Adding Player InteractionIn this chapter, you add more interaction between the player and the objects in the level. Currently, the player can walk around, and a basic physics system allows the player to jump, collide with wall tiles, or fall out of the screen. First you look at a very simple kind of interaction: collecting water drops. Then you see how to create the behavior that allows the player to slide over ice. Finally, you focus on the part of the program that deals with the read more..

  • Page - 361

    366CHAPTER 28: Adding Player InteractionLater, you can determine whether the level is completed by checking the visibility of each water drop. If all the water drops are invisible, you know the player has collected all of them.Ice BlocksAnother type of interaction you can add to the game is special behavior when the player is walking over ice. When the player moves over ice, you want the character to continue sliding at a constant rate and not stop moving when the player releases the arrow key. read more..

  • Page - 362

    367CHAPTER 28: Adding Player InteractionSimilarly, if the game is being played on a touch device, you check whether the player is touching one of the buttons, and you adapt the velocity of the player character accordingly.The only thing you still need to do is find out whether the player is walking on ice and update the walkingOnIce member variable accordingly. You already look at the tiles surrounding the player in the handleCollisions method, so to extend that method to also check whether the read more..

  • Page - 363

    368CHAPTER 28: Adding Player InteractionYou also add a method called die to let the player die. There are two ways the player can die: by falling in a hole out of the game screen and by colliding with an enemy. Therefore, you pass a Boolean parameter to the die method to indicate whether the player died by falling or by colliding with an enemy.In the die method, you do a couple of things. First you check whether the player was already dead. If so, you return from the method without doing read more..

  • Page - 364

    369CHAPTER 28: Adding Player InteractionYou can check in the update method whether the player is falling to death by calculating if the player’s y-position falls outside of the screen. If this is the case, you call the die method: var tiles = this.root.find(ID.tiles);if (this.boundingBox.top >=tiles.rows * tiles.cellHeight) this.die(true); At the start of the update method, you call the update method of the superclass to ensure that the animation is updated: read more..

  • Page - 365

    370CHAPTER 28: Adding Player InteractionThe second case is that the turtle is in waiting mode, and the player is jumping on the turtle. In that case, the player should make an extra-high jump. An easy way to check whether the player is jumping on the turtle is to look at the y velocity. Assume that if that velocity is positive, the player is jumping on the turtle. So, you call the jump method to make the player jump extra high: else if (player.velocity.y > 0 && player.alive) read more..

  • Page - 366

    371 Chapter 29Finishing the Tick Tick GameIn this chapter, you finish the Tick Tick game. First you add a timer such that the player has a limited amount of time to complete each level. Then you add a few mountains and clouds to the background to make the game visually more interesting. Finally, you progress through the levels by adding two extra game states: the “game over” state, and the “level finished” state.Adding a TimerLet’s first look at adding a timer to the game. You don’t read more..

  • Page - 367

    372CHAPTER 29: Finishing the Tick Tick GameNow the only thing you still need to do is implement the update method to program the timer behavior. As a first step, you only update the timer if it’s running. So if the timer isn’t running, you return from the method: if (!this.running) return; Then, as usual you subtract the elapsed game time from the current remaining time: this._timeLeft -= delta; Next you create the text that you want to print on the screen. You could simply print the read more..

  • Page - 368

    373CHAPTER 29: Finishing the Tick Tick GameNow that you’ve calculated the number of minutes and seconds remaining, you can create a string that you draw on the screen: this.text = minutes + ":" + seconds;if (seconds < 10) this.text = minutes + ":0" + seconds; You set the color of the text to yellow so it better fits the design of the game: this.color = powerupjs.Color.yellow; Finally, you want to warn the player if they don’t have a lot of time left to finish the read more..

  • Page - 369

    374CHAPTER 29: Finishing the Tick Tick GameThen you add one line of code to update the value of the variable depending on the current tile the player is standing on: this.walkingOnHot = this.walkingOnHot || currentTile.hot; For the complete code, see the Player class belonging to the TickTickFinal example.Using the walkingOnIce and walkingOnHot variables, you can now update the timer multiplier. You do this in the player’s update method: var timer = this.root.find(ID.timer);if read more..

  • Page - 370

    375CHAPTER 29: Finishing the Tick Tick Game this.exploded = true; this.velocity = powerupjs.Vector2.zero; this.playAnimation("explode"); sounds.player_explode.play();}; First, the player character can’t explode if the character wasn’t alive in the first place, or if the player finished the level. In either of those cases, you simply return from the method. Then, you set the alive status to false and the exploded status to true. You set the velocity to zero (explosions read more..

  • Page - 371

    376CHAPTER 29: Finishing the Tick Tick GameFor clouds, you do something slightly more complicated. You want the clouds to move from left to right or vice versa, and if a cloud disappears from the screen, you want a new one to appear. To do this, you add a Clouds class to the game. You create an instance of this class in the Level constructor and assign it a higher layer value than the background itself and the mountains. This ensures that the clouds are drawn in front of the mountains: var read more..

  • Page - 372

    377CHAPTER 29: Finishing the Tick Tick GameYou position the cloud at either the left border or the right border of the screen, depending on the direction in which the cloud is moving: if (cloud.velocity.x < 0) cloud.position = new powerupjs.Vector2(powerupjs.Game.size.x, cloudHeight);else cloud.position = new powerupjs.Vector2(-cloud.width, cloudHeight); Now you add the new cloud to the list: this.add(cloud); Figure actionGoTo:372,29-1actionGoTo:372, shows a screenshot of a level that read more..

  • Page - 373

    378CHAPTER 29: Finishing the Tick Tick Game // calculate cloud position and velocity // ... this.add(cloud); }} Look closely at the loop: you’re removing and adding objects to a list while traversing it with a for instruction. This can be dangerous, because you modify the length of the list in the body of the for instruction, and the value of i depends on the length of the list. If you aren’t careful, you could run into a case where you remove an item from the list read more..

  • Page - 374

    379CHAPTER 29: Finishing the Tick Tick GameIn the update method of the Level class, you check whether the level was completed. If so, you call the levelFinished method in the Player class, which plays the “celebration” animation: if (this.completed && timer.running) { player.levelFinished(); timer.running = false; window.LEVELS[this._levelIndex].solved = true;} You also stop the timer, because the player is done. Furthermore, you set the solved status of this level to true read more..

  • Page - 375

    381 Part VIInto the Great Wide OpenBy now you know how to program a game in JavaScript. But what’s next? How do you create a full-fledged game that is ready for the market? What do you need to do in order to publish your game? And how should you market it? The final part of this book covers these topics. This part consists of two chapters. The first one deals with producing games, which includes game design, game development, and the operational aspects of game production. The second chapter read more..

  • Page - 376

    383 Chapter 30Producing GamesThis chapter covers several topics related to producing games. I talk first about designing HTML5 games and then about development. I briefly cover game asset production as well. Finally, you see the operational aspects of producing games, such as how to collaborate with multiple people on the same code and how to work on a game-production team. Both Mark Overmars and Peter Vesterbacka share thoughts and tips about these topics throughout the text.Peter Vesterbacka: read more..

  • Page - 377

    384CHAPTER 30: Producing GamesThis section doesn’t cover the design process itself; rather, it mainly discusses how programming web-based applications in JavaScript affects game design. The preceding quote is an example of this approach: because you want your games to play well on a variety of devices, you need to design games that allow for efficient implementation.Mark: “Many devices do not have a keyboard, so your game needs to allow control by touch input. For some games, keyboard read more..

  • Page - 378

    385CHAPTER 30: Producing Gamesroom for them has to be subtracted from the part of the screen that is available for playing. This also means you have to use artwork that can be easily scaled or that can be shown partially without taking anything away from the design.”When you design games that work on a variety of devices, you can’t always use all of the device’s available features. For example, if your game relies heavily on the player tilting the device, then the game isn’t playable on read more..

  • Page - 379

    386CHAPTER 30: Producing Gamesmany different programming languages, including JavaScript. For example, jQuery is a well-known JavaScript library that is used to create interfaces on web sites. Then there are tools that combine libraries with a development environment to create complete games, such as Unity (actionURI(http://unity3d.com/):http://unity3d.actionURI(http://unity3d.com/):com) which has a script engine that uses something very similar to JavaScript called UnityScript. Another game read more..

  • Page - 380

    387CHAPTER 30: Producing GamesIf you use a library, you avoid having to write all the code, but you’re dependent on the library’s limitations. If you don’t properly investigate beforehand whether the library will really solve your problem, you may put a lot of effort into integrating the library into your code and then find out it doesn’t actually do the crucial thing you need it to do. Also, sometimes it’s a good idea to write code from scratch instead of using a library, because read more..

  • Page - 381

    388CHAPTER 30: Producing GamesWhen you’re writing code, always think beforehand about the various solutions that solve a particular problem, and choose the one that fits best. This doesn’t necessarily have to be the most efficient solution all the time. If one solution is slightly less efficient but results in much clearer code, it might be a good idea to go for that solution. There are tools that measure the bottlenecks in code. For Firefox, the Firebug tool has a profiler that can analyze read more..

  • Page - 382

    389CHAPTER 30: Producing GamesBecause it returns the new value, you don’t have to store the old value, removing the need for that temporary variable. You can use this to your advantage in the for loop, to make it more efficient: for (var i = 0, l = myArray.length; i < l; ++i) myArray[i] += 1; These efficiency improvements may seem minor, but if the for loop is executed 60 times per second for an array containing thousands of particles, minor improvements in efficiency may make the read more..

  • Page - 383

    390CHAPTER 30: Producing Gameslevel selection screen. Another reason for hiccups is garbage collection (destroying objects that are no longer used, and freeing up memory). Unfortunately, there is no way to control when garbage collection happens. Anything that is an object falls under garbage collection. This becomes a problem when your game uses many small objects such as vectors. In that case, try to minimize the number of new objects you create, or pass along x and y values to methods read more..

  • Page - 384

    391CHAPTER 30: Producing GamesFurthermore, any variables that shouldn’t be directly accessed outside a class are preceded by an underscore character. Having such a convention in your code is a good thing. It makes your code a lot easier to understand. Another convention this book follows is that in names consisting of multiple words, each following word starts with an uppercase character: function GameObjectList() { ...}GameObjectList.prototype.handleInput = function() { ...};var read more..

  • Page - 385

    392CHAPTER 30: Producing GamesTo get started, you can buy premade packs of sprites. Here are a few examples of web sites where you can get sprites for free, buy sprites, or hire artists who can create sprites for read more..

  • Page - 386

    393CHAPTER 30: Producing GamesMark: “Because we are quite a small team, the project manager is also our game designer. Sometimes this leads to problems. The project manager wants the game to be finished on time, while the designer wants to keep improving or changing the game. In that case, the project manager should tell the designer that the game should be done, which is quite hard to do if both are the same person.”You may have a grasp on the various elements that are needed to produce a read more..

  • Page - 387

    394CHAPTER 30: Producing GamesPeter: “Flat organizations generally work better than deep hierarchical structures. One thing that is very important is that you create an environment where people know what they are supposed to be doing, so that there is clear direction and leadership. It is important to give people jobs with a purpose, no matter if you’re coding away at game, doing the artwork, or working on marketing.”Mark: “If you want to create a game company, be very selective in the read more..

  • Page - 388

    395 Chapter 31Publishing GamesPeter Vesterbacka: “Pretty much everybody on the planet has a smartphone nowadays, make it the biggest gaming platform ever. And we are only at the beginning; it is still growing massively. Mobile is where the volume is, where the center of gravity is.”This final chapter of the book talks about several topics related to getting your game out in the world. First I cover testing and checking code quality to ensure that your game works well on many different read more..

  • Page - 389

    396CHAPTER 31: Publishing GamesWhen you’ve more or less finished writing the code, there are two other major stages in testing: alpha and beta testing. Alpha testing is done internally by a group of people, often the developers themselves. Alpha testing is important because it makes sure all the components the developers have built work together as they should. After the internal alpha testing, software can also be tested externally. This is called beta testing: the software is used by a read more..

  • Page - 390

    397CHAPTER 31: Publishing GamesA tool to help you write better code is JSLint (actionURI(http://www.jslint.com/):www.jslint.com). JSLint is a so-called code-quality checker. It checks your code for things that are generally considered bad practice in coding. For example, JavaScript lets you use variables before they’re declared (although in strict mode this isn’t allowed). JSLint checks that your code doesn’t contain the usage of any undeclared variables. Another example where read more..

  • Page - 391

    398CHAPTER 31: Publishing GamesMark: “We have our own localization tool. Every game has its own dictionary file that stores each text in the game with a unique ID, in all languages. We make a special tool to edit these texts. A lot of texts are not game specific, and they are part of our framework, so we export them together with the game-specific texts. Our tool can also generate this data as a spreadsheet so we can send this to a translator who then simply has to fill in a single column. read more..

  • Page - 392

    399CHAPTER 31: Publishing GamesSelling Your GameIf you want to make a living with creating HTML5 games, there are quite a few different possibilities. A very simple way to make money with your games is to put them on your web site and add advertisement banners—for example, using Google AdWords. If you get a lot of visitors, you will make revenue from the advertisements. However, this ad income will be low unless you attract a lot of players. Perhaps a more lucrative approach is to sell your read more..

  • Page - 393

    400CHAPTER 31: Publishing GamesMarketingNow that you’re programming your own games, you may have started to think about how to get them out in the real world. Maybe you don’t want to create a game just for the achievement, but to make some money with it. Fortunately, nowadays getting games published is easy. For mobile devices, there are app stores to which you can submit your games after you’ve exported them to a specific mobile platform. If you sell your games through a portal, then the read more..

  • Page - 394

    401CHAPTER 31: Publishing GamesI mentioned the Early Access mechanism on Steam in the previous section. Such an open development mechanism is also interesting from a marketing point of view. It allows you to attract players to your game and get them involved in the game’s development. By involving players in the early stages of game development, you can create a very strong bond between the players and the game, because they feel like they’re part of the development process. If you’re read more..

  • Page - 395

    A ■Animal class, actionGoTo:287,288AnimalSelector classarrow actionGoTo:291,class, 293–295handleInput method, actionGoTo:294,296AnimationAnimatedGameObject classloadAnimation actionGoTo:327,method, 331playAnimation method, actionGoTo:328,332collision actionGoTo:337,detection, 341bounding boxes, actionGoTo:338,342,actionGoTo:338, actionGoTo:340,344bounding circles, actionGoTo:338,342calculation, actionGoTo:344,348checking, actionGoTo:345,349pixel color data (see Pixel color read more..

  • Page - 396

    variable actionGoTo:105,timestep, 98velocity, actionGoTo:99,92Boolean type, actionGoTo:83,76Break actionGoTo:284,statement, 285–286C ■Cannon barrelalternative instruction, actionGoTo:86,79if actionGoTo:86,instruction, 79leftDown variable, actionGoTo:85,78toggle behavioractionGoTo:88,, 81update actionGoTo:85,method, 78Cannon actionGoTo:159,class, 155–156Cannon objectcannon actionGoTo:113,class, 107constructoractionGoTo:114,, 108Game_Singleton actionGoTo:115,class, 109PainterGameWorld class, read more..

  • Page - 397

    G ■Game actionGoTo:52,assets, 45,actionGoTo:52, actionGoTo:92,85,actionGoTo:95, 88draw methoddrawing actionGoTo:55,state, 48actionGoTo:55,parameters, 48FlyingSprite practionGoTo:57,ogram, 50MovingSquare actionGoTo:57,example, 50music and sound efactionGoTo:59,fects, 52start methodevent handler function, actionGoTo:54,47Image actionGoTo:53,type, 46objects, actionGoTo:53,46actionGoTo:54,sprites, 47actionGoTo:53,types, 46Game dataactionGoTo:276,disadvantages, 277global actionGoTo:279,variable, read more..

  • Page - 398

    level menu statefor instruction, actionGoTo:270,270getSelectedLevel actionGoTo:271,method, 271handleInput actionGoTo:270,method, 270–271LevelButton actionGoTo:269,class, 269switchTo actionGoTo:267,method, 267TitleMenuState, actionGoTo:268,268title screen, actionGoTo:227,225–226Game world, actionGoTo:27,19in JavaScriptfixed timestep loop, actionGoTo:30,22grouping, actionGoTo:29,21mainLoop function, actionGoTo:30,22actionGoTo:30,setTimeout, 22start function, actionGoTo:30,22update and draw read more..

  • Page - 399

    rocket enemy, actionGoTo:350,355behavior, actionGoTo:351,356creation and resetting, actionGoTo:351,356turtle enemy, waitTime variable, actionGoTo:357,362If statement, actionGoTo:86,79,actionGoTo:86, actionGoTo:237,236,actionGoTo:294, 296–297incrementing countersnotation, actionGoTo:140,136postfix operator, actionGoTo:139,135J ■Javascript game engine, actionGoTo:17,9JavaScript actionGoTo:90,files, 83JavaScript Object Notation actionGoTo:289,(JSON), 290JewelCart actionGoTo:222,class, 219Jewel read more..

  • Page - 400

    handleMouseMove actionGoTo:181,function, 177reset actionGoTo:182,function, 178Mouse actionGoTo:64,position, 57cannon barrel, actionGoTo:71,64atan2 actionGoTo:73,method, 66drawImage method, actionGoTo:72,65draw actionGoTo:73,method, 66Math actionGoTo:73,object, 66start method, actionGoTo:72,65tangent function, actionGoTo:72,65update method, actionGoTo:72,65Draw actionGoTo:66,method, 59event-handler function, actionGoTo:65,58event actionGoTo:65,handlers, 58in FlyingSprite program, read more..

  • Page - 401

    Player interactionice blockshandleCollisions method, actionGoTo:362,367handleInput actionGoTo:361,method, 366water drops actionGoTo:360,collection, 365with enemies, actionGoTo:362,367checkPlayerCollision actionGoTo:364,method, 369die actionGoTo:363,method, 368Sparky class, actionGoTo:364,369Turtle enemy, actionGoTo:364,369update method, actionGoTo:364,369Polymorphism, actionGoTo:157,153Procedural programming paradigm, actionGoTo:13,5Program layoutcomments, actionGoTo:34,26instructions vs. lines, read more..

  • Page - 402

    PlayingState class, actionGoTo:374,379Tile class, actionGoTo:322,325TimerGameObject classMath.ceil actionGoTo:367,method, 372Math.floor actionGoTo:367,method, 372multiplier value, actionGoTo:368,373reset method, actionGoTo:366,371update method, actionGoTo:367,372WaterDrop actionGoTo:321,class, 324–325Tile actionGoTo:277,class, 278–279,actionGoTo:278, actionGoTo:322,325Touchscreen Input, actionGoTo:184,180containsTouch method, actionGoTo:187,183event-handler actionGoTo:185,functions, read more..

  • Page - 403

    Building JavaScript GamesFor Phones, Tablets, and DesktopArjan Egges read more..

  • Page - 404

    Building JavaScript GamesCopyright © 2014 by Arjan EggesPortions of the text are from Learning C# by Programming Games, Egges, Arjan, Fokker, Jeroen D., Overmars, Mark H., © Springer-Verlag Berlin Heidelberg 2013, and are used by permission.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 translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on read more..

  • Page - 405

    I dedicate this book to my parents, Ap and Frida, and to my wife, Sterre. read more..

  • Page - 406

    vii ContentsAbout the Author actionGoTo:418,��������������������������������������������������������������������������������������������������������������� actionGoTo:418,xixAbout the Technical Reviewer read more..

  • Page - 407

    viiiContentsBuilding Your First Web Application actionGoTo:19,11The HTML5 Canvas actionGoTo:24,16JavaScript in a Separate FileactionGoTo:25,17What You Have Learned actionGoTo:26,18Chapter 2: Game Programming Basics ■ actionGoTo:27,����������������������������������������������������������������������������19Building Blocks of a Game read more..

  • Page - 408

    ixContentsAssigning a Function to a Variable actionGoTo:43,35Variables Composed of Multiple Values actionGoTo:44,36The MovingSquare Game actionGoTo:47,39Scope of Variables actionGoTo:51,43What You Have Learned actionGoTo:51,43Chapter 4: Game Assets ■ read more..

  • Page - 409

    xContentsA Number of Different AlternativesactionGoTo:87,80Toggling the Cannon Barrel’s Behavior actionGoTo:88,81What You Have Learned actionGoTo:89,82Chapter 7: Basic Game Objects ■ ���������������������������������������������������������������������������������������actionGoTo:90,83Using Separate JavaScript Files read more..

  • Page - 410

    xiContentsChapter 9: Colors and Collisions ■ actionGoTo:126,�����������������������������������������������������������������������������������121A Different Way to Represent Colors actionGoTo:126,121Controlled Data Access for Objects actionGoTo:128,123Read-Only Properties actionGoTo:130,125Retrieving the Color of the Cannon read more..

  • Page - 411

    xiiContentsValues vs References actionGoTo:159,155Null and Undefined actionGoTo:161,157What You Have Learned actionGoTo:162,158Chapter 12: Finishing the Painter Game ■ ������������������������������������������������������������������������actionGoTo:163,159Adding Motion Effects actionGoTo:163,159Adding Sounds and Music actionGoTo:164,160Maintaining a read more..

  • Page - 412

    xiiiContentsChapter 14: Game Objects in a Structure ■ ����������������������������������������������������������������������actionGoTo:190,187Game Objects in a Grid actionGoTo:190,187Creating a Grid of Sprites actionGoTo:191,188Drawing the Grid actionGoTo:193,190Grid Operations actionGoTo:194,191More Possibilities with Grids read more..

  • Page - 413

    xivContentsDealing With Combinations of Jewels actionGoTo:223,220Finding Valid Combinations actionGoTo:223,220Removing Jewels from the Grid actionGoTo:225,222Updating Other Game Objects actionGoTo:226,223What You Have Learned actionGoTo:226,223Chapter 16: Game States ■ read more..

  • Page - 414

    xvContentsChapter 19: Menus and Settings ■ �����������������������������������������������������������������������������������actionGoTo:258,257Setting Up the Menu actionGoTo:258,257Adding an On/off Button actionGoTo:259,258Adding a Slider Button actionGoTo:260,259Reading and Storing Game Settings actionGoTo:263,262What You Have read more..

  • Page - 415

    xviContentsHandling Input in Reverse Order actionGoTo:295,297Updating Animals actionGoTo:297,299Meeting Other Game Objects actionGoTo:299,301Maintaining the Number of Pairs actionGoTo:301,303What You Have Learned actionGoTo:303,305Chapter 23: Finishing the Penguin Pairs Game ■ �������������������������������������������������������������actionGoTo:304,307Separating Code read more..

  • Page - 416

    xviiContentsPlaying an Animation actionGoTo:328,332The Player Class actionGoTo:329,333What You Have Learned actionGoTo:332,336Chapter 26: Game Physics ■ actionGoTo:333,���������������������������������������������������������������������������������������������337Locking the Character in the Game World read more..

  • Page - 417

    xviiiContentsChapter 28: Adding Player Interaction ■ ��������������������������������������������������������������������������actionGoTo:360,365Collecting Water Drops actionGoTo:360,365Ice Blocks actionGoTo:361,366Enemies Colliding With the Player actionGoTo:362,367What You Have Learned actionGoTo:365,370Chapter 29: Finishing the Tick Tick Game read more..

  • Page - 418

    xix About the AuthorArjan Egges, PhD, is an associate professor in Computer Science at Utrecht University in the Netherlands. He is responsible there for research in the area of computer animation, and he heads the university’s motion capture lab. Arjan has written over 30 research papers on animation. He is the founder of the highly successful, annual ACM SIGGRAPH conference on Motion in Games, the proceedings of which have been published by Springer-Verlag. Arjan is responsible for having read more..

  • Page - 419

    xxi About the Technical ReviewerJon Westfall, PhD, is an assistant professor of psychology, researcher, programmer, and speaker. He has worked as a consultant since 1997, founding his own firm, Bug Jr. Systems. As a consultant, he has developed custom software solutions (including native Windows 32 applications, Windows .NET applications, Windows Phone 7 and Android mobile applications, as well as ASP, ASP.NET, and PHP web applications). He has also served as a senior network and systems read more..

  • Page - 420

    xxiii AcknowledgmentsWriting a book, just like creating a game, is the work of a team. I want to thank Mark Overmars of Tingly Games for the many discussions we had over the past year about HTML5 and JavaScript that ultimately led to this book. I want to thank Peter Vesterbacka of Rovio Entertainment for the interesting interview and the useful thoughts he provided. Thanks also to Jeroen Fokker, who—as a seasoned programming teacher—provided me with many insights into creating a read more..

  • Page - 421

    xxv ForewordWhen I first learned programming in the 1970s you would typically write rather boring programs; for example to print the first 100 prime numbers. A lot has changed since then, and learning to program has become much more exciting. And what is more exciting than creating your own computer games? Playing games is fun, but creating them is a lot more fun. Now it is you who decide on the complexity of the puzzles, the behavior of the enemies, and the power of the weapons.I have developed read more..

  • Page - 422

    xxviForeworda programmer (you), you might need an artist to create the visuals and somebody to do the audio for the game. But such people can easily be found on the Web. And when you have a strong team, you can form your own game company. Many successful companies have started this way.So, reading this book could be your first step on a career path in game development. Surprise yourself and the game community with the games you produce. Enjoy the ride.—Mark Overmars read more..

Write Your Review