Pygame碰撞檢測
阿新 • • 發佈:2018-02-03
== 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 classView CodeBall(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()
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碰撞檢測