Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

p5.jsでリズムマシン

/*
 * rhythm machine
 *
 * @author aadebdeb
 * @date 2017/02/02
 */

var pattern = [
    true, false, false, false,
    true, false, false, false, 
    true, false, false, false,
    true, false, false, false
  ];

var noiseOsc, env;
var part, pharse;
var beat = 0;

var buttons;

function setup() {
  createCanvas(windowWidth, windowHeight);
  rectMode(CENTER);
  
  
  buttons = [];
  for(var y = 0; y < 4; y++) {
    for (var x = 0; x < 4; x++) {
      buttons.push(new Button(x, y));
    }
  }
  
  env = new p5.Env();
  env.setADSR(0.001, 0.01, 0.2, 0.05);
  env.setRange(1, 0);
  env.setExp(true);

  noiseOsc = new p5.Noise('pink');
  noiseOsc.amp(env);
  noiseOsc.start();

  phrase = new p5.Phrase('perc', makePerc, pattern);
  part = new p5.Part();
  part.addPhrase(phrase);
  part.setBPM(100);
  part.loop();
  part.start();
  
}

function draw() {
  background(30);
  
  noStroke();
  translate(width / 2, height / 2);
  for (var x = 0; x < 4; x++) {
    for(var y = 0; y < 4; y++) {
      buttons[x + y * 4].render();
    }
  }
  drawMouse();
}

function drawMouse() {
  var isOnButtons = false;
  
  for (var x = 0; x < 4; x++) {
    for (var y = 0; y < 4; y++) {
      if (buttons[x + y * 4].isOn(mouseX - width / 2, mouseY - height / 2)) {
        isOnButtons = true;
      }
    }
  }
  
  if (isOnButtons) {
    cursor(HAND);
  } else {
    cursor(ARROW);
  }
}

function mousePressed() {
  for (var x = 0; x < 4; x++) {
    for (var y = 0; y < 4; y++) {
      if (buttons[x + y * 4].isOn(mouseX - width / 2, mouseY - height / 2)) {
        pattern[x + y * 4] = !pattern[x + y * 4];
      }
    }
  } 
}

function makePerc(time, doPlay) {

  if (doPlay) {
    env.play();
  }
  
  beat++;
  if (beat == 16) {
    beat = 0;
  }
}

function Button(x_, y_) {

  this.x = x_;
  this.y = y_;
  this.w = (this.x - 1.5) * 100;
  this.h = (this.y - 1.5) * 100;
  this.size = 50;
  
  this.render = function() {
    if (pattern[this.x + this.y * 4]) {
      fill(255, 20, 147);
    } else {
      fill(102, 8, 58);
    }
    
    if (this.x + this.y * 4 == beat) {
      stroke(146, 255, 20);
      strokeWeight(1);
    } else {
      noStroke();
    }
    rect(this.w, this.h, this.size, this.size);
  }
  
  this.isOn = function(w, h) {
    return abs(this.w - w) <= this.size / 2 && abs(this.h - h) <= this.size / 2;
  } 
}
f:id:aa_debdeb:20170130080313j:plain