生活随笔
收集整理的這篇文章主要介紹了
Python实战小项目-飞船游戏
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
飛船游戲
這雖然只是個小游戲,但是代碼也不少,為了避免出錯并且讓代碼清楚整潔我們把代碼分為9個模塊,同時還有一個image文件夾儲存圖像還有編輯過程中Python自己生成的一個文件夾。9個模塊中,每個模塊都有自己的功能,來為我們最終的游戲服務。我們看一下做出來游戲的效果。
1.主函數模塊alien_invasion
這是主函數模塊,也是啟動游戲的模塊,啟動游戲只需要點擊此模塊即可。
代碼:
import pygamefrom pygame
.sprite import Group
from settings import Settings
from ship import Ship
from alien import Alien
from game_stats import GameStats
from button import Button
from scoreboard import Scoreboard
import game_functions as gfdef
run_game():#初始化pygame、設置和屏幕對象pygame
.init()ai_settings
= Settings()screen
= pygame
.display
.set_mode((ai_settings
.screen_width
,ai_settings
.screen_height
))pygame
.display
.set_caption("Alien Invasion")#創建Play按鈕play_button
= Button(ai_settings
,screen
,"Play")#創建一艘飛船、一個子彈的編組和一個外星人編組ship
= Ship(ai_settings
,screen
)bullets
= Group()aliens
= Group()#創建外星人群gf
.create_fleet(ai_settings
,screen
,ship
,aliens
)#創建一個用于儲存游戲統計信息的實例
,并創建記分牌stats
= GameStats(ai_settings
)sb
= Scoreboard(ai_settings
,screen
,stats
)#開始游戲的主循環
while True
:gf
.check_events(ai_settings
,screen
,stats
,sb
,play_button
,ship
,aliens
,bullets
)if stats
.game_active
: ship
.update()gf
.update_bullets(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
)gf
.update_aliens(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
)gf
.update_screen(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
,play_button
)run_game()
2.游戲配置的settings模塊
此模塊實現游戲相關信息的配置和初始化
代碼:
class
Settings():"""儲存《外星人入侵》的所有設置的類"""def
__init__(self
):"""初始化游戲的靜態設置"""#屏幕設置self
.screen_width
= 1200self
.screen_height
= 700self
.bg_color
= (230,230,230)#飛船的設置self
.ship_limit
= 3#子彈設置self
.bullet_width
= 3self
.bullet_height
= 15self
.bullet_color
= 60,60,60self
.bullets_allowed
= 3#外星人設置self
.fleet_drop_speed
= 10#以什么樣的速度加快游戲節奏self
.speedup_scale
= 1.1#外星人點數的提高self
.score_scale
= 1.5self
.initialize_dynamic_settings()def
initialize_dynamic_settings(self
):"""初始化隨游戲進行而變化的設置"""self
.ship_speed_factor
= 1.5self
.bullet_speed_factor
= 3self
.alien_speed_factor
= 1#fleet_direction為1表示向右;為-1表示向左self
.fleet_direction
= 1#記分self
.alien_points
= 50def
increase_speed(self
):"""提高速度設置和外星人點數"""self
.ship_speed_factor
*= self
.speedup_scaleself
.bullet_speed_factor
*= self
.speedup_scaleself
.alien_speed_factor
*= self
.speedup_scaleself
.alien_points
= int(self
.alien_points
* self
.score_scale
)
3.game_stats模塊
用于游戲信息的統計
代碼:
class
GameStats():"""跟蹤游戲的統計信息"""def
__init__(self
,ai_settings
):"""初始化統計信息"""self
.ai_settings
= ai_settingsself
.reset_stats()#讓游戲一開始處于非活動狀態self
.game_active
= False#任何情況都不應該清除最高分self
.high_score
= 0def
reset_stats(self
):"""初始化在游戲運行期間可能變化的統計信息"""self
.ships_left
= self
.ai_settings
.ship_limitself
.score
= 0self
.level
= 1
4.用于儲存函數的game_functions模塊
此模塊用于儲存讓游戲運行的函數,可避免主函數太長,并讓其代碼更易理解。
具體代碼:
import sys
from time import sleepimport pygame
from bullet import Bullet
from alien import Aliendef
check_keydown_events(event
,ai_settings
,screen
,ship
,bullets
):"""響應按鍵"""if event
.key
== pygame
.K_RIGHT
:ship
.moving_right
= Trueelif event
.key
== pygame
.K_LEFT
:ship
.moving_left
= Trueelif event
.key
== pygame
.K_SPACE
:fire_bullet(ai_settings
,screen
,ship
,bullets
)elif event
.key
== pygame
.K_q
:sys
.exit()def
fire_bullet(ai_settings
,screen
,ship
,bullets
):"""如果沒有到達限制,就發射一顆子彈"""#創建一顆子彈,并將其加入到編組bullets中
if len(bullets
) < ai_settings
.bullets_allowed
: new_bullet
= Bullet(ai_settings
,screen
,ship
)bullets
.add(new_bullet
)def
check_keyup_events(event
,ship
):"""松開響應"""if event
.key
== pygame
.K_RIGHT
:ship
.moving_right
= Falseelif event
.key
== pygame
.K_LEFT
:ship
.moving_left
= Falsedef
check_events(ai_settings
,screen
,stats
,sb
,play_button
,ship
,aliens
,bullets
):#監視鍵盤和鼠標事件
for event in pygame
.event
.get():if event
.type
== pygame
.QUIT
:sys
.exit()elif event
.type
== pygame
.KEYDOWN
:check_keydown_events(event
,ai_settings
,screen
,ship
,bullets
)elif event
.type
== pygame
.KEYUP
:check_keyup_events(event
,ship
)elif event
.type
== pygame
.MOUSEBUTTONDOWN
:mouse_x
,mouse_y
= pygame
.mouse
.get_pos()check_play_button(ai_settings
,screen
,stats
,sb
,play_button
,ship
,aliens
,bullets
,mouse_x
,mouse_y
)def
check_play_button(ai_settings
,screen
,stats
,sb
,play_button
,ship
,aliens
,bullets
,mouse_x
,mouse_y
):"""在玩家單機Play按鈕時開始游戲"""button_clicked
= play_button
.rect
.collidepoint(mouse_x
,mouse_y
)if button_clicked and not stats
.game_active
:#重置游戲設置ai_settings
.initialize_dynamic_settings()#隱藏光標pygame
.mouse
.set_visible(False
)#重置游戲統計信息stats
.reset_stats()stats
.game_active
= True#重置記分牌圖像sb
.prep_score()sb
.prep_high_score()sb
.prep_level()sb
.prep_ships()#清空外星人列表aliens
.empty()bullets
.empty()#創建一群新的外星人,并讓飛船居中
create_fleet(ai_settings
,screen
,ship
,aliens
)ship
.center_ship()def
update_screen(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
,play_button
):"""更新屏幕上的圖像,并切換到新屏幕"""#每次循環時都重繪屏幕screen
.fill(ai_settings
.bg_color
)#在飛船和外星人后面重繪所有子彈
for bullet in bullets
.sprites():bullet
.draw_bullet()ship
.blitme()aliens
.draw(screen
)#顯示得分sb
.show_score()#如果游戲處于非活動狀態,就繪制Play按鈕
if not stats
.game_active
:play_button
.draw_button()#讓最近繪制的屏幕可見pygame
.display
.flip()def
update_bullets(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
):"""更新子彈的位置,并刪除已消失的子彈"""#更新子彈的位置bullets
.update()#刪除已消失的子彈
for bullet in bullets
.copy():if bullet
.rect
.bottom
<= 0:bullets
.remove(bullet
)check_bullet_alien_collisions(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
)def
check_high_score(stats
,sb
):"""檢查是否需要建立最高分"""if stats
.score
> stats
.high_score
:stats
.high_score
= stats
.scoresb
.prep_high_score()def
check_bullet_alien_collisions(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
):"""響應子彈和外星人的碰撞"""#刪除發生碰撞的子彈和外星人collisions
= pygame
.sprite
.groupcollide(bullets
,aliens
,True
,True
)if collisions
:for aliens in collisions
.values():stats
.score
+= ai_settings
.alien_points
* len(aliens
)sb
.prep_score()check_high_score(stats
,sb
)if len(aliens
) ==0:#刪除現有的子彈
,加快游戲節奏,并創建一群外星人bullets
.empty()ai_settings
.increase_speed()#加快游戲節奏stats
.level
+= 1sb
.prep_level()create_fleet(ai_settings
,screen
,ship
,aliens
)def
get_number_aliens_x(ai_settings
,alien_width
):"""計算一行可容納多少個外星人"""available_space_x
= ai_settings
.screen_width
- 2 * alien_widthnumber_aliens_x
= int(available_space_x
/ (2 * alien_width
))return number_aliens_xdef
get_number_rows(ai_settings
,ship_height
,alien_height
):"""計算屏幕可容納多少人"""available_space_y
= (ai_settings
.screen_height
-(3 * alien_height
) - ship_height
)number_rows
= int(available_space_y
/ (2 * alien_height
))return number_rowsdef
create_alien(ai_settings
,screen
,aliens
,alien_number
,row_number
):"""創建一個外星人并將其放在當前行"""alien
= Alien(ai_settings
,screen
)alien_width
= alien
.rect
.widthalien
.x
= alien_width
+ 2 * alien_width
* alien_numberalien
.rect
.x
= alien
.xalien
.rect
.y
= alien
.rect
.height
+ 2 * alien
.rect
.height
* row_numberaliens
.add(alien
)def
create_fleet(ai_settings
,screen
,ship
,aliens
):"""創建一個外星人群"""#創建一個外星人,并計算一行可容納多少個外星人#外星人間距為外星人寬度alien
= Alien(ai_settings
,screen
)number_aliens_x
= get_number_aliens_x(ai_settings
,alien
.rect
.width
)number_rows
= get_number_rows(ai_settings
,ship
.rect
.height
,alien
.rect
.height
)#創建外星人群
for row_number in
range(number_rows
):for alien_number in
range(number_aliens_x
):create_alien(ai_settings
,screen
,aliens
,alien_number
,row_number
)def
check_fleet_edges(ai_settings
,aliens
):"""有外星人到達邊緣時采取相應的措施"""for alien in aliens
.sprites():if alien
.check_edges():change_fleet_direction(ai_settings
,aliens
)breakdef
change_fleet_direction(ai_settings
,aliens
):"""將整群外星人下移,并改變它們的方向"""for alien in aliens
.sprites():alien
.rect
.y
+= ai_settings
.fleet_drop_speedai_settings
.fleet_direction
*= -1def
ship_hit(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
):if stats
.ships_left
> 0:"""響應被外星人撞到的飛船"""#將ships_left減
1stats
.ships_left
-= 1#更新分數sb
.prep_ships()else:stats
.game_active
= Falsepygame
.mouse
.set_visible(True
)#清空外星人列表和子彈列表aliens
.empty()bullets
.empty()#創建一群新的外星人,并將飛船放到屏幕底端中央
create_fleet(ai_settings
,screen
,ship
,aliens
)ship
.center_ship()#暫停
sleep(0.5)def
check_aliens_bottom(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
):"""檢查是否有外星人到達了屏幕底端"""screen_rect
= screen
.get_rect()for alien in aliens
.sprites():if alien
.rect
.bottom
>= screen_rect
.bottom
:#像飛船被撞到一樣進行處理
ship_hit(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
)breakdef
update_aliens(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
):"""檢查是否有外星人位于屏幕邊緣,并更新整群外星人的位置"""check_fleet_edges(ai_settings
,aliens
)aliens
.update()#檢測外星人和飛船之間的碰撞
if pygame
.sprite
.spritecollideany(ship
,aliens
):ship_hit(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
)#檢查是否有外星人到達屏幕底端
check_aliens_bottom(ai_settings
,screen
,stats
,sb
,ship
,aliens
,bullets
)
5.外星人的alien模塊
此模塊用于儲存外星人的屬性和行為
代碼:
import pygame
from pygame
.sprite import Spriteclass
Alien(Sprite
):"""表示單個外星人"""def
__init__(self
,ai_settings
,screen
):"""初始化外星人并設置其起始位置"""super(Alien
,self
).__init__()self
.screen
= screenself
.ai_settings
= ai_settings#加載外星人圖像,并設置其rect屬性self
.image
= pygame
.image
.load('image/alien.bmp')self
.rect
= self
.image
.get_rect()#每個外星人最初都在屏幕左上角附近self
.rect
.x
= self
.rect
.widthself
.rect
.y
= self
.rect
.height#儲存外星人的準確位置self
.x
= float(self
.rect
.x
)def
blitme(self
):"""在指定位置繪制外星人"""self
.screen
.blit(self
.image
,self
.rect
)def
check_edges(self
):"""如果外星人位于屏幕邊緣,就返回True"""screen_rect
= self
.screen
.get_rect()if self
.rect
.right
>= screen_rect
.right
:return Trueelif self
.rect
.left
<= 0:return Truedef
update(self
):"""向右或向左移動外星人"""self
.x
+= (self
.ai_settings
.alien_speed_factor
*self
.ai_settings
.fleet_direction
)self
.rect
.x
= self
.x
6.ship模塊
此模塊用于儲存飛船的屬性和行為
代碼:
import pygame
from pygame
.sprite import Spriteclass
Ship(Sprite
):def
__init__(self
,ai_settings
,screen
):"""初始化飛船并設置其初始位置"""super(Ship
,self
).__init__()self
.screen
= screenself
.ai_settings
= ai_settings#加載飛船圖像并獲取其外接矩陣self
.image
= pygame
.image
.load('image/ship.bmp')self
.rect
= self
.image
.get_rect()self
.screen_rect
= screen
.get_rect()#將每艘新飛船放在屏幕底部中央self
.rect
.centerx
= self
.screen_rect
.centerxself
.rect
.bottom
= self
.screen_rect
.bottom#在飛船的屬性center中儲存小數值self
.center
= float(self
.rect
.centerx
)#移動標志self
.moving_right
= Falseself
.moving_left
= Falsedef
update(self
):"""根據移動標志調整飛船的位置"""#更新飛船的center值,而不是rect
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#根據self
.center更新rect對象self
.rect
.centerx
= self
.centerdef
blitme(self
):"""在指定位置繪制飛船"""self
.screen
.blit(self
.image
,self
.rect
)def
center_ship(self
):"""讓飛船在屏幕居中"""self
.center
= self
.screen_rect
.centerx
7.bullet模塊
此模塊用于儲存子彈的屬性和行為
代碼:
import pygame
from pygame
.sprite import Spriteclass
Bullet(Sprite
):"""一個對飛船發射的子彈進行管理的類"""def
__init__(self
,ai_settings
,screen
,ship
):"""在飛船所處的位置創建一個子彈對象"""super(Bullet
,self
).__init__()self
.screen
= screen#在
(0,0)處創建一個表示子彈的矩形,再設置正確的位置self
.rect
= pygame
.Rect(0,0,ai_settings
.bullet_width
,ai_settings
.bullet_height
)self
.rect
.centerx
= ship
.rect
.centerxself
.rect
.top
= ship
.rect
.top#儲存用小數表示的子彈位置self
.y
= float(self
.rect
.y
)self
.color
= ai_settings
.bullet_colorself
.speed_factor
= ai_settings
.bullet_speed_factordef
update(self
):"""向上移動子彈"""#更新表示子彈位置的小數值self
.y
-= self
.speed_factor#更新表示子彈的rect
.yself
.rect
.y
= self
.ydef
draw_bullet(self
):"""在屏幕上繪制子彈"""pygame
.draw
.rect(self
.screen
,self
.color
,self
.rect
)
8.button模塊
此模塊用于儲存按鈕的屬性和行為
代碼:
import pygame
.fontclass
Button():def
__init__(self
,ai_settings
,screen
,msg
):"""初始化按鈕的屬性"""self
.screen
= screenself
.screen_rect
= screen
.get_rect()#設置按鈕的尺寸和其他屬性self
.width
,self
.height
= 200,50self
.button_color
= (0,255,0)self
.text_color
= (255,255,255)self
.font
= pygame
.font
.SysFont(None
,48)#創建按鈕的rect對象
,并使其居中self
.rect
= pygame
.Rect(0,0,self
.width
,self
.height
)self
.rect
.center
= self
.screen_rect
.center#按鈕的標簽只需創建一次self
.prep_msg(msg
)def
prep_msg(self
,msg
):"""將msg渲染為圖像,并使其在按鈕上居中"""self
.msg_image
= self
.font
.render(msg
,True
,self
.text_color
,self
.button_color
)self
.msg_image_rect
= self
.msg_image
.get_rect()self
.msg_image_rect
.center
= self
.rect
.centerdef
draw_button(self
):#繪制一個用顏色填充的按鈕,再繪制文本self
.screen
.fill(self
.button_color
,self
.rect
)self
.screen
.blit(self
.msg_image
,self
.msg_image_rect
)
9.scoreboard模塊
此模塊用于儲存計分板的屬性和行為
代碼:
import pygame
.font
from pygame
.sprite import Groupfrom ship import Shipclass
Scoreboard():"""顯示得分信息的類"""def
__init__(self
,ai_settings
,screen
,stats
):"""初始化得分信息"""self
.screen
= screenself
.screen_rect
= screen
.get_rect()self
.ai_settings
= ai_settingsself
.stats
= stats#顯示得分信息時使用的字體設置self
.text_color
= (30,30,30)self
.font
= pygame
.font
.SysFont(None
,48)#準備初始得分圖像self
.prep_score()self
.prep_high_score()self
.prep_level()self
.prep_ships()def
prep_score(self
):"""將得分轉換為一幅渲染的圖像"""rounded_score
= int(round(self
.stats
.score
,-1))score_str
= "{:,}".format(rounded_score
)self
.score_image
= self
.font
.render(score_str
,True
,self
.text_color
,self
.ai_settings
.bg_color
)#將得分板放在屏幕右上角self
.score_rect
= self
.score_image
.get_rect()self
.score_rect
.right
= self
.screen_rect
.right
- 20self
.score_rect
.top
= 20def
prep_high_score(self
):"""將最高分轉化為渲染的圖像"""high_score
= int(round(self
.stats
.high_score
,-1))high_score_str
= "{:,}".format(high_score
)self
.high_score_image
= self
.font
.render(high_score_str
,True
,self
.text_color
,self
.ai_settings
.bg_color
)#將最高分放在屏幕頂部中央self
.high_score_rect
= self
.high_score_image
.get_rect()self
.high_score_rect
.centerx
= self
.screen_rect
.centerxself
.high_score_rect
.top
= self
.score_rect
.topdef
prep_level(self
):"""將等級轉換為渲染的圖像"""self
.level_image
= self
.font
.render(str(self
.stats
.level
),True
,self
.text_color
,self
.ai_settings
.bg_color
)#將等級放在得分下方self
.level_rect
= self
.level_image
.get_rect()self
.level_rect
.right
= self
.score_rect
.rightself
.level_rect
.top
= self
.score_rect
.bottom
+ 10def
prep_ships(self
):"""顯示余下多少艘飛船"""self
.ships
= Group()for ship_number in
range(self
.stats
.ships_left
):ship
= Ship(self
.ai_settings
,self
.screen
)ship
.rect
.x
= 10 + ship_number
* ship
.rect
.widthship
.rect
.y
= 10self
.ships
.add(ship
)def
show_score(self
):"""在屏幕上顯示得分"""self
.screen
.blit(self
.score_image
,self
.score_rect
)self
.screen
.blit(self
.high_score_image
,self
.high_score_rect
)self
.screen
.blit(self
.level_image
,self
.level_rect
)#繪制飛船self
.ships
.draw(self
.screen
)
這是我所有的模塊。如果你需要這個完整文件可以訪問網盤
鏈接:https://pan.baidu.com/s/1BHM52w7-yNWPCFL8aPI-Qw
提取碼:sjpb
(參考資料《Python編程從入門到實踐》)
總結
以上是生活随笔為你收集整理的Python实战小项目-飞船游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。