ゲームクリア後に原画を3秒だけ表示するようにしてみました。
3秒経過後は、ポップアップを表示します。
PCのブラウザ(Firefox)で表示するとこんな感じ。
右の画像をクリックすると実際のゲームページを開きます。
また、画像を5つ増やしました。以下の10個からランダム選択となります。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>15パズル</title>
<meta name="viewport" content="width=600">
<link rel="stylesheet" type="text/css" href="../css/15-puzzle.css">
<script type="text/javascript" src="../js/15-puzzle101.js">
</script>
</head>
<body onload="init()">
<h1>15 PUZZLE</h1>
<canvas id="gameCanvas" width="600" height="600"></canvas>
</body>
</html>
// 各種設定
var PICTURES = ["nobana.jpg", "risu.jpg", "matterhorn.jpg", "beach.jpg", "foods.jpg","Blue_Moon.jpg","golden_gate_bridge.jpg","orgel.jpg","rose.jpg","sweets.jpg"];
var PICTURE_URL = "nobana.jpg"; // 画像ファイルのURL
var BLOCK_W = 150; // ブロックの幅
var BLOCK_H = 150; // ブロックの高さ
var ROW_COUNT = 4; // 列を何枚に切るか
var COL_COUNT = 4; // 行を何枚に切るか
var NUM_BLOCKS = ROW_COUNT * COL_COUNT;
// 上下左右の相対座標を定義したもの
var UDLR = [[0,-1],[0,1],[-1,0],[1,0]];
// ゲーム全体で使う変数
var context, image; // 描画用
var blocks = []; // 各ブロックを管理する配列変数
var isLock; // マウス操作をロックするかどうか
// 初期化処理
function init() {
// 描画コンテキストの取得
var canvas = document.getElementById("gameCanvas");
if (!canvas.getContext) {
alert("Canvasをサポートしていません。");
return;
}
context = canvas.getContext("2d");
// マウスイベントの設定
canvas.onmousedown = mouseHandler;
// 画像を選択
selectImage();
};
// 画像をランダムに選択
function selectImage() {
r = Math.floor(Math.random() * PICTURES.length);
PICTURE_URL = PICTURES[r];
// メイン画像を読み出す
image = new Image();
image.src = PICTURE_URL;
image.onload = initGame; // 読み込んだらゲームを初期化
}
// ゲームの初期化
function initGame() {
isLock = true; // ユーザ操作をロックする
// パズルのブロックを作成する
for (var i = 0; i < NUM_BLOCKS; i++) {
blocks[i] = i;
}
// 末尾(右下)を空きブロックとする
blocks[NUM_BLOCKS -1] = -1;
drawPuzzle(); // 見本を表示する
// 1秒後にシャッフルを開始する
setTimeout(shufflePuzzle,1000);
}
// パズルの各ピースをシャッフルする
function shufflePuzzle() {
var scount = 160; // シャッフルする回数を指定
var blank = NUM_BLOCKS - 1; // 空きブロック位置
// 一回のみシャッフルを行う関数
var shuffle = function () {
scount--;
if (scount <= 0) {
isLock = false; // ゲーム開始
return;
}
var r, px, py, no;
while (1) {
r = Math.floor(Math.random() * UDLR.length);
px = getCol(blank) + UDLR[r][0];
py = getRow(blank) + UDLR[r][1];
if (px < 0 || px >= COL_COUNT) continue;
if (py < 0 || py >= ROW_COUNT) continue;
no = getIndex(px, py);
break;
}
blocks[blank] = blocks[no]
blocks[no] = -1;
blank = no;
drawPuzzle();
setTimeout(shuffle, 10);
};
shuffle();
}
// パズルの画面を描画する
function drawPuzzle() {
for (var i = 0; i < NUM_BLOCKS; i++) {
// 描画先座標を計算
var dx = (i % COL_COUNT) * BLOCK_W;
var dy = Math.floor(i / COL_COUNT) * BLOCK_H;
// 描画元座標を計算
var no = blocks[i];
if (no < 0) { // 空きブロック
context.fillStyle = "#0000FF";
context.fillRect(dx, dy, BLOCK_W, BLOCK_H);
} else {
var sx = (no % COL_COUNT) * BLOCK_W;
var sy = Math.floor(no / COL_COUNT) * BLOCK_H;
// 画像の一部を切り取って描画
context.drawImage(image, sx, sy, BLOCK_W, BLOCK_H, dx, dy, BLOCK_W, BLOCK_H);
}
// 描画の枠を表示
context.beginPath();
context.strokeStyle = "white";
context.lineWidth = 3;
context.rect(dx, dy, BLOCK_W, BLOCK_H);
context.stroke();
context.closePath();
// ブロック番号を描画する
context.fillStyle = "rgba(255, 255, 255, 0.8)";
context.font = "bold 48px Arial";
var cx = dx + (BLOCK_W - 40) / 2;
var cy = dy + BLOCK_H /2;
context.fillText((no+1), cx, cy);
context.strokeStyle = "black";
context.strokeText((no+1), cx, cy);
}
}
// マウスで移動先をクリックした時の処理
function mouseHandler(t) {
if (isLock) return;
// タッチ座標の取得
var px = t.offsetX, py = t.offsetY;
if (px == undefined) { // FireFox対策
var p = t.currentTarget;
px = t.layerX - p.offsetLeft;
py = t.layerY - p.offsetTop;
}
// 何番目のピースを動かしたいのか計算する
var px2 = Math.floor(px / BLOCK_W);
var py2 = Math.floor(py / BLOCK_H);
var no = getIndex(px2, py2);
// 空白ブロックなら動かせない
if (blocks[no] == -1) return;
// 上下左右に動かせるブロックがあるか確認
for (var i = 0; i < UDLR.length; i++) {
var pt = UDLR[i];
var xx = px2 + pt[0];
var yy = py2 + pt[1];
var no = getIndex(xx, yy);
if (xx < 0 || xx >= COL_COUNT) continue;
if (yy < 0 || yy >= ROW_COUNT) continue;
if (blocks[no] == -1) { // 移動可能か
blocks[no] = blocks[getIndex(px2,py2)];
blocks[getIndex(px2,py2)] = -1;
drawPuzzle();
checkClear();
break;
}
}
}
// クリアしたかどうかチェックする
function checkClear() {
var flag = true;
for (var i = 0; i < (NUM_BLOCKS -1); i++) {
if (blocks[i] != i) { flag = false; break; }
}
if (flag) {
context.drawImage(image, 0, 0); // 元画像を描画する
setTimeout('msgdsp()', 3000); //3秒後にゲームクリア表示
}
}
function msgdsp() {
alert("ゲームクリアしました!");
selectImage(); // 再度ゲームを実行
}
// 列と行からブロック番号を調べる関数
function getIndex(col, row) {
return row * COL_COUNT + col;
}
function getCol(no) { return no % COL_COUNT; }
function getRow(no) {
return Math.floor(no / COL_COUNT);
}
* {
padding:0;
margin:0;
text-align:center;
}
h1 {
background-color:blue;
color:white;
font-size:20px;
padding:4px;
}