我们有一个问题,就是Circle位置变为负数(假设它是相对的,因此这是有道理的),但是,我假设CenterX / Y将始终基于其在场景中的当前位置(JavaFX)。但是,每当我为此添加一个侦听器时,圆圈就会被放置在无效的位置。即使有几行设置它的位置并以相同的方式更新它,我已经听了它的X和Y属性(请注意,我已经将这些内容注释掉了)
Ball.java代码:
弹跳方法:
/**
* 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,则用户丢了一个球 * / @Override 公共无效更新(双deltaTime) { 如果(是秋天) 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] 线距:52.9675209999059 X-X:0.0,Y-X:19095.45300000002 X-Y:-775.0,Y-Y:17460.445000000018调试时间:0.03929486679040967 经过的时间:X-X:0.0,Y-X:19095.45300000002 X-Y:-775.0,Y-Y: 18310.52600000002 Y阈值以下:-848.2400000000009 [Ball:X = 0.0,Y = -850.0830000000009; CenterX = 0.0,CenterY = -850.0830000000009; SpeedX = 0.0SpeedY:-1.8430000000000015] 到线的距离:54.2459571676045 X-X:0.0,Y-X:19943.69300000002 X-Y:-775.0,Y-Y:18310.52600000002调试时间:0.04134649528251092 经过的时间:X-X:0.0,Y-X:19943.69300000002 X-Y:-775.0,Y-Y: 19162.45200000002 Y阈值以下:-850.0830000000009
因此,从本质上讲,我们认为我们当前的碰撞检测问题可能是由于我们基于Ball的X / Y坐标进行检测。我认为这些是相对于Circle最初创建的位置而言的,因为它的坐标会很快变为负值,这使得碰撞处理变得如此困难。
我们认为也许使用绑定到CenterX / Y而不是X / YProperty可以解决我们的问题。但是,如果执行此操作(即使在注释先前的代码设置X / Y时也是如此),则会使圆的位置位于最左上角。即使以后手动设置位置,它仍然会出错。
有人经历过相同的事情或知道可能的解决方案吗?我们知道,我们可以重组我们的班级(例如,将更多此类内容放入主班级),以轻松解决此问题。但是,我们需要一个面向对象的结构,并且没有采取捷径。作为参考,下面是我们当前软件包设置的图片:提出建议!