タイルを動かして、1-15の順番に並べるゲームで、各数字に割り当てるx座標y座標をMathfloorのwidth,heightで割って、配列しています。var moveCountの数字を動かすことによって、ゲームの難易度を変更します。
reference
clientX Property:returns the horizontal coordinate (according to the client area) of the mouse pointer when a mouse event was triggered.The client area is the current window.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>15puzzle</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
</style>
</head>
<body>
<canvas id="stage" width="280" height="280">
Canvas not supported ...
</canvas>
<script>
(function(){
'use strict';
var canvas = document.getElementById('stage');
var context;
var image;
var IMAGE_URL = '15puzzle.png';
var tiles = [];
var ROW_COUNT = 4;
var COL_COUNT = 4;
var PIC_WIDTH = 280;
var PIC_HEIGHT = 280;
var TILE_WIDTH = PIC_WIDTH / COL_COUNT;
var TILE_HEIGHT = PIC_HEIGHT / ROW_COUNT;
var UDLR = [
[ 0, -1],
[ 0, 1],
[ -1, 0],
[ 1, 0],
];
var moveCount = 3;
function initTiles(){
var row, col;
for (row = 0; row < ROW_COUNT; row++){
tiles[row] = [];
for (col = 0; col < COL_COUNT; col++){
tiles[row][col] = row * COL_COUNT + col;
}
}
tiles[ROW_COUNT - 1][COL_COUNT - 1] = -1;
}
function drawPuzzle(){
var row, col;
var sx, sy;
var dx, dy;
for (row = 0; row < ROW_COUNT; row++){
for (col = 0; col < COL_COUNT; col++){
dx = col * TILE_WIDTH;
dy = row * TILE_HEIGHT;
if (tiles[row][col] === -1){
context.fillStyle = '#eeeeee';
context.fillRect(dx, dy, TILE_WIDTH, TILE_HEIGHT);
}else {
sx = (tiles[row][col] % COL_COUNT) * TILE_WIDTH;
sy = Math.floor((tiles[row][col] / ROW_COUNT)) * TILE_HEIGHT;
context.drawImage(image, sx, sy, TILE_WIDTH, TILE_HEIGHT, dx, dy, TILE_WIDTH, TILE_HEIGHT);
}
}
}
/*context.drawImage(image, 0, 0);*/
}
function checkResult(){
var row, col;
for (row = 0; row < ROW_COUNT; row++){
for (col = 0; col < COL_COUNT; col++){
if (row === ROW_COUNT -1 && col === COL_COUNT -1){
return true;
}
if (tiles[row][col] !== row * COL_COUNT + col){
return false;
}
}
}
}
function moveBlank(count){
var blankRow, blankCol;
var targetPosition;
var targetRow, targetCol;
blankRow = ROW_COUNT -1;
blankCol = COL_COUNT -1;
while(true){
targetPosition = Math.floor(Math.random() * UDLR.length);
targetRow = blankRow + UDLR[targetPosition][1];
targetCol = blankCol + UDLR[targetPosition][0];
if(targetRow < 0 || targetRow >= ROW_COUNT){
continue;
}
if(targetCol < 0 || targetCol >= COL_COUNT){
continue;
}
tiles[blankRow][blankCol] = tiles[targetRow][targetCol];
tiles[targetRow][targetCol] = -1;
blankRow = targetRow;
blankCol = targetCol;
if(!--count){
break;
}
}
}
if (!canvas.getContext){
alert('canvas not supported ...');
return
}
context = canvas.getContext('2d');
image = document.createElement('img');
image.src = IMAGE_URL;
image.addEventListener('load', function(){
initTiles();
moveBlank(moveCount);
drawPuzzle();
});
canvas.addEventListener('click', function(e){
var x, y;
var rect;
var row, col;
var i;
var targetRow, targetCol;
rect = e.target.getBoundingClientRect();
x = e.clientX - rect.left;
y = e.clientY - rect.top;
row = Math.floor(y / TILE_HEIGHT);
col = Math.floor(x / TILE_WIDTH);
if (tiles[row][col] === -1){
return;
}
for (i = 0; i < UDLR.length; i++) {
targetRow = row + UDLR[i][1];
targetCol = col + UDLR[i][0];
if (targetRow < 0 || targetRow >= ROW_COUNT) {
continue;
}
if (targetCol < 0 || targetCol >= COL_COUNT) {
continue;
}
if (tiles[targetRow][targetCol] === -1) {
tiles[targetRow][targetCol] = tiles[row][col];
tiles[row][col] = -1;
drawPuzzle();
if (checkResult()){
alert('Game Clear!')
}
break;
}
}
});
})();
</script>
</body>
</html>