pg04

テーマ ゲームエンジン と プログラム

内容

Algodoo + Thyme

Thyme は第1回の講義で紹介した 2次元物理シミュレータ Algodoo に内蔵されてている、Algodoo専用のスクリプト言語です。

Algodoo でプログラムによる処理が必要なときに使用できます。

今回の授業の説明資料は、動画で用意しました。 youtube にアップロードしてあります。

動画の解像度が不足の場合は、再生解像度の設定を 自動から → 720p に変更 や、全画面表示 を試してみてください。

Thymeについては、私の動画以外に以下の外部サイトの解説も参照してみてください。

参考資料1 http://mandel59.hateblo.jp/entry/2012/03/11/005914

参考資料2 https://www6.atwiki.jp/p-phun/pages/36.html

演習1

第1回の復習とオブジェクトを追跡するカメラの設定について扱う。

・algodoo のオブジェクトをキーボードで操作する。

説明ビデオ1(6分)

操作復習

モーターの回転方向を左右矢印キーで、正転、逆転、上矢印でブレーキに設定する。

・画面を移動するオブジェクトに追随するカメラの設定(画面スクロール)

説明ビデオ2(4分)

フリッパーの作成とカメラの追従設定

※オブジェクトのメニューの セレクトメニュー から オブジェクトに合わせて視点を移動させる をチェック

シーンを保存する ファイル名 pg04s1

演習2

・algodoo の Thyme(タイム)

プログラムでオブジェクトを操作する

説明ビデオ3(22分)

オブジェクトのプロパティ(設定値) 右クリックメニューの スクリプト から設定できる。

サークルオブジェクトのプロパティ

color 色

※色の設定には RGBAカラーを使用する。値は 0.0~1.0の範囲で、リストの書式 [1.0 , 1.0 , 1.0 , 1.0] を使う。

※値を並べたものをリストという

radius 半径

※radiusはサークルオブジェクト専用のプロパティ

ボックスオブジェクトの大きさは radius ではなく、 size で設定する。

size サイズ

※幅 と 高さ をリスト [w , h ] wとhは数値で指定する。

※sizeプロパティは ボックスオブジェクトで利用可能(サークルでは利用不能)

vel 速度

※速度の設定は ベクトル(vx,vy)を使う。 リストの書式で [1.0, 0.0] のように指定する。

オブジェクトに初速を与えて、再生してみよう。

モーターの回転スピード(マイナス値は逆回転)を設定する。

ギア(歯車)オブジェクト モーター用のプロパティがある。

・モーターの回転方向をプログラムで制御する

Thyme コンソール の表示 F10 キー

スクリプトの入力欄を開く。

モーターの回線速度の設定を、数値から変数に変更する。

変数: メモリに設定値を格納し、プログラムから利用できるように名前を付けたもの

変数名 変数に付けた名前。プログラムで利用できるメモリは複数あるので名前で区別する。

代入 変数に値をセットすること。

・変数の準備

scene.my.mtspd

最初に実行した際は undefined 未定定義 と表示される。変数用のメモリは存在しているが値がまだ設定されていない状態のため。

設定値 -1.5 を設定する (初期化)

scene.my.mtspd = -1.5

手動で操作:

ボックスオブジェクト と サークルオブジェクト と 歯車 でシーソーを作る

歯車はモーター化しておく

モーターの回転速度を変数の値で設定するプログラム ←歯車に設定する

morterSpeed = { scene.my.mtspd }

計算式による値の設定

scene.my.mtspd = - scene.my.mtspd

コンソールで実行する度に回転方向が+-で反転することを確認する。

オブジェクトのイベント処理

衝突時に実行するプログラム

onCollide = (e) => { scene.my.mtspd = - scene.my.mtspd }

シーンを保存する ファイル名 pg04s2

演習3

説明ビデオ4(13分)

次のスクリプトをコンソールで実行:

画面に、XY座標(pos)と半径(radius)を設定してサークルを追加作成するプログラム

scene.addCircle({ pos = [ 0.0 , 2.0 ]; radius = 1.0 })

画面に、XY座標(pos)とサイズ(size)を設定してボックスを追加作成するプログラム

scene.addBox({ pos = [ 0.0 , 2.0 ]; size = [ 1.0 , 1.0 ] })

(実演は省略)

シミュレーション開始からの経過時間(秒)

sim.time

シミュレーションの開始時点では 0秒 。シミュレーションを開始(再生ボタン)後に、一時停止して、sim.timeの値を観察する(コンソールでsim.timeを評価※)。

※評価とは式やプログラムを実行して値を求めること。

シミュレーションの1フレーム(画面更新)ごとに毎回実行されるプログラム

update = (e) => { radius = 0.1 }

時間に応じて大きくなる半径

update = (e) => { radius = 0.1 + sim.time }

時間に応じて伸縮する半径

update = (e) => { radius = 1 + math.sin(sim.time) }

半分の速度で伸縮

update = (e) => { radius = 1 + math.sin(sim.time/2) }

2倍の速度で伸縮

update = (e) => { radius = 1 + math.sin(sim.time*2) }

