pygame學習筆記(5):遊戲精靈

來源:互聯網
上載者:User
據說在任天堂FC時代,精靈的作用相當巨大,可是那時候只知道怎麼玩超級瑪麗、魂鬥羅,卻對精靈一點也不知。pygame.sprite.Sprite就是Pygame裡面用來實現精靈的一個類,使用時,並不需要對它執行個體化,只需要繼承他,然後按需寫出自己的類就好了,因此非常簡單實用。

一、什麼是精靈

精靈可以認為成是一個個小圖片,一種可以在螢幕上移動的繪圖物件,並且可以與其他繪圖物件互動。精靈映像可以是使用pygame繪製函數繪製的映像,也可以是原來就有的影像檔。

二、sprite中主要且常用的變數有以下幾個:更多詳細的見http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Sprite
self.image這個負責顯示什麼。如self.image=pygame.Surface([x,y])說明該精靈是一個x,y大小的距形,self.image=pygame.image.load(filename)說明該精靈調用顯示filename這個圖片檔案。
複製代碼 代碼如下:


self.image.fill([color]),負責對self.image著色,如self.image=pygame.Surface([x,y])
self.image.fill([255,0,0])


對x,y距形填充紅色。
self.rect負責在哪裡顯示。一般來說,先用self.rect=self.image.get_rect()獲得image距形大小,然後給self.rect設定顯示的位置,一般用self.rect.topleft(topright、bottomleft、bottomright)來設定某一個角的顯示位置。另外,self.rect.top、self.rect.bottom、self.rect.right、self.rect.left分別表示上下左右。
self.update 負責使精靈行為生效。
Sprite.add 添加精靈到group中去。
Sprite.remove 從group中刪除
Sprite.kill 從groups中全部刪除精靈
Sprite.alive 判斷精靈是否屬於groups

三、建立一個簡單的精靈

所有精靈在建立時都是從pygame.sprite.Sprite中繼承的。

(1)做一個精靈,繪製一個寬30、高30的距形,具體代碼如下:

複製代碼 代碼如下:


class Temp(pygame.sprite.Sprite):
def __init__(self,color,initial_position):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([30,30])
self.image.fill(color)
self.rect=self.image.get_rect()
self.rect.topleft=initial_position

這裡逐句進行一下分析,pygame.sprite.Sprite.__init__(self)完成初始化。self.image = pygame.Surface([30,30])定義顯示30*30的一個距形surface。self.image.fill(color)用color來填充顏色。self.rect=self.image.get_rect()擷取self.image大小。self.rect.topleft=initial_position確定左上方顯示位置,當然也可以用topright、bottomrigh、bottomleft來分別確定其他幾個角的位置。精靈的顯示,在一個640*480大小的白色表單[50,100]的位置繪製一個30*30大小的紅色距形,完整代碼如下:
複製代碼 代碼如下:


