前言
本篇文章是建立在上一篇文章([Python小练习]Python低水平实现飞机大战-CSDN博客)的基础上,新增了商店系统
目录
一、商店界面成果展示
玩家可以敲击回车键打开商店界面,在该界面中,玩家可以通过花费score来增加飞机攻击力,飞机速度、飞机子弹尺寸等数值。
二、完整代码展示
import pygame.mixer
import pygame.mixer
import pygame
import random
import sys
import random
import pygame.font
#定义我方生命值
life = 3
# 游戏窗口的宽度和高度
WINDOW_WIDTH = 1000
WINDOW_HEIGHT = 1000
# 飞机尺寸和速度
AIRPLANE_WIDTH = 50
AIRPLANE_HEIGHT = 50
AIRPLANE_SPEED = 5
# 敌机尺寸和速度
ENEMY_WIDTH = 60
ENEMY_HEIGHT = 60
ENEMY_SPEED = 2.1
# 子弹尺寸和速度
BULLET_RADIUS = 20
BULLET_WIDTH = 30
BULLET_HEIGHT = 30
BULLET_SPEED = 3
#定义子弹攻击力
BULLET_ATTACK = 10
# 颜色定义
BLACK = pygame.Color(0, 0, 0)
WHITE = pygame.Color(255, 255, 255)
RED = pygame.Color(255, 0, 0)
PINK = pygame.Color(255, 105, 255) # 粉色
GREEN = pygame.Color("green") # 定义绿色常量
# 初始化 Pygame
pygame.init()
clock = pygame.time.Clock()
pygame.font.init() # 初始化字体模块
font = pygame.font.SysFont(None, 24) # 创建一个字体对象,第一个参数是字体名称,第二个参数是字体大小
# 创建游戏窗口
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('飞机大战')
#死亡界面的分数
score_death = "Finally SCORE:"
# 加载背景图片
background_image = pygame.image.load('background.jpg')
background_image = pygame.transform.scale(background_image, (WINDOW_WIDTH, WINDOW_HEIGHT))
# 加载飞机图片
airplane_image = pygame.image.load('airplane.png')
airplane_image = pygame.transform.scale(airplane_image, (AIRPLANE_WIDTH, AIRPLANE_HEIGHT))
#加载子弹图片
bullet_img = pygame.image.load("bullet.png")
bullet_img = pygame.transform.scale(bullet_img, (BULLET_WIDTH, BULLET_HEIGHT))
# 加载敌机图片
enemy_image = pygame.image.load('enemy3.jpg')
enemy_image = pygame.transform.scale(enemy_image, (ENEMY_WIDTH, ENEMY_HEIGHT))
# 加载死亡界面图片
game_over_image = pygame.image.load('game_over.png')
game_over_image = pygame.transform.scale(game_over_image, (300, 300))
# 创建飞机
airplane = pygame.Rect(WINDOW_WIDTH // 2 - AIRPLANE_WIDTH // 2, WINDOW_HEIGHT - AIRPLANE_HEIGHT, AIRPLANE_WIDTH, AIRPLANE_HEIGHT)
# 创建敌机列表
enemies = []
# 创建子弹列表
bullets = []
# 分数
score = 0
score_death = 0
#添加敌机死亡音效
pygame.init()
pygame.mixer.init()
bullet_hit_sound = pygame.mixer.Sound('sound.mp3')
#添加子弹发射音效
pygame.init()
pygame.mixer.init()
bullet_sound = pygame.mixer.Sound('sound2.mp3')
# 创建敌机
def create_enemy():
enemy_x = random.randint(0, WINDOW_WIDTH - ENEMY_WIDTH)
enemy_y = random.randint(-WINDOW_HEIGHT, -ENEMY_HEIGHT)
enemy = pygame.Rect(enemy_x, enemy_y, ENEMY_WIDTH, ENEMY_HEIGHT)
enemy.h = random.randint(0, 40)
enemies.append(enemy)
# 移动飞机
def move_airplane():
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and airplane.x > 0:
airplane.x -= AIRPLANE_SPEED
if keys[pygame.K_RIGHT] and airplane.x < WINDOW_WIDTH - AIRPLANE_WIDTH:
airplane.x += AIRPLANE_SPEED
# 移动敌机
def move_enemies():
global life
global score_death
global BULLET_RADIUS
global AIRPLANE_SPEED
for enemy in enemies:
enemy.y += ENEMY_SPEED
if enemy.h <= 0:
enemies.remove(enemy)
score_death = score_death + 1
BULLET_RADIUS = BULLET_RADIUS + 2
AIRPLANE_SPEED = AIRPLANE_SPEED + 0.1
if enemy.y > WINDOW_HEIGHT:
enemies.remove(enemy)
life = life - 1
# 当敌机飞出游戏框的下端时,血量减少1
if life<=0:
game_over()
# 移动子弹
def move_bullets():
for bullet in bullets:
bullet.y -= BULLET_SPEED
if bullet.y < 0:
bullets.remove(bullet)
# 检测子弹和敌机的碰撞
def check_collision():
global score_death
for enemy in enemies:
for bullet in bullets:
if enemy.colliderect(bullet):
bullet_hit_sound.play()
enemy.h= enemy.h - BULLET_ATTACK
bullets.remove(bullet)
# 击中敌机,增加分数
increase_score()
# 检测敌机和飞机的碰撞
def check_airplane_collision():
global life
for enemy in enemies:
if enemy.colliderect(airplane):
life = life - 1
enemies.remove(enemy)
if life <=0:
game_over()
# 增加分数
def increase_score():
global score
score += 1
# 显示死亡界面和分数
def game_over():
global score_death
font = pygame.font.Font(None, 36)
score_text = font.render("SCORE:" + str(score), True, WHITE)
window.blit(game_over_image, (WINDOW_WIDTH // 2 - 150, WINDOW_HEIGHT // 2 - 150))
window.blit(score_text, (WINDOW_WIDTH // 2 - 60, WINDOW_HEIGHT // 2 + 50))
pygame.display.update()
pygame.time.delay(3000)
pygame.quit()
sys.exit()
# 商店界面元素
shop_background_image = pygame.image.load("shop_background.png")
# 商品信息
items = [
{"name": "ATTACK", "price": 10},
{"name": "SPEED", "price": 10},
{"name": "SIZE", "price": 10}
]
selected_item = None # 当前选中的商品
# 游戏主循环
running = True
shop_mode = False # 商店模式,用于切换游戏界面和商店界面
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullet_sound.play()
# 创建子弹
bullet = pygame.Rect(airplane.x + AIRPLANE_WIDTH // 2 - BULLET_RADIUS // 2, airplane.y,BULLET_RADIUS, BULLET_RADIUS)
bullets.append(bullet)
if event.key == pygame.K_RETURN:
if not shop_mode: # 切换到商店模式
shop_mode = True
selected_item = None # 重置选中的商品
else: # 切换回游戏模式
shop_mode = False
if shop_mode:
if event.key == pygame.K_UP:
# 上移选中的商品
if selected_item is None:
selected_item = 0
else:
selected_item = (selected_item - 1) % len(items)
if event.key == pygame.K_DOWN:
# 下移选中的商品
if selected_item is None:
selected_item = 0
else:
selected_item = (selected_item + 1) % len(items)
if event.key == pygame.K_LEFT:
# 购买选中的商品
if selected_item is not None:
selected_item_name = items[selected_item]["name"]
selected_item_price = items[selected_item]["price"]
if score >= selected_item_price:
score -= selected_item_price
print("购买商品:", selected_item_name)
if selected_item_name == "SPEED":
BULLET_SPEED+=1
elif selected_item_name == "SIZE":
BULLET_RADIUS = BULLET_RADIUS + 20
elif selected_item_name == "ATTACK":
BULLET_ATTACK = BULLET_ATTACK + 3
if not shop_mode:
# 游戏模式逻辑
move_airplane()
move_enemies()
move_bullets()
check_collision()
check_airplane_collision()
window.blit(background_image, (0, 0))
window.blit(airplane_image, (airplane.x, airplane.y))
for enemy in enemies:
window.blit(enemy_image, (enemy.x, enemy.y))
for bullet in bullets:
pygame.draw.circle(window, PINK, (bullet.x + bullet.width // 2, bullet.y + bullet.height // 2), bullet.width // 2)
# 显示分数
font = pygame.font.Font(None, 36)
score_text = font.render("score : " + str(score), True, WHITE)
score_kill_text = font.render("kill : " + str(score_death), True, WHITE)
score_life_text = font.render("life : " + str(life), True, WHITE)
attack_text = font.render("ATTACK : " + str(BULLET_ATTACK), True, WHITE)
window.blit(score_text, (10, 10))
window.blit(score_kill_text, (10, 40))
window.blit(score_life_text, (10, 70))
window.blit(attack_text, (10, 100))
pygame.display.update()
clock.tick(60)
# 创建新的敌机
if random.randint(0, 60) == 0:
create_enemy()
else:
# 商店模式逻辑
window.blit(shop_background_image, (0, 0))
for i, item in enumerate(items):
name = item["name"]
price = item["price"]
text = font.render(f"{name}: {price} points", True, WHITE)
if selected_item == i:
# 选中的商品使用不同的颜色
text = font.render(f"{name}: {price} points", True, GREEN)
window.blit(text, (10, 10 + i * 30))
pygame.display.update()
clock.tick(60)
# 退出游戏
pygame.quit()
sys.exit()
三、商店界面代码详细解释
1.设置商店界面初始参数
#初始化商店内的某些信息
clock = pygame.time.Clock()
pygame.font.init() # 初始化字体模块
font = pygame.font.SysFont(None, 24) # 创建一个字体对象,第一个参数是字体名称,第二个参数是字体大小
# 在同目录下提前放置商店背景图片
shop_background_image = pygame.image.load("shop_background.png")
# 定义所有商品信息
# f分别为--ATTACK:飞机攻击力;SPEED:飞机移动速度;SIZE:子弹尺寸
items = [
{"name": "ATTACK", "price": 10},
{"name": "SPEED", "price": 10},
{"name": "SIZE", "price": 10}
]
selected_item = None # 当前选中的商品
2.界面开启及内部操作
在游戏内,敲击回车键可进入商店界面,再次敲击回车键返回到游戏。在商店内,可敲击上下键来上下移动选择商品,再敲击向左移动的按键,确定购买商品
#这部分代码放在“用空格创建子弹”的下面,具体查看第二部分的完整代码展示
if event.key == pygame.K_RETURN:
if not shop_mode: # 切换到商店模式
shop_mode = True
selected_item = None # 重置选中的商品
else: # 切换回游戏模式
shop_mode = False
if shop_mode:
if event.key == pygame.K_UP:
# 上移选中的商品
if selected_item is None:
selected_item = 0
else:
selected_item = (selected_item - 1) % len(items)
if event.key == pygame.K_DOWN:
# 下移选中的商品
if selected_item is None:
selected_item = 0
else:
selected_item = (selected_item + 1) % len(items)
if event.key == pygame.K_LEFT:
# 购买选中的商品
if selected_item is not None:
selected_item_name = items[selected_item]["name"]
selected_item_price = items[selected_item]["price"]
if score >= selected_item_price:
score -= selected_item_price
print("购买商品:", selected_item_name)
if selected_item_name == "SPEED":
BULLET_SPEED+=1
elif selected_item_name == "SIZE":
BULLET_RADIUS = BULLET_RADIUS + 20
elif selected_item_name == "ATTACK":
BULLET_ATTACK = BULLET_ATTACK + 3
3.不打开商店时的游戏逻辑
if not shop_mode:
# 游戏模式逻辑
move_airplane()
move_enemies()
move_bullets()
check_collision()
check_airplane_collision()
window.blit(background_image, (0, 0))
window.blit(airplane_image, (airplane.x, airplane.y))
for enemy in enemies:
window.blit(enemy_image, (enemy.x, enemy.y))
for bullet in bullets:
pygame.draw.circle(window, PINK, (bullet.x + bullet.width // 2, bullet.y + bullet.height // 2), bullet.width // 2)
# 显示分数
font = pygame.font.Font(None, 36)
score_text = font.render("score : " + str(score), True, WHITE)
score_kill_text = font.render("kill : " + str(score_death), True, WHITE)
score_life_text = font.render("life : " + str(life), True, WHITE)
attack_text = font.render("ATTACK : " + str(BULLET_ATTACK), True, WHITE)
window.blit(score_text, (10, 10))
window.blit(score_kill_text, (10, 40))
window.blit(score_life_text, (10, 70))
window.blit(attack_text, (10, 100))
pygame.display.update()
clock.tick(60)
# 创建新的敌机
if random.randint(0, 60) == 0:
create_enemy()
4.打开商店后的商店逻辑
else:
# 商店模式逻辑
window.blit(shop_background_image, (0, 0))
for i, item in enumerate(items):
name = item["name"]
price = item["price"]
text = font.render(f"{name}: {price} points", True, WHITE)
if selected_item == i:
# 选中的商品使用不同的颜色
text = font.render(f"{name}: {price} points", True, GREEN)
window.blit(text, (10, 10 + i * 30))
pygame.display.update()
clock.tick(60)
总结
在本篇文章中,我们继承了之前飞机大战文章的大部分代码,并增添了简易的商店系统,支持玩家敲击按键消耗分数来升级属性,但本篇文章尚有很多不足,游戏内容也有待优化,欢迎大佬指出!非常感谢您的观看!