去年作った戦車が撃ちあうゲームをGAEのページへ移行した。
Canvas Tank Battle | 無職のHTML5 Canvas移行のついでに、地形マップをCanvasタグではなく背景のdiv要素に描画するようにした。
ステージ開始時にだけ地形の描画が行われるようになるので、負荷がちょっと減る。
背景に画像などを使用する場合は、負荷の減少が大きくなるだろう。
やったことをまとめようと思ったが、CSSで要素を重ねただけなので書くことが無い。
HTMLはこんな感じ。
<div class="divcv">
<div class="backdiv"></div>
<div id="mcvback" class="landdiv"></div>
<div class="wrapcv"><canvas id="mcv" class="cv" width="400" height="400"></canvas></div>
</div>
これを、親要素を position: relative 、背景要素を position: absolute にして、z-indexを指定して重ねるだけ。
CSSは以下のとおり。
<style TYPE="text/css">
/* 親要素div */
.divcv {
position: relative;
margin: 10px 35px 0px 20px;
width: 400px;
}
/* Canvas */
.cv {
border-style: solid;
border-width: 1px;
border-color: #808080;
}
/* Canvasを囲うdiv */
.wrapcv {
position: relative;
z-index: 5;
}
/* 地形マップを描画する背景div
* マップのサイズはステージごとに変わるため、top/leftはJavaScriptで設定
*/
.landdiv {
position: absolute;
z-index: 1;
}
/* Canvas領域に色をつけるためだけのdiv */
.backdiv {
position: absolute;
top: 0;
left: 0;
width: 400px;
height: 400px;
z-index: 0;
background-color: #F8F8FF;
}
</style>
JavaScriptで背景を描画したが、地形1マスごとにdiv要素を作ってひたすらappendしただけ。
Canvasのborder-widthの分だけ座標をズラす必要がある。
ソースは以下のとおり。jQueryはver1.4.4を使用。
/* 背景描画
* return なし
*/
tkgame.drawland = function() {
var grSep = tkgame.canv.grSep; // マスのサイズ(px)
// 背景div設定
var $mcvback = $('#' + tkgame.con.id.mcvback); // 地形マップを描画する背景div
var bwdth = 1; // Canvasのborder-width
$mcvback.empty(); // 全ての子要素を削除
/* tkgame.canv.stgx, tkgame.canv.stgy は、ステージ左上の座標
* tkgame.canv.axlen, tkgame.canv.aylen は、ステージの横幅何マスか、縦幅何マスか
*/
$mcvback.css('top', (tkgame.canv.stgy + bwdth) + 'px');
$mcvback.css('left', (tkgame.canv.stgx + bwdth) + 'px');
$mcvback.css('width', (tkgame.canv.axlen * grSep) + 'px');
$mcvback.css('height', (tkgame.canv.aylen * grSep) + 'px');
// 地形要素設定
var $landdiv; // 背景の地形要素
var landname;
/* tkgame.canv.landAr は、地形情報を格納した二次元配列
* 詳細は
tkland.js を参照
*/
for (var ix = 0; ix < tkgame.canv.landAr.length; ix++) {
for (var iy = 0; iy < tkgame.canv.landAr[ix].length; iy++) {
landname = tkgame.canv.landAr[ix][iy];
$landdiv = $('<div/>').addClass(tkgame.con.classn.landdiv);
$landdiv.css('top', (grSep * iy) + 'px');
$landdiv.css('left', (grSep * ix) + 'px');
$landdiv.css('width', grSep + 'px');
$landdiv.css('height', grSep + 'px');
$landdiv.css('backgroundColor', tkland.type[landname].col);
$mcvback.append($landdiv);
}
}
};
IE + FlashCanvas でもちゃんと表示できることを確認した。
これでひと通りの移行作業が終わった。
さて次は何を作ろうかな。