├── CNAME ├── README.md ├── css └── style.css ├── images ├── face0.gif ├── face1.png ├── face2.png ├── face3.png ├── face4.png ├── face5.png ├── face6.png └── snake_ladder_layer.gif ├── index.html └── js ├── gamePlay.js ├── jquery.js └── saapSeedi.js /CNAME: -------------------------------------------------------------------------------- 1 | saapseedi.com 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | online-snake-and-ladder-game-html5-canvas 2 | ========================================= 3 | 4 | Snakes and Ladders is an ancient Indian board game regarded today as a worldwide classic. It is played between two or more players on a gameboard having numbered, gridded squares. A number of ladders and snakes are pictured on the board, each connecting two specific board squares. The object of the game is to navigate one's game piece, according to die rolls, from the start to the finish, helped or hindered by ladders and snakes respectively. I've developed this snakes and ladders game in javascript using html5 canvas so that it can be played online on web browsers 5 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | canvas { 2 | border: 5px solid #ffffff; 3 | position: absolute; 4 | left: 0px; 5 | top: 0px; 6 | } 7 | 8 | #diceName { 9 | font-size:50px; 10 | font-weight: bold; 11 | } 12 | 13 | #diceControl { 14 | cursor: pointer; 15 | } -------------------------------------------------------------------------------- /images/face0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalchawla/online-snake-and-ladder-game-html5-canvas/fd24374f62cc35ac4713af48073388a678e822bf/images/face0.gif -------------------------------------------------------------------------------- /images/face1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalchawla/online-snake-and-ladder-game-html5-canvas/fd24374f62cc35ac4713af48073388a678e822bf/images/face1.png -------------------------------------------------------------------------------- /images/face2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalchawla/online-snake-and-ladder-game-html5-canvas/fd24374f62cc35ac4713af48073388a678e822bf/images/face2.png -------------------------------------------------------------------------------- /images/face3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalchawla/online-snake-and-ladder-game-html5-canvas/fd24374f62cc35ac4713af48073388a678e822bf/images/face3.png -------------------------------------------------------------------------------- /images/face4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalchawla/online-snake-and-ladder-game-html5-canvas/fd24374f62cc35ac4713af48073388a678e822bf/images/face4.png -------------------------------------------------------------------------------- /images/face5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalchawla/online-snake-and-ladder-game-html5-canvas/fd24374f62cc35ac4713af48073388a678e822bf/images/face5.png -------------------------------------------------------------------------------- /images/face6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalchawla/online-snake-and-ladder-game-html5-canvas/fd24374f62cc35ac4713af48073388a678e822bf/images/face6.png -------------------------------------------------------------------------------- /images/snake_ladder_layer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalchawla/online-snake-and-ladder-game-html5-canvas/fd24374f62cc35ac4713af48073388a678e822bf/images/snake_ladder_layer.gif -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Saap Seedi - Online Snake and Ladder Game 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 |

14 | 15 |
16 | 17 | 18 | 19 | 20 | Fork me on GitHub 21 |
22 | Follow 23 | 24 |
25 | 26 | -------------------------------------------------------------------------------- /js/gamePlay.js: -------------------------------------------------------------------------------- 1 | saapSeedi.init(); 2 | var processing = false; 3 | 4 | function updateDiceName() { 5 | var playerName = "", playerColor = "#000000"; 6 | if (saapSeedi.players.length) { 7 | playerName = saapSeedi.players[saapSeedi.state.turn].name; 8 | playerColor = saapSeedi.players[saapSeedi.state.turn].color; 9 | } 10 | $("#diceName").attr({ 11 | "style": "color: " + playerColor 12 | }).hide().html(playerName).fadeIn(2000); 13 | } 14 | 15 | function movePlayer() { 16 | processing = true; 17 | 18 | if (!saapSeedi.players.length) { 19 | processing = false; 20 | return false; 21 | } 22 | 23 | var player = saapSeedi.players[saapSeedi.state.turn]; 24 | 25 | var random = Math.floor((Math.random() * 6) + 1); 26 | 27 | //Roll dice 28 | saapSeedi.rollDice(); 29 | 30 | //Show dice after 1 to 3 seconds 31 | setTimeout(function() { 32 | saapSeedi.showDice(random); 33 | 34 | //Fire move request after 1 second so that player can shift eyes from dice to board 35 | setTimeout(function() { 36 | player.position == 1 ? player.move(player.position + random - 1, undefined, random == 6, updateDiceName) : player.move(player.position + random, undefined, random == 6, updateDiceName); 37 | if (random == 6) { 38 | //Show message after the piece reaches destination 39 | setTimeout(function() { 40 | alert("You get another bonus chance."); 41 | }, saapSeedi.config.moveSpeed * 6 + 100); 42 | } 43 | 44 | processing = false; 45 | }, 1000); 46 | }, Math.floor((Math.random() * 3000) + 1000)); 47 | } 48 | 49 | $("#addPlayer").on("click", function(e) { 50 | var playerName = $("#playerName").val(); 51 | var player = saapSeedi.addPlayer(playerName); 52 | 53 | if (player) { 54 | alert("Player '" + playerName + "' successfully added."); 55 | $("#playerName").val(""); 56 | } 57 | 58 | if (saapSeedi.config.maxPlayers == saapSeedi.state.playerCount) { 59 | $("#playerName").hide(); 60 | $("#addPlayer").hide(); 61 | } 62 | 63 | updateDiceName(); 64 | }); 65 | 66 | $("#diceControl").on("click", function(e) { 67 | if (processing) { 68 | return false; 69 | } 70 | movePlayer(); 71 | }); 72 | 73 | if (window.innerHeight > window.innerWidth) { 74 | $("#controls").css({top: window.innerWidth + 20,position: 'absolute'}); 75 | } else { 76 | $("#controls").css({left: window.innerHeight + 20,position: 'absolute'}); 77 | } 78 | -------------------------------------------------------------------------------- /js/saapSeedi.js: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | 3 | Looks like you have good hands in Javascript, We are hiring Javascript Hackers at 4 | AdPushup (New Delhi, India Office). Check out http://careers.adpushup.com 5 | 6 | *********************************************************************************/ 7 | 8 | (function(w, d) { 9 | function board(width, height) { 10 | this.boardBg = null; 11 | this.boardFg = null; 12 | this.width = width; 13 | this.height = height; 14 | this.config = { 15 | maxPlayers: 4, 16 | moveSpeed: 150, 17 | runSpeed: 15, 18 | colors: ["red", "blue", "green", "black"], 19 | snakeLadderLayer: "images/snake_ladder_layer.gif", 20 | snakes: [{s: 36,e: 2}, {s: 46,e: 29}, {s: 79,e: 42}, {s: 93,e: 53}], 21 | ladders: [{s: 8,e: 49}, {s: 22,e: 57}, {s: 54,e: 85}, {s: 61,e: 98}] 22 | }; 23 | this.state = { 24 | playerCount: 0, 25 | turn: 0 26 | }; 27 | this.blocks = []; 28 | this.players = []; 29 | } 30 | 31 | var player = function(board, id, name, color) { 32 | this.board = board; 33 | this.id = id; 34 | this.name = name; 35 | this.color = color; 36 | this.position = 1; 37 | } 38 | 39 | var b = board.prototype; 40 | var p = player.prototype; 41 | 42 | p.placeGoti = function(position) { 43 | var playerId = this.id; 44 | var board = this.board; 45 | var blockX = board.blocks[position].x; 46 | var blockY = board.blocks[position].y; 47 | var blockW = board.width / 10; 48 | var blockH = board.height / 10; 49 | var gotiR = board.height / 60; 50 | var gotiX = blockX + (blockW / 10) + gotiR + (playerId * gotiR); 51 | var gotiY = blockY + (0.9 * blockH) - gotiR; 52 | var boardFg = board.boardFg; 53 | boardFg.beginPath(); 54 | boardFg.arc(gotiX, gotiY, gotiR, 0, 2 * Math.PI, false); 55 | boardFg.fillStyle = this.color; 56 | boardFg.fill(); 57 | boardFg.lineWidth = gotiR / 3; 58 | boardFg.strokeStyle = '#ffffff'; 59 | boardFg.stroke(); 60 | } 61 | 62 | p.removeGoti = function() { 63 | var board = this.board; 64 | var players = board.players; 65 | var playerId = this.id; 66 | var position = this.position; 67 | 68 | var blockX = board.blocks[position].x; 69 | var blockY = board.blocks[position].y; 70 | var blockW = board.width / 10; 71 | var blockH = board.height / 10; 72 | var boardFg = board.boardFg; 73 | boardFg.clearRect(blockX, blockY, blockW, blockH); 74 | 75 | var player_id; 76 | for (player_id in players) { 77 | if (players[player_id]['position'] == position && player_id != playerId) { 78 | players[player_id].placeGoti(position); 79 | } 80 | } 81 | } 82 | 83 | p.move = function(position, speed, isSpecial, callback) { 84 | var player = this; 85 | var board = player.board; 86 | var players = board.players; 87 | 88 | if (typeof isSpecial == "undefined" && player.id !== board.state.turn) { 89 | board.log("It's " + players[board.state.turn].name + "'s turn."); 90 | return false; 91 | } 92 | 93 | if (position < 1) { 94 | board.log("Invalid move."); 95 | return false; 96 | } 97 | 98 | if (position > 100) { 99 | if (!isSpecial) { 100 | board.nextPlayer(); 101 | } 102 | 103 | if (typeof callback == 'function') { 104 | callback.call(w); 105 | } 106 | 107 | return true; 108 | } 109 | 110 | if (player.position < position) { 111 | player.removeGoti(); 112 | player.position++; 113 | player.placeGoti(player.position); 114 | } else if (player.position > position) { 115 | player.removeGoti(); 116 | player.position--; 117 | player.placeGoti(player.position); 118 | } else { 119 | player.removeGoti(); 120 | player.placeGoti(player.position); 121 | } 122 | 123 | speed = typeof speed !== 'undefined' ? speed : board.config.moveSpeed; 124 | 125 | if (player.position != position) { 126 | window.setTimeout(function() { 127 | player.move(position, speed, isSpecial, callback); 128 | }, speed); 129 | } else { 130 | //Check snake or ladder 131 | var check = board.isClear(player.position); 132 | if (check) { 133 | setTimeout(function() { 134 | player.move(check, board.config.runSpeed, isSpecial, callback); 135 | }, 1000); 136 | } else { 137 | //Check kill 138 | if (player.position != 1) { 139 | var players_id; 140 | for (players_id in players) { 141 | if (players[players_id]['position'] == player.position && players_id != player.id) { 142 | board.log(player.name + " killed " + players[players_id]['name'] + "."); 143 | setTimeout(function() { 144 | players[players_id].move(1, board.config.runSpeed, true, callback); 145 | }, 1000); 146 | break; 147 | } 148 | } 149 | } 150 | 151 | if (!isSpecial) { 152 | board.nextPlayer(); 153 | } 154 | //Check win 155 | if (player.position == 100) { 156 | board.log("Congrats " + player.name + ", You just won the game."); 157 | players.splice(player.id, 1); 158 | board.state.playerCount--; 159 | isSpecial = false; 160 | } 161 | 162 | if (typeof callback == 'function') { 163 | callback.call(w); 164 | } 165 | 166 | return true; 167 | } 168 | } 169 | } 170 | 171 | b.init = function() { 172 | if (window.innerHeight > window.innerWidth) { 173 | this.width = this.height = window.innerWidth - 10; 174 | } 175 | this.createBoard(); 176 | 177 | var img = new Image('images/face0.gif'); 178 | img = new Image('images/face1.png'); 179 | img = new Image('images/face2.png'); 180 | img = new Image('images/face3.png'); 181 | img = new Image('images/face4.png'); 182 | img = new Image('images/face5.png'); 183 | img = new Image('images/face6.png'); 184 | } 185 | 186 | b.createBoard = function() { 187 | var canvas = document.createElement('canvas'); 188 | canvas.height = this.height; 189 | canvas.width = this.width; 190 | canvas.style.zIndex = 1; 191 | document.body.appendChild(canvas); 192 | var boardBg = this.boardBg = canvas.getContext('2d'); 193 | 194 | canvas = document.createElement('canvas'); 195 | canvas.height = this.height; 196 | canvas.width = this.width; 197 | canvas.style.zIndex = 2; 198 | document.body.appendChild(canvas); 199 | var boardFg = this.boardFg = canvas.getContext('2d'); 200 | 201 | canvas = document.createElement('canvas'); 202 | canvas.height = this.height; 203 | canvas.width = this.width; 204 | canvas.style.zIndex = 3; 205 | var snakeLadderLayer = new Image(); 206 | snakeLadderLayer.src = this.config.snakeLadderLayer; 207 | snakeLadderLayer.onload = function() { 208 | canvas.getContext('2d').drawImage(snakeLadderLayer, 0, 0, canvas.width, canvas.height); 209 | document.body.appendChild(canvas); 210 | } 211 | 212 | var a = 100, b = 91, w = this.width / 10, h = this.height / 10, y = -h, x, color, i; 213 | boardBg.font = w / 4 + 'px Georgia'; 214 | while (a > 0) { 215 | x = 0; 216 | y += h; 217 | for (i = a; i >= b; i--) { 218 | color = '#' + (Math.random() * 0xFFFFFF << 0).toString(16); 219 | boardBg.fillStyle = color 220 | boardBg.fillRect(x, y, w, h); 221 | boardBg.fillStyle = '#ffffff'; 222 | boardBg.fillText(i, x + (w / 10), y + (h / 5)); 223 | this.blocks[i] = { 224 | x: x, 225 | y: y, 226 | color: color 227 | }; 228 | x += w; 229 | } 230 | x = 0; 231 | y += h; 232 | for (i = b - 10; i <= a - 10; i++) { 233 | color = '#' + (Math.random() * 0xFFFFFF << 0).toString(16); 234 | boardBg.fillStyle = color 235 | boardBg.fillRect(x, y, w, h); 236 | boardBg.fillStyle = '#ffffff'; 237 | boardBg.fillText(i, x + (w / 10), y + (h / 5)); 238 | this.blocks[i] = { 239 | x: x, 240 | y: y, 241 | color: color 242 | }; 243 | x += w; 244 | } 245 | a = a - 20; 246 | b = b - 20; 247 | } 248 | } 249 | 250 | b.addPlayer = function(name) { 251 | if (!name) { 252 | this.log('Please specify name of the player.'); 253 | return false; 254 | } 255 | 256 | var players = this.players, player_id; 257 | for (player_id in players) { 258 | if (players[player_id]['name'] == name) { 259 | this.log(name + " is already playing, Can't you specify some other name :/"); 260 | return false; 261 | } 262 | } 263 | 264 | var id = players.length; 265 | if (id >= this.config.maxPlayers) { 266 | this.log("Maximum players limit reached, Can't add more players"); 267 | return false; 268 | } 269 | 270 | var player = new this.player(this, id, name, this.config.colors[id]); 271 | player.placeGoti(1); 272 | players.push(player); 273 | this.state.playerCount++; 274 | return player; 275 | } 276 | 277 | b.nextPlayer = function() { 278 | if (this.state.turn + 1 == this.state.playerCount) { 279 | this.state.turn = 0; 280 | } else { 281 | this.state.turn++; 282 | } 283 | } 284 | 285 | b.isClear = function(position) { 286 | var snakes = this.config.snakes; 287 | for (var key in snakes) { 288 | if (snakes[key].s == position) { 289 | return snakes[key].e; 290 | } 291 | } 292 | 293 | var ladders = this.config.ladders; 294 | for (var key in ladders) { 295 | if (ladders[key].s == position) { 296 | return ladders[key].e; 297 | } 298 | 299 | } 300 | return false; 301 | } 302 | 303 | b.rollDice = function() { 304 | var dice = document.getElementById('dice'); 305 | dice.src = 'images/face0.gif'; 306 | } 307 | 308 | b.showDice = function(value) { 309 | value = parseInt(value); 310 | if (isNaN(value) || value < 1 || value > 6) { 311 | this.log("Invalid value."); 312 | return false; 313 | } 314 | var dice = document.getElementById('dice'); 315 | dice.src = 'images/face' + value + '.png'; 316 | } 317 | 318 | b.log = function(message) { 319 | alert(message); 320 | //console.log(message); 321 | } 322 | 323 | b.player = player; 324 | w.saapSeedi = new board(w.innerHeight - 10, w.innerHeight - 10); 325 | })(window, document); --------------------------------------------------------------------------------