我正在使用类似于弹跳窗口徽标屏幕保护程序的JavaFX创建弹跳球动画。我现在的代码很不错,但它只会以顺时针方式反弹球。这一般情况良好,但最终球会以逆时针方向旋转,在这种情况下它看起来不再真实。我试图找到一种计算球如何反弹的方法;在我看来,这真的归结为球的天使。我正在使用AnimationTimer
Translates
每个球的Bounds
球。当球的 class BallAnimation extends AnimationTimer{
private final Sphere ball;
private double movex = 0;
private double movey = 0;
private double xvariation = 0;
private double yvariation = 0;
private boolean right = true;
private boolean up = false;
private boolean changeColorRandomly = true;
private double rate = 1;
public BallAnimation(Sphere ball){
this.ball = ball;
ball.setLayoutX(200);
ball.setLayoutY(50);
}
public void handle(long now){
move(right,up);
Bounds ballBounds = ball.localToScene(ball.getBoundsInLocal());
if(ballBounds.intersects(rightWall.getBoundsInParent())){
calculateMotion(rightWall);
randomBounceAngle();
setRandomColor();
}
if(ballBounds.intersects(leftWall.getBoundsInParent())){
calculateMotion(leftWall);
randomBounceAngle();
setRandomColor();
}
if(ballBounds.intersects(ceiling.getBoundsInParent())){
calculateMotion(ceiling);
randomBounceAngle();
setRandomColor();
}
if(ballBounds.intersects(floor.getBoundsInParent())){
calculateMotion(floor);
randomBounceAngle();
setRandomColor();
}
}
private void calculateMotion(Line touchedWall){
if(touchedWall.equals(rightWall)){
right = false;
up = false;
}
if(touchedWall.equals(leftWall)){
right = true;
up = true;
}
if(touchedWall.equals(ceiling)){
right = true;
up = false;
}
if(touchedWall.equals(floor)){
right = false;
up = true;
}
}
public void move(boolean right, boolean up){
if(right && !up){
ball.setTranslateX((movex += (getRate() + xvariation)));
ball.setTranslateY((movey += (getRate() + yvariation)));
}
if(right && up){
ball.setTranslateX((movex += (getRate() + xvariation)));
ball.setTranslateY((movey -= (getRate() + yvariation)));
}
if(!right && up){
ball.setTranslateX((movex -= (getRate() + xvariation)));
ball.setTranslateY((movey -= (getRate() + yvariation)));
}
if(!right && !up){
ball.setTranslateX((movex -= (getRate() + xvariation)));
ball.setTranslateY((movey += (getRate() + yvariation)));
}
System.out.println("("+movex+", "+movey+")");
}
public double getRate(){
return rate;
}
public void setRate(double rate){
this.rate = rate;
}
public void randomBounceAngle(){
double ran = Math.random();
if(ran >= .50){
//shallow bounce angle
xvariation = 3;
yvariation = 2;
}else{
//sharp bounce angle
xvariation = 2;
yvariation = 3;
}
}
遇到边界时,翻译方向改变了,在这次会议上我需要一个建议......
BallAnimation是一个内部阶级。
login.SuccessfulLogin(testdata);
login.clickLink(By.xpath(testdata.getParam("MenuLocator")));
login.WaitForElementVisibilty(By.xpath(testdata.getParam("loginLocator")));
login.compareValue(testcase, "", expectedResultMap.get("MenuLoginTxt"),
driver.findElement(By.xpath(testData.getParam("loginLocator"))).getText());
// here should enter the code to close the menu!
log.info("User Logged in Successfully");
......问题是当球击中右边界时它会向下弹跳并向下弹跳,底部会向上弹跳并向左,向左和向右,向上和向下:向上和向下弹跳。这在大多数情况下都很好,但有时它需要以反方式反弹。
答案 0 :(得分:2)
嗯,在完美物理世界中,角度等于出角度。如果使用x / y轴,则对于x轴的反射,否定球的速度的y分量。对于偏离y轴的反射,否定球的速度的x分量。
我在javascript中使用图层重新编写了pong,并检测了用于控制桨的键盘敲击(这是在'00或'01中使用Netscape 4.7x)。我作弊,并设置了向8个方向移动球的功能。如果球沿着轴(直线左/右或上/下)行进,则快速随机数提供不同的反弹。否则,以相同的角度反弹。
答案 1 :(得分:1)
这是一个反射法线周围向量的函数。它可用于创建反弹,通过反射球在球反弹的墙壁的法线(或另一个物体侧面的法线)周围的球的速度矢量。
private Point2D reflect(Point2D vector, Point2D normal) {
return vector.subtract(normal.multiply(vector.dotProduct(normal) * 2));
}
它是我根据 sample breakout game 中的示例代码创建的 this question 实现的一部分。
为基于向量的反射显示的代码使用了此问题的答案中提供的公式,该公式直接转换为 JavaFX 类:
请注意,如果您搜索,有许多数学教程和 Stackoverflow 问题都在讨论执行反射的函数和方法。
在突破游戏中,球从墙壁或砖块等垂直或水平表面反弹的特殊情况是,球反弹的线平行于坐标系的 x 轴和 y 轴,因此反弹可以通过否定速度向量的 x 或 y 值来执行。如果您希望使用这种简化,请参阅 example code in this question 或其他有关反思的问题的答案。
if (topWall) {
dy = dy * -1;
}
if (leftWall || rightWall) {
dx = dx * -1;
}
if(bottomWall) {
dy = dy * -1;
}