Rmake Wikiは、Rmakeに関する情報共有をするためのWikiです。


スクリプト/つくってみよう1

最終投稿者:rurun9 更新:2011年08月22日 14:14:50

ハイ、こんにちわー。

今回は簡単なゲームを実際に作ってみましょーか。
その前にコチラを見ておいて下さい。

スクリプト/配列

変数をたくさん用意したいとき、a0,a1,a2,a3,…のように名前に数字を付けてしまいたい場合があります。
そんな時は配列変数にしちゃった方が管理が楽ですよっと。
配列を扱うのは非常にワカり難いかもしれませんが、
何番目の変数かというのを示すインデックス部分に別の変数を入れる事ができ、複雑なスクリプトを組み上げる事が可能になります。
ぶっちゃけ、配列無しでは高度なゲームをつくるのは無理です。是非とも習得しましょー。


ルールはこんな感じのを用意しました。
トランプを使います
1~13をランダムで並べかえて伏せておく…山
手札にも1~13を一枚ずつ持っている
手札から一枚を選んで出し、山からも一枚めくってきて、二つを比べる
数の大きい方に +1 点
13枚終了時の点数を表示
完成するとこんなの ⇒ ◆13H&L
サーティーンハイ&ロー!!
前半は運の要素が強いものの、後半は残りの札が限られてくるので、勝敗の確率が偏りますね。
コレが面白いかどうかはさておき、つくってみました。
仮にこれがライアーゲームだったりカイジだったりしたら、つまらないとか言ってる場合じゃありませんw
ノベル型でチャプターを分けて書いてあります。
ではさっそくスクリプトを見ていきましょー
#chapter0

setHelpVisible(false) #メニュー項目の非表示
setMenuItemVisible(getMenuHideWindow(), false)
setMenuItemVisible(getMenuSave(), false)
setMenuItemVisible(getMenuLoad(), false)

setSpeakWindowRect(50,50,700,500) #メッセージウインドウの位置&大きさ
setSelectWindowRect(600,80,100,420) #選択肢ウインドウの位置&大きさ

setTextViewMode(false) #文字列が一瞬で全部表示される

setVariable("a",createArray()) #札…0~12山札、13~25出札
setVariable("b",createArray()) #残っている手札


def moji(n) #数字から文字に変換する処理
 case n
 when 0 return "A"
 when 1 return "2"
 when 2 return "3"
 when 3 return "4"
 when 4 return "5"
 when 5 return "6"
 when 6 return "7"
 when 7 return "8"
 when 8 return "9"
 when 9 return "10"
 when 10 return "J"
 when 11 return "Q"
 when 12 return "K"
 end
end #moji()終


def word() #表示する文章をつくる処理
 setVariable("win",0); setVariable("loose",0) #点
 w="COMvsPLAYER\n"
 i=0
 while i<getVariable("turn")
   w=w+moji( getVariable("a")[i] )
   if getVariable("a")[i] < getVariable("a")[i+13]
     w=w+" < "+moji( getVariable("a")[i+13] )+"\n"
     setVariable("win",getVariable("win")+1)
   elsif getVariable("a")[i] == getVariable("a")[i+13]
     w=w+" = "+moji( getVariable("a")[i+13] )+"\n"
   else
     w=w+" > "+moji( getVariable("a")[i+13] )+"\n"
     setVariable("loose",getVariable("loose")+1)
   end
 i=i+1
 end

 return w
end #word()終
チャプター0では、まず画面の設定、変数に初期値を与えてゲームの準備をしています。
それからゲーム中に必要となる各処理を、ユーザー定義関数でまとめています。

テストプレイでもわかるように、文字ゲーなので画面表示しているのは文字列だけです。
word()では、出された山札vs出した手札、そしてどちらが勝ったのかを、経過ターン毎に一行ずつ書いているワケです。
#chapter1 変数に初期値を入れる処理

setVariable("turn",0) #ターン

i=0 #まずは数を順に並べる
while i<13
  getVariable("a")[i]=i #山札
  getVariable("s")[i]=i
i=i+1
end

i=0 #13枚をシャッフルする
while i<13
  r=rand(13) #山札の i 番目とランダム r 番目を入れ替える
  x=getVariable("a")[i]
  getVariable("a")[i]=getVariable("a")[r]
  getVariable("a")[r]=x
i=i+1
end
チャプター1では、変数に初期値を与えてゲームの準備をしています。
ゲーム終了後に「再プレイする」場合に、"chapter1"に戻ってきます。

次からが動作のメインとなる部分になります。
#chapter2

