Python高级第2课——飞机大战(只读课堂)
歡迎來到“只讀課堂”!
In?[1]:
#這節(jié)課我們來實(shí)戰(zhàn)python:Python游戲開發(fā)In?[2]:
#飛機(jī)大戰(zhàn)In?[3]:
#以下是我們今天的課件以及項(xiàng)目規(guī)劃,如果想直接進(jìn)入課堂,就往下拉。飛機(jī)大戰(zhàn)
創(chuàng)建游戲是趣學(xué)語言的理想方式。看別人玩你編寫的游戲讓你很有滿足感,而編寫簡單的游戲有助于你明白專業(yè)級游戲是怎么編寫出來的。在閱讀本章的過程中,請動手輸入并運(yùn)行代碼,以明白各個代碼塊對整個游戲所做的貢獻(xiàn),并嘗試不同的值和設(shè)置,這樣你將對如何改進(jìn)游戲的交互性有更深入的認(rèn)識。
> 游戲《飛機(jī)大戰(zhàn)》將包含很多不同的文件,因此請?jiān)谀愕南到y(tǒng)中新建一個文件夾,并將其命名為PlaneFight。請務(wù)必將這個項(xiàng)目的所有文件都存儲到這個文件夾中,這樣相關(guān)的import語句才能正確地工作。
規(guī)劃項(xiàng)目
開發(fā)大型項(xiàng)目時,做好規(guī)劃后再動手編寫項(xiàng)目很重要。規(guī)劃可確保你不偏離軌道,從而提高項(xiàng)目成功的可能性。
> 在游戲《飛機(jī)大戰(zhàn)》中,你可以控制著一架最初出現(xiàn)在屏幕底部中央的飛機(jī)。玩家可以使用箭頭鍵左右移動飛機(jī),還可使用空格鍵進(jìn)行射擊。游戲開始時,一群外星人出現(xiàn)在天空中,他們在屏幕中向下移動。玩家的任務(wù)是射殺這些外星人。只要有外星人撞到了玩家的飛機(jī)或到達(dá)了屏幕底部,游戲結(jié)束。
安裝Pygame
1. 手動安裝
- 先下載whl文件
> 下載地址:?https://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame
- 手動安裝
>?pip install pygame?1.9.3?cp36?cp36m?win_amd64.whl
2.?pip安裝
>?pip3 install pygame
> 以上可以使用Linux和Windows系統(tǒng)
Linux系統(tǒng)也可以使用sudo apt install python3-pygame?安裝Python3的版本。
檢測安裝
進(jìn)入Python環(huán)境,執(zhí)行:
```python
>>> import pygame
>>>
```
如果沒有任何輸出,就說明Python導(dǎo)入了Pygame
開始游戲項(xiàng)目
首先創(chuàng)建一個空的Pygame窗口,供后面用來繪制游戲元素,如飛機(jī)和外星人。我們還將讓這個游戲響應(yīng)用戶輸入、設(shè)置背景色以及加載飛機(jī)圖像。
創(chuàng)建Pygame窗口以及響應(yīng)用戶輸入
首先,我們創(chuàng)建一個空的Pygame窗口。使用Pygame編寫的游戲的基本結(jié)構(gòu)如下:
```python
import sys
import pygame
def run_game():
初始化游戲并創(chuàng)建一個屏幕對象
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('PlaneFight')
開始游戲主循環(huán)
while True:
監(jiān)控鍵盤和鼠標(biāo)事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
讓最近繪制的屏幕可見
pygame.display.flip()
run_game()
```
我們導(dǎo)入了模塊sys和pygame。模塊pygame包含開發(fā)游戲所需的功能。玩家退出時,我們將使用模塊sys來退出游戲。
開頭是函數(shù)run_game()?,代碼行pygame.init()初始化背景設(shè)置,讓Pygame能夠正確地工作。
調(diào)用pygame.display.set_mode()來創(chuàng)建一個名為screen的顯示窗口,這個游戲的所有圖形元素都將在其中繪制。實(shí)參(800, 600)是一個元組,指定了游戲窗口的尺寸。通過將這些尺寸值傳遞給pygame.display.set_mode(),我們創(chuàng)建了一個寬800像素、高600像素的游戲窗口(你可以根據(jù)自己的顯示器尺寸調(diào)整這些值)。
對象screen是一個surface。在Pygame中,surface是屏幕的一部分,用于顯示游戲元素。在這個游戲中,每個元素(如外星人或飛機(jī))都是一個surface。display.set_mode()返回的surface表示整個游戲窗口。我們激活游戲的動畫循環(huán)后,每經(jīng)過一次循環(huán)都將自動重繪這個surface。
為訪問Pygame檢測到的事件,我們使用方法pygame.event.get()。所有鍵盤和鼠標(biāo)事件都將促使for循環(huán)運(yùn)行。在這個循環(huán)中,我們將編寫一系列的if語句來檢測并響應(yīng)特定的事件。例如,玩家單擊游戲窗口的關(guān)閉按鈕時,將檢測到pygame.QUIT事件,而我們調(diào)用sys.exit()來退出游戲。
調(diào)用了pygame.display.flip(),命令Pygame讓最近繪制的屏幕可見。在這里,它在每次執(zhí)行while循環(huán)時都繪制一個空屏幕,并擦去舊屏幕,使得只有新屏幕可見。在我們移動游戲元素時,pygame.display.flip()將不斷更新屏幕,以顯示元素的新位置,并在原來的位置隱藏元素,從而營造平滑移動的效果。
設(shè)置背景色
Pygame默認(rèn)創(chuàng)建一個黑色屏幕,太乏味了。下面來將背景設(shè)置為另一種顏色:
```python
import sys
import pygame
def run_game():
初始化游戲并創(chuàng)建一個屏幕對象
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('PlaneFight')
設(shè)置背景色
bg_color = (255, 255 ,255) # R G B 0-255
開始游戲主循環(huán)
while True:
監(jiān)控鍵盤和鼠標(biāo)事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
每次循環(huán)都重繪屏幕
screen.fill(bg_color)
讓最近繪制的屏幕可見
pygame.display.flip()
run_game()
```
在Pygame中,顏色是以RGB值指定的。這種顏色由紅色、綠色和藍(lán)色值組成,其中每個值的可能取值范圍都為0~255。顏色值(255, 0, 0)表示紅色,(0, 255, 0)表示綠色,而(0, 0, 255)表示藍(lán)色。通過組合不同的RGB值,可創(chuàng)建1600萬種顏色。在顏色值(230, 230, 230)中,紅色、藍(lán)色和綠色量相同,它將背景設(shè)置為一種淺灰色。
我們調(diào)用方法screen.fill(),用背景色填充屏幕;這個方法只接受一個實(shí)參:一種顏色。
創(chuàng)建游戲設(shè)置類/重構(gòu)代碼
每次給游戲添加新功能時,通常也將引入一些新設(shè)置。下面來編寫一個名為settings的模塊,其中包含一個名為Settings的類,用于將所有設(shè)置存儲在一個地方,以免在代碼中到處添加設(shè)置。這樣,我們就能傳遞一個設(shè)置對象,而不是眾多不同的設(shè)置。另外,這讓函數(shù)調(diào)用更簡單,且在項(xiàng)目增大時修改游戲的外觀更容易:要修改游戲,只需修改settings.py中的一些值,而無需查找散布在文件中的不同設(shè)置。
```python
class Settings():
'''存儲《飛機(jī)大戰(zhàn)》的所有設(shè)置的類'''
def?init(self):
'''初始化游戲的設(shè)置'''
屏幕設(shè)置
self.screen_width = 800
self.screen_height = 600
self.bg_color = (230, 230, 230)
在planefight.py文件下面是這樣的:
```python
import sys
import pygame
from settings import Settings
def run_game():
初始化游戲并創(chuàng)建一個屏幕對象
pygame.init()
game_settings = Settings()
screen = pygame.display.set_mode((game_settings.screen_width, game_settings.screen_height))
pygame.display.set_caption('flygame')
設(shè)置背景色
bg_color = (230, 230 ,230)
開始游戲主循環(huán)
while True:
監(jiān)控鍵盤和鼠標(biāo)事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
每次循環(huán)都重繪屏幕
screen.fill(game_settings.bg_color)
讓最近繪制的屏幕可見
pygame.display.flip()
run_game()
添加飛機(jī)圖像
在游戲中幾乎可以使用任何類型的圖像文件,但使用位圖(.bmp)文件最為簡單,因?yàn)镻ygame默認(rèn)加載位圖。
下面將飛機(jī)加入到游戲中。為了在屏幕上繪制玩家的飛機(jī),我們將加載一幅圖像,再使用Pygame方法blit()繪制它。
當(dāng)選擇用于表示飛機(jī)的圖像后,需要將其顯示到屏幕上。我們將創(chuàng)建一個名為plane的模塊,其中包含Plane類,它負(fù)責(zé)管理飛機(jī)的大部分行為。
```python
import pygame
class Plane():
def?init(self, screen):
'''初始化飛機(jī)并設(shè)置其初始位置'''
self.screen = screen
加載飛機(jī)圖像并獲取其外接矩形
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect
將每架新飛機(jī)放在屏幕底部中央
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
def blitme(self):
"""在指定位置繪制飛機(jī)"""
將背景圖畫上去,blit是個重要函數(shù),第一個參數(shù)為一個Surface對象,第二個為左上角位置。
self.screen.blit(self.image, self.rect)
重構(gòu)代碼
在大型項(xiàng)目中,經(jīng)常需要在添加新代碼前重構(gòu)既有代碼。重構(gòu)旨在簡化既有代碼的結(jié)構(gòu),使其更容易擴(kuò)展。我們將創(chuàng)建一個名為gamefunctions的新模塊,它將存儲大量讓游戲《飛機(jī)大戰(zhàn)》運(yùn)行的函數(shù)。通過創(chuàng)建模塊gamefunctions,可避免planefight.py太長,并使其邏輯更容易理解。
函數(shù)check_events()
首先把管理事件的代碼移到一個名為check_events()的函數(shù)中,以簡化run_game()并隔離事件管理循環(huán)。
```python
import sys
import pygame
def check_events():
監(jiān)控鍵盤和鼠標(biāo)事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
函數(shù)update_screen
另外把更新屏幕的代碼移植到update_screen的函數(shù)中。也在gamefunctions文件里面。
```python
import sys
import pygame
def update_screen(game_settings, screen, plane):
"""更新屏幕上的圖像,并切換到新屏幕"""
每次循環(huán)時都重繪屏幕
screen.fill(game_settings.bg_color)
plane.blitme()
讓最近繪制的屏幕可見
pygame.display.flip()
這兩個函數(shù)重寫后主函數(shù)就是這樣了:
```python
import sys
import pygame
from settings import Settings
from plane import Plane
import gamefunctions as gf
def run_game():
初始化游戲并創(chuàng)建一個屏幕對象
pygame.init()
game_settings = Settings()
screen = pygame.display.set_mode((game_settings.screen_width, game_settings.screen_height))
pygame.display.set_caption('PlaneFight')
創(chuàng)建一艘飛船
plane = Plane(screen)
開始游戲主循環(huán)
while True:
gf.check_events()
gf.update_screen(game_settings, screen, plane)
run_game()
In?[4]:
#光看課件是沒有用的。In?[5]:
#下面我們來正式開始講課。In?[6]:
#今天我只能給大家講一些。In?[7]:
#這節(jié)課我們來實(shí)現(xiàn)“控制著一腳最初出現(xiàn)在屏幕底部中央的飛機(jī)”。In?[8]:
#如果沒有“Pygame”模塊,那么就去安裝。In?[9]:
pip install pygame The following command must be run outside of the IPython shell:$ pip install pygameThe Python package manager (pip) can only be used from outside of IPython. Please reissue the `pip` command in a separate terminal or command prompt.See the Python documentation for more informations on how to install packages:https://docs.python.org/3/installing/In?[10]:
#主要涉及到重構(gòu)代碼In?[11]:
#你要玩飛機(jī)大戰(zhàn),一定要一個窗口是吧In?[12]:
import pygameIn?[13]:
import sysIn?[15]:
def run_game():pygame.init()screen = pygame.display.set_mode((800, 600))pygame.display.set_caption('PlaneFight')while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()pygame.display.flip()run_game() An exception has occurred, use %tb to see the full traceback.SystemExit C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2918: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)In?[1]:
#剛剛我們已經(jīng)運(yùn)行了一遍。In?[2]:
#運(yùn)行的結(jié)果是會產(chǎn)生一個窗口。下面我來詳細(xì)講一下各個代碼。
In?[3]:
#前面兩個import就是導(dǎo)入了sys和pygame模塊,我們后面才可以使用。In?[4]:
#def是初始化然后創(chuàng)建一個屏幕(run game)In?[5]:
#剛剛出現(xiàn)的一個屏幕就是用pygame.init()產(chǎn)生的。In?[6]:
#screen = pygame.display.set_mode((800, 600))就是設(shè)定窗口大小In?[7]:
#800是長度,600是高。In?[8]:
#如果你想變小屏幕,就可以該車成400,300In?[9]:
#while True是一只循環(huán),是讓程序一直死循環(huán)In?[10]:
#event.get可以監(jiān)控到窗口里所有的事件In?[11]:
#sys.exit()是表示如果不按Esc那個窗口是退不掉的。In?[12]:
#我們再來運(yùn)行試試In?[15]:
import sys import pygame def run_game():pygame.init()screen = pygame.display.set_mode((800, 600))pygame.display.set_caption('PlaneFight')while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()pygame.display.flip()run_game() An exception has occurred, use %tb to see the full traceback.SystemExit C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2918: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)?
In?[16]:
#我們可以看到運(yùn)行窗口是上面這個樣子的。In?[17]:
#pygame.display.flip就是繪制新的圖片,也就是刷新。In?[18]:
#這句話的意思就是全局更新屏幕。設(shè)置背景顏色
In?[2]:
import sys import pygame def run_game():pygame.init()screen = pygame.display.set_mode((800, 600))pygame.display.set_caption('PlaneFight')bg_color = (255, 255 ,255)while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()screen.fill(bg_color)pygame.display.flip()run_game() An exception has occurred, use %tb to see the full traceback.SystemExit C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2918: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)In?[3]:
#通過以上代碼我們就把窗口的背景顏色由黑色改為了白色。?
In?[4]:
#R是red的縮寫,就是紅色In?[5]:
#G是green的縮寫,就是綠色In?[6]:
#B是blue的縮寫,就是藍(lán)色In?[7]:
#0-250的數(shù)值就是從黑到白,數(shù)值越接近250就越白。In?[10]:
import sys import pygame def run_game():pygame.init()screen = pygame.display.set_mode((800, 600))pygame.display.set_caption('PlaneFight')bg_color = (0, 255 ,0)while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()screen.fill(bg_color)pygame.display.flip()run_game() An exception has occurred, use %tb to see the full traceback.SystemExit C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2918: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)In?[8]:
#如果把數(shù)值改一下,改成0,250,0,那么就是綠色。?
In?[11]:
#如果改成50,150,200,會變成下面這種顏色:In?[12]:
import sys import pygame def run_game():pygame.init()screen = pygame.display.set_mode((800, 600))pygame.display.set_caption('PlaneFight')bg_color = (50, 150 ,200)while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()screen.fill(bg_color)pygame.display.flip()run_game() An exception has occurred, use %tb to see the full traceback.SystemExit C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2918: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)?
In?[13]:
#這款藍(lán)色相對來說好看一些。In?[14]:
#screen的意思就是我們的屏幕(窗口)In?[15]:
#在后面可以改填充之類的surface(圖層),可以重復(fù)疊加,還可以添加小的圖像。In?[16]:
#注意,在pygame里面圖形都是矩形的。創(chuàng)建游戲設(shè)置類
In?[17]:
#這里我們?yōu)榱朔奖闫鹨?#xff0c;是不再添加注釋了的,要看注釋的向上拉去看課件。In?[18]:
#建議再建一個文件,叫做"Settings"。In?[19]:
#它會儲存關(guān)于所有窗口的設(shè)置。In?[20]:
import sys import pygame from settings import Settingsdef run_game():pygame.init()game_settings = Settings()screen = pygame.display.set_mode((game_settings.screen_width, game_settings.screen_height))pygame.display.set_caption('flygame')bg_color = (230, 230 ,230)while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()screen.fill(game_settings.bg_color)pygame.display.flip()run_game() --------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) <ipython-input-20-1dc072ba7479> in <module>()3 import pygame4 ----> 5 from settings import Settings6 7 def run_game():ModuleNotFoundError: No module named 'settings'In?[21]:
#同學(xué)們,這里記得裝settings模塊In?[22]:
pip install settings The following command must be run outside of the IPython shell:$ pip install settingsThe Python package manager (pip) can only be used from outside of IPython. Please reissue the `pip` command in a separate terminal or command prompt.See the Python documentation for more informations on how to install packages:https://docs.python.org/3/installing/In?[23]:
#pygame.init()就是實(shí)例化添加飛機(jī)圖像
In?[24]:
import pygameclass Plane():def __init__(self, screen):'''初始化飛機(jī)并設(shè)置其初始位置'''self.screen = screenself.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()self.screen_rect = screen.get_rectself.rect.centerx = self.screen_rect.centerx self.rect.bottom = self.screen_rect.bottomdef blitme(self): """在指定位置繪制飛機(jī)""" self.screen.blit(self.image, self.rect)In?[25]:
#建議再創(chuàng)建一個文件"plane"來儲存。好了,我們這節(jié)課就先暫時講到這里!
本次只讀課堂的python教程就到這了,歡迎下一次的收看!
總結(jié)
以上是生活随笔為你收集整理的Python高级第2课——飞机大战(只读课堂)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高并发之阿里云弹性伸缩的使用记录
- 下一篇: websocket python爬虫_p