33. 实现桌球的反弹

33.Making Your Balls Bounce

In this post, we will finally complete our pool game. We’ve already seenhow to detect collisions between balls: we just need to check if two circles are overlapping. We’ve also seenhow to resolve a collision when bouncing a ball off a wall(i.e. one moving object and one stationary). The final piece of the puzzle is just to put it all together in the case of two moving balls.

在这篇文章中,我们将最终完成我们的桌球游戏。我们已经看到如何检测球之间的碰撞:我们只需要检查两个圆是重叠的。我们也看到了如何解决当球与墙壁反弹时的碰撞(即一个移动对象和一个固定对象)。最后的难题是只是将其结合在一起在两个移动球的情形下。

Bouncy Balls

球之间的反弹

The principle behind collision resolution for pool balls is as follows. You have a situation where two balls are colliding, and you know their velocities (step 1 in the diagram below). You separate out each ball’s velocity (the solid blue and green arrows in step 1, below) into two perpendicular components: the component heading towards the other ball (the dotted blue and green arrows in step 2) and the component that is perpendicular to the other ball (the dashed blue and green arrows in step 2).

桌球间的碰撞解决方案背后的原理如下。你有一个情境,两球的碰撞,你知道他们的速度(步骤1在下图)。你分离出每一球的速度(在步骤1中的蓝色和绿色的实线箭头,下图)分成两个垂直分量:朝着其他球(在步骤2中的蓝色和绿色的虚线箭头)的分量以及垂直于其他球(在步骤2中的蓝色和绿色的折线箭头)的分量。

This is the same principle as we used when colliding with a wall. The difference here is that while you still leave alone the components that are parallel, instead of reversing each ball’s component that heads towards the other ball, youswap the components between the two balls (as we move from step 2 to step 3), then finally recombine the velocities for each ball to leave the result (step 4):

我们使用壁碰撞同样的原理不同之处在于仍然保持各自的平行分量的同时,交换两个球的相对分量(正如我们从步骤2转到步骤3所示的那样),而不是反转每个球朝着另一个球的分量,接下来为每个球重新合成速度来得到结果(步骤4):

This means that the code we need is actually only a small modification on the previous code for wall collision:

这意味着我们需要的代码实际上只要在前面的墙壁碰撞代码之上做一点小小的修改:

                double towardsThem = distAlong(b.getMoveX(), b.getMoveY(), distX, distY);
                double towardsMe = distAlong(c.getMoveX(), c.getMoveY(), distX, distY);
                
                double myOrtho = distAlong(b.getMoveX(), b.getMoveY(), distY, -distX);
                double theirOrtho = distAlong(c.getMoveX(), c.getMoveY(), distY, -distX);

                b.setMove(towardsMe * distX + myOrtho * distY,
                          towardsMe * distY + myOrtho * -distX);
                c.setMove(towardsThem * distX + theirOrtho * distY,
                          towardsThem * distY + theirOrtho * -distX);
You can have a play with the relevant scenario over on the Greenfoot site.

你可以在Greenfoot网站上玩一下相应的游戏剧本。

Programming Challenge Task

编写挑战任务

The scenario needs a bit more work to make a finished game: interface polish, a second player (with two types of balls, and a black 8-ball) and scoring. Feel free to take the code and finish off the game.

这个游戏剧本需要更多的一点工作去成为一个完整的游戏:平滑的界面,第二个玩家(使用两种类型的球,以及一个黑8球)以及计分。任意使用代码同时完成游戏。

Mathematical Challenge Task

The collision resolution is not as precise as it could be. Because it uses the destination position at the end of the frame for resolving the collision, two balls which move towards each quickly can potentially bounce off at a strange angle. This could be fixed by modelling a ball’s position as:

\begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} \text{startX} \\ \text{startY} \end{pmatrix} + t \times \begin{pmatrix} \text{moveX} \\ \text{moveY} \end{pmatrix}

Where t varies from 0 (at the start of the frame) to 1 (at the end). You can then find at which value of t the two balls collide (building on thecircle collision work), and use these positions of the exact collision when resolving the collision. If you feel like a challenge, have a go at using that idea to improve the collision mechanism.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
         针对有大量Unity初学者想在短期内(例如:2-4周间)快速掌握Untiy的基本使用,了解基本开发技能。为满足入门学员的学习要求,“刘国柱讲Unity”系列课程,因此推出了本套“Unity快速入门系列课程”,目前内容包含如下:    1: 项目“我的世界”: 讲解Unity软件的重要组成窗口与基本使用。    2: 项目:  台球游戏:   讲解Untiy中脚本的基本使用,Unity碰撞体与触发器的使用。    3:  项目: “Flappy Bird” 讲解纯2D(手游)游戏的开发过程,了解Unity2D 开发技能。    4:  项目: 太空射击 讲解使用3D空间,开发2D手游的过程,其中讲解“单例模式”做数据传值技术、基本粒子系统的使用、音频处理方法、碰撞与触发检测脚本算法......    5:   模块“移动端发布技术”,讲解快速发布Android 发布包(*.APK文件)技术。讲解JDK的安装与配置,以及Android SDK 的配置方式方法。    一、热更新系列(技术含量:中高级):A:《lua热更新技术中级篇》https://edu.csdn.net/course/detail/27087B:《热更新框架设计之Xlua基础视频课程》https://edu.csdn.net/course/detail/27110C:《热更新框架设计之热更流程与热补丁技术》https://edu.csdn.net/course/detail/27118D:《热更新框架设计之客户端热更框架(上)》https://edu.csdn.net/course/detail/27132E:《热更新框架设计之客户端热更框架(中)》https://edu.csdn.net/course/detail/27135F:《热更新框架设计之客户端热更框架(下)》https://edu.csdn.net/course/detail/27136二:框架设计系列(技术含量:中级): A:《游戏UI界面框架设计系列视频课程》https://edu.csdn.net/course/detail/27142B:《Unity客户端框架设计PureMVC篇视频课程(上)》https://edu.csdn.net/course/detail/27172C:《Unity客户端框架设计PureMVC篇视频课程(下)》https://edu.csdn.net/course/detail/27173D:《AssetBundle框架设计_框架篇视频课程》https://edu.csdn.net/course/detail/27169三、Unity脚本从入门到精通(技术含量:初级)A:《C# For Unity系列之入门篇》https://edu.csdn.net/course/detail/4560B:《C# For Unity系列之基础篇》https://edu.csdn.net/course/detail/4595C: 《C# For Unity系列之中级篇》https://edu.csdn.net/course/detail/24422D:《C# For Unity系列之进阶篇》https://edu.csdn.net/course/detail/24465四、虚拟现实(VR)与增强现实(AR):(技术含量:初级)A:《虚拟现实之汽车仿真模拟系统 》https://edu.csdn.net/course/detail/26618五、Unity基础课程系列(技术含量:初级) A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》 https://edu.csdn.net/course/detail/24643B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》https://edu.csdn.net/course/detail/24645 C:《Unity ECS(二) 小试牛刀》https://edu.csdn.net/course/detail/27096六、Unity ARPG课程(技术含量:初中级):A:《MMOARPG地下守护神_单机版实战视频课程(上部)》https://edu.csdn.net/course/detail/24965B:《MMOARPG地下守护神_单机版实战视频课程(中部)》https://edu.csdn.net/course/detail/24968C:《MMOARPG地下守护神_单机版实战视频课程(下部)》https://edu.csdn.net/course/detail/24979

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值