#手札の残り枚数(配列の長さ)を確認して max に入れる
max=getArrayLength( getVariable("s") )

ss=createArray() #選択肢となる配列を用意
i=0 #手札のカード番号配列 s を、文字に変換して ss に入れる
while i<max
  pushArray( ss, moji( getVariable("s")[i] ) )
i=i+1
end

#画面に前回までの結果と、選択肢を表示。何番目を選んだのかを k に入れる
k=speakWithSelectArray( ss, word() )

#選んだ札の番号を、出札として登録
getVariable("a")[getVariable("turn")+13]=getVariable("s")[k]

#ここから使用した手札を配列 s から抜き取る処理
#選んだものを境にして p=(0~ひとつ前) と q=(ひとつ後~最後) に分ける
#配列には0番目があるのでスライスで切り取る個数に注意
p=sliceArray(getVariable("s"),0,k)
q=sliceArray(getVariable("s"),k+1,max-k+1)

#ここで一度、配列 s を空っぽにするために、再定義(新しい配列で上書きしている)
setVariable("s",createArray())

i=0 #臨時配列 p を配列 s にコピーする
while i<getArrayLength( p )
  getVariable("s")[i]=p[i]
i=i+1
end

i=0 #臨時配列 q を s に追加する
while i<getArrayLength( q )
  pushArray(getVariable("s"), q[i] )
i=i+1
end

#以上で選択肢配列 s から、使用したものが抜き取られたのでターン終了。次へ
setVariable("turn", getVariable("turn")+1 )

if 12<getVariable("turn") #13枚の手札を全て使ったら勝敗判定へ
  changeChapter("chapter3")
else #まだ手札が残っているなら、繰り返す
  changeChapter("chapter2")
end
画面上に結果を表示して選択肢を出しているのが、たった一行である点にはお気付きでしょうか?

今回つくっているのは、手持ちの札(選択肢)が一度使用されるとなくなる、というもの。
手札を配列で管理しているので、そのまま選択肢として表示しています。
しかし、毎ターン選んだひとつだけ抜き取らないといけません。
そこで配列から選んだひとつを取り除いてその隙間を詰める、という事をしています。
配列の切ったり貼ったりをしているわけですね。

尚、ローカル変数はチャプターが切り替わる際に削除されますが、基本変数 s は残るので一度カラにしてから入れ直しをしているのです。
それにしてもややこしや~…
#chapter3

#勝敗を数えて結果表示
w=word()+getVariable("loose")+" vs "+getVariable("win")

#同点以上ならクリアできるようにしています
if getVariable("loose") <= getVariable("win")
  case speakWithSelect(2,"Again","Clear", w+" Win" )
  when 0 changeChapter("chapter1")
  when 1 goEnding()
  end
else
  case speakWithSelect(2,"Again","End", w+" Loose" )
  when 0 changeChapter("chapter1")
  when 1 goBadEnding()
  end
end
終了時に結果を表示して完成です。


どうでしたか?
自分でつくっておいてアレですが、文字ゲーで選択肢を減らしていくよりも、
画像を並べてマウスでクリックしていく方が絶対に簡単なんじゃないか?とか思いましたorz

ともかく、これが理解できれば配列は扱えるようにはなるかと。
そうしたら、スクリプト/コツ/売ったり買ったりできるお店処理 なんかを読んでみてはいかがでしょうか?
知らない関数はリファレンスで調べて、
ユーザー定義関数で何を処理しているのか、を把握するのが大切です。
今となってはRPGのお店機能が標準システムに加わったので、敢えて自分でお店を作る必要性までは無くなってしまいましたが、RPGでのアイテムの管理には配列を扱える事が必須となっています。
ともかく、お疲れ様でしたー。
次回は、スプライトを使ったアクションゲームに挑戦します!

 スクリプトの組み方の基礎知識など

このWikiの掲示板(すべて読む

コメント一覧

投稿者:rurun9(投稿日:2010/08/14 17:24)

えーと
誰からもツッコミが入らなかったけど無駄な部分を省いておきました。

投稿者:rurun9(投稿日:2010/08/01 17:01)

そーですね、初回から配列は誰もついて来れない感じになり、やっちまった感が(汗)

配列の途中をひとつを引っこ抜く、という作業がややこしいだけなんですが。
…今気付いた。コレ ss もローカル変数配列でいいんだ…

投稿者:shirosaboten(投稿日:2010/08/01 15:32)

はぁ~、配列って難しいですねぇ…もうしばらくこのブログ記事とにらめっこしてみます

User_icon
ゲスト