25. 射击石头:在点和圆之间进行碰撞检测

25.Shooting Rocks: Collision Detection between a point and a circle

The very first example on this blog looked at moving a spaceship around. In this post we’ll return to our spaceship, and get it shooting asteroids. Firing a bullet is quite straightforward: you add the bullet, make it point in the same direction as the spaceship, then let it continue in a straight line. But how can you know when the bullet has hit an asteroid?

博客的第一个例子便是讨论太空飞船的四处移动。在这篇帖子里我们将回到我们的太空飞船,让它射击小行星。发射子弹是非常明了的:添加一个子弹对象,让它朝向与飞船相同的方向,接着让它沿直线运行。但是你怎样知道子弹什么时候碰到了行星呢?

If you want to perform collision detection with a mathematical approach, you must model the two entities involved as geometric items: a point, a line, a circle, a rectangle, or some other polygon. Our bullet can be modelled as a point, and our asteroid can be modelled as a circle (the red outline below):

如果你希望使用数学的方式实现碰撞检测,你必须将这两个实体以几何形式进行建模:一个点、一条线、一个圆、一个矩形,或者一些其他多边形。我们的子弹可以建模为一个点,而行星可以建模为一个圆(下图中红色标出的)

So to find out if our bullet has hit an asteroid, we need to check if a point has intersected a circle. A circle is defined as being a particular distance (the radius) from a given point (the centre). So to find out if a point intersects a circle, find out how far the point is from the centre. If this distance is less than the radius, the point must be inside the circle; if the distance is greater than the radius, if must be outside the circle. For example, below, the distance from the centre to the blue point is less than the radius, which means it is inside the circle, whereas the distance from the centre to the purple point is greater than the radius, which means it is outside the circle:

于是若要知道子弹是否撞上了行星,我们需要检查一个点是否与一个圆相交。一个圆被定义为始于某个给定点(圆心)的特定距离(半径)。因此要知道一个点是否与园相交,便要知道该点离圆心有多远。如果其距离小于半径,则点必定在园的内部;如果距离大于半径,它必定在园的外部。举例来说,在下图中,从圆心到蓝点得距离小于半径,这便意味着它在圆的内部,而圆心到紫点的距离大于半径,这意味着它在圆的外部:

Finding out the distance between the point and the centre of the circle is done with Pythagoras, making the overall code very simple — check the Pythagorean distance against the radius to see if the bullet is touching the asteroid:

寻求点和圆心的距离可以使用勾股定理完成,这使得整个代码非常简单——检查弦长与半径的长度来判断子弹是否与行星接触:

    private boolean touching(Asteroid asteroid)
    {
        double distX = asteroid.getX() - getX();
        double distY = asteroid.getY() - getY();
        double dist = Math.sqrt(distX * distX + distY * distY);
        
        return (dist < asteroid.getRadius());
    }

You can play with the scenario and view the full source code over on the Greenfoot site.

你可以在Greenfoot网站里玩一下游戏剧本同时查看完整的源代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值