javascript - 鼠标按下时的矢量吸引力
问题描述
目前正在尝试使用 createVector 函数在 3D 立方体上创建吸引效果。该吸引力旨在在按下鼠标时触发,但目前它正在说明错误:
Uncaught TypeError: Cannot read property 'copy' of undefined
编码:
let cubes = [];
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
backCol = color(243, 243, 243);
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 cube of cubes) {
cube.update();
}
attracting();
}
function attracting() {
for (let a = 0; a < cubes.length; a++) {
cubes[a].attraction(mouseX,mouseY);
}
}
class Cubes {
constructor(x, y) {
this.x = x;
this.y = y;
this.size = 30;
this.stroke = 70;
this.gap = 150;
this.shift1 = color(96);
this.shift2 = color(244);
//vector variables
this.pos = createVector(x, y);
this.vel = createVector();
this.acc = createVector();
}
update() {
this.shape();
this.test_Color();
//attraction values
this.vel.add(this.acc);
this.vel.limit(5);
this.pos.add(this.vel);
this.acc.mult(0);
}
shape() {
push();
stroke(this.stroke);
this.test_Color();
translate(this.x - width / 2, this.y - height / 2, 0);
this.test_rotation()
box(this.size);
pop();
}
test_Color() {
fill(this.shift1);
}
test_rotation() {
rotateX(frameCount / 60);
rotateY(frameCount / 60);
}
attraction(target) {
//all cubes supposed to attract towards the mouse when pressed
if (mouseIsPressed) {
let force = p5.Vector.sub(target.pos,this.pos);
let d = force.mag();
d = constrain(d, 1, 25);
var G = 50;
var strength = G / (d * d);
force.setMag(strength);
if (d < 20) {
force.mult(10);
}
this.vel.add(force);
}
}
}
不确定要进一步添加什么细节。不确定要进一步添加什么细节。不确定要进一步添加什么细节。不确定要进一步添加什么细节。不确定要进一步添加什么细节。不确定要进一步添加什么细节。不确定要进一步添加什么细节。
解决方案
- 您正在使用索引
a
作为参数,Cubes.attraction
该参数期望具有pos
矢量场的对象(多维数据集?) - 您正在尝试使用
this.x
/来定位您的多维数据集this.y
,而update
. 改用this.pos
向量 - 您可以通过仅检查一次鼠标按下来进行优化,然后才
attraction
以鼠标坐标作为矢量参数调用每个立方体 - 在物理学中,力驱动加速度,而不是速度。我改变了,但也许是你故意的。
- 您应该将您的班级名称更改为
Cube
而不是Cubes
let cubes = [];
function setup() {
/* max(...) here is just for rendering with minimum size in the snippet */
createCanvas(max(windowWidth, 800), max(windowHeight, 600), WEBGL);
backCol = color(243, 243, 243);
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 cube of cubes) {
cube.update();
}
attracting();
}
function attracting() {
/* changed to check for mouse pressed once for all cubes */
if (mouseIsPressed) {
/* generating mouse position vector once for all cubes */
const mousePosVect = new p5.Vector(mouseX, mouseY);
for (let a = 0; a < cubes.length; a++) {
cubes[a].attraction(mousePosVect);
}
}
}
class Cubes {
constructor(x, y) {
/* Removed useless and confusing this.x, this.y */
this.size = 30;
this.stroke = 70;
this.gap = 150;
this.shift1 = color(96);
this.shift2 = color(244);
//vector variables
this.pos = createVector(x, y);
this.vel = createVector();
this.acc = createVector();
}
update() {
this.test_Color();
//attraction values
this.vel.add(this.acc);
this.vel.limit(5);
this.pos.add(this.vel);
this.acc.mult(0);
this.shape();
}
shape() {
push();
stroke(this.stroke);
this.test_Color();
/* Used this.pos instead of this.x, this.y for positioning */
translate(this.pos.x - width / 2, this.pos.y - height / 2, 0);
this.test_rotation();
box(this.size);
pop();
}
test_Color() {
fill(this.shift1);
}
test_rotation() {
rotateX(frameCount / 60);
rotateY(frameCount / 60);
}
attraction(targetVector) {
//all cubes supposed to attract towards the mouse when pressed
/* Set target argument to vector,
* moved the `if (mouseIsPressed)` condition outside */
let force = p5.Vector.sub(targetVector,this.pos);
let d = force.mag();
d = constrain(d, 1, 25);
var G = 50;
var strength = G / (d * d);
force.setMag(strength);
if (d < 20) {
force.mult(10);
}
/* changed to add force to acceleration
* instead of velocity (physically accurate) */
this.acc.add(force);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>P5 cube attractor</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js" integrity="sha512-gQVBYBvfC+uyor5Teonjr9nmY1bN+DlOCezkhzg4ShpC5q81ogvFsr5IV4xXAj6HEtG7M1Pb2JCha97tVFItYQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<!--h1>P5 test</h1-->
</body>
</html>
推荐阅读
- uima - NLP 管道、DKPro、Ruta - 缺少描述符错误
- android - 聆听多个意图
- c# - 从内部连接返回数据而不创建新对象
- textures - 我的世界是如何做到的,只有纹理上的某些像素会受到生物群系混合的影响?
- nebular - 如何为最近的搜索和自动完成自定义 nebular nb-search?
- r - Rcpp如何在每个单元格中给出给定长度的向量相同的值
- java - 比较方法在某些 Android 设备上违反了其一般合同
- shell - 如何参数化 sh 和 sed 中的变量
- go - Go 如何编写代码并执行系统命令以启动新终端?
- node.js - 使用 Heroku 和 GitHub 部署 Node.js 应用程序