こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

HTML5,JavaScriptのアプリについて

現在Monacaでスマホのアプリを作っております
3×3のパズルを作ったのですがわからない点があるので教えてください
コードは
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=3.0">
<script src="plugins/plugin-loader.js"></script>
<style> *{ margin:0; padding:0; position: absolute;}
#title {
background-color: blue; color: white;
padding:3px; font-size:14px;
width:320px; height:14px;
}

#game_canvas {
top:20px; width:320px; height:320px;
}
</style>

</head>
<body>

<div id="title">8puzzle</div>
<canvas id="game_canvas" width="320" height="320"></canvas>
<script>

//設定

var main_image = "img/photo.png";
var panels = [];
var cell_w = 320 / 3; //横に4分割
var cell_h = 320 / 3; //縦に4分割
var pos_array = [[-1,0],[1,0],[0,-1],[0,1]]; //上下左右の座標

//Canvasのコンテキストを取得

var canvas = document.getElementById("game_canvas");
var con = canvas.getContext("2d")

//画像の読み込み

var image = new Image();
image.src = main_image;
image.onload = function() {
con.drawImage(image,0,0);
setTimeout(shufflePanel,3000);
}

//パネルのシャッフル

function shufflePanel() {

//パネルを初期化
for (var i = 0; i < 9; i++) {
panels[i] = i;
}

//シャッフル
for (var j = 0; j < 9 ; j++) {
var r = Math.floor(Math.random() * 9);
var tmp = panels[r];
panels[r] = panels[j];
panels[j] = tmp;
}
drawPanels();
}


//パネルを番号に応じて描画
function drawPanels() {
for (var i = 0; i < 9; i++){
var no = panels[i];
var pcol = no % 3;
var prow = Math.floor(no / 3);
var px = pcol * cell_w;
var py = prow * cell_h;
var tx = (i % 3) * cell_w;
var ty = Math.floor(i / 3) * cell_h;
if (no == 8) {
//穴の表示
con.beginPath();
con.fillStyle = "#CCCCCC";
con.fillRect(tx, ty, cell_w, cell_h);
} else {
//画像を切り取って表示
con.drawImage(image, px, py, cell_w, cell_h, tx, ty, cell_w, cell_h);
}
//枠を描画
con.beginPath();
con.moveTo(tx + cell_w, ty);
con.lineTo(tx, ty);
con.lineTo(tx, ty + cell_h);
con.strokeStyle = "#999999";
con.stroke();
}
}
//ユーザーのtouchイベントに反応する
canvas.ontouchstart = function(e) { //for iPhone
if (e.touches.length > 0){
var t = e.touches[0];
checkPanelXY(t.clientX, t.clientY);
}
e.preventDefault();
};

canvas.onmousedown = function(e) { //for PC
checkPanelXY(e.clientX, e.clientY);
};
function checkPanelXY(sx, sy) {
//タップされたパネルを取得する
var col = Math.floor(sx / cell_w);
var row = Math.floor((sy-20) / cell_h);
var no = row * 3 + col;
//穴の上なら何もしない
if (panels[no] == 8) { return }
//穴に接リンしているか確認
for (var i = 0; i < pos_array.length; i++) {
var row2 = pos_array[i][0] + row;
var col2 = pos_array[i][1] + col;
var check = getPanelNo(row2, col2);
if (check == 8) {
swapPanel(row, col, row2, col2);
}
}
};
//行(row)と列(col)からパネル番号を返す
function getPanelNo(row, col) {
//範囲外なら-1を返す
if (col < 0 || row < 0 || col >= 3 || row >= 3){
return -1;
}
return panels[row * 3 + col];
}

//パネルを入れ替える
function swapPanel(row1, col1, row2, col2) {
var index1 = row1 * 3 + col1;
var index2 = row2 * 3 + col2;
var tmp = panels[index1];
panels[index1] = panels[index2];
panels[index2] = tmp;
drawPanels();


}

</script>

</body>
</html>

です
動くことは動くのですが私の知識だとまだ理想には程遠いです、、、
理想としては
1.パズル完成後「CLEAR」の表示(ダイアログで表示したいです)
2.完成までかかった時間の表示
3.パズルの画面が中央に来てほしい
4.タブレットで使用したときに画面が小さいのでディバイスごとに適した大きさにしたい
5.今は用意した画像を読み込ませていますが自分で撮った写真などを読み込ませたい