import pygame,sys
pygame.init()
class Temp(pygame.sprite.Sprite):
def __init__(self,color,initial_position):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([30,30])
self.image.fill(color)
self.rect=self.image.get_rect()
self.rect.topleft=initial_position
screen=pygame.display.set_mode([640,480])
screen.fill([255,255,255])
b=Temp([255,0,0],[50,100])
screen.blit(b.image,b.rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()


(2)做一個精靈,顯示內容為某一圖片,這裡以前面用過的小車圖片為例,代碼如下:
複製代碼 代碼如下:


import pygame,sys
pygame.init()
class Car(pygame.sprite.Sprite):
def __init__(self,filename,initial_position):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load(filename)
self.rect=self.image.get_rect()
#self.rect.topleft=initial_position
self.rect.bottomright=initial_position
print self.rect.right

screen=pygame.display.set_mode([640,480])
screen.fill([255,255,255])
fi='ok1.jpg'
b=Car(fi,[150,100])
screen.blit(b.image,b.rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()


這段代碼與(1)的不同之處在於self.image定義為pygame.image.load(filename),用來顯示filename檔案,本代碼使用了ok1.jpg檔案,並定義了小車右底角的顯示位置是[150,100]。

三、學習精靈組

(1)使用精靈在螢幕上放多個映像,這種方法沒用利用精靈組的概念,而是利用了list來產生每一個精靈。Cargroup用來儲存不同位置的Car,screen.blit(carlist.image,carlist.rect)逐個顯示每一個精靈。具體見代碼:

複製代碼 代碼如下:


import pygame,sys
pygame.init()
class Car(pygame.sprite.Sprite):
def __init__(self,filename,initial_position):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load(filename)
self.rect=self.image.get_rect()
self.rect.bottomright=initial_position


screen=pygame.display.set_mode([640,480])
screen.fill([255,255,255])
fi='ok1.jpg'
locationgroup=([150,200],[350,360],[250,280])
Cargroup=[]
for lo in locationgroup:
Cargroup.append(Car(fi,lo))
for carlist in Cargroup:
screen.blit(carlist.image,carlist.rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()


具體效果見圖:

(2)使用精靈組來實現多個映像。上面精靈是存在一個列表中,很方便,就是有點不太好用。除了精靈,pygame還提供了精靈組,它很適合處理精靈列表,有添加,移除,繪製,更新等方法。具體如下:http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Sprite
Group.sprites 精靈組
Group.copy 複製
Group.add 添加
Group.remove 移除
Group.has 判斷精靈群組成員
Group.update 更新
Group.draw 位塊顯示
Group.clear - 繪製背景
Group.empty 清空
同樣還是上面的這個例子,這裡用精靈組來實現。

複製代碼 代碼如下:


import pygame,sys
pygame.init()
class Car(pygame.sprite.Sprite):
def __init__(self,filename,initial_position):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load(filename)
self.rect=self.image.get_rect()
self.rect.bottomright=initial_position
screen=pygame.display.set_mode([640,480])
screen.fill([255,255,255])
fi='ok1.jpg'
locationgroup=([150,200],[350,360],[250,280])
Cargroup=pygame.sprite.Group()
for lo in locationgroup:
Cargroup.add(Car(fi,lo))

for carlist in Cargroup.sprites():
screen.blit(carlist.image,carlist.rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()


兩個例子都是在[150,200],[350,360],[250,280]三個位置顯示三輛小車,不同之處第一個用的是list,第二個用的是精靈組。差別就在幾句話上,一是Cargroup=pygame.sprite.Group()定義Cargroup為精靈組,二是Cargroup.add(Car(fi,lo))用add代替了append,三是for carlist in Cargroup.sprites()這句中逐個顯示精靈,這裡試了一下,直接用for carlist in Cargroup也是可以的。精靈組的代碼是高度最佳化過了,常常比列表還快。插入和刪除都是常見的操作,代碼還可以避免記憶體在迴圈中反覆消耗。

四、動畫

利用精靈組做動畫會顯得比較方便,這裡我們首先讓上面的三輛小車運動起來。
(1)三輛小車以不同的速度前行,利用random.choice隨機產生[-10,-1]之間的值作為速度讓小車從下向上運動,並且當到達頂部時,再從底部出現。代碼如下:

複製代碼 代碼如下:


import pygame,sys
from random import *
pygame.init()
class Car(pygame.sprite.Sprite):
def __init__(self,filename,initial_position,speed):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load(filename)
self.rect=self.image.get_rect()
self.rect.topleft=initial_position
self.speed=speed
def move(self):
self.rect=self.rect.move(self.speed)
if self.rect.bottom < 0: #當小車底部到達視窗頂部時,讓小車從下面出來
self.rect.top=480
screen=pygame.display.set_mode([640,480])
screen.fill([255,255,255])
fi='ok1.jpg'
locationgroup=([150,200],[350,300],[250,200])
Cargroup=pygame.sprite.Group()
for lo in locationgroup:
speed=[0,choice([-10,-1])]
Cargroup.add(Car(fi,lo,speed))

while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()
pygame.time.delay(20)
screen.fill([255,255,255])
for carlist in Cargroup.sprites():
carlist.move()
screen.blit(carlist.image,carlist.rect)
pygame.display.update()

(2)可以通過左右鍵控制三輛小車的左右移動,按左鍵向左移動,當到達最左邊時,不再移動,按右鍵向右移動,當到達最右邊時,不再移動。具體代碼如下:
複製代碼 代碼如下:


import pygame,sys
from random import *
pygame.init()
class Car(pygame.sprite.Sprite):
def __init__(self,filename,initial_position,speed):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load(filename)
self.rect=self.image.get_rect()
self.rect.topleft=initial_position
self.speed=speed
def move(self):
self.rect=self.rect.move(self.speed)
if self.rect.bottom < 0:
self.rect.top=480
def moveleft(self):
self.rect.left=self.rect.left-10
if self.rect.left<0:
self.rect.left=0
def moveright(self):
self.rect.right=self.rect.right+10
if self.rect.right>640:
self.rect.right=640
screen=pygame.display.set_mode([640,480])
screen.fill([255,255,255])
fi='ok1.jpg'
locationgroup=([150,200],[350,300],[250,200])
Cargroup=pygame.sprite.Group()
for lo in locationgroup:
speed=[0,choice([-10,-1])]
Cargroup.add(Car(fi,lo,speed))

while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key==pygame.K_LEFT:
for carlist in Cargroup.sprites():
carlist.moveleft()
screen.blit(carlist.image,carlist.rect)
if event.key==pygame.K_RIGHT:
for carlist in Cargroup.sprites():
carlist.moveright()
screen.blit(carlist.image,carlist.rect)
pygame.time.delay(20)
screen.fill([255,255,255])
for carlist in Cargroup.sprites():
carlist.move()
screen.blit(carlist.image,carlist.rect)
pygame.display.update()

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.