Accelerated Ball leaving screen (Processing 2.1) - processing

It is supposed to be a balloon going up, stoping when the window ends. I cannot understand why my ball eventually disappears... Somebody help me.... When I try to tune the gravity parameter or the accelereation one, it either starts moving crazy fast (and dissapears), or real slow (eventually dissapears too). I have the checkEdges(), method defined so that this does not happen. Obviously something is not right
Mover mover;
void setup(){
size(300,600);
background(255);
mover = new Mover();
}
void draw(){
background(255,50);
mover.applyForceWind();
mover.applyForceGravity();
mover.update();
mover.display();
mover.checkEdges();
}
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
PVector gravity;
PVector wind;
Mover(){
location = new PVector(width/2,height*0.9);
velocity = new PVector(0,0);
acceleration = new PVector(0,-1);
}
void applyForceWind(){
PVector wind = new PVector(0.001,0);
acceleration.add(wind);
}
void applyForceGravity(){
PVector gravity = new PVector(0,0.1);
acceleration.add(gravity);
}
void update(){
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display(){
stroke(0);
fill(155);
ellipse(location.x,location.y,30,30);
}
void checkEdges(){
if ( location.x > width || location.x < 0){ velocity.x *= (-1);}
if ( location.y > height || location.y < 0){ velocity.y *=(-1);}
}
}

