为了使按键完成球发射,您可以像使用mouseClicked()函数一样使用keyPressed()函数。为了使水平球在发射球后继续移动,您可以将球的速度xDir设置为其旧值。为了确保它继续朝同一个方向前进,您应该在将其设置为 0 之前使用一个变量来存储其当前值,然后您可以在发射球后将 xDir 设置为该值。为了有多个红球,您需要存储一个球信息列表,以便您可以同时绘制多个球,为了有效地做到这一点,您可能需要创建一个Ball 类。
在下面的程序中,我创建了一个球类来封装所有球的绘制,并使用PVectors 来处理位置和速度的 x 和 y 坐标。
// 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;
}
}
编辑:
使球减速并从窗口边界弹跳。我还使用了一个随机函数来随机化球减速的速度和速率。
// 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;
}
}