您可以通過給塊/瓦片世界座標(即表示網格內塊的列和行)而不是每次手動計算它來簡化您的解決方案。
然後,你可以簡單地檢查後,將鼠標位置翻譯爲世界座標。另外,您可以創建一個字典,將每個列/行映射到塊/瓷磚對象(您沒有顯示剩餘的代碼,因此我不知道您是如何實際存儲瓷磚的;也許列表列表?如果是,那麼您只需檢索具有索引的正確圖塊)。
這會讓你擺脫循環。
另外,我覺得使用pygame.event.poll()
代替pygame.event.get()
可能是一個問題了。
使用poll
時,您只能從事件隊列中獲取一個事件。這意味着您每幀只能處理一個事件。也許這會導致你的滯後?
您應該檢查您在主循環中運行的其他函數。我會運行一個分析器來查看遊戲瓶頸的位置(有時結果令人驚訝)。
下面是使用dict
來查找鼠標光標下的圖塊的簡單示例。評論中有更多解釋。
import pygame
import random
pygame.init()
BRICK_HEIGHT = 48
BRICK_WIDTH = 64
class Block(object):
def __init__(self, x=0, y=0, num=0, width=0, color=(122, 122, 122)):
# w_x and w_y represents the world coordinates
# that means the 'column' and 'row' in the 'grid'
self.w_x, self.w_y = x, y
# to calculate the absolute (screen) position,
# simply multiply x, y with BRICK_WIDTH, BRICK_HEIGHT
self.rect = pygame.rect.Rect(x*BRICK_WIDTH, y*BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT)
self.width = width
self.color = color
def draw(self, surface):
pygame.draw.rect(surface, self.color, self.rect, self.width)
def move(self, global_pos):
# to translate the absolute (screen) position
# back to the world coordinates, simply divide
# with BRICK_WIDTH, BRICK_HEIGHT
x, y = global_pos
self.w_x = (x/BRICK_WIDTH)
self.w_y = (y/BRICK_HEIGHT)
# recalculate the absolute (screen) position,
# so the cursor "snaps" to the grid
self.rect.x = self.w_x * BRICK_WIDTH
self.rect.y = self.w_y * BRICK_HEIGHT
screen = pygame.display.set_mode((10*BRICK_WIDTH, 10*BRICK_HEIGHT))
clock = pygame.time.Clock()
c = Block(width=4, color=(200, 255, 200))
def r_color():
return (random.randint(30, 255),
random.randint(30, 255),
random.randint(30, 255))
# blocks maps (column, row) to a block
# note that this keeps the information of the
# position of a block at *two* places, which needs
# to be in sync. That's a drawback, but the
# lookup is fast!
blocks = {}
for x in xrange(10):
for y in xrange(10):
if random.randint(0, 100) < 33:
blocks[(x, y)] = Block(x, y, color=r_color())
while True:
pos = pygame.mouse.get_pos()
c.move(pos)
for e in pygame.event.get():
if e.type == pygame.QUIT:
raise Exception()
if e.type == pygame.MOUSEBUTTONDOWN:
# finding the tile under the mouse is as easy as:
block = blocks.get((c.w_x, c.w_y))
# and since it's a dict, the lookup is very fast.
print 'Selected block color: {}'.format(block.color) if block else 'No block selected'
screen.fill((0, 30, 30))
for b in blocks.values():
# The blocks calculated their absolute position by themself.
# That may or may not what you want. Another way is to calculate
# their absolute position here, so the blocks only needs to
# know about their world coordinates
b.draw(screen)
c.draw(screen)
# run at 60 FPS
clock.tick(60)
pygame.display.flip()
![enter image description here](https://i.stack.imgur.com/yYUmF.gif)
輝煌!非常感謝你。在發佈這個問題之後不久,我發現引起巨大延遲的原因實際上是poll()而不是get()。儘管如此,你的解決方案要聰明得多(考慮到我使用「碰撞方法」來「選擇」),我的解決方案可能會更復雜一些。不,我不使用字典。世界實際上是由程序產生的。我生成了N個迷宮的隨機迷宮(每個屏幕都是不同的迷宮),並且它們存儲在一個列表中。每個迷宮都是一個列表,地牢本身就是迷宮對象列表。非常感謝你!! –