当前位置: 首页>Python>正文

用python入侵別人手機,python小游戲----外星人入侵

用python入侵別人手機,python小游戲----外星人入侵

源代碼:

AlienInvasion/game at main · CrashBugger/AlienInvasion (github.com)

本文來自作者對《python編程-從入門到實踐》的學習記錄,剛剛入門python,小白一個,若有錯誤,歡迎大佬指出。

圖片資源:

用python入侵別人手機,

just nobibi,show me the code!話不多說,開始項目。

1.創建pygame窗口響應用戶輸出

導包

import pygame
import sys
import settings

接下來

開始進行初步準備sssssssss

def run_game():# 初始化游戲并創建一個屏幕對象pygame.init()screen = pygame.display.set_mode((1200, 800))pygame.display.set_caption("Alien Invasion")# 游戲主循環while True:# 監視鍵盤和鼠標時間for event in pygame.event.get():if event == pygame.QUIT:sys.exit()# 讓最近的繪制的屏幕可見pygame.display.flip()
  • ?其中pygame.init()方法初始化背景設置
  • pygame.display.set_mode()創建一個名為screen的窗口對象,以后我們將在這里面繪制圖形元素,需要傳入一個元組,表示窗口的長高。screen是一個surface對象
  • while循環控制游戲進行,for循環偵聽事件,pygame.event.get()方法拿到事件列表,當檢測到用戶離開時,系統退出
  • display.flip()方法讓最近繪制的屏幕可見
    

2.設置背景色

python小游戲代碼大全、先上代碼

def run_game():# 初始化游戲并創建一個屏幕對象pygame.init()screen = pygame.display.set_mode((1200, 800))pygame.display.set_caption("Alien Invasion")# shezhibeijingsebg_color = (230, 230, 230)# 游戲主循環while True:# 監視鍵盤和鼠標時間for event in pygame.event.get():if event == pygame.QUIT:sys.exit()# 每次循環重新繪制屏幕screen.fill(bg_color)# 讓最近的繪制的屏幕可見pygame.display.flip()
  • 創建一個元組bg_color存儲RGB顏色,接下來在主循環中在screen中填充顏色,

3.創建設置類

?這一步對前一步進行優化,創建一個settings類,用來保存我們的設置

class Settings():def __init__(self):self.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)

接下來回到主方法創建這個類的實例進行設置

def run_game():# 初始化游戲,并創建一個屏幕對象pygame.init()ai_settings = settings.Settings()screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))pygame.display.set_caption("Ailien Invasion")# bg_color = (230, 230, 230)while True:# 監聽事件for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()# 每次循環重置屏幕screen.fill(ai_settings.bg_color)# 最近繪制的屏幕可見pygame.display.flip()

4.創建ship類并繪制飛船

創建一個新的文件夾,命名為images,將ship.bmp放進去,接下來創建ship類

import pygameclass Ship():def __init__(self, screen):self.screen = screen# 加載飛船圖像并獲取外接矩形self.image = pygame.image.load("D:\PyCharm\Code\project\game\images\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.bottomdef blitme(self):"""在指定位置繪制飛船"""self.screen.blit(self.image, self.rect)
  • pygame可以像處理矩形一樣處理游戲元素,處理rect對象,可以使用矩形中心xy坐標和矩形四角
  • 要將飛船顯示在中央,需要設置rect對象的center,centerx或centery;如果要將飛船與邊緣對其,可以設置其top,bottom,left,right屬性;如果要調整坐標,需要設置其x,y屬性,注意原點在左上角。
  • 在主方法中加入飛船
def run_game():# 初始化游戲,并創建一個屏幕對象pygame.init()ai_settings = settings.Settings()screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))pygame.display.set_caption("Ailien Invasion")# 創建一艘飛船ship = Ship(screen)while True:# 監聽事件for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()# 每次循環重置屏幕screen.fill(ai_settings.bg_color)ship.blitme()# 最近繪制的屏幕可見pygame.display.flip()

?5.重構模塊geme_functions

  • 我們將游戲中的各個控制方法抽離到一個專門的模塊
  • game_functions.py
import sys
import pygame
import shipfrom game import settingsdef check_events():"""響應按鍵和鼠標事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()def update_screen(ai_settings: settings.Settings, screen, ship: ship.Ship):"""更新屏幕上的圖像,并切換到新屏幕"""# 每次循環chonghuipingmuscreen.fill(ai_settings.bg_color)ship.blitme()# 最近繪制的屏幕可見pygame.display.filp()

?這些都是原本主循環中的方法,現在整合到一個模塊

主方法在修改一下

pygame外星人入侵、先把剛創建的模塊導包

import game_functions as gf
def run_game():# 初始化游戲,并創建一個屏幕對象pygame.init()ai_settings = settings.Settings()screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))pygame.display.set_caption("Ailien Invasion")# 創建一艘飛船ship = Ship(screen)while True:# 監聽事件gf.check_events()# 每次循環重置屏幕gf.update_screen(ai_settings, screen, ship)

6.駕駛飛船

先在ship類中新加一個屬性moving_right=False,當檢測到移動時,置位true,并新定義update方法,更新飛船位置

  • Ship類
    def __init__(self, screen):self.screen = screen# 加載飛船圖像并獲取外接矩形self.image = pygame.image.load("D:\PyCharm\Code\project\game\images\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# 移動標志self.moving_right = Falsedef blitme(self):"""在指定位置繪制飛船"""self.screen.blit(self.image, self.rect)def update(self):if self.moving_right:self.rect.centerx += 1

我們在game_functions.py的check_events方法中加入檢測用戶鍵盤的代碼

  • game_functions.py
def check_events(ship: ship.Ship):"""響應按鍵和鼠標事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()# 用戶按下鍵盤elif event.type == pygame.KEYDOWN:if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.type == pygame.KEYUP:if event.key == pygame.K_RIGHT:ship.moving_right = False

