是否可以获得精灵碰撞的地方的坐标?如果它不止一个可以得到两者? 非常感谢求解器
答案 0 :(得分:0)
您可以使用Pymunk物理库来获取联系点。当然,这意味着您必须首先熟悉这个库(初学者可能有点困难)。您尤其需要了解碰撞处理程序,仲裁器和回调函数的工作原理。
因此,您创建了一个碰撞处理程序,用于检查两个指定碰撞类型的形状之间是否存在碰撞,例如: handler = space.add_collision_handler(1, 1)
。当发生collsion时,处理程序调用一些回调函数(在示例中我将handler.post_solve
设置为回调函数),该函数接收仲裁对象作为保存碰撞数据的参数。然后,您可以从此仲裁器中提取所需信息,将其添加到列表或其他数据结构中,并在主循环中使用它。
import sys
import random
import pygame as pg
import pymunk as pm
from pymunk import Vec2d
def flipy(p):
"""Convert chipmunk coordinates to pygame coordinates."""
return Vec2d(p[0], -p[1]+600)
class Ball(pg.sprite.Sprite):
def __init__(self, space, pos, mass=5, radius=30, elasticity=0.9):
super().__init__()
self.image = pg.Surface((60, 60), pg.SRCALPHA)
pg.draw.circle(self.image, pg.Color('royalblue'), (30, 30), radius)
self.rect = self.image.get_rect(center=pos)
# Set up the body and shape of this object and add them to the space.
inertia = pm.moment_for_circle(mass, 0, radius, (0, 0))
self.body = pm.Body(mass, inertia)
self.body.position = flipy(pos)
self.shape = pm.Circle(self.body, radius, (0, 0))
self.shape.elasticity = elasticity
# This type will be used by the collision handler.
self.shape.collision_type = 1
self.space = space
self.space.add(self.body, self.shape)
def update(self):
pos = flipy(self.body.position)
self.rect.center = pos
if pos.y > 600:
self.space.remove(self.body, self.shape)
self.kill()
def main():
screen = pg.display.set_mode((800, 600))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
done = False
contact_points = []
def contact_callback(arbiter, space, data):
"""Append the contact point to the contact_points list."""
if arbiter.is_first_contact:
for contact in arbiter.contact_point_set.points:
contact_points.append(contact.point_a)
# Pymunk stuff.
space = pm.Space()
space.gravity = Vec2d(0, -900)
# This collision handler will be used to get the contact points.
# It checks if shapes with `collision_type` 1 collide with others
# that also have type 1.
handler = space.add_collision_handler(1, 1)
# After a collision is solved, the callback funtion will be called
# which appends the contact point to the `contact_points` list.
handler.post_solve = contact_callback
# Create some static lines.
static_lines = [
pm.Segment(space.static_body, (170, 200), (0, 300), .1),
pm.Segment(space.static_body, (170, 200), (500, 200), .1),
pm.Segment(space.static_body, (500, 200), (600, 260), .1),
]
for line in static_lines:
line.elasticity = 0.9
space.add(static_lines)
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEBUTTONDOWN:
all_sprites.add(Ball(space, event.pos))
contact_points = []
space.step(1/60) # Update the physics space.
all_sprites.update()
screen.fill((60, 70, 80))
all_sprites.draw(screen) # Draw the sprite group.
# Draw static_lines.
for line in static_lines:
body = line.body
p1 = flipy(body.position + line.a.rotated(body.angle))
p2 = flipy(body.position + line.b.rotated(body.angle))
pg.draw.line(screen, pg.Color('gray68'), p1, p2, 5)
# Draw contact_points.
for point in contact_points:
x, y = flipy(point)
x, y = int(x), int(y)
pg.draw.circle(screen, pg.Color('orange'), (x, y), 8)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()