#雪が降るアニメーション作品を作る
今回は、プロデルに雪を降らせてみようと思います。
完成画面は、次のような感じです。夜にシトシト雪が降り続くようなアニメーションを作ってみます。
雪を作る
まずは、雪の一粒を作ってみます。
雪は、単に背景を白で塗りつぶした円で表現してもよいのですが少し味気ないので、もう少し凝った雪にしようと思います。そこで、半透明の白色の円を何重にも重ねて、立体感のある雪を作ってみます。
半透明の色は、「色情報」種類で作れます。「色情報」種類では、赤,緑,青の比率を0~255の範囲で指定しますが、最初にアルファ値(0~255)を加えると、色に透明度を指定できます。
まずアルファ値25の半透明な白色で、塗りつぶした円を描きます。そして同じ座標を中心として半径の徐々に小さくしながら、円を重ねて描きます。
この後、この雪をたくさん作って、画面の上から下へ移動させます。
雪の移動を簡単にするために、この重ねた円を「子キャンバス」の中に作っておきます。子キャンバスの中に作成した図形は、一つの図形としてまとめて操作できます。つまり、子キャンバスの座標を移動すれば、その中の重ねた円もまとめて移動できます。
窓というウィンドウを作る
そのタイトルは、「雪」
窓へキャンバス1というキャンバスを作る
そのドッキング方向を全体に変える
その背景色は、黒
窓を表示する
キャンバス1に子キャンバスを作って雪とする
雪の位置は{100,100}
雪色という色情報({25,255,255,255})を作る
サイズは、60.0
20回繰り返す
雪へ円を描く
その位置と大きさは{-サイズ/2,-サイズ/2,サイズ,サイズ}
その背景色を雪色に変える
その線色を透明に変える
サイズをサイズ/20だけ減らす
繰り返し終わり
キャンバス1を更新する
待機する
実行すると、ちょっと大きめな雪ができました。
雪を降らせる
今度は、この雪を降らしてみましょう。
とりあえず、雪を同じように100個作ってみます。作った雪は「雪一覧」配列に子キャンバスの単位で入れておきます。そして、タイマーを使って一定間隔で、「雪一覧」配列に入った雪の位置を少しずつ下へ移動させていきます。
タイマーを使って一定間隔(0.1秒)ごとに「時間になった」手順を呼び出します。「それぞれ繰り返す」文で「雪一覧」配列に入った子キャンバスの縦位置を少しずつ(10ピクセル分)移動させていきます。
また、雪が画面よりも下の位置になり消えた場合には、再び縦座標を画面上に戻します。このとき、雪がワンパターンとならないように、画面上に戻るときに、雪の座標を乱数で決めます。縦座標も画面の上端より少し上の座標を乱数で決めると、より法則性がないアニメーションになるかと思います。
キャンバスの動きをなめらかにするために、キャンバスの「自動更新」を×にしておきます。自動更新をオフにすると、「更新する」手順が実行されるまで、キャンバスの再描画が行われません。今回のように多数の円を描くような場合、図形の座標や色などを設定したから最後に「更新する」手順を一度実行することで、再描画が効率的になります。
雪のサイズは、少し小さめにすると雪っぽくなって良いかと思います。
メイン画面を表示する
待機する
メイン画面とは
ウィンドウを受け継ぐ
+雪一覧={}
はじめの手順
初期化する
雪色という色情報({25,255,255,255})を作る
描画幅は、幅/キャンバス1の倍率
描画高さは、高さ/キャンバス1の倍率
100回繰り返す
キャンバス1に子キャンバスを作って雪とする
雪の位置は{0から描画幅までの乱数,0から描画高さまでの乱数}
雪一覧に雪を加える
サイズは、20.0
20回繰り返す
雪へ円を描く
その位置と大きさは{-サイズ/2,-サイズ/2,サイズ,サイズ}
その背景色を雪色に変える
その線色を透明に変える
サイズをサイズ/20だけ減らす
繰り返し終わり
繰り返し終わり
タイマー1というタイマーを作る
タイマー1の時間になった時の手順は、時間になった
タイマー1の間隔を100に変える
タイマー1を開始する
終わり
初期化する手順
ーー自動生成された手順です。ここにプログラムを書き加えても消える場合があります
この実質大きさを{1292,826}に変える
この画面状態を「最大化」に変える
この内容を「雪」に変える
この間隔を{4}に変える
初期化開始する
キャンバス1というキャンバスを作る
その位置と大きさを{0,0,1292,826}に変える
その自動更新を×に変える
その移動順を1に変える
その背景色を「黒」に変える
そのドッキング方向を「全体」に変える
初期化終了する
この設計スケール比率を{144,144}に変える
終わり
大きさが変化した時の手順
もしキャンバス1が無なら返す
描画幅は、幅/キャンバス1の倍率
描画高さは、高さ/キャンバス1の倍率
雪一覧のすべての雪についてそれぞれ繰り返す
雪の位置は{0から描画幅までの乱数,0から描画高さまでの乱数}
繰り返し終わり
キャンバス1を更新する
終わり
時間になった手順
雪一覧のすべての雪についてそれぞれ繰り返す
雪の縦を雪の縦+10に変える
もし雪の縦が描画高さ以上なら
雪の位置は、{0から描画幅までの乱数,-(0から描画高さ/2までの乱数)}
もし終わり
繰り返し終わり
キャンバス1を更新する
終わり
終わり
雪っぽくなってきました。
雪を揺らめかせる
さらに雪が風によって左右に僅かに揺れるような動きにしてみたいと思います。
ただし、縦座標と同じように雪の横を雪の横+10に変える
などとして横座標を単純に数ピクセル分だけ増やしてしまうと、雪の動きが直線的になってしまいます。(これはこれでよいかもしれませんが)
ここでは、ゆらゆらと動く動きを表現するために、サインカーブを使ってみます。sin値は、「サイン」名詞手順で角度もしくはラジアン値で計算できます。
[(雪の縦)度のサイン]
などとすると、縦の座標に応じて-1~1までの範囲で緩やかな値を求めることができます。このサイン値は、一定の周期で変化するので、横の位置の加減に使うと、ゆらゆらとした動きを表現できます。
時間になった手順
雪一覧のすべての雪についてそれぞれ繰り返す
雪の縦を雪の縦+10に変える
雪の横を雪の横+[(雪の縦/2)度のサイン]*3に変える
もし雪の縦が描画高さ以上なら
雪の位置は、{0から描画幅までの乱数,-(0から描画高さ/2までの乱数)}
もし終わり
繰り返し終わり
キャンバス1を更新する
終わり
今回は、控えめな動きにしてみましたが、雪が僅かにゆらゆらと動いていることが分かるかと思います。ちょっとした違いですが、少しリアルっぽくなったのではないでしょうか。
なお、[(雪の縦/2)度のサイン]*3
の式を変えることで周期や振れ幅を変えることができますのでお好みに調整してみてください。
クリスマスツリーwith粉雪
雪を降らせるアニメーションが完成しました!プログラムを実行して、クリスマスソングなどを流しながら眺めれば、この季節らしい気分が味わえますね
ところで、2019年のプロデルアドベントカレンダーでは、クリスマスツリーを作っていました。今度は、そのプログラムと組み合わせて、クリスマスツリーに今回の雪を降らせてみました。
LEDは、0
葉色は、「#00C500」
色配列は、{「緑」、「赤」、「黄色」、「ピンク」、「水色」、「オレンジ」}
メイン画面を表示する
待機する
メイン画面とは
ウィンドウを受け継ぐ
+雪一覧={}
はじめの手順
初期化する
描画幅は、幅/キャンバス1の倍率
描画高さは、高さ/キャンバス1の倍率
雪色という色情報({25,255,255,255})を作る
100回繰り返す
キャンバス1に子キャンバスを作って雪とする
雪の位置は{0から描画幅までの乱数,0から描画高さまでの乱数}
雪一覧に雪を加える
サイズは、20.0
20回繰り返す
雪へ円を描く
その位置と大きさは{-サイズ/2,-サイズ/2,サイズ,サイズ}
その背景色を雪色に変える
その線色を透明に変える
サイズをサイズ/20だけ減らす
繰り返し終わり
繰り返し終わり
タイマー1というタイマーを作る
タイマー1の時間になった時の手順は、時間になった
タイマー1の間隔を100に変える
タイマー1を開始する
カメさんというカメを作る
カメさんの位置は、{-5,-5}
カメさんをキャンバス1に表示する
カメさんを隠す
キャンバス1へ「Merry Christmas!」という文字を描く
その位置は、{80,5}
そのフォントを「Yu Gothic」に変える
その文字色を緑色に変える
その文字サイズを20に変える
キャンバス1へ「Merry Christmas!」という文字を描く
その位置は、{82,7}
そのフォントを「Yu Gothic」に変える
その文字色を赤に変える
その文字サイズを20に変える
クリスマスツリーを表示する
タイマー2というタイマーを作る
タイマー2の時間になった時の手順は、ライト時間になった
タイマー2の間隔を800に変える
タイマー2を開始する
終わり
初期化する手順
ーー自動生成された手順です。ここにプログラムを書き加えても消える場合があります
初期化開始する
この実質大きさを{600,460}に変える
この内容を「Merry Christmas!」に変える
この間隔を{4}に変える
キャンバス1というキャンバスを作る
その位置と大きさを{0,0,640,461}に変える
その自動更新を×に変える
その移動順を1に変える
その背景色を「黒」に変える
そのドッキング方向を「全体」に変える
初期化終了する
この設計スケール比率を{144,144}に変える
終わり
大きさが変化した時の手順
もしキャンバス1が無なら返す
描画幅は、幅/キャンバス1の倍率
描画高さは、高さ/キャンバス1の倍率
雪一覧のすべての雪についてそれぞれ繰り返す
雪の位置は{0から描画幅までの乱数,0から描画高さまでの乱数}
繰り返し終わり
キャンバス1を更新する
終わり
時間になった手順
雪一覧のすべての雪についてそれぞれ繰り返す
雪の縦を雪の縦+10に変える
雪の横を雪の横+[(雪の縦/2)度のサイン]*3に変える
もし雪の縦が描画高さ以上なら
雪の位置は、{0から描画幅までの乱数,-(0から描画高さ/2までの乱数)}
もし終わり
繰り返し終わり
キャンバス1を更新する
終わり
ライト時間になった手順
LEDを点灯する
0.7秒待つ
LEDは、0
終わり
クリスマスツリーを表示する手順
左=100
上=50
ーー地面を描く
図形描画によって円をキャンバス1に{左+60,上+270}から{180,30}まで白で描く
図形描画によってキャンバス1を白で{左+80,上+280}へ塗りつぶす
ーー幹を描く
カメさんの向きは、180
カメさんの太さは、2
カメさんの色は、茶
カメさんの位置を{左+135,上+228}に変える
カメさんを55だけ前へ進ませる
カメさんを90だけ左へ回転させる
カメさんを30だけ前へ進ませる
カメさんを90だけ左へ回転させる
カメさんを55だけ前へ進ませる
ーー左の枝を描く
カメさんの太さは、3
カメさんの色は、葉色
カメさんの位置を{左+150,上+70}に変える
カメさんを145だけ左へ回転させる
カメさんを80だけ前へ進ませる
2回繰り返せ
カメさんを145だけ左へ回転させる
カメさんを30だけ前へ進ませる
カメさんを145だけ右へ回転させる
カメさんを80だけ前へ進ませる
繰り返し終わり
カメさんを145だけ左へ回転させる
カメさんを50だけ前へ進ませる
ーー右の枝を描く
カメさんの向きは、0
カメさんの位置は、{左+150,上+70}
カメさんの色は、葉色
カメさんを145だけ右へ回転させる
カメさんを80だけ前へ進ませる
2回繰り返せ
カメさんを145だけ右へ回転させる
カメさんを30だけ前へ進ませる
カメさんを145だけ左へ回転させる
カメさんを80だけ前へ進ませる
繰り返し終わり
カメさんの太さは、3
カメさんを145だけ右へ回転させる
カメさんを50だけ前へ進ませる
カメさんを20だけ左へ回転させる
カメさんを70だけ前へ進ませる
ーー星を描くーー
カメさんの位置は、{左+151,上+42}
カメさんの色は、黄色
カメさんの太さは、1
カメさんを110だけ右へ回転させる
S=38
Pを5から5ずつ増やしながら25まで繰り返す
5回繰り返せ
カメさんを144だけ右へ回転させる
カメさんをSだけ前へ進ませる
繰り返し終わり
カメさんの位置は、{左+151,上+42+P}
S=S-10
繰り返し終わり
ーー枝を塗りつぶす
カメさんに{左+150,上+100}を「緑色」で塗りつぶす
ーー幹をを塗りつぶす
カメさんに{左+150,上+240}を「茶色」で塗りつぶす
カメさんに{左+150,上+270}を「茶色」で塗りつぶす
ーー背景塗りつぶし
カメさんを隠す
LEDを点灯する
終わり
ーーーーーーーーーーーーーーーーーー
LEDを点灯する手順
カメさんを隠す
(LEDが50)になるまで繰り返す
Cは、1から30までの乱数
もしC>7なら。C=1。もし終わり
Xは、(80から220までの乱数)*2
Xは、(Xを1で四捨五入したもの)/2
Yは、(90から225までの乱数)*2
Yは、(Yを1で四捨五入したもの)/2
カメさんの向きは、135
カメさんの太さは、4
もしX<150ならば
補正は、-8
そうでなければ
補正は、8
もし終わり
カメさんの位置は、{左+X+補正,上+Y+5}
DCは、カメさんの下部色
カメさんの位置は、{左+X,上+Y}
もしDCが「#008000」なら
カメさんの色は、色配列(C)
カメさんを4だけ前へ進ませる
LED=LED+1
もし終わり
繰り返し終わり
終わり
終わり
##まとめ
雪が降る様子を再現したメディアアート作品を作ってみました。今回は雪をテーマにしたアニメーションでしたが、キャンバス描画やタイマーなどの基本部分を応用すれば、季節感のある色々なアニメーション作品も作れます。また、描いたイラストや撮った写真を作品に取り入れるのも面白いと思います。
アニメーション作品は、書いたプログラムの実行結果が結果として分かりやすく表れる点で、プログラミングの勉強には最適かと思います。
ぜひプロデルでいろいろな作品を作ってみてください。
参考ページ