You had an extra close curly brace in your code, just FYI. The problem with the ball eventually getting "stuck" on the floor and disappearing is due to your checkEdges() code, as you suspected. To shed some light on the issue, try this code:
void checkEdges(){
if ( location.x > width || location.x < 0){ velocity.x *= (-1);}
if ( location.y > height || location.y < 0){
velocity.y *=(-1);
println("velocity: " + velocity.y + "; position: " + location.y);
}
}
And it will give something like this:
...
velocity: -2.3999999; position: 602.1
velocity: -2.3; position: 602.1
velocity: -2.2; position: 602.1
velocity: -2.1000001; position: 602.1
velocity: 2.0000002; position: 600.1
velocity: -2.1000001; position: 602.19995
velocity: 2.0000002; position: 600.19995
velocity: -2.1000001; position: 602.2999
velocity: 2.0000002; position: 600.2999
...
As you can see, the y-velocity at each successive "bounce" is slightly lower than the one before it, meaning that your system is bleeding energy. In particular, when the velocity becomes too low to get it back above the bottom of the screen (it goes below 2.1, which how far it has to go to get back up), it starts behaving erratically. Imagine it goes for a while, and then the next time it has to bounce, it only has a y velocity of -2. It's at y=602.1 > 600, so multiply y velocity by negative one. On the next iteration, it moves up 2 units, so y is now 600.1, but that is still off the screen so it inverts the velocity again! Here's a (crude) picture to illustrate the idea:
The red lines represent the iteration after the velocity was reversed. The length of each red line decreases as time goes on (the ball doesn't bounce quite as high), and eventually it doesn't actually get back above the barrier! At this point, it's still below the bottom of the screen, and so the inversion test still passes, so it turns the positive velocity negative, while it's still below the bottom of the screen.
There are a few ways to fix this:
Prevent the ball from losing energy as time goes on. This can be tricky to do. Here's a clue: if you swap the order of these two lines in your update() function, the ball will gain energy as time goes on! An interesting result.
location.add(velocity);
velocity.add(acceleration);
It doesn't make sense to allow the ball to go below the edge of the window anyway, so if it is there, then force it back up to the edge, ie insert this into your checkEdges() method:
location.y = height;
When I use the second bullet, I get a constant bounce response and no loss of speed as time goes on:
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
Also, a side note: there is no need to create new wind and gravity PVectors each time you call the methods. In fact, you even declared them as class variables anyways! Set their values in the constructor and then you can use them in your other methods.

Dude, acceleration is constant, but you're adding to it every iteration....

Related

recalibrate ball in pong so the edge hits first, not the centre in Processing

I've recently built a game of pong for a UNI assignment in Processing, but whenever the ball hits the top, bottom, side of the screen or the 'paddle' it only bounces back once half the ball is off the screen. I just want the edge of the ball to hit first rather than the centre, but am unsure where my code is going wrong. I hope this makes sense, I'm a definite beginner.
Here is my code for reference
//underwater pong
float x, y, speedX, speedY;
float diam = 10;
float rectSize = 200;
float diamHit;
PImage bg;
PImage img;
int z;
void setup() {
size(920, 500);
smooth();
fill(255);
stroke(255);
imageMode(CENTER);
bg = loadImage("underthesea.jpg");
img = loadImage("plastic.png");
reset();
}
void reset() {
x = width/2;
y = height/2;
//allows plastic to bounce
speedX = random(5, 5);
speedY = random(5, 5);
}
void draw() {
background(bg);
image(img, x/2, y);
rect(0, 0, 20, height);
rect(width/2, mouseY-rectSize/2, 50, rectSize);
//allows plastic to bounce
x += speedX;
y += speedY;
// if plastic hits movable bar, invert X direction
if ( x > width-30 && x < width -20 && y > mouseY-rectSize/2 && y < mouseY+rectSize/2 ) {
speedX = speedX * -1;
}
// if plastic hits wall, change direction of X
if (x < 25) {
speedX *= -1.1;
speedY *= 1.1;
x += speedX;
}
// if plastic hits up or down, change direction of Y
if ( y > height || y < 0 ) {
speedY *= -1;
}
}
void mousePressed() {
reset();
}
I wasn't able to run your code because I am missing the background and plastic images, but here's what's probably going wrong. I'm not 100% since I do not know the dimensions of your images either.
You are using imageMode(CENTER). See the documentation for details.
From the docs:
imageMode(CENTER) interprets the second and third parameters of image() as the image's center point. If two additional parameters are specified, they are used to set the image's width and height.
This treats the coordinates you input into the image function as the center of the image.
Your first issue is that you are placing your image at x/2 but doing all your collision checks with x in mind. x does not represent the middle of your image, because you're drawing it at x/2.
Then I'm not sure if you are doing your horizontal collision checks right, as you are checking against hardcoded values. I do know you are doing your vertical collision checks wrong. You are checking if the center of the image is at the top of the canvas, 0, or the bottom of the canvas, height. This means that your image will already have moved out of the screen halfway.
If you want to treat the image coordinates as the center of your image, you need to check the left edge of the image at x - imageWidth / 2, the right edge at X+ imageWidth / 2, the top edge at y - imageWidth / 2 (remember the y coordinates are 0 at the top of the canvas and increase towards the bottom) and the bottom at y - imageWidth / 2. Here's a great website which goes into more detail on 2d collision detection, i'd highly recommend you give it a read. It's an awesome website.

Processing | How to stop the ball from changing it's color

Here's a little code that I've written to get a ball bouncing in Processing. The ball should change it's color everything it bounces off the "ground" and become slower and slower and lay at the ground at the end.
But - and that's the problem I've got - the ball doesn't stops changing it's color at the bottom - and that means it didn't stops bouncing, right?
The question is: How do I tell the ball to stop and not to change it's color anymore?
float y = 0.0;
float speed = 0;
float efficiency = 0.9;
float gravitation = 1.3;
void setup(){
size(400, 700);
//makes everything smoother
frameRate(60);
//color of the ball at the beginning
fill(255);
}
void draw() {
// declare background here to get rid of thousands of copies of the ball
background(0);
//set speed of the ball
speed = speed + gravitation;
y = y + speed;
//bouce off the edges
if (y > (height-25)){
//reverse the speed
speed = speed * (-1 * efficiency);
//change the color everytime it bounces off the ground
fill(random(255), random(255), random(255));
}
//rescue ball from the ground
if (y >= (height-25)){
y = (height-25);
}
/*
// stop ball on the ground when veloctiy is super low
if(speed < 0.1){
speed = -0.1;
}
*/
// draw the ball
stroke(0);
ellipse(200, y, 50, 50);
}
The problem is that even though you are setting the speed to -0.1 when it is small, and y to height - 25, the very next pass through the loop adds gravity to speed and then speed to y, making y larger than height - 25 (by slightly more than 1 pixel) again. This makes the ball jump up and down through an infinite loop of hops of zero height.
You could use a threshold on the reflected speed. If it is below the threshold, stop the loop.
At the top of the file, add a line like
float threshold = 0.5; //experiment with this
Then in draw(), right after the line
speed = speed * (-1 * efficiency);
add the line
if(abs(speed) < threshold) noLoop();
In this case, you can throw away the if clause which checks when the speed is super-low.

Making an object bounce of an other object that is moved by mouseY/mouseX in processing

I am pretty new with processing and need some help. I'm trying to build a simple kickball game. Easy idea: when the ball hits the yellow bar, the ball bounces of. To keep the ball "alive" you have to make it bounce of the yellow bar. I've successfully found code for the bouncing ball (it now bounces of the bottom of the window), and I've also successfully created a bar that moves with the mouse. What I haven't been able to create so far is for the ball to actually bounce of the bar. Looking for som help here!! Thanks!!
float ballX = 100;
float ballY = 0;
float h = 50;
int x, y;
//create a variable for speed
float speedY = 2;
void setup() {
size(400,400);
smooth();
noStroke();
// change the mode we draw circles so they are
// aligned in the top left
ellipseMode(CORNER);
}
void draw() {
//clear the background and set the fill colour
background(0);
fill(255);
//draw the circle in it's current position
ellipse(ballX, ballY, h,h);
//add a little gravity to the speed
speedY = speedY + 0.5;
//add speed to the ball's
ballY = ballY + speedY;
//bar
x = mouseX;
y = mouseY;
fill(255, 255, 0);
rect(x, y, 50, 10);
if (ballY > height - h) {
// set the position to be on the floor
ballY = height - h;
// and make the y speed 90% of what it was,
// but in the opposite direction
speedY = speedY * -0.9;
//switch the direction
//speedY = speedY;
}
else if (ballY <= 0) {
// if the ball hits the top,
// make it bounce off
speedY = -speedY;
}
}
I'd warn you against just copy-pasting code you found on the internet. You have to really understand what it's doing, otherwise you're going to have a ton of headaches as your code becomes more complicated. Try to rewrite the logic yourself, that way you understand exactly how the bouncing works.
To figure out whether the ball is intersecting the paddle, I'd recommend taking out a piece of paper and a pencil and drawing some examples. Try to figure out a pattern of what the position and size of the ball and paddle are when they're intersecting.
But basically, you need to check whether the ball is "inside" the bounds of the rectangle. This is true if the ball is to the right of the left side of the paddle, to the left of the right side of the paddle, below the top of the paddle, and above the bottom of the paddle.

Adding physics to a obj in processing

So I’m trying to give an obj some physics, and have work with the example of the bouncing ball that processing comes with, and I have make it instead of a ball to be a cylinder, but I can’t find the way to make the obj to have the physics.
I’m importing the obj with the library saito.objloader. I have this code, which is the invocation of the obj
import processing.opengl.*;
import saito.objloader.*;
OBJModel modelCan;
PVector location; // Location of shape
PVector velocity; // Velocity of shape
PVector gravity; // Gravity acts at the shape's acceleration
float rotX, rotY;
void setup() {
size(1028, 768, OPENGL);
frameRate(30);
modelCan = new OBJModel(this, "can.obj", "absolute", TRIANGLES);
modelCan.scale(50);
modelCan.translateToCenter();
modelCan.enableTexture();
location = new PVector(100,100,100);
velocity = new PVector(1.5,2.1,3);
gravity = new PVector(0,0.2,0);
}
void draw() {
background(129);
lights();
// Add velocity to the location.
location.add(velocity);
// Add gravity to velocity
velocity.add(gravity);
// Bounce off edges
if ((location.x > width) || (location.x < 0)) {
velocity.x = velocity.x * -1;
}
if (location.y > height) {
// We're reducing velocity ever so slightly
// when it hits the bottom of the window
velocity.y = velocity.y * -0.95;
location.y = height;
}
if (location.z < -height || location.z > 0) { //note that Zaxis goes 'into' the screen
velocity.z = velocity.z * -0.95;
//location.z = height;
}
println("location x: "+location.x);
println("location y: "+location.y);
println("location z: "+location.z);
println("velocidad x: "+velocity.x);
println("velocidad y: "+velocity.y);
println("velocidad z: "+velocity.z);
pushMatrix();
translate(width/2, height/2, 0);
modelCan.draw();
popMatrix();
}
I hope you guys can help me! Thanks!
The bouncing ball example is a very simple example, and I guess you can't apply it to a cylinder in an easy way.
You might want to have a look at these sites :
http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/
http://shiffman.net/ (his book is essential )
https://github.com/shiffman/Box2D-for-Processing (again : Daniel Shiffman)
Collision detection is made in computer time : it means that it's correlated with the frequency of your program execution. For instance, the velocity of an object can be so big that between two render cycles your first object is passing through your second object: collision detection won't happen. They didn't collide during the previous cycle, and don't collide during the current cycle.
That's why some physics "engine" like Box2D try to anticipate the collision, computing the bounding box of each object.
If you want to make accurate collision detection in 3D, you can look at the Bullet library, used in many games and movies : http://bulletphysics.org/wordpress/ but the learning curve might be large.
In your program, you can try to give a threshold to your collision detection (and add the dimensions of your object to its position, if you want the whole body to collide, not only its center !): if your object's position is between your limit and (your limit +/- a threshold) consider it's colliding, but you won't totally avoid tunnelling.

Gravity simulation going haywire

I'm currently working on a Processing sketch featuring a very basic gravity simulation (based on an example given in Daniel Schiffman's book Learning Processing) but my gravity keeps behaving in a bizarre way and I'm at a loss to know what to do about it. Here's the simplest example I can come up with:
float x = 50;
float y = 50;
float speed = 2;
float gravity = 0.1;
void setup() {
size(400, 400);
}
void draw() {
background(255);
fill(175);
stroke(0);
ellipseMode(CENTER);
ellipse(x, y, 10, 10);
y = y + speed;
speed = speed + gravity;
//Dampening bounce effect when the ball hits bottom
if (y > height) {
speed = speed * -0.95;
}
}
The above is virtually identical to what's in Schiffman's book aside from a different starting speed and a different window size. It seems to work fine for the first two bounces but on the third bounce the ball becomes stuck to the bottom of the window.
I have no idea where to even begin trying to debug this. Can anyone give any pointers?
If y remains greater than height, your code just keeps flipping the speed over and over without giving the ball a chance to bounce. You want the ball to move away from the boundary whenever it is at or past the boundary.
Setting y to height in the (if y > height) block helps, but the ball never comes to 'rest' (sit on the bottom line when done).
There are two problems with Shiffman's example 5.9 which is where you probably started:
1) y can become greater than (height + speed), which makes it seem to go thud on the ground or bounce wildly
-- fixed with the suggestion
2) The algorithm to update y does things in the wrong order, so the ball never comes to rest
Correct order is:
if it is time to 'bounce
negate speed including dampening (* 0.95)
set y to location of the 'ground'
Add gravity to speed
Add speed to y
This way, when it is time to bounce (y is > height), and speed is positive (going downward):
speed is set to negative (times dampening)
y is set to height
speed is set less negative by the gravity factor
y is made less positive by adding the (still negative) speed
In my example, I didn't want the object to disappear so I use a variable named 'limit' to be the lowest (most positive y) location for the center of the object.
float x = 50;
float y = 50;
float speed = 2;
float gravity = 0.1;
void setup() {
size(400, 400);
y = height - 20;
}
void draw() {
background(255);
fill(175);
stroke(0);
ellipseMode(CENTER);
ellipse(x, y, 10, 10);
float limit = height - (speed + 5);
//Dampening bounce effect when the ball hits bottom
if (y > limit) {
speed = speed * -0.95;
y = limit;
}
speed = speed + gravity;
y = y + speed;
}

Resources