I’ve made my first game; Snake! It is a simple HTML5 Snake Game.
Now we’ll look for how to make a HTML5 snake game.
Before start to coding, let’s look what do you need for making the game;
- A code editor (I prefer Sublime Text. It is the best!)
- Pixi.js (Pixi is a very simple 2D library. It is more clean than pure WebGL functions.)
Now, we can start coding!
The SnakeGame() class;
1 |
var SnakeGame = {}; |
We need a SnakeGame.Game() class;
1 2 3 4 5 6 7 8 9 10 11 12 13 |
SnakeGame.Game = function (parameters) { this.app = parameters.app; this.width = 0; this.height = 0; this.x = 0; this.y = 0; this.snake = null; this.meals = []; }; |
..and let we write methods of SnakeGame.Game() class;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
SnakeGame.Game.prototype.setSnake = function (snake) { this.snake = snake; this.snake.game = this; }; SnakeGame.Game.prototype.step = function (parameters) { var t_Game = this; t_Game.meals.forEach(function (m, mi) { m.meal.clear(); m.meal.drawRect(m.x, m.y, t_Game.snake.length, t_Game.snake.length); }); }; SnakeGame.Game.prototype.placeMeals = function () { if (this.meals.length < 1) { var meal = new PIXI.Graphics(); this.app.stage.addChild(meal); meal.beginFill(0x2060C6); this.meals.push({ x: randomInt(15, this.app.renderer.view.width) - 15, y: randomInt(15, this.app.renderer.view.height) - 15, meal: meal }); } }; |
We’ve created the Game.prototype.setSnake() method, now we need a Snake() class;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
SnakeGame.Snake = function () { var t_Snake = this; t_Snake.x = 0; t_Snake.y = 0; t_Snake.length = 10; t_Snake.game = null; t_Snake.piece_size = 20; t_Snake.ep = null; t_Snake.addition = 0.2; t_Snake.d = null; t_Snake.rds = { 'l': 'r', 'r': 'l', 'd': 'u', 'u': 'd' }; t_Snake.ss = [ ['r', 5], ['d', 8], ['l', 3], ['d', 4], ['r', 8] ]; t_Snake.points_factor = 10; t_Snake.points = 0; t_Snake.ss.forEach(function (s, i) { t_Snake.points += s[1]*t_Snake.points_factor; }); }; |
Init method of Snake() objects. We’ll use this for restarting the game.
1 2 3 4 5 6 7 |
SnakeGame.Snake.prototype.init = function () { this.snline = new PIXI.Graphics(); this.game.app.stage.addChild(this.snline); this.x = 50; this.y = 50; }; |
We set a property for direction d in Snake() class, and a step list property ss.
Now we’re creating a method for set current direction;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
SnakeGame.Snake.prototype.rotate = function (rotation) { if ( (this.d == rotation) || ((this.d == 'l') && (rotation == 'r')) || ((this.d == 'r') && (rotation == 'l')) || ((this.d == 'u') && (rotation == 'd')) || ((this.d == 'd') && (rotation == 'u')) ) { return false; } if (this.ss.length > 1) { if ( (this.rds[this.ss[this.ss.length-2][0]] == rotation) && (this.ss[this.ss.length-1][1] < 1) ) { return false; } } this.ss.push([rotation, 0]); return true; }; |
These are okay. Now we have the real issue; collisions.. There are three collision types;
- Border Collision (Detecting collision when snake impact to walls..)
- Meal Collision (Detecting snake eating meals.)
- Self Collision (Detecting collision when snake impact to itself!
Border Collision
This is more simple than Self Collision and Meal Collision. We can implement this very simply;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
SnakeGame.Snake.prototype.borderCollision = function () { var t_Snake = this; if ( (t_Snake.ep.x <= 0) || (t_Snake.ep.x >= t_Snake.game.app.renderer.view.width) || (t_Snake.ep.y <= 0) || (t_Snake.ep.y >= t_Snake.game.app.renderer.view.height) ) { return true; } return false; }; |
Meal Collision
Now we need understand the snake is hungry; This is more difficult than Border Collision.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
SnakeGame.Snake.prototype.mealCollision = function (parameters) { var t_Snake = this; var collision = false; t_Snake.game.meals.forEach(function (m, mi) { var mx = m.x + t_Snake.length/2; var my = m.y + t_Snake.length/2; var dx = Math.abs(mx - t_Snake.ep.x); var dy = Math.abs(my - t_Snake.ep.y); if ( (dx <= (t_Snake.length)) && (dy <= (t_Snake.length)) ) { t_Snake.game.meals.splice(mi, 1); m.meal.clear(); t_Snake.game.app.stage.removeChild(m.meal); var ls = t_Snake.ss[0]; if (ls[1] <= 0) { t_Snake.ss.splice(0, 1); ls = t_Snake.ss[0]; } t_Snake.addition += 0.05; t_Snake.ss.unshift([ls[0], 5]); if (t_Snake.ss[0][0] == 'l') { t_Snake.x += t_Snake.length*5; } else if (t_Snake.ss[0][0] == 'r') { t_Snake.x -= t_Snake.length*5; } else if (t_Snake.ss[0][0] == 'u') { t_Snake.y += t_Snake.length*5; } else if (t_Snake.ss[0][0] == 'd') { t_Snake.y -= t_Snake.length*5; } t_Snake.points += t_Snake.length*5; collision = true; return false; } }); return collision; }; |
These are okay..and let’s make the the difficult!..
Self Collision
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
SnakeGame.Snake.prototype.selfCollision = function () { var t_Snake = this; var collision = false; var stx = this.x; var sty = this.y; var sbx = stx; var sby = sty; this.ss.slice(0, this.ss.length-2).forEach(function (s, i) { if (s[0] == 'l') { stx += (t_Snake.length * s[1]) * -1; } else if (s[0] == 'r') { stx += t_Snake.length * s[1]; } else if (s[0] == 'u') { sty += (t_Snake.length * s[1]) * -1; } else if (s[0] == 'd') { sty += t_Snake.length * s[1]; } var diff_x = parseInt(Math.abs(t_Snake.ep.x - stx)); var diff_y = parseInt(Math.abs(t_Snake.ep.y - sty)); if ((s[0] == 'u') || (s[0] == 'd')) { if (diff_x < (t_Snake.length/2)) { if (s[0] == 'u') { if ((t_Snake.ep.y >= sty) && (t_Snake.ep.y <= sby)) { collision = true; return false; } } else if (s[0] == 'd') { if ((t_Snake.ep.y >= sby) && (t_Snake.ep.y <= sty)) { collision = true; return false; } } } } else if ((s[0] == 'l') || (s[0] == 'r')) { if (diff_y < (t_Snake.length/2)) { if (s[0] == 'l') { if ((t_Snake.ep.x >= stx) && (t_Snake.ep.x <= sbx)) { collision = true; return false; } } else if (s[0] == 'r') { if ((t_Snake.ep.x >= sbx) && (t_Snake.ep.x <= stx)) { collision = true; return false; } } } } sbx = stx; sby = sty; }); return collision; }; |
Three collision types are ok. We can continue..
The Snake Step Method
The game needs a step() method. This is snake’s frame creation method.
Remember, we’ve already created a main frame creation method for SnakeGame.Game() class; SnakeGame.Game.step().
It was like such as;
1 2 3 4 5 6 7 8 |
SnakeGame.Game.prototype.step = function (parameters) { var t_Game = this; t_Game.meals.forEach(function (m, mi) { m.meal.clear(); m.meal.drawRect(m.x, m.y, t_Game.snake.length, t_Game.snake.length); }); }; |
Now we’re making a frame creation method for the snake;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
SnakeGame.Snake.prototype.step = function (parameters) { var t_Snake = this; t_Snake.snline.clear(); t_Snake.snline.x = t_Snake.x; t_Snake.snline.y = t_Snake.y; t_Snake.snline.moveTo(0, 0); t_Snake.snline.lineStyle(t_Snake.length, 0x157518, 1); var rx = 0; var ry = 0; t_Snake.ss.forEach(function (s, i) { if (s[0] == 'l') { rx += (t_Snake.length * s[1]) * -1; } else if (s[0] == 'r') { rx += t_Snake.length * s[1]; } else if (s[0] == 'u') { ry += (t_Snake.length * s[1]) * -1; } else if (s[0] == 'd') { ry += t_Snake.length * s[1]; } t_Snake.snline.lineTo(rx, ry); }); t_Snake.ep = { x: t_Snake.x + rx, y: t_Snake.y + ry }; t_Snake.d = t_Snake.ss[t_Snake.ss.length-1][0]; var a = t_Snake.addition*parameters.delta; var decr = function (i, d) { if (i > t_Snake.ss.length-1) { return; } var s0 = t_Snake.ss[i][1] - d; t_Snake.ss[i][1] = s0; var cd = t_Snake.length; if (s0 < 0) { cd *= d + s0 } else { cd *= d; } if (t_Snake.ss[i][0] == 'l') { t_Snake.x -= cd; } else if (t_Snake.ss[i][0] == 'r') { t_Snake.x += cd; } else if (t_Snake.ss[i][0] == 'u') { t_Snake.y -= cd; } else if (t_Snake.ss[i][0] == 'd') { t_Snake.y += cd; } if (t_Snake.ss[i][1] <= 0) { t_Snake.ss.splice(i, 1); } if (s0 < 0) { decr(i, s0*-1); } }; decr(0, a); t_Snake.ss[t_Snake.ss.length-1][1] += a; }; |
FPS Synchronization
We need sync FPS with our specified snake speed.
This method has using parameters.delta (0 – 1] variable. This method takes into calculating the parameters.delta variable.
We’ll get the delta from PIXI.ticker.Ticker() object and pass it to this method.
Exporting a Game Controller Class
We need a class for exporting a controller class; Game(). We’ll able to control the game like;
- Create new game
- Pause or resume controls
- Shortcuts binding
- Drawing screen
- Drawing game menus
We’re using Pixi.js‘s Ticker here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
var Game = function (parameters) { var t_Game = this; t_Game.parameters = parameters; t_Game.events = {}; t_Game.events.finish = function () {}; t_Game.events.begin = function () {}; t_Game.events.pause = function () {}; t_Game.events.continue = function () {}; t_Game.playing = false; t_Game.app = new PIXI.Application(800, 600, { view: t_Game.parameters.view }); t_Game.app.renderer.view.style.position = "fixed"; t_Game.app.renderer.view.style.display = "block"; t_Game.app.renderer.view.style.left = "0px"; t_Game.app.renderer.view.style.top = "0px"; var onResize = function (event) { t_Game.app.renderer.resize(window.innerWidth, window.innerHeight); }; onResize(); window.addEventListener('resize', onResize); t_Game.app.renderer.autoResize = true; t_Game.app.renderer.resize(window.innerWidth, window.innerHeight); var bg_texture = PIXI.Texture.fromImage('images/bg.png'); var bg_sprite = new PIXI.TilingSprite(bg_texture, t_Game.app.renderer.width, t_Game.app.renderer.height); var bgLayer = new PIXI.Graphics(); bgLayer.beginFill(0x000000, 0.75); bgLayer.drawRect(0, 0, t_Game.app.renderer.width, t_Game.app.renderer.height); t_Game.app.stage.addChild(bg_sprite); t_Game.app.stage.addChild(bgLayer); var style = new PIXI.TextStyle({ fontFamily: 'Arial', fontSize: 36, fill: '#157518', wordWrap: true, wordWrapWidth: 200 }); var snakeText = new PIXI.Text('snake', style); snakeText.x = 20; snakeText.y = 20; t_Game.app.stage.addChild(snakeText); var pointsText = new PIXI.Text('Points: 0', { fontFamily: 'Arial', fontSize: 13, fill: '#ffffff' }); pointsText.x = 20; pointsText.y = 60; t_Game.app.stage.addChild(pointsText); var fpsText = new PIXI.Text('FPS: 0', { fontFamily: 'Arial', fontSize: 13, fill: '#ffffff' }); fpsText.x = 20; fpsText.y = 80; t_Game.app.stage.addChild(fpsText); var infoText = new PIXI.Text('Shortcuts:\np: pause\nn: new game', { fontFamily: 'Arial', fontSize: 13, fill: '#ffffff' }); infoText.x = 20; infoText.y = 100; t_Game.app.stage.addChild(infoText); var oguzhan = new PIXI.Text('by Oğuzhan Eroğlu', { fontFamily: 'Arial', fontSize: 13, fill: '#ffffff' }); oguzhan.x = 125; oguzhan.y = 38; t_Game.app.stage.addChild(oguzhan); t_Game.newGame = function () { if (t_Game.game !== undefined) { t_Game.snake.snline.clear(); t_Game.game.meals.forEach(function (m, mi) { m.meal.clear(); }); } t_Game.game = new SnakeGame.Game({ app: t_Game.app }); t_Game.snake = new SnakeGame.Snake(); t_Game.game.setSnake(t_Game.snake); t_Game.snake.init(); var time = 0; t_Game.ticker = new PIXI.ticker.Ticker(); var then = Date.now; var now; t_Game.ticker.add(function (delta) { fpsText.setText('FPS: ' + parseInt(t_Game.ticker.FPS)); pointsText.setText('Points: ' + parseInt(t_Game.snake.points)); t_Game.game.placeMeals(); t_Game.game.step({delta: delta}); t_Game.snake.step({delta: delta}); t_Game.snake.mealCollision({delta: delta}); if (t_Game.snake.selfCollision() || t_Game.snake.borderCollision()) { t_Game.finish(); } }); }; t_Game.finish = function () { t_Game.playing = false; t_Game.ticker.stop(); t_Game.events.finish({ points: t_Game.snake.points }); }; t_Game.stop = function () { t_Game.playing = false; t_Game.ticker.stop(); }; t_Game.pause = function () { t_Game.playing = false; t_Game.ticker.stop(); t_Game.events.pause({ points: t_Game.snake.points }); }; t_Game.continue = function () { t_Game.play(); t_Game.events.continue(); }; t_Game.play = function () { t_Game.playing = true; t_Game.ticker.start(); t_Game.events.begin(); }; var handler = function (event) { if([32, 37, 38, 39, 40].indexOf(event.keyCode) > -1) { event.preventDefault(); } if (event.keyCode == 37) { // LEFT t_Game.snake.rotate('l'); } else if (event.keyCode == 39) { // RIGHT t_Game.snake.rotate('r'); } else if (event.keyCode == 38) { // UP t_Game.snake.rotate('u'); } else if (event.keyCode == 40) { // DOWN t_Game.snake.rotate('d'); } else if (event.keyCode == 13) { // ENTER if (!t_Game.playing) { t_Game.newGame(); t_Game.play(); } } else if (event.keyCode == 80) { // P if (t_Game.playing) { t_Game.pause(); } else { t_Game.continue(); } } else if (event.keyCode == 78) { // N t_Game.stop(); t_Game.newGame(); t_Game.play(); } }; window.addEventListener('keydown', handler); if (parent && inIframe()) { parent.window.addEventListener('keydown', handler); } t_Game.app.renderer.view.addEventListener('touchstart', function (event) { if (t_Game.snake.d == 'l') { t_Game.snake.rotate('u'); } else if (t_Game.snake.d == 'r') { t_Game.snake.rotate('d'); } else if (t_Game.snake.d == 'd') { t_Game.snake.rotate('l'); } else if (t_Game.snake.d == 'u') { t_Game.snake.rotate('r'); } }, false); }; |
All game controls is here. We’ll export this game controller class and use it.
Some Helpers
1 2 3 4 5 6 7 8 9 10 11 |
function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function inIframe() { try { return window.self !== window.top; } catch (e) { return true; } } |
main.js that using Game Controller
Now we’re creating a main.js with using Game() controller class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
var game; $(document).ready(function (event) { var $gameOver = $('.gameOver'); var $gameOver_startButton = $gameOver.find('.gameOver_startButton'); var $gameOver_points = $gameOver.find('.gameMenu_box_points_number'); var $pause = $('.pause'); var $pause_continueButton = $pause.find('.pause_continueButton'); var $pause_points = $pause.find('.gameMenu_box_points_number'); game = new Game({ view: $('.gameView').get(0) }); game.events.finish = function (parameters) { $gameOver_points.html(parameters.points); $gameOver.stop().fadeIn(250); }; game.events.begin = function () { $pause.stop().fadeOut(250); $gameOver.stop().fadeOut(250); }; game.events.pause = function (parameters) { $pause_points.html(parameters.points); $pause.stop().fadeIn(250); }; game.events.continue = function () { $pause.stop().fadeOut(250); }; $gameOver_startButton.on('click', function (event) { game.newGame(); game.play(); }); $pause_continueButton.on('click', function (event) { game.continue(); }); game.newGame(); game.play(); }); |
We’ve already set keyboard shortcuts in Game() controller class.. And make emitting some events from there; finish , begin , pause , coninue ..
A Simple HTML for Game Screen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name=description content="Snake game."> <meta name=viewport content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="css/game.css" /> <script type="text/javascript" src="js/jquery-3.1.1.min.js"></script> <script type="text/javascript" src="js/pixi.min.js"></script> <script type="text/javascript" src="js/game.js"></script> <script type="text/javascript" src="js/main.js"></script> <title>Snake - Game</title> </head> <body> <canvas class="gameView"> Your browser does not support canvas element. </canvas> <div class="gameMenu gameOver"> <div class="table"> <div class="table_td"> <div class="gameMenu_box"> <div class="gameMenu_box_title"> Game Over </div> <div class="gameMenu_box_content"> <div class="gameMenu_box_points"> <span class="gameMenu_box_points_label"> Total Points: </span> <span class="gameMenu_box_points_number">0</span> </div> <div class="clear"></div> <div class="gameOver_startButton btn"> Play Again </div> </div> </div> </div> </div> </div> <div class="gameMenu pause"> <div class="table"> <div class="table_td"> <div class="gameMenu_box"> <div class="gameMenu_box_title"> Game Paused </div> <div class="gameMenu_box_content"> <div class="gameMenu_box_points"> <span class="gameMenu_box_points_label"> Total Points: </span> <span class="gameMenu_box_points_number">0</span> </div> <div class="clear"></div> <div class="pause_continueButton btn"> Continue </div> </div> </div> </div> </div> </div> </body> </html> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
* { margin: 0px; padding: 0px; } body { color: #292929; text-align: left; line-height: 100%; /*background-image: url('../images/bg.png'); background-repeat: repeat;*/ font-family: 'Arial'; position: relative; } h1, h2, h3, h4, h5, h6 { line-height: inherit; font-weight: inherit; font-size: inherit; } textarea { font-family: Tahoma, Verdana, Arial, sans-serif; } a, a:visited { text-decoration: none; cursor: pointer; } a:hover { text-decoration: none; } .clear { clear: both; } .left { float: left; } .right { float: right; } .center { margin-left: auto; margin-right: auto; } .content_center { text-align: center; } .content_left { text-align: left; } .content_right { text-align: right; } img { border: 0px; } .table { display: table; width: 100%; height: 100%; } .table_td { display: table-cell; vertical-align: middle; } .main_width { width: 1280px; } .gameView { z-index: 5000; } .gameMenu { position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; background: rgba(0,0,0,0.1); z-index: 5000; text-align: center; user-select: none; cursor: default; display: none; } .gameMenu_box { display: inline-block; padding: 25px; background: rgba(255,255,255,0.25); border-radius: 1px; box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25); text-align: center; } .gameMenu_box_title { font-family: 'Arial'; font-weight: bold; font-size: 20px; } .gameMenu_box_content { margin-top: 10px; font-size: 14px; } .gameMenu_box_points { margin-top: 10px; margin-bottom: 10px; padding: 10px; border-radius: 1px; display: inline-block; box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15); background: rgba(255,255,255,0.3); } .gameMenu_box_points_label { font-weight: bold; } .gameMenu_box_points_number { } .btn { padding: 10px; background: #157518; color: white; cursor: pointer; transition: all 250ms; display: inline-block; box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15); } .btn:hover { background-color: rgba(21, 117, 24, 0.6); } |
index.html
We’ll include game screen (game.html) with iframe in here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name=description content="Snake game."> <meta name=viewport content="width=device-width; initial-scale=1; maximum-scale=1.0; user-scalable=0;"> <link href="https://fonts.googleapis.com/css?family=Londrina+Solid|VT323" rel="stylesheet"> <script type="text/javascript" src="js/jquery-3.1.1.min.js"></script> <title>Snake - Game</title> <style type="text/css"> * { margin: 0px; padding: 0px; } body { text-align: center; background: #245425; color: #fafafa; } .game { margin-top: 25px; display: inline-block; border: 10px solid #378239; border-radius: 10px; box-shadow: 0px 0px 15px 0px rgba(5, 53, 6, 0.4); } .gameIframe { border: 0px; display: block; margin: auto; } .logo { font-family: 'Londrina Solid', cursive; font-size: 50px; margin-top: 25px; text-shadow: 0px 0px 10px rgba(5, 53, 6, 0.56); } .description { font-family: 'Londrina Solid', cursive; font-size: 25px; text-shadow: 0px 0px 10px rgba(5, 53, 6, 0.56); } .link { font-family: 'VT323', monospace; font-size: 20px; margin-top: 10px; display: inline-block; border: 1px solid #378239; background: #306b32; border-radius: 2px; padding: 5px 10px; } .a, .a:visited { color: #fafafa; transition: opacity 250ms; text-decoration: none; } .a:hover { opacity: 0.8; } .footer { font-family: 'Arial'; font-size: 13px; margin-top: 25px; } .footer .a { color: #6ce06f; } @media screen and (max-width: 450px) { .logo { font-size: 30px; margin-top: 15px; } .description { font-size: 20px; } .link { font-size: 15px; } } </style> <script type="text/javascript"> $(document).ready(function () { var gameIframe = document.getElementById('gameIframe'); var w = window.innerWidth; var h = window.innerHeight; if (h < 800) { gameIframe.width = 500; gameIframe.height = 300; } if (w <= 770) { gameIframe.width = 600; } if (w <= 600) { gameIframe.width = 275; } }); </script> </head> <body> <div class="logo"> snake </div> <div class="description"> HTML5 SNAKE GAME WITH PIXI.JS </div> <div class="clear"></div> <div class="link"> <a class="a" href="http://oguzhaneroglu.com/games/snake/" title="HTML5 Snake Game with pixi.js">http://oguzhaneroglu.com/games/snake/</a> </div> <div class="clear"></div> <div class="game"> <iframe src="game.html" id="gameIframe" class="gameIframe" width="800" height="600"></iframe> </div> <div class="footer"> Licensed under <a class="a" href="https://opensource.org/licenses/MIT" title="MIT License">MIT</a>. Copyright © 2017, <a class="a" href="http://oguzhaneroglu.com/" title="Oğuzhan Eroğlu, Software Engineer">Oğuzhan Eroğlu</a>. </div> <a href="https://github.com/rohanrhu/snake" target="_blank"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"></a> </body> </html> |
That’s all.. We creted a HTML5 Snake Game.
You can download source code from Github and play snake.