SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

JavaScriptとCSSによるアドベンチャーゲームの作成

フィルタによる画像処理で高度な演出を実現する


アドベンチャゲーム

 最後に、今までの機能を組み合わせてJavaScriptによるアドベンチャゲームの基盤を作成してみましょう。特に新しい機能を使う必要はありません。HTML文書のイメージやテキストをスクリプトから実行時に変更したり、表示するオブジェクトを絶対座標で指定したりすることができれば、アドベンチャーゲームの基本的な機能は整います。それに加えて本稿のフィルタやトランジションフィルタを使えば、さらにゲームらしい表現が可能になります。

 ただし、ゲームには状態の遷移を表現する機能がなければなりません。ゲームは勝手にプログラムが操作してよいものではなく、ユーザーの入力を待ち、ユーザーと対話をしながら進める必要があります。これを実現するには、マウスクリックのイベントを受け、ゲームを次の場面に進めるという作業が必要です。

 一般的な解決方法は、ゲーム専用の独自のスクリプト言語やシナリオ記述言語を開発することですが、これは結果としてインタプリンタの開発に繋がっていくため、簡単に作れるものではありません。この場では、代わりにJavaScriptの機能であるeval()メソッドを使ってこれを実現します。

eval(codeString)

 eval()メソッドは、codeStringに指定された文字列をJavaScriptプログラムとして実行します。ゲームのシナリオをそのままスクリプトで配列オブジェクトの要素として記述し、ユーザーがクリックすると配列オブジェクトから次のコードを取り出してeval()に実行させるという手段を使います。

アドベンチャゲーム
<html>
    <head>
    <meta http-equiv="Content-Type"
          content="text/html; charset=shift_jis">
    <title>サンプル 05</title>

    <script language="javascript">
var lines;               //命令の配列
var index = 0;           //現在実行している命令のインデックス

var frameWidth;          //ゲーム画面の幅
var frameHeight;         //ゲーム画面の高さ
var messageWindowWidth;  //メッセージウィンドウの幅
var messageWindowHeight; //メッセージウィンドウの高さ

//次のコードを実行する
function next() {
    if (index >= lines.length) return;

    eval(lines[index]);
    index++;
}

//イメージを変更する
function setImage(url) {
    foreImg.filters(0).Apply();

    if (url == null) {
        foreImg.style.visibility = "hidden";
    }
    else {
        foreImg.style.visibility = "visible";
        foreImg.src = url;
        foreImg.style.left = frameWidth / 2 - foreImg.width / 2;
        foreImg.style.top = frameHeight - foreImg.height;
    }

    foreImg.filters(0).Play();
}

//テキストを変更する
function setText(text) {
    msgText.filters(0).Apply();
    msgText.innerHTML = text;
    msgText.filters(0).Play();
}

//初期化
function document_load() {
    frameWidth = 640;
    frameHeight = 480;
    messageWindowWidth = 600;
    messageWindowHeight = 140;

    body.innerHTML = "<span id=\"backImg\"></span>";
    body.innerHTML += "<img id=\"foreImg\" src=\"fore00.png\">";
    body.innerHTML += "<span id=\"msgWnd\"></span>";
    body.innerHTML += "<span id=\"msgText\"></span>";

    backImg.style.position= "absolute";
    backImg.style.left= 0;
    backImg.style.top= 0;
    backImg.style.backgroundImage = "url(back00.jpg)";
    backImg.style.backgroundRepeat = "no-repeat";
    backImg.style.width = frameWidth;
    backImg.style.height = frameHeight;

    foreImg.style.filter = "BlendTrans(Duration=1)";
    foreImg.style.position= "absolute";
    foreImg.style.visibility = "hidden";
    foreImg.style.left= 0;
    foreImg.style.top= 0;

    msgWnd.style.position= "absolute";
    msgWnd.style.width = messageWindowWidth;
    msgWnd.style.height = messageWindowHeight;
    msgWnd.style.left = 0;
    msgWnd.style.top = 0;

    msgWnd.style.position= "absolute";
    msgWnd.style.width = messageWindowWidth;
    msgWnd.style.height = messageWindowHeight;
    msgWnd.style.left = frameWidth / 2 - messageWindowWidth / 2;
    msgWnd.style.top = frameHeight - messageWindowHeight - 10;

    msgText.style.position= "absolute";
    msgText.style.width = messageWindowWidth;
    msgText.style.height = messageWindowHeight;
    msgText.style.left = frameWidth / 2 - messageWindowWidth / 2;
    msgText.style.top = frameHeight - messageWindowHeight - 10;

    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 =
    "BlendTrans(Duration=0.5) Shadow(Color=#000000, Direction=135)";

    lines = new Array(
        "setImage(\"fore00.png\");" +
            "setText(\"画面をクリックしてください\");",
        "setText(\"こんにちは、赤坂本のサンプルでお馴染みに" +
            "なりつつある猫耳キャラの「マーチ」です\");",
        "setImage(\"fore02.png\");" +
        "setText(\"何でブルマなのかは聞いちゃいけません…。" +
            "きっと赤坂の趣味なのです\");",
        "setImage(\"fore00.png\");" +
        "setText(\"ともあれ、こんな感じにゲーム風のプログラムを" +
            "ブラウザ上で実行できます\");",
        "setImage(\"fore01.png\");" +
        "setText(\"Ajaxなど、他の技術と組み合わせれば" +
            "いろんなことができそうですよ~\");"
    );

    body.onclick = next; //イベントの登録
    next();
}
    </script>
    </head>

    <body id="body" onLoad="document_load()">
    </body>
</html>

 このプログラムは、背景、キャラクターイメージ、テキストを表示できるだけの簡単な機能しか備えていません。よって、ゲームの保存、音声の制御、シナリオの分岐、履歴表示など、足りない機能を挙げれば限りがないのですが、これだけのコードで動くゲームが作れるのはJavaScriptの魅力と言えるでしょう。

最後に

 今回は、少ないコード量で作れるアドベンチャゲームを作りましたが、フィルタを使った演出はシューティング、シミュレーション、RPGなど、他のジャンルのゲームでも十分に応用することができます。ネットで見かけるJavaScriptで作られたゲームの多くは、ごく簡単なミニゲームが大半ですが、近年Ajaxの登場などによって再評価されているように、プログラム方法によっては大規模で高度なアプリケーションの開発も不可能ではありません。ユーザー認証やデータ保存を行うサービスを提供するサーバーを作成し、スクリプトと通信させれば本格的なゲームをブラウザ上で実行することも可能です。ぜひ、さまざまな方法で挑戦してください。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

赤坂 玲音(アカサカ レオン)

平成13年度「全国高校生・専門学校生プログラミングコンテスト 高校生プログラミングの部」にて最優秀賞を受賞。2005 年度~ Microsoft Most Variable Professional Visual Developer - Visual C++。プログラミング入門サイト WisdomSoft の管理人。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/340 2006/05/08 10:32

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー