Error while using class in prototype of function - p5.js

I'm working on a p5 project and I have an issue. When I'm trying to use my class name in my prototype I've an error ',' expected but I don't have any place where I can place one.
Here are the files.
-----FIRST FILE-----
class Pipe {
constructor() {
this.width = 50;
this.height = floor(random(canvas.height - 100));
this.x = canvas.width + this.width;
this.topY = canvas.height - this.height;
}
show() {
fill(0, 204, 0);
rect(this.x, canvas.height - this.height, this.x + width, canvas.height);
}
update() {
this.x -= panSpeed;
}
### IT'S THIS "p" which causing the problem ###
colided(Player p) {
if (p.x + p.size > this.x && p.x - p.size < this.x + this.width) {
if (p.y + p.size > this.topY) {
return true;
}
}
return false;
}
}
-----SECOND FILE-----
class Player {
constructor(x, y) {
this.x = x;
this.y = y;
this.velY = 0;
this.velX = panSpeed;
this.size = 20;
}
show() {
noStroke();
fill(255, 255, 0);
ellipse(this.x, this.y, this.size);
}
update() {
this.velY += gravity;
this.velY = constrain(this.velY, -1000, 25);
this.y += this.velY;
if (pipe.colided(this)) {
this.y = 0;
}
}
flap() {
this.velY -= 50;
}
}
-----THIRD FILE-----
var panSpeed = 5;
var gravity = 3;
var player;
var pipe;
function setup() {
window.canvas = createCanvas(800, 800);
player = new Player(100, canvas.height / 2);
pipe = new Pipe();
}
function draw() {
background(135, 206, 250);
pipe.update();
pipe.show();
player.update();
player.show();
}
function keyPressed() {
switch (key) {
case ' ':
player.flap();
break;
}
}
-----THE HTML-----
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>p5.js example</title>
<style> body {padding: 0; margin: 0;} </style>
<script src="lib/p5.js"></script>
<script src="lib/p5.sound.js"></script>
<script src="js/sketch.js"></script>
<script src="js/toto.js"></script>
<script src="js/pipe.js"></script>
</head>
<body>
</body>
</html>

First off, remove ### IT'S THIS "p" which causing the problem ###
Second off your issue is
colided(Player p) {
...
}
You're trying to give it a type of Player, which is not valid JavaScript. If you remove player and just have
colided(p) {
...
}
That'll sort your issue. FYI if you were to use Typescript as an example for optional static typing, the syntax would be colided(p : Player)
class Pipe {
constructor() {
this.width = 50;
this.height = floor(random(canvas.height - 100));
this.x = canvas.width + this.width;
this.topY = canvas.height - this.height;
}
show() {
fill(0, 204, 0);
rect(this.x, canvas.height - this.height, this.x + width, canvas.height);
}
update() {
this.x -= panSpeed;
}
colided(p) {
if (p.x + p.size > this.x && p.x - p.size < this.x + this.width) {
if (p.y + p.size > this.topY) {
return true;
}
}
return false;
}
}
class Player {
constructor(x, y) {
this.x = x;
this.y = y;
this.velY = 0;
this.velX = panSpeed;
this.size = 20;
}
show() {
noStroke();
fill(255, 255, 0);
ellipse(this.x, this.y, this.size);
}
update() {
this.velY += gravity;
this.velY = constrain(this.velY, -1000, 25);
this.y += this.velY;
if (pipe.colided(this)) {
this.y = 0;
}
}
flap() {
this.velY -= 50;
}
}
var panSpeed = 5;
var gravity = 3;
var player;
var pipe;
function setup() {
window.canvas = createCanvas(800, 800);
player = new Player(100, canvas.height / 2);
pipe = new Pipe();
}
function draw() {
background(135, 206, 250);
pipe.update();
pipe.show();
player.update();
player.show();
}
function keyPressed() {
switch (key) {
case ' ':
player.flap();
break;
}
}
<script src="https://cdn.jsdelivr.net/npm/p5#0.10.2/lib/p5.js"></script>

