スクリプトを作れるようになろう-01
投稿者: 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ってどうやって使うんですか?(∀)
移動する=座標の変化
という概念を、今のうちに頭に入れておきたいものです。