不能在不弄乱重力的情况下翻转球的方向 [英] Can't flip direction of ball without messing up gravity

查看:121
本文介绍了不能在不弄乱重力的情况下翻转球的方向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个像乒乓球的游戏,除了只有一个球拍并且球以弹丸运动而运动.目的是使球尽可能长时间地在桨上弹跳.当我将球击中桨时,速度的y分量的方向将其符号翻转.这样做的问题是,当球向上运动时,重力会沿该方向作用,使球加速.代码在下面

I am making a game like pong except that there is only one paddle and the ball moves in projectile motion. The goal is to keep the ball bouncing on your paddle for as long as possible. I when I have the ball hit the paddle the direction of the y component of the velocity has it's sign flipped. The issue with this is that when the ball is moving up gravity acts upon in in that direction, speeding it up. The code is below

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

This is the code for my ball class, this is the tick method which is called 60 times a second

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;

    }

}

这是我的Ball Trajectory类,它处理所有与此相关的数学运算

This is my ball Trajectory class which handles all the math for this

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为-1时为正.

And I have tried to use an if statement with y reflection to make 9.8 negative when yreflection is 1 and positive when it is -1.

推荐答案

您并不是真正在做反射...要通过长轴进行反射,您应该否定速度矢量的适当坐标(并校正位置),但我没有在您的代码中看到这种行为.取而代之的是,无论向上/向下的方向如何,您的y速度都没有任何符号,因此您只需向其添加重力acc即可以纠正代码或将yreflection添加到与重力相关的代码中...也可以获得theta ?我只希望在第一次射击时能有角度

you are not really doing reflection ... to reflect by major axis you should negate the appropriate coordinate of the speed vector (and correct the position) I do not see such behavior in your code. Instead your y velocity has no sign regardless of the direction up/down hence you just add gravity acc to it ... to remedy either rewrite the code or add the yreflection to your gravity related code too... also you got theta? I would expect angle only in the first shooting

请参见

您只使用/添加您想使用的力量. 但是在碰撞中,一旦检测到您在墙壁内,您也需要校正位置以及反射速度;否则,您可能会遇到两次碰撞 ...

You just use/add forces you want to use. But in your collision once you detect you are inside wall you need to correct the position along with the reflection of speed too otherwise you risk double collisions ...

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

Here small C++ example with air friction:

//---------------------------------------------------------------------------
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 ...

My coordinate system is (0,0) is top left and x point right and y points down ... To use this just init the walls x0,y0,x1,y1 call the ball_init() and then in some timer call ball_update(dt) and render ball at pos and radius r ...

它是这样的:

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

PS. You need to tweak the parameters like delta time dt, accelerations or add pixel scale to match your needs... You need to have all units compatible ... I recommend using SI (m,m/s,m/s^2,s,N,.. ) so you also need to decide how big is pixel (in meters)

这篇关于不能在不弄乱重力的情况下翻转球的方向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