いつクリはてブロ

いつになったらクリエイティブするの?

画像素材を用意せずにいきなり始めるゲーム開発~PIZZA COOKER解説~

この記事はDXRubyAdventCalendar2015、7日目の記事です。www.adventar.org

昨日はしのかろさんの「デジゲー博のレポートとその時使用したFiberテクニック」でした。
DXRuby Advent Calendar 2015 デジゲー博のレポートとその時使用したFiberテクニック · GitHub

パチスロをリアルに再現するというのはなかなか興味深いテーマですね。
精密な画面同期が要求されるゲームというと、私の場合真っ先に音ゲーが思い浮かびます。
いずれDXRuby製の音ゲーなんかも登場するんでしょうか?(もうある?)

みんなもイベント会場でライブコーディング、しよう!(虚ろな目

画像素材を用意せずにいきなり始めるゲーム開発

というわけで今回のテーマです。
前回は「もう少し複雑なゲームに取り組む」というテーマで次回予告したのですが、先に『PIZZA COOKER』のコード解説でもうひと記事稼げるをしなきゃいけないと思ったので、今回はコード解説でいこうと思います。
今回の内容は大体こんな感じです。

  • DXRubyの図形描画
  • 高校数学を学び直したくなるプログラミング~三角関数極座標形式~
  • 画像素材の使いドコロ
  • 再利用前提のコードを書く

『PIZZA COOKER』についてはこちらを参照してください。vivit-jc.hatenablog.com

前回記事はこちら。vivit-jc.hatenablog.com

DXRubyの図形描画

と書くと技術的な話題っぽいですが、そんなに難しい中身ではないです。(私も簡単なものしか使ってないです)
画像素材にこだわると良いゲームが出来るのは確かですが、そこに時間を掛ければ掛けるほど、プログラミングがつまらなくなっていきます*1
とにかくゲームを作りたい! 自分のアイディアを世に知らしめたい! という思いを胸に強く抱いて、まずプログラム部分を先に終わらせましょう。
そういう場合に役に立つのがシンプルな図形描画です。
具体的には以下。

  • draw_pixel
  • draw_line
  • draw_box
  • draw_box_fill
  • draw_circle
  • draw_circle_fill

これらのリファレンスは以下のアドレスから。
DXRuby Window.draw_morph

要するにこれらで仮置きをすればいいのです。画像は後から付ければいい。
『PIZZA COOKER』の場合は、ピザの描画をこれらWindowモジュール直下の図形描画だけで何とかしています。
案外円や四角形だけでもそれっぽく見えるものです。
(そういえば『MAGURO』は図形描画すら無かったですね…)

f:id:vivit_jc:20151204155029p:plain
ピザに見えますね?

DXRubyの図形描画は結構軽めのようで、焼く前のピザにトッピングを乗せるシーンでは、溶ける前のチーズを100個くらいランダムに配置してそれらをグルグル回すということをやっているので、ちょっと重くなるかなと思いましたが、そんなことはありませんでした。

Imageクラスは画像の読み込みと変形などを中心としたクラスですが、画像素材によらない図形描画もできるので、これを使えばもっといろんなことができます。

DXRuby Image

Windowモジュール直接では書けなかった三角形もImageクラスなら描けるぞ!

高校数学を学び直したくなるプログラミング~三角関数極座標形式~

『PIZZA COOKER』の解説をするにあたり、タイトルをこちらにしようか迷ったんですが、DXRubyAdventCalendarなので主題を「画像素材を〜」に譲りました。
具材を乗せる際にピザが回転運動するのですが、回転させるにあたって使った手法を解説していきます。

tx1 = PIZZA_X+(pizza.radius*0.72)*Math.cos(rad(@game.deg+topping[0])+Math::PI/12.0)
ty1 = PIZZA_Y+(pizza.radius*0.72)*Math.sin(rad(@game.deg+topping[0])+Math::PI/12.0)

PIZZA_X,PIZZA_Y: ピザの中心座標
pizza.radius: ピザの半径
Math.sin(): サイン^q^
Math.cos(): コサイン^q^
rad(): 度数法(360度)から弧度法(2π)への変換^q^(自分で定義した関数)
@game.deg: 度数法による現在の回転角^q^
topping[0]: そのトッピンググループの位置(角度)
+Math::PI/12.0: π/12=15度^q^

ピザ生地やトマトソースは円形なので、回す必要はありません。
回すのは具材のみです。
f:id:vivit_jc:20151208012118p:plain
具材の位置は、3つの具材を1グループにまとめて0~359の数値として保存しています。
クロックに従って@game.degが加算されるので、それに従って座標が計算され回転しているように描画されます。

f:id:vivit_jc:20151208012120p:plain
draw_circle()にはXY座標(直交座標形式)で座標を与えるので、sinとcosを使って座標を計算します。
図でいうPが具材の描画位置ですね。

f:id:vivit_jc:20151208012115p:plain
また、具材は3つを1つのグループとしています。
1つのグループにつき、

  • 基準軸から+15度、半径の72%の位置
  • 基準軸から-15度、半径の55%の位置
  • 基準軸上、半径の30%の位置

のそれぞれの箇所に具材を表示しています。
これを具材を乗せるフェイズで6グループ追加しているわけです。
具材はピーマン、サラミ、オリーブの3種類を3箇所にランダムで配置しています。
結構手抜きというか、簡素な実装ですが、案外ピザに見えるものですね。


チーズはどう表示しているかというと、

Window.draw_circle_fill(PIZZA_X+c[1]*Math.cos(rad(@game.deg+c[0])),PIZZA_Y+c[1]*Math.sin(rad(@game.deg+c[0])),7,CHEESE)

こんな感じです。
座標をランダムに設定して、そこを中心に半径7の円を描いているだけです。
ただこの座標(c[1],c[0])は極座標形式になっています。*2

f:id:vivit_jc:20151208013815p:plain
極座標形式とは、ある点の座標を、原点からの距離と基準軸からの回転角の2つの数値で表現する形式です。
極座標形式の便利なところは、座標に対して直接角度を足したり引いたりできるところです。
時間に従って角度を足していくと、その物体は回っているように描画されます。
また、掛け算を使えば30度ずつ回転するなども簡単に扱えます。

アクションゲームやシューティングゲームなどで回転運動を扱うときは、これら三角関数極座標を味方に付けることができないとかなり苦戦するので、何とか習得したいものです。
高校や大学で習ったとは言っても、普段使わないとなかなか厳しいものがありますね…。

画像素材の使いドコロ

全く画像素材を使わないというのもそれはそれで寂しいものです。
せめてタイトル画面くらいはそれっぽい画像を貼りたいですね。
適当にググって出てくる写真や画像などを乗せるだけで、しっかり雰囲気を演出してくれます。
(ゲームを実際に公開する際は、著作権に気を配りましょう)
自機やモンスター、アイテムなどの画像素材も、無料で使えるものがインターネット上にたくさんありますが、画像素材を吟味し始めてしまうのは罠で、完成が遠のきます。
先述した通り、先にプログラムを書きましょう。

『PIZZA COOKER』の場合は、気分を盛り上げるため、タイトル画面とピザ窯だけはパブリックドメインの写真を使用しました。
なんだか場違いなくらいオシャレなタイトル画面になったので、ブログなどで画像を貼るときにも便利でした。
嬉しい副産物です。

再利用前提のコードを書く

f:id:vivit_jc:20151208020104p:plain
今回のコードは、『MAGURO』と並べてみると分かるとおり、多くの部分のソースコードを『MAGURO』からコピー&ペーストしています。
こだわらなくていいなら、タイトル画面などはどんどん手を抜いて再利用しましょう。
また、今後手を抜けるように、次回以降共通で使えるっぽいところは疎結合(他のソースコードへの依存を極力抑え、切り取って別のところでも使いやすくする)を保つよう意識してコードを書きましょう。
経験上、過去の遺産は利用するタイミングは意外と来るものです。
(実際、『MAGURO』のソースコード自体もさらにそれ以前のものを流用しています。)

vivit-jc.hatenablog.com
ソースコードの独立性の保ち方としては、既存の方法論に則ってプログラムするというのがいいでしょう。
MVCモデルは、DXRubyのようなGUIプログラミングにおいて存分に効果を発揮してくれます。

結論

まとめると、言いたいことは次の通りです。

  • 今すぐコードを書け

やる気や勢いを面倒臭さが上回る前に、完成させてしまいましょう。
プログラムがおそらく最も面倒臭くなりやすく、それを終わらせてからであれば、画像素材の用意は消化試合みたいなものです。
いきなりプログラミングに取り掛かってもちゃんとグラフィカルな動きをしてくれるDXRubyなら、あなたもゲームを「完成」させられるはずです。(申し訳程度のDXRuby要素)

次回こそ「もうちょっと凝ったゲームが作りたい人へ」というテーマで記事を書きます。
最後までお読みいただき、ありがとうございました。


明日はunohanaTさんの「なんかゲーム作りたい」です。
うわあ! とっても楽しみだなあ!!😃😃😃😃

*1:個人の感想です

*2:普通は(半径,角度)という書き方をするんですが何故か逆になってたり、度数法から変換すればいい数値をわざわざ弧度法で直書きしてたり、見直すと結構適当ですネ…