Processing bat and ball game on vertical axis - processing

This is the code I have at the moment but I want to put the bat on the y axis and have it move up and down vertically rather than horizontally, and have the ball bounce in a left to right motion rather than up and down. Help is needed quickly. Thanks.
int x=250; // Horizontal position of ball
int direction_x=2; // Change in horizontal position each time draw() executed
int y=150; // Vertical position of ball
int direction_y=2; // Change in horizontal position each time draw() executed
int lives=3;
int score=0;
void setup()
{
size(400,400); // Create a window 400x400 pixels
}
void draw()
{
background(255,255,255); // Clear screen to white
fill(0,255,0); // Set fill colour to blue
rect(mouseY-60,380,120,20); // Position rectangle using mouse
fill(0,0,255);
ellipse(x,y,20,20); // Draw blue disk centered on x,y diameter 20
x=x+direction_x; // Update position
if(x<10) direction_x=-direction_x; // Reverse direction if hit boundary
if(x>(width-10)) direction_x=-direction_x;
y=y+direction_y;
if(y<10) direction_y=-direction_y;
// if(y>(height-10)) direction_y=-direction_y;
if(y>(height-10)) // If ball bits bottom of screen then miss..
{
direction_y=-direction_y; // Bounce
lives--; // Reduce lives by one
if(lives==0) exit(); // If lives is zero then quit
}
if((y>(height-30))&&(abs(mouseX-x)<60)) // If ball has bit paddle then..
{
direction_y=-direction_y; // Bounce
score++; // Increase score by one
}
textSize(32);
fill(0,0,255);
text(score, 10, 30); // Display score
text(lives,width-30, 30); // Display lives
}

Since help is needed quickly, you'll have better luck if you ask a specific "I tried X, expected Y, but got Z instead" type question. It's hard to help with general "how do I do this" type questions, other than to offer general tips.
That being said, there are two main approaches that I can think of:
Option One: Break your problem down into smaller steps. Start with a blank sketch and get just the paddle working how you want it to. Then try adding the ball. After that's working, then try adding game logic. This is the better option here.
Option Two: Since you seem to almost have this working going up and down, you could just rotate everything 90 degrees by using the rotate() function. This is a bit of a hack though.

Thanks Kevin, got it working at last, turns out I just had to change co-ordinates of the paddle from (mouseX,0,0,0) to (0, mouseY,0,0) and needed to add in an additional line of code to change the axis parameters. I was doing my age old trick of over complicating things.
int x=250; // Horizontal position of ball
int direction_x=2; // Change in horizontal position each time draw() executed
int y=150; // Vertical position of ball
int direction_y=2; // Change in horizontal position each time dra) executed
int lives=3;
int score=0;
void setup()
{
size(400,400); // Create a window 400x400 pixels
}
void draw()
{
background(255,255,255); // Clear screen to white
fill(0,255,0); // Set fill colour to blue
rect(0,mouseY-60,20,120); // Position rectangle using mouse
fill(0,0,255);
ellipse(x,y,20,20); // Draw blue disk centered on x,y diameter 20
x=x+direction_x; // Update position
if(x<10) direction_x=-direction_x; // Reverse direction if hit boundary
if(x>(width-10)) direction_x=-direction_x;
y=y+direction_y;
if(y<10) direction_y=-direction_y;
// if(y>(height-10)) direction_y=-direction_y;
if(y>(height-10)) // If ball bits bottom of screen then miss..
{
direction_y=-direction_y; // Bounce
lives--; // Reduce lives by one
if(lives==0) exit(); // If lives is zero then quit
}
if(x<10)
{
direction_x=-direction_x; // Bounce
x=30; // Force x to beyond the paddle on a restart
lives--; // Reduce lives by one
if(lives==0) exit(); // If lives is zero then quit
}
if((x<30)&&(abs(mouseY-y)<60)) // If ball has bit paddle then..
{
direction_x=-direction_x; // Bounce
score++; // Increase score by one
}
textSize(32);
fill(0,0,255);
text(score, 10, 30); // Display score
text(lives,width-30, 30); // Display lives
}

Related

Jumping realistic in Processing with PVectors

