吳裕雄--天生自然python學習筆記:python 用pygame模塊角色類(Sprite)移動與碰撞


角色類(Sprite)
Py game 游戲中有許多組件會重復用到,比如射擊宇宙飛船的游戲中,外星宇宙
飛船可能多達數十艘 , 通過創建“角色類”,可以生成多個相同的對象。
Py game 角色類是游戲設計者最喜愛 的功能,它不但能復制多個對象,還能進行
動畫給制、碰撞偵測等。創建角色類的基本語法為:

 

 

 

 現在我們以上例的自由移動球體為例,來講解創建球體角色類的過程。

通過角色類生成自由移動的球體
紅色球及藍色球角色可獨立自由移動,碰到邊界后反彈。

 

 

import pygame, random, math

class Ball(pygame.sprite.Sprite):
    dx = 0  #x位移量
    dy = 0  #y位移量
    x = 0  #球x坐標
    y = 0  #球y坐標
    def __init__(self, speed, srx, sry, radium, color):
        pygame.sprite.Sprite.__init__(self)
        self.x = srx
        self.y = sry
        self.image = pygame.Surface([radium*2, radium*2])  #創建球的背景區
        self.image.fill((255,255,255))  #球的背景區設為白色
        
        pygame.draw.circle(self.image, color, (radium,radium), radium, 0)   #在背景區上畫實心圓
        self.rect = self.image.get_rect()  #取得球體區域
        self.rect.center = (srx,sry)  #以坐標(srx,xry)作為球體的中心位置
        direction = random.randint(20,70)  #初始移動角度為一個20~70之間的隨機值
        radian = math.radians(direction)  #把從隨機數取得的角度轉換為弧度
        self.dx = speed * math.cos(radian)  #球的水平運動速度
        self.dy = -speed * math.sin(radian)  #球的垂直運動速度
 
    def update(self):
        self.x += self.dx  #計算球新余標
        self.y += self.dy
        self.rect.x = self.x  #移動球圖形
        self.rect.y = self.y
        if(self.rect.left <= 0 or self.rect.right >= screen.get_width()):  #到達左右邊界
            self.dx *= -1  #水平速度變號
        elif(self.rect.top <= 5 or self.rect.bottom >= screen.get_height()-5):  #到達上下邊界
            self.dy *= -1  #垂直速度變號
            
pygame.init()

screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("建立及使用角色")

background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((255,255,255))

allsprite = pygame.sprite.Group()  #建立角色組
ball1 = Ball(8, 100, 100, 10, (0,0,255))  #生成速度為8,藍色球對象
allsprite.add(ball1)  #加入角色組

ball2 = Ball(6, 200, 250, 10, (255,0,0))  #建立紅色球對象
allsprite.add(ball2)  #加入角色組

clock = pygame.time.Clock()

running = True
while running:
    clock.tick(30)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.blit(background, (0,0))  #清除繪圖窗口
    ball1.update()  #對象更新
    ball2.update()
    allsprite.draw(screen)
    pygame.display.update()
pygame.quit()

 

 

碰撞偵測
角色對象提供了多個碰撞偵測的方法 , 以便實現對角色對象的碰撞做不同形式
的偵測,常用的碰撞偵測方法有以下兩種 :
角色對象與角色對象的碰撞
偵測兩個角色對象的碰撞一般使用 colliderect 方法,語法為 :

 

 

下面我們通過上例創建的球體角色來講解兩個角色對象的碰撞偵測
紅色及藍色球體角色會獨立自由移動,碰到邊界會反彈,發生撞時也會反彈 。

 

 

import pygame, random, math

class Ball(pygame.sprite.Sprite):
    dx = 0  #x位移量
    dy = 0  #y位移量
    x = 0  #球x坐標
    y = 0  #球y坐標
 
    def __init__(self, speed, srx, sry, radium, color):
        pygame.sprite.Sprite.__init__(self)
        self.x = srx
        self.y = sry
        self.image = pygame.Surface([radium*2, radium*2])  #繪制球體背景區
        self.image.fill((255,255,255))
        
        pygame.draw.circle(self.image, color, (radium,radium), radium, 0)
        self.rect = self.image.get_rect()  #取得球體區域
        self.rect.center = (srx,sry)  #初始位置
        direction = random.randint(20,70)  #移動角度
        radian = math.radians(direction)  #角度轉為弧度
        self.dx = speed * math.cos(radian)  #球水平運動速度
        self.dy = -speed * math.sin(radian)  #球垂直運動速度
 
    def update(self):
        self.x += self.dx  #計算球新余標
        self.y += self.dy
        self.rect.x = self.x  #移動球圖形
        self.rect.y = self.y
        if(self.rect.left <= 0 or self.rect.right >= screen.get_width()):  #到達左右邊界
            self.dx *= -1  #水平速度變符號
        elif(self.rect.top <= 5 or self.rect.bottom >= screen.get_height()-5):  #到達上下邊界
            self.dy *= -1  #垂直速度變符號

    def collidebounce(self):
        self.dx *= -1
            
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("建立及使用角色")

background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((255,255,255))

allsprite = pygame.sprite.Group()  #建立角色組
ball1 = Ball(8, 100, 100, 15, (0,0,255))  #建立藍色球對象
allsprite.add(ball1)  #加入角色群組
ball2 = Ball(6, 200, 250, 15, (255,0,0))  #建立紅色球對象
allsprite.add(ball2)

clock = pygame.time.Clock()

running = True
while running:
    clock.tick(30)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.blit(background, (0,0))  #清除繪圖窗口
    ball1.update()  #對象更新
    ball2.update()
    allsprite.draw(screen)
    result = pygame.sprite.collide_rect(ball1, ball2)  #偵測碰撞
    if result == True:
        ball1.collidebounce()
        ball2.collidebounce()
    pygame.display.update()
pygame.quit()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM