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