I tried to make a jump look realistic, while I watched through the Videos:
The Natur of Code - The Coding Train
I got into PVectors. I strongly recomend watching him. But to get to my question, everything seems to work, exept that it draws the rectangle (my PVector) the way I want.
void keyPressed() {
if (keyCode == UP) {
for (int i = 0; i < 16; i++) {
location.sub(velocity);
velocity.sub(acceleration);
h.display();
background(0);
}
velocity.set(0, 15);
}
}
That's the Code, I expect it to "jump", but nothing realy happens. You can see that the rectangle get's drawn again (on the same spot), but there's no movement. It's definitly an issue with the drawing of the background or something, I don't know what exaclty though.
The nature of your question is unclear. You mentioned issues regarding the background interfering with your rectangle after the UP arrow key is pressed. This is likely because background(0) is called immediately after h.display(). I would remove background(0) from your loop if it's a display issue.
Other than that, there seem to be other issues with the loop itself. When the UP key is pressed, h is affected by acceleration only for 16 frames. To make your object more realistic, gravity (or whatever acceleration you choose) should constantly be acting upon the object.
With that in mind, here's a solution for you.
void keyPressed() {
if (keyCode == UP) {
// Make the character 'jump' upwards when the UP arrow is pressed.
// Setting the velocity should be the only thing happening when the key is pressed.
velocity.set(0, -2);
}
}
void draw() {
// Reset the background each frame so rectangles don't overlap.
background(255);
// Always draw the rectangle AFTER resetting the canvas.
h.display();
// Change the object's location by it's velocity.
location.add(velocity);
// And chance the object's velocity by it's acceleration.
// Since acceleration is the acting force of gravity in this situation, acceleration need not be changed.
velocity.add(acceleration);
// Prevent the rectangle from falling through the bottom of the canvas.
if(location.y > height - 5) location.y = height - 5;
}
// You negleteced to define your variables in your code snippet. Here they are.
PVector location = new PVector(0, 0);
PVector velocity = new PVector(0, 0);
PVector acceleration = new PVector(0, 0.1); // Notice that acceleration's y-value is 0.01. This is so you can see the effect of gravity.
// Define your rectangle object.
Object h = new Object();
class Object {
Object() {} // Constructor.
void display() {
// Draw the rectangle at the x- and y-positions of the location vector.
// The '+ width/2' places it at the center of the screen.
rectMode(CENTER);
rect(location.x + width/2, location.y, 10, 10);
}
}

Moving image leaving trail and directional movement according to mouse position -Processing

