Canvas 圆圈碰撞,圆圈碰撞后应该移动到哪里?

Canvas circle collision, how to work out where circles should move to once collided?

我正在尝试在 html canvas 中构建游戏。这是一款空中曲棍球游戏,我已经玩得很远了。游戏中一共有三个圆圈,被击中的圆盘和两个控制器(用来击中disc/circle)。

我让圆盘从墙上反弹回来,并且有一个功能可以检测圆盘何时与控制器发生碰撞。我遇到的问题是当两个圆圈发生碰撞时,控制器应该保持静止并且圆盘应该朝正确的方向移动。我已经阅读了很多文章,但仍然无法正确理解。

这是一个 Codepen link 我目前的进度。您可以看到冰球从控制器上弹回,但方向不正确。您还会看到冰球是否来自它穿过它的控制器后面。 http://codepen.io/allanpope/pen/a01ddb29cbdecef58197c2e829993284?editors=001

我想我追求的是弹性碰撞,但不确定如何解决。我找到了这篇文章,但无法使其正常工作。

http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769

这是我的碰撞检测函数。 Self refer's to the disc and controller[i] 是光盘命中的控制器。

this.discCollision = function() {

        for (var i = 0; i < controllers.length; i++) {
                // Minus the x pos of one disc from the x pos of the other disc
                var distanceX = self.x - controllers[i].x,
                        // Minus the y pos of one disc from the y pos of the other disc
                        distanceY = self.y - controllers[i].y,
                        // Multiply each of the distances by itself
                        // Squareroot that number, which gives you the distance between the two disc's
                        distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY),
                        // Added the two disc radius together
                        addedRadius = self.radius + controllers[i].radius;


                // Check to see if the distance between the two circles is smaller than the added radius
                // If it is then we know the circles are overlapping
                if (distance <= addedRadius) {

                    var newVelocityX = (self.velocityX * (self.mass - controllers[i].mass) + (2 * controllers[i].mass * controllers[i].velocityX)) / (self.mass + controllers[i].mass);
                    var newVelocityY = (self.velocityY * (self.mass - controllers[i].mass) + (2 * controllers[i].mass * controllers[i].velocityX)) / (self.mass + controllers[i].mass);

                    self.velocityX = newVelocityX;
                    self.velocityY = newVelocityY;

                    self.x = self.x + newVelocityX;
                    self.y = self.y + newVelocityY; 

                } 
            }   

    }

已更新

解构了一个圆形碰撞演示并尝试实现他们的碰撞公式。这是下面的,用于向前和向下击打 puck/disc 但由于某种原因不会向后或向上击打。

this.discCollision = function() {

            for (var i = 0; i < controllers.length; i++) {
                    // Minus the x pos of one disc from the x pos of the other disc
                    var distanceX = self.x - controllers[i].x,
                            // Minus the y pos of one disc from the y pos of the other disc
                            distanceY = self.y - controllers[i].y,
                            // Multiply each of the distances by itself
                            // Squareroot that number, which gives you the distance between the two disc's
                            distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY),
                            // Added the two disc radius together
                            addedRadius = self.radius + controllers[i].radius;

                    // Check to see if the distance between the two circles is smaller than the added radius
                    // If it is then we know the circles are overlapping                                
                    if (distance < addedRadius) {

                            var normalX = distanceX / distance,
                                normalY = distanceY / distance,
                                midpointX = (controllers[i].x + self.x) / 2,
                                midpointY = (controllers[i].y + self.y) / 2,
                                delta = ((controllers[i].velocityX - self.velocityX) * normalX) + ((controllers[i].velocityY - self.velocityY) * normalY),
                                deltaX = delta*normalX,
                                deltaY = delta*normalY;

                            // Rebound puck
                            self.x = midpointX + normalX * self.radius;
                            self.y = midpointY + normalY * self.radius;
                            self.velocityX += deltaX;
                            self.velocityY += deltaY;

                            // Accelerate once hit
                            self.accelerationX = 3;
                            self.accelerationY = 3;

                    }
            }

    }

我不太擅长这些类型的数学问题,但看起来您需要围绕正弦角和余弦角旋转向量。我将向您指出一个工作示例和驱动它的源代码。这个例子我没有推导。

我最近只解决了这个问题的圆圈碰撞检测部分,但我遇到的一个解决方案包括用于建立新矢量方向的代码。 Ira Greenburg 在 processing.org 上托管了他的原始来源。 Ira 进一步引用了 Keith Peter 在 Foundation Actionscript Animation: Making Things Move!

中的解决方案

我将 Ira 的代码复制到 Processing 的 Javascript 模式,然后将其推送到 Github Pages,这样您就可以在尝试之前看到它。

我的代码的主要问题是用户控制器连接到鼠标。当发生碰撞时,该函数将不断 运行 因为鼠标位置仍然使圆圈接触。我更改了代码,因此控制器由用户键盘控制。

我还在 reddit 上寻求帮助,并得到了一些关于我的碰撞代码的帮助。链接的一些好的资源。 (http://www.reddit.com/r/javascript/comments/3cjivi/having_a_go_at_building_an_air_hockey_game_stuck/)