當用按下鍵盤時,我們在event檢測其type屬性,若為keydown,再進一步判斷是否為向右鍵,并將ship類中的moving——righ屬性置為true,當玩家抬起右鍵時,檢測到keyup,將其置為false,

并在主方法中不斷調用ship類的update方法

  • 主方法
def run_game():# 初始化游戲,并創建一個屏幕對象pygame.init()ai_settings = settings.Settings()screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))pygame.display.set_caption("Ailien Invasion")# 創建一艘飛船ship = Ship(screen)while True:# 監聽事件gf.check_events(ship)# 更新ship.update()# 每次循環重置屏幕gf.update_screen(ai_settings, screen, ship)

7.調整飛船速度并限制飛船移動邊界

  • 在settings類中新加屬性self.ship_speed_factor用于控制飛船速度
  • 接下來在ship的方法init方法傳入settings對象,并在update方法中用他的屬性修改坐標,因為rect只存儲整數部分的值,所以為了精細控制速度,我們用float方法返回rect.centerx保存到center屬性,并在update方法對center修改,最后再用center覆蓋centerx。
  • 判斷邊界只需要在update方法中判斷當前rect的left屬性和right屬性是否超出邊界。
Ship類
class Ship():def __init__(self, screen, ai_settings: Settings):self.screen = screen# 加載飛船圖像并獲取外接矩形self.image = pygame.image.load("D:\PyCharm\Code\project\game\images\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# 移動標志self.moving_right = Falseself.moving_left = False# 飛船設置self.ai_settings = ai_settings# 在飛船的center屬性中存儲小數值self.center = float(self.rect.centerx)def blitme(self):"""在指定位置繪制飛船"""self.screen.blit(self.image, self.rect)def update(self):# 加上邊界判斷if self.moving_right and self.rect.right < self.screen_rect.right:self.center += self.ai_settings.ship_speed_factorif self.moving_left and self.rect.left > 0:self.center -= self.ai_settings.ship_speed_factor# 覆蓋self.rect.centerx = self.center

8.重構check_functions

