最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

爆炸與寶箱,從零開始用Python制作飛機大戰(zhàn) P9

2023-08-24 21:16 作者:我真帥啊kk  | 我要投稿

'''編完之后回頭看有看不懂代碼的意義?來看看我的加注釋版吧,標(biāo)記了各個代碼的意義,如有問題敬請指出,共同探討'''

# Time : 2023/6/30 22:08

# !/user/bin/env python3

# -*- coding: utf-8 -*-

import random # 導(dǎo)入random庫,進(jìn)行隨機運算


import pygame # 導(dǎo)入pygame庫


import os # 導(dǎo)入os庫進(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('飛機大戰(zhàn)(plane_war)') # 設(shè)置標(biāo)題

clock = pygame.time.Clock() # 創(chuàng)建時鐘對象


# 加載圖片

background_img = pygame.image.load(os.path.join('img', 'background.png')).convert() # 背景圖

player_img = pygame.image.load(os.path.join('img', 'player.png')).convert() # 加載飛機圖片

player_mini_img = pygame.transform.scale(player_img, (25, 20)) # 縮小飛機圖片得到生命顯示的小飛機

player_mini_img.set_colorkey(BLACK) # 將小飛機圖片中黑色改為透明

rock_img = pygame.image.load(os.path.join('img', 'rock.png')).convert() # 加載隕石圖片

bullet_img = pygame.image.load(os.path.join('img', 'bullet.png')).convert() # 加載子彈圖片


rock_imges = [] # 創(chuàng)建隕石圖片列表

for i in range(7): # for循環(huán)遍歷

rock_imges.append(pygame.image.load(os.path.join('img', f'rock{i}.png')).convert())

# 格式化字符串,遍歷出每一個圖片素材并加進(jìn)隕石圖片列表


expl_anim = {}

expl_anim['lg'] = []

expl_anim['sm'] = []

expl_anim['player'] = []

for i in range(9):

expl_img = pygame.image.load(os.path.join('img', f'expl{i}.png')).convert()

expl_img.set_colorkey(BLACK)

expl_anim['lg'].append(pygame.transform.scale(expl_img, (75, 75)))

expl_anim['sm'].append(pygame.transform.scale(expl_img, (30, 30)))

player_expl_img = pygame.image.load(os.path.join('img', f'expl{i}.png')).convert()

player_expl_img.set_colorkey(BLACK)

expl_anim['player'].append(player_expl_img)


power_imgs = {}

power_imgs['shield'] = pygame.image.load(os.path.join('img', 'shield.png')).convert()

power_imgs['gun'] = pygame.image.load(os.path.join('img', 'gun.png')).convert()


# 加載聲音

shoot_sound = pygame.mixer.Sound(os.path.join('sound', 'shoot.wav')) # 加載射擊音效

# 加載隕石爆炸音效,組成列表

expl_sounds = [

pygame.mixer.Sound(os.path.join('sound', 'expl0.wav')),

pygame.mixer.Sound(os.path.join('sound', 'expl1.wav'))

]


die_sound = pygame.mixer.Sound(os.path.join('sound', 'rumble.ogg'))

shield_sound = pygame.mixer.Sound(os.path.join('sound', 'pow0.wav'))

gun_sound = pygame.mixer.Sound(os.path.join('sound', 'pow1.wav'))


pygame.mixer.music.load(os.path.join('sound', 'background.ogg')) # 加載背景音樂

pygame.mixer.music.set_volume(0.5) # 調(diào)整背景音樂音量


font_name = pygame.font.match_font('artal') # 查找字體文件路徑



def draw_text(surf, text, size, x, y): # 定義繪制積分函數(shù)

font = pygame.font.Font(font_name, size) # 創(chuàng)建字體對象

text_surface = font.render(text, True, WHITE) # 渲染,開啟抗鋸齒,文本白色

text_rect = text_surface.get_rect() # 獲取矩形輪廓

text_rect.centerx = x # 設(shè)置x坐標(biāo)

text_rect.centery = y # 設(shè)置y坐標(biāo)

surf.blit(text_surface, text_rect) # 繪制文字



