Pygame窗口缩放后Button按钮碰撞hitbox偏移无法正常点击问题求助
问题根源
按钮的碰撞检测逻辑使用的是初始画布(1300*800)的坐标系,但你获取的鼠标位置是缩放后实际窗口的坐标,两者坐标系不匹配;同时你的主代码中连续两次调用pygame.event.get(),会导致事件队列被清空,按钮无法接收点击事件。
可行修改方案
1. 修改主代码
新增原始分辨率常量,统一获取事件队列,计算窗口缩放比例并传递给按钮更新逻辑:
import pygame import sys from pygame.locals import * from buttonClass import Button running = True # 新增原始基础分辨率常量 BASE_WIDTH = 1300 BASE_HEIGHT = 800 pygame.init() mainClock = pygame.time.Clock() win = pygame.display.set_mode((BASE_WIDTH, BASE_HEIGHT), HWSURFACE|DOUBLEBUF|RESIZABLE) fakeMenuScreen = win.copy() # Load background images bar = pygame.image.load("menuimages/bar.png").convert_alpha() sprites = pygame.sprite.Group() singleplayerButton = sprites.add(Button(pygame.Color((0, 0, 0, 0)), pygame.Color((53, 74, 110, 50)), pygame.Rect(85, 250, 375, 50), lambda x : print('HELLO'), "Singleplayer")) multiplayerButton = sprites.add(Button(pygame.Color((0, 0, 0, 0)), pygame.Color((53, 74, 110, 50)), pygame.Rect(85, 320, 375, 50), lambda b: print(f"Button '{b.text}' was clicked"), 'Multiplayer',)) def main_menu(): global win while running == True: # 统一只获取一次事件队列,避免重复调用清空事件 events = pygame.event.get() for event in events: if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == VIDEORESIZE: win = pygame.display.set_mode(event.size, RESIZABLE) # 计算当前窗口相对原始分辨率的缩放比例 current_w, current_h = win.get_size() scale_x = current_w / BASE_WIDTH scale_y = current_h / BASE_HEIGHT win.blit(pygame.transform.smoothscale(fakeMenuScreen, (current_w, current_h)), (0, 0)) fakeMenuScreen.blit(bar, (85, 0)) # 把事件列表和缩放比例传递给按钮更新方法 sprites.update(events, scale_x, scale_y) sprites.draw(fakeMenuScreen) pygame.display.update() if __name__ == "__main__": main_menu()
2. 修改buttonClass.py的update方法
将实际鼠标坐标转换为原始画布坐标后再做碰撞检测:
def update(self, events, scale_x, scale_y): # 转换实际鼠标坐标为原始画布坐标系的坐标 real_x, real_y = pygame.mouse.get_pos() original_pos = (real_x / scale_x, real_y / scale_y) hit = self.rect.collidepoint(original_pos) self.image = self.hov if hit else self.org for event in events: if event.type == pygame.MOUSEBUTTONDOWN and hit: self.callback(self)
修改后缩放窗口时按钮的碰撞检测会和实际显示位置完全匹配。
内容的提问来源于stack exchange,提问作者ahmedquran12
相关产品推荐
相关产品推荐