def check_keydown_events(event, ship):if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Truedef 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(ship: ship.Ship):"""響應按鍵和鼠標事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()# 用戶按下鍵盤elif event.type == pygame.KEYDOWN:check_keydown_events(event, ship)elif event.type == pygame.KEYUP:check_keyup_events(event, ship)
  • 提取出兩個方法,如圖

9.創建子彈類并加入編組

外星人入侵循環導入?bullet.py

import pygame
from pygame.sprite import Spritefrom game.settings import Settings
from game.ship import Shipclass Bullet(Sprite):def __init__(self, ai_settings: Settings, screen, ship: Ship):"""在飛船所在位置創建子彈"""super().__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):"""向上移動子彈"""# 更新y坐標self.y -= self.speed_factor# 覆蓋self.rect.y = self.ydef draw_bullet(self):"""在屏幕上繪制子彈"""pygame.draw.rect(self.screen, self.color, self.rect)
  • 我們繼承sprite類,可以將子彈編組,同時操作編組中的元素。并傳入settings對象ship對象和screen對象
  • 用rect存儲子彈矩形,并設置其centerx和top屬性,讓它與飛船相同
  • 跟上一個相同的原因,我們用float()精細調整子彈y坐標

我們在主方法導包并創建Group()實例,并將其傳入while循環中的三個方法

from pygame.sprite import Group
# 初始化游戲,并創建一個屏幕對象pygame.init()ai_settings = settings.Settings()screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))pygame.display.set_caption("Ailien Invasion")# 創建一艘飛船ship = Ship(screen, ai_settings)# 創建用于存儲子彈的編組bullets = Group()while True:# 監聽事件gf.check_events(ship, bullets)# 更新ship.update()# 更新子彈位置bullets.update()# 每次循環重置屏幕gf.update_screen(ai_settings, screen, ship, bullets)
  • 編組的作用就是存儲子彈,并且當調用update()方法時,自動對里面的每個子彈調用update方法,bullets.update()將被每顆子彈調用

10.Fire!開火

  • 這里期望玩家按空格鍵可以完成開火
  • 我們在functions對check_keydown方法加入對空格的判斷若判斷到,則在編組中新加入子彈;并在update_screen方法中重繪子彈,注意重繪子彈應在screen.flip()方法調用之前
  • 注意修改方法的參數
class Bullet(Sprite):def __init__(self, ai_settings: Settings, screen, ship: Ship):"""在飛船所在位置創建子彈"""super().__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):"""向上移動子彈"""# 更新y坐標self.y -= self.speed_factor# 覆蓋self.rect.y = self.ydef draw_bullet(self):"""在屏幕上繪制子彈"""pygame.draw.rect(self.screen, self.color, self.rect)
  • 成功開火后,有個問題,那些飛出屏幕外的子彈,仍然留在內存中,這樣越積越多,會讓我們的游戲慢的龜爬一樣,所以在主方法while循環中添加一個刪除子彈的方法,判斷子彈的bottom屬性是否小于等于0,成立則從編組中刪除掉
 while True:# 監聽事件gf.check_events(ai_settings, screen, ship, bullets)# 更新ship.update()# 更新子彈位置bullets.update()# 刪除已經消失的子彈for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)# 每次循環重置屏幕gf.update_screen(ai_settings, screen, ship, bullets)
  • 下來我們在對代碼進行優化,創建update_bullets函數和fire_bullets來將原本開火和更新的代碼抽離
  • games_functions.py
  • def update_bullets(bullets: Bullet):"""更新子彈未位置"""# 更新位置bullets.update()# 刪除已經消失的子彈for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)def fire_bullets(ai_settings: Settings, screen: surface, ship: ship.Ship, bullets: Bullet):# 若子彈數量小于3,創建一顆新子彈,if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings, screen, ship)bullets.add(new_bullet)

    修改其中的keydown函數

  • def check_keydown_events(event, ai_settings: Settings, screen, ship, bullets: Bullet):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_bullets(ai_settings, screen, ship, bullets)
    

    11.創建外星人

  • 我們首先改變一下游戲退出的方式,按下Q鍵即可退出,在game_functions.py中的key_down方法加上下面一條

  •     elif event.key == pygame.K_q:sys.exit(1)

    創建外星人類

import pygame
from pygame import surface
from pygame.sprite import Spritefrom game.settings import Settingsclass Alien(Sprite):"""表示單個外星人的類"""def __init__(self, ai_settings: Settings, screen: surface):# 初始化外星人并設置其起始位置super(Alien, self).__init__()self.screen = screenself.ai_settings = ai_settings# 加載外星人圖像,設置其rect屬性self.image = pygame.image.load(r"D:\PyCharm\Code\project\game\images\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)
  • 講解同ship類一樣,不在贅述
  • 接下來我們要將外星人在圖像上畫出來,需要在主方法中創建一個實例
  •    # 創建外星人實例alien = Alien(ai_settings, screen)

    并在game_functions中修改update_screen方法

  • python武裝飛船在手機上運行,game_functions.py

    def update_screen(ai_settings: Settings, screen, ship: ship.Ship, alien: Alien, bullets: Bullet):"""更新屏幕上的圖像,并切換到新屏幕"""# 每次循環重繪屏幕screen.fill(ai_settings.bg_color)ship.blitme()# 繪制外星人alien.blitme()# 重繪子彈for bullet in bullets.sprites():bullet.draw_bullet()# 最近繪制的屏幕可見pygame.display.flip()
  • ?調用個blitme方法即可,注意還需要在flip方法調用之前
  • 嘗試成功,接下來我們要創建一行外星人
  • 在game_functions.py中加入如下方法
  • 在主方法中循環之前加入
  • # 創建外星人群aliens = Group()gf.create_fleet(ai_settings, screen, aliens)

    aliens是一個空的編組,前面介紹過,編組可以對其中的每個元素調用方法,并將它傳入create_fleet()方法,這個方法在game_functions.py中定義

  • game_functions.py

def create_fleet(ai_settings: Settings, screen, aliens: Group):"""創建外星人群"""# 創建一個外星人,并計算一行可以容納多少個外星人alien: Alien = Alien(ai_settings, screen)alien_width = alien.rect.widthavailable_space_x = ai_settings.screen_width - 2 * alien_width# 外星人間距為外星人寬度number_aliens_x = int(available_space_x / (2 * alien_width))# 創建第一行外星人for alien_number in range(number_aliens_x):newalien = Alien(ai_settings, screen)newalien.x = alien_width + 2 * alien_width * alien_numbernewalien.rect.x = newalien.xaliens.add(newalien)
  • 首先計算一行可以容納多少個外星人,間距我們設置為外星人的寬度,接下來在編組中加入新建的外星人

12.重構creat_fleet()

def create_fleet(ai_settings: Settings, screen, aliens: Group):"""創建外星人群"""alien = Alien(ai_settings, screen)number_aliens_x = get_number_aliens(ai_settings, alien.rect.width, )for alien_number in range(number_aliens_x):create_alien(ai_settings, screen, aliens, alien_number)def get_number_aliens(ai_settings: Settings, alien_width: int) -> int:"""獲取一行容納的外星人數量"""available_space_x = ai_settings.screen_width - 2 * alien_width# 外星人間距為外星人寬度number_aliens_x = int(available_space_x / (2 * alien_width))return number_aliens_xdef create_alien(ai_settings, screen, aliens: Group, alien_number):"""創建一個外星人并放在當前行"""alien = Alien(ai_settings, screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xaliens.add(alien)

將其中的幾個功能提取出來

13.添加多行外星人

game_functions.py

def get_number_rows(ai_settings: Settings, ship_height, alien_height) -> int:"""計算能容納多少行"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rows
  • 加入上述代碼