def draw_health(surf, hp, x, y): # 定義繪制血條函數(shù)

if hp < 0: # 判斷血量是否為負(fù)數(shù)

hp = 0 # 如果是,那么將hp設(shè)為0


BAR_LENGTH = 100 # 設(shè)置血條長度

BAR_HEIGHT = 10 # 設(shè)置血條長度

fill = (hp / 100) * BAR_LENGTH # 設(shè)置內(nèi)填充長度

outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT) # 創(chuàng)建外圍矩形,表示血條的外框

fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT) # 創(chuàng)建內(nèi)填充矩形,表示血條的內(nèi)部填充

pygame.draw.rect(surf, GREEN, fill_rect) # 繪制內(nèi)部填充血條

pygame.draw.rect(surf, WHITE, outline_rect, 2) # 繪制外圍輪廓



def draw_lives(surf, lives, img, x, y): # 定義顯示生命函數(shù)

for i in range(lives): # 循環(huán)生命數(shù)次

img_rect = img.get_rect() # 獲取矩形輪廓

img_rect.x = x + 30 * i # 設(shè)置x坐標(biāo)

img_rect.y = y # 設(shè)置y坐標(biāo)

surf.blit(img, img_rect) # 繪制圖像



def new_rock():

rock = Rock() # 創(chuàng)建隕石對象

all_sprites.add(rock) # add:增加,將隕石對象加進(jìn)角色列表

rocks.add(rock) # 將隕石對象加進(jìn)隕石列表



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è)置成飛機圖片,并調(diào)整圖片大小

self.image.set_colorkey(BLACK) # 將素材中的黑色改透明


self.rect = self.image.get_rect() # 獲取矩形輪廓

self.radius = 23 # 設(shè)置半徑

# pygame.draw.circle(self.image, RED, self.rect.center, self.radius)


self.rect.centerx = WIDTH / 2 # 設(shè)置x中心

self.rect.bottom = HEIGHT - 20 # 底部坐標(biāo)


self.speedx = 8 # 設(shè)置x速度

self.health = 100 # 設(shè)置玩家血量

self.lives = 3 # 設(shè)置玩家生命數(shù)量

self.hidden = False # 隱藏狀態(tài)設(shè)為false

self.gun = 1


def update(self): # 位置更新

key_pressed = pygame.key.get_pressed() # 鍵狀態(tài)的列表

if key_pressed[pygame.K_RIGHT]: # 按下右方向鍵向右移動

self.rect.x += self.speedx


if key_pressed[pygame.K_LEFT]: # 檢測按下左方向鍵

self.rect.x -= self.speedx # 將x減speedx,相當(dāng)于向左移動


if self.rect.right > WIDTH: # 檢測是否超過右邊緣

self.rect.right = WIDTH # 條件達(dá)成則回到右邊緣


if self.rect.left < 0: # 檢測是否超過左邊緣

self.rect.left = 0 # 條件達(dá)成則回到左邊緣


if self.hidden and pygame.time.get_ticks() - self.hide_time > 1000: # 判斷隱身結(jié)束

self.hidden = False # 將隱藏狀態(tài)設(shè)置為False

self.rect.centerx = WIDTH / 2 # 設(shè)置x中心

self.rect.bottom = HEIGHT - 20 # 底部坐標(biāo)


self.image.set_alpha(int(self.health * 10)) # 設(shè)置透明度,根據(jù)血量變話,課程外代碼


if self.gun > 2 and pygame.time.get_ticks() - self.gun_time > 5000: # 判斷強化子彈時間是否超過5秒

self.gun = 1 # 將gun變量設(shè)為1,正常模式

def shoot(self):

if not (self.hidden): # 判斷是否不為隱藏狀態(tài)

if self.gun == 1: # 判斷gun是否為1,執(zhí)行正常狀態(tài)的發(fā)射子彈

bullet = Bullet(self.rect.centerx, self.rect.centery) # 創(chuàng)建子彈對象

all_sprites.add(bullet) # 將子彈對象加進(jìn)角色列表中

bullets.add(bullet) # 將子彈對象加進(jìn)子彈角色列表中

