带有交互式平台的PyGame平台游戏“绘制”

时间:2013-12-04 07:55:58

标签: python drawing pygame

我正在寻找实现这一目标的最简单方法。我正在尝试实现可以​​通过鼠标绘制的平台(具有完全碰撞检测)。现在我有一个线条绘制功能,实际绘制小圆圈,但它们是如此接近,以至于它们或多或少看起来像一条线。最好的解决方案是在每个圆圈创建一个小的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   

感谢您的帮助,碰撞检测现在给我一个巨大的麻烦(仍然无法让我的瓷砖正确...)。

2 个答案:

答案 0 :(得分:0)

你想坚持圈子的任何理由?

矩形将使线条/矩形更加平滑,除非您想要查看像素完美碰撞,否则将使碰撞检测变得更加容易。

您似乎也无法将绘制的对象保存在任何地方(例如列表或精灵组),那么您将如何检查碰撞?


这是我为游戏做了一段时间的挑战,它并不完美,但它确实有效:

https://gist.github.com/marcusmoller/bae9ea310999db8d8d95

工作原理:

  • 整个游戏关卡分为10x10像素网格,方便绘图
  • 调平员检查鼠标是否被点击然后保存鼠标位置
  • 玩家现在将鼠标移动到另一个位置并释放鼠标按钮,水平仪现在可以保存新位置。
  • 您现在有两个不同的坐标,可以很容易地制作一个矩形。

答案 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