我正在编程一个战略游戏,它发生在一个六边形网格(是的,一个CIV克隆),并想实现一个系统,允许我显示一些属性的瓷砖,通过我的鼠标悬停在它上面.我目前的实现是 for each Tile(1)创建一个RECT,这个RECT与Tile的精灵具有相同的尺寸和坐标.然后,我使用pygame.Rect.collidepoint(2)来检测冲突.这样做的问题是不同瓷砖的矩形在边缘重叠,导致检测到多个碰撞(3)

(1)

for i in range (0, 100):
    Tiles_rects.append (pygame.Rect(Tiles_pos[i], (TILE_WIDTH, TILE_HEIGHT )))

(2)

for i in range (0, 100):
            # Takes one tile at a time and determines if mouse is on top of it
            mouse_over_tile = pygame.Rect.collidepoint( Tiles_rects[i] , mouse_pos )    
            if mouse_over_tile:
                print (i)    #placeholder

(3)

我试图使对撞机(矩形)更小,并调整它们的位置以居中.虽然这确实修复了重叠,但它也使六边形的相当一部分在悬停时不起作用.圆形对撞机而不是矩形对撞机可能不会有太多用处,因为我的六边形有点散布在x轴上.

推荐答案

您可以利用六边形两侧的坡度为60°这一事实.如果到边界矩形中心的y距离小于距离边界矩形外部的x距离乘以60°的切线,则该点位于六边形内部:

def collideHexagon(bounding_rect, position):
    px, py = position
    if bounding_rect.collidepoint((px, py)):
        dx = min(px - bounding_rect.left, bounding_rect.right - px)
        dy = abs(py - bounding_rect.centery)
        if dy < dx * math.tan(math.radians(60)):
            return True
    return False

最小示例:

import pygame, math

pygame.init()
screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()


len = 100
sin_len = math.sin(math.radians(60)) * len
cos_len = math.cos(math.radians(60)) * len
pts = [
    (len, 0), (len-cos_len, sin_len), (cos_len-len, sin_len),
    (-len, 0), (cos_len-len, -sin_len), (len-cos_len, -sin_len)]
pts = [(x + 200, y + 200) for x, y in pts]

tile_heihgt = sin_len * 2
tile_width = len * 2
tiel_rect = pygame.Rect(0, 0, tile_width, tile_heihgt)
tiel_rect.center = (200, 200)

def collideHexagon(bounding_rect, position):
    px, py = position
    if bounding_rect.collidepoint((px, py)):
        dx = min(px - bounding_rect.left, bounding_rect.right - px)
        dy = abs(py - bounding_rect.centery)
        if dy < dx * math.tan(math.radians(60)):
            return True
    return False

run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    color = "white"
    if collideHexagon(tiel_rect, pygame.mouse.get_pos()):
        color = "red"
 
    screen.fill(0)
    pygame.draw.polygon(screen, color, pts)         
    pygame.display.flip() 

pygame.quit()
exit()

Python相关问答推荐

决策树分类器的基础sklearn熵和log_loss标准是否有差异?

在IIS中运行的FastAPI-获取权限错误:[Win错误10013]试图以其访问权限禁止的方式访问插槽

如何以实现以下所述的预期行为的方式添加两只Pandas pyramme

Django文件上传不起作用:文件未出现在媒体目录或数据库中

替换字符串中的点/逗号,以便可以将其转换为浮动

机器人与Pyton Minecraft服务器状态不和

用Python获取HTML Span类中的数据

在Arrow上迭代的快速方法.Julia中包含3000万行和25列的表

更改Seaborn条形图中的x轴日期时间限制

具有症状的分段函数:如何仅针对某些输入值定义函数?

大Pandas 胚胎中产生组合

如何在Python中将returns.context. DeliverresContext与Deliverc函数一起使用?

需要计算60,000个坐标之间的距离

如何在Python中并行化以下搜索?

Django RawSQL注释字段

python中的解释会在后台调用函数吗?

如何在Python中使用另一个数据框更改列值(列表)

为什么if2/if3会提供两种不同的输出?

基于行条件计算(pandas)

为什么常规操作不以其就地对应操作为基础?