def create_fleet(ai_settings: Settings, screen, ship: ship.Ship, aliens: Group):"""創建外星人群"""alien = Alien(ai_settings, screen)number_aliens_x = get_number_aliens(ai_settings, alien.rect.width)number_rows = get_number_rows(ai_settings, ship.rect.height, alien.rect.height)for alien_number in range(number_aliens_x):for alien_row in range(number_rows):create_alien(ai_settings, screen, aliens, alien_number, alien_row)
def create_alien(ai_settings, screen, aliens: Group, alien_number, row_number):"""創建一個外星人并放在當前行"""alien = Alien(ai_settings, screen)alien_width = alien.rect.width# 當前xalien.x = alien_width + 2 * alien_width * alien_number# 當前yalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberalien.rect.x = alien.xaliens.add(alien)
  • 修改create_fleet方法和create_alien方法
  • create_alien中加入一個參數row_number,表示當前應該添加到第幾行,并據此修改y坐標
  • create_fleet方法中for循環新加一層層數循環

14.外星人移動

首先在settings.py中添加設置參數

  • settings.py
   # 外星人設置self.alien_speed_factor = 0.5#外星人水平移動速度self.fleet_drop_speed = 10#外星人豎直移動速度self.fleet_direction = 1  #移動方向: 1為向右,-1向左
  • ?Alien.py中加入下述代碼
  def update(self):"""向左向右移動外星人"""self.x += self.ai_settings.alien_speed_factor * self.ai_settings.fleet_directionself.rect.x = self.xdef check_edges(self):"""如果外星人到達邊緣,返回True"""screen_rect = self.screen.get_rect()if self.rect.right >= screen_rect.right:return Trueelif self.rect.left <= 0:return True
  • game_functions.py中加入
def change_fleet_direction(ai_settings, aliens):"""將外星人整體下移,并改變他們方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def check_fleet_edges(ai_settings: Settings, aliens):"""有外星人到達邊緣時采取相應的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings, aliens)breakdef update_aliens(ai_settings, aliens):"""檢查是否有外星人位于屏幕邊緣,并更新調整外星人位置"""check_fleet_edges(ai_settings, aliens)aliens.update()
  • update_aliens為我們對主方法提供的接口,上面兩個為輔助函數
  • 主方法while中調用update_aliens方法
 # 更新aliensgf.update_aliens(ai_settings, aliens)

15.射殺外星人并生成新的外星人群

有外星人入侵嗎,我們需要調用pygame.sprite.groupcollied方法,這個方法檢測兩個編組中的元素是否重合,重合的話進行處理,并返回一個字典,每個鍵值對為子彈-外星人。其中第一個True表示重合的話刪除第一個編組中的元素,第二個true表示刪除第二個編組中的元素。我們在更新子彈位置時調用這個方法,并增加主方法中的參數調用

  • 擊殺外星人后,我們需要判斷是否需要生成新的外星人,若編組為空,重新調用生成外星人的方法
  • game_functions.py
def update_bullets(ai_settings, screen, ship, aliens: Alien, bullets: Sprite):"""更新子彈未位置"""# 更新位置bullets.update()# 刪除已經消失的子彈for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)check_bullet_alien_collision(ai_settings, screen, ship, aliens, bullets)def check_bullet_alien_collision(ai_settings, screen, ship, aliens, bullets):# 檢查是否有子彈擊中外星人collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)# 更新外星人if len(aliens) == 0:bullets.empty()create_fleet(ai_settings, screen, ship, aliens)

16.Boom!!!飛船與外星人相撞

如果飛船與外星人相撞或者外星人到底部,我們讓游戲重置,重新生成外星人,并將飛船居中

ship.py

  def center_ship(self):"""讓飛船居中"""self.center = self.screen_rect.centerx
  • 我們還需要將飛船的命數減一,為此我們新建一個GameStatus類,用于記錄游戲狀態信息
  • 在Settings.py中新加屬性
  •    self.ship_limit = 3

  • GameStatus.py
    class GameStatus():"""跟蹤游戲的統計信息"""def __init__(self, ai_settings):"""初始化統計的信息"""self.ai_settings = ai_settingsself.reset_status()def reset_status(self):"""初始化在游戲運行期間可能變化的信息"""self.ships_left = self.ai_settings.ship_limit
    

?game_functions.py

def update_aliens(ai_settings, stats, screen, ship, bullets, aliens):"""檢查是否有外星人位于屏幕邊緣,并更新調整外星人位置"""check_fleet_edges(ai_settings, aliens)aliens.update()# 檢測外星人和飛船是否相撞if pygame.sprite.spritecollideany(ship, aliens):ship_hit(ai_settings, stats, screen, ship, aliens, bullets)# 檢查外星人是否撞到底部check_aliens_bottom(aliens, ai_settings, stats, screen, ship, bullets)def ship_hit(ai_settings: Settings, status: GameStatus, screen, ship: ship.Ship, aliens, bullets):"""響應外星人撞到飛船"""# 將飛船數量ship_left減一status.ships_left -= 1# 清空外星人和子彈aliens.empty()bullets.empty()# 創建一群新的外星人,重置飛船create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()# 暫停sleep(0.5)def check_aliens_bottom(aliens: Alien, ai_settings: Settings, stats: GameStatus,screen: Surface, ship: ship.Ship, bullets):"""檢查是否有外星人到達底部"""screen_rect = screen.get_rect()for alien in aliens:if alien.rect.bottom >= screen_rect.bottom:# 像飛船撞到飛船一樣處理ship_hit(ai_settings, stats, screen, ship, aliens, bullets)break

