欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用pygame完成動畫精靈和碰撞檢測

 更新時間:2021年04月19日 17:00:03   作者:噗噗bug  
這篇文章主要介紹了利用pygame完成動畫精靈和碰撞檢測,代碼詳細(xì),內(nèi)容豐富,對于想要學(xué)習(xí)pygame的朋友來講是一個不錯的練習(xí),需要的朋友可以參考下

動畫精靈和碰撞檢測

一、動畫精靈

動畫精靈:四處移動的單個圖像或圖像部分稱為動畫精靈(sprite),pygame有一個特殊的模塊幫助跟蹤屏幕上移動的大量圖像。利用這個模塊,可以更容易地移動圖形對象。

具備特征:

  • 圖像(image):為動畫精靈顯示的圖片。
  • 矩形區(qū)(rect):包含動畫精靈的矩形區(qū)域。

①、一堆沙灘球都反彈

Pygame 的 sprite 模塊提供了一個動畫精靈基類Sprite,基于pygame.sprite.Sprite 來創(chuàng)建自己的子類。

這里用了常規(guī)的python列表

import sys, pygame
class MyBallClass(pygame.sprite.Sprite):
    def __init__(self, image_file, location):
        pygame.sprite.Sprite.__init__(self)        #初始化動畫精靈
        self.image = pygame.image.load(image_file) #加載圖片
        self.rect = self.image.get_rect()          #得到定義圖像邊界矩形
        self.rect.left, self.rect.top = location   #設(shè)置球的初始位置
#設(shè)置窗口大小和顏色    
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
screen.fill([255, 255, 255])
img_file = "beach_ball.png"
balls = []
#將球增加到列表
for row in range(0, 3):
    for column in range(0, 3):
        location = [column * 180 + 10, row * 180 + 10]
        ball = MyBallClass(img_file, location)
        balls.append(ball)
for ball in balls:
    screen.blit(ball.image, ball.rect)
pygame.display.flip()
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
pygame.quit()
 

顯示效果:

②、讓小球動起來

move() 方法

創(chuàng)建一個新的類方法

 def move(self):
        self.rect = self.rect.move(self.speed)
        #碰到窗口左右兩邊
        if self.rect.left < 0 or self.rect.right > width:
            self.speed[0] = -self.speed[0]
        #碰到窗口上下兩邊
        if self.rect.top < 0 or self.rect.bottom > height:
            self.speed[1] = -self.speed[1]
###
其中 self.speed告訴對象要移動多遠(yuǎn),包含2個列表。
import sys, pygame
from random import *
class MyBallClass(pygame.sprite.Sprite):
    def __init__(self, image_file, location, speed):
        pygame.sprite.Sprite.__init__(self)        #初始化動畫精靈
        self.image = pygame.image.load(image_file) #加載圖片
        self.rect = self.image.get_rect()          #得到定義圖像邊界矩形
        self.rect.left, self.rect.top = location   #設(shè)置球的初始位置
        self.speed = speed                         #創(chuàng)建一個速度
    def move(self):
        self.rect = self.rect.move(self.speed)
        if self.rect.left < 0 or self.rect.right > width:
            self.speed[0] = -self.speed[0]
        if self.rect.top < 0 or self.rect.bottom > height:
            self.speed[1] = -self.speed[1]
#設(shè)置窗口大小和顏色    
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
screen.fill([255, 255, 255])
img_file = "beach_ball.png"
balls = []
#將球增加到列表
for row in range(0, 3):
    for column in range(0, 3):
        location = [column * 180 + 10, row * 180 + 10]
        speed = [choice([-2, 2]), choice([-2, 2])]     #讓每個球變得隨機性
        ball = MyBallClass(img_file, location, speed)
        print("y = ", ball.rect)
        balls.append(ball)
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    #這里不是單獨擦除(覆蓋各個球),直接用白色填充窗口,重新繪制
    pygame.time.delay(20)
    screen.fill([255, 255, 255])
    for ball in balls:
        ball.move()
        screen.blit(ball.image, ball.rect)
    pygame.display.flip()        