説明がへたくそで申し訳ございません
最優先としては3,4の実装です
3,4を詳しく書くと
スマホ、タブレットともに画面の中央に大きく表示ということです
始めたばかりの初心者なのでなるべく噛み砕いて教えていただけると嬉しいです

投稿日時 - 2014-04-26 08:25:20

QNo.8569194

すぐに回答ほしいです

質問者が選んだベストアンサー

CSSにコレを足す記述を忘れてしまったせいかもしれません。

html, body{
width:100%;
}

先の回答では省略してしまいましたが、CSSは下記のように記述して下さい。
#game_canvas {
top:20px;
}

投稿日時 - 2014-04-27 22:36:02

補足

ありがとうございます!
WEB上では中心に表示できたのですがスマホで起動させると
前と変わりません><
そして
con.drawImage(image, px, py, cell_w, cell_h, tx, ty, cell_w, cell_h);
にエラーが出ます
見直したのですがエラーの部分ってどこがおかしいのでしょうか?
errorメッセージは
Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1

です

投稿日時 - 2014-04-28 07:42:55

ANo.3

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

1. getPanelNo関数をつかってすべてのセルのパネル番号が正しければ完了判定するメソッドを作ればよいでしょう。

2. ストップウォッチを実装すればよいと思います。
http://alphasis.info/2013/06/javascript-gyakubiki-stopwatch/

パズル開始時にstopwatchStart() 終了時にstopwatchStop()が
実行されるようにすればよいでしょう。

3. 幅100%でよいのなら
■CSSの変更
#title width:100%;
#game_canvas top:20px;

■HTMLの変更 widthとheight属性削除
<canvas id="game_canvas"></canvas>

■JSの追加 設定とcanvasのコンテキストを取得部分を下記のように変更
//設定
var device_w = document.body.clientWidth;
var main_image = "img/photo.png";
var panels = [];
var cell_w = device_w / 3; //横に4分割
var cell_h = device_w / 3; //縦に4分割
var pos_array = [[-1,0],[1,0],[0,-1],[0,1]]; //上下左右の座標

//Canvasのコンテキストを取得

var canvas = document.getElementById("game_canvas");
canvas.width = device_w;
canvas.height = device_w;
var con = canvas.getContext("2d")

5. このあたりを参考に
http://javascript.go-th.net/%E3%80%90graphics%E3%80%91canvas/canvas%E7%94%BB%E5%83%8F%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%99%E3%82%8B%E3%80%82

画像の拡大縮小機能もひつようそうですね。

投稿日時 - 2014-04-27 14:02:07

補足

3なのですが
書いていただいた通りやりました
すると画像は表示されずtitleのバックカラーもおかしくなったのですがどうすれば。。。
コード載せます。。。
CSS
#title {
background-color: blue; color: white;
padding:3px; font-size:14px;
width:100%; height:14px;
}

#game_canvas top:20px;

JS
//設定
var device_w = document.body.clientWidth;
var main_image = "img/hagaren.png";
var panels = [];
var cell_w = device_w / 3; //横に3分割
var cell_h = device_w / 3; //縦に3分割
var pos_array = [[-1,0],[1,0],[0,-1],[0,1]]; //上下左右の座標

//Canvasのコンテキストを取得

var canvas = document.getElementById("game_canvas");
canvas.width = device_w;
canvas.height = device_w;
var con = canvas.getContext("2d");

投稿日時 - 2014-04-27 16:06:14

>3.パズルの画面が中央に来てほしい
>4.タブレットで使用したときに画面が小さいのでディバイスごとに適した大きさにしたい

JavaScript で画面のサイズを入手して、
Canvas そのものの、位置をCSSで移動してしまうabsoluteとか
http://www.tagindex.com/html5/page/meta_viewport.html
この辺参考になるかと思います。

投稿日時 - 2014-04-26 15:19:53

補足

サイトを見て
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=3.0, user-scalable=no">
としたのですがやはりタブレットでは小さいしスマホで見ても若干のずれがあります。。。
どうすればいいのでしょうか?

投稿日時 - 2014-04-26 20:48:31

あなたにオススメの質問