HTML5 Canvas (IV)

Slippy Snake Game — The Grid System

Maxwell Alexius
6 min readFeb 2, 2017

Author’s Words

So far we’ve been using the HTML5 Canvas to create the 2D graphics. In the previous tutorial, we have created a simple animation with Canvas. In this article, it is going to talk about simple game development. The article choose the Snake game as the topic of the tutorial series, because the algorithm is easy and didn’t take too much time to go through. By the way, I’ve also many kinds of game other than the Snake, you can view my portfolio site.

到目前為止我們使用 HTML5 Canvas 創作出二維平面的圖像。在上一篇教學裡,我們使用 Canvas 創造簡單的動畫。在這一篇教學裡,要開始解說簡單的遊戲開發。以貪吃蛇遊戲為主題的原因是因為它的演算法較為簡單入門,不需要花太多時間就可以達成的。此外,你也可以在我的作品集裡看到很多其他的遊戲也是由 Canvas 所開發出來的。

Although in these several days, I have discovered better version of JavaScript function for creating animations and it produced better result, which is requestAnimationFrame. You can search on the internet about the differences between the setInterval and the requestAnimationFrame. However, for the sake of going through the current tutorial series smoothly, we still use the setInterval version of the animation. (It doesn’t affect too much on the snake game when I tested the result.)

雖然我在這幾天也有看到可以更有效率地創建動畫的 JavaScript 的函式,也就是 requestAnimationFrame。你可以上網查詢它和 setInterval 之間的差別。但為了讓這一系列的教學順利進行,我們照樣採用 setInterval 版本的動畫。(目前為止我測試過貪吃蛇,也是使用 setInterval 版本的動畫但效能差不多)

Snake Game created by the Auther

Topic — Grid System

Template Files

The tutorial series will break down the game development in several parts. In this article, we are mainly focusing on setting the grid system of the Snake Game. Go to this Gist and you will see there are three files, the main HTML template file (SnakeHTMLTemplate.html), the main.css and the main.js file. Copy or download the code inside Gist and you need to place all three files in the same directory!

這一系列的遊戲開發教學會把過程分成好幾個章節。在這一篇文章中,我們找要先開發出貪吃蛇基本的背景座標方格系統。請到這個 Gist 裡面,你會發現有三個檔案,一個主要是 HTML 的模板 (SnakeHTMLTemplate.html) 以及分別為 main.cssmain.js 的檔案。你可以複製或者下載這些在 Gist 裡面的程式碼下來,並記得一定要放在同一個資料夾位置裡!

We will only need to compose JavaScript code in main.js file rather than in the HTML or CSS file. So just left the HTML and the CSS file stay still and mainly focusing on programming in the main.js file!

我們只會需要動到 main.js 裡面的程式碼而非其他的 HTML 或者是 CSS 的檔案。所以把 HTML 以及 CSS 的檔案維持在一邊,專注地開始在 main.js 裡編程吧!

Setting Up Canvas

The following example code shows the setup of the canvas. Noticing that in this tutorial series, variables started with the dollar '$' sign represent the global variables. However, this is just a kind of coding style rather than a rule in JavaScript! Please do not misunderstand that all the variables started with dollar sign in other programming code is also global variables, that’s not true!

下列的範例程式碼設定好了 Canvas。必須注意的是,在這一系列的教學當中,變數名稱開頭如果有錢字符號 '$' 代表的是全域變數然而,這只是一種編程的風格而非 JavaScript 定義的語法!請不要誤會而導致以為任何的變數開頭為錢字符號在其他的編程也是代表為全域變數,實際上卻不然!

Setting Up Canvas

This time we are using the jQuery version and set up the canvas. You can see that the canvas is rendered after the document has already been loaded. We will also define a sequence of the global variables in the beginning of the main.js file during the development. This makes us to adjust the value of the variable easily and perform simple tests.

這一次我們使用 jQuery 的方式來創建 Canvas。你可以看得出來當整個 document 文件載入完畢之後, Canvas 才會被渲染出來。我們也將會在開發的過程當中在 main.js 的開頭定義一連串的全域變數。這使得我們可以輕鬆地調整參數並方便做測試。

Notice that we set the canvas width and height to null. The reason is by defining the grid system and we can calculate the width and the height of the canvas. Constructing grid system is our next step.

注意到我們將 Canvas 的長寬都設為 null。目的是藉由定義座標方格系統來計算出 Canvas 所需要之寬度與長度。而下一步即是把這個系統建構出來。

Grid System

Grid System Object

We define another global variable called $grid which represents the system object. It holds several keys, you can see that maxRow and maxCol is the size of the grid system. The unitSize defines the size of an unit square of the grid and the unitGap defines the gap between the squares in the grid. The grid system is illustrated below the sample code.

我們定義出另一個全域變數 $grid 作為整個方格座標系統物件。你可以藉由這個物件知道 maxRowmaxCol 定義出整個系統的大小。 unitSize 定義出了每個方格在系統裡的大小,而 unitGap 則定義出了系統裡方格與方格之間的間隔大小。在範例程式碼之下圖為這個座標系統示意圖。

Define the $grid variable represents the grid system
Grid System Illustration