pygame.quit()

二、碰撞檢測

上面的動畫,僅僅只是移動和反彈,球與球之間的碰撞還不能反彈.

Pygame 中已經(jīng)內(nèi)置有這種碰撞檢測。

Pygame 還提供了一種方法對動畫精靈分組。 Pygame 的 group 類。例如,在保齡球游戲中,所有球瓶可能在一組,球則在另一組。

動畫精靈模塊的spritecollide()函數(shù)用來檢測某個精靈是否與制定組的其他精靈發(fā)生碰撞,

這個函數(shù)的形式如下:

spritecollide(被檢測的精靈(sprite),指定組(group),是否重疊(False))

要檢查組中精靈之間的碰撞:

  • 從這個組中刪除這個精靈;
  • 檢查這個精靈與組中其他精靈之間的碰撞; 
  • 再把這個精靈添加回原來的組中。 
:為什么要先從組刪除?

答:如果開始時沒有從組中刪除這個精靈,spritecollide() 會檢測到這個精靈與它自身發(fā)生了碰撞,因為它也在這個組中

import sys, pygame
from random import *
class MyBallClass(pygame.sprite.Sprite):
    def __init__(self, image_file, location, speed):
        pygame.sprite.Sprite.__init__(self)        #初始化動畫精靈
        self.image = pygame.image.load(image_file) #加載圖片
        self.rect = self.image.get_rect()          #得到定義圖像邊界矩形
        self.rect.left, self.rect.top = location   #設(shè)置球的初始位置
        self.speed = speed                         #創(chuàng)建一個速度
    def move(self):
        self.rect = self.rect.move(self.speed)
        if self.rect.left < 0 or self.rect.right > width:
            self.speed[0] = -self.speed[0]
        if self.rect.top < 0 or self.rect.bottom > height:
            self.speed[1] = -self.speed[1]
def animate(group):
    screen.fill([255, 255, 255])
    for ball in group:
        group.remove(ball)      #從組刪除精靈
        #檢查精靈與組的碰撞
        if pygame.sprite.spritecollide(ball, group, False): 
            ball.speed[0] = -ball.speed[0]
            ball.speed[1] = -ball.speed[1]
        group.add(ball)
        ball.move()
        screen.blit(ball.image, ball.rect)
    pygame.display.flip()
    pygame.time.delay(20)
#設(shè)置窗口大小和顏色    
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
screen.fill([255, 255, 255])
img_file = "beach_ball.png"
group = pygame.sprite.Group()   #創(chuàng)建精靈組
#將球增加到列表
for row in range(0, 2):
    for column in range(0, 2):
        location = [column * 180 + 10, row * 180 + 10]
        speed = [choice([-2, 2]), choice([-2, 2])]     #讓每個球變得隨機性
        ball = MyBallClass(img_file, location, speed)
        group.add(ball)
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    #這里不是單獨擦除(覆蓋各個球),直接用白色填充窗口,重新繪制
    pygame.time.delay(20)
    screen.fill([255, 255, 255])
    animate(group)   
pygame.quit()

上述代碼存在問題:

  • 球碰撞時,它們會“顫抖”或者發(fā)生兩次 碰撞;
  • 有時球會“卡”在窗口邊界上,顫抖一段時間。

可能原因:上述代碼是先移動一個球,檢查碰撞,然后移動球在檢查下一個。這樣子可能造成球的滯后性

修改animate函數(shù)()
def animate(group):
    screen.fill([255, 255, 255])
    for ball in group:
        ball.move()
    for ball in group:
        group.remove(ball)      #從組刪除精靈
        #檢查精靈與組的碰撞
        if pygame.sprite.spritecollide(ball, group, False): 
            ball.speed[0] = -ball.speed[0]
            ball.speed[1] = -ball.speed[1]
        group.add(ball)
        #ball.move()
        screen.blit(ball.image, ball.rect)
    pygame.display.flip()
    pygame.time.delay(20)

矩形碰撞與像素完美結(jié)合

