2016-01-30 3 views
-1

Я отжимаю программу прыгающего мяча в java. И у меня теперь есть один прыгающий мяч, я бы хотел иметь по крайней мере пять прыгающих мячей. Я попробовал несколько способов сделать это, однако, я только закончил с одним мячом или ошибкой.Несколько шаров - прыгающие шары - Java

Есть ли у вас какие-либо предложения о том, как действовать? Это в куске кода, используемого для одного шара, можно ли переписать этот кусок кода, чтобы аккуратно получить несколько шаров?

import javafx.scene.shape.Rectangle; 

public class World { 

private final double width, height; 

private Ball[] balls; 
private final Rectangle pad; 

public World(double width, double height) { 
    this.width = width; 
    this.height = height; 

    balls = new Ball[1]; 
    balls[0] = new Ball(10, 10); 
    balls[0].setVelocity(75.0, 100.0); 




    pad = new Rectangle(width/2, 0.9 * height, 
      width/8, height/32); 
} 


public void move(long elapsedTimeNs) { 
    balls[0].move(elapsedTimeNs); 
    constrainBall(balls[0]); 
    checkForCollisionWithPad(balls[0]); 
} 


public Ball[] getBalls() { 
    return (Ball[]) balls.clone(); 
} 


public Rectangle getPad() { 
    return pad; 
} 


public void setPadX(double x) { 
    if (x > width) { 
     x = width; 
    } 
    if (x < 0) { 
     x = 0; 
    } 

    pad.setX(x); 
} 


private void constrainBall(Ball ball) { 
    double x = ball.getX(), y = ball.getY(); 
    double dx = ball.getDx(), dy = ball.getDy(); 
    double radius = ball.getRadius(); 


    if (x < radius) { 
     dx = Math.abs(dx); 
    } else if (x > width - radius) { 
     dx = -Math.abs(dx); 
    } 
    if (y < radius) { 
     dy = Math.abs(dy); 
    } else if (y > height - radius) { 
     dy = -Math.abs(dy); 
    } 

    ball.setVelocity(dx, dy); 
} 


private void checkForCollisionWithPad(Ball ball) { 
    if (ball.intersectsArea(
      pad.getX(), pad.getY(), pad.getWidth(), pad.getHeight())) { 
     double dx = ball.getDx(); 
     // set dy negative, i.e. moving "up" 
     double newDy = -Math.abs(ball.getDy()); 
     ball.setVelocity(dx, newDy); 
    } 
} 
} 

Главная

import javafx.animation.AnimationTimer; 
import javafx.application.Application; 
import static javafx.application.Application.launch; 
import javafx.event.EventHandler; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.control.Alert; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 


public class Bounce extends Application { 

private World world; 

private Canvas canvas; 
private AnimationTimer timer; 

protected class BounceTimer extends AnimationTimer { 

    private long previousNs = 0; 


    @Override 
    public void handle(long nowNs) { 

     if (previousNs == 0) { 
      previousNs = nowNs; 
     } 


     world.move(nowNs - previousNs); 

     previousNs = nowNs; 


     GraphicsContext gc = canvas.getGraphicsContext2D(); 


     gc.setFill(Color.WHITESMOKE); 
     gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); 


     Rectangle pad = world.getPad(); 
     gc.setFill(Color.BLACK); 
     double x = pad.getX(), y = pad.getY(), 
       w = pad.getWidth(), h = pad.getHeight(); 
     gc.fillRoundRect(x, y, w, h, h, h); 


     for (Ball b : world.getBalls()) { 
      b.paint(gc); 
     } 



    } 
} 



@Override 
public void start(Stage stage) { 
    Group root = new Group(); 
    Scene scene = new Scene(root, 300, 300, Color.WHITESMOKE); 

    canvas = new Canvas(scene.getWidth(), scene.getHeight()); 
    root.getChildren().add(canvas); 

    stage.setTitle("Bounce"); 
    stage.setScene(scene); 
    stage.setResizable(false); 
    stage.sizeToScene(); 
    stage.show(); 

    world = new World(canvas.getWidth(), canvas.getHeight()); 

    timer = new BounceTimer(); 
    timer.start(); 

    canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, 
      new EventHandler<MouseEvent>() { 
       @Override 
       public void handle(MouseEvent me) { 
        world.setPadX(me.getX()); 
       } 
      }); 
} 


public static void main(String[] args) { 
    launch(args); 
} 

private void showAlert(String message) { 
    alert.setHeaderText(""); 
    alert.setTitle("Alert!"); 
    alert.setContentText(message); 
    alert.show(); 
} 