shoot_sound.play() # 播放子彈發(fā)射的聲音

elif self.gun >= 2: # 判斷gun是否2,執(zhí)行增益發(fā)射子彈

self.gun_time = pygame.time.get_ticks()

bullet1 = Bullet(self.rect.left, self.rect.centery) # 創(chuàng)建子彈對象

bullet2 = Bullet(self.rect.right, self.rect.centery) # 創(chuàng)建子彈對象

all_sprites.add(bullet1) # 將子彈對象加進(jìn)角色列表中

bullets.add(bullet1) # 將子彈對象加進(jìn)子彈角色列表中

shoot_sound.play() # 播放子彈發(fā)射的聲音

all_sprites.add(bullet2) # 將子彈對象加進(jìn)角色列表中

bullets.add(bullet2) # 將子彈對象加進(jìn)子彈角色列表中


def hide(self):

self.hidden = True # 將隱藏狀態(tài)變量設(shè)置為true,用于判斷

self.hide_time = pygame.time.get_ticks() # 將當(dāng)前時間賦值給變量

self.rect.center = (WIDTH / 2, HEIGHT + 50000) # 將位置移動到舞臺外


def gunup(self):

self.gun += 1 # 將gun變量+1,強化子彈




class Rock(pygame.sprite.Sprite): # 創(chuàng)建隕石類

def __init__(self): # 初始化函數(shù)

pygame.sprite.Sprite.__init__(self)

self.image_origin = random.choice(rock_imges) # 將角色設(shè)置成隕石圖片

self.image_origin.set_colorkey(BLACK) # 將素材中的黑色改為透明

self.image = self.image_origin.copy() # 拷貝原本圖片到變量


self.rect = self.image.get_rect() # 獲取矩形輪廓


self.radius = self.rect.width / 2.3 # 設(shè)置半徑

# pygame.draw.circle(self.image, RED, self.rect.center, self.radius)


self.rect.x = random.randrange(0, WIDTH - self.rect.width) # 設(shè)置隕石掉下來的x

self.rect.y = random.randrange(-180, -100) # 設(shè)置隕石初始y


# self.speedy = random.randrange(2, 5) # 隨機設(shè)置掉下速度

self.speedy = 1

self.speedx = random.randrange(-3, 3) # 隨機左右移動


self.rot_degree = random.randrange(-3, 3) # 隨機設(shè)置累加速度的值

self.total_degree = 0 # 初始化旋轉(zhuǎn)的速度


self.rock_hp = self.radius # 設(shè)置血量


def rotate(self):

self.total_degree += self.rot_degree # 累加速度

self.total_degree = self.total_degree % 360 # 將旋轉(zhuǎn)速度設(shè)為旋轉(zhuǎn)速度除360的余數(shù),以防旋轉(zhuǎn)速度超過360

self.image = pygame.transform.rotate(self.image_origin, self.total_degree) # 圖片轉(zhuǎn)動

center = self.rect.center # 將中心點位置保存在變量中

self.rect = self.image.get_rect() # 獲取矩形輪廓

self.rect.center = center # 將之前保存的中心點重新賦值給self.rect.center,以保持圖像的中心位置不變。


def update(self): # 位置更新

self.rotate() # 調(diào)用隕石轉(zhuǎn)動方法

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è)置隕石掉下來的x

self.rect.y = random.randrange(-100, -40) # 設(shè)置隕石初始y


self.speedy = random.randrange(2, 10) # 隨機設(shè)置掉下速度

self.speedx = random.randrange(-3, 3) # 隨機左右移動



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,與飛機x一樣

self.rect.y = y # 設(shè)置子彈初始的的y,與飛機y一樣


self.speedy = -10 # 子彈飛行速度(y變化的跨度)


def update(self): # 位置更新

self.rect.y += self.speedy # 子彈不斷增加y坐標(biāo)

if self.rect.bottom < 0: # 檢測子彈超過邊緣,則清除

self.kill() # 清除角色



class Explosion(pygame.sprite.Sprite): # 創(chuàng)建爆炸效果類

def __init__(self, center, size): # 初始化函數(shù)