在觀察可以方向,球“碰撞”時并不是完全接觸。因為 spritecollide() 沒有使用球的圓形輪廓來檢測碰撞。它使用了球的 rect,也就是球的外圍矩形。

如果希望球的圓形部分(而不是矩形邊界)真正接觸時球才會相互反彈,就必須使用一種稱為“像素完美碰撞檢測 ” 的 方 法。

三、統(tǒng)計時間

在之前我們都用time.delay(50)來控制動畫運行的快慢,

pygame.time.delay(50)

在計算機圖形學(xué)中,每個動畫步叫做一幀,游戲程序員討論圖形更新的快慢時都會提到幀速率(每秒幀數(shù),fps)

問:要怎么控制未知代碼運行時間?

——Pygame 的 time 模塊提供了這樣的工具:一個名為 Clock 的類。

用 pygame.time.Clock() 控制幀速率

并不是向每個循環(huán)增加一個延遲,  pygame.time.Clock() 會控制每個循環(huán)多長時間運行一次。

clock = pygame.time.Clock()
clock.tick(60)
#此處的60指示:這個循環(huán)應(yīng)當(dāng)每秒運行 60 次。
每秒 60 個循環(huán)(或幀)時,每個循環(huán)需要 1000 / 60 = 16.66 ms(大約 17 ms)。
如果循環(huán)中的代碼運行時間超過 17 ms,在 clock 指出開始下一次循環(huán)時當(dāng)前循環(huán)將無法完成。

檢查幀速率

 clock.get_fps()    知道程序能以多快的速度運行,檢查幀速率

調(diào)整幀速率

假設(shè)設(shè)置運行 clock.tick(30),每秒39幀,但 clock.get_fps()檢測實際得到的速率為20fps,說明每個循環(huán)運行的時間比預(yù)計的長,這樣達(dá)不到原來要的效果,需要調(diào)整幀速率。

以小球為例,原來每秒30幀,可以將小球移動比較遠(yuǎn),但是目前的代碼每秒只能運行20幀,達(dá)不到預(yù)期的要求,需要在限有的時間內(nèi)到達(dá)移動的距離,就需要更改小球移動的速度。可以按期望幀頻率與實際幀速率的比值來增加

如果小球?qū)ο缶嚯x是10,期望的幀速率是30fps,程序?qū)嶋H運行速率為20fps. 

object_speed = current_speed * (desired fps / actual fps)
object_speed = 10 * (30 / 20)
object_speed = 15

 沙灘球程序中使用 Clock 和 get_fps()

import sys, pygame
from random import *
class MyBallClass(pygame.sprite.Sprite):
    def __init__(self, image_file, location, speed):
        pygame.sprite.Sprite.__init__(self)        #初始化動畫精靈
        self.image = pygame.image.load(image_file) #加載圖片
        self.rect = self.image.get_rect()          #得到定義圖像邊界矩形
        self.rect.left, self.rect.top = location   #設(shè)置球的初始位置
        self.speed = speed                         #創(chuàng)建一個速度
    def move(self):
        self.rect = self.rect.move(self.speed)
        if self.rect.left < 0 or self.rect.right > width:
            self.speed[0] = -self.speed[0]
        if self.rect.top < 0 or self.rect.bottom > height:
            self.speed[1] = -self.speed[1]
def animate(group):
    screen.fill([255, 255, 255])
    for ball in group:
        ball.move()
    for ball in group:
        group.remove(ball)      #從組刪除精靈
        #檢查精靈與組的碰撞
        if pygame.sprite.spritecollide(ball, group, False): 
            ball.speed[0] = -ball.speed[0]
            ball.speed[1] = -ball.speed[1]
        group.add(ball)
        screen.blit(ball.image, ball.rect)
    pygame.display.flip()
    pygame.time.delay(20)
#設(shè)置窗口大小和顏色    
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
screen.fill([255, 255, 255])
img_file = "beach_ball.png"
clock = pygame.time.Clock()
group = pygame.sprite.Group()   #創(chuàng)建精靈組
#將球增加到列表
for row in range(0, 2):
    for column in range(0, 2):
        location = [column * 180 + 10, row * 180 + 10]
        speed = [choice([-4, 4]), choice([-4, 4])]     #讓每個球變得隨機性
        ball = MyBallClass(img_file, location, speed)
        group.add(ball)
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            frame_rate = clock.get_fps()
            print( "frame rate = ", frame_rate)   
    animate(group)   
    clock.tick(30)