・クリックするとサークルを発生させるボタンを作成する。

説明ビデオ5(5分)

クリック時に実行するプログラム

onClick = (e) => { scene.addCircle({ pos := [1, 1] }) }

↑ 位置の変数 pos の値を設定するときに、 := を使う必要がある。

= を使うと、 onClick をプログラムした、クリックしたオブジェクトの pos を変更してしまうため、自分自身が指定した座標にワープしてしまう。

:= を使うと、新しく追加されるボールの pos の方を設定する。

手動でボタンとして利用するサークルを空中に固定し、スクリプトを設定する

何度かクリックした例

サークルを他のオブジェクト(地面など)と重なった位置に発生させた場合、激しく弾むので、発生する場所は要調整。

コンソールで繰り返しコマンドの実験

繰り返し回数(上限50回)を指定してプログラムを実行する。

例) 4回 ボールを追加するプログラム

for(4, (n) =>{ scene.addCircle({ pos = [ 0.0 , 2.0 ]; radius = 1.0 }) })

コンソールで↑を実行後、シミュレーションを開始する。

再生時刻を、ボールが飛び散る直前の状態に戻す。

シーンを保存する ファイル名 pg04s3

応用: 自由課題

課題1のpg04s1 か 課題2のpg04s2 か 課題3の pg04s3 を適当に修正してプログラムを試す。

※授業中で作業した例を、このページに添付しておくので、参考にしてよい。

修正する課題のファイルをalgodooで開いて、以下のようなコマンドの実行や、作業を試せ。

例) ボールを10個横に並べる

ループが実行されるたびに1つ値が増加する変数 n を利用するプログラムの例。 n = 0 1 2 3 4 ...

重なりながら並ぶ

for(10, (n) =>{ scene.addCircle({ pos = [ n , 2.0 ]; radius = 1.0 }) })

距離2でピッタリ並べる

for(10, (n) =>{ scene.addCircle({ pos = [ n*2 , 2.0 ]; radius = 1.0 }) })

ボールを敷き詰める

繰り返し処理の for コマンドで 別の for コマンドを繰り返し実行させる。 2重ループの処理。

for(10, (m) => { for(10, (n) =>{ scene.addCircle({ pos = [ n*2 , m*2 ]; radius = 1.0 }) })})

※{ }の内側の { for(10, (n) のループでボールを横方向に並べている。

※外側の for(10, (m) の変数mは内側のボール生成コマンドの縦方向の位置 pos = [n*2, m*2]に作用する。

※内側のループが外側のループでさらに繰り返し処理される。結果、10x10個のボールが平面に並ぶ。

例)衝突した相手の情報を調べ、色を赤に変更する。

onCollide = (e) => { e.other.color = [1.0, 0.0, 0.0, 1.0] }

時間に応じて半径が増加するプログラムを設定されたボールを10個並べる。

for(10, (n) =>{ scene.addCircle({ pos = [ n*2 , 8.0 ]; radius = 1.0; update = (e) => {radius = sim.time/10} }) })

例)オブジェクトの位置とオブジェクトのサイズをスクリプトで連動させる。

演習3では三角関数 math.sin を利用して周期的な変化を表現した。

三角関数を使わなくても、回転する棒の先端に取り付けたオブジェクトのy座標(x座標でもOK)を利用すれば周期的な変化を利用できる。

xy座標が0と0(pos = [0, 0])を中心にして回転するオブジェクトを作成する(ボックス+歯車+サークルなど)

コンソールで

scene.my.sin

変数を作成する

回転するサークルなどの update を

(e)=>{

scene.my.sin = pos(1)

}

と設定。pos(0)はx座標、pos(1)はy座標を pos のリストの先頭からのインデックス(目次)を指定してデータを読み出す表記法。

scene.my.sin は +回転半径 ~ -回転半径 の間で周期的に変化する。

周期的にサークルの半径を変化させるには、サークルの update に

(e)=>{

radius = 1 + scene.my.sin / 3

}

を設定。 変化する値の範囲を調整するには、 / 3 を /2 や /4 などに修正してみる。また 1+ を 2+ に修正してもOK。

※作業例をこのページに添付しておく。 pg04sSin

三角形にボールを積み上げる例)

for(30, (m) => { for(30-m+1, (n) =>{ scene.addCircle({ pos = [ n*2+m , m*2 ]; radius = 1.0 }) })})

次回は ゲームエンジン Unityの実習

※ Unity2017を使えるようにアカウントを設定しておいてください。

授業中にアカウントの設定の説明はしますが、多人数で一斉に登録作業をした場合、トラブル発生の懸念があります。

設定方法については、次回の資料を参照。

参考資料:

オープンキャンパス模擬講義 Unityで2Dステージ制作 https://sites.google.com/site/kobashijiangyiyong/opunkyanpasu2015

Unityでゲーム作成 https://prezi.com/vi_87shoakh7/13/ (すこし難しい。挑戦してみたい人はどうぞ。キーボードでゲーム板を傾けてボールを転がすゲームの例)

Unity と C#