成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Python學(xué)習(xí)之路11-武裝飛船

李昌杰 / 2306人閱讀

摘要:和標(biāo)志,用于表示飛船是否正在移動,用于實(shí)現(xiàn)飛船在不松開按鍵下連續(xù)移動。重寫了函數(shù),用于繪制飛船模塊該模塊主要是集中處理游戲中發(fā)生的各種事件。函數(shù)用于監(jiān)聽游戲的事件,比如,它表示游戲推出事件和分別表示鍵盤按下與松開事件。

《Python編程:從入門到實(shí)踐》筆記。
本章主要學(xué)習(xí)如何使用pygame編寫一個(gè)簡單的小飛機(jī)打外星人的游戲,由于本人對用python寫游戲并不是特別感興趣,所以主要是看代碼的構(gòu)建和一些編程規(guī)范,代碼會有所簡略。
1. 準(zhǔn)備工作

Python標(biāo)準(zhǔn)庫中并沒有自帶pygame模塊,所以需要自行安裝,可以在控制臺(Windows下是cmd)上使用命令行安裝:pip install pygame。如果你是用的PyCharm,也可以在設(shè)置中安裝:

點(diǎn)擊右邊的加號,在彈出的窗口中輸入pygame,然后安裝即可。

該項(xiàng)目中需要使用一些書中的圖片,這些圖片都可以在 http://www.ituring.com.cn/boo... 中下載到。

2. 游戲基本內(nèi)容

首先需要新建一個(gè)項(xiàng)目,筆者取名為“alien_invasion”,并在該項(xiàng)目的根目錄下新建一個(gè)images文件夾,用于存放項(xiàng)目中用到的圖片。在本節(jié)中,我們將先創(chuàng)建4個(gè)文件:

alien_invasion.py:游戲主程序

settings.py:游戲的配置文件

game_functions.py:存放游戲的控制函數(shù),比如響應(yīng)鼠標(biāo)、鍵盤等

ship.py:飛船類

2.1 alien_invasion.py模塊:

該模塊經(jīng)過重構(gòu)后的代碼如下:

import pygame

import game_functions as gf
from settings import Settings
from ship import Ship

def run_game():
    # 初始化游戲并創(chuàng)建一個(gè)屏幕對象
    pygame.init()   # 初始化背景設(shè)置,讓pygame能正常工作
    ai_settings = Settings()  # 實(shí)例化一個(gè)游戲配置類
    # 返回一個(gè)游戲窗口
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")   # 給這個(gè)游戲窗口設(shè)置一個(gè)標(biāo)題

    ship = Ship(ai_settings, screen)   # 實(shí)例化一個(gè)飛船類,傳入了參數(shù)ai_settings和屏幕對象screen

    # 開始游戲的主循環(huán)
    while True:
        gf.check_events(ship)  # 用于響應(yīng)游戲事件
        ship.update()   # 更新飛船狀態(tài)
        gf.update_screen(ai_settings, screen, ship)  # 重繪screen

run_game()

①代碼第1行導(dǎo)入pygame模塊,它包含開發(fā)游戲所需的基本功能;

②代碼3到5行導(dǎo)入的是自行編寫且經(jīng)過重構(gòu)的模塊;

③第9行代碼執(zhí)行游戲的初始化工作,比如初始化游戲背景等;

④第10行實(shí)例化一個(gè)游戲配置類,用于配置游戲參數(shù),該類的具體實(shí)現(xiàn)見本篇后面的內(nèi)容;

⑤代碼第12-13行用于生成一個(gè)名為screen的顯示窗口,長寬從配置對象ai_settings中讀出;display.set_mode()返回的是一個(gè)surface,在pygame中,surface是屏幕的一部分,用于顯示游戲元素,這里的screen表示的是整個(gè)游戲窗口。我們激活游戲的循環(huán)后,每經(jīng)過一次循環(huán)pygame都將重繪這個(gè)screen

⑥代碼第20行的check_events()函數(shù)用于響應(yīng)游戲中發(fā)生的時(shí)間,比如鼠標(biāo),鍵盤,關(guān)閉窗口等。

