简体   繁体   English

带角度的爆发式桨叶碰撞

[英]Breakout paddle collision with angle

I know there's so many stuff on the internet about this, and I have looked at quite a lot of it, but I just can't get it to work with my code. 我知道互联网上有很多关于此的东西,我已经看了很多,但是我无法使其与我的代码一起使用。 I kinda know the maths behind it, but again struggling to get it into code. 我有点了解它背后的数学原理,但是再次努力将其纳入代码中。 I have 2 speed variables for the ball float xSpeed, ySpeed . 我有2个速度变量,用于float xSpeed, ySpeed Both are equal to 3 (or -3 depending on collision - I just have basic collision atm). 两者都等于3(或-3取决于碰撞-我只有基本的碰撞atm)。 I'm also using a rectangle for ball ballRect as well as the paddle paddleRect . 我还为ball ballRect和paddle paddleRect使用了一个矩形。 I'm updating the position as so: 我正在这样更新职位:

ballRect.X += xSpeed; ballRect.Y += ySpeed;

I've found bits of code, and tried doing it myself, but they just were really buggy. 我已经找到了一些代码,并尝试自己做,但是它们确实是越野车。 One would (I think) work on the first hit, but when it came to the next hit it would stick to the paddle. (我认为)第一个击中将起作用,但是当涉及下一个击时,它将粘在桨上。

double relativeBallPos = (paddleRect.X + ballRect.X);
        double ballVelx = xSpeed;
        double ballVely = ySpeed;

        double angleRads = Math.Tan((ballVelx / relativeBallPos));
        double angleInDeg = angleRads * (180 / Math.PI);
        double angleOfReflection = (angleInDeg * 2);

        ballVelx = ballVelx * angleOfReflection;


        if (ballRect.X + (ballRect.Width / 2) < paddleRect.X + (paddleRect.Width / 2))
        {
            xSpeed = (float)-ballVelx;
        }
        else if (ballRect.X + (ballRect.Width / 2) > paddleRect.X + (paddleRect.Width / 2))
        {
            xSpeed = (float)ballVelx;
        }

(This goes off at a (probably incorrect) angle and just goes straight up after the first hit) Thanks for any help :) (这会以(可能不正确的)角度倾斜,并且在第一次打击后会一直向上倾斜)感谢您的帮助:)

If your ball intersects any horizontal threshold (the horizontal sides of the bricks, or of the paddle), negate ySpeed . 如果您的球与任何水平阈值(砖块或球拍的水平边) ySpeed ,请否定ySpeed If it intersects any vertical threshold, negate xSpeed . 如果它与任何垂直阈值相交,则取xSpeed There, now you have a functional breakout game. 在那里,现在您有了功能突破游戏。

You can add a bit more polish by changing the angle of the ball when it hits the paddle based on the position of the collision along it, with center being a full reflect (ie negate ySpeed ) and xSpeed getting a factor of the distance (positive or negative) of the distance from the center. 您可以根据碰撞沿球的位置来改变球在击中球时的角度,从而增加一点抛光效果,其中中心为ySpeed (即ySpeedySpeed ), xSpeed为距离的正数(正)或负数)到中心的距离。

Yes, what you are seeing is completely normal, if your objects are moving very fast and game tick speed is slow, you may have glitches like sticking to the paddle or even missing the paddle completely, and just going straight through. 是的,您所看到的完全是正常现象,如果您的物体移动得非常快而游戏滴答速度很慢,则您可能会遇到一些小故障,例如粘在桨上,甚至完全错过了桨,然后一直直走。

The solution to missing the paddle is increase game tick speed, ie process game moves more frequently. 解决缺少桨的方法是提高游戏的滴答速度,即过程游戏的移动更加频繁。

Ball to paddle stickiness can be alleviated by doing a roll back of object movement in time. 可以通过及时回滚物体运动来减轻球对桨的粘性。 For example you have objects A and B, which are colliding at some point in time. 例如,您有对象A和B在某个时间点碰撞。 If you simply reverse their X and Y speeds, you may end up with colliding again in the next point in time, so you would then reverse their speeds again, and so on, which appears as though it's stuck. 如果简单地反转它们的X和Y速度,则可能在下一个时间点再次发生碰撞,因此您将再次反转它们的速度,依此类推,好像卡住了。 It can sometimes get stuck on one only axis, so it will slide on the paddle, and then go straight down, which is just another side effect of the same issue. 有时它可能卡在一个轴上,因此它将在桨上滑动,然后笔直向下,这只是同一问题的另一个副作用。

How to do a roll back? 如何回滚? You know where A is moving, and suppose B is a paddle, so it's static. 您知道A在哪里移动,并且假设B是一个桨,所以它是静态的。 You know that A is colliding with B at the moment. 您知道A目前正在与B碰撞。 You can calculate a vector of A's movement and slide A back in time through that vector reversed. 您可以计算A的运动向量,然后将A反向移动到那个向量上。 For example, if top left corner of the screen is (0,0) , and A was moving at the speed of X=+10,Y=+10 , you would move it back by whole or fraction of the step (depends on how complex you want to go with this), so by (-10,-10) or fraction thereof. 例如,如果屏幕的左上角是(0,0) ,并且A以X=+10,Y=+10的速度移动,则可以将其向后移动整个步长或小数步(取决于的复杂程度),因此乘以(-10,-10)或其中的一部分。 You can use intersection rectangle to calculate precise values, and only move enough so the objects are barely touching. 您可以使用相交矩形来计算精确值,并且只能移动足够远,以使对象几乎不接触。

Ideally, you would reflect the vector off the hit surface (use physics, ie hit angle = reflect angle) and before applying new speeds, move your ball in a way that it does not collide with paddle. 理想情况下,您将向量从击球表面反射(使用物理方法,即击球角=反射角),并在应用新速度之前,以不与球拍碰撞的方式移动球。 To simplify, you can assume your hit surface is horizontal and is just a straight line, so your reflection formula is very simple. 为简化起见,您可以假设击球表面是水平的并且只是一条直线,因此反射公式非常简单。

This topic is well covered here (although using XNA, same principle applies): 这里很好地涵盖了该主题(尽管使用XNA,但原理相同):

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

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