pygame.sprite.Sprite.__init__(self)

self.size = size # 設(shè)置類型

self.image = expl_anim[self.size][0] # 將角色設(shè)置成子彈圖片


self.rect = self.image.get_rect() # 獲取矩形輪廓

self.rect.center = center # 設(shè)置位置

self.frame = 0 # 幀數(shù)

self.last_update = pygame.time.get_ticks() # 設(shè)置上一次更新的時間


def update(self): # 位置更新

now = pygame.time.get_ticks() # 現(xiàn)在的時間

if now - self.last_update > 50: # 檢測現(xiàn)在的時間比上次更新的時間是否超過了50

self.last_update = now # 將上次更新的時間設(shè)為現(xiàn)在時間

self.frame = self.frame + 1 # 幀數(shù)+1

if self.frame == len(expl_anim[self.size]): # 判斷幀數(shù)是否等于這個爆炸效果類型的總幀數(shù),也就是是否爆炸效果播放完了

self.kill() # 清除對象

else:

self.image = expl_anim[self.size][self.frame] # 如果沒播放完爆炸效果

center = self.rect.center # 將當(dāng)前中心位置賦值給center

self.rect = self.image.get_rect() # 設(shè)置矩形輪廓

self.rect.center = center # 將現(xiàn)在中心位置改為center



class Power(pygame.sprite.Sprite): # 創(chuàng)建增益效果類

def __init__(self, center): # 初始化函數(shù)

pygame.sprite.Sprite.__init__(self)

self.type = random.choice(['shield', 'gun']) # 創(chuàng)建增益類時,隨機選擇盾牌或子彈增益

self.image = power_imgs[self.type] # 將角色設(shè)置成子彈圖片

self.image.set_colorkey(BLACK) # 將素材中的黑色改為透明

if self.type == 'shield': # 判斷是否為盾牌類型

shield_sound.play() # 播放盾牌聲音

elif self.type == 'gun': # 判斷是否為子彈增益

gun_sound.play() # 播放子彈增益音效


self.rect = self.image.get_rect() # 獲取矩形輪廓

self.rect.center = center # 將中心設(shè)為center


self.speedy = 3 # 子彈飛行速度(y變化的跨度)


def update(self): # 位置更新

self.rect.y += self.speedy # 子彈不斷增加y坐標(biāo)

if self.rect.top > HEIGHT: # 檢測子彈超過邊緣,則清除

self.kill() # 清除角色



all_sprites = pygame.sprite.Group() # 創(chuàng)建所有角色表

rocks = pygame.sprite.Group() # 創(chuàng)建隕石角色表

bullets = pygame.sprite.Group() # 創(chuàng)建子彈角色表

powers = pygame.sprite.Group() # 創(chuàng)建增益效果角色表


player = Player() # 創(chuàng)建玩家類對象

all_sprites.add(player) # 將創(chuàng)建的玩家類對象放入角色列表


score = 0 # 初始化分?jǐn)?shù)


pygame.mixer.music.play(-1) # 循環(huán)播放背景音樂


for item in range(10): # 循環(huán)10次,共創(chuàng)建10個隕石對象

new_rock() # 創(chuàng)建隕石對象



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: # 檢測事件是否為按下按鍵


if event.key == pygame.K_SPACE: # 檢測按下的按鍵是否為空格

player.shoot() # 如果是,調(diào)用發(fā)射子彈方法發(fā)射子彈


elif event.key == pygame.K_UP: # 新增代碼,b站評論區(qū)中的用1000積分換生命,檢測按下的按鍵是否為上箭頭

if score > 999 and not player.lives >= 3: # 判斷評分是否大于999,玩家生命數(shù)是否大等于3

player.lives += 1 # 將玩家命加一

score -= 1000 # 分?jǐn)?shù)減1000

'割草機模式'

'''key_pressed = pygame.key.get_pressed()

if key_pressed[pygame.K_SPACE]: # 按下右方向鍵向右移動

player.shoot()'''


all_sprites.update() # 調(diào)用角色池里面的位置更新方法


