1. 程式人生 > >Pygame碰撞檢測

Pygame碰撞檢測

== flip 根據 定義 rom add from right cor

學習自小甲魚視頻教學(筆記)

技術分享圖片

功能實現:

在隨機位置生成若幹個小球以隨機速度運動;

若小球運動出左邊界則從右邊界進入,上下邊界同理;

若兩小球相碰撞則都以相反速度運動分開。

代碼如下:

1.嘗試自己寫碰撞檢測函數(對比兩球之間的圓心距離和半徑即可)。

技術分享圖片
  1 import pygame
  2 import sys
  3 import math
  4 from pygame.locals import *
  5 from random import *
  6 
  7 
  8 # 面向對象的編程方法,定義一個球的類型
  9 class
Ball(pygame.sprite.Sprite): 10 def __init__(self, image, position, speed, bg_size): 11 # 初始化動畫精靈 12 pygame.sprite.Sprite.__init__(self) 13 14 self.image = pygame.image.load(image).convert_alpha() 15 self.rect = self.image.get_rect() 16 # 將小球放在指定位置
17 self.rect.left, self.rect.top = position 18 self.speed = speed 19 self.width, self.height = bg_size[0], bg_size[1] 20 21 # 定義一個移動的方法 22 def move(self): 23 self.rect = self.rect.move(self.speed) 24 # 如果小球的左側出了邊界,那麽將小球左側的位置改為右側的邊界 25
# 這樣便實現了從左邊進入,右邊出來的效果 26 if self.rect.right < 0: 27 self.rect.left = self.width 28 if self.rect.left > self.width: 29 self.rect.right = 0 30 if self.rect.bottom < 0: 31 self.rect.top = self.height 32 if self.rect.top > self.height: 33 self.rect.bottom = 0 34 35 36 def collide_check(item, target): 37 col_balls = [] 38 for each in target: 39 distance = math.sqrt( 40 math.pow((item.rect.center[0] - each.rect.center[0]), 2) + 41 math.pow((item.rect.center[1] - each.rect.center[1]), 2)) 42 if distance <= (item.rect.width + each.rect.width) / 2: 43 col_balls.append(each) 44 45 return col_balls 46 47 48 def main(): 49 pygame.init() 50 51 ball_image = ball.png 52 bg_image = background.png 53 running = True 54 55 # 根據背景圖片指定遊戲界面尺寸 56 bg_size = width, height = 1024, 500 57 screen = pygame.display.set_mode(bg_size) 58 pygame.display.set_caption(Collision Spheres) 59 60 background = pygame.image.load(bg_image).convert_alpha() 61 62 # 用來存放小球對象的列表 63 balls = [] 64 65 # 創建6個位置隨機,速度隨機的小球 66 BALL_NUM = 6 67 for i in range(BALL_NUM): 68 position = randint(0, width - 70), randint(0, height - 70) 69 speed = [randint(1, 6), randint(1, 6)] 70 ball = Ball(ball_image, position, speed, bg_size) 71 while collide_check(ball, balls): 72 ball.rect.left, ball.rect.top = randint(0, width - 70), randint(0, height - 70) 73 74 balls.append(ball) 75 76 clock = pygame.time.Clock() 77 78 while running: 79 for event in pygame.event.get(): 80 if event.type == QUIT: 81 sys.exit() 82 83 screen.blit(background, (0, 0)) 84 85 for each in balls: 86 each.move() 87 screen.blit(each.image, each.rect) 88 89 for i in range(BALL_NUM): 90 item = balls.pop(i) 91 92 if collide_check(item, balls): 93 item.speed[0] = -item.speed[0] 94 item.speed[1] = -item.speed[1] 95 96 balls.insert(i, item) 97 98 pygame.display.flip() 99 clock.tick(60) 100 101 102 if __name__ == __main__: 103 main()
View Code

2.使用sprite模塊提供的碰撞檢測函數。

sprite 模塊提供了一個 spritecollide() 函數,用於檢測某個精靈是否與指定組中的其他精靈發生碰撞。

