Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带互动平台的PyGame平台;“已绘制”;在里面_Python_Drawing_Pygame - Fatal编程技术网

Python 带互动平台的PyGame平台;“已绘制”;在里面

Python 带互动平台的PyGame平台;“已绘制”;在里面,python,drawing,pygame,Python,Drawing,Pygame,我正在寻找最简单的方法来实现这一点。我正在尝试实现可以通过鼠标绘制的平台(具有完全碰撞检测)。现在我有一个画线的功能,它可以画小圆圈,但是它们靠得太近了,看起来或多或少像一条线。最好的解决方案是在每个圆上创建一个小pygame.Rect对象吗?这将是很多rect对象。这不是一个图像,所以像素完美似乎不是一个选项 def drawGradientLine(screen, index, start, end, width, color_mode): #color values change

我正在寻找最简单的方法来实现这一点。我正在尝试实现可以通过鼠标绘制的平台(具有完全碰撞检测)。现在我有一个画线的功能,它可以画小圆圈,但是它们靠得太近了,看起来或多或少像一条线。最好的解决方案是在每个圆上创建一个小pygame.Rect对象吗?这将是很多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   
i=0
而(i

感谢您的帮助,碰撞检测现在让我非常头疼(我的瓷砖也无法正确使用)

你有什么理由坚持使用圆圈吗

矩形将使直线/矩形更加平滑,并使碰撞检测更加容易,除非您希望查看像素完美碰撞

# 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))
您似乎也不会将绘制的对象保存在任何位置(如列表或精灵组中),因此如何检查碰撞


这是我前一段时间为游戏制作的leveleditor,它并不完美,但很有效:

工作原理:

  • 整个游戏级别划分为10x10px网格,以便于绘制
  • leveleditor检查鼠标是否被单击,然后保存鼠标位置
  • 玩家现在将鼠标移动到另一个位置并释放鼠标按钮,leveleditor现在保存该新位置
  • 现在有了两个不同的坐标,可以很容易地将它们做成一个矩形

与其创建一大堆要测试碰撞的
rect
对象,不如建议创建一个称为
掩码的东西,对绘制的可碰撞对象进行碰撞测试。基本上,
遮罩
是图像中正在使用哪些像素以及哪些像素不在图像中的映射。您几乎可以将其视为曲面的阴影或轮廓

当您调用
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\u 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)
希望这对你来说不会太复杂!现在,您可以检查掩码中的每个“活动”点,以便在玩家的
rect
中进行碰撞(或在平台中绘制的任何其他要碰撞的对象),或者,您可以从此类玩家对象的表面创建一个遮罩,并使用
pygame.mask.overlap\u 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\u count
应该是遮罩之间重叠的像素数的计数。如果这大于零,那么您知道发生了碰撞

# 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))

这是pygame.Mask.overlap\u区域的文档

谢谢,我没有考虑使用masks/我认为它不起作用。但有一件事让我困惑——那么,既然我检测到了碰撞,那又怎么样?我怎样才能让我的“玩家”真正穿越那个区域?我是否需要在碰撞检测中添加基于遮罩的案例?你可能会有一些简单的例子吗?所以你不确定在检测到碰撞后该怎么办?这取决于上下文。首先,您可能希望阻止玩家通过引入平台,这意味着如果检测到碰撞,您将希望稍微移动玩家,使其不再戳入平台内部。这可以让你“降落”在平台上,也可以防止你跳过平台。如果你想在不需要跳跃的情况下穿过不平的平台,这是一个更难解决的问题。