⑦代碼第21行用于更新飛船的信息,如飛船位置

⑧最后一行用于啟動游戲,即初始化游戲,并開始主循環(huán)。

2.2 settings.py模塊

該文件主要是游戲的配置信息,存放游戲的各種參數(shù)。

class Settings:
    """存儲《外星人入侵》的所有設(shè)置的類"""

    def __init__(self):
        """初始化游戲的設(shè)置"""
        # 屏幕設(shè)置
        self.screen_width = 1200   # 游戲窗口寬度
        self.screen_height = 800   # 游戲窗口高度
        self.bg_color = (230, 230, 230)  # 游戲背景顏色
        self.ship_speed_factor = 1.5  # 飛船的移動速度

這里故意將飛船的速度設(shè)置為浮點(diǎn)數(shù),也可以是整數(shù)。在設(shè)置游戲元素的位置時(shí),如果直接使用浮點(diǎn)數(shù),則只會截取整數(shù)部分。

2.3 ship.py模塊

該模塊描述了一個(gè)飛船類的基本內(nèi)容:

import pygame

class Ship:
    def __init__(self, ai_settings, screen):
        """初始化飛機(jī)并設(shè)置其初始位置"""
        self.screen = screen
        self.ai_settings = ai_settings

        # 加載飛機(jī)圖片并獲取其外接矩形
        self.image = pygame.image.load("images/ship.bmp")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # 將每艘新飛船放在屏幕底部中央
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        # 自定義一個(gè)能存儲浮點(diǎn)數(shù)的臨時(shí)變量,x坐標(biāo)
        self.center = float(self.rect.centerx)
        
        # 標(biāo)志,用于表示是否正在向某個(gè)方向移動
        self.moving_right = False
        self.moving_left = False

    def update(self):
        """根據(jù)移動標(biāo)志調(diào)整飛船的位置"""
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.center += self.ai_settings.ship_speed_factor
        if self.moving_left and self.rect.left > 0:
            self.center -= self.ai_settings.ship_speed_factor

        # 用臨時(shí)變量更新rect的centerx,截取截取整數(shù)部分
        self.rect.centerx = self.center

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

__init__()中的self.center屬性,代碼將self.rect.centerx即飛船的中心x坐標(biāo)轉(zhuǎn)換成浮點(diǎn)數(shù),并將其存儲在self.center中。之所以轉(zhuǎn)換成浮點(diǎn)數(shù),是因?yàn)樵?b>settings.py文件中,我們將飛船移動速度設(shè)置成了浮點(diǎn)數(shù)。

self.moving_rightself.moving_left標(biāo)志,用于表示飛船是否正在移動,用于實(shí)現(xiàn)飛船在不松開按鍵下連續(xù)移動。

udpate()方法,用于增減飛船的中心位置x坐標(biāo)(因?yàn)轱w船只能在底部移動,所以不用改y坐標(biāo)),并防止飛船移動出游戲窗口。

④重寫了blitme()函數(shù),用于繪制飛船

2.4 game_functions.py模塊

該模塊主要是集中處理游戲中發(fā)生的各種事件。

import sys
import pygame

def check_keydown_event(event, ship):
    """響應(yīng)按下按鍵"""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    if event.key == pygame.K_LEFT:
        ship.moving_left = True

def check_keyup_event(event, ship):
    """響應(yīng)松開按鍵"""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    if event.key == pygame.K_LEFT:
        ship.moving_left = False

