python 中的碰撞形状
Colliding shapes in python
我的计划是创建一个 "simple" 2 人迷你游戏(例如相扑和比赛)。
我的目标是有效地实现与方形、圆形(和三角形?)形状的物体的碰撞(我当前的代码只能处理简单的壁物理和物体的运动),这些物体可以是环境的一部分(例如 "rocks" 或不可移动的障碍物)或部分用户控制的项目(例如 "cars" 或可推动的障碍物)。也很高兴知道如何在碰撞中考虑质量。
有两个方面我需要帮助:
两个移动物体(具有质量和二维向量)之间的不同类型的动态碰撞
(物理部分不是检测)。
确保所有需要碰撞的东西都足够快地碰撞(这样我的慢速计算机仍然可以每秒渲染超过 40-60 帧),并根据特定规则(或者如果它那么根据一条规则可能吗?)。这样也不会很难管理需要碰撞的对象(添加、删除、修改等)。
或者我应该为 ex 实现两种类型的碰撞。静态+动态圈和动态+动态圈?
def checkcollisions(object1, object2):
# x is the current x position
# y is the current y position
# angle is the current vector angle (calculated from x and y with pythagoros
# speed is the length of the vector
dx = object1.x - object2.x
dy = object1.y - object2.y
dist = hypot(dx, dy)
if dist < object1.radius + object2.radius:
angle = atan2(dy, dx) + 0.5 * pi
total_mass = object1.mass + object2.mass
'''''http://www.petercollingridge.co.uk/pygame-physics-simulation/mass'''''
if (0.79 <= object1.angle < 2.36 or 0.79-2*pi <= object1.angle < 2.36-2*pi) or (3.93 <= object1.angle < 5.5 or 3.93-2*pi <= object1.angle < 5.5-2*pi) and ((0.79 <= object2.angle < 2.36 or 0.79-2*pi <= object2.angle < 2.36-2*pi) or (3.93 <= object2.angle < 5.5 or 3.93-2*pi <= object2.angle < 5.5-2*pi)):
(object2angle, object2speed) = vectorsum((object2.angle, object2.speed*(object2.mass-object1.mass)/total_mass), (angle+pi, 2*object1.speed*object1.mass/total_mass))
(object1angle, object1speed) = vectorsum((object1.angle, object1.speed*(object1.mass-object2.mass)/total_mass), (angle, 2*object2.speed*object2.mass/total_mass))
else:
'''''https://en.wikipedia.org/wiki/Elastic_collision'''''
CONTACT_ANGLE = angle
x = (((object1.speed * cos(object1.angle - CONTACT_ANGLE) * (object1.mass-object2.mass)+ 2*object2.mass*object2.speed*cos(object2.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object1.speed*sin(object1.angle - CONTACT_ANGLE)*cos(CONTACT_ANGLE + 0.5 * pi)
y = (((object1.speed * cos(object1.angle - CONTACT_ANGLE) * (object1.mass-object2.mass)+ 2*object2.mass*object2.speed*cos(object2.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object1.speed*sin(object1.angle - CONTACT_ANGLE)*sin(CONTACT_ANGLE + 0.5 * pi)
object1angle = pi/2 - atan2(y, x)
object1speed = hypot(x, y)
x = (((object2.speed * cos(object2.angle - CONTACT_ANGLE)*(object2.mass-object1.mass)+2*object1.mass*object1.speed*cos(object1.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object2.speed*sin(object2.angle - CONTACT_ANGLE)*cos(CONTACT_ANGLE + 0.5 * pi)
y = (((object2.speed * cos(object2.angle - CONTACT_ANGLE)*(object2.mass-object1.mass)+2*object1.mass*object1.speed*cos(object1.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object2.speed*sin(object2.angle - CONTACT_ANGLE)*sin(CONTACT_ANGLE + 0.5 * pi)
object2angle = pi/2 - atan2(y, x)
object2speed = hypot(x, y)
(object2.angle, object2.speed) = (object2angle, object2speed)
(object1.angle, object1.speed) = (object1angle, object1speed)
object1.speed *= 0.999
object2.speed *= 0.999
overlap = 0.5*(object1.radius + object2.radius - dist+1)
object1.x += sin(angle)*overlap
object1.y -= cos(angle)*overlap
object2.x -= sin(angle)*overlap
object2.y += cos(angle)*overlap
'''''http://www.petercollingridge.co.uk/pygame-physics-simulation/mass'''''
def vectorsum(vectorx, vectory): # Every array's first number is the degree from 0, the second is speed
x = sin(vectory[0]) * vectory[1] + sin(vectorx[0]) * vectorx[1]
y = cos(vectory[0]) * vectory[1] + cos(vectorx[0]) * vectorx[1] # Calculating new vectors from anle and lenght
angle = pi / 2 - atan2(y, x) # Calculating the degree
speed = hypot(x, y) # Calculating the speed
return angle, speed
(我只是 Python(或英语)的初学者,所以请记住这一点。)
- 碰撞检测在 pygame 中非常容易。看看使用 pygame.sprite. They have several functions to detect collisions. (spritecollide, groupcollide,等等)如果你有一些复杂的碰撞交互,通常你使用矩形或圆形来查看它们是否碰撞,然后只对它们进行复杂的计算。虽然对于大多数游戏来说,你不需要完美碰撞检测的成本,但足够接近就足够了。
- 至于碰撞时发生的事情,那更多的是物理而不是编程。要记住的一些概念是:动量守恒、弹性与非弹性碰撞、偏转角。 "How to building a 2D physics engine" 对于 SO 问题来说有点太宽泛了。也许看看 how-to-create-a-custom-2d-physics-engine-oriented-rigid-bodies
我的计划是创建一个 "simple" 2 人迷你游戏(例如相扑和比赛)。
我的目标是有效地实现与方形、圆形(和三角形?)形状的物体的碰撞(我当前的代码只能处理简单的壁物理和物体的运动),这些物体可以是环境的一部分(例如 "rocks" 或不可移动的障碍物)或部分用户控制的项目(例如 "cars" 或可推动的障碍物)。也很高兴知道如何在碰撞中考虑质量。
有两个方面我需要帮助:
两个移动物体(具有质量和二维向量)之间的不同类型的动态碰撞 (物理部分不是检测)。
确保所有需要碰撞的东西都足够快地碰撞(这样我的慢速计算机仍然可以每秒渲染超过 40-60 帧),并根据特定规则(或者如果它那么根据一条规则可能吗?)。这样也不会很难管理需要碰撞的对象(添加、删除、修改等)。
或者我应该为 ex 实现两种类型的碰撞。静态+动态圈和动态+动态圈?
def checkcollisions(object1, object2):
# x is the current x position
# y is the current y position
# angle is the current vector angle (calculated from x and y with pythagoros
# speed is the length of the vector
dx = object1.x - object2.x
dy = object1.y - object2.y
dist = hypot(dx, dy)
if dist < object1.radius + object2.radius:
angle = atan2(dy, dx) + 0.5 * pi
total_mass = object1.mass + object2.mass
'''''http://www.petercollingridge.co.uk/pygame-physics-simulation/mass'''''
if (0.79 <= object1.angle < 2.36 or 0.79-2*pi <= object1.angle < 2.36-2*pi) or (3.93 <= object1.angle < 5.5 or 3.93-2*pi <= object1.angle < 5.5-2*pi) and ((0.79 <= object2.angle < 2.36 or 0.79-2*pi <= object2.angle < 2.36-2*pi) or (3.93 <= object2.angle < 5.5 or 3.93-2*pi <= object2.angle < 5.5-2*pi)):
(object2angle, object2speed) = vectorsum((object2.angle, object2.speed*(object2.mass-object1.mass)/total_mass), (angle+pi, 2*object1.speed*object1.mass/total_mass))
(object1angle, object1speed) = vectorsum((object1.angle, object1.speed*(object1.mass-object2.mass)/total_mass), (angle, 2*object2.speed*object2.mass/total_mass))
else:
'''''https://en.wikipedia.org/wiki/Elastic_collision'''''
CONTACT_ANGLE = angle
x = (((object1.speed * cos(object1.angle - CONTACT_ANGLE) * (object1.mass-object2.mass)+ 2*object2.mass*object2.speed*cos(object2.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object1.speed*sin(object1.angle - CONTACT_ANGLE)*cos(CONTACT_ANGLE + 0.5 * pi)
y = (((object1.speed * cos(object1.angle - CONTACT_ANGLE) * (object1.mass-object2.mass)+ 2*object2.mass*object2.speed*cos(object2.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object1.speed*sin(object1.angle - CONTACT_ANGLE)*sin(CONTACT_ANGLE + 0.5 * pi)
object1angle = pi/2 - atan2(y, x)
object1speed = hypot(x, y)
x = (((object2.speed * cos(object2.angle - CONTACT_ANGLE)*(object2.mass-object1.mass)+2*object1.mass*object1.speed*cos(object1.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object2.speed*sin(object2.angle - CONTACT_ANGLE)*cos(CONTACT_ANGLE + 0.5 * pi)
y = (((object2.speed * cos(object2.angle - CONTACT_ANGLE)*(object2.mass-object1.mass)+2*object1.mass*object1.speed*cos(object1.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object2.speed*sin(object2.angle - CONTACT_ANGLE)*sin(CONTACT_ANGLE + 0.5 * pi)
object2angle = pi/2 - atan2(y, x)
object2speed = hypot(x, y)
(object2.angle, object2.speed) = (object2angle, object2speed)
(object1.angle, object1.speed) = (object1angle, object1speed)
object1.speed *= 0.999
object2.speed *= 0.999
overlap = 0.5*(object1.radius + object2.radius - dist+1)
object1.x += sin(angle)*overlap
object1.y -= cos(angle)*overlap
object2.x -= sin(angle)*overlap
object2.y += cos(angle)*overlap
'''''http://www.petercollingridge.co.uk/pygame-physics-simulation/mass'''''
def vectorsum(vectorx, vectory): # Every array's first number is the degree from 0, the second is speed
x = sin(vectory[0]) * vectory[1] + sin(vectorx[0]) * vectorx[1]
y = cos(vectory[0]) * vectory[1] + cos(vectorx[0]) * vectorx[1] # Calculating new vectors from anle and lenght
angle = pi / 2 - atan2(y, x) # Calculating the degree
speed = hypot(x, y) # Calculating the speed
return angle, speed
(我只是 Python(或英语)的初学者,所以请记住这一点。)
- 碰撞检测在 pygame 中非常容易。看看使用 pygame.sprite. They have several functions to detect collisions. (spritecollide, groupcollide,等等)如果你有一些复杂的碰撞交互,通常你使用矩形或圆形来查看它们是否碰撞,然后只对它们进行复杂的计算。虽然对于大多数游戏来说,你不需要完美碰撞检测的成本,但足够接近就足够了。
- 至于碰撞时发生的事情,那更多的是物理而不是编程。要记住的一些概念是:动量守恒、弹性与非弹性碰撞、偏转角。 "How to building a 2D physics engine" 对于 SO 问题来说有点太宽泛了。也许看看 how-to-create-a-custom-2d-physics-engine-oriented-rigid-bodies