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

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

问题描述

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

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

public Ball(double x, double y, Game game) {超级(x,y);this.game=游戏;}公共无效滴答(){时间+=1.0/60.0;如果(x<=0)外部反射=1.0;否则 if(x>=Game.Width-15)外部反射=-1.0;如果(y<=0)yreflection=1.0;否则 if(y>=Game.Height-15)gameover=1;//这里的不同变量,因为如果球击中屏幕底部,我用它来结束游戏x+=traj.xvel()*xreflection;y-=traj.yvel(time)*yreflection;if(Physics.Collision(this, game.getP())) {时间=2;System.out.println("碰撞");yreflection=-1;}}

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

public double xvel() {double xvelo=initvel*Math.cos(Math.toRadians(theta));返回 xvelo;}公共双yvel(双倍时间){双 yvelo;yvelo=initvel*Math.sin(Math.toRadians(theta))-(9.8*time);返回伊维洛;}

并且我尝试使用带有 y 反射的 if 语句使 yreflection 为 1 时为 9.8,而当 yreflection 为 -1 时为正.

解决方案

你并没有真正在做反射......要通过长轴反射你应该否定速度向量的适当坐标(并纠正位置)我不在您的代码中看到这种行为.相反,无论向上/向下方向如何,您的 y 速度都没有符号,因此您只需向它添加重力 acc ......以补救要么重写代码,要么将 yreflection 添加到与重力相关的代码中.. 你还有 theta 吗?我只希望第一次拍摄的角度

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

    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

    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;
    
        }
    
    }
    

    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;
    }
    

    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.

    解决方案

    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

    see

    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;
        }
    //---------------------------------------------------------------------------
    

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

    This is how it look like:

    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天全站免登陆