hits_rock_and_bullet = pygame.sprite.groupcollide(rocks, bullets, False, True) # 檢測隕石是否碰到子彈,

# 如果碰到則隕石扣血

for hit in hits_rock_and_bullet:

hit.rock_hp -= 20 # 扣的數(shù)相當(dāng)于子彈威力

if hit.rock_hp <= 0: # 檢測隕石血量是否低等于0

random.choice(expl_sounds).play() # 播放隕石被擊碎的音頻

score += int(hit.radius) # 分?jǐn)?shù)增加隕石大小

expl = Explosion(hit.rect.center, 'lg') # 創(chuàng)建爆炸類型為lg的爆炸特效對象

all_sprites.add(expl) # 爆炸特效對象加進(jìn)角色表中,以進(jìn)行更新

new_rock() # 新建隕石

if random.random() > 0.1: # random.randonm()是弄一個0到1之間的隨機小數(shù),判斷該小數(shù)是否大于0.1,概率為百分之90

p = Power(hit.rect.center) # 創(chuàng)建增益效果對象

all_sprites.add(p) # 在角色表中增加增益效果對象,以便進(jìn)行更新

powers.add(p) # 在增益效果角色表中增加增益效果對象,以便單獨操作

hit.kill() # 清除隕石


hits_player_and_rock = pygame.sprite.spritecollide(player, rocks, True, pygame.sprite.collide_circle) # 檢測隕石碰到飛機

for hit in hits_player_and_rock:

player.health -= hit.radius # 血量減去隕石大小


new_rock() # 新建隕石


expl = Explosion(hit.rect.center, 'sm')

all_sprites.add(expl)

if player.health <= 0: # 判斷檢測血量小于等于0

death_expl = Explosion(player.rect.center, 'player') # 創(chuàng)建爆炸特效對象,類型為飛機爆炸

all_sprites.add(death_expl) # 在角色表中增加該爆炸特效對象

die_sound.play() # 播放飛機爆炸音效

player.lives -= 1 # 將命減一

player.hide() # 調(diào)用飛機隱藏方法隱藏

player.health = 100 # 血量回復(fù)到一百


if player.lives == 0: # 判斷檢測生命數(shù)等于零

running = False # 調(diào)整工具變量,結(jié)束游戲


hits_player_and_power = pygame.sprite.spritecollide(player, powers, True) # 檢測增益效果碰到飛機

for hit in hits_player_and_power:

if hit.type == 'shield': # 判斷增益效果是否為盾牌

player.health += 25 # 增加25滴血

if player.health > 100: # 如果增加后血量大于100

player.health = 100 # 將血量設(shè)置成100

elif hit.type == 'gun': # 判斷增益效果是否為子彈增益

player.gunup() # 調(diào)用子彈增益方法



screen.fill(BLACK) # 設(shè)置窗口界面顏色,顯示畫面

screen.blit(background_img, (0, 0)) # 填充背景圖片


all_sprites.draw(screen) # 繪制角色


draw_text(screen, str(score), 30, WIDTH / 2, 50) # 繪制分?jǐn)?shù)


draw_health(screen, player.health, 10, 30) # 繪制血量


draw_lives(screen, player.lives, player_mini_img, WIDTH - 100, 15) # 繪制命數(shù)


pygame.display.update() # 更新狀態(tài)


pygame.quit() # 退出


爆炸與寶箱,從零開始用Python制作飛機大戰(zhàn) P9的評論 (共 條)

分享到微博請遵守國家法律
沛县| 朝阳县| 莱阳市| 漯河市| 江城| 大新县| 垫江县| 滁州市| 申扎县| 德保县| 秦安县| 平谷区| 介休市| 嵊泗县| 元氏县| 南澳县| 潼南县| 梨树县| 海南省| 延庆县| 西城区| 澜沧| 格尔木市| 衡山县| 齐齐哈尔市| 岚皋县| 宜丰县| 麻江县| 景泰县| 新民市| 防城港市| 蒲江县| 获嘉县| 荔波县| 桑日县| 册亨县| 鄂尔多斯市| 海城市| 南部县| 烟台市| 饶平县|