2017-01-22 193 views
1

在我的pygame中,我繪製了一個帶for循環的幾個矩形。我有一個由一個圓圈物體代表的球員。它看起來像這樣:如何檢查任何矩形是否包含圓? (在pygame中)

enter image description here

所以玩家可以用方向鍵移動,這將移動它們每一個關鍵點。最終,玩家不應該移動到這些矩形之外。所以他們每次移動我想檢查: 如果(任何繪製的矩形包含一個球員):return True else return False。

有沒有簡單的方法來做到這一點?還是應該徹底改變我的方法?

它不應該是能夠在點動矩形外是這樣的: enter image description here

,但只有在這樣的矩形: enter image description here

這是這個例子的代碼,我現在所擁有的:

import pygame 

pygame.init() 

#grid 
w = 25 
h = 25 
m = 2 

size = (550, 700) 
screen = pygame.display.set_mode(size) 
screen.fill((255, 255, 255)) 


class Player: 
    def __init__(self): 
     self.x = 149 
     self.y = 14 
     self.r = 10 

    def draw(self): 
     pygame.draw.circle(screen, (255, 0, 0), (self.x, self.y), self.r) 

    def update(self,event): 
      if event.key == pygame.K_LEFT: 
       screen.fill((250, 250, 250)) 
       self.x -= 27 
       self.draw() 
      elif event.key == pygame.K_RIGHT: 
       screen.fill((250, 250, 250)) 
       self.x += 27 
       self.draw() 
      elif event.key == pygame.K_UP: 
       screen.fill((250, 250, 250)) 
       self.y -= 27 
       self.draw() 
      elif event.key == pygame.K_DOWN: 
       screen.fill((250, 250, 250)) 
       self.y += 27 
       self.draw() 

player1 = Player() 
player1.draw() 

done = False 

while not done: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      done = True 

     elif event.type == pygame.KEYDOWN: 
      player1.update(event) 

     for row in range(5): 
      for col in range(5): 
       if row == 0 or row == 4 or col == 0 or col == 4: 
        pygame.draw.rect(screen, (0,0,0), ((w + m) * col + m, ((h + m) * row + m), w, h), 1) 

    pygame.display.flip() 

有一個Rect.contains(矩形)功能,但此檢查,如果一個矩形包含另一個矩形。是否有這樣的功能,基本上說:選擇所有現有的矩形,並檢查它們是否包含(選擇矩形)?

任何提示或幫助絕對讚賞。同時讓我知道這是否是完全錯誤的方法來做這件事。

問候。

+0

'pygame.draw.circle'返回'python.Rect'對象,所以你可以把'circle'爲'rectangle'。此外,你可以使用'row','col'而不是'x','y'來檢查'collision'。 – furas

+1

但是在你所有的代碼中都有一個小錯誤 - 你不能保留列表上所有矩形的位置,所以你不能檢查它們在圓位置的位置。 – furas

+0

BTW:爲了使代碼更具可讀性,你可以在pygame.init()之前保留所有類和函數 - 參見[簡單模板](https://github.com/furas/python-examples/blob/master/pygame/ __templates __/1__simple__.py) – furas

回答

1

您可以將circle視爲rectangle。如果將所有對象視爲矩形,則需要較少的計算(CPU功率)來檢查衝突。

你必須創建所有的矩形列表,以便您可以檢查這個列表圈子位置 - 然後你可以使用circle_rect.colliderect(some_rect)

import pygame 

# --- constants --- 

#grid 
W = 25 
H = 25 
M = 2 

SIZE = (550, 700) 

BLACK = ( 0, 0, 0) 
WHITE = (255, 255, 255) 
RED = (255, 0, 0) 

FPS = 25 
# --- classes --- 

class Player: 

    def __init__(self): 
     # to keep position and size 
     self.rect = pygame.Rect(0, 0, 20, 20) 

     # set start position 
     self.rect.center = 149, 14 

     self.r = 10 

    def draw(self): 
     pygame.draw.circle(screen, RED, self.rect.center, self.r) 

    def update(self, event): 
     # create copy of position 
     newrect = self.rect.copy() 

     # move "copy" to new position 
     if event.key == pygame.K_LEFT: 
      newrect.x -= 27 
     elif event.key == pygame.K_RIGHT: 
      newrect.x += 27 
     elif event.key == pygame.K_UP: 
      newrect.y -= 27 
     elif event.key == pygame.K_DOWN: 
      newrect.y += 27 

     # check if "copy" is still in rectangles 
     for rectangle in all_rectangles: 
      if newrect.colliderect(rectangle): 
       # now you can set new position 
       self.rect = newrect 
       # don't check other rectangles 
       break 

# --- main --- 

# - init - 

pygame.init() 

screen = pygame.display.set_mode(SIZE) 
screen_rect = screen.get_rect() 

# - objects - 

player1 = Player() 

# create list with rectangles (but not draw them) 

all_rectangles = [] 

for row in range(5): 
    for col in range(5): 
     if row == 0 or row == 4 or col == 0 or col == 4: 
      all_rectangles.append(pygame.Rect((W + M) * col + M, ((H + M) * row + M), W, H)) 

# - mainloop - 

clock = pygame.time.Clock()  
done = False 

while not done: 

    # - events (without draws) - 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      done = True 

     elif event.type == pygame.KEYDOWN: 
      player1.update(event) 


    # - draw everything in one place - 

    screen.fill(WHITE) 

    for rectangle in all_rectangles: 
     pygame.draw.rect(screen, BLACK, rectangle, 1) 

    player1.draw() 

    pygame.display.flip() 

    # - FPS - keep the same speed on all computers - 

    clock.tick(FPS) 

# - end - 
pygame.quit() 

BTW:你可以使用,而不是rowcolx,y保持矩形位置和圓圈位置(和檢查碰撞),並且只繪製時將row/col轉換爲x/y。您還可以創建類似矩形的列表,如

all_rectangles = [ 
    "######", 
    "# #", 
    "# #", 
    "# #", 
    "######", 
] 

然後創建映射更容易。


編輯:

map = [ 
    "######## #######", 
    "#  ####  #", 
    "#  # #  #", 
    "# ######## #", 
    "######  # #", 
    " #  #####", 
    " #   # ", 
    " ############ ", 
] 

all_rectangles = [] 

for r, row in enumerate(map): 
    for c, item in enumerate(row): 
     if item == '#': 
      all_rectangles.append(pygame.Rect((W + M) * c + M, ((H + M) * r + M), W, H)) 

enter image description here

+0

徹底徹底地完成之後,我創建了一個包含所有位置的列表,並且像移動播放器之前那樣比較移動,我的pygame正在按照我現在想要的方式工作!謝謝你,我永遠感激! – Noob17

+1

@ Noob17查看[其他修改](https://github.com/furas/python-examples/tree/master/pygame/example-maze) – furas

相關問題