private final Alert alert = new Alert(Alert.AlertType.INFORMATION); 
} 

Бал

import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.paint.Color; 



public class Ball { 

public static final double BILLION = 1_000_000_000.0; 

private double x, y; // position of the balls center 
private double dx, dy; // velocity measured in pixels/second 
private double radius; 
private Color color; 




    public Ball(double x0, double y0) { 


    x = x0; 
    y = y0; 
    radius = 10; 
    color = Color.MAGENTA; 
} 


public Ball(double x0, double y0, double rad, Color col) { 


    x = x0; 
    y = y0; 
    radius = rad; 
    color = col; 

} 

Ball(int i, int i0, Color BLUEVIOLET) { 
    throw new UnsupportedOperationException("Not supported yet."); 
} 

    public void setColor(Color col) { // setColor 
    color = col; } 

public double getX() { 
    return x; 
} 


public double getY() { 
    return y; 
} 


public void setX(double newX) { 
    x = newX; 
} 


public void setY(double newY) { 
    y = newY; 
} 


public double getRadius() { 
    return radius; 
} 


public double getDx() { 
    return dx; 
} 


public double getDy() { 
    return dy; 
} 


public void setVelocity(double newDx, double newDy) { 
    dx = newDx; 
    dy = newDy; 
} 


public void moveTo(double newX, double newY) { 
    x = newX; 
    y = newY; 
} 



public void move(long elapsedTimeNs) { 
    x += dx * elapsedTimeNs/BILLION; 
    y += dy * elapsedTimeNs/BILLION; 
} 


public void paint(GraphicsContext gc) { 
    gc.setFill(color); 
    // arguments to fillOval: see the javadoc for GraphicsContext 
    gc.fillOval(x - radius, y - radius, radius * 2, radius * 2); 
} 


public boolean intersectsArea(
     double rectX, double rectY, 
     double rectWidth, double rectHeight) { 


    double closestX = clamp(x, rectX, rectX + rectWidth); 
    double closestY = clamp(y, rectY, rectY + rectHeight); 


    double distanceX = x - closestX; 
    double distanceY = y - closestY; 


    return (distanceX * distanceX) + (distanceY * distanceY) 
      < (radius * radius); 
} 


private double clamp(double value, double lower, double upper) { 
    if (value < lower) { 
     return lower; 
    } 
    if (value > upper) { 
     return upper; 
    } 
    return value; 
} 
} 
+1

В чем проблема? Я не вижу, чтобы вы пытались создать что-либо и не преуспели. Можете ли вы показать свою ** основную **? – Idos

+2

В вашем методе 'move' вы нацеливаете только один мяч. – Yass

+1

Я обновил основной код – elenagold

ответ

1

Как сказал Stormblessed, вы только против одного мяча в методе move. Вы должны сделать:

public void move(Ball ball, long elapsedTimeNs) { 
    ball.move(elapsedTimeNs); 
    constrainBall(ball); 
    checkForCollisionWithPad(ball); 
} 

Edit: Так как вы хотите, чтобы метод обработчик принимать только elapsedTimeNs аргумент, сделайте следующее:

public void move(long elapsedTimeNs) { 
    for (Ball ball : balls) { 
     ball.move(elapsedTimeNs); 
     constrainBall(ball); 
     checkForCollisionWithPad(ball); 
    } 
} 

Edit 2: Вы должны, вероятно, есть метод, который создает новый мяч для удобства:

public Ball newBall(double x, double y, double velocity1, double velocity2) { 
    Ball tmp = new Ball(x, y); 
    tmp.setVelocity(velocity1, velocity2); 
    balls.add(tmp); 
    return tmp; 
} 

Edit 3: причина он выдает ошибку, что вы назначены balls иметь место только один индекс с помощью balls = new Ball[]. Вы должны использовать ArrayList (java.util.ArrayList) вместо, например, так:

import java.util.ArrayList; 

ArrayList<Ball> balls = new ArrayList<>; 

Вы должны теперь использовать balls.add и balls.get вместо = и []. Соответственно, были обновлены ссылки.

+1

Не работает, дает мне ошибку в главном коде ... – elenagold

+0

Какая ошибка и в каком контексте? – Majora320

+1

В нем указано, что в основном методе обработки, который метод перемещения в Main не может быть обработан для заданных типов: требуется; ball, long найдено: long Причина: фактические и формальные списки аргументов различаются по длине – elenagold

Смежные вопросы