pygame.quit()

到此這篇關(guān)于利用pygame完成動畫精靈和碰撞檢測的文章就介紹到這了,希望對大家有幫助,更多相關(guān)pygame內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!

相關(guān)文章

  • Jupyter?Notebook界面漢化完整步驟

    Jupyter?Notebook界面漢化完整步驟

    這篇文章主要給大家介紹了關(guān)于Jupyter?Notebook界面漢化的相關(guān)資料,設(shè)置成中文界面后非常利于操作,文中介紹的方法非常簡單,需要的朋友可以參考下
    2023-09-09
  • Python中用戶輸入與while循環(huán)詳情

    Python中用戶輸入與while循環(huán)詳情

    這篇文章主要介紹了Python中用戶輸入與while循環(huán)詳情,,包括如何接收用戶輸入并進行處理,在程序滿足一定的條件時讓程序一直運行,通過獲取用戶輸入并學(xué)會控制程序在用戶想要結(jié)束時退出循環(huán),即可編寫出交互式程序,下文詳細(xì)內(nèi)容介紹,需要的朋友可以參考一下
    2022-03-03
  • python3 Scrapy爬蟲框架ip代理配置的方法

    python3 Scrapy爬蟲框架ip代理配置的方法

    Scrapy是用python實現(xiàn)的一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。使用Twisted高效異步網(wǎng)絡(luò)框架來處理網(wǎng)絡(luò)通信。這篇文章主要介紹了python3 Scrapy爬蟲框架ip代理配置,需要的朋友可以參考下
    2020-01-01
  • pyscript的簡單應(yīng)用實現(xiàn)

    pyscript的簡單應(yīng)用實現(xiàn)

    本文主要介紹了pyscript的簡單應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • python之隨機數(shù)函數(shù)的實現(xiàn)示例

    python之隨機數(shù)函數(shù)的實現(xiàn)示例

    這篇文章主要介紹了python之隨機數(shù)函數(shù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 一文帶你了解Python中的生成器和迭代器

    一文帶你了解Python中的生成器和迭代器

    生成器(Generators)和迭代器(Iterators)是 Python 中用于處理序列數(shù)據(jù)的強大工具,本文主要來和大家介紹一下它們的具體使用,方便大家更好的了解它們,需要的可以學(xué)習(xí)下
    2022-03-03
  • 教你pycharm快速添加遠(yuǎn)程環(huán)境的詳細(xì)過程

    教你pycharm快速添加遠(yuǎn)程環(huán)境的詳細(xì)過程

    今天通過本文給大家分享pycharm快速添加遠(yuǎn)程環(huán)境的過程,通過在setting中選擇設(shè)置符號add,具體詳細(xì)過程跟隨小編一起通過本文學(xué)習(xí)下吧
    2021-07-07
  • python爬取B站關(guān)注列表及數(shù)據(jù)庫的設(shè)計與操作

    python爬取B站關(guān)注列表及數(shù)據(jù)庫的設(shè)計與操作

    這篇文章主要為大家介紹了python爬取B站關(guān)注列表及數(shù)據(jù)庫的設(shè)計與操作,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • 詳解Python 協(xié)程的詳細(xì)用法使用和例子

    詳解Python 協(xié)程的詳細(xì)用法使用和例子

    這篇文章主要介紹了詳解Python 協(xié)程的詳細(xì)用法和例子,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Python實現(xiàn)對象轉(zhuǎn)換為xml的方法示例

    Python實現(xiàn)對象轉(zhuǎn)換為xml的方法示例

    這篇文章主要介紹了Python實現(xiàn)對象轉(zhuǎn)換為xml的方法,結(jié)合實例形式分析了Python對象屬性、節(jié)點的操作及與xml相互轉(zhuǎn)換的相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06

最新評論