Reputation: 83
The point of this exercise is for the ball to travel a smaller distance every cycle, so it leaves an espiral like trace, and ends up in the middle of the canvas.
My logic told me to make a variable "del" that gets bigger with every cycle and add it to the limit of the travel distance. It works fine for all the sides except the left one (where the cycle ends) if I add the variable to that side the ball never hits a limit.
How can I fix it? Thank you so much in advance!
let speed = 7;
let speedX = speed;
let speedY = 0;
let ellipseD = 50;
let ellipseR = ellipseD / 2;
let x = 0;
let y = ellipseR;
let limit = 25;
let del = 0;
function setup() {
createCanvas(500, 500);
}
function draw() {
background(166, 236, 255, 10);
fill(255);
strokeWeight(2);
stroke(21, 171, 212);
ellipse(x, y, ellipseD, ellipseD);
x = x + speedX;
y = y + speedY;
if (x >= width - (limit + del)) {
speedX = 0;
speedY = speed;
}
if (y >= height - (limit + del)) {
speedX = -speed;
speedY = 0;
}
if (y >= height - (limit + del) && x < limit) {
speedX = 0;
speedY = -speed;
}
if (y < limit + del && x <= limit) {
speedX = speed;
speedY = 0;
del = del + 50;
console.log(del);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
Upvotes: 3
Views: 338
Reputation: 56885
The first approach I tried is changing your last branch (the one that shrinks the square space by incrementing del
) to this:
if (y < limit + (del + 50) && x <= limit) {
The 50 here is the increment amount, which ensures that the right turn occurs before the snake overlaps with the area it's already visited.
The problem is, the condition then becomes too aggressive and fires prematurely. The fix I used is to add a check for the speedX
and speedY
in each branch to make sure the snake is moving in the right direction before triggering the condition. Since all conditions should be disjoint per frame, I made them else if
s for clarity.
Finally, if speed
doesn't cleanly divide ellipseD
and ellipseR
, you might see some artifacts and gaps in the snake pattern, so I used 7, 42 and 21 (42 / 2) respectively to clean up the gaps a bit. You might need to play with these sizes a bit to get the desired effect.
const speed = 7;
let speedX = speed;
let speedY = 0;
const ellipseD = 42;
const ellipseR = ellipseD / 2;
let x = 0;
let y = ellipseR;
const limit = 25;
let del = 0;
function setup() {
createCanvas(500, 500);
}
function draw() {
background(166, 236, 255, 10);
fill(255);
strokeWeight(2);
stroke(21, 171, 212);
ellipse(x, y, ellipseD, ellipseD);
x += speedX;
y += speedY;
if (x >= width - (limit + del) && speedX > 0) {
speedX = 0;
speedY = speed;
}
else if (y >= height - (limit + del) && speedY > 0) {
speedX = -speed;
speedY = 0;
}
else if (y >= height - (limit + del) &&
x < (limit + del) && speedX < 0) {
speedX = 0;
speedY = -speed;
}
else if (y < limit + ellipseD + del && speedY < 0) {
speedX = speed;
speedY = 0;
del += ellipseD;
if (del > width / 2) {
noLoop();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
Upvotes: 4
Reputation: 20140
I think the most obvious issue with the behavior on the left hand side is that you are not taking del
into account when checking x
:
// This checks if the ellipse is in the bottom left
if (y >= height - (limit + del) && x < limit) {
speedX = 0;
speedY = -speed;
}
The problem with this code is that x < limit
should be x < limit + del
. And a similar issue exists in the check for when the ellipse is in the top left.
However, once you "fix" that you will start having issues because the check for the top left will fire repeatedly as del
increases faster than the ellipse moves. So it is necessary to add checks to see what direction the ellipse is moving in before updating speed and the value of del
.
let speed = 7;
let speedX = speed;
let speedY = 0;
let ellipseD = 50;
let ellipseR = ellipseD / 2;
let x = ellipseR;
let y = ellipseR;
let limit = ellipseR;
let del = 0;
function setup() {
createCanvas(500, 500);
}
function draw() {
background(166, 236, 255, 10);
fill(255);
strokeWeight(2);
stroke(21, 171, 212);
ellipse(x, y, ellipseD, ellipseD);
x = x + speedX;
y = y + speedY;
if (x >= width - (limit + del) && x >= width - (limit + del) && speedX > 0) {
speedX = 0;
speedY = speed;
console.log('top right');
}
if (y >= height - (limit + del) && x >= width - (limit + del) && speedY > 0) {
speedX = -speed;
speedY = 0;
console.log('bottom right');
}
if (y >= height - (limit + del) && x <= (limit + del) && speedX < 0) {
speedX = 0;
speedY = -speed;
console.log('bottom left');
}
if (y < (limit + del) && x <= limit + del && speedY < 0) {
speedX = speed;
speedY = 0;
del = del + 50;
console.log(del);
console.log('top left');
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
Upvotes: 1