How to make a simple game with HTML5 canvas
In order to make it clear that HTML5 makes the simple process of making a game, we first make a very simple game and take a look at the process.
The game is very simple, nothing more than a hero catches the monster to score, then the game starts again, the monster appears in the random location of the map, the hero initialized in the middle of the map. Click here, we can play this game directly first
1. Create a Canvas object
It is believed that we all know, of course, the code is created by JS dynamic canvas, you can also directly on the HTML page to create a canvas, and then through document.getELementById()
to obtain, the two methods are no different, just see you more accustomed to which kind of.
// 创建画布canvas,并获取画布上下文环境 var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.width = 512; canvas.height = 480; document.body.appendChild(canvas);
2. Loading images
The game needs images, so let's load some pictures. I want to be as simple as possible, so I only use the image object to do, of course, can also be loaded into the image of the function of a class or any other form. The Bgready in the code is used to identify whether the picture is fully loaded, and only when the picture is loaded, we can use it, and if it is drawn or rendered before loading is complete, JS will report a DOM error.
We will use three images (backgrounds, heroes, monsters), each of which needs to be dealt with.
// 背景图片 bgImagevar bgReady = false;var bgImage = new Image();bgImage.onload = function () { bgReady = true;};bgImage.src = "images/background.png";
One thing to note here is to bgImage.src
write in bgImage.onload
order to solve the IE display bug, so it is recommended that everyone write this.
3. Define the objects to be used by the game
// 游戏对象 var hero = { speed: 256, // 英雄每秒移动的速度,即256px/s x: 0, y: 0 }; var monster = { x: 0, y: 0 }; var monstersCaught = 0;
Define some variables that will be used later. The speed attribute of the Hero object indicates the hero's movement velocity (pixels/second), the Monster object does not move, so it has only a pair of coordinates, and monsterscaught represents the number of monsters the player catches.
4. Handling player Input
// 键盘 输入处理 var keysDown = {};addEventListener("keydown", function (e) { keysDown[e.keyCode] = true;}, false);addEventListener("keyup", function (e) { delete keysDown[e.keyCode];}, false);
Which key is pressed by the user, handled by the keyboard event, and the keycode of the pressed key is saved in the empty object Keysdown. If a key is encoded in the variable, it means that the user is currently pressing the key.
5. New Games
// 当英雄捉住怪物之后重新开始游戏,英雄的位置在画布中间,怪物位置随机 var reset = function () { hero.x = canvas.width / 2; hero.y = canvas.height / 2; // 将怪物位置随机放在地图上,当然不能超过地图。 monster.x = 32 + (Math.random() * (canvas.width - 64)); monster.y = 32 + (Math.random() * (canvas.height - 64)); };
Start a new game by calling the Reset function. This function places the hero (that is, the player character) in the middle of the screen and randomly chooses a location to place the monster.
6. Updating objects
// 更新游戏对象 var update = function (modifier) { if (38 in keysDown) { // 上 hero.y -= hero.speed * modifier; } if (40 in keysDown) { // 下 hero.y += hero.speed * modifier; } if (37 in keysDown) { // 左 hero.x -= hero.speed * modifier; } if (39 in keysDown) { // 右 hero.x += hero.speed * modifier; } // 是否捉住怪物 if ( hero.x <= (monster.x + 32) && monster.x <= (hero.x + 32) && hero.y <= (monster.y + 32) && monster.y <= (hero.y + 32) ) { ++monstersCaught; reset(); } };
Update has a modifier parameter, which may seem a bit odd. You'll see it in the main function of the game, which is the main function, but I'll explain it here. The modifier parameter is a time-dependent number that starts at 1. If the interval is exactly 1 seconds, its value will be 1, the hero moves the distance is 256 pixels (Hero's speed is 256 pixels/second), and if the interval is 0.5 seconds, it is 0.5, that is, the hero moves the distance is half its speed, and so on. Typically, the interval for the update function call is very short, so the value of the modifier is small, but in this way it ensures that the hero moves at the same speed regardless of the speed of the code execution.
This is not the same as our previous practice, we often move to the right x += spped
, moving to the left x -= speed
, the previous practice, the equivalent of a given object movement speed, no matter what the machine, must ensure that the distance of each move is speed
the length.
We've implemented moving heroes based on user input, but we can also check them as we move heroes to determine if there are other events happening. For example, if a hero collides with a monster-when a hero collides with a monster, we score the player (monsterscaught plus 1) and reset the game (call the Reset function).
7. Render Objects
// Draw everything var render = function () { if (bgReady) { ctx.drawImage(bgImage, 0, 0); } if (heroReady) { ctx.drawImage(heroImage, hero.x, hero.y); } if (monsterReady) { ctx.drawImage(monsterImage, monster.x, monster.y); } // Score ctx.fillStyle = "rgb(250, 250, 250)"; ctx.font = "24px Helvetica"; ctx.textAlign = "left"; ctx.textBaseline = "top"; ctx.fillText("Goblins caught: " + monstersCaught, 32, 32); };
The update function is equivalent to just changing the value, while the render function is a drawing pattern, and the game becomes more interesting when you can see your action, so let's draw it on the screen. First we draw the background image to canvas, then the hero and the monster. Note that the order is important, because any image that is located on the surface will overwrite the pixels below it.
Think about it, every time if the hero's position changes, then we will all the scene including the background are redrawn once, then you see in the interface is like a hero took a step
Next is the text, which is somewhat different, and we call the Filltext function to show the player's score. Because there is no need for complex animations or to move the text, it is OK to just draw a bit.
8. Main game Loop
// 游戏主循环var main = function () { var now = Date.now(); var delta = now - then; update(delta / 1000); render(); then = now; requestAnimationFrame(main); }; var w = window;requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
The main loop of the game is used to control the game flow. First we have to get the current time so that we can calculate the time difference (elapsed since the last cycle). It then computes the value of the modifier and gives it to update (the delta must be divided by 1000 to convert it to milliseconds). Last call to render and update the time of the record.
Game main loop is the most important concept in the game, no matter how the game changes, nothing is to move, disappear. While the move disappears, it is nothing more than a redraw of the canvas, so place the moving or vanishing position in the update function and place the canvas in the render function. And over time, it's just that these two function functions have been executing.
9. Start the game
var then = Date.now();reset();main();
It's almost done, this is the last piece of code. First call reset to start a new game. (Remember, this will put the hero in place and randomly place the monsters). Then save the start time to the variable then and start the game's main loop.
HTML5 a basic process of making "game"