画像ファイルの描画
Processing は gif, jpg, tga, png 形式の画像データを表示できます。画像データはPImageクラスのオブジェクトとしてプログラム内に読み込みます(PImageオブジェクトには画像のピクセルデータが保存される)。読み込んだ複数のPImageオブジェクトを切り替えて表示することでアニメーションさせることができます。サンプルや練習問題で使う画像ファイルは、画像ページからコピーできます。
単独の画像ファイルを扱う
リスト2-2は、描いた円が左から右へ移動するプログラムでした。これと同様の動きで、画像ファイルから読み込んだイメージが移動するプログラムを作ります。(1) スケッチフォルダ(pdeファイルのあるフォルダ、[Sketch]メニュー→[Show Sketch Flolder]で表示される)の下にdataフォルダを作り、その中に画像ファイル(今の場合star20.png)を置きます。Processingはdataフォルダを起点に画像ファイルを探します。
(2) PImageオブジェクトを入れる変数を用意します(setupメソッドの前)。PImageはProcessingが画像データを扱うためのクラス(プログラム部品)です。
PImage dot;
(3) loadImageメソッドに画像ファイルを指定してPImageオブジェクトを作ります(setupメソッド内)。
dot = loadImage("star20.png");
(4) processingのimageメソッドを使って、画像データを描画します(普通drawメソッドの中)。
image(dot, x, height/2-dot.height/2);
クリックで開始⇔停止
【リスト9-1】 int x; // 位置(x座標) PImage dot; //変数の用意 ←(2) void setup() { size(250, 125); //描画するための画面 dot = loadImage("star20.png"); //画像の描画 ←(3) x = -dot.width; //最初の位置、画像の幅分左に置く } void draw() { background(255); //モニタ画面の背景を白でクリア x = x + 1; // 位置を変化。 image(dot, x, height/2-dot.height/2); //画像を描画 ←(4) if (x >= width) { x = -dot.width; } }
複数の画像ファイルをまとめて扱う
15個の画像データを順番に表示し、パラパラ漫画のようにアニメーションさせることを考えます。(1) PImageオブジェクトを入れる配列gazouを用意します(setupメソッドの前)。
PImage[] gazou;
(2) 配列gazou内のデータ数を指定し、配列の領域を確保。その後、画像ファイルを順に読みPImageオブジェクトを作って、配列に入れます(setupメソッドの中)。
gazou = new PImage[15]; ←[ ]の中の数字に、画像の数を指定する。 for (int i = 1; i <= gazou.length; i++) { gazou[i-1] = loadImage("change" + i + ".png"); }画像ファイルは、スケッチフォルダのdataフォルダ直下にあるものとします。この例では、ファイル名がchange1.png, change2.png, …, change15.pngの15個。
(3) 画像の枚数が15枚と多くないので、フレームレート(1秒間の描画回数)がデフォルト(60)のままだと、目まぐるしく動きすぎます。frameRate()関数を使って、調整します(setupメソッドの中)。
frameRate(10);numberの値が0のとき、配列gazouの最初の画像データを、x, yの位置に表示する。
(4) processingのimage関数を使って、画像データを描画する(普通drawメソッドの中)。
number++; //次に表示する画像の番号 number = number%15; // numberの値は15になったら0に戻る x = width/2 - gazou[number].width/2; // 画面の中央に表示 y = height/2 - gazou[number].height/2; image(gazou[number], x, y);numberの値が0のとき、配列gazouの最初の画像データを、x, yの位置に表示する。
クリックで開始⇔停止
【リスト9-2】 PImage[] gazou; //画像を格納する配列 ←(1) int cell = 15; //画像の数 int number = 0; //表示する画像の番号 int x, y; void setup(){ size(250, 250); gazou = new PImage[cell]; for (int i = 1; i <= gazou.length; i++) { gazou[i-1] = loadImage("change" + i + ".png"); } // ↑画像のロード ←(2) frameRate(10); } void draw(){ background(255); number++; number = number%cell; //次に表示する画像の番号 x = width/2 -gazou[number].width/2; y = height/2 -gazou[number].height/2; image(gazou[number], x, y); //描画 ←(2) }
リスト9-2で使う画像ファイルは、 画像ページにあります。
背景用の画像が繰り返し動く
ゲームやアニメーションでは、背景画像が左あるいは右へ動きながら連続して表示される場面をよく見かけます。下は背景用の画像を左に動かして表示するスケッチの例です。(1) PImageオブジェクトを入れる変数imgを用意(setupメソッドの前)。
PImage img;(2) 画像データを変数imgに読み込む(setupメソッドの中)。
img = loadImage("fieldH.png");(3) 元の画像を0から画像の幅分、1ピクセルずつ左にずらしながら表示することで、左へ動いているように見せる。ずらす大きさの最大値は、画像の幅ー1で、ずらすピクセル数が最大値となったら、また普通に表示します。ずらすピクセル数は次のように計算します。
int shiftX = frameCount % img.width;frameCountはProcessingのシステム変数で、スケッチの起動後画面に表示されたフレームの数が保存されています。frameCountはdrawが実行されるたびに1ずつ増加するので、これを画像の幅で割った余りを使います。
(4) ずらした画像を表示するにはcopy関数を使う。画像幅が、画面幅より小さい場合は繰り返し画像が表示されます。
for (int i = -shiftX; i < width; i += img.width) { copy(img, 0, 0, img.width, height, i, 0, img.width, height); }
クリックで開始⇔停止
【リスト9-3】 PImage img; //画像用変数の用意←(1) void setup() { size(500, 250); img = loadImage("fieldH.png"); //画像のロード←(2) } void draw() { int shiftX = frameCount % img.width; // 0から(画像の幅-1)までの値←(3) for (int i = -shiftX; i < width; i += img.width) { copy(img, 0, 0, img.width, height, i, 0, img.width, height); } // shiftXピクセル左にずらした画像を描く←(4) }
リスト9-3で使う画像ファイルは、 画像ページにあります。
演習問題
キーgで開始、sで停止。マウス押下でジャンプ。
【問題9-1】インタラクティブなアニメーションを制作してみましょう。10枚の画像を、リスト9-2のように複数の画像を順番に表示し、アニメーションさせます。そこで、マウスでクリックするとキャラクタが上部に大きくジャンプするようにします。マウスボタンを押している間は、ジャンプしている画像を上部に表示し、いったんアニメーションを止め、ボタンを離すと再び歩くような動きにします。左の実行例で使っている画像(10枚の跳ねている姿と背景)は、画像ページにあります。
左図では、フレームレートを5にしています。
キーgで開始、sで停止。マウス押下でジャンプ。
【問題9-2】問題9-1と同様なインタラクションをするアニメーションを制作します。キャラクタが歩いているところを、マウスでクリックするとジャンプします。問題9-19と違い、画像の表示位置を少しずつ変化させます。マウスボタンを押している間は、ジャンプしている画像を上部に表示し、いったんアニメーションを止め、ボタンを離すと再び歩くような動きにします。左の実行例で使っている画像(5枚の歩いている姿、ジャンプ、道)は、画像ページにあります。
左図では、フレームレートを5にしています。
キーgで開始、sで停止。マウス押下でジャンプ。
【問題9-3】問題9-2のキャラクタが歩くアニメーションを修正し、キャラクタのx方向の位置は中央から動かさず、背景画像を右へ流れるように動かして、歩いているように見せてください。
リスト9-3とは背景画像を動かす方向が逆なので、x方向に画像をずらす大きさshiftXを、リスト9-3とは逆の(画像の幅-1)から0へ変化させます。
int shiftX = frameCount % 画像の幅; shiftX = (画像の幅 - 1) - shiftX;上図では、フレームレートを10にしています。