できるだけ単純にJavaScriptでアドベンチャーゲームを作る。

theater.jsはv2.0.0公開に向けて現在調整中です。ただ、やはりシナリオ記述の簡易化にちょっと手間取っています・・・。しかもやたらと重いし><;

そこで(?)ためしに超簡易版theater.jsを作成してみました。(すでに外部ファイルでもないですが^^;)

prototype.js使用、画像ファイルは別途用意する必要があります。

>>動作を確認

>>ダウンロード(prototype.js、画像ファイル含む)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 //EN">
<html>
<head>
<title>TheaterJS BASIC</title>
<meta http-equiv="content-type" content="text/html; charset=shift_jis"/>
<meta http-equiv="pragma" content="no-cache"/>
<meta http-equiv="cache-control" content="no-cache"/>
<meta http-equiv="imagetoolbar" content="no"/>
<script src="prototype.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
#img{
  display:block;
  margin:0 auto 0 auto;
  border:solid #0000ff 4px;
  background-color:#6699cc;
}
#msg{
  margin:0 auto 0 auto;
  letter-spacing:1px;
  height:115px;
  border:solid #0000ff 4px;
  font-weight:bold;
  font-size:16px;
  color:#ffffff;
  background-color:#6699cc;
  padding:2px;
  width:476px;
}
</style>
<script type="text/javascript">
var Theater = Class.create();
Theater.prototype = {
  initialize: function(param){
    param.img.each(function(img){
      new Image().src = img;
    });
    this.pushCurent(param.scenario);
  },
  
  current: [],
  
  scenario: [],

  param: {},
  
  pushCurent: function(scenario, index){
    index = index || 0;
    this.current.push({scenario:scenario, index:index});
  },

  play: function(){
    var length = this.current.length;
    if(length == 0) return;
    var current = this.current[length - 1];
    if(current.index >= current.scenario.length){
      this.current.pop();
      this.play();
    }else{
      current.scenario[current.index++].bind(this)();
    }
  }	
};

var actorYes = function (){
  if(confirm("どっち?")){
    this.pushCurent(scenarioOK);
  }else{
    this.pushCurent(scenarioNG);
  }
  this.play();
};

var actorNo = function (){
  if(confirm("どっち?")){
    this.pushCurent(scenarioNG);
  }else{
    this.pushCurent(scenarioOK);
  }
  this.play();
};

var scenarioOK =  [
  function (){
    $('img').src = 'img/sample2.gif';
    $('msg').innerHTML = '正解!';
  },
  function (){
    $('msg').innerHTML = '^^';
    this.param.count++;
  }	  
];

var scenarioNG = [
  function(){
    $('img').src = 'img/sample5.gif';
    $('msg').innerHTML = '残念!';					  
  },
  function(){
    $('msg').innerHTML = '><;';					  
  }
];

var scenario = [
  function (){
    $('img').src = 'img/sample1.gif';
    $('msg').innerHTML = 'ようこそ';
    this.param.count = 0;
    this.param.name = "unknown";
  },
  function (){
    $('img').src = 'img/sample2.gif';
    $('msg').innerHTML = 'お名前を入力してください';
    this.param.name = prompt("お名前を入力してください", this.param.name);
    $('msg').innerHTML = 'ようこそ' + this.param.name + 'さん';
  },
  function (){
    $('img').src = 'img/sample4.gif';
    $('msg').innerHTML = '第一問:1+1=2?';
  },
  actorYes,
  function (){
    $('img').src = 'img/sample4.gif';
    $('msg').innerHTML = '第二問:2+3=6?';
  },
  actorNo,
  function (){
    $('img').src = 'img/sample4.gif';
    $('msg').innerHTML = '第三問:3+4=7?';
  },
  actorYes,
  function (){
    $('msg').innerHTML = 'おわり';
  },
  function (){
    $('msg').innerHTML = this.param.name + 'さんの結果:正解' + this.param.count;
  },
  function (){
    if(this.param.count == 3){
      $('img').src = 'img/sample7.gif';
      $('msg').innerHTML = '全問正解!';
    }else{
      $('img').src = 'img/sample6.gif';
      $('msg').innerHTML = '残念><;';
    }
  },
  function (){
    $('img').src = 'img/sample1.gif';
    $('msg').innerHTML = 'お疲れ様でした';
  }
];

var theater = new Theater({
  scenario: scenario,
  img:[
    'img/sample1.gif',
    'img/sample2.gif',
    'img/sample3.gif',
    'img/sample4.gif',
    'img/sample5.gif',
    'img/sample6.gif',
    'img/sample7.gif'
  ]
});
</script>
</head>
<body>
<div onclick="theater.play();">
<img id="img" src="img/sample1.gif"/>
<div id="msg"></div>
</div>
</body>
</html>

基本的には関数の配列(scenario)を作成して、それをonclick時に順番に実行しているだけ。各関数はTheaterクラスインスタンスのメンバとして実行されます。なのでthisにより他のメンバを参照可能です。

シナリオ中に別のシナリオへ飛ぶときは、pushCurentメソッドを使用してからplayメソッドを呼びだします。呼び出したシナリオが終了すると、元のシナリオに復帰します。

prompt等で得られた入力値は、this.paramのメンバとして保持することで、シナリオ中で共有できます。

これを多機能化(煩雑化?)したのが拙作theater.jsなのですが。「重いし、よく分からないから使いたくない」みたいな場合はこのサンプルを参考にしてください。。。