見出し画像

p5.jsでシンセサイザーを作る 第8話 ホイール制作の後編

Javascriptとp5.jsを使って、オリジナルなシンセサイザーを作るプログラミングの記事です。とりあえず何を作るのかを手っ取り早くお伝えしたいので、第0話で公開している完成品もチェックしてみてください。

シンセサイザーのホイール制作

ぐりぐり

前回のコードと実行結果

前回はfor文を使って目盛が一定の範囲内に描画されるようにすることでホイールを表現しました。

let x = 100;
let y = 50;
let lineSize = 50;
let lineInterval = 10;

let slideMax = 150; //指定範囲の最大値
let slideMin = 100; //指定範囲の最小値

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(200);
  
  fill(250,125,0);
  for (let i = 0; i < 10; i++){
    if(y + i * lineInterval <= slideMax && y + i * lineInterval >= slideMin){
      line (x, y + i * lineInterval, x + lineSize, y + i * lineInterval);
    }
  }
}
描画された状態

目盛りの線を動かす

当たり判定とマウスの動き

この処理のポイントは、マウスが押された、マウスドラッグされた、マウスが離された。という3つのイベントを検出する事です。

touchStarted()で当たり判定をとります。ここでマウスクリックが始まった点を基準として設定します。
touchMoved()でドラッグが検出された時、目盛りの起点となるyにマウスの現在値を代入します
touchEnded()ではマウスクリックが話されたときに、これらの処理を停止するようにします。

目盛りを動かすコード

let strokeValue = 2;

let x = 50;
var y = 100;

let slideStat = false;

let slideMax = 300;
let slideMin = 100;
let lineInterval = 10;

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(250);
  
  fill(150,150,150);
  stroke(150, 100, 100);
  slideLineDraw();
}

function slideLineDraw(){
  fill(255, 125, 0);
  for (let i = 0; i < 50; i++){
    if(y + i * lineInterval <= slideMax && y + i * lineInterval >= slideMin){
      line (x, y + i * lineInterval, x + 20, y + i * lineInterval);
    }
  }
}

function touchStarted() {
    if (
    mouseX > x &&
    mouseX < x + 30 &&
    mouseY > y &&
    mouseY < y + slideMax - slideMin
  ) {
    slideStat = true;
    }
}

function touchMoved() {
   if(slideStat == true){
    y = mouseY; //- mousePosY;
  }
}

function touchEnded() {
  slideStat = false;
}

繰り返しのfor文と、当たり判定、これに合致する起点となるyの値をマウスの操作で可変するようにしました。
上記はそのコードの全体全体像です。

実行すると

動いた!

マウスの座標がドラッグされることによって目盛りが動いています。嬉しい!
しかし、この処理ではマウス座標の下半分だけが描画されているので、上半分も無理やり実装してみます。

function slideLineDraw(){
  fill(255, 125, 0);
  //下半分の繰り返し描画
  for (let i = 0; i < 50; i++){
    if(y + i * lineInterval <= slideMax && y + i * lineInterval >= slideMin){
      line (x, y + i * lineInterval, x + 20, y + i * lineInterval);
    }
  }
  //上半分の繰り返し描画
  for (let i = 0; i < 50; i++){
    if(y - i * lineInterval <= slideMax && y - i * lineInterval >= slideMin){
      line (x, y - i * lineInterval, x + 20, y - i * lineInterval);
    }
  }
}
上下ともに良好

うまく動くようになりました。今回の実装では横線の描画を上下でそれぞれ50回繰り返していますが、そこまで沢山はいらないと思いました。とにかく、このロジックを応用してホイールの回転を表現できそうです。

ここまでのコード

let strokeValue = 2;

let x = 50;
var y = 100;

let slideStat = false;

let slideMax = 300;
let slideMin = 100;
let lineInterval = 10;

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(250);
  
  fill(150,150,150);
  stroke(150, 100, 100);
  slideLineDraw();
}

