スクリプトを作れるようになろう-01
      投稿者: ikosami
     投稿日:2012/03/21 00:42
 ikosami
     投稿日:2012/03/21 00:42
    
      どうも。ikosamiです。
ブログなどを見ていると、
ノベルでスクリプトを組んで作るゲームを、
桁外れに難しい物だと、思い込んでしまっている人が多いようなので
今回は、できる限り簡単に、単純に迷路を作って
「あれ? こんな感じでも良いんだ?」
と、思ってもらいたいと思います。
なお、できる限り単純にしているので
今回は、画像は使いません。
①配列を使わない場合 (配列の便利さを知る)
まず、迷路なのでステージの形を作る必要があります。
とりあえず、配列を使わないで一番単純な方法で設定してみます。
迷路の形は(■=壁 ▽=自分 △=ゴール)
です。(簡単すぎるのは気にしないでください。)
( 「;」を書くと、そこは改行したことになります。)
では、これでスクリプトを作ってみます。
※配列を使わないと、どういうことになるのかを知るための物ですので
実際にこんな物は作らないでください。
なので、詳しい説明はつけません。
と、こうなります。
まぁこの5×5程度のサイズなら、できなくはないですね。
それに、自分が入ることのできない位置は考えずに書いているので
これだけで済みます。
でも、これが20×20とかならどうなるでしょう?
配列を使わない場合、すべての可能性を書き出す必要があるので
ものすごい苦労することになります。
ちなみに、僕は本当に昔これをやっていて、
オセロの時は1000行超えてました。
http://rmake.jp/boards/2/topics/217
しかも、ステージのマップを少し変えるとなると、
このスクリプトはほとんど作り直しになります。
結論として、
配列を使わない=すべての可能性を自分で書き出す必要がある
ということです。
とりあえず、これだけでは、配列の重要性はわかりにくいと思うので、
次は配列を使ったスクリプトを書いてみます。
②配列を使ったスクリプトの作成
では、配列を使って、迷路のステージを作ってみたいと思います。
とりあえず、
http://page.rmake.jp/wikis/145
の、「配列を一気に設定する関数」を使います。
この関数は、絶対に必要なわけではありませんが、
これを使うと、すごく楽なので。
では、ステージを設定してみます。
(■=壁 ▽=自分 △=ゴール)
(1=壁 2=ゴール)
では、スクリプトのほうを作ってみます。
まず自分の居場所を設定します。
配列は0から始まるので、そこは注意しましょう。
次はループの設定です。
ノベルでゲームを作る場合、
ループは、ほとんどの場合に使います。(本当のノベルゲームを除く)
これだけです。
ゲームのスクリプトは
while loop
と
end
の間に書いていきます。
移動は、
で十分です。
では、「↑」を選んだ場合のスクリプトを作っていきましょう。
まず、進んだ先が壁かどうかの判定をします。
xとyに位置情報が入っているので、それで判定できます。
なお、xとyの順番を間違えると、正常に動作しません。
僕もしょっちゅう間違えるので、注意しましょう。
このスクリプトに、壁でなかった場合とゴールの時も付け足せば、
移動は完璧です。
では、これをすべての移動に当てはめてみましょう。
それぞれどこが違うわかりますか?
↑の場合は y-1
→の場合は x+1
←の場合は x-1
↓の場合は y+1
となっています。
でも、これはほとんど同じですよね?
違う場所が1箇所や2箇所なら、もっとまとめることができます。
こんな感じで。
何をしたかわかりますか?
それぞれのどこがどう違うのかがはっきりしている場合は、
その違いを別の変数に入れて、
その変数を足す ということをすれば
だいぶ楽になります。
でも、これは少しわかりづらいだけで、
ほとんどの人が使っている方法です。
例えば、こんな感じ
って感じで。
ああ、あとついでに、エラー時の対応もしておきましょう。
これだと、もしステージの設定ミスで
外周に壁を作り忘れた場合どうなると思いますか?
設定の外に出てしまうので
[y+yi][x+xi] = null
となります。(null=「何も示さないもの」)
s[y+yi][x+xi] == 1 にも
s[y+yi][x+xi] == 2 にも当てはまらないので、
else の処理が行われて、永遠に進み続けることになります。
市販のゲームなどのすり抜けバグは、
これが理由で、永遠に進むことができてしまうのです。
なので、
として、nullの場合は進めないようにしましょう。
(※RPGなどのゲームでこうしてしまうと、万が一すり抜けバグが起きた時に
まったく動けなくなるので、帰れなくなります・・・
移動が中心のゲームでない場合は、こういう設定はやめましょう。)
ところで、今、どれくらいできていると思いますか?
実はもう全部できてるんです。
「ループの中を書くと」とか書いてたので、
わかりにくいかもしれませんが、
これだけです。
画像を表示しないとなると、
これで、全部なんです。
すごく単純ですよね?
ちなみに
設定の部分をこんな風に変えても
完全に対応でき、色々なステージを簡単に作ることができます。
暗闇迷路 - 【迷路ゲーム】
今回は、ここまでにします。
わからない部分が、少しでもあったらどんどんコメントしてください。
    
    ツイート
    
    ブログなどを見ていると、
