ゲームのマップを表示する

 RPGやシミュレーションゲームではラウンドマップを表示することがあります。ゲーム開始時のマップセレクト画面やゲーム中においての次のマップデータに切り替える場合などです。現在のパソコンではメモリをふんだんに使用できるため広大なマップデータを一度に読み込んでしまうことも可能ですが、せっかくのAjaxなので、最低限のデータを読み込んでマップを表示してみます。
 まず、ゲームのマップデータですが以下のように数値(実際は文字列)の羅列になっています。

00000000
01001010
00020000
01111001
11110011
11111011
00111011
00011000

1文字がゲームのマップブロック(最小限のブロック。ここでは32×32ピクセル(ドット)を1ブロックとしています)に対応しています。ここでは、処理を簡単にするためマップデータの文字と画像ファイルの文字を対応させています。0とあれば0.gif、1とあれば1.gif、2であれば2.gifの画像になります。数値でなくwとすればw.gifファイルを読み込むことになります。
 マップデータの読み込みですが、これはテキストファイルを読み込むスクリプトと全く同じです。異なるのはマップの処理部分だけですが、マップデータは8×8ブロックサイズのため、縦横8回ずつデータを読み込みimgタグを生成するだけです。生成したimgタグを最後にdivタグ内にinnerHTMLを使って出力すればマップが表示されます。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>マップデータを表示する</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadDataFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
$("result").innerHTML = parseMap(httpObj.responseText);
}
}
// マップデータファイルを解析して表示
function parseMap(mapText)
{
var MapWidth = 8; // マップの横幅
var MapHeight = 8; // マップの縦幅
var LF = String.fromCharCode(10); // 改行コード (LF)
lineData = mapText.split(LF);
resultImage = "";
for (var i=0; i<MapHeight; i++)
{
for (var j=0; j<MapWidth; j++)
{
mapNumber = lineData[i].charAt(j);
resultImage += '<img src="images/'+mapNumber+'.gif" width="32" height="32">';
}
resultImage += "<br>";
}
return resultImage;
}
// --></script>
</head>
<body>
<h1>マップデータを表示する</h1>
<p>マップデータを読み込み表示します</p>
<form name="ajaxForm">
<input type="button" value="Round 1" onClick="loadDataFile('round/1.txt')">
<input type="button" value="Round 2" onClick="loadDataFile('round/2.txt')">
<input type="button" value="Round 3" onClick="loadDataFile('round/3.txt')">
</form>
<div id="result"></div>
</body>
</html>

 上記のスクリプトは平面的なマップ表示ですが、ゲームによっては上斜めから見たような感じにしたい場合もあります。このような場合、マップブロックを32×32のまま細かく分割して用意しマップデータもそれに合わせる方法とマップデータは、そのままでマップ画像を横長にして表示する方法があります。ここでは、マップデータは、そのままで画像を横長(水平に45度傾けたもの。画像サイズは64×32ピクセル(ドット))にして表示します。単純に表示してしまうとブロックとブロックの間に隙間ができてしまいます。(サンプルを実行する
 これを解決するにはマップの表示位置をスタイルシートで設定します。常に32ピクセル(1ブロックの半分)ずつ座標をずらして上から重ね合わせます。これで期待通りにマップが表示されます。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>マップデータを表示する2</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadDataFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
$("result").innerHTML = parseMap(httpObj.responseText);
}
}
// マップデータファイルを解析して表示
function parseMap(mapText)
{
var MapWidth = 8; // マップの横幅
var MapHeight = 8; // マップの縦幅
var mx = blockSize = 32; // マップのブロックサイズ
var screenOffset = 250; // マップの表示位置
var LF = String.fromCharCode(10); // 改行コード (LF)
lineData = mapText.split(LF);
resultImage = "";
for (var i=0; i<MapHeight; i++)
{
for (var j=0; j<MapWidth; j++)
{
mapNumber = lineData[i].charAt(j);
mx = MapWidth * blockSize + j*blockSize - i*blockSize;
my = i*blockSize + screenOffset;
resultImage += '<img src="images/'+mapNumber+'.gif" class="mapBlock" style="top:'+my+'px;left:'+mx+'px">';
}
resultImage += "<br>";
}
return resultImage;
}
// --></script>
<style type="text/css"><!--
.mapBlock {
width:64px;
height:32px;
position:absolute;
}
--></style>
</head>
<body>
<h1>マップデータを表示する2</h1>
<p>マップデータを読み込み斜めに表示します</p>
<form name="ajaxForm">
<input type="button" value="Round 1" onClick="loadDataFile('round/1.txt')">
<input type="button" value="Round 2" onClick="loadDataFile('round/2.txt')">
<input type="button" value="Round 3" onClick="loadDataFile('round/3.txt')">
</form>
<div id="result"></div>
</body>
</html>

 このようなマップデータ処理はゲームだけでなく他にも応用することができるでしょう。
 次項ではEXCEL(マイクロソフト エクセル)で生成されたXMLデータを表示します。

[第三章 4:EXCELのXMLデータを表示するへ]
[目次へ]

(2006.1.5)