【问题标题】:Can't flip direction of ball without messing up gravity在不破坏重力的情况下无法翻转球的方向
【发布时间】:2019-05-06 02:44:50
【问题描述】:

我正在制作一个类似于乒乓球的游戏,只是只有一个球拍并且球以弹丸运动方式移动。目标是尽可能长时间地让球在你的桨上弹跳。当我让球击中桨时,速度的 y 分量的方向的符号翻转了。这样做的问题是,当球向上移动时,重力会朝那个方向起作用,使其加速。代码如下

这是我的球类的代码,这是每秒调用 60 次的 tick 方法

public Ball(double x, double y, Game game) {
    super(x,y);
    this.game=game;
}
public void tick() {
        time+=1.0/60.0;
        if(x<=0)
            xreflection=1.0;
        else if(x>=Game.Width-15)
            xreflection=-1.0;
        if(y<=0)
            yreflection=1.0;
        else if(y>=Game.Height-15)
            gameover=1;//different variable here as I use this to end the game if the ball hits the bottom of the screen
    x+=traj.xvel()*xreflection;
    y-=traj.yvel(time)*yreflection;

    if(Physics.Collision(this, game.getP())) {
    time=2;
        System.out.println("Collision");
        yreflection=-1;

    }

}

这是我的球轨迹类,它处理所有的数学

public double xvel() {
    double xvelo=initvel*Math.cos(Math.toRadians(theta));
    return xvelo;
}

public double yvel(double time) {
    double yvelo;
        yvelo=initvel*Math.sin(Math.toRadians(theta))-(9.8*time);
    return yvelo;
}

我尝试使用带有 y 反射的 if 语句,当 yreflection 为 1 时使 9.8 为负数,当它为 -1 时为正数。

【问题讨论】:

  • 我不知道如何重写代码来做到这一点...我尝试将重力与速度计算分开添加,并在添加重力之前将速度的符号翻转到适当的方向这打破了我的碰撞检测
  • 当我尝试使用弹跳球示例中的模型重写我的代码时,我的球移动得非常快,但它不起作用
  • 不管我做什么这都行不通我已经尝试过调整一切
  • 我只是想通了,问题是双重碰撞而不是数学。我只需要在碰撞后将球向上移动球的距离即可避免这种情况。感谢您的帮助,很抱歉打扰
  • 我将 cmets 移动到带有摩擦的小 C++ 示例中

标签: java graphics physics game-development


【解决方案1】:

您并没有真正进行反射...要通过主轴进行反射,您应该否定速度矢量的适当坐标(并更正位置)我在您的代码中看不到这种行为。相反,无论向上/向下的方向如何,您的 y 速度都没有符号,因此您只需为其添加重力 ... ?我只希望在第一次拍摄时有角度

这里是带有空气摩擦的小 C++ 示例:

//---------------------------------------------------------------------------
double pos[2],vel[2],acc[3],r;  // ball
double x0,y0,x1,y1;             // walls
//---------------------------------------------------------------------------
void ball_update(double dt)
    {
    int i;
    double v,k=0.0001,g=9.81;
    dt*=10.0;                                   // time multiplier for simulation speed ...
    // compute driving force/acceleration
    v=sqrt((vel[0]*vel[0])+(vel[1]*vel[1]));    // |vel|
    acc[0]=  -(k*vel[0]*v);                     // gravity + air friction (k*vel^2)
    acc[1]=+g-(k*vel[1]*v);
    // Newton/D'Alembert simulation
    for (i=0;i<2;i++) vel[i]+=acc[i]*dt;
    for (i=0;i<2;i++) pos[i]+=vel[i]*dt;
    // colision/reflect
    if (pos[0]<x0+r){ pos[0]=x0+r; vel[0]=-vel[0]; }
    if (pos[0]>x1-r){ pos[0]=x1-r; vel[0]=-vel[0]; }
    if (pos[1]<y0+r){ pos[1]=y0+r; vel[1]=-vel[1]; }
    if (pos[1]>y1-r){ pos[1]=y1-r; vel[1]=-vel[1]; }
    }
//---------------------------------------------------------------------------
void ball_init()
    {
    Randomize();
    pos[0]=0.5*(x0+x1);
    pos[1]=0.5*(y0+y1);
    double a=2.0*M_PI*Random(),v=50.0;
    vel[0]=v*cos(a);
    vel[1]=v*sin(a);
    r=20.0;
    }
//---------------------------------------------------------------------------

我的坐标系是(0,0)在左上角,x指向右,y指向下... 要使用它,只需初始化墙壁x0,y0,x1,y1 调用ball_init(),然后在一些计时器中调用ball_update(dt) 并在pos 和半径r 处渲染球...

这就是它的样子:

PS.您需要调整参数,如增量时间dt、加速度或添加像素比例以满足您的需求...您需要所有单位兼容...我建议使用SI (m,m/s,m/s^2,s,N,.. ) 所以你还需要确定像素有多大(以米为单位)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 2010-11-04
    相关资源
    最近更新 更多