オセロや将棋のような盤をHTML5+JavaScriptで実装する場合、
1.盤全体をひとつのCanvasにする
2.マスそれぞれをCanvasにする
3.マスを構成する要素imgなどをそれぞれ並べる
という方法が考えられる。どれを選択するか。
1.盤全体をひとつのCanvasにする
- (+)HTMLスッキリ
- (+)CSS(position, top, leftやら)の設定がめんどくさくないかもしれない
- (+)Canvas内部はブラウザによって見た目が変わりにくい
- (-)Canvasって重くね?
2.マスそれぞれをCanvasにする
- (+)HTMLちょっとスッキリ
- (+)onmousedownとか登録すればオブジェクト指向的でわかりやすい
- (+)Canvas内部はブラウザによって見た目が変わりにくい
- (-)Canvasって重くね?
3.マスを構成する要素imgなどをそれぞれ並べる
- (+)重くなさそう
- (+)マスをぜんぶ再描画しなくても、変更したい構成要素をいじるだけで実現可能
- (-)クリックイベントなどが登録しにくい
- (-)ブラウザによって見た目が変わりそう
- (-)派手な動きさせにくそう
- (-)CSS(position, top, leftやら)めんどそう
- (-)HTMLぐちゃぐちゃ
クリックイベントなどが登録しにくい問題は特に、マス全体に渡る要素が必ず一番上(z-index)にあるとは限らないので、一番上に
<span id="responseClick" style="z-index:9999; width:30px; height:30px;"></span>
みたいのを置いて、それにonmousedownなどを設定する必要があるだろう。
最初は3でやろうと思っていたのだが、ブラウザによって見え方変わりそう、ということを考えると、やっぱ1か2かなあ。
2は、クリックイベントを登録する方法がよくわからず非常に難しい。
たとえばマスを
<canvas id="c0" style="width:30px; height:30px;"></canvas>
<canvas id="c1" style="width:30px; height:30px;"></canvas>
var ClassCell = function(iId){
this.mId = iId;
this.mCanvas = document.getElementById('c'+iId);
this.Click = function(e){
console.log(""+this.mId+"クリックされました")
}
this.mCanvas.onclick = this.Click;
};
var cells = [
new ClassCell(0),
new ClassCell(1)
];
みたいにクラス化した場合、たとえばがクリックされると、ClassCell.Click内のthisがCanvasを意味してしまって、うまく働かない。
まさか
var cells = [
new ClassCell(0),
new ClassCell(1)
];
function c0click(e){
cells[0].mCanvas.Click(e);
}
function c1click(e){
cells[1].mCanvas.Click(e);
}
cells[0].mCanvas.onclick = c0click;
cells[1].mCanvas.onclick = c1click;
とかマスの数だけやるのもアホらしいし……。
なんかいい方法あんのかな?
ないなら、1の方法でやるしかあるまい……。
いい方法があったら教えてほしいです。
追記
@Karakuri さんがコメントに書いてくださった方法
下記のコードでできました。
どういう理屈なんだこれ~
<canvas id="c0" style="border:solid;"></canvas>
<canvas id="c1" style="border:solid;"></canvas>
var cells = [];
$().ready(function(){
cells = [
new ClassCell(0),
new ClassCell(1)
];
});
var ClassCell = function(iId){
var self = this;
this.mId = iId;
this.mCanvas = document.getElementById('c'+iId);
this.Click = function(e){
console.log(""+self.mId+"クリックされました")
}
this.mCanvas.onclick = this.Click;
};
0クリックされました
1クリックされました