嗨,我最近尝试制作一个球类游戏,并为此找到了解决方案。所以我做了什么:在玩游戏时,桨在运动。我的坐标系保持不变,画布的左上角点是0,0。桨在此坐标系中移动。x轴从0指向画布宽度,y轴从0指向画布高度。我创建了一个固定大小为100的宽度和20的高度的桨。然后我在其周围绘制一个想象的圆圈。当球击中桨时,我会计算桨的中心点
double paddleCenter=Squash.paddle.getXpos()+Squash.paddle.getPaddleWidth()/2;
然后我从球的当前位置减去中心,这样坐标系将位于球拍的中心,ballCenter是球击中球拍的点(-(paddlewidth + r).. 0 ..(paddlewidth + r ))这不过是重新调整桨的击球点
double x0 = ballCenterX-paddleCenter;
借助球的击球点(x0)计算圆的相交点,这是一个重新计算,我们用已知的x0坐标求圆上的y坐标,并且需要翻转y轴
double y0 = -Math.sqrt(paddleRadius*paddleRadius-x0*x0);
计算半径为paddle的圆的正态方程的导数,圆的半径定义为paddleRadius f(x,y)= x ^ 2 + y ^ 2-r ^ 2
double normalX=2*x0;
double normalY=2*y0;
归一化N向量,以获得表面法线的单位向量
double normalizer=Math.sqrt(normalX*normalX + normalY*normalY);
normalX=normalX/normalizer;
normalY=normalY/normalizer;
现在我们有了桨的归一化(单位)表面法线。使用这些表面法线计算新方向,这将借助反射向量公式进行计算:new_direction = old_direction-2 * dot(N,old_direction)* N,但是如果表面法线始终指向上方,则法线将球击中桨的位置不断变化
double eta=2; //this is the constant which gives now perfect reflection but with different normal vectors, for now this set to 2, to give perfect reflection
double dotprod=vX*normalX+vY*normalY;
vX=vX-eta*dotprod*normalX;//compute the reflection and get the new direction on the x direction
vY=-vY;//y direction is remain the same (but inverted), as we just want to have a change in the x direction
我已经发布了针对该问题的解决方案。有关更多详细信息和完整游戏,请参见我的github存储库:
https://github.com/zoli333/BricksGame
用eclipse用Java编写。Ball.java中对此有另一种解决方案,其中不会发生重新缩放,我不将坐标坐标系移动到桨的中心点,而是从相对于左上角的0,0坐标系计算以上所有坐标桨的中心点。这也可以。