Java中2D游戏的曲线轨迹

Java中2D游戏的曲线轨迹,java,physics,game-physics,Java,Physics,Game Physics,我想用Java做一个游戏,我希望我的球有一个弯曲的轨迹,基于桨的加速度(不涉及重力)。如何计算给定时刻的球位?我想我需要先计算速度,但我不知道怎么做。旋转球的路径。 曲线轨迹?你的意思是当你击球时,你给球加上旋转,然后旋转使球在空中弯曲吗 如果是,则使用以下方法 球需要以下属性 ball = { x, // position x, y y, dx, // delta x and y dy, dr, // delta rotation radi

我想用Java做一个游戏,我希望我的球有一个弯曲的轨迹,基于桨的加速度(不涉及重力)。如何计算给定时刻的球位?我想我需要先计算速度,但我不知道怎么做。

旋转球的路径。 曲线轨迹?你的意思是当你击球时,你给球加上旋转,然后旋转使球在空中弯曲吗

如果是,则使用以下方法

球需要以下属性

ball =  {
    x,  // position x, y
    y,
    dx, // delta x and y
    dy,
    dr,  // delta rotation
    radius,  // balls radius
}
还有一只蝙蝠

bat = {
    top, // y pos of top of bat
    dx, // delta x (sideways speed
    // plus what ever else you have
}
当球击中球棒时,进行正常反射

ball.dy = -ball.dy;
ball.y = bat.top - ball.radius
假设球棒位于屏幕底部,将球棒的侧向移动转化为球的旋转只需要球的半径(对于最简单的方法而言)

旋转量与球相对于球棒的侧向运动有关,然后除以半径得到每帧旋转的变化。将其添加到球的当前旋转

ball.dr += (ball.dx - bat.dx) / ball.radius
我们不会做一个完整的流体动力学模拟,而是一个近似值

马格纳斯效应 当球在空中旋转时,球的一侧在气流中向前移动(外侧),另一侧在相反方向移动(内侧)。表面气流的不平衡以及内部旋转拉动空气的方式导致内部垂直于球运动方向的低压区域

这个低压区施加的力分布在球的直径上

Force = (airDensity * ballVelocity * Math.pow(2 * PI * ball.radius,2) * ball.dr ) / (2 * ball.radius)
我们不需要所有这些。空气密度与球半径一样固定。因此,力是球速度和球旋转速率之间的线性关系。其余的可以设置为一个系数值,我们称之为spinCof

力增加了加速度,加速度取决于质量。同样,这不会改变,因此我们可以将其添加到spinCof值中

所以最后的公式是

Acceleration = spinCof * ballVelocity * ball.dr;
spinCof的值未知,您需要进行实验以找到一个可播放的值

在代码中执行此操作

spinCof = ? some value 
var ballVelocity = Math.sqrt(ball.dx * ball.dx + ball.dy * ball.dy);
var nx = ball.dx / ballVelocity;  // get normalised vector of motion
var ny = ball.dy / ballVelocity;
var accel = spinCof * ballVelocity * ball.dr; // get the acceleration due to spin
ball.dx -= ny * accel;  // apply acceleration perpendicular to motion
ball.dy += nx * accel;  // 
就这样

这在实践中是一个很好的例子

var createImage=function(w,h){var i=document.createElement(“canvas”);i.width=w;i.height=h;i.ctx=i.getContext(“2d”);返回i;}
//创建画布并添加到DOM
var canvas=createImage(512200);
var ctx=canvas.ctx;
document.body.appendChild(画布);
var w=画布宽度;
var h=画布高度;
常数spinCof=0.01;
常数航空价格=0.001;
常数自旋摩擦=0.001;
变量球={
x:ctx.canvas.width*2,//启动屏幕
y:0,
dx:1,
dy:0,,
王:0,,
博士:0,
半径:30,
holdFrames:0,//发射球之前等待的时间
画(){
ctx.strokeStyle=“黑色”;
ctx.lineWidth=2;
setTransform(1,0,0,1,this.x,this.y);
ctx.rotate(this.ang);
ctx.beginPath();
ctx.moveTo(0,0);
弧(0,0,这个半径,0,数学π*2);
ctx.stroke();
setTransform(1,0,0,1,0,0);
}, 
更新(){
如果(this.holdFrames>0){
此值为1.holdFrames-=1;
this.ang+=this.dr;
}否则{
this.dx*=(1-空气摩擦);//由于空气而增加摩擦力
这是1.dy*=(1-航空价格);
this.dr*=(1-旋转摩擦力);//为球旋转添加摩擦力
var ballVelocity=Math.sqrt(this.dx*this.dx+this.dy*this.dy);
var nx=this.dx/ballVelocity;//获取归一化运动矢量
var ny=此.dy/球速;
var accel=spinCof*ballVelocity*this.dr;//获取由于旋转而产生的加速度
this.dx-=ny*accel;//应用垂直于运动的加速度
this.dy+=nx*加速度;//
this.x+=this.dx;
this.y+=this.dy;
this.ang+=this.dr;
如果(this.x>ctx.canvas.width+this.radius){//ball off canvas所以重置
this.dx=Math.random()*5+4;//设置随机x速度
这是0.dy=0;
this.dr=(Math.random()*0.5)*(Math.random()<0.5?-1:1);//设置随机自旋
这个.x=0;
这个.y=canvas.height/2;
此.holdFrames=60;
}
}
}
}
//主动画循环
函数mainLoop1(时间){
ctx.globalCompositeOperation=“目的地输出”;
ctx.globalAlpha=0.1;
ctx.fillRect(0,0,w,h);//清除da屏幕
ctx.globalCompositeOperation=“源代码结束”;
ctx.globalAlpha=1;
更新();
ball.draw();
requestAnimationFrame(mainLoop1);
}    
//启动动画

requestAnimationFrame(mainLoop1)