python-pygame的使用隨筆

外星人大戰---打飛機遊戲

首先必須使用安裝pygame庫文件,而且必須是要跟python的版本一致性才能使用,不然會一直報錯,具體的安裝方法和使用方法見百度文庫https://jingyan.baidu.com/article/3052f5a10b2d4297f31f861c.html
安裝完成後有一個小插曲,一直提示我 pip install --upgrade pip出錯
找了半天發現時我的pip的版本太老了,需要升級,

python -m pip install -U pip
這樣纔是正確的升級方式,詳見python官方文檔。

安裝完成後就開始實現外星人大戰遊戲

alient_invasion.py 文件

import pygame  #首先第一步需要導入pygame文件

#第二步需要初始化程序並創建一個屏幕對象
pygame.init()
screen = pygame.display.set_mode((1200,800)) #創建遊戲的屏幕,寬/高
pygame.display.set_caption("Alient_Invasion") #創建窗口顯示的名稱

#第三步需要創建飛船
#加載飛船圖像並獲取其外接矩形
image = pygame.image.load('images/ship.bmp') #相對路徑文件下的圖片,最好是bmp格式的
rect = self.image.get_rect()
#獲得屏幕的外接矩形
screen_rect =screen.get_rect()
#將每艘飛船放在屏幕底部中央,其實就是給飛船的rect賦值
rect.centerx = self.screen_rect.centerx
rect.bottom = self.screen_rect.bottom
#飛船的移動速度
ship_speed_factor =1.5 
轉換rect.centerx,只能取整數換成能夠取小數
center = float(self.rect.centerx)
#移動標誌
moving_right= False
moving_left = False
# 是否允許發射子彈
allow_bullet = False

#根據移動標識來不斷的移動飛船
def update():
  #rect.right<screen_rect.right用來判斷不會超出屏幕寬度,並根據移動標誌來不斷的移動飛船位置
  if moving_right and rect.right<screen_rect.right:
      center += ship_speed_factor
  if moving_left and rect.left>0:
      center -= ship_speed_factor
  #根據center 更新飛船的rect對象
  rect.centerx = center

def blitme(self):
    '''在指定的位置繪製飛船'''
    screen.blit(image,rect)

#第四步:開始遊戲的主循環   ps:之所以需要死循環,是因爲需要不斷的更新遊戲窗口中的變動,包含子彈的移動,飛船的移動,事件的獲取等等
while True:

    #遍歷pygame.event.get()方法來獲取事件並監聽鍵盤和鼠標的事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
           sys.exit()
        #捕獲到鍵盤按下時
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,ship)  #此方法的實現在gamefunction.py 文件中,底部有寫到
          # 捕獲到鍵盤松開時
        elif event.type == pygame.KEYUP:
            check_keyup_events(event,ship)

    #不斷獲取鍵盤事件並移動飛船位置
    update()

    #每次循環時都重新繪製屏幕
    screen.fill(settings.bg_color)
    #調用繪製飛船的方法
    blitme()
    #使其可見
    pygame.display.flip()
gamefunction.py 文件
#響應按鍵時的處理
def check_keydown_events(event,ship):
    if event.key == pygame.K_RIGHT:
        # 向右移動飛船
        moving_right = True
    elif event.key == pygame.K_LEFT:
        # 向左移動飛船
        moving_left = True
    elif event.key == pygame.K_SPACE:
        #允許發射子彈
        allow_bullet = True
#響應按鍵鬆開時的處理
def check_keyup_events(event):
    if event.key == pygame.K_RIGHT:
        # 向右移動飛船
        moving_right = False
    elif event.key == pygame.K_LEFT:
        # 向左移動飛船
        moving_left = False
    elif event.key == pygame.K_SPACE:
        #允許發射子彈
        allow_bullet = True

這樣,飛船和屏幕的處理以及響應按鍵就處理完成了,但是想要發射子彈怎麼辦?

首先需要創建一個子彈的類

bullet.py文件

from pygame.sprite import Sprite
class Bullet(Sprite):
    '''一個對飛船發射的子彈管理的類,繼承Sprite類 '''
    def __init__(self,settings,screen,ship):
        '''在飛船所處的位置創建一個子彈類'''
        super(Bullet,self).__init__()
        self.screen = screen
        #在(0,0)處創建一個子彈的矩形,再設置其到正確的位置
        self.rect = pygame.Rect(0,0,settings.bullet_width,settings.bullet_height)
        self.rect.centerx = ship.center
        self.rect.top = ship.rect.top
        #存儲用小數表示的子彈位置
        self.y = float(self.rect.y)

        self.color = settings.bullet_color
        self.speed_factor = settings.bullet_speed_factor

    def update(self):
        '''向上移動子彈'''
        self.y -=self.speed_factor
        self.rect.y = self.y

    #繪製子彈
    def draw_bullet(self):
        pygame.draw.rect(self.screen,self.color,self.rect)

創建完成後在主文件alient_invasion.py 文件中

#創建一個用於存儲子彈的編組
bullets = Group()

#讓飛船發射子彈
def allow_bullets():
    if allow_bullet:
        if len(bullets) == 0:
            new_bullet = Bullet(settings,screen,ship) #初始化子彈類
            bullets.add(new_bullet) #將初始化的子彈類放入存儲子彈的編組中
        elif len(bullets)>0:
            #設置子彈的速度,讓第一顆子彈移動到700時發射第二顆子彈,實際上讓子彈的速度變快,最大不超過800
             for bullet in bullets:
                if(bullet.rect.bottom == 700):
                    new_bullet = Bullet(settings, screen, ship)
                    bullets.add(new_bullet)

然後在遊戲的主循環中添加

#發射子彈

allow_bullets()
#不斷的更新子彈移動

bullets.update()

#在飛船後面重繪所有子彈,
for bullet in bullets.sprites():
    bullet.draw_bullet()

# 刪除已消失的子彈
for bullet in bullets:
    if bullet.rect.bottom <= 0:
        bullets.remove(bullet)

至此子彈設置完成,其實就是用for循環不斷的把每一個子彈(繼承Sprite類)的類初始化後,放入用於存儲子彈的編組Group()中

然後用for循環 不斷更新每一個Group()中的子彈的對象,比如刪除,移動位置等

最後還是用for循環使每一個子彈可見。

參考飛船的實現,可以實現敵機,並且讓敵機發射子彈,具體的實現方式不細訴。

第一次寫,寫的比較亂,這個是在不同的類中整合出來的,

可能看着不習慣,不過理解了原理就好了

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章