update
This commit is contained in:
parent
60360e70b5
commit
c9bbf29b9d
@ -1,256 +0,0 @@
|
|||||||
const canvasWidth = 800;
|
|
||||||
const canvasHeight = 800;
|
|
||||||
const backgroundColor = "#333333";
|
|
||||||
let vehicle;
|
|
||||||
let target;
|
|
||||||
let demo = "wander";
|
|
||||||
|
|
||||||
function setup() {
|
|
||||||
createCanvas(canvasWidth, canvasHeight);
|
|
||||||
cursor(CROSS);
|
|
||||||
vehicle = new Vehicle(0, 0);
|
|
||||||
target = new Target(canvasWidth / 2, canvasHeight / 2);
|
|
||||||
if (demo == "wander") {
|
|
||||||
vehicle.maxVelocity = 5;
|
|
||||||
vehicle.maxSteering = 3;
|
|
||||||
vehicle.velocity = createVector(1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function draw() {
|
|
||||||
background(backgroundColor);
|
|
||||||
switch (demo) {
|
|
||||||
case "seek2":
|
|
||||||
demoSeek2();
|
|
||||||
break;
|
|
||||||
case "arrive":
|
|
||||||
demoSeek(true);
|
|
||||||
break;
|
|
||||||
case "wander":
|
|
||||||
demoWander();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
demoSeek();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Vehicle {
|
|
||||||
constructor(x, y) {
|
|
||||||
this.position = createVector(x, y);
|
|
||||||
this.velocity = createVector(0, 0);
|
|
||||||
this.acceleration = createVector(0, 0);
|
|
||||||
this.color = "#FFFFFF";
|
|
||||||
this.size = 32;
|
|
||||||
this.maxVelocity = 6;
|
|
||||||
this.maxSteering = 0.25;
|
|
||||||
this.path = [];
|
|
||||||
this.drawPath = true;
|
|
||||||
this.pathes = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
seek(target, arrive = false) {
|
|
||||||
let steering = p5.Vector.sub(target.position, this.position);
|
|
||||||
|
|
||||||
let desiredVelocity = this.maxVelocity;
|
|
||||||
if (arrive) {
|
|
||||||
let slowdownDistance = this.size * 3;
|
|
||||||
let distance = steering.mag();
|
|
||||||
if (distance < slowdownDistance) {
|
|
||||||
desiredVelocity = map(distance, 0, 100, 0, this.maxVelocity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
steering.setMag(desiredVelocity);
|
|
||||||
steering.sub(this.velocity);
|
|
||||||
return steering;
|
|
||||||
}
|
|
||||||
|
|
||||||
flee(target) {
|
|
||||||
let steering = this.seek(target).mult(-1);
|
|
||||||
return steering;
|
|
||||||
}
|
|
||||||
|
|
||||||
wander() {
|
|
||||||
let wanderPoint = this.velocity.copy();
|
|
||||||
wanderPoint.setMag(100);
|
|
||||||
wanderPoint.add(this.position);
|
|
||||||
|
|
||||||
// stroke(255);
|
|
||||||
// let x1 = wanderPoint.x + -25 * cos(PI / 2 + this.velocity.heading());
|
|
||||||
// let y1 = wanderPoint.y + -25 * sin(PI / 2 + this.velocity.heading());
|
|
||||||
// let x2 = wanderPoint.x + 25 * cos(PI / 2 + this.velocity.heading());
|
|
||||||
// let y2 = wanderPoint.y + 25 * sin(PI / 2 + this.velocity.heading());
|
|
||||||
// line(x1, y1, x2, y2);
|
|
||||||
|
|
||||||
noStroke();
|
|
||||||
fill("#F063A4");
|
|
||||||
let offset = map(noise(Date.now() / 1000), 0, 1, -50, 50);
|
|
||||||
let x = offset * cos(PI / 2 + this.velocity.heading());
|
|
||||||
let y = offset * sin(PI / 2 + this.velocity.heading());
|
|
||||||
wanderPoint.add(x, y);
|
|
||||||
circle(wanderPoint.x, wanderPoint.y, 8);
|
|
||||||
let steering = wanderPoint.sub(this.position);
|
|
||||||
return steering;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(steering) {
|
|
||||||
if (steering) {
|
|
||||||
steering.limit(this.maxSteering);
|
|
||||||
this.acceleration.add(steering);
|
|
||||||
}
|
|
||||||
this.velocity.add(this.acceleration);
|
|
||||||
this.velocity.limit(this.maxVelocity);
|
|
||||||
this.position.add(this.velocity);
|
|
||||||
this.acceleration.set(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
noFill();
|
|
||||||
if (this.pathes.length >= 10) this.pathes.shift();
|
|
||||||
stroke(255);
|
|
||||||
strokeWeight(2);
|
|
||||||
[...this.pathes, this.path].forEach((path, i) => {
|
|
||||||
let c = map(i, 0, this.pathes.length, 127, 255);
|
|
||||||
let w = map(i, 0, this.pathes.length, 1, 5);
|
|
||||||
stroke(c);
|
|
||||||
strokeWeight(w);
|
|
||||||
beginShape();
|
|
||||||
path.forEach((v) => vertex(v.x, v.y));
|
|
||||||
endShape();
|
|
||||||
});
|
|
||||||
|
|
||||||
// stroke(255);
|
|
||||||
// strokeWeight(4);
|
|
||||||
// beginShape();
|
|
||||||
// this.path.forEach((v) => {
|
|
||||||
// vertex(v.x, v.y);
|
|
||||||
// });
|
|
||||||
// endShape();
|
|
||||||
|
|
||||||
push();
|
|
||||||
noStroke();
|
|
||||||
fill(this.color);
|
|
||||||
translate(this.position.x, this.position.y);
|
|
||||||
rotate(this.velocity.heading());
|
|
||||||
triangle(
|
|
||||||
this.size / 2,
|
|
||||||
0,
|
|
||||||
-this.size / 2,
|
|
||||||
-this.size / 4,
|
|
||||||
-this.size / 2,
|
|
||||||
this.size / 4
|
|
||||||
);
|
|
||||||
pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
edges() {
|
|
||||||
if (this.position.x < 0) {
|
|
||||||
this.position.x = canvasWidth;
|
|
||||||
return true;
|
|
||||||
} else if (this.position.x >= canvasWidth) {
|
|
||||||
this.position.x = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (this.position.y < 0) {
|
|
||||||
this.position.y = canvasHeight;
|
|
||||||
return true;
|
|
||||||
} else if (this.position.y >= canvasHeight) {
|
|
||||||
this.position.y = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bounce() {
|
|
||||||
if (this.position.x <= this.size / 2) {
|
|
||||||
this.position.x = this.size / 2;
|
|
||||||
this.velocity.x *= -1;
|
|
||||||
return true;
|
|
||||||
} else if (this.position.x > canvasWidth - this.size / 2) {
|
|
||||||
this.position.x = canvasWidth - this.size / 2;
|
|
||||||
this.velocity.x *= -1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (this.position.y <= this.size / 2) {
|
|
||||||
this.position.y = this.size / 2;
|
|
||||||
this.velocity.y *= -1;
|
|
||||||
return true;
|
|
||||||
} else if (this.position.y >= canvasHeight - this.size / 2) {
|
|
||||||
this.position.y = canvasHeight - this.size / 2;
|
|
||||||
this.velocity.y *= -1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Target extends Vehicle {
|
|
||||||
constructor(x, y) {
|
|
||||||
super(x, y);
|
|
||||||
this.position = createVector(random(canvasWidth), random(canvasHeight));
|
|
||||||
this.color = "#F063A4";
|
|
||||||
this.size = 32;
|
|
||||||
this.maxVelocity = 6;
|
|
||||||
this.maxSteering = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
push();
|
|
||||||
stroke(255);
|
|
||||||
strokeWeight(1);
|
|
||||||
fill(this.color);
|
|
||||||
circle(this.position.x, this.position.y, this.size);
|
|
||||||
pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function demoSeek(arrive) {
|
|
||||||
target.position.x = mouseX;
|
|
||||||
target.position.y = mouseY;
|
|
||||||
let steering = vehicle.seek(target, arrive);
|
|
||||||
vehicle.update(steering);
|
|
||||||
target.show();
|
|
||||||
vehicle.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function demoWander() {
|
|
||||||
let steering = vehicle.wander();
|
|
||||||
vehicle.update(steering);
|
|
||||||
if (vehicle.edges()) {
|
|
||||||
vehicle.pathes.push(vehicle.path);
|
|
||||||
vehicle.path = [];
|
|
||||||
}
|
|
||||||
if (frameCount % 1 == 0) vehicle.path.push(vehicle.position.copy());
|
|
||||||
vehicle.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function demoSeek2() {
|
|
||||||
let distance = p5.Vector.dist(vehicle.position, target.position);
|
|
||||||
if (distance < target.size / 2) {
|
|
||||||
target.position = createVector(
|
|
||||||
random(canvasWidth),
|
|
||||||
random(canvasHeight)
|
|
||||||
);
|
|
||||||
target.acceleration = createVector(0, 0);
|
|
||||||
target.velocity = createVector(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
let seekSteering = vehicle.seek(target);
|
|
||||||
let fleeSteering = target.flee(vehicle);
|
|
||||||
vehicle.update(seekSteering);
|
|
||||||
target.update(fleeSteering);
|
|
||||||
target.bounce();
|
|
||||||
target.show();
|
|
||||||
vehicle.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取随机向量,可指定大小
|
|
||||||
* @param {number} magnitude 向量大小
|
|
||||||
* @return {p5.Vector} vector 随机向量
|
|
||||||
*/
|
|
||||||
function randomVector(magnitude) {
|
|
||||||
let vector = p5.Vector.random2D();
|
|
||||||
if (magnitude) vector.mult(magnitude);
|
|
||||||
return vector;
|
|
||||||
}
|
|
39
1003.矢量的投影.js
Normal file
39
1003.矢量的投影.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
let v0, v1, v2, v3;
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
createCanvas(600, 400);
|
||||||
|
cursor(CROSS);
|
||||||
|
v0 = createVector(200, 200);
|
||||||
|
v1 = createVector(300, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
v2 = createVector(mouseX, mouseY).sub(v0).div(2);
|
||||||
|
v3 = vectorProjection(v2, v1);
|
||||||
|
|
||||||
|
background(0);
|
||||||
|
stroke("#777777");
|
||||||
|
translate(v0.x, v0.y);
|
||||||
|
line(v2.x, v2.y, v3.x, v3.y);
|
||||||
|
drawVector(v1, "#FF0000");
|
||||||
|
drawVector(v2, "#00FF00");
|
||||||
|
drawVector(v3, "#FFFF00");
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawVector(vector, color = "#FFFFFF") {
|
||||||
|
push();
|
||||||
|
fill(color);
|
||||||
|
stroke(color);
|
||||||
|
line(0, 0, vector.x, vector.y);
|
||||||
|
circle(0, 0, 4);
|
||||||
|
translate(vector.x, vector.y);
|
||||||
|
rotate(vector.heading());
|
||||||
|
triangle(0, 0, -4, -2, -4, +2);
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function vectorProjection(v1, v2) {
|
||||||
|
const v = v2.copy().normalize();
|
||||||
|
const sp = v1.dot(v);
|
||||||
|
return v.setMag(sp);
|
||||||
|
}
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
14
index.html
14
index.html
@ -3,8 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>p5.js example</title>
|
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
|
||||||
<link rel="shortcut icon" href="data:" type="image/x-icon" />
|
<title>p5.js</title>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -12,10 +12,16 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-color: gray;
|
background-color: gray;
|
||||||
}
|
}
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
height: 100vh;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="p5/p5.min.js"></script>
|
<script src="p5/p5.min.js"></script>
|
||||||
<!-- <script src="p5/addons/p5.sound.js"></script> -->
|
<script src="p5/addons/p5.sound.min.js"></script>
|
||||||
<script src="sketch.js"></script>
|
<script src="vehicle.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
143
sketch.js
143
sketch.js
@ -1,145 +1,8 @@
|
|||||||
function setup() {
|
function setup() {
|
||||||
createCanvas(400, 600);
|
cursor(CROSS);
|
||||||
// 画线
|
createCanvas(600, 600);
|
||||||
// stroke("#00FF00");
|
|
||||||
// line(50, 50, 150, 150);
|
|
||||||
|
|
||||||
// 画(椭)圆
|
|
||||||
// stroke("#FF0000");
|
|
||||||
// circle(300, 100, 100);
|
|
||||||
// ellipse(300, 100, 100, 100);
|
|
||||||
|
|
||||||
// 画矩形
|
|
||||||
// stroke("#FFFF00");
|
|
||||||
// square(75, 275, 50);
|
|
||||||
// rect(50, 250, 100, 100);
|
|
||||||
|
|
||||||
// 画三角形
|
|
||||||
// stroke("#0000FF");
|
|
||||||
// triangle(100, 250, 50, 350, 150, 350);
|
|
||||||
|
|
||||||
// 辅助线
|
|
||||||
// stroke("#DDDDFF");
|
|
||||||
// for (let x = 0; x < width; x += 25) {
|
|
||||||
// line(x, 0, x, height);
|
|
||||||
// }
|
|
||||||
// for (let y = 0; y < height; y += 25) {
|
|
||||||
// line(0, y, width, y);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
noStroke();
|
background(64);
|
||||||
stroke("#333333");
|
|
||||||
|
|
||||||
// 天空
|
|
||||||
background("lightblue");
|
|
||||||
|
|
||||||
// 地面
|
|
||||||
fill("lightgreen");
|
|
||||||
rect(0, 275, width, height);
|
|
||||||
|
|
||||||
// 太阳
|
|
||||||
fill("#FF0000");
|
|
||||||
circle(100, 100, 75);
|
|
||||||
|
|
||||||
// 光
|
|
||||||
let a = frameCount % 50;
|
|
||||||
for (let i = 0; i < 8; i++) {
|
|
||||||
push();
|
|
||||||
translate(100, 100);
|
|
||||||
rotate((i / 4) * PI);
|
|
||||||
triangle(-5, 50 + a, 5, 50 + a, 0, 65 + a);
|
|
||||||
pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 烟囱
|
|
||||||
fill("#7733CC");
|
|
||||||
rect(275, 125, 25, 100);
|
|
||||||
|
|
||||||
// 房顶
|
|
||||||
fill("#DD66FF");
|
|
||||||
triangle(250, 150, 150, 200, 350, 200);
|
|
||||||
|
|
||||||
// 墙
|
|
||||||
fill("#FFDDAA");
|
|
||||||
rect(175, 200, 150, 100);
|
|
||||||
|
|
||||||
// 窗户
|
|
||||||
fill("#FFFF66");
|
|
||||||
let b = map(a, 0, 50, -10, 10);
|
|
||||||
if (b > 0) {
|
|
||||||
ellipse(225, 225, 25 + b);
|
|
||||||
ellipse(275, 225, 25 - b);
|
|
||||||
} else {
|
|
||||||
ellipse(225, 225, 25 - b);
|
|
||||||
ellipse(275, 225, 25 + b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 门
|
|
||||||
fill("#DD33CC");
|
|
||||||
rect(235, 250, 30, 50);
|
|
||||||
|
|
||||||
bird(200, 75);
|
|
||||||
bird(300, 50);
|
|
||||||
|
|
||||||
// 树叶
|
|
||||||
fill("#66AA00");
|
|
||||||
triangle(100, 340, 40, 400, 160, 400);
|
|
||||||
fill("#AAFF00");
|
|
||||||
triangle(100, 325, 50, 375, 150, 375);
|
|
||||||
fill("#66AA00");
|
|
||||||
triangle(100, 305, 60, 350, 140, 350);
|
|
||||||
|
|
||||||
// 树干
|
|
||||||
fill("#FFDDAA");
|
|
||||||
rect(85, 400, 30, 50);
|
|
||||||
|
|
||||||
// 小路
|
|
||||||
fill("#DD66FF");
|
|
||||||
ellipse(275, 350, 50, 25);
|
|
||||||
fill("#7733CC");
|
|
||||||
ellipse(288, 400, 75, 35);
|
|
||||||
fill("#66AA00");
|
|
||||||
ellipse(300, 460, 100, 50);
|
|
||||||
fill("#FF9933");
|
|
||||||
ellipse(325, 550, 125, 70);
|
|
||||||
|
|
||||||
// 蘑菇
|
|
||||||
fill("#FF0000");
|
|
||||||
arc(175, 475, 50, 50, PI, 0, PIE);
|
|
||||||
fill("#FFDDAA");
|
|
||||||
circle(157, 470, 8);
|
|
||||||
circle(165, 462, 8);
|
|
||||||
circle(175, 457, 8);
|
|
||||||
circle(175, 470, 8);
|
|
||||||
circle(185, 462, 8);
|
|
||||||
circle(193, 470, 8);
|
|
||||||
fill("#FF9933");
|
|
||||||
rect(165, 475, 20, 20);
|
|
||||||
|
|
||||||
noStroke();
|
|
||||||
fill(0);
|
|
||||||
text("作品:基础图形绘画练习一", 50, 550);
|
|
||||||
text("作者:赵海洋爸爸 三(8)班", 50, 570);
|
|
||||||
}
|
|
||||||
|
|
||||||
function bird(x, y) {
|
|
||||||
push();
|
|
||||||
let a = frameCount % 10;
|
|
||||||
noFill();
|
|
||||||
stroke(0);
|
|
||||||
translate(x, y);
|
|
||||||
fill("#FFDDAA");
|
|
||||||
arc(0, 0, 50, 50, 0, PI, PIE);
|
|
||||||
ellipse(30, -10, 30);
|
|
||||||
fill("#FFFFFF");
|
|
||||||
ellipse(28, -10, 10);
|
|
||||||
fill("#333333");
|
|
||||||
ellipse(28, -10, 5);
|
|
||||||
fill("#FF3333");
|
|
||||||
triangle(40, -15, 40, -5, 60, -10);
|
|
||||||
fill("#FFFF66");
|
|
||||||
triangle(-20, -20 + a * 2, -10, 5, 10, -5);
|
|
||||||
pop();
|
|
||||||
}
|
}
|
||||||
|
200
vehicle.js
Normal file
200
vehicle.js
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
let vehicle1;
|
||||||
|
let vehicle2;
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
cursor(CROSS);
|
||||||
|
createCanvas(600, 600);
|
||||||
|
vehicle1 = new Vehicle(300, 300, "#CCCCCC");
|
||||||
|
vehicle2 = new Vehicle(300, 300, "#CC3333");
|
||||||
|
vehicle2.velocity = randomVector(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
巡游小车();
|
||||||
|
// 追逐鼠标();
|
||||||
|
// 逃避鼠标();
|
||||||
|
// 小车追逐();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 巡游小车() {
|
||||||
|
background(64);
|
||||||
|
vehicle1.wander();
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle1.turn();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 追逐鼠标() {
|
||||||
|
background(64);
|
||||||
|
vehicle1.seek({ position: createVector(mouseX, mouseY) });
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle1.turn();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 逃避鼠标() {
|
||||||
|
background(64);
|
||||||
|
vehicle1.flee({ position: createVector(mouseX, mouseY) });
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle1.turn();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 小车追逐() {
|
||||||
|
background(64);
|
||||||
|
vehicle1.seek(vehicle2);
|
||||||
|
vehicle2.move();
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle2.turn();
|
||||||
|
vehicle1.turn();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle2.show();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回可指定大小的随机二维向量
|
||||||
|
* @param {number} magnitude 向量大小
|
||||||
|
* @return {p5.Vector} vector 随机二维向量
|
||||||
|
*/
|
||||||
|
function randomVector(magnitude) {
|
||||||
|
let vector = p5.Vector.random2D();
|
||||||
|
return magnitude ? vector.mult(magnitude) : vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Vehicle {
|
||||||
|
constructor(x, y, color) {
|
||||||
|
this.color = color;
|
||||||
|
this.position = createVector(x, y);
|
||||||
|
this.path = [];
|
||||||
|
this.pathes = [];
|
||||||
|
this.velocity = createVector(0, 0);
|
||||||
|
this.heading = this.velocity.heading();
|
||||||
|
this.acceleration = createVector(0, 0);
|
||||||
|
this.maxVelocity = 5;
|
||||||
|
this.maxAcceleration = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
seek(target, slowdownDistance = 100) {
|
||||||
|
const desired = p5.Vector.sub(target.position, this.position);
|
||||||
|
const distance = desired.mag();
|
||||||
|
const magnitude =
|
||||||
|
slowdownDistance > 0 && distance <= slowdownDistance
|
||||||
|
? map(distance, 0, slowdownDistance, 0, this.maxVelocity)
|
||||||
|
: this.maxVelocity;
|
||||||
|
desired.setMag(magnitude);
|
||||||
|
const steering = p5.Vector.sub(desired, this.velocity);
|
||||||
|
this.acceleration.add(steering);
|
||||||
|
}
|
||||||
|
|
||||||
|
flee(target, fleeDistance = 100) {
|
||||||
|
const desired = p5.Vector.sub(this.position, target.position);
|
||||||
|
const distance = desired.mag();
|
||||||
|
const magnitude =
|
||||||
|
!fleeDistance || fleeDistance <= 0
|
||||||
|
? this.maxVelocity
|
||||||
|
: distance <= fleeDistance
|
||||||
|
? map(distance, 0, fleeDistance, this.maxVelocity, 0)
|
||||||
|
: 0;
|
||||||
|
desired.setMag(magnitude);
|
||||||
|
const steering = p5.Vector.sub(desired, this.velocity);
|
||||||
|
this.acceleration.add(steering);
|
||||||
|
}
|
||||||
|
|
||||||
|
wander() {
|
||||||
|
const target = this.velocity.copy();
|
||||||
|
target.setMag(50).add(this.position);
|
||||||
|
|
||||||
|
// stroke(128);
|
||||||
|
// const x1 = target.x + -25 * cos(PI / 2 + this.heading);
|
||||||
|
// const y1 = target.y + -25 * sin(PI / 2 + this.heading);
|
||||||
|
// const x2 = target.x + 25 * cos(PI / 2 + this.heading);
|
||||||
|
// const y2 = target.y + 25 * sin(PI / 2 + this.heading);
|
||||||
|
// line(x1, y1, x2, y2);
|
||||||
|
|
||||||
|
const offset = map(noise(Date.now() / 1000), 0, 1, -50, 50);
|
||||||
|
const x = offset * cos(PI / 2 + this.heading);
|
||||||
|
const y = offset * sin(PI / 2 + this.heading);
|
||||||
|
target.add(x, y);
|
||||||
|
|
||||||
|
// noStroke();
|
||||||
|
// fill("#F063A4");
|
||||||
|
// circle(target.x, target.y, 5);
|
||||||
|
|
||||||
|
const steering = target.sub(this.position);
|
||||||
|
this.acceleration.add(steering);
|
||||||
|
}
|
||||||
|
|
||||||
|
move() {
|
||||||
|
this.acceleration.limit(this.maxAcceleration);
|
||||||
|
this.velocity.add(this.acceleration);
|
||||||
|
if (this.velocity.mag() > 0) this.heading = this.velocity.heading();
|
||||||
|
this.velocity.limit(this.maxVelocity);
|
||||||
|
this.position.add(this.velocity);
|
||||||
|
this.acceleration.set(0, 0);
|
||||||
|
this.path.push(this.position.copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
turn() {
|
||||||
|
let x = this.position.x;
|
||||||
|
let y = this.position.y;
|
||||||
|
while (x < 0 || x >= width) x = (x + width) % width;
|
||||||
|
while (y < 0 || y >= height) y = (y + height) % height;
|
||||||
|
const edgeCrossed = x != this.position.x || y != this.position.y;
|
||||||
|
if (edgeCrossed) {
|
||||||
|
this.pathes.push(this.path);
|
||||||
|
this.path = [];
|
||||||
|
}
|
||||||
|
this.position.x = x;
|
||||||
|
this.position.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bounce() {
|
||||||
|
// if (this.position.x <= this.size / 2) {
|
||||||
|
// this.position.x = this.size / 2;
|
||||||
|
// this.velocity.x *= -1;
|
||||||
|
// return true;
|
||||||
|
// } else if (this.position.x > canvasWidth - this.size / 2) {
|
||||||
|
// this.position.x = canvasWidth - this.size / 2;
|
||||||
|
// this.velocity.x *= -1;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// if (this.position.y <= this.size / 2) {
|
||||||
|
// this.position.y = this.size / 2;
|
||||||
|
// this.velocity.y *= -1;
|
||||||
|
// return true;
|
||||||
|
// } else if (this.position.y >= canvasHeight - this.size / 2) {
|
||||||
|
// this.position.y = canvasHeight - this.size / 2;
|
||||||
|
// this.velocity.y *= -1;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
drawPath() {
|
||||||
|
push();
|
||||||
|
noFill();
|
||||||
|
stroke(50);
|
||||||
|
strokeWeight(1);
|
||||||
|
// if (this.pathes.length >= 10) this.pathes.shift();
|
||||||
|
[...this.pathes, this.path].forEach((path) => {
|
||||||
|
beginShape();
|
||||||
|
path.forEach((v) => vertex(v.x, v.y));
|
||||||
|
endShape();
|
||||||
|
});
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
push();
|
||||||
|
translate(this.position.x, this.position.y);
|
||||||
|
rotate(this.heading);
|
||||||
|
stroke(this.color);
|
||||||
|
fill(this.color);
|
||||||
|
triangle(0, 0, -10, 2.5, -10, -2.5);
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user