ノベルでスクリプトを組んで作るゲームを、
桁外れに難しい物だと、思い込んでしまっている人が多いようなので
今回は、できる限り簡単に、単純に迷路を作って
「あれ? こんな感じでも良いんだ?」
と、思ってもらいたいと思います。
なお、できる限り単純にしているので
今回は、画像は使いません。
①配列を使わない場合 (配列の便利さを知る)
まず、迷路なのでステージの形を作る必要があります。
とりあえず、配列を使わないで一番単純な方法で設定してみます。
迷路の形は(■=壁 ▽=自分 △=ゴール)
■■■■■ ■▽■△■ ■ ■ ■ ■■■ ■■■■■
です。(簡単すぎるのは気にしないでください。)
( 「;」を書くと、そこは改行したことになります。)
では、これでスクリプトを作ってみます。
※配列を使わないと、どういうことになるのかを知るための物ですので
実際にこんな物は作らないでください。
なので、詳しい説明はつけません。
b = 7#(自分の場所の設定)
loop = true #(ループの設定)
while loop #(クリアするまで無限ループ)
case speakWithSelect(4,"↑","→","←","↓", 
    "どちらに進みますか?")
  when 0
    if b == 12
      speak("進みました")
      b = 7
    elsf b == 14
      speak("ゴールです!")
      goEnding()
    elsf b == 17
      speak("進みました")
      b = 12
    else
      speak("その方向には壁があり、進めません")
    end
  when 1
    if b == 12
      speak("進みました")
      b = 13
    elsf b == 13
      speak("進みました")
      b = 14
    else
      speak("その方向には壁があり、進めません")
    end
  when 2
    if b == 13
      speak("進みました")
      b = 12
    elsf b == 14
      speak("進みました")
      b = 13
    else
      speak("その方向には壁があり、進めません")
    end
  when 3
    if b == 7
      speak("進みました")
      b = 12
    elsf b == 12
      speak("進みました")
      b = 17
    else
      speak("その方向には壁があり、進めません")
    end