So I managed to make most of the exercise but can't think of a way to make the trail of the moving image. Also, in the video ball moves in the direction of mouse position.
However, when I tried to do that, mouse position is changing every time and the ball is following the mouse while moving. The velocity had to be calculated using the mouse position. Any help would be appreciated.
This is how it should look: https://streamable.com/9jdc3
My code:
PImage ball, bFire;
int xPosB, yPosB, bW, bH, bFW, bFH, velocityX, velocityY;
boolean bMoving;
void setup() {
size(1024, 512);
//loading images
ball = loadImage("ball.png");
bFire = loadImage("ballFire.png");
//resizing images
ball.resize(ball.width/4, ball.height/4);
bFire.resize(bFire.width/4, bFire.height/4);
//starting values
//ball
xPosB = width/2;
yPosB = height/2;
}
void draw() {
background(0);
//draw ball
imageMode(CENTER);
image(ball, xPosB, yPosB);
//draw fire ball
if (bMoving) {
image(bFire, xPosB, yPosB);
xPosB+=velocityX;
yPosB+=velocityY;
}
//colision detection
if (xPosB-bFire.width/2 <= 0 || xPosB+bFire.width/2 >= width) {
velocityX*=-1;
} else if (yPosB-bFire.height/2 <= 0 || yPosB+bFire.height/2 >= height) {
velocityY*=-1;
}
}
void mousePressed() {
if (mouseButton == LEFT) {
bMoving=!bMoving;
velocityX = mouseX/100;
velocityY = mouseY/100;
}
}
I can't repoduce the problem you describe - of the ball following the mouse.
I can tell you that the mousepressed() you use is incorrect.
You assign the velocity, but because mouseX and mouseY will always be positive the ball will always move to the right and down.
Try the code below, it sets the velocity to the difference between the mouse and the current position of the ball. The ball will now always move towards the mouse.
void mousePressed() {
if (mouseButton == LEFT) {
bMoving=!bMoving;
velocityX = (mouseX - xPosB) / 50;
velocityY = (mouseY - yPosB) / 50;
}
Second point: I don't know how your ballFire.png looks, but right now it is drawn at the exact same X/Y location of the ball. This cannot give you a trailing effect, for that you'll have to draw the fireball a little behind the ball.
Try the code below:
//draw fire ball
if (bMoving) {
image(bFire, xPosB-velocityX, yPosB-velocityY);
xPosB+=velocityX;
yPosB+=velocityY;
}
//draw ball
imageMode(CENTER);
image(ball, xPosB, yPosB);
It draws the fireBall behind the ball based on the velocity. So faster means more distance. You can tweak this distance of course. If you want multiple firballs as trailing effect, draw the fireball multiple times with different offsets.
Final note: you'll want to draw the ball last, else the fireball will be drawn half over the normal ball.

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.

Processing, ellipse not following alpha values?

class Particle{
PVector velocity, location; //PVector variables for each particle.
Particle(){ //Constructor - random location and speed for each particle.
velocity = new PVector(random(-0.5,0.5), random(-0.5,0.5));
location = new PVector(random(0,width),random(0,width));
}
void update() { location.add(velocity); } //Motion method.
void edge() { //Wraparound case for particles.
if (location.x > width) {location.x = 0;}
else if (location.x < 0) {location.x = width;}
if (location.y > height) {location.y = 0;}
else if (location.y < 0) {location.y = height;}
}
void display(ArrayList<Particle> p){ //Display method to show lines and ellipses between particles.
for(Particle other: p){ //For every particle in the ArrayList.
float d = PVector.dist(location,other.location); //Get distance between any two particle.
float a = 255 - d*2.5; //Map variable 'a' as alpha based on distance. E.g. if distance is high, d = 100, alpha is low, a = 255 - 225 = 30.
println("Lowest distance of any two particle =" + d); //Debug output.
if(d<112){ //If the distance of any two particle falls bellow 112.
noStroke(); //No outline.
fill(0,a); //Particle are coloured black, 'a' to vary alpha.
ellipse(location.x, location.y, 8, 8); //Draw ellipse based on location of particle.
stroke(0,a); //Lines are coloured black, 'a' to vary alpha.
strokeWeight(0.7);
line(location.x,location.y,other.location.x,other.location.y); //Draw line between four coordinates, between two particle.
}
}
}
}
ArrayList<Particle> particles = new ArrayList<Particle>(); //Create a new arraylist of type Particle.
void setup(){
size(640,640,P2D); //Setup frame of sketch.
particles.add(new Particle()); //Add five Particle elements into arraylist.
particles.add(new Particle());
particles.add(new Particle());
particles.add(new Particle());
particles.add(new Particle());
}
void draw(){
background(255); //Set white background.
for(Particle p: particles){ //For every 'p' of type Particle in arraylist particles.
p.update(); //Update location based on velocity.
p.display(particles); //Display each particle in relation to other particles.
p.edge(); //Wraparound if particle reaches edge of screen.
}
}
In the above code, there are to shape objects, lines and ellipses. The transparency of which are affected by variable a.
Variable 'a', or alpha, is extrapolated from 'd' which is distance. Hence, when the objects are further, the alpha value of the objects falls.
In this scenario, the alpha values of the line do not change over time e.g. fade with distance. However the ellipses seem to be stuck on alpha '255' despite having very similar code.
If the value of 'a' is hardcoded, e.g.
if(d<112){ //If the distance of any two particle falls bellow 112.
noStroke(); //No outline.
fill(0,100); //Particle are coloured black, set alpha 'a' to be 100, grey tint.
ellipse(location.x, location.y, 8, 8); //Draw ellipse based on location of particle.
the ellipses changes colour as expected to a grey tint.
Edit: I believe I have found the root of the issue. The variable 'a' does not discriminate between the particles that are being iterated. As such, the alpha might be stuck/adding up to 255.
You're going to have to post an MCVE. Note that this should not be your entire sketch, just a few hard-coded lines so we're all working from the same code. We should be able to copy and paste your code into our own machines to see the problem. Also, please try to properly format your code. Your lack of indentation makes your code hard to read.
That being said, I can try to help in a general sense. First of all, you're printing out the value of a, but you haven't told us what its value is. Is its value what you expect? If so, are you clearing out previous frames before drawing the ellipses, or are you drawing them on top of previously drawn ellipses? Are you drawing ellipses elsewhere in your code?
Start over with a blank sketch, and add just enough lines to show the problem. Here's an example MCVE that you can work from:
stroke(0);
fill(0);
ellipse(25, 25, 25, 25);
line(0, 25, width, 25);
stroke(0, 128);
fill(0, 128);
ellipse(75, 75, 25, 25);
line(0, 75, width, 75);
This code draws a black line and ellipse, then draws a transparent line and ellipse. Please hardcode the a value from your code, or add just enough code so we can see exactly what's going on.
Edit: Thanks for the MCVE. Your updated code still has problems. I don't understand this loop:
for(Particle other: p){ //For every particle in the ArrayList.
float d = PVector.dist(location,other.location); //Get distance between any two particle.
float a = 255 - d*2.5; //Map variable 'a' as alpha based on distance. E.g. if distance is high, d = 100, alpha is low, a = 255 - 225 = 30.
println("Lowest distance of any two particle =" + d); //Debug output.
if(d<112){ //If the distance of any two particle falls bellow 112.
noStroke(); //No outline.
fill(0,a); //Particle are coloured black, 'a' to vary alpha.
ellipse(location.x, location.y, 8, 8); //Draw ellipse based on location of particle.
stroke(0,a); //Lines are coloured black, 'a' to vary alpha.
strokeWeight(0.7);
line(location.x,location.y,other.location.x,other.location.y); //Draw line between four coordinates, between two particle.
}
}
}
You're saying for each Particle, you loop through every Particle and then draw an ellipse at the current Particle's location? That doesn't make any sense. If you have 100 Particles, that means each Particle will be drawn 100 times!
If you want each Particle's color to be based off its distance to the closest other Particle, then you need to modify this loop to simply find the closest Particle, and then base your calculations off of that. It might look something like this:
Particle closestNeighbor = null;
float closestDistance = 100000;
for (Particle other : p) { //For every particle in the ArrayList.
if (other == this) {
continue;
}
float d = PVector.dist(location, other.location);
if (d < closestDistance) {
closestDistance = d;
closestNeighbor = other;
}
}
Notice the if (other == this) { section. This is important, because otherwise you'll be comparing each Particle to itself, and the distance will be zero!
Once you have the closestNeighbor and the closestDistance, you can do your calculations.
Note that you're only drawing particles when they have a neighbor that's closer than 112 pixels away. Is that what you want to be doing?
If you have a follow-up question, please post an updated MCVE in a new question. Constantly editing the question and answer gets confusing, so just ask a new question if you get stuck again.

Algorithm for shape calculation (Ellipse)

I have n circles that must be perfectly surrounding an ellipse as shown in the picture here :
In this picture I need to find out the position of each circle around the ellipse, and also be able to calculate the ellipse that will fit perfectly inside those surrounding circles.
The information i know is the radius of each circles (all same), and the number of circles.
Hopefully this time the post is clear.
Thanks for your help.
Please let me know if you need more explanation.
OK as i understand you know common radius of circles R0 and their number N and want to know inside ellipse parameters and positions of everything.
If we convert ellipse to circle then we get this:
const int N=12; // number of satelite circles
const double R=10.0; // radius of satelite circles
struct _circle { double x,y,r; } circle[N]; // satelite circles
int i;
double x,y,r,l,a,da;
x=0.0; // start pos of first satelite circle
y=0.0;
r=R;
l=r+r; // distance ang angle between satelite circle centers
a=0.0*deg;
da=divide(360.0*deg,N);
for (i=0;i<N;i++)
{
circle[i].x=x; x+=l*cos(a);
circle[i].y=y; y+=l*sin(a);
circle[i].r=r; a+=da;
}
// inside circle params
_circle c;
r=divide(0.5*l,sin(0.5*da))-R;
c.x=circle[i].x;
c.y=circle[i].y+R+r;
c.r=r;
[Edit 1]
For ellipse its a whole new challenge (took me two hours to find all quirks out)
const int N=20; // number of satelite circles
const double R=10.0; // satelite circles radius
const double E= 0.7; // ellipse distortion ry=rx*E
struct _circle { double x,y,r; _circle() { x=0; y=0; r=0.0; } } circle[N];
struct _ellipse { double x,y,rx,ry; _ellipse() { x=0; y=0; rx=0.0; ry=0.0; } } ellipse;
int i,j,k;
double l,a,da,m,dm,x,y,q,r0;
l=double(N)*R; // circle cener lines polygon length
ellipse.x =0.0; // set ellipse parameters
ellipse.y =0.0;
r0=divide(l,M_PI*sqrt(0.5*(1.0+(E*E))))-R;// aprox radius to match ellipse length for start
l=R+R; l*=l;
m=1.0; dm=1.0; x=0.0;
for (k=0;k<5;k++) // aproximate ellipse size to the right size
{
dm=fabs(0.1*dm); // each k-iteration layer is 10x times more accurate
if (x>l) dm=-dm;
for (;;)
{
ellipse.rx=r0 *m;
ellipse.ry=r0*E*m;
for (a=0.0,i=0;i<N;i++) // set circle parameters
{
q=(2.0*a)-atanxy(cos(a),sin(a)*E);
circle[i].x=ellipse.x+(ellipse.rx*cos(a))+(R*cos(q));
circle[i].y=ellipse.y+(ellipse.ry*sin(a))+(R*sin(q));
circle[i].r=R;
da=divide(360*deg,N); a+=da;
for (j=0;j<5;j++) // aproximate next position to match 2R distance from current position
{
da=fabs(0.1*da); // each j-iteration layer is 10x times more accurate
q=(2.0*a)-atanxy(cos(a),sin(a)*E);
x=ellipse.x+(ellipse.rx*cos(a))+(R*cos(q))-circle[i].x; x*=x;
y=ellipse.y+(ellipse.ry*sin(a))+(R*sin(q))-circle[i].y; y*=y; x+=y;
if (x>l) for (;;) // if too far dec angle
{
a-=da;
q=(2.0*a)-atanxy(cos(a),sin(a)*E);
x=ellipse.x+(ellipse.rx*cos(a))+(R*cos(q))-circle[i].x; x*=x;
y=ellipse.y+(ellipse.ry*sin(a))+(R*sin(q))-circle[i].y; y*=y; x+=y;
if (x<=l) break;
}
else if (x<l) for (;;) // if too short inc angle
{
a+=da;
q=(2.0*a)-atanxy(cos(a),sin(a)*E);
x=ellipse.x+(ellipse.rx*cos(a))+(R*cos(q))-circle[i].x; x*=x;
y=ellipse.y+(ellipse.ry*sin(a))+(R*sin(q))-circle[i].y; y*=y; x+=y;
if (x>=l) break;
}
else break;
}
}
// check if last circle is joined as it should be
x=circle[N-1].x-circle[0].x; x*=x;
y=circle[N-1].y-circle[0].y; y*=y; x+=y;
if (dm>0.0) { if (x>=l) break; }
else { if (x<=l) break; }
m+=dm;
}
}
Well I know its a little messy code so here is some info:
first it try to set as close ellipse rx,ry axises as possible
ellipse length should be about N*R*2 which is polygon length of lines between circle centers
try to compose circles so they are touching each other and the ellipse
I use iteration of ellipse angle for that. Problem is that circles do not touch the ellipse in their position angle thats why there is q variable ... to compensate around ellipse normal. Look for yellowish-golden lines in image
after placing circles check if the last one is touching the first
if not interpolate the size of ellipse actually it scales the rx,ry by m variable up or down
you can adjust accuracy
by change of the j,k fors and/or change of dm,da scaling factors
input parameter E should be at least 0.5 and max 1.0
if not then there is high probability of misplacing circles because on very eccentric ellipses is not possible to fit circles (if N is too low). Ideal setting is 0.7<=E<=1.0 closser to 1 the safer the algorithm is
atanxy(dx,dy) is the same as `atan(dy/dx)
but it handles all 4 quadrants like atan2(dy,dx) by sign analysis of dx,dy
Hope it helps

Resources