请老师看一下我的代码有什么问题
main
import pygame
import sys
import constants
from game.plane import OurPlane, SmallEnemyPlane
from game.war import PlaneWar
def main():
'''游戏入口'''
war = PlaneWar()
# 添加小型敌方飞机
war.add_small_enemies(constants.NUM)
war.run_game()
if __name__ == '__main__':
main()
war
import pygame
import sys
import constants
from game.plane import OurPlane, SmallEnemyPlane
from store.result import PlayRest
class PlaneWar:
"""飞机大战"""
# 游戏状态
READY = 0 # 游戏开始
PLAYING = 1 # 游戏进行中
OVER = 2 # 游戏结束
status = READY # 准备中 1 游戏中 2 游戏结束
our_plane = None
# #设置帧数
frame = 0 # 播放帧数
# 一架飞机可以属于多个精灵组
small_enemies = pygame.sprite.Group()
enemies = pygame.sprite.Group()
# 结果得分
rest = PlayRest()
def __init__(self):
# 初始化游戏
pygame.init()
self.width, self.height = 480, 852
# 屏幕对象
self.screen = pygame.display.set_mode((self.width, self.height))
# 设置窗口标题
pygame.display.set_caption('飞机大战')
# 加载背景图片
self.bg = pygame.image.load(constants.BG_IMG)
self.bg_over = pygame.image.load(constants.BG_OVER_IMG)
# 游戏的标题与游戏的开始按钮
self.img_game_start = pygame.image.load(constants.IMG_GAME_START)
self.img_game_title = pygame.image.load(constants.IMG_GAME_TITLE)
self.img_game_start_rect = self.img_game_start.get_rect()
self.img_game_title_rect = self.img_game_title.get_rect()
# 开始按钮的宽度和高度
self.t_width, self.t_height = self.img_game_title.get_size()
self.s_width, self.s_height = self.img_game_start.get_size()
self.img_game_title_rect.topleft = (int((self.width - self.t_width) / 2), int(self.height / 2 - self.t_height))
self.img_game_start_rect.topleft = (int((self.width - self.s_width) / 2), int(self.height / 2 + self.s_height))
# 游戏文字对象
self.score_font = pygame.font.Font(constants.FONT_GAME, 40)
# 加载背景音乐
pygame.mixer.music.load(constants.BG_MUSIC)
pygame.mixer.music.set_volume(0.2)
pygame.mixer.music.play(-1)
# 我方飞机对象
self.our_plane = OurPlane(self.screen, speed=20)
# 设置帧率
self.clock = pygame.time.Clock()
# 上次按的键盘上的某一个键,用于控制飞机
self.key_down = None
def bind_event(self):
# 1.监听事件
for event in pygame.event.get():
# 退出游戏
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
# 鼠标点击进入游戏
# 游戏正在准备中,点击才能进入游戏
if self.status == self.READY:
self.status = self.PLAYING
self.rest.score = 0
elif self.status == self.PLAYING:
self.our_plane.shoot()
elif self.status == self.OVER:
self.status == self.READY
self.add_small_enemies(constants.NUM)
elif event.type == pygame.KEYDOWN:
# 键盘事件
self.key_down = event.key
# 游戏正在进行中
if self.status == self.PLAYING:
if event.key == pygame.K_w or event.key == pygame.K_UP:
self.our_plane.move_up()
elif event.key == pygame.K_s or event.key == pygame.K_DOWN:
self.our_plane.move_down()
elif event.key == pygame.K_a or event.key == pygame.K_LEFT:
self.our_plane.move_left()
elif event.key == pygame.K_d or event.key == pygame.K_RIGHT:
self.our_plane.move_right()
elif event.key== pygame.K_SPACE:
# 发射子弹
self.our_plane.shoot()
def add_small_enemies(self, num):
# 敌方小型飞机随机引入6架
for i in range(num):
small_plane = SmallEnemyPlane(self.screen, 4)
small_plane.add(self.small_enemies, self.enemies)
def run_game(self):
"""游戏主循环"""
while True:
# 1.设置帧速率
self.clock.tick(60)
self.frame += 1
if self.frame >= 60:
frame = 0
# 2.绑定事件
self.bind_event()
# 3.更新游戏的状态
if self.status == self.READY:
# 游戏正在准备中
# 绘制背景
self.screen.blit(self.bg, self.bg.get_rect())
# 标题
self.screen.blit(self.img_game_title, self.img_game_title_rect)
# 开始按钮
self.screen.blit(self.img_game_start, self.img_game_start_rect)
self.key_down = None
elif self.status == self.PLAYING:
# 游戏进行中
# 绘制背景
self.screen.blit(self.bg, self.bg.get_rect())
# 绘制飞机
self.our_plane.blit_me()
self.our_plane.update(self)
# 绘制子弹
self.our_plane.ballets.update(self)
# 绘制敌方战机
self.small_enemies.update()
# 游戏分数
self.score_text = self.score_font.render('得分:{}'.format(self.rest.score), False,
constants.FONT_GAME_COLER)
self.screen.blit(self.score_text, self.score_text.get_rect())
elif self.status == self.OVER:
# # 游戏结束
# 游戏背景
self.screen.blit(self.bg_over, self.bg_over.get_rect())
# 分数统计
# 1. 本次总分
score_text = self.score_font.render(
'{0}'.format(self.rest.score),
False,
constants.FONT_GAME_COLER
)
score_text_rect = score_text.get_rect()
text_w, text_h = score_text.get_size()
# 改变文字的位置
score_text_rect.topleft = (int((self.width - text_h) / 2), int(self.height / 2))
self.screen.blit(score_text, score_text_rect)
# 2. 历史最高分
score_his = self.score_font.render('{0}'.format(self.rest.get_max_score()), False,
constants.FONT_GAME_COLER
)
self.screen.blit(score_his, (150, 40))
#刷新屏幕
pygame.display.flip()
plane
import random
import constants
import pygame
from game.ballet import Ballet
'''
飞机的种类
我方飞机 小型敌方飞机 中型敌方飞机 大型敌方飞机
'''
class Plane(pygame.sprite.Sprite):
"""
飞机的基础类
"""
# 飞机的图片
plane_images = []
# 飞机爆炸的图片
distory_images = []
# 飞机坠毁的音乐
down_sound_src = None
# 飞机的状态 True 活的 False 死的
active = True
# 该飞机发射的子弹精灵组
ballets = pygame.sprite.Group()
def __init__(self, screen, speed=None):
super().__init__()
# 加载静态资源
self.screen = screen
self.img_list = []
self.destory_img_list = []
self.down_sound = None
self.load_src()
# 飞行的速度
self.speed = speed or 10
# 获取飞机的位置
self.rect = self.img_list[0].get_rect()
# 飞机的高度和宽度
self.plane_w, self.plane_h = self.img_list[0].get_size()
# 游戏窗口的大小
self.width, self.height = self.screen.get_size()
# 改变飞机的初始化位置
self.rect.left = int((self.width - self.plane_w) / 2)
self.rect.top = int(self.height / 2)
def load_src(self):
"""加载静态资源"""
# 飞机图像
for img in self.plane_images:
self.img_list.append(pygame.image.load(img))
# #飞机坠毁的图片
# for img in self.destory_images():
# self.destory_img_list.append(pygame.image.load(img))
# 坠毁的音乐
if self.down_sound_src:
self.down_sound = pygame.mixer.Sound(self.down_sound_src)
@property
def image(self):
return self.img_list[0]
def blit_me(self):
self.screen.blit(self.image, self.rect)
def move_up(self):
"""飞机向上移动"""
self.rect.top -= self.speed
def move_down(self):
"""飞机向下移动"""
self.rect.top += self.speed
def move_left(self):
"""飞机向左移动"""
self.rect.left -= self.speed
def move_right(self):
"""飞机向右移动"""
self.rect.left += self.speed
def broken_down(self):
"""飞机坠毁效果"""
# 1.播放坠毁音乐
if self.down_sound:
self.down_sound.play()
# 2.播放坠毁动画
for img in self.destory_img_list:
self.screen.blit(img, self.rect)
# 3. 坠毁后。。
self.active = False
def shoot(self):
"""'飞机发射的子弹"""
ballet = Ballet(self.screen, self, 15)
self.ballets.add(ballet)
class OurPlane(Plane):
"""我方的飞机"""
# 飞机的图片
plane_images = [constants.OUR_PLANE_IMG_1, constants.OUR_PLANE_IMG_2]
# 飞机爆炸的图片
destory_images = constants.OUR_destroy_IMG_list
# 飞机坠毁的音乐
down_sound_src = None
def update(self, war):
if war.frame % 5:
self.screen.blit(self.img_list[0], self.rect)
else:
self.screen.blit(self.img_list[1], self.rect)
# 飞机撞击检测
rest = pygame.sprite.spritecollide(self, war.enemies, False)
if rest:
# 1.游戏结束
war.status = war.OVER
# 2.敌方飞机清除,精灵族的清除方法
war.enemies.empty()
war.small_enemies.empty()
# 3.我放飞机坠毁效果
self.broken_down()
# 4.记录游戏成绩
def move(self, key):
"""飞机控制自动移动"""
if key == pygame.K_w or key == pygame.K_UP:
self.move_up()
elif key == pygame.K_s or key == pygame.K_DOWN:
self.move_down()
elif key == pygame.K_a or key == pygame.K_LEFT:
self.move_left()
elif key == pygame.K_d or key == pygame.K_RIGHT:
self.move_right()
def move_up(self):
"""向上移动。超出范围之后拉回来"""
super().move_up()
if self.rect.top <= 0:
self.rect.top = 0
def move_down(self):
super().move_down()
if self.rect.bottom >= self.height:
self.rect.bottom = self.height # bottom为底部
def move_left(self):
super().move_left()
if self.rect.left <= 0:
self.rect.left = 0
def move_right(self):
super().move_right()
if self.rect.right >= self.width:
self.rect.right = self.width
class SmallEnemyPlane(Plane):
""" 敌方的小型飞机"""
# 飞机的图片
plane_images = [constants.SMALL_EMPTY_PLANE]
# 飞机爆炸的图片
distory_images = constants.SMALL_EMPTY_PLANE_DISTROY
# 飞机坠毁的音乐
down_sound_src = constants.SMALL_EMPTY_PLANE_DOWN_SOUND
def __init__(self, screen, speed):
super().__init__(screen, speed)
# 每次生成一架敌方战机
# 改变飞机的随机位置
self.init_pos()
def init_pos(self):
# 屏幕宽度-飞机的宽度
self.rect.left = random.randint(0, self.width - self.plane_w)
# 屏幕外随即高度
self.rect.top = random.randint(-5 * self.plane_h, -self.plane_h)
def update(self, *args):
"""更新飞机的移动"""
super().move_down()
# 画在屏幕上
self.blit_me()
# 超出范围如何处理
# 1.重用
if self.rect.top >= self.height:
self.active = False
# self.kill()
self.reset()
# todo 2.多线程,多进程
def reset(self):
self.active = True
self.init_pos()
def broken_down(self):
"""飞机爆炸"""
super().broken_down()
# 重复利用飞机对象
self.reset()
ballet
import pygame
import constants
class Ballet(pygame.sprite.Sprite):
"""子弹类"""
# 子弹状态 ,True活的
active = True
def __init__(self, screen, plane, speed=None):
super().__init__()
self.screen = screen
self.speed = speed or 10
self.plane = plane
# 加载子弹图片
self.image = pygame.image.load(constants.BALLET_IMG)
# 改变子弹的位置
self.rect = self.image.get_rect()
self.rect.centerx = plane.rect.centerx
self.rect.top = plane.rect.top
# 发射的音乐效果
self.shoot_sound = pygame.mixer.Sound(constants.BALLET_SHOOT_SOUND)
self.shoot_sound.set_volume(0.2)
self.shoot_sound.play()
def update(self, war):
"""更新子弹的位置"""
self.rect.top -= self.speed
# 超出屏幕范围
if self.rect.top < 0:
self.remove(self.plane.ballets)
# 绘制子弹
self.screen.blit(self.image, self.rect)
# 碰撞检测,检测子弹是否已经碰撞到了敌机
rest = pygame.sprite.spritecollide(self, war.enemies, False)
for r in rest:
# 1:子弹消失
self.kill()
# 2.飞机爆炸坠毁的效果
r.broken_down()
# 3.统计成绩
war.rest.score += constants.SCORE_SHOOT_SMALL
war.rest.set_history
运行没有问题,但是写的自动移动的代码没有运行,移动优化没有成功,成绩写入也没有自动写入
constants
import os
import pygame
# 项目的根目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 内部返回py文件的绝对路径,外部返回py文件的目录
# 静态文件的目录
ASSETS_DIR = os.path.join(BASE_DIR, 'assets')
# 背景图片
BG_IMG = os.path.join(ASSETS_DIR, 'images/background.png')
BG_OVER_IMG = os.path.join(ASSETS_DIR, 'images/game_over.png')
# 背景音乐
BG_MUSIC = os.path.join(ASSETS_DIR, 'sounds/game_bg_music.mp3')
# 游戏字体加载
FONT_GAME = os.path.join(ASSETS_DIR, 'font/simhei.ttf')
FONT_GAME_COLER = pygame.Color(255,0,0)
# 击中小型飞机增加10分
SCORE_SHOOT_SMALL = 10
#游戏结果存储的文件地址
PLAY_RESULT_STORE_FILE=os.path.join(BASE_DIR,'store/rest.txt')
# 游戏开始界面
IMG_GAME_START = os.path.join(ASSETS_DIR, 'images/game_start.png')
IMG_GAME_TITLE = os.path.join(ASSETS_DIR, 'images/game_title.png')
# 我放飞机的静态资源
OUR_PLANE_IMG_1 = os.path.join(ASSETS_DIR, 'images/hero1.png')
OUR_PLANE_IMG_2 = os.path.join(ASSETS_DIR, 'images/hero2.png')
OUR_destroy_IMG_list = [
os.path.join(ASSETS_DIR, 'images/hero_broken_n1.png'),
os.path.join(ASSETS_DIR, 'images/hero_broken_n2.png'),
os.path.join(ASSETS_DIR, 'images/hero_broken_n3.png'),
os.path.join(ASSETS_DIR, 'images/hero_broken_n4.png')]
# 子弹的静态资源
BALLET_IMG = os.path.join(ASSETS_DIR, 'images/bullet1.png')
BALLET_SHOOT_SOUND = os.path.join(ASSETS_DIR, 'sounds/bullet.wav')
# 敌方飞机的静态资源
SMALL_EMPTY_PLANE = os.path.join(ASSETS_DIR, 'images/enemy1.png')
SMALL_EMPTY_PLANE_DISTROY = [
os.path.join(ASSETS_DIR, 'images/enemy1_down1.png'),
os.path.join(ASSETS_DIR, 'images/enemy1_down2.png'),
os.path.join(ASSETS_DIR, 'images/enemy1_down3.png'),
os.path.join(ASSETS_DIR, 'images/enemy1_down4.png')]
# 敌方飞机坠毁的音效
SMALL_EMPTY_PLANE_DOWN_SOUND = os.path.join(ASSETS_DIR, 'sounds/enemy1_down.wav')
#敌方飞机数量
NUM=6
rest
import constants
class PlayRest():
__score = 0 # 总分
__life = 3 # 生命数量
__blood = 1000 # 生命值
@property
def score(self):
"""单次游戏分数"""
return self.__score
@score.setter
def score(self, value):
"""设置游戏分数"""
if value < 0:
return None
self.__score = value
def set_history(self):
"""记录最高分"""
# 1.读取文件中的历史最高分数
# 2.如果新的分数比文件中的分数要大,则进行储存,小于文件中分数不做处理
# 3.储存分数不是追加模式a,而是替换模式w
if int(self.get_max_score()) < self.score:
with open(constants.PLAY_RESULT_STORE_FILE, 'w') as f:
f.write('{}'.format(self.score))
def get_max_score(self):
"""读取文件中的历史最高分"""
rest = 0
with open(constants.PLAY_RESULT_STORE_FILE, 'r') as f:
r = f.read()
if r:
rest = r
return rest
rest.txt
10
正在回答
同学,你好。将游戏结束后再次点击鼠标的后,游戏状态进入准备状态,应该使用赋值语句,如:

祝学习愉快~
- 参与学习 人
- 提交作业 2727 份
- 解答问题 8160 个
想要进入Python Web、爬虫、人工智能等高薪领域,你需要掌握本阶段的Python基础知识,课程安排带你高效学习轻松入门,学完你也能听得懂Python工程师的行业梗。
了解课程


恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星