莞爾の草原。

RGSS3(RPGツクールVX Ace)や自作のことを主に書いていくブログです。不定期で更新していきます。

【RGSS3】二人ポーカースクリプト(AI搭載)(Script : Heads Up Poker)

f:id:kanjinokusa0405:20170923221625p:plain

「ポーカー? そんぐらい楽勝っしょ」

そんな軽率なノリで作り始めました。まさか三日もかかるとは思いませんでした。

f:id:kanjinokusa0405:20170923221340p:plain

ジョーカーなしのヘッズアップポーカーです(ジョーカーは仕様が面倒くさいので搭載しなかったのは内緒)。これさえ作れればプログラマーになれるといいますが、こんなものを作らなければならないくらいだったらプログラマーにはなりたくありません。

 

【サンプルプロジェクト】

https://www.dropbox.com/s/m0rj138597lkmeu/Poker.exe?dl=0

スクリプト本体】

https://www.dropbox.com/s/vpuu9w4vqh3qlm6/PokerScript.txt?dl=0

【お借りしたトランプの画像】

sozai.7gates.net

 

利用規約はこちら(http://kanjinokusargss3.hatenablog.com/entry/2017/08/03/150359

 

【更新履歴】
・ver.0.00

・公開しました

・ver.0.01
・コミュ太郎氏の助言を受けてcard_numberとsame_number_countの処理を簡略化
・ワンゲームが終わった後にゲームを終了しようとしても終われないバグを修正
・アンティの額を変えられるように変更
・チップ制度を追加。

 

【RGSS3】混乱時行動拡張スクリプト(Script : Extend Actions in Confusing)

f:id:kanjinokusa0405:20170803204301p:plain

混乱時の行動パターンを拡張するスクリプトです。混乱時に混乱しているアクターが敵にアイテムを使ったり、味方に攻撃スキルを使ったりするようになります。某最終幻想よりの仕様です。

 

スクリプト

https://www.dropbox.com/s/uujvorl2f9ypi7d/RGSS3ConfusingAction.txt?dl=0

サンプルプロジェクト:

https://www.dropbox.com/s/cgoudgiaxx6xcxi/ConfuseExtension.exe?dl=0

 

利用規約はこちら(http://kanjinokusargss3.hatenablog.com/entry/2017/08/03/150359

 

【更新履歴】
・ver.1.00 公開しました
・ver.1.00a コミュ太郎氏により使用不能のスキルがあるとまれに行動できなくなる不具合の修正とスクリプトの簡略化が行われました。

【RGSS3】技の攻撃対象拡張スクリプト(Script : Extend the Target of specific skill or item)

f:id:kanjinokusa0405:20170803151054p:plain

味方を殴ったり敵を回復したりできるようになるスクリプトです。攻撃対象を決めるウィンドウでRかLキーを押すと攻撃対象が敵から味方、味方から敵へ変わります。混乱・眠り状態の仲間を治したいときや、レベル調整で仲間を間引きたいときなどに使えるでしょう。

 

スクリプト

https://www.dropbox.com/s/u7xyvsk8lzoctqs/RGSS3TargetExtend.txt?dl=0

【「XPスタイルバトル」および「戦闘コマンド消したりするやつ」対応版(コミュ太郎氏制作)】(ver.1.00)

http://wikiwiki.jp/comtarorgss/?RGSS3%2F%B5%BB%A4%CE%C2%D0%BE%DD%CA%D1%B9%B9_XP%A5%B9%A5%BF%A5%A4%A5%EB%A5%D0%A5%C8%A5%EB%C2%D0%B1%FE%C8%C7

 

  サンプルプロジェクト:

https://www.dropbox.com/s/d9m0l6morbc1rdd/TargetExtension.exe?dl=0

 

更新履歴:

・ver.1.00 公開しました。

・ver.1.10 一部スキルでの対象変更を禁止できるようにしました。 

・ver.1.11 一度対象変化できるスキルを使おうとすると、次の対象変化禁止のスキルでも対象変化できてしまうバグを修正。

 ・ver.1.12 戦闘開始時にスキルを選んでも正常に対象変化が行われないバグを修正。

 

利用規約

・利用報告は不要ですが、報告していただけると舞い上がります。

・素材の改変は自由ですが、無断で素材を二次配布する行為は禁止です。

・Readmeやスタッフロールなどのクレジットに当サイト名(莞爾の草原。)や作者の名前(莞爾の草)、もしくはスクリプト名のどれか一つを必ず明記してください。

・商用利用も可。成人ゲームでも使っていただいて構いません。

・他の制作者様のスクリプトとの競合に関しましては一切相談を受け付けません。

バグ報告は当ブログもしくは作者Twitterhttps://twitter.com/kanjinokusa)からお願いします。菓子折りをもって全力で土下座します。

 

【RPGツクールVX Ace】動くタイトル画面を作ろう!(ウィンドウ編)【初心者向け】

どうも、つい最近自転車を撤去された莞爾です。以後気を付けます、もとい、以後お見知りおきを。

f:id:kanjinokusa0405:20170720184429p:plain
さて、デフォルトのタイトル画面には「ニューゲーム、コンティニュー、シャットダウン」のコマンドがありますが、「ウィンドウの位置を変えたーい」とか、「選択肢を中央揃えにしたーい」とか、「ウィンドウを消して選択肢だけにしたいてー」とか、「オリジナルのコマンドをつけくわえたいロドリゲスー」とか、いろいろやりたいことはあると思います。

それとこれは独自の見解ですが、何かと疎まれがちなツクール感はここから出ているような気もします。何て言ったって一番最初にプレイヤーが見る画面ですから。
……と、前置きはさておいて、早速動かしていきましょう。

 

目次

■ウィンドウの位置を変える

■ウィンドウの大きさを変える

選択肢を中央揃えにする(行間の長さを変える)

ウィンドウを消して選択肢だけにする

■選択肢を横に並べる

■オリジナルのコマンドをつけくわえる

 

■ウィンドウの位置を変える

f:id:kanjinokusa0405:20170720184627p:plain

まず、デフォルトのウィンドウの位置はclass Window_TitleCommandのupdate_placementというメソッドの中で決められています。このメソッドはinitializeというクラスを読み込んだ時に一度だけ実行されるメソッドから呼ばれています。

ではさっそく、数値の変えていきましょう。デフォルトのXは(ゲーム画面の横幅(Graphics.width、デフォルトでは544)-このウィンドウの横幅)÷2となっており、Yのほうは(ゲーム画面の縦幅(Graphics.height、デフォルトでは416)×1.6-このウィンドウの縦幅)÷2となっています。

f:id:kanjinokusa0405:20170720185507p:plain

では、試しにこの位置設定の部分を#でコメントアウト(該当の部分を評価しないこと)してみましょう。すると、ほかにこのウィンドウの位置を設定している箇所がないため、ウィンドウX・Yはデフォルト設定の0になります。つまり、こうです。

f:id:kanjinokusa0405:20170720185806p:plain

さて、では次にこのウィンドウを任意の位置に持っていきましょう。例えば、右に50下に300のところに持っていきたいというなら、

f:id:kanjinokusa0405:20170720190625p:plain

こうです。そしてこうすると……

f:id:kanjinokusa0405:20170720190701p:plain

こうなります。だいぶ雰囲気が変わりますね。

ちなみに、Xの数字は数学みたく正のほうに増えるにつれて右のほうにずれ、負のほうに増えると左にずれていきますが、Yは正のほうに増えるにつれて位置が下がっていき、負のほうに増えるにつれて位置が上がっていきます。

X=30,Y=-15の場合の図。

f:id:kanjinokusa0405:20170720190135p:plain

それと、数字で直接指定していると、Graphics.resize_screenで画面のサイズを変えたときや、このウィンドウのサイズを変えたときなんかに、ウィンドウが思ってた位置よりずれてしまうことがあります。

f:id:kanjinokusa0405:20170720191146p:plain

先ほどちょっと触れましたデフォルトの位置設定ではそれを避けるために、直接数字で指定することなく、画面のサイズやこのウィンドウのサイズ、倍率などを使って位置を調整していました。まあ、そんなに頻繁に画面のサイズもろもろを変えることはないと思うので大丈夫だと思いますが、もし気になる方はそういった方法で位置調整すればいいでしょう。

ちなみに、Scene_Titleでも位置を変えることができます。Window_TitleCommandで設定した座標はScene_Titleで設定されたものに加算されます。基本的に使うならどちらか一つでいいです。

f:id:kanjinokusa0405:20170720193220p:plain

 

 

■ウィンドウの大きさを変える

タイトル画面の選択肢のウィンドウの横幅はWindow_TitleCommand内のwindow_widthによって160と決められています。

f:id:kanjinokusa0405:20170720190455p:plain

この数値を変更することによって、ウィンドウの横幅を自由に変えることができます。

ちなみに、縦幅を決めるwindow_heightというメソッドはWindow_TitleCommand内にはなく、Window_TitleCommandのスーパークラスであるWindow_Commandの中に入っています。スーパークラスとは、サブクラス(子クラス、ここでいうWindow_TitleCommand)のもととなるクラスのことで、スーパークラスで決められた命令は、特に変更がない限りサブクラスでも同様に行われます(画像編でもスーパークラスについて説明しています

【RPGツクールVX Ace】動くタイトル画面を作ろう!(画像編)【初心者向け】 - 莞爾の草原。

)。

話を戻します。つまり、Window_TitleCommandクラスにはないメソッドなので、スーパークラスのWindow_Commandからメソッドwindow_heightをコピペしてきます。

f:id:kanjinokusa0405:20170720195645p:plain

「fitting_heightって何?」とお思いの方もいると思います。これはWindow_Commandのスーパークラススーパークラス、Window_Base内にあるメソッドです。ひいおじいちゃんの形見って感じですね。……違いますかそうですか。とにかくスーパークラスは何個でも呼び出せるんです。

f:id:kanjinokusa0405:20170720200336p:plain

見てみると、line_number×行の高さ(デフォルトでは24)+行間(12)×2という計算になっています。このline_numberというのはこのメソッドを呼ぶときに、呼んだ側が指定した引数を格納する変数です。

window_heightではfitting_height(visible_line_number)となっていて、今回はline_numberにはvisible_line_numberが代入されていることになります。このvisible_line_numberというのはWindow_Command内にあるメソッドで選択肢の数を返します。つまり、3です。つまり、Window_TitleCommandデフォルトのウィンドウの縦幅は3×24(行の高さ)+12(行間)×2、ということで96であることが分かります。くどい。

ちなみに、縦幅をwindow_heightの数字より1でも小さくすると、下の図のように矢印が表示され一つ下の選択肢が表示されなくなります。

f:id:kanjinokusa0405:20170720202158p:plain

f:id:kanjinokusa0405:20170720202504p:plain

スクリプトを組めばこうなることを避けることもできますが、特に理由のない限りはwindow_heightの数字より大きい数字にすることをおすすめします。

それと、大きさを変えるとウィンドウが画面からはみ出ることがあります。ウィンドウの位置変更の方法は上記参照。

f:id:kanjinokusa0405:20170720201845p:plain

f:id:kanjinokusa0405:20170720201716p:plain

 それと、WindowクラスはSpriteクラスではないので、ウィンドウを画像として拡大したり角度をつけたりということはできません。

 

選択肢を中央揃えにする(行間の長さを変える)

f:id:kanjinokusa0405:20170720203353p:plain

いくらウィンドウの横幅を大きくできたとしても選択肢が全部左揃えだとなんだかちょっと不揃い感を感じるという人もいると思います。

ということで選択肢を中央揃えにしましょう。

基本的に、ウィンドウ上で文字を描写するときはWindowクラスのcontentsというBitmapのdraw_textというメソッドを使うのですが、このときに文字のアライメント(揃え方)を決めることができます。そして、そのアライメントはWindow_Command内で自由にいじれるようになっています(デフォルトで)。

そういうことで、アライメントを決めているこのdef alignmentをWindow_TitleCommandにコピペします。

f:id:kanjinokusa0405:20170720203808p:plain

アライメントの設定は簡単で、0が右揃えで、1が中央、2が左です。今回は中央揃えなのでreturn 0の0を1に変えます。

f:id:kanjinokusa0405:20170720204641p:plain

 

 

f:id:kanjinokusa0405:20170720204715p:plain

するとちゃんと中央揃えになります。

ちなみにこれ、RPGツクールVX Ace付属の説明書にちゃんとやり方が書いてあります。だからといって受け売りを話してたわけじゃないですけど。受け売りを話してたわけじゃないですけど。

f:id:kanjinokusa0405:20170720204909p:plain

 

次に行間を広くします。こんな感じです。

f:id:kanjinokusa0405:20170720215008p:plain

f:id:kanjinokusa0405:20170720215140p:plain

まず、Window_Baseからline_heightというメソッドをWindow_TitleCommandに持ってきます。次に任意の高さに変えます。これだけです。

 

 

ウィンドウを消して選択肢だけにする

f:id:kanjinokusa0405:20170720205404p:plain

これも説明書にやり方が書いてあるので、使用例だけ紹介するとこんな感じです。

f:id:kanjinokusa0405:20170720205612p:plain

f:id:kanjinokusa0405:20170720205708p:plain

ただ、デフォルトだと黒い影が薄いので、Window_Commandからdraw_itemをコピペしてきてこうすると影が濃くなります。

f:id:kanjinokusa0405:20170720210139p:plain

f:id:kanjinokusa0405:20170720210216p:plain

 

■選択肢を横に並べる

f:id:kanjinokusa0405:20170720211042p:plain

ちょうどこんな感じです。ではさっそく作っていきましょう。

f:id:kanjinokusa0405:20170720212013p:plain

変更点は3点。まとめるとこんな感じです。

スーパークラスをWindow_CommandからWindow_HorzCommandに変える。

・新たにcol_maxというメソッドを設ける。

・window_widthをGraphics.widthに変える。

これだけでOKです。Window_HorzCommandのスーパークラスがWindow_Commandのため、Window_Commandのメソッドも使うことができます。

 

オリジナルのコマンドをつけくわえる【上級者向け】

 これ、コマンドを作るだけなら簡単ですが、その先の実行内容を作るのは上級者向けです。いろんなケースが想像できるので、全てを対応することはできませんのでコマンドの作り方だけを説明していきます。

まずWindow_TitleCommandクラスのメソッドmake_command_listに任意のコマンドを付け加えます。

f:id:kanjinokusa0405:20170720213026p:plain

次に、Scene_Titleのcreate_command_windowにも同じ任意のコマンドを加えます。どちらかが抜けているとうまく実行しません。

f:id:kanjinokusa0405:20170720213433p:plain

そして次に、set_handlerの中で作ったメソッドを作ります(この場合command_additionになります)。

f:id:kanjinokusa0405:20170720214107p:plain

f:id:kanjinokusa0405:20170720213700p:plain

 起動するとこうなります。

ただ、今回の場合command_additionの中が空なので、このコマンドを押すとフリーズします。

ここから先どうするのかはあなた次第です。

 

さて、この記事で私は何回デフォルトという言葉を使ったでしょうか。あ、数えなくて結構です。

【RPGツクールVX Ace】動くタイトル画面を作ろう!(天候編)【初心者向け】

どうも。RGSS3(VX Ace)歴4年のかんじの草です。今回はタイトル画面に雨(その他)を降らせていきたいと思います。

前回(【RPGツクールVX Ace】動くタイトル画面を作ろう!(画像編)【初心者向け】 - 莞爾の草原。)に引き続いて初心者向けに書いていこうと思うのですが、スクリプトを学んでいくうえで何よりも大切なことは、スクリプトに苦手意識を持たないことです。

スクリプトは怖いものじゃない」「スクリプトはあなたのツクールライフをよりよくするものだ」

そう頭に念じてやっていきましょう。冗長だ。

 

以下のスクリプトを▼ 素材の下に貼り付けることでタイトル画面に雨を降らせることができます(上書きなので注意)。デフォルトとの相違点は青文字で記します。

#==============================================================================
# ■ Scene_Title
#------------------------------------------------------------------------------
#  タイトル画面の処理を行うクラスです。
#==============================================================================

class Scene_Title < Scene_Base
#--------------------------------------------------------------------------
# ● 背景の作成
#--------------------------------------------------------------------------
def create_background
@sprite1 = Sprite.new
@sprite1.bitmap = Cache.title1($data_system.title1_name)
@sprite2 = Sprite.new
@sprite2.bitmap = Cache.title2($data_system.title2_name)
@sprite1.z=-50
@sprite2.z=-50
center_sprite(@sprite1)
center_sprite(@sprite2)
@weather = Spriteset_Weather.new(Viewport.new)
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
@weather.type = :rain

#:rain(雨)の部分を

#:stormに変えると嵐になり、

#:snowに変えると雪になり、

#:noneに変えると天候がなくなります。
@weather.title=true#true=天気がタイトルから呼び出されている
@weather.power = 15#天気の強さ。マップでいじる天気の強さと同じ
@weather.ox = 0
@weather.oy = 0
@weather.update
end
#--------------------------------------------------------------------------
# ● 背景の解放
#--------------------------------------------------------------------------
def dispose_background
@sprite1.bitmap.dispose
@sprite1.dispose
@sprite2.bitmap.dispose
@sprite2.dispose
@weather.dispose
end
end

#==============================================================================
# ■ Spriteset_Weather
#------------------------------------------------------------------------------
#  天候エフェクト(雨、嵐、雪)のクラスです。このクラスは Spriteset_Map クラ
# スの内部で使用されます。
#==============================================================================

class Spriteset_Weather
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :title #Spriteset_WeatherクラスがTitle画面から呼び出された時にtrueになる。
#--------------------------------------------------------------------------
# ● 暗さの取得
#--------------------------------------------------------------------------
def dimness

#Spriteset_WeatherがScene_Titleから呼び出されているときに、@titleがtrueになります。
@title ? 0 : (@power * 6).to_i
end
#--------------------------------------------------------------------------
# ● メンバ変数の初期化
#--------------------------------------------------------------------------
def init_members
@type = :none
@ox = 0
@oy = 0
@power = 0
@sprites = []#はてなの仕様上全角にしてあります。半角に変えてください

@title=false
end
end

 

f:id:kanjinokusa0405:20170701233449p:plain

ただ、これだけだとやや地味というか、まだ何か足りない……そう思う方もいるかもしれません。

では、いろいろカスタムしていきましょう!

 

【目次】

・タイトル画面にBGSを流そう!

・雨の画像を編集しよう!

 

 

 

 

・タイトル画面にBGSを流そう!

せっかく雨を降らせたのなら、是非とも雨の音もつけたいですよね。

ということで付けていきましょう。

#--------------------------------------------------------------------------
# ● タイトル画面の音楽演奏
#--------------------------------------------------------------------------
def play_title_music
$data_system.title_bgm.play
RPG::BGS.stop
RPG::ME.stop
RPG::BGS.stop
Audio.bgs_play('Audio/BGS/Rain',70)
end

上がスクリプトです。Scene_Titleに貼り付けてください。どこにでも貼り付けていいわけではなく、それは前回の画像編で解説しているとおりです。どこに貼ればいいかわからない方はclass Scene_Title < Scene_Baseのすぐ下に貼り付けてください。

上の青字の部分は、Audioというモジュールから実行するBGS:Rainをボリューム70で再生するように命令しているメソッドです。モジュールとは、前回使用したCacheやGraphics、VocabやSoundなどの、クラスのどこからでも呼び出せる、ざっくり言えばクラスより強い奴です。モジュールの名前は必ず大文字から始まらなくてはなりません。

また、青の上にあるRPG::BGS.stop、RPG::ME.stop、RPG::BGS.stopのRPG::○○(音楽の種類)の中でも一様にこのAudioのモジュールが使われています。

f:id:kanjinokusa0405:20170702002928p:plain

Audio.bgs_playというメソッドには引数という呼び出すときに必要なものがあります。それが、()のなかにあるものです。なのでAudio.bgs_play('Audio/BGS/Rain',70)の引数は、'Audio?BGS/Rain'と70という数字となります。

「'Audio?BGS/Rain'はファイル名だとして、70って何?」とお思いの方もいるかもしれません。こういった引数がなにかわからないときは、呼び出し元のメソッドを見ましょう。説明書のAudio(モジュール)のページには、

Audio.bgs_play(filename[, volume[, pitch[, pos]]]) (RGSS3)

BGS の演奏を開始します。順にファイル名、ボリューム、ピッチ、再生開始位置を指定します。

再生開始位置 (RGSS3)ogg または wav の場合のみ有効です。

RGSS-RTP に含まれるファイルも自動的に探します。拡張子は省略可能です。

 とあります。

つまり引数70の正体は二番目のvolume、つまり音量ということになります。

三番目のpitchというのは文字通りピッチのことで、posというのは再生開始位置を指します。

ちなみに、引数の中にある[](半角角かっこ)は、必要ではない引数のことで、省略しても問題がないです。だから、70の引数を消してAudio.bgs_play('Audio/BGS/Rain')としてもちゃんとメソッドを実行することができます。

 

・雨の画像を編集しよう!

「雨をもっと大きくしたい」「雨の色を変えたい」など、いろいろとやりたいことが出てくると思います。スクリプトを知ると可能性が広がり、同時に視野も広くなってくるでしょうからね。

ということで、画像を編集していきましょう。

 

例えば、「大きい雨と小さい雨を分けてタイトル画面に奥行きを出したい」とします。

そんな時はこうしましょう。

class Spriteset_Weather
#--------------------------------------------------------------------------
# ● スプライトの追加
#--------------------------------------------------------------------------
def add_sprite
sprite = Sprite.new(@viewport)
sprite.opacity = 0
if @title
sprite.zoom_x=s=rand(40)/10
sprite.zoom_y=s
end
@sprites.push(sprite)
end

end

これを実行するとこうなります。

f:id:kanjinokusa0405:20170702005754p:plain

四角!って感じですが、動画で見てみると結構いい感じです。

さて、なにをしたかというと、「もし@titleがtrueならば、sprite(パーティクル)の拡大率を「0から39のうちの乱数を10で割ったもの」にする」というものです。zoom_xとzoom_yは前回の画像編で触れたスプライトのプロパティです。このspriteは文字通りSpriteクラスのものなので、Spriteクラスにできるプロパティやメソッドなら好きに実行することができます。

f:id:kanjinokusa0405:20170702010815p:plain

例えば、 sprite.mirror =rand(3)==1;sprite.blend_type =2;sprite.angle=(361)とするとこんな感じにちゃんと動作します。趣味が悪いわ。

f:id:kanjinokusa0405:20170702012909p:plain

case rand(3)
when 0
sprite.color=Color.new(255,0,0)
when 1
sprite.color=Color.new(0,255,0)
when 2
sprite.color=Color.new(0,0,255)
end

 

また、雨雪嵐のほかに、自分が用意した画像を降らせることもできます。

#--------------------------------------------------------------------------
# ● スプライトの更新[雨]
#--------------------------------------------------------------------------
def update_sprite_rain(sprite)
sprite.bitmap = @title ? Cache.system("Ball") : @rain_bitmap#ここのキャッシュの部分を変える
sprite.x -= 1
sprite.y += 6
sprite.opacity -= 12
end

ただ、あまり画像が大きすぎると重くなので注意が必要です。ちなみに、sprite.x -= 1;sprite.y += 6の数字の部分を変えることで粒子の落ち方を変えることができます。例えばsprite.y -= 6とすると、粒子が上がっていきます。

f:id:kanjinokusa0405:20170702012015p:plain

f:id:kanjinokusa0405:20170702012148p:plain

これにさっきの拡大率を変える奴を使うとこんな感じ。内部的には雨の設定となっています。

 

 

【RPGツクールVX Ace】動くタイトル画面を作ろう!(画像編)【初心者向け】

本記事はVX Ace初心者の方、もしくはスクリプトがよくわからない方を対象に書いていきます。なので、分かりやすいように、だいぶざっくりとした説明をしていきます(悪くいえば大雑把?)。また、スクリプトの大まかな仕組みを理解して頂けるよう、ちょっと踏み込んだ話もしています。「そういうところは読み飛ばしたい!」という方は、青字の部分だけお読みください。

もし至らない点、こうするにはどうすればいいか、などのご質問がありましたらお気軽にコメントしてください。

 

【目次】

1.画像を動かそう!

2.画像を増やそう!

3.画像を編集しよう!

 

f:id:kanjinokusa0405:20170701051151p:plain

さて、改めてVX Aceのタイトル画面を見てみましょう。

デフォルトでは「暗転する」「カーソルを動かす」以外の動きがありません。

これはいわば真っ白なキャンバスのようなもので、実はスクリプトで改造しやすくするためにこのようなシンプルな形になっているのです(独自研究含む)。真っ白なまま使うのもいいですが、やはり、動画としてみたとき、それはやや地味に写るでしょう。

 

ということで早速動きをつけていきましょう!(スクリプトを見ながら読んでいくと分かりやすいと思います)

 

1.画像を動かそう!

まず初めにタイトル画面で画像を動かしていきましょう。ですがその前に、要となるdef updateというメソッドを見ていきましょう。このメソッド、クラスScene_Title(タイトル画面の画像、音楽などをつかさどるクラス)内にはないのですが、実はクラスScene_TitleのスーパークラスとなるクラスScene_Base内にちゃんと入っています。

f:id:kanjinokusa0405:20170701052025p:plain

「メソッドもクラスもスーパークラスもよく意味が分からない!」という方にざっくり説明すると、クラスの中にいくつかのメソッド(操作。実行するコード)とプロパティ(属性。オブジェクト固有のデータで、オブジェクトの性質や設定に関する情報)が入っていて、スーパークラスというのは、そのクラスのベースとなるクラスのことを指します。

def updateは1フレームごとに実行され、画面や入力情報をリフレッシュするメソッドで、大体の場合これがないとゲームがフリーズしてしまいます。では、なぜdef updateのないScene_Titleがフリーズしないのかといえば、前述したScene_Titleのベースとなるスーパークラスの中にdef updateがあるからです。Scene_Base内のdef updateがScene_Titleの中で使われているのです。

そして、def updateの中で何が行われているか見てみましょう。

def updateの下に「update_basic」という文章がありますが、これはdef update_basicを呼び出しているのです。

メソッド内で他のメソッドを呼び出す際には、defを取って後に続くメソッド名だけを書きます。

f:id:kanjinokusa0405:20170701053921p:plain

def updateは必ず1フレームごとに実行されるので、def update_basicもまた、必ず1フレームごとに実行されています。画像を動かすのに使うメソッドは、別にdef updateでもdef update_basicでもどちらでもよいのですが、今回はわざわざ行数が多いdef update_basicを使わずに、def updateのほうを使いましょう。

また、スーパークラスからメソッドを持ってくるとき、superをつかってメソッドの内容を省略することができます。例えば、

def update_basic

Graphics.update

Input.update

update_all_windows

end

をScene_Titleに持ってくるとき、確かにこれでもいいのですが、

def update_basic

super

end

とすると、この一行だけで上の三行と同じメソッドを実行します。

つまりこの場合、super = Graphics.update Input.update update_all_windowsということになるわけです。

覚えておいて損はないでしょう。

f:id:kanjinokusa0405:20170701054722p:plain

Scene_Titleに、Scene_Baseから持ってきたdef updateを貼り付けます。ただ、どこにでも貼り付けていいというわけではありません。実はメソッドやクラス、条件文を終わらせるときには必ずendをつけなければならないという決まりごとがあって、そのendの数が合わなかったり、変な場所でendが使われたりすると、エラーを吐き出してしまうからです。また、メソッド内でメソッドの定義(define)をすることできません(基本的にね)。

なので、どこがメソッド(クラス)とendとの間かわからない方は、上の画像の位置に挿入することをお勧めします(行数にして8行目)。

また、ifやwhenやtimesなどの条件文や繰り返し文の終わりの際にもendを使うため、単にdefとendの間だからといってやすやすと挿入できないので注意。

f:id:kanjinokusa0405:20170701055455p:plain

f:id:kanjinokusa0405:20170701055719p:plain

さて、やっと画像を動かしていくわけですが、まずは既存の、タイトルの遠景から動かしていきましょう。ここからはスクリプトウィンドウの右下にあるヘルプ(H)を押して、説明書を読みながら進めていくことをお勧めします。

Scene_Title内では、タイトルの遠景はインスタンス変数@sprite1の中にSpriteとして格納されています。説明書の検索(S)から「Sprite」と検索し、Spriteの頁を開いてください。

f:id:kanjinokusa0405:20170701060823p:plain

そこによると、スプライトのX座標はxで管理されているとあります(実はスプライトもクラスの一つで、xやyはそのクラス内のプロパティです)。

では、def updateを利用して、1フレームごとにスプライト@sprite1のxに+1していきましょう。

f:id:kanjinokusa0405:20170701061437p:plain

#(シャープ)は実行しない部分なので写さなくていいです。

それではゲームを起動してみましょう。

f:id:kanjinokusa0405:20170701061602p:plain

タイトル画面が動きました! +で右に、-で左に進み、xではなくyにしたときは、+で下に、-で上に進みます!

ただ、これだと遠景が行ったっきりで帰ってきません。背景が黒くなってしまいます。

f:id:kanjinokusa0405:20170701061833p:plain

「遠景をループさせたい……」という方にはこちら。まず、Scene_Title内にあるdef create_backgroundの、@sprite1 = Sprite.newという箇所を@sprite1 = Plane.newとし、そのすぐ下にあるcenter_sprite(@sprite1)という文章の頭に#(半角シャープ)をつけます。

次に、def updateの中にある、さっき書いた@sprite1.x+=1の.xという部分を、.oxに書き換えます。

f:id:kanjinokusa0405:20170701062416p:plain

プレーン(クラス)とは、ビットマップのパターンを画面全体に並べて表示する特殊なスプライトで、プレーンの中にはxとyというプロパティがなく、その代わりにoxとoyというプロパティ使います。ちなみにスプライトにもoxとoyというプロパティはありますが、そっちは一般的に画像を動かすのではなく、画像の原点をずらすときに使います。

スプライトとプレーンは二つとも同じObjectというスーパークラスを持ちますが、共有しないプロパティが多いで、説明書で確認するなど、注意してください。

f:id:kanjinokusa0405:20170701063546p:plain

そして、今遠景にしたことは近景にも同様に動作します。近景のスプライトを保管しているのはインスタンス変数@sprite2です。上の画像ではこのようにスクリプトを組んで動かしています。

f:id:kanjinokusa0405:20170701063721p:plain

それと、タイトルの文字は@foreground_spriteにスプライトとして保管されており、動かすことも可能です。

 

 

 

2.画像を増やそう!

さて、今まで既存の画像だけを動かしてきましたが、「遠景でも近景でもないもう一つの画像を表示したい!」という方もいると思います(多分)。

f:id:kanjinokusa0405:20170701065218p:plain

例えば上の画像のように。

「そんなの遠景や近景のどちらかに直接画像編集で貼り付ければいいじゃん!」と、お思いになるかも知れませんが、もしかしたら「遠景と近景を両方バラバラに動かして、真ん中に動かない画像を置きたい!」というときが来るかもしれません。そんなときのために、一緒に学びましょう。

実はこれ、簡単なお約束さえ覚えればさして難しい内容ではありません。

1・画像を表示する

2・画像を削除する

たったこれだけです。

では見ていきましょう。

 

1・画像を表示する

上の図の場合はこうなります。

#--------------------------------------------------------------------------
# ● 背景の作成
#--------------------------------------------------------------------------
def create_background
@sprite1 = Sprite.new
@sprite1.bitmap = Cache.title1($data_system.title1_name)
@sprite2 = Sprite.new
@sprite2.bitmap = Cache.title2($data_system.title2_name)
center_sprite(@sprite1)
center_sprite(@sprite2)
@sprite3 = Sprite.new

@sprite3.bitmap = Cache.battler("Angel",0)

@sprite3.z=@sprite1.z+1
@sprite2.z=@sprite3.z+1

center_sprite(@sprite3)

end

解説していくと、一行目の「@sprite3 = Sprite.new」が、「@sprite3に新しくスプライトのクラスを代入する」という意味です(ちなみに、sprite3の部分の変数名は別になんて名前を付けてもいいです)。

二行目の「@sprite3.bitmap = Cache.battler("Angel",0)」は、「@sprite3のビットマップに、Cacheというモジュールのbattlerというメソッドが返したビットマップを代入する」ということです。

勘のいい方はもう気付かれたと思いますが、これ実は遠景と近景を呼び出した時と全く同じです。

@sprite1 = Sprite.new
@sprite1.bitmap = Cache.title1($data_system.title1_name)
@sprite2 = Sprite.new
@sprite2.bitmap = Cache.title2($data_system.title2_name)←これ

この呼び出し方は全てのスプライトに共通します。ただ、Cacheから呼び出すのではなく、直接Bitmapのクラスで返すこともありますが、今のところこれはどうでもいい話です。

それと、メソッドを呼び出すのに引数(argument)が必要な場合があり、その際に引数を指定していないと「wrong number of arguments(指定した引数の数 for 実際に必要だった引数の数)」というエラーが出てきます。

スクリプトの上のほうにあるCacheを見てみると、● 戦闘グラフィックの取得 の引数はself.battler(filename, hue)とあるので二つであるということが分かります。他のCacheの引数はアニメーションを除いてすべて一つなので、油断していると結構間違えるので注意。

 

次に、@sprite3.z=@sprite1.z+1ですが、このzというのは画像表示の優先順位のことで、例えば、Aという画像とBというスプライトがあったとき、AもBもz軸の数字は等しく0ですが、後に作成されたスプライトのほうが手前に表示されますが、Aのz軸が1でもBより大きければ、AはBより手前に表示され、その逆もしかりです。

今回は、天使のキャラ(@sprite3)を近景(@sprite2)の後ろに表示するために、

@sprite3.z=@sprite1.z+1;@sprite2.z=@sprite3.z+1と書きました。


center_sprite(@sprite3)

これはScene_Titleの中だけのメソッドです。このメソッドの中では、かっこで指定された変数の中に入っているクラス:スプライトの、プロパティx(もしくはy)を参照する箇所があるので、プロパティにxとyがないクラス:プレーンにこれを使うとエラーが出ます。さっき、SpriteをPlaneに変える際に、center_spriteの先頭に#をつけるようにしたのはそのためです。

 

ちなみに、スプライトのクラスを代入する変数は、今回はインスタンス変数を使いましたが、別にローカル変数でもグローバル変数でもクラス変数でも構いません。変数の特性に関しては、説明書の「変数と定数」を参照してください。ちなみに、Scene系でスプライトやプレーンを表示するときは、もっぱらインスタンス変数が使われています。というか、特に理由のないとき以外はわざわざインスタンス変数以外の変数を使う必要はありません。

2・画像を削除する

スプライトやプレーン、ビットマップなどの画像類は、バグを防ぐために一度生成したら消さなければなりません。

では試しに、画像を消さないとどういうことになるのか見てみましょう。

こうなります。デン

f:id:kanjinokusa0405:20170701073634p:plain

「まあデザイン的にはこれでもアリかな……」って気もしますが、ダメなものはダメです。

こうならないためにも必ず画像を削除しましょう。

これもあまり難しい話ではないのでご安心を。

Scene_Title内にあるdef dispose_backgroundに、「

@sprite3.bitmap.dispose

@sprite3.dispose

」と付け加えるだけです。
これも、上にある

@sprite1.bitmap.dispose
@sprite1.dispose
@sprite2.bitmap.dispose
@sprite2.dispose

と同じです。

disposeとは英語で「削除する」を意味し、@sprite3.bitmap.disposeは、@sprite3.bitmap = Cache.battler("Angel",0)としたときに代入した「ビットマップ(Cache.battler("Angel",0))を削除する」という意味で、@sprite3.disposeは@sprite3 = Sprite.newのときに代入した「Spriteのクラスを削除する」という意味です。なお、この二行を逆にしてはいけません。

【悪い例】

@sprite3.dispose

@sprite3.bitmap.dispose

こうすると、@sprite3の中にあるスプライトのクラスが削除され、@sprite3の変数の中には何もないのに、bitmapというメソッドを呼び出し、削除しようとしていることになります。

 

f:id:kanjinokusa0405:20170701083828p:plain



とりあえず、今のうちは@sprite1と@sprite2の動きをならっているだけでいいでしょう。

 

f:id:kanjinokusa0405:20170701075522p:plain

削除すれば、ロード画面に天使が表示されることはなくなります。

 

 

3.画像を編集しよう!

さて、今のところスプライトに使ったメソッドはx、yzbitmapdisposeの5つだけですが、説明書のスプライトのページを見れば、まだまだたくさんメソッドがあることがわかります。簡単なものから見ていきましょう。

・disposed?

スプライトがすでに解放されている場合には真(true)を返します。主にif,unlessなどの条件文や、p などとともに使います。

例:

p "deleted" if @sprite3.disposed? => "deleted"

p @sprite3.disposed? => true

 

flash(color, duration)

スプライトのフラッシュを開始します。duration はフラッシュにかけるフレーム数です。

color に nil を指定した場合は、フラッシュの時間分スプライト自体を消去します。

例:

def update
@sprite3.flash(Color.new(255,255,255),15)
update_basic
end

f:id:kanjinokusa0405:20170701082010p:plain

・width
スプライトの幅を取得します。src_rect.width と等価です。

例:

p @sprite3.width => 384

 

・height
スプライトの高さを取得します。src_rect.height と等価です。

例:

p @sprite3.height => 288

 

・x
画像x軸の座標です。

・y

画像y軸の座標です。

・z 

画像z軸の座標です。数値が大きいほど手前に表示され、値が等しい場合は後に生成されたものが手前に表示されます。

 

・ox

画像x軸の原点。

 

・oy 

画像y軸の原点。

 

・opacity

 スプライトの不透明度です。0 ~ 255 の範囲で指定します。範囲外の値は自動で修正されます。
例:

@sprite3.opacity=0

 

・src_rect
ビットマップから転送される矩形 (Rect) です。Rectとは画像の大切な四要素(x,y,width,height)を含む四角形のクラス。

例:

p @sprite3.src_rect  => (0, 0, 384, 288)

 

・viewport
スプライトが関連付けられているビューポート (Viewport) への参照です。 画面の一部にスプライトを表示し、他の部分にはみ出さないようにしたい場合に使用します(トリミング)。

例:

@viewport=Viewport.new(0,0,300,280)
@viewport.z=150
@sprite3.viewport=@viewport
f:id:kanjinokusa0405:20170701091550p:plain

個人的にあんまり好きじゃないです。

 

・visible

スプライトの可視状態です。trueのとき可視になります。
また、falseにすると、opacityに関係なく画像を透明にできます。

例:@sprite3.visible=false

 

・zoom_x

スプライトの X 方向拡大率です。1.0 で等倍になります。

・zoom_y

スプライトの Y 方向拡大率です。1.0 で等倍になります。
例:

@sprite3.zoom_x=4
@sprite3.zoom_y=2.5

f:id:kanjinokusa0405:20170701091850p:plain

 

 

・angle

スプライトの回転角度です。反時計回りを正とする 360 度系で指定します。回転描画には時間がかかりますので、多用は避けてください。

例:

def update
update_basic
@sprite3.angle+=1
end

f:id:kanjinokusa0405:20170701092155p:plain

 

・mirror

スプライトの左右反転フラグです。真のとき反転して描画されます。初期値は false です。

例:

@sprite3.mirror=true

f:id:kanjinokusa0405:20170701092509p:plain

 

・bush_opacity

・bush_depth

 下の一部だけ半透明にします。透明度をbush_opacityで決められ、0で透明になる。bush_depthで、どれだけ下まで半透明にするか決められる。

例:

@sprite3.bush_depth =150
@sprite3.bush_opacity =120

f:id:kanjinokusa0405:20170701092720p:plain

 

・blend_type

スプライトの合成方法 (0:通常、1:加算、2:減算) です。

例:

@sprite3.blend_type=2#減算

f:id:kanjinokusa0405:20170701093252p:plain

・color

スプライトを特定の色に染めます。アルファで濃さを調整できます。

例:

@sprite3.color =Color.new(255,0,0,255)

f:id:kanjinokusa0405:20170701093450p:plain

 

・tone

スプライトの色調を変更します。

例:

@sprite3.tone=Tone.new(255,0,0)

f:id:kanjinokusa0405:20170701093928p:plain

・wave_amp

・wave_length

・wave_speed

・wace_phase

波形描画のための振幅、周期、速度、位相です。波形描画とは、スプライトを正弦波関数によりラインごとに横にずらして描画するもので、いわゆるラスタスクロールのような表現を行います。

wave_amp には波形の振幅を、wave_length には波形の周期を、それぞれピクセル数で指定します。

wave_speed は波形がアニメーションする速度を指定します。規定値は 360 で、値が大きいほど速くなります。

wave_phase はスプライトの一番上のラインでの位相を 360 度系の角度で指定します。これは update メソッドが呼ばれるごとに更新されます。波形描画を行うスプライト同士で同期を取る必要がある場合以外、特にこのプロパティを使用する必要はありません。

例:

  def create_background
@sprite1 = Sprite.new
@sprite1.bitmap = Cache.title1($data_system.title1_name)
@sprite2 = Sprite.new
@sprite2.bitmap = Cache.title2($data_system.title2_name)
center_sprite(@sprite1)
center_sprite(@sprite2)
@sprite3 = Sprite.new
@sprite3.bitmap = Cache.battler("Angel",0)
center_sprite(@sprite3)
@sprite3.wave_amp=10
@sprite3.wave_length=15
@sprite3.wave_speed=360
@sprite3.wave_phase=200

end

def update
update_basic
@sprite3.update
end
f:id:kanjinokusa0405:20170701094258p:plain

こんなものほとんど使ったことがないです

 

 

さて、いかがだったでしょうか。なるべく簡潔でわかりやすいように、と書いてみたのですが、気付いたころには文字数が8800字を超えていました。実は、Bitmapクラスを利用してまた別の画像編集をすることができるのですが、それはまたの機会に書きたいと思います。

次回はタイトル画面に雨や雪、その他を降らせる方法を書いていきます。

【製作中ホラゲ】デイドリーム・リバーのプロローグと製作の方針

莞爾です。Twitterでは書ききれない内容もあるので、こちらに書くことにしました。

 

ということで、さっそく始めていきたいと思います。

f:id:kanjinokusa0405:20170625172939p:plain

※画像は制作中のものです。

※15禁です。流血表現があります。

 

f:id:kanjinokusa0405:20170625173011p:plain

何やら意味深なOPから始まります。

 

f:id:kanjinokusa0405:20170625173223p:plain

朝、登校してきた中学生の伊沢京介(いさわ・きょうすけ)は、理科室で死体が見つかったと騒ぎになっていることに気づきます。

f:id:kanjinokusa0405:20170625173448p:plain

そして、教師の話声から、その死体の主が伊沢と同じテニス部の佐々木翔(ささき・しょうま)であるのではないかと疑い始めます。

 

伊沢の友人の籏崎健斗(はたざき・けんと)は登校中、佐々木の母親が泣きながら「翔真を見なかったか?」と聞いて回っていたのを目撃していました。そのことを聞いても、伊沢はまだ佐々木が死んだことを信じられずにいました。

f:id:kanjinokusa0405:20170625174205p:plainですが、籏崎の携帯に入っていた佐々木からの留守番電話を聞き、伊沢は佐々木の死を信じざるを得なくなります。

f:id:kanjinokusa0405:20170625174348p:plain

f:id:kanjinokusa0405:20170625174520p:plain

伊沢と籏崎は、何が佐々木を死に至らしめたのかを知るために、部活動を無断で休んで夜中の学校に行くことを決意します。

f:id:kanjinokusa0405:20170625174850p:plain

そこに、引退したテニス部の先輩である岡梨優也(おかなし・ゆうや)が現れ、彼らが部活に参加しなかったことを受け、何があったのかを探ってきます。

f:id:kanjinokusa0405:20170625175217p:plain

事情を知った岡梨は叱らないまでも、「自分もそういうことに興味がないわけではない」といって二人をやんわりと注意します。それを聞いた籏崎は、何を勘違いしたのか岡梨を夜中の学校に誘います。そして、何を思ったのか岡梨は二人に同行することを決意します。

 

f:id:kanjinokusa0405:20170625175907p:plain

そうして、3人は夜中の学校に集まります。

 

……これより先は製作中です

f:id:kanjinokusa0405:20170625180016p:plain

f:id:kanjinokusa0405:20170625180132p:plain

f:id:kanjinokusa0405:20170625180242p:plain

f:id:kanjinokusa0405:20170625180328p:plain

 

【今後の抱負】

 昔から映画が好きでよく見ていて、ホラー映画もそのうちです。そして、ホラー映画を見ているときに共通して「容赦ないな」って思うんですよ。

 足を折ったり、爪を(自主規制)だり、目に(自主規制)したり……普通の人間ならそんなこと躊躇してしまってまずできないでしょう(できるという人は正真正銘アブノーマルです。おめでとうございます)。そしてそれに恐怖を感じて脂汗を流している自分がいるわけですよ。

 だから、製作の方針本の矢の一つには「容赦しない」を挙げたいと思います。むしろ、腹籠りを刺殺して中のモノに乱暴するくらいの心意気がないようではホラーゲームなんて作れるはずがないんですよ、思うにの話ですけど。とかく、目をそむけたくなるほどおぞましく猟奇的でなければ、真のキチガイホラー通を納得させるような作品は作れないと思うんです。私が作りたいのは小奇麗な人形劇ではなく、理不尽でえげつない陰湿な質の悪いハエのたかった残飯のような作品なんです。

 そして、三本の矢二本目は「不意をつく」ことです。ホラーといえばこれって感じもするほど大切な要素です。気を抜いているときにサッと不意をつくこと。言って僕も作者でありプレイヤーであるわけですから、いつ気を抜いているのかというのは手に取るようにわかるわけです。

 気を抜いているときというのは、比較的何かに没頭しているときが多くて、例えば本を読んでいる最中に、急に目の前に誰かの手が見えたら、本を読んでない時と比べて格段に驚くでしょう。また、一人だと思って気を抜いてたら人がいることに気付いたり、ドアを開けようとしたら急に人が出てきたり、そんなときにも人は驚きます。つまり、驚くということは、予期していたものとは違うことが起こったときにおこる本能的な習性ですから、人間の本能に沿うように作っていけば、きっとより強く驚かすことができるはずです。

 そして、三本の矢三本目は「雰囲気を作る」ことです。なによりも大切なのがこれです。雰囲気というのはざっくり言うと「いつか何か出てくるんだろうなぁ」とプレイヤーに警戒させることです。警戒しているときの息苦しさはなんといってもホラーの醍醐味といえるでしょう。そしてそれを作るためには、まず最初の段階で大きめのジャブを打つ必要があります。そうすることによってプレイヤーが「このゲームは人畜無害じゃない」と早いうちから警戒する、いい雰囲気ができるのです。

 「容赦しない」「不意をつく」「雰囲気を作る」……この三つの矢を胸に突き刺して、作っていこうと思います。