質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.52%

カーソルがある物体(四角形など)に触れた時に色を変えるプログラムを

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,229

tenjin

score 259

現在、Processingのexampleで紹介されていたSpringというコードを改良して、様々な図形の色がそれぞれ、カーソルが触れた時に色を変えるというプログラムを書いています。

参考コードのSpring:https://processing.org/examples/spring.html

現状では以下の様になっており、四角形の物体に触れた時のみ、全ての図形の色が変わる様になっています。それぞれの物体を制御するにはどうしたら良いでしょうか。

// Spring drawing constants for top bar
int springHeight = 32;  // Height
int left;               // Left position
int right;              // Right position
boolean over = false;   // If mouse over
boolean move = false;   // If mouse down and over


float R = 150;   // Rest position

// Spring simulation variables
float ps = R;    // Position


void setup() {
  size(640, 360);
  rectMode(CORNERS);
  noStroke();
  left = width/2 - 100;
  right = width/2 + 100;
}

void draw() {
  background(102);
  updateSpring();
  drawSpring();
}

void drawSpring() {  
  // Set color and draw top bar
  if(over || move) { 
    fill(#CE2828);
  } else { 
    fill(204);
  }
  rect(left, ps, right, ps + springHeight);
  ellipse(30,30, 50,50);
  ellipse(100, 50, 80, 80);

}


void updateSpring() {
  // Test if mouse is over the top bar
  if(mouseX > left && mouseX < right && mouseY > ps && mouseY < ps + springHeight) {
    over = true;
  } else {
    over = false;
  }

}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

Processingには暗いので良い例かどうか微妙ですが、とりあえず書いてみたという例を挙げてみます。

Processingの該当サンプルですが、変数があれこれ沢山あって分かりにくいです。多分サンプルではオブジェクト指向的な要素を排除しているのだろうと思います。しかしながら、オブジェクト指向的な思考にある程度なれてくると、それを排除してコードを書くことは(変数がばらばらに多数できるきたりすることが乱雑に感じるため)非常に苦痛になってきます。そこで本サンプルではオブジェクト指向をややこしくない程度に用いています。(ただしコード量は多少大きくなっています)

// 任意の図形を表す抽象クラス
abstract class MyShape {
  // 画面上へこの図形を描画するメソッド
  abstract void draw();

  // 指定位置がこの図形に含まれるかどうか判定するメソッド
  abstract boolean contains(float x, float y);
}

// 長方形を表すクラス
class MyRect extends MyShape {
  float x, y, w, h;

  MyRect(float x, float y, float w, float h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
  }

  void draw(){
    rect(x, y, w, h);
  }

  boolean contains(float mx, float my) {
    return mx >= x && mx <= (x + w) && my >= y && my <= (y + h);
  }
}

// 楕円を表すクラス
class MyEllipse extends MyShape {
  float x, y, w, h;

  MyEllipse(float x, float y, float w, float h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
  }

  void draw() {
    ellipse(x, y, w, h);
  }

  boolean contains(float mx, float my) {
    float dx = 2 * (mx - x) / w;
    float dy = 2 * (my - y) / h;
    return sqrt(dx * dx + dy * dy) <= 1.0;
  }
}

ArrayList<MyShape> shapes = new ArrayList<MyShape>();

void setup(){
  size(640, 360);
  noStroke();
  MyShape s;
  s = new MyRect(width/2-100, 150, 200, 32);
  shapes.add(s);
  s = new MyEllipse(30, 30, 50, 50);  
  shapes.add(s);
  s = new MyEllipse(100, 50, 80, 80);  
  shapes.add(s);
}

void draw() {
  background(102);
  for (MyShape s : shapes) {
    if (s.contains(mouseX, mouseY)) {
      fill(#CE2828);
    } else {
      fill(204);
    }
    s.draw();
  }
}

なお、rectMode, ellipseModeはいずれもデフォルト、即ち長方形は左上の座標、幅、高さで指定し、楕円は中心の座標、幅、高さで指定するものと仮定しています。

このコードが何をしているかは読み解いてみてください。クラスを定義している部分が難しく感じるかも知れませんが、そこは申し訳ないです。そこについてはJavaの初歩の解説を調べてみてください。またこんな記事も参照してみてください。
Processingでオブジェクト指向プログラミング


蛇足的補足:ProcessingにはPShapeというクラスが既にあるにもかかわらず、なぜわざわざMyShapeというクラスを定義するのか奇妙に感じる向きがいらっしゃると思います。最初PShapeを用いようとしたのですがcontainsメソッドがなかった(正確に言えば定義はされているが実装されてなかった)のでMyShapeなんてものを定義してしまいました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/02 13:55

    ご丁寧にご回答いただきましてありがとうございます。オブジェクト指向もきちんと勉強したいと思います。

    キャンセル

+1

こんな感じかな

void drawSpring() {  
  // Set color and draw top bar
  if (over || move) { 
    fill(#CE2828);
  } else { 
    fill(204);
  }
  rect(left, ps, right, ps + springHeight);

  if (dist(mouseX, mouseY, 30, 30)<25)fill(#CE2828);
  ellipse(30, 30, 50, 50);

  fill(204);
  if (dist(mouseX, mouseY, 100, 50)<40||over || move)fill(#CE2828);
  ellipse(100, 50, 80, 80);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/02 13:56

    ご回答いただきましてありがとうございます!
    すでに書いてあったコードを元にご提案くださったので大変分りやすかったです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる