我正在寻找实现这一目标的最简单方法。我正在尝试实现可以通过鼠标绘制的平台(具有完全碰撞检测)。现在我有一个线条绘制功能,实际绘制小圆圈,但它们是如此接近,以至于它们或多或少看起来像一条线。最好的解决方案是在每个圆圈创建一个小的pygame.Rect对象吗?这将是很多矩形对象。它不是一个图像所以像素完美似乎不是一个选项?
def drawGradientLine(screen, index, start, end, width, color_mode):
#color values change based on index
cvar1 = max(0, min(255, 9 * index-256))
cvar2 = max(0, min(255, 9 * index))
#green(0,255,0), blue(0,0,255), red(255,0,0), yellow(255,255,0)
if color_mode == 'green':
color = (cvar1, cvar2, cvar1)
elif color_mode == 'blue':
color = (cvar1, cvar1, cvar2)
elif color_mode == 'red':
color = (cvar2, cvar1, cvar1)
elif color_mode == 'yellow':
color = (cvar2, cvar2, cvar1)
dx = end[0] - start[0]
dy = end[1] - start[1]
dist = max(abs(dx), abs(dy))
for i in xrange(dist):
x = int(start[0]+float(i)/dist*dx)
y = int(start[1]+float(i)/dist*dy)
pygame.draw.circle(screen, color, (x, y), width)
这是我的绘图功能。这是我在主游戏事件循环中放置的循环。
i = 0
while (i < len(pointList)-1):
drawGradientLine(screen, i, pointList[i], pointList[i + 1], r, mode)
i += 1
感谢您的帮助,碰撞检测现在给我一个巨大的麻烦(仍然无法让我的瓷砖正确...)。
答案 0 :(得分:0)
你想坚持圈子的任何理由?
矩形将使线条/矩形更加平滑,除非您想要查看像素完美碰撞,否则将使碰撞检测变得更加容易。
您似乎也无法将绘制的对象保存在任何地方(例如列表或精灵组),那么您将如何检查碰撞?
这是我为游戏做了一段时间的挑战,它并不完美,但它确实有效:
https://gist.github.com/marcusmoller/bae9ea310999db8d8d95
工作原理:
答案 1 :(得分:0)
我不打算创建一大堆rect
个对象来测试碰撞,而是建议创建一个名为mask
的绘制可碰撞对象的东西,并测试碰撞对象。基本上,mask
是正在使用像素且不在图像中的像素的地图。你几乎可以把它想象成一个表面的阴影或轮廓。
当您致电pygame.draw.circle
时,您已经在传递表面。现在你正在直接绘制到屏幕上,这可能不像我建议的那样有用。我建议创建一个rect
,它覆盖正在绘制的线的整个区域,然后创建该大小的表面,然后将线绘制到此表面。我的代码将假设您已经知道了线的点的界限。
line_rect = pygame.Rect(leftmost, topmost, rightmost - leftmost, bottommost - topmost)
line_surf = pygame.Surface((line_rect.width, line_rect.height))
在drawGradientLine
函数中,您必须将点坐标转换为line_surf
的对象空间。
while (i < len(pointList)-1):
drawGradientLine(line_surf, (line_rect.x, line_rect.y), i, pointList[i], pointList[i+1], r, mode)
i += 1
def drawGradientLine(surf, offset, index, start, end, width, color_mode):
# the code leading up to where you draw the circle...
for i in xrange(dist):
x = int(start[0]+float(i)/dist*dx) - offset[0]
y = int(start[1]+float(i)/dist*dy) - offset[1]
pygame.draw.circle(surf, color, (x, y), width)
现在你将有一个表面,其中绘制的对象是blitted。请注意,如果要绘制的线条的宽度大于1,则可能必须在创建曲面时向曲面添加一些填充。
现在您已拥有表面,您将需要创建它的mask
。
surf_mask = pygame.mask.from_surface(line_surf)
希望这对你来说不是太复杂!现在,您可以检查掩码中的每个“活动”点,以查看来自玩家rect
内的碰撞(或任何其他想要与绘制平台发生碰撞的对象),或者您可以从曲面创建遮罩这样一个玩家对象并使用pygame.Mask.overlap_area
函数来检查像素完美碰撞。
# player_surf is a surface object I am imagining exists
# player_rect is a rect object I am imagining exists
overlap_count = surf_mask.overlap_area(player_surf, (line_rect.x - player_rect.x, line_rect.y - player_rect.y))
overlap_count
应该是掩码之间重叠像素数的计数。如果这大于零,那么你知道发生了碰撞。
以下是pygame.Mask.overlap_area
的文档:http://www.pygame.org/docs/ref/mask.html#pygame.mask.Mask.overlap_area