半透明オブジェクト
フィルタを利用すれば、簡単に半透明なオブジェクトを実現することができます。ゲームではさまざまな画面を重ね合わせることが多く、場合によっては一部のオブジェクトを半透明にして背景を透過させた方が美しく見える場合があります。例えば、メッセージウィンドウやステータスウィンドウなど、文字を表示するためのフレームは背景を半透明にさせた方が画面が見やすくなります。
半透明を実現させるには、filterプロパティにAlphaフィルタを指定します。Alphaは、オブジェクトに不透明度を指定することで完全に透明にしたり、半透明にしたり、または不透明にすることができます。
Alpha(Opacity=opacity, FinishOpacity=finishopacity, Style=style,
StartX=startX, StartY=startY, FinishX=finishX, FinishY=finishY)
Opacityパラメータに0~100までの不透明度を指定します。0であれば完全に透明、100であれば不透明であることを表します。より0に近ければ背景が強く表示され、100に近ければオブジェクトが強く表示されるということになります。これ以降のパラメータはオブジェクト全体を一定の率で透過させる場合には不要です。部分的に半透明にする特別な演出で利用するパラメータです。
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=shift_jis">
<title>サンプル 02</title>
<script language="javascript">
var opacity = 50;
function document_load() {
fore.style.filter = "Alpha(Opacity=" + opacity + ")";
label.innerHTML = "Opacity=" + opacity;
}
function dec_click() {
if (opacity > 0) opacity -= 10;
fore.style.filter = "Alpha(Opacity=" + opacity + ")";
label.innerHTML = "Opacity=" + opacity;
}
function inc_click() {
if (opacity < 100) opacity += 10;
fore.style.filter = "Alpha(Opacity=" + opacity + ")";
label.innerHTML = "Opacity=" + opacity;
}
</script>
</head>
<body onLoad="document_load()">
<table width="100%" height="100%">
<tr><td align="center">
<input type="button" onClick="dec_click()"
value="より透明に">
<input type="button" onClick="inc_click()"
value="より不透明に">
</th></tr>
<tr><td align="center"><p id="label">Opacity=100</td></tr>
<tr><td align="center" style="
background-image:url(back00.jpg);
background-repeat:no-repeat;
background-position:center;
">
<img src="fore00.jpg" id="fore">
</th></tr></table>
</body>
</html>
このHTML文書は、テーブルの背景に「back00.jpg」ファイルを表示させ、その前景に「fore00.jpg」を表示させています。「fore00.jpg」にはforeという名前を与え、このオブジェクトの不透明度をスクリプトから制御しています。表示されている[より透明に]ボタンを押すと、AlphaフィルタのOpacityパラメータの値を10ずつ減らし、[より不透明に]ボタンを押すと10ずつ増やします。
タイマーと組み合わせることによってフェード・イン、フェード・アウトを実現することも可能ですが、フェード処理はもっと簡単な方法があるのでAlphaフィルタを使う必要はありません。それよりもAlphaフィルタは文字表示専用のフレームなどの背景を透過させるのに適しているでしょう。
半透明なメッセージウィンドウを作成する場合、メッセージウィンドウの枠と背景を表すオブジェクトと、メッセージウィンドウ上にテキストを表示するウィンドウを分離させなければなりません。通常、こうした特定の意味を持たないコンテナ用のオブジェクトにはspan要素を使うとよいでしょう。枠と背景色を持つspan要素と、その上にテキストを表示するspan要素を絶対座標指定で重ね合わせるのです。
ゲーム用のテキストは、単純なテキストではいけません。複雑な背景画の上に表示されるゲームテキストは、単色だと背景に溶け込んで読めなくなってしまう可能性があるため、通常は文字に枠をつけたり、異なる色の影をつけます。この作業はShadowフィルタやDropShadowフィルタが適しています。
Shadow(Color=color, Direction=direction)
DropShadow(Color=color, OffX=offX, OffY=offY, Positive=positive)
Shadowは、オブジェクトの縁に沿って指定した方向に向かう影を描画します。影の色はcolorに#から始まる#RRGGBB方式で指定することができ、方向はdirectionで指定します。指定できる方向は真上を0として45度ずつ時計回りに、以下の値のいずれかを指定できます。なお、省略した場合は左下を表す225が設定されます。
| 方向 | 数値 |
| 真上 | 0 |
| 右上 | 45 |
| 右 | 90 |
| 右下 | 135 |
| 真下 | 180 |
| 左下 | 225(デフォルト) |
| 左 | 270 |
| 左上 | 315 |
DropShadowの場合は、OffXとOffYに陰を配置する場所をピクセル単位のオフセットで指定することができます。positiveには、透明なピクセルに対して影を作成するかどうかを表す論理値です。透明なオブジェクトに影を表示させる場合は0を設定し、そうでなければ0以外を設定します。
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=shift_jis">
<title>サンプル 03</title>
<script language="javascript">
function document_load() {
var messageWindowWidth = 600;
var messageWindowHeight = 140;
body.style.backgroundImage = "url(back00.jpg)";
body.style.backgroundRepeat = "no-repeat";
body.style.backgroundPosition = "center";
body.innerHTML = "<span id=\"msgWnd\"></span>";
body.innerHTML += "<span id=\"msgText\"></span>";
msgWnd.style.position= "absolute";
msgWnd.style.width = messageWindowWidth;
msgWnd.style.height = messageWindowHeight;
msgWnd.style.left =
body.clientWidth / 2 - messageWindowWidth / 2;
msgWnd.style.top =
body.clientHeight / 2 - messageWindowHeight / 2;
msgText.style.position= "absolute";
msgText.style.width = messageWindowWidth;
msgText.style.height = messageWindowHeight;
msgText.style.left =
body.clientWidth / 2 - messageWindowWidth / 2;
msgText.style.top =
body.clientHeight / 2 - messageWindowHeight / 2;
msgWnd.style.borderStyle = "outset";
msgWnd.style.borderColor = "#5050FF";
msgWnd.style.backgroundColor = "#AAAAFF";
msgWnd.style.filter = "Alpha(Opacity=70)";
msgText.style.padding = "10";
msgText.style.fontSize = "26";
msgText.style.color = "#FF8040";
msgText.style.filter = "Shadow(Color=#000000, Direction=135)";
msgText.innerHTML =
"アドベンチャーゲームで一般的なメッセージウィンドウです。";
msgText.innerHTML += "固定ダイアログを想定しているので、" +
"ウィンドウサイズを変更しないでください";
}
</script>
</head>
<body id="body" onLoad="document_load()">
</body>
</html>
このHTML文書では、スクリプトから動的に背景イメージとメッセージウィンドウを作成しています。HTML文書のBODY要素内には何も記述されていない部分に注目してください。これまで本稿で解説してきたフィルタ処理は、全てCSSによって実現できることなので、メッセージ用のテキストや座標の設定はHTML文書内でCSSを使った方が簡単であるという意見もあるでしょう。しかし、プログラム側が制約するレイアウトに関わる部分を、デザイナーが担当するHTML文書の静的なCSSで記述するべきではないのです。他の文書で機能を使い回したり、部分的な変更が必要になったとき、スクリプトやHTML文書が互いの制約に縛られるようでは、スクリプタとデザイナが喧嘩を始めてしまうかもしれません。
こうしたスクリプト的な処理に関わる部分は、可能な限りスクリプトでオブジェクトを動的に生成するべきです。そうすれば、オブジェクトに変更が求められたときもスクリプタの責任の下で適切に管理でき、さらに変更にも強い文書を作ることができます。ゲームのようなエンターテイメントツールの場合は、特にレイアウト関係の変更には強くなければなりません。よって、ゲームの重要な要素となる背景、テキストウィンドウ、前景イメージなどは柔軟に対応できるスクリプトで処理した方が保守が容易になります。

