2015年12月14日

DXRubyAdventCalender2015 14日目

この記事はDXRuby Advent Calendar 2014の14日目です。

今年も昨年に引き続きDXRubyWSを使った作例の紹介になります。

■DXRubyWSを使ってゲームっぽいもの作ろう



2014年はDXRubyWSを使って作ったエフェクト作成ツールと、そのツールで作ったエフェクトをプログラム上で再生するデモを紹介しました。

今年はDXRubyの基本に立ち戻りDXRubyWSを使ったゲームを作ろうと思います。

DXRubyWSはWindowSystemの名の通りDXRuby上でWindowベースのGUIを作るのに適したライブラリです。
機能を見るとどっちかというとアプリ向けでありゲームに使うにはオーバースペックという意見が見られます。
ただ、スプライトを階層化して管理する機能を上手く使えばゲーム制作にも便利だと思います。

実用上はマウスで操作するゲームのメニュー部分なんかをWSで作って、ゲーム部分は自分で作るみたいな使い分けをするような形になるでしょうか。

どのような形が一番いいのかはわからないですが、今回はWSの機能を積極的に使う方向で考えてみます。

まずはどういうゲームがいいか考えましょう。

WSにはマウスイベントを受け取る機能があります。
WSのコントロールオブジェクトに対してクリックやドラッグなどを行うと、それに応じて処理を実行してくれるので、それを軸にしてみます。

マウスを使うゲームというとOSU!みたいなタイプの音ゲー、メイドインワリオのタッチペン使って遊ぶようなミニゲームなどが候補でしょうか。

ということで、今回はうちのマスコットエイプリルの頭をなでなでするゲームで行きます。

■エイプリルなでなでゲーム(仮)



まずは簡単に構造を考えましょう。

WSでアプリを作る時はウィンドウを作ってそこにボタンやらチェックボックスやらコントロールを配置します。
WSControlオブジェクトはWSContainerによって管理され、コンテナが配下のコントロールにイベントを流します。
ウィンドウがコンテナで、ボタンなどがコントロールですね。

標準コントロールのウィンドウをそのまま使ってもよいですが、標準のウィンドウはいろいろと機能がついていて、今回はそれらは使わないのでGameScreenというコンテナを作ってそれにコントロールを管理してもらうことにしましょう。

さて、他に必要なものは、なでなでされるキャラクターですね。
これは単純コントロールとして作ってもよいのですが、コンテナとして内部をパーツ分けすると別のものに使い回す時に便利だと思われるので、Charaというコンテナを作って中にパーツを配置していく形にします。

中身についてですが、せっかくなので表情の変化なども行えるようにキャラクターのベースと顔を分けておこうと思います。
また、マウスで左右にドラッグするとなでなでしていると判定される判定用のコントロールも作りましょう。

必要なものと構造をまとめるとこのような感じですね。

WS.desktop
聾SGameScreen
 聾SChara
  聾SFace
  聾SNadeNadeArea

全部説明すると長くなってしまうので特に重要な部分だけ簡単に解説します。


module WS
class WSChara
### なでなで判定エリア ###
class WSNadeAreaA < WSControl
include Draggable
def initialize(cx, cy, width, height)
super(cx, cy, width, height)
end
end
end
end


Draggableモジュールをインクルードするとドラッグ処理に関するイベントを受け取ることができるようになります。
コントロールをドラッグした際自動でon_drag_moveメソッドが実行されます。
また:drag_moveとして登録されているハンドラが実行されます。
WSNadeAreaA内にon_drag_moveメソッドを作ってその中で処理を行ってもよいですし、上の構造からハンドラ
を登録して処理をさせても構いません。
処理の流れや構造にあった方法を選択しましょう。
それらのメソッドやハンドラはドラッグ開始点からマウスのx,y座標がどれくらい移動したかを引数としてうけとります。
例えばウィンドウをドラッグした場合、受け取った移動量からウィンドウの座標を求めて再設定する処理を書くことでウィンドウの移動処理が作れます。

今回は移動量からなでる速度を求めて丁度いい速度の時だけスコアがあがる。
早すぎたり遅すぎたりしたらスコアが下がるようにします。


module WS
class WSChara < WSContainer
def initialize(cx, cy, width, height)
super(cx, cy, width, height)
@stroke = 0
@last_stroke = 0
@score = 0
create_control
end

def create_control
area = WSNadeAreaA.new(50, 20, 220, 100)
add_control(area_a, :c_area_a)
area_a.add_handler(:score_reset){ score_reset }
area_a.add_handler(:drag_move, method(:nadenade))
end

def nadenade(obj, dx, dy)
@stroke = (@last_stroke - dx).abs
@last_stroke = dx
case @stroke
when 1
@score += 2 if @score < 20
when 2...4
@score += 4
when 5...8
@score += 1
when 9...24
@score = -200 if @score > -200
when 25...640
@score = -500
end
end
end
end


ざっくりとこのような感じで。
ドラッグ時のイベントで渡されてくる移動量dxから1フレームでどれくらい動いているかを判定して丁度いい速さなら
@scoreに+4、ちょっと早いなら+2、遅いなら+1、とても早いなら大きくマイナス。
このようなメソッドをWSCharaに作り、配下のWSNadeAreaオブジェクトのarea_aの:drag_moveハンドラとして登録します。
area_aがドラッグされる度にハンドラとして登録したnadenadeが実行され、引数としてドラッグ量が渡されるのでそれを元にスコアが算出されます。

このように、WSではドラッグやクリックなどの判定や実行結果などを利用し処理を実行させるための基本的な処理が用意されていてお手軽に作ることができます。

■まとめ



ということで、今回突貫で作ったゲームがこちら。

【エイプリルなでなでゲーム】
http://www.abish.sakura.ne.jp/el/NTAC2015.zip


adc15.jpg

遊び方
・エイプリルの頭のあたりを丁度いい速度で左右にドラッグしてなでなでしてください。
・エイプリルが喜ぶと表情が変わります。
・最高にハイになるとなんかキラキラします。
・エイプリルが嫌がるとしょんぼりします。  

雑なゲームですが是非さわってみてください。
これ判定範囲や表情パターンなどを変えたらドキドキ魔女裁判みたいないかがわしいゲームが作れそうですよね。
また今回作ったWSCharaから判定を取っ払ってWSFaceに目パチや口パク処理をつければ立ち絵のひな形として使えそうですね。
最小構成にするという意味ではどうしても自分で一から作るがよいことになりますが、アイデア次第ではメニューなどのインターフェース以外にもWSを使っていろいろなゲームパーツがつくれそうです。

明日は土屋つかささんの『ショートショートなノベルゲームを作ってみた』です。
ノベルエンジンの制作者である土屋さんのノベルゲーム、とても楽しみですね!
posted by 鳴海つかさ at 22:15| Comment(0) | TrackBack(0) | 日記