spritecollide(sprite, group, dokill, collided = None)

第一個參數指定被檢測的精靈

第二個參數指定一個組,由 sprite.Group() 生成

第三個參數設置是否從組中刪除檢測到碰撞的精靈

第四個參數設置一個回調函數,用於定制特殊的檢測方法。如果該參數忽略,那麽默認是檢測精靈之間的 rect 是否產生重疊。

註意:

  實現圓形的碰撞檢測,我們還需要指定 spritecollide() 函數的最後一個參數。

  sprite 模塊中正好有一個 collide_circle() 函數用於檢測兩個圓之間是否發生碰撞...

  這個函數需要你的精靈對象中必須有一個 radius(半徑)屬性才行。

技術分享圖片
 1 import pygame
 2 import sys
 3 from pygame.locals import *
 4 from random import *
 5 
 6 # 面向對象的編程方法,定義一個球的類型
 7 class Ball(pygame.sprite.Sprite):
 8     def __init__(self, image, position, speed, bg_size):
 9         # 初始化動畫精靈
10         pygame.sprite.Sprite.__init__(self)
11 
12         self.image = pygame.image.load(image).convert_alpha()
13         self.rect = self.image.get_rect()
14         # 將小球放在指定位置
15         self.rect.left, self.rect.top = position
16         self.speed = speed
17         self.width, self.height = bg_size[0], bg_size[1]
18         self.radius = self.rect.width / 2
19 
20     # 定義一個移動的方法
21     def move(self):
22         self.rect = self.rect.move(self.speed)
23         # 如果小球的左側出了邊界,那麽將小球左側的位置改為右側的邊界
24         # 這樣便實現了從左邊進入,右邊出來的效果
25         if self.rect.right < 0:
26             self.rect.left = self.width
27         if self.rect.left > self.width:
28             self.rect.right = 0
29         if self.rect.bottom < 0:
30             self.rect.top = self.height
31         if self.rect.top > self.height:
32             self.rect.bottom = 0
33 
34 
35 def main():
36     pygame.init()
37 
38     ball_image = ball.png
39     bg_image = background.png
40     running = True
41 
42     # 根據背景圖片指定遊戲界面尺寸
43     bg_size = width, height = 1024, 500
44     screen = pygame.display.set_mode(bg_size)
45     pygame.display.set_caption(Collision Spheres)
46 
47     background = pygame.image.load(bg_image).convert_alpha()
48 
49     # 用來存放小球對象的列表
50     balls = []
51     group = pygame.sprite.Group()
52 
53     # 創建6個位置隨機,速度隨機的小球
54     BALL_NUM = 6
55     for i in range(BALL_NUM):
56         position = randint(0, width - 70), randint(0, height - 70)
57         speed = [randint(1, 6), randint(1, 6)]
58         ball = Ball(ball_image, position, speed, bg_size)
59         while pygame.sprite.spritecollide(ball, group, False, pygame.sprite.collide_circle):
60             ball.rect.left, ball.rect.top = randint(0, width - 70), randint(0, height - 70)
61         balls.append(ball)
62         group.add(ball)
63 
64     clock = pygame.time.Clock()
65 
66     while running:
67         for event in pygame.event.get():
68             if event.type == QUIT:
69                 sys.exit()
70 
71         screen.blit(background, (0, 0))
72 
73         for each in balls:
74             each.move()
75             screen.blit(each.image, each.rect)
76 
77         for each in group:
78             group.remove(each)
79 
80             if pygame.sprite.spritecollide(each, group, False, pygame.sprite.collide_circle):
81                 each.speed[0] = -each.speed[0]
82                 each.speed[1] = -each.speed[1]
83 
84             group.add(each)
85 
86         pygame.display.flip()
87         clock.tick(60)
88 
89 
90 if __name__ == __main__:
91     main()
View Code

本演示圖片素材下載:https://files.cnblogs.com/files/GraceSkyer/20180203.zip

Pygame碰撞檢測