我們調用update_aliens方法時,順便檢查一下飛船與外星人是否相撞,通過

pygame.sprite.spritecollideany(ship, aliens)

Python外星人入侵,方法,第一個參數為一個飛船對象,第二個參數為一個編組,

17.游戲結束

game_functions.py的__ini__t中加入

  # 游戲剛啟動處于活動狀態self.game_active = True
  • 這個屬性讓我們可以再玩家命數耗盡后置為False退出游戲。
  • 改動game_functions.py方法,加入判斷
def ship_hit(ai_settings: Settings, status: GameStatus, screen, ship: ship.Ship, aliens, bullets):"""響應外星人撞到飛船"""# 將飛船數量ship_left減一if status.ships_left > 0:status.ships_left -= 1# 清空外星人和子彈aliens.empty()bullets.empty()# 創建一群新的外星人,重置飛船create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()# 暫停sleep(0.5)else:status.game_active = False
  • 主方法的while循環改為
  •  while True:# 監聽事件gf.check_events(ai_settings, screen, ship, bullets)if stats.game_active:# 更新ship.update()# 更新子彈gf.update_bullets(ai_settings, screen, ship, aliens, bullets)# 更新aliensgf.update_aliens(ai_settings, stats, screen, ship, bullets, aliens)# 每次循環重置屏幕gf.update_screen(ai_settings, screen, ship, aliens, bullets)
    

    18.添加開始按鈕

  • button.py
import pygame.font
class Button():def __init__(self, ai_settings: Settings, screen: Surface, 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)
  • font屬性中我們調用pygame.font()方法,None表示用默認字體,48指的是字體字號。為了讓按鈕在屏幕居中,我們創建一個rect對象,并讓他居中
  • 接下來在新建一個方法prep_msg方法來處理按鈕的渲染和繪制按鈕的方法
    def prep_msg(self, msg):"""將msg渲染為圖像,并將其在按鈕上居中"""self.msg_image = self.font.render(self, 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)
  • 其中的font.render方法將存儲在msg中的文本轉換為圖像,并將其存儲在msg_image中,其中的True參數表示開啟抗鋸齒功能,可以讓文字邊緣更光滑。接下來最后調通過rect調整按鈕位置。
  • 接下來draw_button來繪制按鈕。
  • game_functions.py的update_screen中加入判斷游戲活動狀態的if語句,若不在活動狀態,繪制一個按鈕
  • def update_screen(ai_settings: Settings, screen, stats: GameStatus, ship: ship.Ship, aliens: Group, bullets: Bullet,play_button: Button):"""更新屏幕上的圖像,并切換到新屏幕"""# 每次循環重繪屏幕screen.fill(ai_settings.bg_color)ship.blitme()# 繪制外星人aliens.draw(screen)# 重繪子彈for bullet in bullets.sprites():bullet.draw_bullet()if not stats.game_active:play_button.draw_button()# 最近繪制的屏幕可見pygame.display.flip()

    主方法中創建按鈕實例,并將其傳入update_screen方法中

  •  # 創建play按鈕play_button = Button(ai_settings, screen, "Play")

    19.開始游戲或重置游戲

  • 在game_functions.py中加入監視與按鈕相關的鼠標事件
  • def check_events(ai_settings, screen, ship, bullets, stats: GameStatus, play_button: Button):"""響應按鍵和鼠標事件"""for event in pygame.event.get():# 用戶按下鍵盤if 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.K_SPACE:fire_bullets(ai_settings, )elif event.type == pygame.MOUSEBUTTONDOWN:# 若按下按鈕mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(stats, play_button, mouse_x, mouse_y)
    def check_play_button(stats: GameStatus, play_button: Button, mouse_x, mouse_y):"""在玩家單擊play時開始游戲"""if play_button.rect.collidepoint(mouse_x, mouse_y):stats.game_active = True

    其中mouse.get_pos返回一個元組,表示鼠標點擊的坐標,我們用play_button.rect.collidepoint方法判斷是否與按鈕坐標重合

  • 接下來重置游戲,因為上面僅對第一次點擊有用

  • 再次修改check_lpay_button方法

  • def check_play_button(ai_settings, screen, stats: GameStatus, play_button: Button, mouse_x, mouse_y, aliens, ship,bullets):"""在玩家單擊play時開始游戲"""if play_button.rect.collidepoint(mouse_x, mouse_y):# 重置游戲并統計信息stats.reset_status()stats.game_active = True# 清空外星人和子彈的列表bullets.empty()aliens.empty()# 創建外星人,并讓飛船居中create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()

    瘋狂外星人小游戲、我們新加了這個方法的參數,不要忘了在調用這個方法的位置加上(pycharm中ctrl+alt+h可以查看調用次方法的方法)

  • 現在還是有個問題,如果玩家在點擊按鈕后再次點擊,會出現再次重置的情況,所以我們再加入對stats.game_active的判斷,同時再讓點擊后光標不可見

  • def check_play_button(ai_settings, screen, stats: GameStatus, play_button: Button, mouse_x, mouse_y, aliens, ship,bullets):"""在玩家單擊play時開始游戲"""button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)if button_clicked and not stats.game_active:#讓光標不可見pygame.mouse.set_visible(False)# 重置游戲并統計信息stats.reset_status()stats.game_active = True# 清空外星人和子彈的列表bullets.empty()aliens.empty()# 創建外星人,并讓飛船居中create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()

    修改ship_hit方法,讓游戲重置時,鼠標可見

  • def ship_hit(ai_settings: Settings, status: GameStatus, screen, ship: ship.Ship, aliens, bullets):"""響應外星人撞到飛船"""# 將飛船數量ship_left減一if status.ships_left > 0:status.ships_left -= 1# 清空外星人和子彈aliens.empty()bullets.empty()# 創建一群新的外星人,重置飛船create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()# 暫停sleep(0.5)else:status.game_active = Falsepygame.mouse.set_visible(True)
    

    20.加快游戲節奏

  • 我們修改Settings.py中的屬性來加快游戲
  • class Settings():def __init__(self):"""  初始化游戲時的靜態設置"""self.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)# 飛船設置self.ship_speed_factor = 1.0self.ship_limit = 3# 子彈設置self.bullet_speed_factor = 0.7self.bullet_width = 3self.bullet_height = 15self.bullet_color = 60, 60, 60# 限制子彈數量self.bullets_allowed = 3# 外星人設置self.alien_speed_factor = 0.5  # 外星人水平移動速度self.fleet_drop_speed = 10  # 外星人豎直移動速度self.fleet_direction = 1  # 移動方向: 1為向右,-1向左# 以什么樣的速度加快游戲節奏self.speedup_scale = 1.1self.initialize_dynamic_settings()def initialize_dynamic_settings(self):"""初始化游戲進行而變化的設置"""self.ship_speed_factor = 1.5self.bullet_speed_factor = 3self.alien_speed_factor = 1self.fleet_direction = 1def increase_speed(self):"""提高速度設置"""self.ship_speed_factor *= self.speedup_scaleself.alien_speed_factor *= self.speedup_scaleself.alien_speed_factor *= self.speedup_scale

    增加了一個倍率屬性和兩個方法

    def check_play_button(ai_settings: Settings, screen, stats: GameStatus, play_button: Button, mouse_x, mouse_y, aliens,ship,bullets):"""在玩家單擊play時開始游戲"""button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)if button_clicked and not stats.game_active:#重置游戲節奏ai_settings.initialize_dynamic_settings()。。。。。。。。。。。。。。。。。。。。。。。
    

  • 接下來修改

