У нас есть проблема с тем, что позиция Круга становится отрицательной (если она относительна, так что это имеет смысл), однако я предполагаю, что CenterX / Y всегда будет основываться на его текущем местоположении на сцене (JavaFX).Однако всякий раз, когда я добавляю слушателя для этого, круг помещается в недопустимом месте.Даже когда несколько строк устанавливают его положение и обновляют его одинаково, я уже слушаю его свойства X и Y (заметьте, я прокомментировал эти вещи)
Код Ball.java:
метод bounce:
/**
* To be documented
* @param Vector
* @param Vector
*/
public void bounce(Vector y, Vector x)
{
// Get vector between two points of the side
dest = new Vector(y.getX() - x.getX(), y.getY() - x.getY());
Vector n1 = new Vector(-dest.getY(), dest.getX());
n1 = n1.getUnitVector();
Vector yCopy = new Vector(y.getX(), y.getY());
// Vector between pall and a point
dest = new Vector(y.getX(), y.getY());
dest.setX(dest.getX() - this.getX());
dest.setY(dest.getY() - this.getY());
double distanceToLine = dest.getDotProduct(n1);
System.out.println("Distance toline: " + distanceToLine);
if (distanceToLine > Constants.BALL_RADIUS || distanceToLine + Constants.BALL_RADIUS < Constants.BALL_RADIUS)
{
System.out.println("X-X: " + x.getX() + ", Y-X: " + y.getX() + " X-Y: " + x.getY() + ", Y-Y: " + y.getY());
Vector nextLocation = new Vector(this.getCenterY(), this.getCenterY());
Vector speed = new Vector(this.speedX, this.speedY);
nextLocation.add(speed);
// Distance from next location to the side
y.subtract(nextLocation);
dest = new Vector(y.getX(), y.getY());
double nextDistToLine = dest.getDotProduct(n1);
double time = (Constants.BALL_RADIUS - distanceToLine) / (nextDistToLine - distanceToLine);
// If the ball will be next to line within update
System.out.println("Debug time: "+ time);
if (time > 0 && time <= 1000)
{
Vector moveToLine = new Vector(this.goalSpeedX, this.goalSpeedY);
moveToLine.multiply(time);
moveToLine.add(new Vector(this.getCenterX(), this.getCenterY()));
System.out.println("Time passed: X-X: " + x.getX() + ", Y-X: " + yCopy.getX() + " X-Y: " + x.getY() + ", Y-Y: " + y.getY());
if (x.getX() == yCopy.getX())
{
System.out.println("XX CONFIRMED: XX : " + x.getX() + " YX: " + y.getX());
if (moveToLine.getY() >= x.getY() - Constants.BALL_RADIUS && moveToLine.getY() <= y.getY() + Constants.BALL_RADIUS || (moveToLine.getY() >= y.getY() - Constants.BALL_RADIUS && moveToLine.getY() <= x.getY() + Constants.BALL_RADIUS))
{
System.out.println("Move2Line-Y: " + moveToLine.getY() + " ");
this.add(moveToLine.getX(), moveToLine.getY());
this.goalSpeedX = -this.goalSpeedX;
System.out.println("Bounce: moveToLine: getY() - Y");
}
}
else if (x.getY() == yCopy.getY())
{
System.out.println("YY CONFIRMED: XX : " + x.getX() + " YX: " + yCopy.getX());
if (moveToLine.getX() > x.getX() - Constants.BALL_RADIUS && moveToLine.getX() < y.getX() + Constants.BALL_RADIUS || (moveToLine.getX() > y.getX() - Constants.BALL_RADIUS && moveToLine.getX() < x.getX() + Constants.BALL_RADIUS))
{
this.add(moveToLine.getX(), moveToLine.getY());
this.goalSpeedX = -this.goalSpeedX;
System.out.println("Bounce: moveToLine: getX() - X");
}
}
}
}
}
/ ** * Унаследовано от суперкласса (GameObject) для вызова в GameLoop * @param deltaTime Время дельты в миллисекундах с момента последнего обновления * @TODO: если координата Y ниже 0, пользователь потерялball * / @Override публичное обновление void (double deltaTime) {if (isFalling) this.speedY + = Constants.BALL_GRAVITY;
this.speedY += approach(this.goalSpeedY, this.speedY, deltaTime * 30);
this.speedX += approach(this.goalSpeedX, this.speedX, deltaTime * 30);
add(Math.min(Constants.MAX_BALL_SPEED, this.speedX), Math.min(Constants.MAX_BALL_SPEED, this.speedY));
this.centerX.set(getCenterX() + Math.min(Constants.MAX_BALL_SPEED, this.speedX));
this.centerY.set(getCenterY() + Math.min(Constants.MAX_BALL_SPEED, this.speedY));
System.out.println(this.toString());
if (this.getCenterX() > Constants.VECTOR_TOP_RIGHT.getX())
{
bounce(Constants.VECTOR_TOP_RIGHT, Constants.VECTOR_BOT_RIGHT);
System.out.println("Over X treshold: " + this.getX());
}
else if (this.getCenterX() < Constants.VECTOR_TOP_LEFT.getX())
{
bounce(Constants.VECTOR_BOT_LEFT, Constants.VECTOR_TOP_LEFT);
System.out.println("Under X treshold: " + this.getX());
}
else if (this.getCenterY() > Constants.VECTOR_TOP_RIGHT.getY())
{
bounce(Constants.VECTOR_TOP_LEFT, Constants.VECTOR_TOP_RIGHT);
System.out.println("Crossed Y treshold: " + this.getY());
}
else if (this.getCenterY() < Constants.VECTOR_BOT_LEFT.getY())
{
bounce(Constants.VECTOR_BOT_RIGHT, Constants.VECTOR_BOT_LEFT);
System.out.println("Below Y treshold: " + this.getY());
}
}
Другой класс (GameHandler, но таймер определенно работает, и у нас естьотладка в течение нескольких часов)
/**
* Called by AnimationTimer in GameLoop
* @param time Milliseconds since last update
*/
public void update(double deltaTime) {
if (this.state == GameState.PLAYING) {
//System.out.println("GameLoop: Update time: " + deltaTime + " ms");
this.ball.update(deltaTime);
for(Wall wall : walls)
{
wall.update(deltaTime);
}
}
}
/** This breaks the Circle class for some reason?
*balltest.centerXProperty().bind(gameHandler.getBall().getCenterXProperty());
*balltest.centerYProperty().bind(gameHandler.getBall().getCenterYProperty());
*/
Результаты отладки:
[Ball: X = 0.0, Y = -848.2400000000009; CenterX = 0.0, CenterY = -848.2400000000009; SpeedX = 0.0SpeedY: -1.8410000000000015] Расстояние Toline: 52.9675209999059 XX: 0.0, YX: 19095.45300000002 XY: -775.0, YY: 17460.445000000018 Время отладки: 0.03929486679040967 Время прошло: XX: 0.0, YX: 19095.45300000002 XY: YY: -Y18310,52600000002 Ниже Y Treshold: -848,2400000000009 [Бал: Х = 0.0, Y = -850,0830000000009; CenterX = 0,0, CenterY = -850,0830000000009; SpeedX = 0.0SpeedY: -1,8430000000000015] Расстояние toline: +54,2459571676045 XX: 0,0, YX: 19943,69300000002 XY: -775.0, YY: 18310.52600000002 Время отладки: 0.04134649528251092 Пройденное время: XX: 0.0, YX: 19943.69300000002 XY: -775.0, YY: 19162.45200000002 Ниже порога Y: -850.0830000000009
* 1019проблемы обнаружения могут быть связаны с тем фактом, что мы основываем наше обнаружение на координатах X / Y шара.Я думаю, что они относительно того, где изначально был создан Круг, потому что его координаты могут быстро стать отрицательными, что усложняет обработку столкновений.
Мы думали, что, возможно, использование привязки к CenterX / Y вместо X / YProperty решит нашпроблемы.Однако, если мы сделаем это (даже комментируя предыдущий код, установив X / Y), он сделает круг в верхнем левом углу.Даже если впоследствии мы вручную установим его положение, оно все равно прослушивается.
Кто-нибудь испытывал то же самое или знал о возможном решении?Мы знаем, что мы можем реструктурировать наши классы (например, помещая больше этих вещей в основной класс), чтобы облегчить решение этой проблемы.Однако нам нужна объектно-ориентированная структура, и мы не будем использовать ярлыки.Для справки, вот изображение нашей текущей настройки пакета: Предложения приветствуются!