引入圖片+聲音,從零開(kāi)始用Python編程制作飛機(jī)大戰(zhàn)【教程第6集】

'''編完之后回頭看有看不懂代碼的意義?來(lái)看看我的加注釋版吧,標(biāo)記了各個(gè)代碼的意義,如有問(wèn)題敬請(qǐng)指出'''
# Time : 2023/6/30 22:08
# !/user/bin/env python3
# -*- coding: utf-8 -*-
import random # 導(dǎo)入random庫(kù),進(jìn)行隨機(jī)運(yùn)算
import pygame # 導(dǎo)入pygame庫(kù)
import os # 導(dǎo)入os庫(kù)進(jìn)行文件操作
# 定義常量
WIDTH = 500 # 窗口的寬
HEIGHT = 600 # 窗口的高
WHITE = (255, 255, 255) # 白色RGB常量
GREEN = (0, 255, 0) # 綠色RGB常量
RED = (255, 0, 0) # 紅石RGB常量
YELLOW = (255, 255, 0) # 黃色RGB常量
BLACK = (0, 0, 0) # 黑色RGB常量
# 游戲初始化
pygame.init() # 游戲初始化
pygame.mixer.init() # 音頻初始化
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 設(shè)置界面寬高
pygame.display.set_caption('飛機(jī)大戰(zhàn)(plane_war)') # 設(shè)置標(biāo)題
clock = pygame.time.Clock() # 創(chuàng)建時(shí)鐘對(duì)象
# 導(dǎo)入圖片
background_img = pygame.image.load(os.path.join('img', 'background.png')).convert() # 導(dǎo)入背景圖
player_img = pygame.image.load(os.path.join('img', 'player.png')).convert() # 導(dǎo)入飛機(jī)圖片
rock_img = pygame.image.load(os.path.join('img', 'rock.png')).convert() # 導(dǎo)入隕石圖片
bullet_img = pygame.image.load(os.path.join('img', 'bullet.png')).convert() # 導(dǎo)入子彈圖片
# 導(dǎo)入聲音
shoot_sound = pygame.mixer.Sound(os.path.join('sound', 'shoot.wav')) # 導(dǎo)入射擊音效
# 導(dǎo)入隕石爆炸音效,組成列表
expl_sounds = [
pygame.mixer.Sound(os.path.join('sound', 'expl0.wav')),
pygame.mixer.Sound(os.path.join('sound', 'expl1.wav'))
]
pygame.mixer.music.load(os.path.join('sound', 'background.ogg')) # 導(dǎo)入背景音樂(lè)
pygame.mixer.music.set_volume(0.5) # 調(diào)整背景音樂(lè)音量
class Player(pygame.sprite.Sprite): # 創(chuàng)建玩家類
def __init__(self): # 初始化函數(shù)
pygame.sprite.Sprite.__init__(self)
self.image = pygame.transform.scale(player_img, (50, 40)) # 角色設(shè)置成飛機(jī)圖片,并調(diào)整圖片大小
self.image.set_colorkey(BLACK) # 將素材中的黑色改透明
self.rect = self.image.get_rect() # 獲得輪廓
self.rect.centerx = WIDTH / 2 # 設(shè)置x中心
self.rect.bottom = HEIGHT - 20 # 底部坐標(biāo)
self.speedx = 8 # 設(shè)置x速度
def update(self): # 位置更新
key_pressed = pygame.key.get_pressed() # 鍵狀態(tài)的列表
if key_pressed[pygame.K_RIGHT]: # 按下右方向鍵向右移動(dòng)
self.rect.x += self.speedx
if key_pressed[pygame.K_LEFT]: # 檢測(cè)按下左方向鍵
self.rect.x -= self.speedx # 將x減speedx,相當(dāng)于向左移動(dòng)
if self.rect.right > WIDTH: # 檢測(cè)是否超過(guò)右邊緣
self.rect.right = WIDTH # 條件達(dá)成則回到右邊緣
if self.rect.left < 0: # 檢測(cè)是否超過(guò)左邊緣
self.rect.left = 0 # 條件達(dá)成則回到左邊緣
def shoot(self):
bullet = Bullet(
self.rect.centerx, self.rect.centery) # 創(chuàng)建子彈對(duì)象
all_sprites.add(bullet) # 將子彈對(duì)象加進(jìn)角色列表中
bullets.add(bullet) # 將子彈對(duì)象加進(jìn)子彈角色列表中
shoot_sound.play() # 播放子彈發(fā)射的聲音
class Rock(pygame.sprite.Sprite): # 創(chuàng)建隕石類
def __init__(self): # 初始化函數(shù)
pygame.sprite.Sprite.__init__(self)
self.image = rock_img # 將角色設(shè)置成隕石圖片
self.image.set_colorkey(BLACK) # 將素材中的黑色改為透明
self.rect = self.image.get_rect() # 獲得輪廓
self.rect.x = random.randrange(0, WIDTH - self.rect.width) # 設(shè)置隕石掉下來(lái)的x
self.rect.y = random.randrange(-100, -40) # 設(shè)置隕石初始y
self.speedy = random.randrange(2, 5) # 隨機(jī)設(shè)置掉下速度
self.speedx = random.randrange(-3, 3) # 隨機(jī)左右移動(dòng)
def update(self): # 位置更新
self.rect.y += self.speedy # 隕石不斷增加y坐標(biāo)
self.rect.x += self.speedx # 隕石不斷更新x坐標(biāo)
if self.rect.top > HEIGHT or self.rect.left > WIDTH or self.rect.right < 0: # 判斷輪廓超出邊緣就重新回到上面
self.rect.x = random.randrange(0, WIDTH - self.rect.width) # 設(shè)置隕石掉下來(lái)的x
self.rect.y = random.randrange(-100, -40) # 設(shè)置隕石初始y
self.speedy = random.randrange(2, 10) # 隨機(jī)設(shè)置掉下速度
self.speedx = random.randrange(-3, 3) # 隨機(jī)左右移動(dòng)
class Bullet(pygame.sprite.Sprite): # 創(chuàng)建子彈類
def __init__(self, x, y): # 初始化函數(shù)
pygame.sprite.Sprite.__init__(self)
self.image = bullet_img # 將角色設(shè)置成子彈圖片
self.image.set_colorkey(BLACK) # 將素材中的黑色改為透明
self.rect = self.image.get_rect() # 獲得輪廓
self.rect.x = x # 設(shè)置子彈初始的的x,與飛機(jī)x一樣
self.rect.y = y # 設(shè)置子彈初始的的y,與飛機(jī)y一樣
self.speedy = -10 # 子彈飛行速度(y變化的跨度)
def update(self): # 位置更新
self.rect.y += self.speedy # 子彈不斷增加y坐標(biāo)
if self.rect.bottom < 0: # 檢測(cè)子彈超過(guò)邊緣,則清除
self.kill() # 清除角色
all_sprites = pygame.sprite.Group() # 創(chuàng)建所有角色表
rocks = pygame.sprite.Group() # 創(chuàng)建隕石角色表
bullets = pygame.sprite.Group() # 創(chuàng)建子彈角色表
player = Player() # 創(chuàng)建玩家類對(duì)象
all_sprites.add(player) # 將創(chuàng)建的玩家類對(duì)象放入角色列表
pygame.mixer.music.play(-1) # 循環(huán)播放背景音樂(lè)
for item in range(10): # 循環(huán)10次,共創(chuàng)建10個(gè)隕石對(duì)象
rock = Rock() # 創(chuàng)建隕石對(duì)象
all_sprites.add(rock) # add:增加,將隕石對(duì)象加進(jìn)角色列表
rocks.add(rock) # 將隕石對(duì)象加進(jìn)隕石列表
running = True # 定義工具變量用于控制循環(huán)
while running: # 主循環(huán),循環(huán)至關(guān)閉窗口
clock.tick(60) # 設(shè)置幀數(shù)
for event in pygame.event.get(): # 獲取事件
if event.type == pygame.QUIT: # 判斷是否為退出事件
running = False # 如果是,則將變量設(shè)為False,停止循環(huán)
elif event.type == pygame.KEYDOWN: # 檢測(cè)有按鍵按下
if event.key == pygame.K_SPACE: # 判斷是否為空格
player.shoot() # 如果是,則調(diào)用射擊函數(shù)射出子彈
all_sprites.update() # 調(diào)用角色池里面的位置更新方法
hits_rock_and_bullet = pygame.sprite.groupcollide(rocks, bullets, True, True) # 檢測(cè)隕石是否碰到子彈,
# 如果碰到則刪除并新建一個(gè)隕石
for hit in hits_rock_and_bullet:
random.choice(expl_sounds).play() # 播放隕石被擊碎的音頻
r = Rock() # 新建一個(gè)隕石對(duì)象并賦值到r
all_sprites.add(r) # 在所有角色表中增加隕石對(duì)象
rocks.add(r) # 在隕石角色表中增加隕石對(duì)象
hits_rock_and_player = pygame.sprite.spritecollide(player, rocks, False) # 檢測(cè)隕石碰到飛機(jī)
if hits_rock_and_player:
running = False # 將工具變量設(shè)為False,停止游戲
screen.fill(BLACK) # 設(shè)置窗口界面顏色,顯示畫面
screen.blit(background_img, (0, 0)) # 填充背景圖片
all_sprites.draw(screen) # 繪制角色
pygame.display.update() # 更新?tīng)顟B(tài)
pygame.quit() # 退出