一个p5.js自定义旋转行为的问题。

问题描述 投票:1回答:1

我试图做一个自定义的旋转磁性行为,使一堆box()正常旋转,如果在一定距离内,就会停止旋转,并向光标进行磁力吸引。

我不知道如何解决这个问题,因为现在立方体只能随机旋转。

请帮助提供一些线索,谢谢

let cubes = [];

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  backCol = color(243, 243, 243);
  //background(backCol);

  for (let i = 0; i < 10; i++) {
    for (let j = 0; j < 10; j++) {
      let xPos = map(i, 0, 9, 50, width - 50);
      let yPos = map(j, 0, 9, 50, height - 50);

      cubes.push(new Cubes(xPos, yPos));

    }
  }

}

function draw() {
  background(backCol);
  noFill();

  for (let a = 0; a < cubes.length; a++) {
    cubes[a].update();
  }
}

class Cubes {

  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.size = 30;
    this.stroke = 70;
    this.shift1 = color(96);
    this.shift2 = color(244);
    this.a = atan2(mouseY-this.y, mouseX-this.x);
  }

  update() {
    this.shape();
    this.magnetic();
  }
  

  shape() {
    push();
    stroke(this.stroke);
    translate(this.x - width / 2, this.y - height / 2, 0);
    rotateX(millis()/1000);
    rotateY(millis()/1000);
    box(this.size);
    pop();
  }

  shift_Color() {
    let distance = dist(mouseX, mouseY, this.x, this.y);
    let shiftX = map(mouseX,0,this.a,0,1.0);
    let change = lerpColor(this.shift1,this.shift2,shiftX);

    if (distance < this.a) {
      fill(change);
    } else {
      noFill();
    }
  }
  
  magnetic() {
    let distance = dist(mouseX, mouseY, this.x, this.y);
    
    if (distance < this.size * 2) {
      rotateX(this.a);
      rotateY(this.a);
    } else {
      rotateX(millis()/1000);
      rotateY(millis()/1000);
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
javascript processing p5.js
1个回答
1
投票

你必须调用方法 magnetic() 在该方法中 shape其间 push()pop()而不是 rotateX()rotateY() 而不是在画完盒子之后。

shape() {
    push();
    stroke(this.stroke);
    translate(this.x - width / 2, this.y - height / 2, 0);
    //rotateX(millis()/1000);
    //rotateY(millis()/1000);
    this.magnetic()
    box(this.size);
    pop();
}

更多的角度 a 取决于当前鼠标的位置,而不是鼠标的位置,当对象被构造时。计算角度 a 在该方法中 magnetic 而不是在构造函数中。

magnetic() {
    let distance = dist(mouseX, mouseY, this.x, this.y);

    if (distance < this.size * 2) {
      this.a = atan2(mouseY-this.y, mouseX-this.x);
      rotateX(this.a);
      rotateY(this.a);
    } else {
      rotateX(millis()/1000);
      rotateY(millis()/1000);
    }
}

请看这个例子。

let cubes = [];

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  backCol = color(243, 243, 243);
  //background(backCol);

  for (let i = 0; i < 10; i++) {
    for (let j = 0; j < 10; j++) {
      let xPos = map(i, 0, 9, 50, width - 50);
      let yPos = map(j, 0, 9, 50, height - 50);

      cubes.push(new Cubes(xPos, yPos));

    }
  }

}

function draw() {
  background(backCol);
  noFill();

  for (let a = 0; a < cubes.length; a++) {
    cubes[a].update();
  }
}

class Cubes {

  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.size = 30;
    this.stroke = 70;
    this.shift1 = color(96);
    this.shift2 = color(244);
    this.a = atan2(mouseY-this.y, mouseX-this.x);
  }

  update() {
    this.shape();
    //this.magnetic();
  }
  

  shape() {
    push();
    stroke(this.stroke);
    translate(this.x - width / 2, this.y - height / 2, 0);
    //rotateX(millis()/1000);
    //rotateY(millis()/1000);
    this.magnetic()
    box(this.size);
    pop();
  }

  shift_Color() {
    let distance = dist(mouseX, mouseY, this.x, this.y);
    let shiftX = map(mouseX,0,this.a,0,1.0);
    let change = lerpColor(this.shift1,this.shift2,shiftX);

    if (distance < this.a) {
      fill(change);
    } else {
      noFill();
    }
  }
  
  magnetic() {
    let distance = dist(mouseX, mouseY, this.x, this.y);
    
    if (distance < this.size * 2) {
      this.a = atan2(mouseY-this.y, mouseX-this.x);
      rotateX(this.a);
      rotateY(this.a);
    } else {
      rotateX(millis()/1000);
      rotateY(millis()/1000);
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
© www.soinside.com 2019 - 2024. All rights reserved.