コンピュータプログラミングII (13)

モノをひとまとまりとして捉える (6)

このスライドの使い方

テキスト等がはみ出した場合は、フォントサイズを小さくして調整する。 「S」 キーで小さく、「B」 キーで大きくなる。また、 下記のキーボード操作が使用できる。(一部キー操作は IE のみ対応)

「←」 or 「Page Up」 前のスライドに戻る
「→」 or 「Page Down」 or「スペース」 次のスライドに進む
「Home」 and 「End」 先頭(Home)または最後(End)のスライドへ移動
「C」 or 「contents?」 をクリック スライド一覧の表示
「F11」 or 「Ctrl+Shift+F (Win)」, 「Cmd+Shift+F (Mac)」 フルスクリーン表示と通常表示の切り替え
「F」 フッタの表示と非表示の切り替え
「A」 全スライド表示に切替 (印刷時に使う)
「S」「-」/「B」「+」 フォントサイズの大(B) 小(S)

本日のゴール

マウスとキーボードによるインタラクティブなプログラム

これまでは mousePressed など、 状態を表すシステム変数を使ってきた。

これらの問題を解決する方法として、組み込み関数を用いる方法がある。

イベントとイベントハンドラ

このような、突然発生する出来事のことをイベント (event)と呼び、 マウスクリックのイベントが発生した、などと言う。

イベントが発生した時に、何らかの処理をするものをイベントハンドラ (event handler)と呼ぶ。

これらの関数は、イベントが発生した時に自動的に呼び出される。

例: マウスをクリックすると回転が止まる円

一定の回転半径、回転速度で円が回転している。 マウスをクリックすると回転が停止し、再度クリックするとまた動き出す。

例: マウスをクリックすると回転が止まる円

final int d = 50;       // 円の直径
final int r = 200;      // 回転半径
final int dTheta = 2;   // 回転角の増分/1フレーム
int theta;              // 回転角
boolean isRunning;      // 動いているか否か

void setup() {
  size(480, 480);
  noStroke();
  background(255, 255, 255);
  colorMode(HSB, 360, 100, 100);  // 色の指定をHSBに
                                  // (色相 0-360, 彩度 0-100, 明度 0-100)
  theta = 0;
  isRunning = true;
}

例: マウスをクリックすると回転が止まる円

void mouseClicked() {
  isRunning = !isRunning;
}

void draw() {
  background(0, 0, 100);
  float rad = radians(theta);
  float x =  r * cos(rad);
  float y = -r * sin(rad);
  fill(theta % 360, 100, 100);
  ellipse(x + width / 2, y + height / 2, d, d);
  if(isRunning) {
    theta = theta + dTheta;
  }
}

練習1: マウスをクリックすると重力が上下反転

ボールを斜めに落とした時の動きをアニメーションにする。 ボールは床と天井と壁でバウンドさせる。 床と壁の弾性係数は elas (= 0.98等) とする。 画面サイズは高さ 480、幅 480 とする。

マウスをクリックすると、重力が下向きになったり上向きになったり交互に変化するようにすること。 また、重力の向きに連動してボールの色も変化するようにすること。

ファイル名: ballGravityUpAndDown.pde

練習1: マウスをクリックすると重力が上下反転 - ヒント

練習1: 参考 - 重力が下向きのみ (ball_02_oo4.pde)

キーの検出 - 通常の文字

通常の文字 (ASCII keys) の場合は char 型のシステム変数 key を使う。

void keyPressed() {
  if(key == 'x') {
    turtle.moveLeft();
  }
  else if(key == 'm') {
    turtle.moveRight();
  }
}

次の char 型の定数を使うことができる(これらは特殊文字扱いではない): BACKSPACE, TAB, ENTER, RETURN, ESC, DELETE.

キーの検出 - 特殊文字

カーソルキーなどの特殊文字の場合は key が CODED という値を持つので、 その場合には int 型のシステム変数 keyCode を調べる。

void keyPressed() {
  if(key == CODED) {
    if(keyCode == LEFT) {
      turtle.moveLeft();
    }
    else if(keyCode == RIGHT) {
      turtle.moveRight();
    }
  }
}

定数として UP, DOWN, LEFT, RIGHT, ALT, CONTROL, SHIFT などが用意されている。他のキーについては以下を参照。

例: ドリフトする亀

x, m のキーで、のんびりしているはずの亀が左右にドリフト(横すべり)する。

例: ドリフトする亀

文字・文字列の描画

text関数による文字の表示は、 ヒストグラムのラベルとして用いたが、ここで関連する関数をまとめる。

textSize(文字の大きさ)
文字の大きさをピクセル数で指定。引数の型は float。
text(文字または文字列, 左端のx座標, ベースラインのy座標)
文字または文字列を描画。
textWidth(文字または文字列)
文字または文字列の幅を算出。
textAscent()
ベースラインより上側の高さ。
textDescent()
ベースラインより下側の高さ。g, j, p, q, y などがベースラインよりも下に出る。
void draw() {
  fill(150, 50, 50);
  textSize(width / 80);
  text('T', x, y);
}

フォントの指定が必要であれば reference などを参照のこと。

練習2: フェードアウトする文字

キー入力した1文字1文字が、画面のランダムな位置に表示され、 だんだん小さくなっていくアニメーションを作成しなさい。 文字の色は1文字1文字変えること。 現れる文字の数には上限があってよい。 画面サイズは高さ 480、幅 480 とする。

1文字を表すクラス Letter を定義し、利用すること。

ファイル名: typing.pde

練習2: フェードアウトする文字 - ヒント

練習2: フェードアウトする文字 - ヒント

class Letter の実装例

class Letter {
  char charLetter;             // 文字
  float x;                     // 文字の左端のx座標
  float y;                     // 文字のベースラインのy座標
  float h;                     // 文字の色相
  float charSize;              // 文字の大きさ [pixels]
  final float dCharSize = 1;   // 文字の大きさの減少値 [pixels]
  Letter(char aLetter) {
    charLetter = aLetter;
    charSize = random(128, 256);
    textSize(charSize);
    x = random(0, width - textWidth(aLetter));
    y = random(textAscent(), height - textDescent());
    h = random(0, 360);
  }
  void draw() {
    if (charSize > 0) {
      fill(h, 100, 100);
      textSize(charSize);
      text(charLetter, x, y);
      charSize -= dCharSize;
    }
  }
}

モードによって異なる動作をする関数 - 描画色

Processing の組み込み関数の中にはモード(mode)によって引数の解釈が変わり、 異なる動作をするものがある。

注: 動作状態の種類をモード(mode)と呼ぶ。例: もうすでに冬休みモードだ。

colorMode (復習)

塗りつぶしの色を決める fill() などの関数は、引数の解釈が colorMode によって異なる。

colorMode(HSB, 色相の最大値, 彩度の最大値, 明度の最大値);
fill(色相, 彩度, 明度);
colorMode(RGB, 赤の最大値, 緑の最大値, 青の最大値);
fill(赤成分, 緑成分, 青成分);

モードによって異なる動作をする関数 - 図形

図形の位置や大きさを指定する方法が、モードにより異なる。

ellipseMode()

rectMode()

モードによって異なる動作をする関数 - テキスト

text() 関数でテキストを書くときの配置が、モードにより異なる。

textAlign()

Processing のスケッチとスケッチフォルダ