end
end
と、こうなります。
まぁこの5×5程度のサイズなら、できなくはないですね。
それに、自分が入ることのできない位置は考えずに書いているので
これだけで済みます。
でも、これが20×20とかならどうなるでしょう?
配列を使わない場合、すべての可能性を書き出す必要があるので
ものすごい苦労することになります。
ちなみに、僕は本当に昔これをやっていて、
オセロの時は1000行超えてました。
http://rmake.jp/boards/2/topics/217
しかも、ステージのマップを少し変えるとなると、
このスクリプトはほとんど作り直しになります。
結論として、
配列を使わない=すべての可能性を自分で書き出す必要がある
ということです。
とりあえず、これだけでは、配列の重要性はわかりにくいと思うので、
次は配列を使ったスクリプトを書いてみます。
②配列を使ったスクリプトの作成
では、配列を使って、迷路のステージを作ってみたいと思います。
とりあえず、
http://page.rmake.jp/wikis/145
の、「配列を一気に設定する関数」を使います。
この関数は、絶対に必要なわけではありませんが、
これを使うと、すごく楽なので。
では、ステージを設定してみます。
■■■■■ ■▽■△■ ■ ■ ■ ■■■ ■■■■■
(■=壁 ▽=自分 △=ゴール)
(1=壁 2=ゴール)
s = createArray()
s[0] = Array("1,1,1,1,1")
s[1] = Array("1,0,1,2,1")
s[2] = Array("1,0,0,0,1")
s[3] = Array("1,0,1,1,1")
s[4] = Array("1,1,1,1,1")
では、スクリプトのほうを作ってみます。
まず自分の居場所を設定します。
x = 1; y = 1
配列は0から始まるので、そこは注意しましょう。
次はループの設定です。
ノベルでゲームを作る場合、
ループは、ほとんどの場合に使います。(本当のノベルゲームを除く)
loop = true while loop end
これだけです。
ゲームのスクリプトは
while loop
と
end
の間に書いていきます。
移動は、
case speakWithSelect(4,"↑","→","←","↓", 
    "どちらに進みますか?")
  when 0
  when 1
  when 2
  when 3
end
で十分です。
では、「↑」を選んだ場合のスクリプトを作っていきましょう。
まず、進んだ先が壁かどうかの判定をします。
if s[y-1][x] == 1
  speak("その方向には壁があり、進めません")
end
xとyに位置情報が入っているので、それで判定できます。
なお、xとyの順番を間違えると、正常に動作しません。
僕もしょっちゅう間違えるので、注意しましょう。
このスクリプトに、壁でなかった場合とゴールの時も付け足せば、
移動は完璧です。
if s[y-1][x] == 1
  speak("その方向には壁があり、進めません。")
elsif s[y-1][x] == 2
  speak("ゴールです。")
  goEnding()
else
  speak("進みました。")
  y = y - 1
end
では、これをすべての移動に当てはめてみましょう。
case speakWithSelect(4,"↑","→","←","↓", 
    "どちらに進みますか?")
  when 0
    
    if s[y-1][x] == 1
      speak("その方向には壁があり、進めません。")
    elsif s[y-1][x] == 2
      speak("ゴールです。")
      goEnding()
    else
      speak("進みました。")
      y = y - 1
    end
  when 1
    if s[y][x+1] == 1
      speak("その方向には壁があり、進めません。")
    elsif s[y][x+1] == 2
      speak("ゴールです。")
      goEnding()
    else
      speak("進みました。")
      x = x + 1
    end
  when 2
    if s[y][x-1] == 1
      speak("その方向には壁があり、進めません。")
    elsif s[y][x-1] == 2
      speak("ゴールです。")
      goEnding()
    else
      speak("進みました。")
      x = x - 1
    end
  when 3
    if s[y+1][x] == 1
      speak("その方向には壁があり、進めません。")
    elsif s[y+1][x] == 2
      speak("ゴールです。")
      goEnding()
    else
      speak("進みました。")
      y = y + 1
    end
end
それぞれどこが違うわかりますか?
↑の場合は y-1
→の場合は x+1
←の場合は x-1
↓の場合は y+1
となっています。
でも、これはほとんど同じですよね?
違う場所が1箇所や2箇所なら、もっとまとめることができます。
こんな感じで。
case speakWithSelect(4,"↑","→","←","↓", 
    "どちらに進みますか?")
  when 0
    xi =  0;yi = -1
  when 1
    xi =  1;yi =  0
  when 2
    xi = -1;yi =  0
  when 3
    xi =  0;yi =  1
end
if s[y+yi][x+xi] == 1
  speak("その方向には壁があり、進めません。")
elsif s[y+yi][x+xi] == 2
  speak("ゴールです。")
  goEnding()
else
  speak("進みました。")
  x = x + xi;y = y + yi