python入侵電腦。game_functions.py中的check_bullet_alien_collision

def check_bullet_alien_collision(ai_settings: Settings, screen, ship, aliens, bullets):# 檢查是否有子彈擊中外星人collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)# 更新外星人if len(aliens) == 0:bullets.empty()#增加游戲節奏ai_settings.increase_speed()create_fleet(ai_settings, screen, ship, aliens)
  • 但是現在還有個問題,我們重置游戲時游戲節奏沒有重置
  • def check_play_button(ai_settings: Settings, screen, stats: GameStatus, play_button: Button, mouse_x, mouse_y, aliens,ship,bullets):"""在玩家單擊play時開始游戲"""button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)if button_clicked and not stats.game_active:#重置游戲節奏ai_settings.initialize_dynamic_settings()
    

    21.計分

  • 新增game_status.py中GameStatus類中的屬性
  •     def reset_status(self):"""初始化在游戲運行期間可能變化的信息"""self.ships_left = self.ai_settings.ship_limitself.score = 0

    新建scoreboard.py模塊,并創建Scoreboard類:

  • class Scoreboard():"""顯示得分信息的類"""def __init__(self, ai_settings: Settings, screen: Surface, status: GameStatus):"""初始化得分涉及的屬性"""self.screen = screenself.screen_rect = screen.get_rect()self.ai_settings = ai_settingsself.status = status# 顯示得分時的字體設置self.text_color = (30, 30, 30)self.font = pygame.font.SysFont(None, 48)# 準備初始得分圖像self.prep_score()def prep_score(self):"""將得分轉換為渲染圖像"""score_str = str(self.status.score)self.score_image = self.font.render(score_str, True, self.text_color)# 將得分顯示在屏幕右上角self.score_rect = self.score_image.get_rect()self.score_rect.right = self.screen_rect.right - 20self.score_rect.top = 20def show_score(self):"""在屏幕上顯示得分"""self.screen.blit(self.score_image, self.score_rect)
    

    22.創建記分牌

  • 在主方法中循環前創建得分牌實例
  •  # 創建一個記分牌sb = Scoreboard(ai_settings, screen, stats)

    并將其傳入循環中的update_screen方法中

  • game_functions.py

  • def update_screen(ai_settings: Settings, screen, stats: GameStatus, ship: ship.Ship, aliens: Group, bullets: Bullet,play_button: Button, sb: Scoreboard):"""更新屏幕上的圖像,并切換到新屏幕"""。。。。。。。。。。。。。。# 顯示得分sb.show_score()# 最近繪制的屏幕可見pygame.display.flip()

    接下來我們開始增加分數

  • settings.py中加入分數設置

  •     def initialize_dynamic_settings(self):"""初始化游戲進行而變化的設置"""self.ship_speed_factor = 1.5self.bullet_speed_factor = 0.7self.alien_speed_factor = 0.7self.fleet_direction = 1# 計分self.alien_points = 50
  • ?game_functions.py中修改方法
    def check_bullet_alien_collision(ai_settings: Settings, screen, ship, aliens, bullets, stats: GameStatus,sb: Scoreboard):# 檢查是否有子彈擊中外星人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()# 更新外星人if len(aliens) == 0:bullets.empty()# 增加游戲節奏ai_settings.increase_speed()create_fleet(ai_settings, screen, ship, aliens)
    

    python武裝飛船。其中collisions是一個字典,我們拿到他的值,這個值是一個列表,其中包括我們一顆子彈打掉的全部飛船(不排除一箭雙雕),所以求出列表長度來算分

  • 不要忘了在形參中加入新的值并修改調用此方法傳入的參數

  • 接下來我們設置游戲難度提高后的點數

  • settings.py

  • class Settings():def __init__(self):。。。。。。。。。。。。。。# 點數提高速度self.score_scale = 1.5def increase_speed(self):。。。。。。。。。。。。。。"""提高點數"""self.alien_points = int(self.alien_points * self.score_scale)
    

    為了讓記分牌跟以前那種街機風格的記分牌一樣,每三位用“,”隔開,我們修改prep_score方法

  • scoreboard.py

  •     def prep_score(self):"""將得分轉換為渲染圖像"""# 將得分圓整rounded_score = int(round(self.status.score, -1))score_str = "{:,}".format(rounded_score)# score_str = str(self.status.score)刪去self.score_image = self.font.render(score_str, True, self.text_color)# 將得分顯示在屏幕右上角self.score_rect = self.score_image.get_rect()self.score_rect.right = self.screen_rect.right - 20self.score_rect.top = 20

    python入侵個人電腦。其中round()中的-1表示我們向10取整

  • 23.顯示最高得分

  • scoreboard.py
  •  def __init__(self, ai_settings: Settings, screen: Surface, status: GameStatus):"""初始化得分涉及的屬性"""。。。。。。。。。。。。self.prep_high_score()def show_score(self):"""在屏幕上顯示得分"""。。。。。。。。。。。。。。。。。self.screen.blit(self.high_score_image, self.high_score_rect)def prep_high_score(self):"""將最高得分轉換為渲染的圖像"""high_score = int(round(self.status.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.top

    接下來我們判斷是否誕生了最高分

  • game_functions.py加入

  • def check_high_score(stats: GameStatus, sb: Scoreboard):"""檢查是否誕生了最高分"""if stats.high_score < stats.score:stats.high_score = stats.scoresb.prep_high_score()

    我們需要在check_bullet_collision中調用分數判斷

    def check_bullet_alien_collision(ai_settings: Settings, screen, ship, aliens, bullets, stats: GameStatus,sb: Scoreboard):# 檢查是否有子彈擊中外星人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)。。。。。。。。。。。。。。。

    24、顯示等級

  • 增加屬性:
  • game_status.py
        def reset_status(self):"""初始化在游戲運行期間可能變化的信息"""。。。。。。。。。。。。。self.level = 1

    scoreboard.py

  •  def __init__(self, ai_settings: Settings, screen: Surface, status: GameStatus):"""初始化得分涉及的屬性"""。。。。。。。。。。。。。。。。self.prep_level()  
    def show_score(self):"""在屏幕上顯示得分"""。。。。。。。。。。。。。。。。。。self.screen.blit(self.level_image, self.level_rect)def prep_level(self):"""將等級渲染為圖像"""self.level_imageself.level_image = self.font.render(str(self.status.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 + 10

    game_functions.py中修改

  • def check_bullet_alien_collision(ai_settings: Settings, screen, ship, aliens, bullets, stats: GameStatus,sb: Scoreboard):。。。。。。。。。。。。。。。。。。。。。。。。。# 更新外星人if len(aliens) == 0:bullets.empty()# 增加游戲節奏ai_settings.increase_speed()# 如果外星人都被消滅,就提高一個等級stats.level += 1sb.prep_level()create_fleet(ai_settings, screen, ship, aliens)

    python小游戲代碼。為了每次點擊play按鈕時重置記分牌,我們修改

  • def check_play_button(ai_settings: Settings, screen, stats: GameStatus, play_button: Button, mouse_x, mouse_y, aliens,ship, bullets, sb: Scoreboard, ):"""在玩家單擊play時開始游戲"""...........................................# 重置得分牌圖像sb.prep_score()sb.prep_high_score()sb.prep_level()# 清空外星人和子彈的列表bullets.empty()aliens.empty()# 創建外星人,并讓飛船居中create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()

    我們新傳進來了個參數sb(ScoreBoard類)

  • 25.顯示剩余飛船

  • ship.py
  • class Ship(Sprite):def __init__(self, screen, ai_settings: Settings):"""初始化飛船,并設置其起始位置"""super(Ship, self).__init__()
    。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    讓飛船繼承sprite類,這樣我們可以加入編組中管理

  • scoreboard.py類修改

  • 
    class Scoreboard():"""顯示得分信息的類"""def __init__(self, ai_settings: Settings, screen: Surface, status: GameStatus):"""初始化得分涉及的屬性"""。。。。。。。。。。。。。。self.prep_ships()def show_score(self):"""在屏幕上顯示得分"""。。。。。。。。。。。。。。。。。。self.ships.draw(self.screen)def prep_ships(self):"""顯示還剩下多少飛船"""self.ships = Group()for ship_number in range(self.status.ships_left):ship = Ship(self.screen, self.ai_settings)ship.rect.x = 10 + ship_number * ship.rect.widthship.rect.y = 10self.ships.add(ship)
    

    game_functions.py修改,調用prep_ships方法

  • def check_play_button(ai_settings: Settings, screen, stats: GameStatus, play_button: Button, mouse_x, mouse_y, aliens,ship, bullets, sb: Scoreboard, ):"""在玩家單擊play時開始游戲"""。。。。。。。。。。。。。。。。。。# 重置得分牌圖像sb.prep_score()sb.prep_high_score()sb.prep_level()sb.prep_ships()# 清空外星人和子彈的列表bullets.empty()aliens.empty()# 創建外星人,并讓飛船居中create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()

    接下來我們在飛船撞到外星人時更新ships編組

  • def ship_hit(ai_settings: Settings, status: GameStatus, screen, ship: ship.Ship, aliens, bullets, sb: Scoreboard):"""響應外星人撞到飛船"""# 將飛船數量ship_left減一if status.ships_left > 0:status.ships_left -= 1# 更新記分牌sb.prep_ships()。。。。。。。。。。。。。。。。。。

    我們又加了一個sb參數,按ctrl+alt+h查看調用此方法的函數,依次修改函數形參

  • 最終結果

完結撒花,本來沒想到需要這么多字,打的我手疼(哭)。。。。沒有辛勞也有苦勞,祝點贊的各位看官bug少少,頭發多多~~~~

https://www.nshth.com/python/338575.html
>

相关文章:

  • 用python入侵別人手機
  • python小游戲代碼大全
  • pygame外星人入侵
  • 外星人入侵循環導入
  • python武裝飛船在手機上運行
  • 有外星人入侵嗎
  • python外星人入侵
  • 瘋狂外星人小游戲
  • pygame外星人入侵,python外星人入侵小游戲
  • 用python入侵別人手機,python外星人入侵游戲圖片_Python外星人入侵游戲編程完整版
  • 誰是外星人游戲,20_外星人游戲項目03——
  • python游戲腳本開發,python 外星人游戲怎么打開_Python外星人入侵游戲開發—創建游戲窗口
  • 用python入侵別人手機,python小游戲----外星人入侵
  • python游戲腳本開發,python 外星人游戲下載大全_【Python】Python制作外星人入侵小游戲
  • python播放聲音模塊,python外星人入侵添加音效_python外星人入侵游戲打包
  • python飛機大戰源碼,基于pygame的飛船大戰外星人游戲
  • python 外星人入侵游戲 學習總結 以及完整代碼
  • 有外星人入侵嗎,python外星人入侵游戲代碼_python外星人入侵 游戲源碼
  • python飛機大戰源碼,python項目——外星人入侵游戲
  • 純python開發的大型游戲,Python之外星人游戲(帶源碼和圖片資源)項目
  • python編程書籍推薦,培訓python排行榜
  • bilibili播放量排行榜,b站每日排行榜爬蟲
  • python爬蟲爬取網頁表格數據,python爬蟲爬取歌曲_python爬蟲實戰:爬取全站小說排行榜
  • 爬蟲爬取網站之家,【Python爬蟲】用Python爬取娛樂圈排行榜數據
  • 可以用python寫網頁嗎,有關python的比賽_用 Python 寫一個 Kaggle 比賽排行榜的爬蟲
  • python django框架,python開源框架排行_Python開源項目最新月榜TOP 10
  • 用python刷網頁瀏覽量,用Python獲取公眾號閱讀數、點贊數。
  • 用python做一個簡單的游戲,python有什么好玩的書_史上最全的Python書排行榜|你想知道的都在這里
  • python庫大全一覽,總結!Github年度最強Python庫排行榜
  • python b站 排行_Python爬蟲抓取B站小視頻排行榜,新手也可以跟著做哦!
  • ubuntu運行安卓app,ubuntu AndroiStudio 中 外設(手機、平板) 無法使用
  • ad軟件怎么將原理圖生成pcb,AD20怎樣生成PCB文件??
  • 基于python的影評數據分析,python爬取《你好, 李煥英》豆瓣評論數據
  • 測試顯卡性能的工具,技嘉顯卡性能測試軟件,你好六啊!GTX 1660 Ti深度測試:升吧
  • 捕獲異常的方法有,Scala系列20:Scala中異常捕獲與拋出異常
  • 通過thread類創建線程,【0805作業】繼承Thread類創建線程,輸出20次數字,“你好”,線程名
  • ip靜態,Centos7 配置靜態 IP 地址
  • ip靜態,Centos7 安裝,配置靜態IP