Processingでゲーム制作
Processing Community Day Tokyo 2019
FAL
作成: 2019-02-02
改定: 2019-02-10
はじめに
Processingを使ったミニゲーム作りを題材として、以下の内容をお話しします。
すみませんが大半が技術の話です。
技術の話:
画面上でいろんなものがリアルタイムに動くような� プログラムはどうやって作ればいいのか?
表現の話:
動き、形、色……などなど、魅力的な表現のために� どのような工夫ができるのか?
目的: ゲームを題材に
「技術」と「表現」の選択肢を増やすこと
はじめに
技術の話
ゲームプログラムの骨組みを覚えると�幅広い用途に応用できる
技術の話
多くのゲームプログラムの骨組みは共通している
技術の話 > ゲームの骨組み
Collapsing Ideas by FAL
Collapsing Ideas by FAL
Chess-like Game Generator by FAL
例: 2Dシューティング
例: 2Dアクション
例: ボードゲーム
ゲームの骨組みはゲーム以外にも広く応用できる
技術の話 > ゲームの骨組み
CMYK by FAL
Creative Imagery by FAL
Elektro by FAL
Amöba by FAL
Königsberg by FAL
Organic Network by FAL
いずれも、�同じようなプログラムの�土台を使いまわして、�表面だけを変更して�作っています。
以降、サンプルとしてソースコードが多数登場します。
サンプルコードは以下からダウンロードできますので、�分かりにくいところは一つ一つ動かしてみて、�理解を深めていただければと思います。
サンプルコード
技術の話
基本:「クラス」でプログラムを部品化する
技術の話
ゲーム画面上の要素は独自に動き回る
技術の話 > 基本
parcitleFlow by yasai
Rectangle Microbes by FAL
例:すべての要素が
単一の規則で動く
例:それぞれの要素が
独自にバラバラに動く
→ 今回こっちの方を
やりたい
https://www.openprocessing.org/sketch/422446
独自に動く主体を作るために「クラス」を使う(1)
技術の話 > 基本
どんなソースコードにする?
例題
独自に動く主体を作るために「クラス」を使う(2)
技術の話 > 基本
例題
[ 考え方 ]
独自に動く主体を作るために「クラス」を使う(3)
技術の話 > 基本
ベタ書きの場合
位置(x座標とy座標)
速度(方向と、1フレームごとのスピード)
表示
位置の更新
setup
draw
Sample: ClassSampleBefore
独自に動く主体を作るために「クラス」を使う(4)
技術の話 > 基本
ベタ書きの場合
位置(x座標とy座標)
速度(方向と、1フレームごとのスピード)
表示
位置の更新
setup
draw
画面上を動く要素に関連する部分を
ひとまとめにしたい!
そこで……
独自に動く主体を作るために「クラス」を使う(5)
技術の話 > 基本
クラスを使う場合
位置
速度
表示
位置の更新
setup & draw の中から、
Elementクラスの部分が
「部品」として切り出された!
Sample: ClassSampleAfter
画面上を動く要素、ということで
Element と名付けたクラスを作ってみた
複雑なプログラムはクラスという部品を組み立てて作る
技術の話 > 基本
------
---------
----
小規模
大規模
ベタ書き
部品化
〇 手軽に
書ける
× 長すぎて
破綻
× 最初ちょっと
面倒
〇 組み合わせで
自由に
増築できる
---------------------------
---------
---------------
-------
----------------------------
-----------------------
-------
--------------
---------------------
-----------------
------
-----------------------
-----------
--------------------
-------------------------
---------------------
---------------
---------------------
---------------------
---------------------
!?
※ 図はイメージです
多くのゲームに共通するのは、画面上の要素の
「生成・消滅」「多様性」「相互作用」である
技術の話
生成・消滅
相互作用
多様性
・プレイヤー
・敵
・攻撃
・エフェクト
いろいろいて
バラバラに動く
衝突したり
距離が近いと反応したり
次々と
生まれては
消える
Duel by FAL
生成・消滅: 基本的な構造
技術の話
【この章の目標】�画面中心で要素が生まれ、
画面端で死ぬようにする
増えたり減ったりするものを扱うには可変長リスト(1)
技術の話 > 生成・消滅
さっきのソースコードでは要素を1個しか作れない。
複数作って動かすためには?
増えたり減ったりするものを扱うには可変長リスト(2)
技術の話 > 生成・消滅
1秒ごとに
要素を追加
全要素を
更新
全要素を
表示
※ Elementクラスはさっきと同じ
可変長リストの一種
ArrayList
Sample: ListSample1
複数の要素を
動かせるようになった!
多数の要素を管理する専用のクラスを作ると便利(1)
技術の話 > 生成・消滅
「リスト内の全要素を~~する」
という処理はとても頻繁に使います。
そこで、この部分を司るクラスを作ってみましょう
多数の要素を管理する専用のクラスを作ると便利(2)
技術の話 > 生成・消滅
drawの中から
forループ処理が
切り出された!
全要素を
更新
全要素を
表示
※ Elementクラスはさっきと同じ
Sample: ListSample2
ArrayListを継承。ArrayListの元々の機能に加え、
さらに機能を追加したクラスを作成
用済みの要素には死んでいただき、
死んだ要素には退場していただく(1)
技術の話 > 生成・消滅
さっきのソースコードでは要素の「削除」が無いので、
リストの中身が永遠に増える一方です。
要素が画面端に来たら削除したい。
[ 考え方 ]
用済みの要素には死んでいただき、
死んだ要素には退場していただく(2)
技術の話 > 生成・消滅
画面外に出たら
isDeadフラグを立てる
・isDeadフラグの立った要素は
リストから削除
・ループ途中で削除したいときは
拡張forではなくIteratorを使う
※ 変更ない部分は省略
死んでいただく処理
退場していただく処理
Sample: ListSample3
生成・消滅: 基本的な構造(再掲)
技術の話
OK?
【この章の目標】�画面中心で要素が生まれ、
画面端で死ぬようにする
多様性: 要素に個別の特徴を持たせる
技術の話
【この章の目標】�要素の形がランダムで
●か■のどちらかに
なるようにする
最も素朴な方法は条件分岐
技術の話 > 多様性
※ 変更ない部分は省略
typeに応じて
●か■か、表示方法を変える
Sample: FeatureSample1
クラスの継承によって特徴の違いを出せる(1)
技術の話 > 多様性
簡単な分岐ならさっきのでOKですが
条件分岐に頼っているとifやswitchだらけになって大変です。
他の方法を考えてみよう。
せっかくクラスを使っているのだから、
「●要素のクラス」「■要素のクラス」を作ればよいのでは?
クラスの継承によって特徴の違いを出せる(2)
技術の話 > 多様性
※ 変更ない部分は省略
Elementクラスとその中のdisplay()を
abstract(継承専用)にする
Elementを継承して
種類ごとにクラスを作る。
種類ごとに異なる処理だけを
ここに書く
Element
CircleElement
SquareElement
draw() の中で
new Element() の
部分も要変更 →
Sample: FeatureSample2
そこで、継承に頼らない方法が
もう一つあります
クラスの継承は複雑になると破綻する
技術の話 > 多様性
動物
ワンと鳴く
動物
ニャーと鳴く
動物
飛ぶ
動物
飛ばない
動物
犬
猫
ウミネコ
!?
特徴そのものを切り出して部品化すると
より柔軟にできる(1)
技術の話 > 多様性
Element.display() の中身を切り出して
表示専用の部品を作成
自分自身(this)を渡して
処理を委託
(これを「委譲」という)
※ 表示に限らず、同じ考え方で様々な部品が作れる
Sample: FeatureSample3
特徴そのものを切り出して部品化すると
より柔軟にできる(2)
技術の話 > 多様性
インタフェース:
あるクラスに何ができるのか? を指定するための部品
※2
p5.js だと遥かに簡単で、
クラスまで作らなくても関数オブジェクトを渡せばよいです
※1
なんでこんなことするの? という疑問をお持ちの場合、
解消にはある程度の時間が必要かもしれません。
まずは自分にとって分かりやすい方法でコードを書きつつ、
いろいろ興味の赴くままに調べてみることをお勧めします。
この話面白いんだけど……力不足ですみません……!
多様性: 要素に個別の特徴を持たせる(再掲)
技術の話
【この章の目標】�要素の形がランダムで
●か■のどちらかに
なるようにする
OK?
相互作用: 基本となるのは「総当たり」法
技術の話
【この章の目標】�●と■が衝突したら
どちらも消えるようにする
すべての要素の組み合わせについて
位置関係を判定する(1)
技術の話 > 相互作用
[ 考え方 ]
すべての要素の組み合わせについて
位置関係を判定する(2)
技術の話 > 相互作用
・他のグループとの衝突を処理する
collide() を追加
・全ての組み合わせを判定
・距離が一定以下なら(=衝突したら)死
●と■を別々のグループに
●と■を
衝突させる
中身は省略
(Sample参照)
Sample: CollisionSample
(補足)総当たり法の実装は
「グループ間」と「グループ内」で異なる
技術の話 > 相互作用
●グループと
■グループの間
●グループ内
実装例
※ さっきやったのは
こっち
相互作用: 基本となるのは「総当たり」法(再掲)
技術の話
OK?
【この章の目標】�●と■が衝突したら
どちらも消えるようにする
集大成: 以上を元に、ゲームらしきものが作れる
技術の話
サンプル『インベーダーもどき』
Sample: GameSample
主な変更点
技術の話 > 集大成
以下、サンプルスケッチ CollisionSample から
GameSample への主な変更点を記述します。
土台としては CollisionSample の時点で大方できており、
本質的な意味での変更は特にありません。
主な変更点 メイン(GameSample)タブ
技術の話 > 集大成
「自分」「敵」「自分の弾丸」の�3グループを用意
30フレームに1回、「敵」を追加
「自分の弾丸」と「敵」で衝突判定
Sample: GameSample
主な変更点 Elementタブ
技術の話 > 集大成
位置と速度の初期値をゼロに�… new Element() の後で都度設定するように
表示処理のdisplayerと同じく、�更新処理をupdaterとして切り出し�… 「自分」とそれ以外で動き方を変えられるように
Sample: GameSample
主な変更点 ElementComponentタブ
技術の話 > 集大成
弾丸の
表示処理
Elementから切り出した、通常の更新
「自分」の更新用。マウスで移動・発射
Sample: GameSample
集大成: 以上を元に、ゲームらしきものが作れる(再掲)
技術の話
サンプル『インベーダーもどき』
OK?
Sample: GameSample
表現の話
見た目を変えるための諸要素
表現の話
ゲームまたは類似のスケッチを対象に
Processingの基本機能で行える表現を考えると、
基本要素はこんな感じで列挙できるのではないかと思います。
一つずつ確認していき、そのうえで、
どんな組み合わせができるか考えてみましょう。
位置
表現の話
例: 落下
=下方向の加速度
回転角度
表現の話
例: 等速で回転
スケール
表現の話
例: サイン波で拡大縮小
位置(加速度)
+
回転(角加速度)
(それぞれランダムに変化)
ここまでの応用例
表現の話
Kinetic Typography by FAL
形
表現の話
Geometric Icon Maker by FAL
Amöba by FAL
例:不定形な物体
例:図形の組み合わせ
noise() で
歪ませながら
円を描くと
こうなる
色
表現の話
例:混色
例:配色
好みの配色を
試行錯誤して探す
手っ取り早いのは
colorMode(HSB) で
色相だけずらす方法
Creative Imagery by FAL
CMYK by FAL
blendMode()
をいろいろ試す
左図は
SUBTRACT
ググると
いろいろ出ます
↑順に
色相・彩度・明度
(色相=0 は赤)
透明度
表現の話
例
fill() でα値を指定して
半透明にする
Transparent by FAL
質感
表現の話
Color Field Painting by FAL
Solid Aether by FAL より画像抜粋
例:グラデーション&影
例:重ね塗り
strokeWeight() で
太線にして
line() を大量に
重ねるとこうなる
filter(BLUR) で
ぼかすと
影っぽいものを
作れる
グラデーションは
地道に
ピクセル操作
ここまでの応用例
表現の話
回転速度
+
スケール
+
形(図形の組み合わせ)
Motion Graphics by FAL
ここまでの応用例
表現の話
位置(ランダム移動)
&加速度(落下)
+
回転速度
+
色&透明度
+
質感(背景で、ピクセルごとに� 明るさを変えてザラザラ化)
Rectangle Petals by FAL
画面効果
表現の話
例:画面揺らし
ランダムな値で
translate() すると
画面を揺らせる
これを
呼ぶと
発動
他、半透明な rect() を
画面全体にかけることで
フラッシュや残像効果など……
ここまでの応用例
表現の話
Duel by FAL
見た目を変えるための諸要素(再掲)
表現の話
好きに組み合わせてみよう!