Problems with dist function in p5js - p5.js

I'm currently trying to make a basic platformer game, I'm trying to use a dist function to detect if the player is touching the ground or not. I need to just detect the Y coors of the ground and player. Any suggestions?
let x2,y2;
let x,y;
function setup() {
createCanvas(400, 400);
x=200;
y=200;
x2=200;
y2=200;
}
function draw() {
background(220);
ellipse(x,y,20,20)
rect(x2-300,y2+150,500,200);
if(dist(x,x2,y2,y)==140){
y=y+0;
}else{
y=y+5;
}
if(keyIsPressed&&keyCode === LEFT_ARROW){
x=x-2;
}
if(keyIsPressed&&keyCode === RIGHT_ARROW){
x=x+2;
}
}

You can use a more permissive threshold condition like a range instead of the distance being exactly 140 (e.g. >= 140).
Here's a version of your code with this minor tweak added:
let x2, y2;
let x, y;
function setup() {
createCanvas(400, 400);
x = 200;
y = 200;
x2 = 200;
y2 = 200;
}
function draw() {
background(220);
ellipse(x, y, 20, 20);
rect(x2 - 300, y2 + 150, 500, 200);
if (dist(x, x2, y2, y) >= 140) {
y = y + 0;
} else {
y = y + 5;
}
if (keyIsPressed && keyCode === LEFT_ARROW) {
x = x - 2;
}
if (keyIsPressed && keyCode === RIGHT_ARROW) {
x = x + 2;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
I do have a few more suggestions:
for an initial game prototype this ok, but for a more complex game using dist() (which uses sqrt()) behind the scenes could get computationally expensive. Since you only need to compare y coordinates you could implement this difference directly (if(y - y2 >= 140)).
additionally y = y + 0 doesn't add anything useful, but it does
read and write the y variable which again, takes a bit of time.
This won't impact performance that much and you should always
optimise at the end if you need to and not sacrifice code
readability, however less code means less to read and maintain in the
future. The more complex the programs you write will get the more
time you'll spend reading (and understanding) code rather than
writing it.
on above note I recommend also formatting code (in the
p5.js web editor Edit > Tidy Code does this for you, otherwise
there could be a similar option in your current code editor).
be kind to your future self and add code comments to explain what/why/how you did things. It will help a lot (imagine having to revisit your code after a few weeks/months and not remembering why you wrote things in a certain way).
Here's a modified version of your code with a few of the suggestions above:
let x2, y2;
let x, y;
function setup() {
createCanvas(400, 400);
x = 200;
y = 200;
x2 = 200;
y2 = 200;
}
function draw() {
background(220);
ellipse(x, y, 20, 20);
rect(x2 - 300, y2 + 150, 500, 200);
if(y - y2 < 140) {
y = y + 5;
}
if (keyIsPressed && keyCode === LEFT_ARROW) {
x = x - 2;
}
if (keyIsPressed && keyCode === RIGHT_ARROW) {
x = x + 2;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
Have fun learning !

Related

Creating random pixeled lines in Proccesing

I'm trying to make a game and I'm stuck on random level design. Basically, I'm trying to create a line from one edge/corner to another edge/corner while having some randomness to it.
See below image 1 [link broken] and 2 for examples. I'm doing this in processing and every attempt I've tried hasn't yielded proper results. I can get them to populate randomly but not in a line or from edge to edge. I'm trying to do this on a 16 x 16 grid by the way. Any ideas or help would be greatly appreciated thanks!
Image 2:
Based on your description, the challenge is in having a connected line from top to bottom with a bit of randomness driving left/right direction.
There are multiple options.
Here's a basic idea that comes to mind:
pick a starting x position: left's say right down the middle
for each row from 0 to 15 (for 16 px level)
pick a random between 3 numbers:
if it's the 1st go left (x decrements)
if it's the 2nd go right (x increments)
if it's the 3rd: ignore: it means the line will go straight down for this iteration
Here's a basic sketch that illustrates this using PImage to visualise the data:
void setup(){
size(160, 160);
noSmooth();
int levelSize = 16;
PImage level = createImage(levelSize, levelSize, RGB);
level.loadPixels();
java.util.Arrays.fill(level.pixels, color(255));
int x = levelSize / 2;
for(int y = 0 ; y < levelSize; y++){
int randomDirection = (int)random(3);
if(randomDirection == 1) x--;
if(randomDirection == 2) x++;
// if randomDirection is 0 ignore as we don't change x -> just go down
// constrain to valid pixel
x = constrain(x, 0, levelSize - 1);
// render dot
level.pixels[x + y * levelSize] = color(0);
}
level.updatePixels();
// render result;
image(level, 0, 0, width, height);
fill(127);
text("click to reset", 10, 15);
}
// hacky reset
void draw(){}
void mousePressed(){
setup();
}
The logic is be pretty plain above, but free to replace random(3) with other options (perhaps throwing dice to determine direction or exploring other psuedo-random number generators (PRNGs) such as randomGaussian(), noise() (and related functions), etc.)
Here's a p5.js version of the above:
let levelSize = 16;
let numBlocks = levelSize * levelSize;
let level = new Array(numBlocks);
function setup() {
createCanvas(320, 320);
level.fill(0);
let x = floor(levelSize / 2);
for(let y = 0 ; y < levelSize; y++){
let randomDirection = floor(random(3));
if(randomDirection === 1) x--;
if(randomDirection === 2) x++;
// if randomDirection is 0 ignore as we don't change x -> just go down
// constrain to valid pixel
x = constrain(x, 0, levelSize - 1);
// render dot
level[x + y * levelSize] = 1;
}
// optional: print to console
// prettyPrintLevel(level, levelSize, numBlocks);
}
function draw() {
background(255);
// visualise
for(let i = 0 ; i < numBlocks; i++){
let x = i % levelSize;
let y = floor(i / levelSize);
fill(level[i] == 1 ? color(0) : color(255));
rect(x * 20, y * 20, 20, 20);
}
}
function prettyPrintLevel(level, levelSize, numBlocks){
for(let i = 0; i < numBlocks; i+= levelSize){
print(level.slice(i, i + levelSize));
}
}
function mousePressed(){
setup();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
The data is a structured a 1D array in both examples, however, if it makes it easier it could easily be a 2D array. At this stage of development, whatever is the simplest, most readable option is the way to go.

How could I move randomly this triangle? p5.js

Since few days I try to animate my triangle, I want to move it randomly on my canvas. All of my tests were a failure so if you have some tips I am open to it!
I wish my triangle move on x and y axis randomly like a free electron and in the future I would like to have other triangles that move randomly and when they touch each other they bounce but it's another step!
My code:
let x = 50;
let y = 200;
let y1 = 100;
let y2 = 200
let x1 = 100;
let x2= 150;
let speed = 5;
let startColor;
let endColor;
let amt = 0;
function setup() {
startColor = color("hsl(172, 100%, 50%)");
endColor = color("hsl(335, 100%, 50%)");
createCanvas(windowWidth, 800);
frameRate(45);
}
function draw() {
colorMode(RGB);
background(252, 238, 10);
shape(); // Appel de la function shape
bounce();// appel de la fonction bounce
}
function bounce() {
x = x + speed;
x1 = x1 + speed;
x2 = x2 + speed;
y = y + speed
y1 = y1 + speed
y2 = y2 + speed
if (x2 > windowWidth || x < 0) {
speed = speed * -1;
}
}
function shape() {
if (amt >= 1) {
amt = 0;
let tmpColor = startColor;
startColor = endColor;
endColor = tmpColor;
}
amt += 0.01;
let colorTransition = lerpColor(startColor, endColor, amt);
noStroke();
fill(colorTransition);
triangle(x, y, x1, y1, x2, y2);
}
First you have a code working to make your triangle always move in the same direction. What you could do to make it random is to change the speed you are using:
For now each call to bounce moves the triangle by speed pixels. So if in draw() before calling shape() you add the following, triangle will begin to randomly move by a small amount:
speed = map(random(), 0, 1, -5, 5);
There are tons of different ways to do it, here we have making use of processing's random() to generate a number between 0 and 1 and map() to get a value between -5 and 5.
Now the issue is that you have only one type of speed and you apply to both axis x and y. What you want is probably to have speedX and speedY with two different values applied to both component of your position.
Once you try to do that you'll realize that having two variables for speedX and speedY is not very convenient and that you'd rather have one variable for your position with two component x and y and same for your speed. This way you'll be able to do position = position + speed. This requires that you refactor your code to use a more object oriented paradigm. To learn how to do that, one of the best resources online is the "Nature of Code" playlist by The coding train youtube channel.
I work every day and i followed all your advices and now this is what i have product, thanks for all !!
let triangle1;
let triangle2;
let triangle3;
let triangle4;
let triangle5;
let speedX;
let speedY;
let startColor;
let endColor;
let amt = 0;
function setup() {
startColor = color("hsl(172, 100%, 50%)");
endColor = color("hsl(335, 100%, 50%)");
createCanvas(windowWidth, 800);
//creer notre triangle
triangle1 = new Triangles(200, 100, 0, 4);
triangle2 = new Triangles(100, 50, 2, 0);
triangle3 = new Triangles(50, 200, -1, 4);
triangle4 = new Triangles(250, 400, 4, 4);
triangle5 = new Triangles(150, 500, 0, 2);
}
function draw() {
colorMode(RGB);
background(252, 238, 10);
triangle1.show();
triangle1.move();
triangle2.show();
triangle2.move();
triangle3.show();
triangle3.move();
triangle4.show();
triangle4.move();
triangle5.show();
triangle5.move();
}
class Triangles {
//configuration de l'objet
constructor(triX, triY, speedX, speedY){
this.x = triX;
this.y = triY;
this.speedX = speedX;
this.speedY = speedY;
}
show(){
if (amt >= 1) {
amt = 0;
let tmpColor = startColor;
startColor = endColor;
endColor = tmpColor;
}
amt += 0.01;
let colorTransition = lerpColor(startColor, endColor, amt);
noStroke();
fill(colorTransition);
noStroke();
triangle(this.x, this.y, this.x + 25, this.y + 40, this.x -25, this.y + 40);
}
move(){
this.x += this.speedX;
this.y += this.speedY;
if(this.x > width || this.x < 0){
this.speedX *= -1;
}
if(this.y > height || this.y < 0){
this.speedY = this.speedY * -1;
}
}
}

Is there a way to move lines from one place to another randomly?

Actually I'm trying to convert this JavaScript code to processing code. But got stuck.
var leftToRight = Math.random() >= 0.5;
if(leftToRight) {
context.moveTo(x, y);
context.lineTo(x + width, y + height);
} else {
context.moveTo(x + width, y);
context.lineTo(x, y + height);
}
context.stroke();
This is what I came up with and I know its fundamentally wrong but there must be a way. If anyone can at least point me in the right direction it would be great.
void draw() {
line(x1, y1, x2, y2);
for(int i = 0; i < 1000; i++) {
if(x1 == 0) {
x1 = width;
y1 = 0;
x2 = 0;
y2 = height;
line(x1, y1, x2, y2);
} else if(x1 == width) {
x1 = 0;
y1 = 0;
x2 = width;
y2 = height;
line(x1, y1, x2, y2);
}
}
Due to the nature of your question, it was difficult to assume what exactly you needed answered. For simplicity's sake, I assume you want the Java code converted to Processing. Hence, I will be ignoring what you wrote in your second code snippet.
The Java code essentially does the following:
Generates a random number from 0.0 to 1.0
Chooses one output based on whether the number is greater than 0.5:
Creates a line from (x, y) to (x + width, y + height) or
Creates a line from (x + width, y) to (x, y + height).
Here's a sample of Processing code that may assist you in this. This code is very close to that of the Java snippet you provided, as that is what you asked for.
int x = 0, y = 0;
if(random(0, 1) > 0.5) line(x, y, x + width, y + height);
else line(x + width, y, x, y + height);
When run, the canvas will show either this:
or this:
I hope this helps.

Processing - why does my Random Walker always tend toward the top left?

I am currently going through Daniel Shiffman's 'The Nature Of Code', and have been playing around with one of the first exercises - a simple 'RandomWalker()'. I have implemented similar things in Java & had no trouble, however for some reason my walker always seems to go in more or less the same direction:
RandomWalker
This happens 100% of the time. Here is my code:
class Walker
{
int x;
int y;
// Constructor
Walker()
{
x = width / 2;
y = height / 2;
}
void display()
{
stroke(0); // Colour
point(x, y); // Colours one pixel in
}
void step()
{
float stepX;
float stepY;
stepX = random(-1, 1);
stepY = random(-1, 1);
x += stepX;
y += stepY;
}
}
Walker w;
void setup()
{
size(640, 360);
w = new Walker();
background(255);
}
void draw()
{
w.step();
w.display();
}
Is this some artefact of the random function? My first thought is that it's something to do with the pseudorandom nature of the function but the textbook specifically states that this should not be noticeable, and yet this happens every single time. I was wondering if maybe there's something wrong with my code?
Thanks in advance.
Your x and y variables are both int types. That means that they don't have a decimal part, so any time you add or subtract from them, they are truncated. Here are some examples:
int x = 1;
x = x + .5;
//1.5 is truncated, and x stays 1
int x = 1;
x = x - .5;
//.5 is truncated, and x becomes 0
This is why you see your x and y variables only decreasing. To fix this, just change x and y to float types, so they keep track of the decimals.
If you really need x and y to be int values, then you need stepX and stepY to also be int values:
int stepX;
int stepY;
stepX = (int)random(-5, 5);
stepY = (int)random(-5, 5);
x += stepX;
y += stepY;
But you probably just want to store x and y as float values.
PS: I love random walkers!

make curtain like behaviour in drawing of lines

I am new to Processing.js and need a little bit support with this issue. I have made a HTML-Canvas animation where I have lines with a curtain like behavior which can be seen here:
Click
this is made with a canvas plugin called Paper.js
I now want to get similar effect on processing but don't really know how to figure it out. My attempt was:
float x;
float y;
void setup() {
size(1024, 768);
strokeWeight(2);
background(0, 0, 0);
}
void mouseMoved() {
x = mouseX;
y = mouseY;
}
void draw() {
background(0);
line(50, 50, x += x - x/5, y += y - y/5);
stroke(255, 255, 255);
line(50, 700, x += x - x/15, y += y - y/15);
stroke(255, 255, 255);
line(75, 50, x += x - x/25, y += y - y/25);
stroke(255, 255, 255);
line(75, 700, x += x - x/35, y += y - y/35);
// and so on, would create it within a loop
}
So what I am trying to do is basically get the same effect which I have done in HTML and adapt it in Processing.js.
Thanks in advance.
I'd strongly recommend ignoring the paper.js and reimplementing this properly. We're seeing a sequence of lines that connect to a historical line of coordinates, based on mouse position, so let's just implement that:
class Point {
float x, y;
Point(float _x, float _y) { x=_x; y=_y; }}
// our list of historical points
ArrayList<Point> points;
// the horizontal spacing of our lines has fixed interval
float interval;
// how many lines do we want to draw?
int steps = 50;
void setup() {
size(500, 500);
// initialise the "history" as just the midpoint
points = new ArrayList<Point>();
for (int i=0; i<steps; i++) {
points.add(new Point(width/2, height/2));
}
// compute the horizontal interval, because it's
// width-dependent. Never hard code dependent values.
interval = width/(float)steps;
// the lower we set this, the slower it animates.
frameRate(60);
}
void draw() {
// white background, black lines
background(255);
stroke(0);
// for each historic point, draw two
// lines. One from height 0 to the point,
// another from height [max] to the point.
Point p;
for (int i=0; i<steps; i++) {
p = points.get(i);
line(interval/2 + i*interval, 0, p.x, p.y);
line(interval/2 + i*interval, height, p.x, p.y);
}
// when we move the mouse, that counts as a new historic point
points.remove(0);
points.add(new Point(mouseX, mouseY));
}
Sketch running in the browser: http://jsfiddle.net/M2LRy/1/
(You could speed this up by using a round-robin array instead of an ArrayList, but ArrayLists are pretty convenient here)

Resources