简体   繁体   English

Function 无法随机检测事件

[英]Function fails to detect event at random times

I have these functions:我有这些功能:

void apply_gravity(double delta){
    velocity.y+=9.8*100*delta;
}

void move_body(double delta){
    location.x+=velocity.x*delta;
    location.y+=velocity.y*delta;
}

void processPhysics(double delta){
    apply_gravity(delta);
    move_body(delta);
    if(location.y>=SCREENY){
        velocity.y=-coefficient_of_restitution*velocity.y;
    }
}

delta is the time elapsed between two calls to the function. velocity contains two parts, x and y which represent the increment per second to the location's x and y. delta 是两次调用 function 之间经过的时间。velocity 包含两部分,x 和 y,表示位置的 x 和 y 的每秒增量。 coefficient of restitution represents how much of the original velocity the body retains after collision.恢复系数表示物体在碰撞后保留了多少原始速度。

Basically, here is what I want this code to do:基本上,这是我希望此代码执行的操作:
Accelerate downwards by 9.8*100px per second.以每秒 9.8*100px 的速度向下加速。 When the body goes below a limit (SCREENY px), it should bounce back, just like if it is hitting a floor.当身体低于限制(SCREENY px)时,它应该反弹回来,就像它撞到地板一样。 The collision should be perfectly elastic, and for now, SCREENY does not vary at all.碰撞应该是完全弹性的,现在,SCREENY 根本没有变化。

The code perfectly works for most of the times.该代码在大多数情况下都能完美运行。 BUT, sometimes, instead of "bouncing", the body just passes through the "floor".但是,有时候,身体不是“弹跳”,而是只是穿过“地板”。 Basically, it seems that velocity.y does NOT negate even when the body crosses SCREENY.基本上,即使身体穿过 SCREENY,velocity.y 似乎也不会否定。 The comparision (location.y>=SCREENY) just fails at random times.比较 (location.y>=SCREENY) 只是随机失败。 Sometimes it works, sometimes it doesn't.有时有效,有时无效。

That should not happen.那不应该发生。

What is going wrong here?这里出了什么问题?

Your object is still allowed to pass through the floor, only updating the velocity.你的 object 仍然被允许穿过地板,只是更新速度。 However, in the next frame, the object may still be in the floor, and have its velocity negated a second time (and third, and fourth).然而,在下一帧中,object 可能仍在地板上,并且其速度第二次(以及第三次和第四次)无效。 I imagine it would look like it gets stuck and vibrates a bit of a distance within the wall.我想它看起来会被卡住并在墙内振动一段距离。 If the object is within the wall, you should instead calculate where it should be if it had bounced, and update the position AND velocity accordingly.如果 object 在墙内,您应该计算它在反弹时应该在的位置,并相应地更新 position 和速度。 Not just the velocity.不仅仅是速度。

A possible solution could look like:可能的解决方案如下所示:

void apply_gravity(double delta){
    velocity.y += 9.8 * 100 * delta;
}

void move_body(double delta){
    location.x += velocity.x * delta;
    location.y += velocity.y * delta;
}

void processPhysics(double delta){
    apply_gravity(delta);
    move_body(delta);
    if(location.y > SCREENY) // change to > from >= (eliminates edge case)
    {
        location.y = SCREENY - coefficient_of_restitution * (location.y - SCREENY); // update position as well, accounting for loss of velocity due to bounce
        velocity.y = -coefficient_of_restitution * velocity.y;
    }
}

The above solution will yield an error if the object is moving greater than one screen length in a single physics tic, so be careful about high speeds.如果 object 在单个物理抽动中移动超过一个屏幕长度,上述解决方案将产生错误,因此请注意高速。 You'll need a slightly more complicated algorithm to handle those situations.您需要稍微复杂一些的算法来处理这些情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM