We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm trying to make a simple version of pong. My code works when I simply draw a single ellipse and code it to bounce off of the Paddle (rectangle), but when I create an array of balls (ellipses) the balls no longer bounce off of the paddle. I'm not sure where I'm going wrong, I thought I followed the P5.js intersecting objects tutorial pretty well. Again I want any Ball from the array to bounce off of the Paddle, if the objects intersect.
var gravity = 0.1;
var balls = [];
var n = 0;
function setup() {
createCanvas(400, 400);
Paddle = new Paddle(180, height / 4 * 3);
for (n = 0; n < 7; n++) {
append(balls, new Ball(random(width), random(height)));
}
}
function draw() {
background(51);
Paddle.display();
Paddle.borders();
for (n = 0; n < balls.length; n++) {
balls[n].display();
balls[n].move();
}
for (i = 0; i < balls.length; i++){
if (balls[i].intersects(Paddle)) {
balls[n].bounce();
}
}
}
function mouseClicked() {
if (n < 9 && mouseY < height - 50) {
append(balls, new Ball(mouseX, mouseY));
}
}
function keyPressed() {
if (keyCode === RIGHT_ARROW) {
Paddle.move(1);
} else if (keyCode === LEFT_ARROW) {
Paddle.move(-1);
}
}
function Paddle(x, y) {
this.x = x;
this.y = y;
this.r = 25;
this.move = function(dir) {
this.x += dir * 15;
}
this.borders = function() {
if (this.x > width)
this.x = 0;
if (this.x < 0)
this.x = width;
}
this.display = function() {
stroke(0, 255, 0);
fill(0, 255, 0);
rectMode(CENTER);
rect(this.x, this.y, this.r * 4, this.r * 2)
}
}
function Ball(x, y) {
this.x = x;
this.y = y;
this.r = 25;
this.yspeed = 0.1;
// this.toBounce = false;
this.move = function() {
this.y += this.yspeed;
this.yspeed += gravity;
if (this.y > height) {
this.y = height;
this.yspeed *= -1
}
if (this.y < 0) {
this.y = 0;
this.yspeed *= -1
}
}
this.intersects = function(Paddle) {
var d = dist(Ball.x, Ball.y, Paddle.x, Paddle.y);
if (d < Ball.r + Paddle.y) {
return true;
} else {
return false;
}
}
this.bounce = function() {
this.y = this.y *= -1
this.yspeed *= -1;
}
this.display = function() {
stroke(255)
fill(255, 0, 0);
ellipse(this.x, this.y, this.r * 2, this.r * 2);
}
}
Answers
line 26
balls[n].bounce();
that n is 0. Should change it to i?
Don't use global variables as the for-loop iterator and you won't run into these kinds of problems so easily
Thanks I did not notice that, however it does not fix the issue.
Sorry I can't run your code at the moment. However, do you need line 97? I would think you just need to change the speed orientation aka. sign. The value of y gets updated in your move() function.
Kf
Well for a single ellipse to bounce off of the Paddle I believe I had to add it, as I tried without.
@wjsandbe - there are a lot of errors in your code :/
In the context of your specific problem the following line is the main cause:
var d = dist(Ball.x, Ball.y, Paddle.x, Paddle.y);
To calculate distance based on the current ball's position that should be:
var d = dist(this.x, this.y, Paddle.x, Paddle.y);
...but there's a lot of other stuff wrong - e.g.
You also do some very strange things like:
Paddle = new Paddle(180, height / 4 * 3);
Here you've overwritten the Paddle constructor with a reference to your Paddle instance. It looks like you can get away with it in this case; but it's not good practice. Also the
i
variable in your for loop is undeclared so is a global variable - which is a Bad Thing. It should be:But you don't even need this since it duplicates the preceding loop that uses an
n
variable (which - as @Sayid mentioned - also happens to conflict with the globally declaredn
).Sorry - I guess this might seem a little disheartening. I'll try and get a mostly working version together and post some code later ;)
Thanks, this was very helpful. I'm still learning I'll see if I can clean this up! Appreciate it.
Here's a more or less working version (it would still benefit from quite a few improvements):
I am curious, why is it bad practice to connect a loop to a global variable? For example I used the variable n so that I could follow the number of the array throughout my code, if it wasn't global I couldn't do this.
as well on line 22 I used the first loop for the subset function, so that the users cannot add more than 8 balls. When this is taken out the user can continuously add balls, which is not idea, as I link the ball movements to sound so people can compose a song by playing pong.
Thanks though this was very helpful.
But in practice what you most likely need to know is balls.length. See how I test against this (line 35) in order to determine whether a new ball can be added.
Testing against n however could produce inconsistent results: in principle the value of n could be anything between 0 and balls.length when the mouseClicked event is triggered. So even if balls.length were 100 n would sometimes be less than 9, allowing a new ball to be added - probably not what you intended :/
globals in general are bad practice and should be avoided...
I understand. Thanks again you have been very helpful!