Tonejs 音序器无法将变量识别为对象

Tonejs sequencer does not recognise variables into an object

我正在尝试使用 p5.js、p5.sound 库和 tone.js

构建一个包含音序器的对象

问题是我的代码无法识别在一个对象内的一个函数中编写的变量。

class tr909 中的所有其他函数可以识别我在 class 构造函数中声明的变量,但变量 "sequence" 无法识别它们。

正如您在下面看到的,tr909 class 有 sX 和 sY 变量,但是当我在名为 sequence 的函数中(在 tr909 class 内部,在底部),这个函数赢了'不再识别变量。

你知道为什么会这样吗?

谢谢! :)

 //object 
let tr9091;
let bL9091 = 16; //beat lenght

let posX9091 = 100; //positionX 909
let posY9091 = 220; //positionY 909

let sX9091 = 320; //sizeX of 909
let sY9091 = 60; //sizeY of 909

// var cellWidth = sX9091 / bL9091; //dont know why, if I put it in constructor of 909 object, sequence function does not recognise cellWidth

//Pre-load  audio files 
let hh909, clp909m, bd909;

let time;
let beatIndex;
var sX;
let sequence;
// var sX = 1;

function preload() {

  bd909 = loadSound('assets/bass_sample.mp3');
  hh909 = loadSound('assets/hh_sample.mp3');
  clp909 = loadSound('assets/clap_sample.mp3');

}

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

  tr9091 = new tr909(bd909, hh909, clp909, bL9091, posX9091, posY9091, sX9091, sY9091);


}

function draw() {

}

function keyPressed() {
  if (key === ' ') {
    tr9091.clicked();
  }
}

function mousePressed() {
  tr9091.rectPressed();
}

class tr909 {

constructor(bd, hh, clp, beatLenght, pX, pY, sX, sY) {
    //variables 
    this.bd = bd;
    this.hh = hh;
    this.clp = clp;

    this.beatLenght = beatLenght;


    this.pX = pX; //positionX 909
    this.pY = pY; //positionY 909

    this.sX = sX; //sizeX 909
    this.sY = sY; //sizeY 909

    this.cellWidth = this.sX / this.beatLenght;


    //sequences
    this.bdPat = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0];
    this.hhPat = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
    this.clpPat = [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0];

    this.sPat = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];

    this.cursorPos = 0;

    //phrases
    this.bdPhrase = new p5.Phrase('bd', (time) => {
      this.bd.play(time)
    }, this.bdPat);

    this.hhPhrase = new p5.Phrase('hh', (time) => {
      this.hh.play(time)
    }, this.hhPat);

    this.clpPhrase = new p5.Phrase('clp', (time) => {
      this.clp.play(time)
    }, this.clpPat);


    //parts
    this.drums = new p5.Part();


    //adding phrase to parts
    this.drums.addPhrase(this.bdPhrase);
    this.drums.addPhrase(this.hhPhrase);
    this.drums.addPhrase(this.clpPhrase);

    this.drums.addPhrase('seq', this.sequence, this.sPat);



    //BPM
    let bpmCTRL;
    this.bpmCTRL = createSlider(30, 120, 120, 1);
    this.bpmCTRL.position(pX + 10, pY + 70);
    this.bpmCTRL.input(() => {
      this.drums.setBPM(this.bpmCTRL.value())
    });
    this.drums.setBPM('120');

    this.drawMatrix();

  } //final constructor


  clicked() { //play loop
    this.drums.loop();
  }

  rectPressed() {
    //Y mouse click inside the object 
    if ((mouseY > this.pY && mouseY < this.pY + this.sY) && (mouseX > this.pX && mouseX < this.pX + this.sX)) {
      this.rowClicked = floor(3 * (mouseY - this.pY) / this.sY);
      this.indexClicked = floor(16 * (mouseX - this.pX) / this.sX);

      if (this.rowClicked === 0) {
        console.log("firstrow " + this.indexClicked);
        this.bdPat[this.indexClicked] = +!this.bdPat[this.indexClicked];
      } else if (this.rowClicked === 1) {
        console.log("secondtrow");
        this.hhPat[this.indexClicked] = +!this.hhPat[this.indexClicked];
      } else if (this.rowClicked === 2) {
        console.log("thrtrow");
        this.clpPat[this.indexClicked] = +!this.clpPat[this.indexClicked];
      }
      this.drawMatrix();
    }
  }



//visual interface
  drawMatrix() {

    fill(80);
    stroke('gray');
    strokeWeight(2);
    rect(this.pX, this.pY, this.sX, this.sY);


    stroke('gray');
    strokeWeight(2);

    //vertical lines
    for (let i = 0; i < this.beatLenght; i++) {
      line(this.pX + i * this.cellWidth, this.pY, this.pX + i * this.cellWidth, this.pY + this.sY);
    }

    for (let i = 0; i < 4; i++) {
      line(this.pX, this.pY + i * this.sY / 3, this.pX + this.sX, this.pY + i * this.sY / 3);
    }

    //draw circles

    for (let i = 0; i < this.beatLenght; i++) {
      if (this.bdPat[i] === 1) {
        ellipse(this.pX + i * this.cellWidth + 0.5 * this.cellWidth, this.pY + this.sY / 6, 10);
      }
      if (this.hhPat[i] === 1) {
        ellipse(this.pX + i * this.cellWidth + 0.5 * this.cellWidth, this.pY + this.sY / 2, 10);
      }
      if (this.clpPat[i] === 1) {
        ellipse(this.pX + i * this.cellWidth + 0.5 * this.cellWidth, this.pY + this.sY * 5 / 6, 10);
      }
    }

  }

  sequence(time, beatIndex) {

    this.cellWidth = this.sX / this.beatLenght;

    stroke('red');
    fill(255, 0, 0, 30);
    rect(beatIndex * this.cellWidth, this.sX, this.cellWidth, this.sY);
    console.log(beatIndex);
  }


} //final object

因为这里:

this.drums = new p5.Part();
//adding phrase to parts
this.drums.addPhrase(this.bdPhrase);
this.drums.addPhrase(this.hhPhrase);
this.drums.addPhrase(this.clpPhrase);
this.drums.addPhrase('seq', this.sequence, this.sPat);

您将其作为回调函数传递。检查此线程中的第一个答案: How to access the correct `this` inside a callback?

将参数 this.sequence 替换为:

function(){ this.sequence() }.bind( this )

甚至更短:

this.sequence.bind(this);

或者像这样:

()=>{ this.sequence() }

或者,当你想传入参数或return值时:

(...args) => this.sequence(...args)