And now, we can calculate the width and height of the canvas. Please review the example code below. Notice that in mathematics, the number of gaps is one more than the number of rows (or cols) in the grid system.

現在,我們可以計算出 Canvas 的長度與寬度。請檢視以下的範例程式碼。要注意的是,間隔的數量比列數(或者是行數)還要再多一個。

Calculate and setup canvas width and height

Concept of Abstraction

Let’s make a function called initializeGridSystem. It is simple, we just packed the process of measuring the canvas width and height in to a function, then call it right after the start of the main function.

讓我們創建一個叫做 initializeGridSystem 函式。這很簡單,只要將一整個計算 Canvas 的長度與寬度的過程包進這個函式,在主要的執行序裡呼叫這個函式即可。

Define a function called initializeGridSystem()

So why do we need to do this step? The answer is, this is not a necessary step. However, it will help us read and understand the code quickly. This technique is called abstraction.

所以為何我們需要這樣做?而答案是這並非必要的步驟之一。然而,這可以讓我們快速地閱讀、清楚地知道某段程式碼的意義。這個技巧就叫做抽象化

To explain in a simple way, that is, in software programming, packing a series of control statements or actions into an understandable function. It suppresses the complexity and make it easier for human to interact with the system. So back into our example code, we can just know that the function will initialise the grid system first rather than examining the code and knowing the details of the calculation process. By the way, there is a formal explanation about the concept of abstraction, you can view it on wikipedia.

也就是說,在編程技巧裡,將一系列的控制程序或動作包進一個函式裡。而這個函式可以降低程式碼複雜程度並讓人類可以更容易地跟系統「溝通」。所以在範例程式碼裡,我們只要知道這個函式告訴我們它在初始化整個方格座標系統而不需要再去檢視並知道整段程式碼計算的過程。此外,有一個對於抽象化概念較為正式的說法,請參考維基百科

The current result of the canvas

Open your HTML file, you should see the result of the canvas is illustrated above. The number of rows and columns can customised or test them by changing the values of the maxRow and maxCol in the grid system object. Currently they are set to 20 and 28. The next step is to draw the grid system.

打開你的 HTML 文檔,你應該可以看得到如上圖呈現出來的畫面。列數與行數取決於你的 maxRowmaxCol 之值,你可以改變它們的值來測試看看。目前的列數為 20 而行數則為 28 。下一步即為畫出整個方格座標系統。

Drawing Squares

Let’s define a function which belongs to the $grid object, it can draw the squares given the row and the column of the square. It can also customise the style of the square. (Check the previous tutorial to review the basic JavaScript syntax if you are not familiar with JS Functions and Objects.)

讓我們定義一個屬於座標物件的函式,給予列數以及行數可以畫出相對應位置之方格。它也可以自定義方格框框的樣式。(如果你不熟悉 JS 函式與物件的話,可以參考上一篇文章之基本 JS 語法)

Example code for drawing square given the value of row and column
The illustration shows how to use the drawSquare function

You can test it by calling the the function inside the main function. In the example, the code draws the 3 X 5 grid system with a red square in position (2, 4). (The second row and the fourth column.)

你可以在主程序裡測試這個函式。在以下範例程式碼,我們畫出了 3 X 5 的座標系統,並在位置 (2, 4) 標示了一個紅色的方格。(第二橫列之第四直行)

Test codes
Test for Drawing the Squares

Drawing Grid System

Finally, using the technique of abstraction and nested looping statements, we can draw the full grid system. The result code and canvas are shown below.

最後,藉由抽象畫技巧搭配雙重迴圈,我們可以畫出完整的方格座標系統。程式碼與 Canvas 結果皆陳列在下方。

Draw the full grid system
The result of full grid system

Summery

Our first step is finally completed! In this article, it not only show you how to create the grid system via Canvas, it also taught the important technique called abstraction. It is a very useful for dealing complex program, if you are interested, you can also search for JavaScript functional programming.

第一步已經完成了!在這一篇文章裡,除了藉由 Canvas 創建出完整的方格座標系統,這篇文章也提供了一個很重要的技巧叫做抽象化。這個技巧可以應對複雜的程式流程,如果你有興趣的話,你也可以去搜尋 JavaScript 函式編程。(建議用英文搜尋,不過並不代表中文版沒有資料,只是沒有英文版多和詳細)

In the next article, we are going to create the main character in this game, which is the Snake! If you want to review the HTML5 Canvas, you can view the first chapter of this tutorial series or check out my reading list. If you are also interested in other application created by Canvas, check out my portfolio site! Hope you enjoy ~

在下一篇,我們將介紹如何創建這個遊戲的主角,也就是貪吃蛇!如果你想要複習 HTML5 Canvas,你可以去觀看這一系列的第一篇教學。你也可以看看我的文章列表。如果你對於 Canvas 應用也有興趣的話,可以看看我的作品集。祝你愉快~

Previous Article : Introduction to Three.JS

上一篇文章:入門 Three.JS

Previous Article from Current Tutorial Series : HTML5 Canvas (III)

上一篇教學系列文章: HTML5 Canvas (III)

--

--

Maxwell Alexius

A web developer, artist, and designer, and loves everything related to dragons. Welcome to visit my site : https://svartalvhe.im/maxwell-alexius