I was wondering if anyone could help me with this program.
I need to make the ball that is going horizontally start moving again and then shoot another ball that is going vertically. How can I make this happen over and over again, rather than it stopping after one go?
Also, how can I make the ball launching done by any key on the keyboard rather than the touchpad?
This is my program:
int xPos =200;
int yPos =700;
int xDir=3; // SPEED
float ball2X;
float ball2Y;
float ball2Speed=5;
boolean ball2Exist = false;
void setup () {
size (1280, 960);
}
void draw() {
background(255);
fill (255, 200, 200);
rect (0, 550, width, height);
fill (225);
//Player(ball)
ellipse(xPos, yPos, 140, 140);
fill (255, 200, 200);
xPos=xPos+xDir;
if (xPos>width-20 || xPos<20)
{
xDir=-xDir;
}
if(ball2Exist)
{
fill (255, 0, 0);
ellipse(ball2X, ball2Y, 70, 70);
ball2Y -= ball2Speed;
}
}
void mouseClicked() {
if(xDir!=0) // first click
xDir = 0;
else // second click
{
ball2X = xPos;
ball2Y = yPos;
ball2Exist = true;
}
}
In order to make the ball launching done by pressing a key, you can use the keyPressed()
function in the same way that you used the mouseClicked()
function. In order to make the horizontal ball continue moving after launching a ball, you can just set the ball's speed xDir
to its old value. To ensure that it continues going in the same direction you should use a variable to store its current value before you set it to 0, then you can set xDir to this value after launching the ball. In order to have multiple red balls you want to store a list of ball information so that you can draw multiple balls at the same time and in order to this effectively, you probably want to create a Ball
class.
In the following program, I made a ball class to encapsulate all of the ball drawing, and I used PVectors
to deal with the x and y corrdinates for position and speed.
// Horizontal ball
Ball mainBall;
// List of red balls
ArrayList<Ball> balls;
void setup () {
size (1280, 960);
//Create main ball
mainBall = new Ball(200, 700, 3, 0, 140, color(255, 200, 200));
// Create list of balls
balls = new ArrayList<Ball>();
}
void draw() {
background(255);
fill (255, 200, 200);
rect (0, 550, width, height);
ellipseMode(CENTER);
//If the main ball collides with edge of window, reverse speed
mainBall.collisionUpdate();
//Draw the main ball
mainBall.drawBall();
//Create arraylist to store balls to get removed from the list
ArrayList<Ball> toRemove = new ArrayList<Ball>();
// For every ball
for(Ball ball : balls){
ball.drawBall();
//If the ball is off the screen need to remove it
if(ball.isNotVisible()){
toRemove.add(ball);
}
}
// Remove all the non-visible balls
balls.removeAll(toRemove);
}
void launch(){
// Add a new ball to the list
balls.add(new Ball(mainBall.position.x, mainBall.position.y, 0, -5, 70, color(255, 0, 0)));
}
void mouseClicked() {
launch();
}
void keyPressed(){
launch();
}
// Ball class
class Ball{
PVector position;
PVector speed;
float diameter;
color c;
Ball(float x, float y, float xSpeed, float ySpeed, float _diameter, color _c){
position = new PVector(x, y);
speed = new PVector(xSpeed, ySpeed);
diameter = _diameter;
c = _c;
}
void drawBall(){
fill(c);
circle(position.x, position.y, diameter);
// Update position of ball
position.add(speed);
}
void collisionUpdate(){
if(position.x < diameter/2 || position.x > width-diameter/2 || position.y < diameter/2 || position.y > height-diameter/2 ){
//Reverse speed
speed.mult(-1);
}
}
// Return true or false if the ball is off the screen
boolean isNotVisible(){
return position.x > width+diameter || position.x < -diameter || position.y > height+diameter || position.y < -diameter;
}
}
Edit:
To make the balls decelerate and ricochet off the window boundaries. I also used a random function to randomise the speed and the rate at which the balls decelerate.
// Horizontal ball
Ball mainBall;
// List of red balls
ArrayList<Ball> balls;
PVector oldSpeed;
void setup () {
size (1280, 960);
//Create main ball
mainBall = new Ball(200, 700, 3, 0, 140, color(255, 200, 200));
// Create list of balls
balls = new ArrayList<Ball>();
}
void draw() {
background(255);
fill (255, 200, 200);
rect (0, 550, width, height);
ellipseMode(CENTER);
//If the main ball collides with edge of window, reverse speed
mainBall.collisionUpdate();
//Draw the main ball
mainBall.drawBall();
//Create arraylist to store balls to get removed from the list
ArrayList<Ball> toRemove = new ArrayList<Ball>();
// For every ball
for(Ball ball : balls){
// Balls bounce within the screen
ball.collisionUpdate();
// Slow the speed of the ball
ball.slowSpeed(random(0.98,0.999));
ball.drawBall();
//If the ball is off the screen need to remove it
if(ball.isNotVisible()){
toRemove.add(ball);
}
}
// Remove all the non-visible balls
balls.removeAll(toRemove);
}
void launch(){
if(!mainBall.isStationary()){
oldSpeed = mainBall.speed;
mainBall.setSpeed(0, 0);
}else{
// Add a new ball to the list
balls.add(new Ball(mainBall.position.x, mainBall.position.y, 0, random(-8, -5), 70, color(255, 0, 0)));
//Make the main ball move again
mainBall.setSpeed(oldSpeed);
}
}
void mouseClicked(){
launch();
}
void keyPressed(){
launch();
}
// Ball class
class Ball{
PVector position;
PVector speed;
float diameter;
color c;
Ball(float x, float y, float xSpeed, float ySpeed, float _diameter, color _c){
position = new PVector(x, y);
speed = new PVector(xSpeed, ySpeed);
diameter = _diameter;
c = _c;
}
void drawBall(){
fill(c);
circle(position.x, position.y, diameter);
// Update position of ball
position.add(speed);
}
void setSpeed(float xSpeed, float ySpeed){
speed = new PVector(xSpeed, ySpeed);
}
void setSpeed(PVector _speed){
speed = _speed;
}
boolean isStationary(){
return speed.x == 0 && speed.y == 0;
}
void collisionUpdate(){
if(position.x < diameter/2 || position.x > width-diameter/2 || position.y < diameter/2 || position.y > height-diameter/2 ){
//Reverse speed
speed.mult(-1);
}
}
void slowSpeed(float deceleration){
if(speed.mag() < 0.5){
speed = new PVector(0, 0);
}else{
speed.mult(deceleration);
}
}
// Return true or false if the ball is off the screen
boolean isNotVisible(){
return position.x > width+diameter || position.x < -diameter || position.y > height+diameter || position.y < -diameter;
}
}