function slideLineDraw(){
  fill(255, 125, 0);
  //下半分の繰り返し描画
  for (let i = 0; i < 50; i++){
    if(y + i * lineInterval <= slideMax && y + i * lineInterval >= slideMin){
      line (x, y + i * lineInterval, x + 20, y + i * lineInterval);
    }
  }
  //上半分の繰り返し描画
  for (let i = 0; i < 50; i++){
    if(y - i * lineInterval <= slideMax && y - i * lineInterval >= slideMin){
      line (x, y - i * lineInterval, x + 20, y - i * lineInterval);
    }
  }
}

function touchStarted() {
    if (
    mouseX > x &&
    mouseX < x + 30 &&
    mouseY > y &&
    mouseY < y + slideMax - slideMin
  ) {
    slideStat = true;
    }
}

function touchMoved() {
   if(slideStat == true){
    y = mouseY; //- mousePosY;
  }
}

function touchEnded() {
  slideStat = false;
}

これらを応用して、影とか、ビジュアル面の部分を装飾していくと、意外にホイールの表現ができるようになると思います。

このように応用します

完成版ホイールのコード全文

let strokeValue = 2;
let mousePosX = 0.0;
let mousePosY = 0.0;

let slideX = 70;
let slideY = 170;
let slideSizeX = 22;
let slideSizeY = 100;

let slideKnobX = slideX + 8;
let slideKnobY = slideY + slideSizeY / 2 - 5;
let slideKnobCenterY = slideY + slideSizeY / 2 - 5;

let slideStat = false;

let slideMax = 176;
let slideMin = 254;

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(250);
  
  fill(110,110,110);
  rect(slideX,slideY,slideSizeX,slideSizeY,2);
  
  fill(180,180,180);
  rect(slideX + 2 ,slideY + 4, 17 ,slideSizeY - 8,2);
  fill(150,150,150);
  stroke(150, 100, 100);
  noStroke();
  triangle(slideX + 2 ,slideY + 4, 
           slideX + 2  ,slideY + slideSizeY - 4,
           slideX + 17,slideY + slideSizeY - 4);
  stroke(strokeValue);
  slideLineDraw();
  slideKnobDraw();
  slideLineDraw();
}

function slideKnobDraw(){
  fill(250, 250, 250);
  rect(slideX + 1,slideKnobY,18,10);
  if (slideStat == true){
      fill(255, 125, 0);
      rect(slideX + 1,slideKnobY,18,10);
  }
}

function slideLineDraw(){
  fill(255, 125, 0);
  for (let i = 0; i < 10; i++){
    if (slideKnobY - i * 8 >= slideMax){
      line(slideX + 3 ,slideKnobY - i * 8,slideX + 17,slideKnobY - i * 8);
    }
  }
  for (let i = 0; i < 10; i++){
    if (slideKnobY + i * 8 <= slideMin){
      line(slideX + 3,slideKnobY + 10 + i * 8,slideX + 17 ,slideKnobY + 10 + i * 8);
    }
  }
}

function touchStarted() {
    if (
    mouseX > slideX &&
    mouseX < slideX + 30 &&
    mouseY > slideY &&
    mouseY < slideY + slideSizeY
  ) {
    slideStat = true;
    //slideY= 0
    mousePosY = mouseY;
    }
}

function touchMoved() {
   if(slideStat == true){
    slideKnobY = mouseY - mousePosY + slideKnobCenterY;
    if (slideKnobY <= slideMax) {
      slideKnobY = slideMax;
    }
    if (slideKnobY >= slideMin) {
      slideKnobY = slideMin;
    }
    slideOct = map(slideKnobY, slideMin, slideMax,0.5,2);
  }
}

function touchEnded() {
  slideStat = false;
  slideKnobY = slideY + slideSizeY / 2 - 5;
}

実際にp5.jsのエディターにコピペして、試してみてください。

ここまで、ノブ、キー、ホイールの表現ができました。
このパーツを使えば、自分が作りたい楽器のインターフェースが配置できるようになります。
このあとは、作ったパーツを配置して動作させるフェーズに入ります。

いいなと思ったら応援しよう!

この記事が参加している募集