end
何をしたかわかりますか?
それぞれのどこがどう違うのかがはっきりしている場合は、
その違いを別の変数に入れて、
その変数を足す ということをすれば
だいぶ楽になります。
でも、これは少しわかりづらいだけで、
ほとんどの人が使っている方法です。
例えば、こんな感じ
case speakWithSelect(3,"100円","200円","300円", 
    "いくらの物を買いますか?")
  when 0
    cost = 100
  when 1
    cost = 200
  when 2
    cost = 300
end
money = money - cost
って感じで。
ああ、あとついでに、エラー時の対応もしておきましょう。
if s[y+yi][x+xi] == 1
  speak("その方向には壁があり、進めません。")
elsif s[y+yi][x+xi] == 2
  speak("ゴールです。")
  goEnding()
else
  speak("進みました。")
  x = x + xi;y = y + yi
end
これだと、もしステージの設定ミスで
外周に壁を作り忘れた場合どうなると思いますか?
設定の外に出てしまうので
[y+yi][x+xi] = null
となります。(null=「何も示さないもの」)
s[y+yi][x+xi] == 1 にも
s[y+yi][x+xi] == 2 にも当てはまらないので、
else の処理が行われて、永遠に進み続けることになります。
市販のゲームなどのすり抜けバグは、
これが理由で、永遠に進むことができてしまうのです。
なので、
if s[y+yi][x+xi] == 0
  speak("進みました。")
  x = x + xi;y = y + yi
elsif s[y+yi][x+xi] == 2
  speak("ゴールです。")
  goEnding()
else
  s[y+yi][x+xi] == 1
  speak("その方向には壁があり、進めません。")
end
として、nullの場合は進めないようにしましょう。
(※RPGなどのゲームでこうしてしまうと、万が一すり抜けバグが起きた時に
まったく動けなくなるので、帰れなくなります・・・
移動が中心のゲームでない場合は、こういう設定はやめましょう。)
ところで、今、どれくらいできていると思いますか?
実はもう全部できてるんです。
「ループの中を書くと」とか書いてたので、
わかりにくいかもしれませんが、
これだけです。
#////////この関数は、コピーしてきてください////////////
def Array(a)
  a = splitString(a, ",")
  i = 0
  while i < getArrayLength(a)
    a[i] = toNumber(a[i])
    i = i + 1
  end
return a
end
#///////////////////////////////
s = createArray()
s[0] = Array("1,1,1,1,1")
s[1] = Array("1,0,1,2,1")
s[2] = Array("1,0,0,0,1")
s[3] = Array("1,0,1,1,1")
s[4] = Array("1,1,1,1,1")
x = 1; y = 1
loop = true
  while loop
  case speakWithSelect(4,"↑","→","←","↓", 
      "どちらに進みますか?")
    when 0
      xi =  0;yi = -1
    when 1
      xi =  1;yi =  0
    when 2
      xi = -1;yi =  0
    when 3
      xi =  0;yi =  1
  end
  if s[y+yi][x+xi] == 0
    speak("進みました。")
    x = x + xi;y = y + yi
  elsif s[y+yi][x+xi] == 2
    speak("ゴールです。")
    goEnding()
  else
    s[y+yi][x+xi] == 1
    speak("その方向には壁があり、進めません。")
  end
end
画像を表示しないとなると、
これで、全部なんです。
すごく単純ですよね?
ちなみに
s = createArray()
s[0] = Array("1,1,1,1,1")
s[1] = Array("1,0,1,1,0,1")
s[2] = Array("1,0,0,0,0,2,1")
s[3] = Array("1,0,1,1,0,1")
s[4] = Array("1,1,1,1,1")
設定の部分をこんな風に変えても
完全に対応でき、色々なステージを簡単に作ることができます。
暗闇迷路 - 【迷路ゲーム】
今回は、ここまでにします。
わからない部分が、少しでもあったらどんどんコメントしてください。
コメントする
コメントするには、ログインする必要があります。
コメント一覧
      こんなんでいいんだ!
Arrayってどうやって使うんですか?(∀)
    
        Arrayってどうやって使うんですか?(∀)

 
  
  
 
移動する=座標の変化
という概念を、今のうちに頭に入れておきたいものです。