def check_events(ship):
    """響應(yīng)按鍵和鼠標(biāo)事件"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_event(event, ship)

        elif event.type == pygame.KEYUP:
            check_keyup_event(event, ship)

def update_screen(ai_settings, screen, ship):
    """更新屏幕上的圖像,并切換到新屏幕"""
    # 每次循環(huán)時(shí)都重繪屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()

    # 讓最近繪制的屏幕可見
    pygame.display.flip()

①在pygame中,用K_RIGHTK_LEFT表示方向按鍵,其實(shí)鍵盤上每個(gè)鍵在pygame中都有所對于,以K_開頭。check_keydown_event()函數(shù)和check_keyup_event()函數(shù)都是對下面的check_event()的進(jìn)一步簡化,這兩個(gè)函數(shù)的代碼均可以放在check_event()中,但這樣代碼將會很臃腫,結(jié)構(gòu)不清晰。

check_event()函數(shù)用于監(jiān)聽游戲的事件,比如pygame.QUIT,它表示游戲推出事件;pygame.KEYDOWNpygame.KEYUP分別表示鍵盤按下與松開事件。本次大循環(huán)中(外層的while循環(huán))發(fā)生的所有事件都存儲在pygame.event中,我們使用get()方法獲得這些事件。

③在update_screen()函數(shù)中,我們使用screenfill()方法填充窗體的背景色,調(diào)用blitme()方法來在窗體中繪制飛船,最后,調(diào)用pygame.display.flip()方法讓最近的繪制在窗體中可見。

2.5 運(yùn)行游戲

現(xiàn)在我們運(yùn)行alien_invasion.py文件,我們將得到如下窗體:

目前功能還比較簡單,只能實(shí)現(xiàn)飛船的左右移動。

3. 添加射擊功能

為了添加射擊功能,需要先添加一個(gè)子彈類。

3.1 Bullet.py
import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):  # 使用精靈
    """一個(gè)對飛船發(fā)射的子彈進(jìn)行管理的類"""

    def __init__(self, ai_settings, screen, ship):
        """在飛船所處的位置創(chuàng)建一個(gè)子彈對象"""
        super(Bullet, self).__init__()
        self.screen = screen

        # 在(0,0)處創(chuàng)建一個(gè)表示子彈的矩形,再設(shè)置正確的位置
        self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
                                ai_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx   # 從飛機(jī)的中央位置射出
        self.rect.top = ship.rect.top           # 從飛機(jī)的頂部射出

        # 存儲用浮點(diǎn)數(shù)表示的子彈位置,因?yàn)樽訌椫辉趛軸上運(yùn)動,所以不需要x坐標(biāo)
        self.y = float(self.rect.y)

        self.color = ai_settings.bullet_color   # 子彈顏色
        self.speed_factor = ai_settings.bullet_speed_factor   # 子彈速度

    def update(self):
        """向上移動子彈"""
        # 更新表示子彈位置的浮點(diǎn)數(shù)值
        self.y -= self.speed_factor
        # 更新表示子彈的rect的位置
        self.rect.y = self.y

    def draw_bullet(self):
        """在屏幕上繪制子彈"""
        pygame.draw.rect(self.screen, self.color, self.rect)

首先我們需要導(dǎo)入pygame模塊以及其中的Sprite類(直譯的話叫做“精靈類”,然而這名字叫的真的很尷尬),它可以讓我們在后面方便批量處理相同類型的同一操作,子彈類繼承自Sprite類。該子彈類并沒有使用圖片,而是直接在screen上繪制矩形用于表示子彈。update()方法用于更新子彈的位置。pygame.draw.rect()用于在screen上繪制子彈。

3.2 修改settings.py

在該模塊中添加子彈類的參數(shù):

class Settings:
    def __init__(self):
        -- snip --
        # 子彈設(shè)置
        self.bullet_speed_factor = 1
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 60, 60, 60
        # 表示窗口中最多允許存在的子彈數(shù),當(dāng)然你也可以將其去掉
        self.bullets_allowed = 3   
3.3 修改game_functions.py

游戲中我們按空格鍵發(fā)射子彈,并發(fā)射子彈的過程多帶帶寫在一個(gè)函數(shù)fire_bullet()中。為了響應(yīng)空格鍵,需要修改check_event()函數(shù)和check_keydown_event()函數(shù),前者只修改了參數(shù),后者在判斷結(jié)構(gòu)中添加了一個(gè)判斷。有了子彈類,那我們還需要在screen中繪制子彈,所以還需要修改update_screen()函數(shù),而子彈自身信息(比如子彈的移動)的修改則放在了一個(gè)新的函數(shù)update_bullets()中。

import sys
import pygame
from Bullet import Bullet

# 新增函數(shù)!
def fire_bullet(ai_settings, screen, ship, bullets):
    """如果還沒有到達(dá)限制,就發(fā)射一顆子彈"""
    # 創(chuàng)建新子彈,并將其加入到編組bullets中
    # 如果你想讓飛船能無限發(fā)射子彈,可以將判斷語句刪除
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)

# 修改了參數(shù)!
def check_keydown_event(event, ship, ai_settings, screen, bullets):
    -- snip --
    # 按空格鍵發(fā)射子彈
    elif event.key == pygame.K_SPACE:
        fire_bullet(ai_settings, screen, ship, bullets)

# 修改了參數(shù)!
def check_events(ai_settings, screen, ship, bullets):
    """響應(yīng)按鍵和鼠標(biāo)事件"""
    for event in pygame.event.get():
        -- snip -- 
        elif event.type == pygame.KEYDOWN:
            # 增加了參數(shù)
            check_keydown_event(event, ship, ai_settings, screen, bullets)
        -- snip --

# 修改了函數(shù)!
def update_screen(ai_settings, screen, ship, bullets):
    -- snip --
    # 繪制子彈
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    -- snip --

# 新增函數(shù)
def update_bullets(bullets):
    """更新子彈的位置,并刪除已消失的子彈"""
    # 更新子彈的位置
    # bullets是個(gè)Group對象,調(diào)用一次update()就會調(diào)用其中所有Sprite對象的update()
    # 相當(dāng)于你不用自己寫for循環(huán)了
    bullets.update()

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

當(dāng)子彈從窗口中消失時(shí),它并沒有從內(nèi)存中消失,如果對于已經(jīng)從屏幕中消失的子彈不做處理的話,時(shí)間一長,子彈數(shù)一多,光子彈一項(xiàng)的內(nèi)存占用就會越來越多(土豪請忽略),雖然只是線性增長,但作為一個(gè)合格的程序員,應(yīng)該避免這種無謂的浪費(fèi)。

3.4 修改alien_invation.py

最后,我們修改主程序,在其中添加一個(gè)pygame.sprite中的Group對象用于表示子彈集合,以及對該對象的操作代碼。

import pygame
from pygame.sprite import Group   # 導(dǎo)入一個(gè)新類

import game_functions as gf
from settings import Settings
from ship import Ship

def run_game():
    -- snip --
    bullets = Group()

    # 開始游戲的主循環(huán)
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        gf.update_bullets(bullets)
        gf.update_screen(ai_settings, screen, ship, bullets)
3.5運(yùn)行新代碼

以下是運(yùn)行截圖:

4. 小結(jié)

自此,我們創(chuàng)建了一個(gè)能開火的小飛機(jī),在下一篇文章中我們將向其中添加外星人。

本篇中的代碼都是經(jīng)過了重構(gòu)后的代碼,但是,當(dāng)我們自己在編程時(shí),如果對某一框架還是小白,搞不清楚該如何組織代碼,那就把所有代碼都寫在一個(gè)或幾個(gè)文件里(雖然這種習(xí)慣很不好),也暫時(shí)不用考慮代碼結(jié)構(gòu)之類的問題,因?yàn)?strong>你的任務(wù)是造東西,而不是寫漂亮代碼,用精巧結(jié)構(gòu),用別人沒看過的語法。兩者能兼?zhèn)洚?dāng)然更好,但每個(gè)人都有當(dāng)小白的時(shí)期,有一定熟練度后,再來考慮代碼重構(gòu)的問題。


迎大家關(guān)注我的微信公眾號"代碼港" & 個(gè)人網(wǎng)站 www.vpointer.net ~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/41790.html

相關(guān)文章

  • Python學(xué)習(xí)之路12-外星人

    摘要:現(xiàn)在開始創(chuàng)建多行外星人。小結(jié)本篇講述了如何在游戲中添加大量相同的元素如何用嵌套循環(huán)來創(chuàng)建元素網(wǎng)格如何控制對象在屏幕上移動的方向以及響應(yīng)事件如何檢測和響應(yīng)元素碰撞如何在游戲中跟蹤統(tǒng)計(jì)信息如何使用標(biāo)志來判斷游戲是否結(jié)束。 《Python編程:從入門到實(shí)踐》筆記。本章主要是對上一篇的繼續(xù),添加外星人,外星人與飛船的交互。 1. 回顧項(xiàng)目 開發(fā)較大的項(xiàng)目時(shí),進(jìn)入每個(gè)開發(fā)階段前回顧一下開發(fā)計(jì)劃,...

    chemzqm 評論0 收藏0
  • Python學(xué)習(xí)之路13-記分

    摘要:之所以這里要添加這四行代碼,其實(shí)是為了當(dāng)你重新開始也就是第二次及以后點(diǎn)擊按鈕游戲時(shí),計(jì)分板能正確顯示。當(dāng)?shù)谝贿\(yùn)行游戲時(shí),沒有這四行也能正確顯示計(jì)分板。 《Python編程:從入門到實(shí)踐》筆記。本篇是Python小游戲《外星人入侵》的最后一篇。 1. 前言 本篇我們將結(jié)束Pygame小游戲《外星人入侵》的開發(fā)。在本篇中,我們將添加如下內(nèi)容: 添加一個(gè)Play按鈕,用于根據(jù)需要啟動游戲以...

    tommego 評論0 收藏0
  • 前端開發(fā)-從入門到Offer - 收藏集 - 掘金

    摘要:一些知識點(diǎn)有哪些方法方法前端從入門菜鳥到實(shí)踐老司機(jī)所需要的資料與指南合集前端掘金前端從入門菜鳥到實(shí)踐老司機(jī)所需要的資料與指南合集歸屬于筆者的前端入門與最佳實(shí)踐。 工欲善其事必先利其器-前端實(shí)習(xí)簡歷篇 - 掘金 有幸認(rèn)識很多在大廠工作的學(xué)長,在春招正式開始前為我提供很多內(nèi)部推薦的機(jī)會,非常感謝他們對我的幫助?,F(xiàn)在就要去北京了,對第一份正式的實(shí)習(xí)工作也充滿期待,也希望把自己遇到的一些問題和...

    sf_wangchong 評論0 收藏0
  • 阿里云推企業(yè)云安全架構(gòu) 11層防護(hù)武裝到“牙齒”

    摘要:年,阿里云在全球范圍內(nèi)率先發(fā)起數(shù)據(jù)保護(hù)倡議。借助阿里云的網(wǎng)絡(luò)溯源,警方最終成功抓捕到名犯罪嫌疑人,將黑客組織一網(wǎng)打盡。過去兩年,阿里云已陸續(xù)協(xié)助警方破獲案件數(shù)十起攻擊相關(guān)案件,抓捕百余人次。9月28日,阿里云正式發(fā)布首個(gè)企業(yè)云安全架構(gòu)和《2017阿里云安全白皮書》(以下簡稱白皮書),企業(yè)可參考架構(gòu)指南和白皮書構(gòu)建安全、穩(wěn)固的信息化架構(gòu)。白皮書將用戶隱私和數(shù)據(jù)安全列為第一原則,并于2015年全...

    Kaede 評論0 收藏0
  • 關(guān)于開發(fā)Python項(xiàng)目的心得總結(jié)

    摘要:最近照著編程從入門到實(shí)踐這本書上的內(nèi)容,開發(fā)了第一個(gè)完整的項(xiàng)目。之前都是用寫一些腳本什么的,這是第一次開發(fā)一個(gè)完整的項(xiàng)目,現(xiàn)將在開發(fā)過程中的一些心得總結(jié)如下。 最近照著《Python編程從入門到實(shí)踐》這本書上的內(nèi)容,開發(fā)了第一個(gè)完整的Python項(xiàng)目。之前都是用Python寫一些腳本什么的,這是第一次開發(fā)一個(gè)完整的項(xiàng)目,現(xiàn)將在開發(fā)過程中的一些心得總結(jié)如下。 這個(gè)Python項(xiàng)目是一個(gè)小...

    zhoutao 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<