In this project, I have used the text to point function to create vehicles which exhibit the seek, arrive and flee behaviours. Currently, the vehicles form the word ‘SWIMMY’ which is the start and target position. On clicking, I want the vehicles to form another word, say, fish. How can I change the target position of the vehicles on clicking the mouse or a button? I tried using a mouse clicked function in the sketch file but it did not work.
I have been struggling with figuring this out, so it would mean a lot if you could help me.
The sketch file:
var font;
var vehicles= [];
let water;
let img;
function preload(){
font = loadFont ('AvenirNextLTPro-Demi.otf');
//img = loadImage ('swimmy fish-1.png'); //this was perhaps to use the image of swimmy instead of the elipses
}
function setup(){
noCursor();
createCanvas(1200, 500);
water = createVideo('Water.mp4');
//links the term 'water' to the video
water.hide(); //hides the extrarandom video plaing at the bottom
water.autoplay(); //autoplays the video on loading of sketch
water.loop();
textFont(font); //all settings to make text appear
// textSize(192);
// fill(255);
// noStroke();
//text('SWIMMY',100,0); //all this text was to make the text on which the points could be made but now that we have points, we dont need them
var points = font.textToPoints('S w i m m y',100,300,192);
//this creates a variable that is the points converted from text. 100 and 300 are the positions on x ad y and 192 is the size of the font
for (var i = 0; i<points.length;i++){
var pt = points[i];
// stroke(255);
// strokeWeight(10);
// point(pt.x,pt.y); //all these three contol the way the points will look but I have changed those to the elipses so i dont need these
var vehicle = new Vehicle(pt.x , pt.y);
//now that there is an intro of a new variable vehicle, instead of drawing points in set up, they can be represented here
vehicles.push(vehicle);
//so now there is a new vehicle for every point isolated in the console
//** everytime a new vehicle is introduced, it must be added in the index.html section
}
}
function fish(x,y){
fill(random(192,192,192),random(255,129,129));
ellipse(x+14,y,10,12);
fill(random(192,192,192),random(255,129,129));
ellipse(x,y,25,15);
}
function mouseClicked() {
var points = font.textToPoints('The Fish',100,300,180);
}
//water.loop(); // set the video to loop and start playing
//}
//the above function only makes sense if i want to control when i want the video to start playing
function draw(){
background(0,119,190);
image(water, 0, 0); // draw the video frame to canvas
//filter(GRAY);
//image(water, 150, 150);
//water.loop();
noStroke();
fill(random(0,0,0), random(105,105,105));
ellipse(mouseX+14,mouseY,10,12);
fill(random(0,0,0),random(105,105,105));
ellipse(mouseX,mouseY,25,15)
for (var i = 0; i< vehicles.length; i++){ //noprotect
var v = vehicles[i];
v.behaviours(); //this would make use of the behaviours we have put in the vehicles.js
v.update();
v.show();
}
}
The vehicle.js file:
function Vehicle(x,y){ //constructor function to make vehicle ojects
//this.pos = createVector(x,y); //is this is on, the points srat possition will be on swimmy itself
this.pos = createVector(random(width),random(height)); //the vehicles need a starting position which will be a vector
//this.vel = createVector();
this.vel = p5.Vector.random2D(); //giving each a random veocity
this.acc = createVector();
this.target = createVector(x,y); //this is the objects target position
//each vehicles obj needs a position, a target position, a velocity and an acceleration
this.r=8
this.maxspeed = 10;
this.maxforce = 1;
}
//below the vehichle prototype is a better and more efficient way of attaching functions to objects
Vehicle.prototype.behaviours = function(){
var arrive = this.arrive(this.target);
var mouse = createVector(mouseX,mouseY);
var flee = this.flee(mouse); //to make vehicles afraid of the mouse
arrive.mult(1);
flee.mult(5);
//here we differentiate the different forces, so the flee force is much more forcefull than the arrive force
this.applyForce(flee);
this.applyForce(arrive);
//applyForce function doesnt actually exist so it has to be written below
//**if we needed only one behaviour, for example the seek function then that would be it. but here were assuming that there will be more than one behaviour which is why we have the prototype behaviours
}
Vehicle.prototype.applyForce = function(f){
this.acc.add(f); //so if multiple forces are at play, we could add all of them in the acceleration and hence all the animations must start by 0
}
Vehicle.prototype.update = function(){ //way of attaching functions to objects
this.pos.add(this.vel);
this.vel.add(this.acc);
//basic physics idea of acc changing velocity and velocity changing acceleration
this.acc.mult(0); //this multiplies everything by 0 so that everything starts from 0 for the applyForce function to work
}
//below funtion of show to display or render the stuff we have said so far
Vehicle.prototype.show = function() {
stroke(random(192,192,192),random(255,129,129));
strokeWeight(1);
// point(this.pos.x,this.pos.y);//linking the vehicle to particular points and their characteristics. the this.pos. is beign brought in from the for loop in sketch.js where it is pt.x and pt.y
// triangle(this.pos.x-5, this.pos.y+5, this.pos.x+5, this.pos.y+5, this.pos.x, this.pos.y-5); //this has made all the points into triangles. if i only say /points' the function will always create a circle.
//image(img, this.pos.x, this.pos.y);
fish(this.pos.x,this.pos.y); //the fish is the point
//translate(this.pos.x, this.pos.y);
//rotate(PI / 2.0);
}
Vehicle.prototype.arrive = function(target){
var desired = p5.Vector.sub (target, this.pos);
var d = desired.mag();
var speed = this.maxspeed;
if (d<100){
speed = map(d, 0, 100, 0, this.maxspeed);
}
desired.setMag(speed);
var steer = p5.Vector.sub(desired, this.vel);
steer.limit(this.maxforce);
return steer;
}
Vehicle.prototype.seek = function(target){
var desired = p5.Vector.sub (target, this.pos); //this line is subtracting the vector points from position to target, you subtract the two vectors
//desired vel is always its aximum speed
desired.setMag(this.maxspeed);
var steer = p5.Vector.sub(desired, this.vel);
//since steering= desired vel- current vel
steer.limit(this.maxforce);// so the steering isnt that powerful
return steer; //the idea is to calculate that force and return it to be applied in seek
}
Vehicle.prototype.flee = function(target){
var desired = p5.Vector.sub (target, this.pos);
var d = desired.mag();
if (d<50){
desired.setMag(this.maxspeed);
desired.mult(-1); //,aking the vehicle move in the away direction
var steer = p5.Vector.sub(desired, this.vel);
steer.limit(this.maxforce);
return steer; //the idea is to calculate that force and return it to be applied in seek
}else{
return createVector(0,0);
}
//the point of adding the if and else is to control when and how much the vehicles are afraid of the mosue
}