Related

p5.js: Random movement of drawing tool

I coded this drawing tool:
var a = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
background(0, 0, 255);
}
function draw() {
fill(0, 255, 255, random(255));
translate(mouseX, mouseY);
rotate(a);
textSize(120);
textAlign(CENTER, CENTER);
text('*', 0, 0);
rotate(a);
a = a + 0.08;
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.4.1/lib/p5.js"></script>
Now I would like to have a movement, without doing it with the cursor. I have thought about something like this:
var a;
function centerCanvas() {
var x = (windowWidth - width) / 2;
var y = (windowHeight - height) / 2;
a.position(x, y);
}
function setup() {
a = createCanvas(windowHeight, windowHeight);
centerCanvas();
}
function draw() {
fill(0, 255, 255, random(255));
var x =
windowHeight / 2 +
sin(frameCount * 0.01) * cos(frameCount * 0.04) * windowHeight / 3;
var y =
windowHeight / 2 +
cos(frameCount * 0.01) * sin(frameCount * 0.04) * windowHeight / 3;
rotate(a);
textSize(120);
textAlign(CENTER, CENTER);
text('*', 0, 0);
rotate(a);
a = a + 0.08;
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.4.1/lib/p5.js"></script>
Unfortunately, it doesn't work. It also would be cool if the movement would be random inside the canvas. Does anyone know how to do it?
This (almost) worked for me:
let wander;
function setup() {
createCanvas(windowWidth, windowHeight);
background(0, 0, 0);
wander = new Vehicle(0, 0);
}
function draw() {
wander.wander();
wander.update();
wander.edges();
wander.show();
}
class Vehicle {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = createVector(1, 0);
this.acc = createVector(0, 0);
this.maxSpeed = 4;
this.maxForce = 0.2;
this.r = 16;
this.wanderTheta = PI / 2;
this.xoff = 0;
}
wander() {
let angle = noise(this.xoff) * TWO_PI * 2;
let steer = p5.Vector.fromAngle(angle);
steer.setMag(this.maxForce);
this.applyForce(steer);
this.xoff += 0.01;
}
applyForce(force) {
this.acc.add(force);
}
update() {
this.vel.add(this.acc);
this.vel.limit(this.maxSpeed);
this.pos.add(this.vel);
this.acc.set(0, 0);
}
show() {
stroke(255);
strokeWeight(2);
fill(255);
push();
translate(this.pos.x, this.pos.y);
rotate(this.vel.heading());
textAlign(CENTER, CENTER);
textSize(120);
fill(0, 255, 255, random(255));
text("*", 0, 0);
pop();
}
edges() {
let hitEdge = false;
if (this.pos.x > width + this.r) {
this.pos.x = -this.r;
hitEdge = true;
} else if (this.pos.x < -this.r) {
this.pos.x = width + this.r;
hitEdge = true;
}
if (this.pos.y > height + this.r) {
this.pos.y = -this.r;
hitEdge = true;
} else if (this.pos.y < -this.r) {
this.pos.y = height + this.r;
hitEdge = true;
}
}
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.4.1/lib/p5.js"></script>
Using P5.js's noise function is a really accurate way to represent wandering. With a little tinkering you can get the effect you want.
EDIT
This is your (debugged) code:
let a;
let r;
function centerCanvas() {
var x = (windowWidth - width) / 2;
var y = (windowHeight - height) / 2;
a.position(x, y);
}
function setup() {
a = createCanvas(windowHeight, windowHeight);
centerCanvas();
}
function draw() {
fill(0, 255, 255, random(255));
const x = windowHeight / 2 +
sin(frameCount * 0.01) * cos(frameCount * 0.04) * windowHeight / 3;
const y = windowHeight / 2 +
cos(frameCount * 0.01) * sin(frameCount * 0.04) * windowHeight / 3;
translate(x, y);
rotate(a * 0.08);
textSize(50);
textAlign(CENTER, CENTER);
text('*', 0, 0);
a += 1;
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.4.1/lib/p5.js"></script>
How about this?
var a = 0;
var x = 0;
var y = 0;
var delta = 1;
function setup() {
createCanvas(windowWidth, windowHeight);
background(0, 0, 255);
}
function draw() {
fill(0, 255, 255, random(255));
x = x + 2 + Math.random();
y = y + 0.5 + Math.random();
x = x * delta;
y = y * delta;
if (x < 0) delta = -1;
translate((x) % windowWidth,(y) % windowHeight);
rotate(a);
textSize(120);
textAlign(CENTER, CENTER);
text('*', 0, 0);
rotate(a);
a = a + 0.08;
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.4.1/lib/p5.js"></script>

p5.js change object colour after X frames

I would like to change the fill colour of an object over time. Is there a way to change the fill colour of an object after X frames?
I am learning about constructors, and I am thinking that in the code's updateParticle function, after this.age counts to 'X', the fill colour of the ellipse could change.
'''
function Particle(x, y, xSpeed, ySpeed, size, colour) {
this.x = x;
this.y = y;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.size = size;
this.colour = colour;
this.age = 0;
this.drawParticle = function() {
fill(this.colour);
noStroke();
ellipse(this.x, this.y, this.size);
}
this.updateParticle = function() {
this.x += this.xSpeed;
this.y += this.ySpeed;
this.age++;
}
}
function Emitter(x, y, xSpeed, ySpeed, size, colour) {
this.x = x;
this.y = y;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.size = size;
this.colour = colour;
this.particles = [];
this.startParticles = [];
this.lifetime = 0;
this.addParticle = function() {
var p = new Particle(random(this.x - 10, this.x + 10),
random(this.y - 10, this.y + 10),
random(this.xSpeed - 0.4, this.xSpeed + 0.4),
random(this.ySpeed - 5, this.ySpeed - 1),
random(this.size - 4, this.size + 40),
this.colour);
return p;
}
this.startEmitter = function(startParticles, lifetime) {
this.startParticles = startParticles;
this.lifetime = lifetime;
for (var i = 0; i < startParticles; i++) {
this.particles.push(this.addParticle());
}
}
this.updateParticles = function() {
var deadParticles = 0
for (var i = this.particles.length - 1; i >= 0; i--) {
this.particles[i].drawParticle();
this.particles[i].updateParticle();
if (this.particles[i].age > random(0, this.lifetime)) {
this.particles.splice(i, 1);
deadParticles++;
}
}
if (deadParticles > 0) {
for (var i = 0; i < deadParticles; i++) {
this.particles.push(this.addParticle());
}
}
}
}
var emit;
function setup() {
createCanvas(800, 600);
emit = new Emitter(width / 2, height - 100, 0, -1, 10, color(200, 0, 200, 50));
emit.startEmitter(600, 4000);
}
function draw() {
background(200);
emit.updateParticles();
}
'''
Well you could just:
if(frameCount % 30 == 0){ // % 30 is the remainder of num / 30, so 4 % 3 = 1, since 3 / 3 = 0 And 4 / 3 = 3.33
fill("lime") // these are just preset colors in p5.js AND css lime == rgb(0,255,0)
} else {
fill('darkred')
}
or you could also do it with for example a switch statement: using background for no reason
switch(MY_frameCount){
case 1:
background('blue')
break
case 2:
background("darkgreen")
break
case 376:
background(crimson)
// break
}
MY_frameCount ++
or:
if(Math.random() < 0.1){
fill(Math.random() * 255, Math.random() * 255, Math.random() * 255)
} // this should on average fill with random color every 10 frames

Is it possible to change particle color?

is it possible to change the particle color to any color in mind?
Because i only get one color and i want to change it to make it more suitable for spring is there a way to configure the colors based on your taste following is my functions code:
function Particle() {
this.pos = createVector(random(width), random(height));
this.vel = createVector(0, 0);
this.acc = createVector(0, 0);
this.maxspeed = 4;
this.h = 100;
this.prevPos = this.pos.copy();
this.update = function() {
this.vel.add(this.acc);
this.vel.limit(this.maxspeed);
this.pos.add(this.vel);
this.acc.mult(0);
}
this.follow = function(vectors) {
var x = floor(this.pos.x / scl);
var y = floor(this.pos.y / scl);
var index = x + y * cols;
var force = vectors[index];
this.applyForce(force);
}
this.applyForce = function(force) {
this.acc.add(force);
}
this.show = function() {
strokeWeight(6);
stroke(255, this.h, 10);
this.h = this.h + 1;
if (this.h > 255) {
this.h = 100;
}
strokeWeight(8);
line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
this.updatePrev();
}
this.updatePrev = function() {
this.prevPos.x = this.pos.x;
this.prevPos.y = this.pos.y;
}
this.edges = function() {
if (this.pos.x > width) {
this.pos.x = 0;
this.updatePrev();
}
if (this.pos.x < 0) {
this.pos.x = width;
this.updatePrev();
}
if (this.pos.y > height) {
this.pos.y = 0;
this.updatePrev();
}
if (this.pos.y < 0) {
this.pos.y = height;
this.updatePrev();
}
}
}
The call to stroke(255, this.h, 10) in the show function is what is determining the color of the line drawn by the Particle class in this case. It looks like it is cycling from red to yellow. The stroke function is well documented. You can certainly use it to make the line drawn in this example any color you want. You can learn more about color in p5js on p5js.org.

In html canvas, how can I make "new component" an unicode font instead of image?

In the following code, I would like to use
function startGame() {
myGamePiece = new component(30, 30, "smiley.gif", 10, 120, "image");
myGameArea.start();
}
any unicode font, for example 🐇, so how do I attribute? "font" instead of "image" is not working. Any help or pointer would be appreciated.
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
}

Possibly miss using if else statements in p5.js animation

I'm trying to get a line to snake down a canvas. I'm using if else statements, currently the line travels left to right, then down then right to left. But here I get stuck, it should go down again and then left to right again. not sure if I should be using functions?
Here is the pen
function setup(){
createCanvas(600,800);
background(250,180,20)
}
function draw(){
var left = 600;
var right = 800;
var speed = 3
timeline.move()
}
var timeline = {
speed : 3,
x : 20,
y : 20,
move : function(){
fill(0);
ellipse(this.x,this.y,20,20)
if(this.x<width-20){
this.x = this.x + this.speed
}
else if(this.y > 0){
this.y = this.y + this.speed}
if(this.y > 100 || this.x < 20){
this.y = this.y - this.speed
this.speed= this.speed*-1
this.x = this.x + this.speed+1}
if(this.x < 20 && this.y > 200){
this.y = this.y + this.speed
}
}
}
Thanks in advance
I would try to use some kind of points or instructions instead of hardcoding the values. It would probably get much easier to build upon. You could also probably break down the movement part into more generic functions if you want.
Here is some modified code:
function setup(){
createCanvas(600,800);
background(250,180,20)
}
var points = [
{x: 500, y:20},
{x: 500, y:80},
{x: 20, y: 80},
{x: 500, y: 300}
]
var currentPointIndex =0;
function draw(){
var left = 600;
var right = 800;
var speed = 3
timeline.move()
}
var timeline = {
speed : 5,
x : 20,
y : 20,
move : function(){
fill(0);
ellipse(this.x,this.y,20,20)
var didMove = false;
var currentPoint = points[currentPointIndex];
if(this.x < currentPoint.x - this.speed){
this.x += this.speed;
didMove = true;
}
else if(this.x > currentPoint.x + this.speed){
this.x -= this.speed;
didMove = true;
}
if(this.y < currentPoint.y - this.speed){
this.y += this.speed;
didMove = true;
}
else if(this.y > currentPoint.y + this.speed){
this.y -= this.speed;
didMove = true;
}
if(!didMove && currentPointIndex < points.length){
currentPointIndex++;
}
}
}
It's quick and dirty, but shows the general idea. Hope it is helpful!

Resources