20234107 沈紫娴《Python程序设计》实验四报告

20234107沈紫娴 2024-05-27 18:27:35


20234108 2023-2024-2 《Python程序设计》综合实践
课程:《Python程序设计》
班级:2341
姓名:沈紫娴
学号:20234107
实验教师:王志强
实验日期:2024年5月27日
必修/选修: 专选课

1.实验内容
Python综合应用:
选择利用PyCharm编写游戏“飞机大战”。
2. 实验过程及结果
(1)安装pygame模块:

在file--settings--Project Interpreter中添加pygame package。

(2)素材准备

直接在项目下,将准备好的素材图片文件夹整个导入,命名为image。

(3)游戏原理

主要涉及图形界面、事件处理、游戏逻辑几部分。主要运用到初始化和退出(pygame.init、pygame.quit)、坐标系(pygame.Rect)、创建游戏窗口(pygame.display.set_mode)、绘制图像(pygame.image.load())、调用(build)、更新(update)、设置时钟对象(pygame.time.Clock())、监听事件(pygame.event.get())、精灵和精灵组等功能。综合运用了pygame的各个模块、面向对象的编程等知识。
那么,我们就要运用上述原理来搭建程序的框架。针对游戏初始化我们有三个功能要实现:1.设置游戏窗口2.创建游戏时钟3.创建精灵,精灵组;针对游戏循环我们有五个功能要实现:1.设置刷新频率2.事件监听3.碰撞检测4.更新绘制精灵组5.更新屏幕显示。
①背景图像的滑动
在游戏中我们让飞机在移动的时候能够实现背景图不断变换,就运用精灵组的功能,先在精灵组中新建背景精灵,再在主文件中调用,实现背景长图重复划过屏幕,实现移动的效果。一下分别为在精灵组和主代码中的操作:

class Background(GameSprite):
    """游戏背景精灵"""

    def update(self):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:
            self.rect.y = -self.rect.height
 def __create_sprites(self):
        background1 = plane_sprites.Background("./飞机大战/images/background.png")
        background2 = plane_sprites.Background("./飞机大战/images/background.png")
        background2.rect.y = -background2.rect.height
        self.back_group = pygame.sprite.Group(background1, background2)
     

最后再更新绘制精灵组


    def __update_sprites(self):

        self.back_group.update()
        self.back_group.draw(self.screen)

②敌机的移动和判定。在游戏中设置定时器,每隔一秒出现一架敌机。然后再在精灵组中创建敌机类,再在主代码中调用。然后再运用random板块,随机敌机出现的位置。


    def __init__(self):
        super().__init__('./飞机大战/images/enemy1.png')
        self.speed = random.randint(2, 4)
        self.rect.bottom = 0

        max_x = SCREEN_RECT.width - self.rect.width
        self.rect.x = random.randint(0, max_x)

③销毁敌机
当敌机移出屏幕后一定要对敌机进行销毁,使用精灵类自带的kill()功能,判断飞出后直接使用kill()功能进行销毁。
④玩家飞机
首先我们先在主文件里创建一个英雄飞机的类,并设置它的位置和速度,由于飞机默认静止,所以设置它的速度为0。采用pygame自带的使用键盘提供的方法获取键盘按键,获取到按键元组,然后用元组索引进行判断是否满足左右键,然后进行相应的移动操作。然后在精灵组里创建英雄飞机的精灵和精灵组,这里需要单独把英雄设置成属性,为后面碰撞检测做准备,以及到时候直接调用发射子弹的方法,最后更新和绘制英雄飞机。
⑤子弹
让子弹每0.5秒发射一次,用定时器来实现这个功能。然后和创建敌机的方法一样,创建一个子弹类,来对子弹进行创建更新和绘制。之后再和敌机一样进行更新绘制到屏幕上,位置可以设置到英雄战机的头部偏上一点。
然后再用pygame提供的pygame.sprites.groupcollide()方法,设定敌机和子弹发生碰撞。

  
    def __check_collide(self):

        pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)


⑥敌机碰撞玩家飞机
使用pygame.sprites.groupcollide()类型的pygame.sprite.spritecollide()方法,传入一个精灵和精灵组,返回一个敌机列表,然后判断是否销毁,判断返回列表里是否有值,如果有的话,表示英雄飞机和敌机发生碰撞,用kill()销毁英雄战机。

    
    def __check_collide(self):
        pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)
        enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
        if len(enemies) > 0:
            self.hero.kill()
            PlaneGame.__game_over()


下面是完整代码:
主代码:


import pygame
from plane_sprites import *


class PlaneGame(object):
    """飞机大战主游戏"""

    def __init__(self):
        print("游戏初始化")
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        self.clock = pygame.time.Clock()
        self.__creat_sprites()
        pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)
        pygame.time.set_timer(HERO_FIRE_EVENT, 500)

    def __creat_sprites(self):
        bg1 = Background()
        bg2 = Background(True)
        self.back_group = pygame.sprite.Group(bg1, bg2)
        self.enemy_group = pygame.sprite.Group()
        self.hero = Hero()
        self.hero_group = pygame.sprite.Group(self.hero)
        self.enemy_hit_group = pygame.sprite.Group();

    def start_game(self):
        print("游戏开始.....")
        while True:
        
            self.clock.tick(FRAME_PER_SEC)

            self.__event_handler()

            self.__check_collide()

            self.__update_sprites()

            pygame.display.update()

    def __event_handler(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                PlaneGame.__game_over()
            elif event.type == CREATE_ENEMY_EVENT:
                print("敌机出场")
          
                enemy = Enemy()
              
                self.enemy_group.add(enemy)
            elif event.type == HERO_FIRE_EVENT:
                self.hero.fire()

        keys_pressed = pygame.key.get_pressed()

        if keys_pressed[pygame.K_RIGHT]:
            self.hero.speed = 3
        elif keys_pressed[pygame.K_LEFT]:
            self.hero.speed = -3
        else:
            self.hero.speed = 0

    def __check_collide(self):

        enemy_hit = pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)


        enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
        if len(enemies) > 0:

            self.hero.kill()
      
            PlaneGame.__game_over()

    def __update_sprites(self):
        self.back_group.update()
        self.back_group.draw(self.screen)
        self.enemy_group.update()
        self.enemy_group.draw(self.screen)
        self.hero_group.update()
        self.hero_group.draw(self.screen)
        self.hero.bullets.update()
        self.hero.bullets.draw(self.screen)

    @staticmethod
    def __game_over():
        print("游戏结束")
        pygame.quit()
        exit()


if __name__ == '__main__':

    game = PlaneGame()

    game.start_game()

精灵组代码:


import random
import pygame
SCREEN_RECT=pygame.Rect(0,0,480,700)
FRAME_PER_SEC=60
explode_index=0
CREATE_ENEMY_EVENT=pygame.USEREVENT
HERO_FIRE_EVENT=pygame.USEREVENT+1
class GameSprite(pygame.sprite.Sprite):
    """飞机大战游戏精灵"""
    def __init__(self,image_name,speed=1):

        super().__init__()
        self.image=pygame.image.load(image_name)
        self.rect=self.image.get_rect()
        self.speed=speed
    def update(self):
        self.rect.y+=self.speed

class Background(GameSprite):
    """游戏背景精灵"""
    def __init__(self,is_alt=False):
        super().__init__("./images/background.png")
        if is_alt:
            self.rect.y = -self.rect.height
    def update(self):
        super().update()
        if self.rect.y>=SCREEN_RECT.height:
           self.rect.y= -self.rect.height

class Enemy(GameSprite):
    """敌机精灵"""

    def __init__(self):
        super().__init__("./images/enemy1.png")
        self.speed=random.randint(1,3)
        self.rect.bottom=0
        max_x=SCREEN_RECT.width-self.rect.width
        self.rect.x=random.randint(0,max_x)
        self.explode_index=0
    def update(self):
        super().update()
        if self.rect.y>=SCREEN_RECT.height:
            self.kill()
        #if self.explode_index==5:
            #return
        if self.explode_index!=0:
            new_rect=self.rect
            super.__init__("./images/enemy1_down1.png")
            self.explode_index=self.explode_index+1
            self.rect=new_rect


    def __del__(self):
         pass
class Hero(GameSprite):
    """英雄精灵"""
    def __init__(self):
        super().__init__("./images/me1.png",0)
        self.rect.centerx=SCREEN_RECT.centerx
        self.rect.bottom=SCREEN_RECT.bottom-120
        self.bullets=pygame.sprite.Group()
    def update(self):
        self.rect.x+=self.speed
        if self.rect.x<0:
            self.rect.x=0
        elif self.rect.right>SCREEN_RECT.right:
            self.rect.right=SCREEN_RECT.right
    def fire(self):
        print("发射子弹...")
        for i in (0,1,2):
            bullet=Bullet()
            bullet.rect.bottom=self.rect.y-i*20
            bullet.rect.centerx=self.rect.centerx
            self.bullets.add(bullet)
    def explode(self,screen):
        new_rect=self.rect
        for i in (1,2,3,4):
            super.__init__("./images/me_destroy_2.png")
            self.rect.centerx=new_rect.centerx
            self.rect.centery=new_rect.centery
            screen.blit(self.image,(self.rect.x,self.rect.y))
            pygame.display.update()
class Bullet(GameSprite):
    """子弹精灵"""
    def __init__(self):
        super().__init__("./images/bullet1.png",-2)
    def update(self):
        super().update()
        if self.rect.bottom<0:
            self.kill()
    def __del__(self):
        print("子弹被销毁")

程序运行视频:

 

  1. 实验过程中遇到的问题和感想体会

-问题1:无法找到图片素材文件

-问题1解决方案:图片文件夹路径错误,不小心在文件夹中又多嵌套了一个文件夹,修改过后成功运行。

-问题2:运行结束后,报错“libpng warning: iCCP: known incorrect sRGB profile”(libpng 警告:iCCP:已知不正确的 sRGB 配置文件)

-问题2解决方案:原因是因为libpng 1.6太敏感,1.6及以上版本增强了ICC profiles检查,所以发出警告。把png格式的文件在Photoshop中重新保存一遍即可。
感想体会:在小游戏的编写中,飞机大战属于比较简单的程序,但是在这个全新的领域的探索中,我依然面临诸多问题和挑战。并且将人的思维转化为程序思维,并整合成整个游戏的逻辑框架,也是有难度的。但是,我因此对pygame板块产生了浓厚的兴趣,希望即使在结课后也对其继续探索,未来能不仅参考别人的代码,也开发出自己想玩的小游戏代码。

4.课程感想体会
在这一学期的python课中,主要学习了以下内容:
环境搭建:如何安装Python和配置开发环境。基本语法:变量、注释、输入输出等。数值类型:整数、浮点数、复数。序列类型:列表(list)、元组(tuple)、集合(set)和字典(dictionary)的使用。控制结构:条件语句:if、elif、else;循环语句:while循环和for循环;循环控制:break。函数的定义和调用:如何定义函数以及如何调用函数。面向对象编程:类和对象:类的定义和对象的创建;继承和封装。文件及目录操作。socket编程。网络爬虫开发等。在课上我们学习到了丰富的技术知识,老师的课件和ppt也十分清晰易懂。同时,也做了许多实践活动:比如猜数字、猜拳游戏、制作计算器、socket编程实践等等。在丰富的实践与理论学习中,我对这些知识也有了基本的掌握,对python的理解更进一步,也有助于我更智慧高效地运用编程知识来处理一些数据,有助于未来实现更高效的智慧办公,掌握一门专业技能,不落后于时代潮流。
同时,除了专业技能上的收获,python也极大地培养了我的逻辑思维和思考问题的方式,使我思考问题能够从更多方面展开,也拓宽了我解决问题的思路。在解决一些繁杂、人力耗费巨大的任务时,可以运用编程知识帮忙解决问题。同时,也培养了我的探索和实验的能力:在实验中,我遇到问题不再退缩放弃,而是充分运用一切学习资源,到社区论坛求解,将问题各个疏通,逐一击破,最后化解难题,克服了许多畏难情绪。即使一行代码出错,也会引发整个程序的错误,因此,编写python也使我更加认真仔细,减少出错。
最后,我也紧跟老师的教诲,不但在python这一门学科上,在其它学科上,也不断探索,不断求知,不使自己落后于时代的浪潮。
参考资料
-https://blog.csdn.net/q610098308/article/details/135407153?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-135407153-blog-121900456.235^v43^pc_blog_bottom_relevance_base8&spm=1001.2101.3001.4242.1&utm_relevant_index=3

...全文
103 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
下载代码方式:https://pan.quark.cn/s/a4b39357ea24 全国计算机等级考试二级教程《Python语言程序设计》(2018年版)被视为针对Python入门者和备考人员的核心学习材料。该资料汇总了教材内的所有编程练习答案,这些答案在Python 3.5.3环境中经过实际执行测试,从而保障了代码的准确性和应用价值。备考人员借助这些答案,能够评估自身的学习进度,并深入理解和熟练掌握Python编程的基础原理与方法。 1. Python基础理论:Python作为一门高级编程语言,因其简明扼要的语法结构和卓越的功能表现而备受推崇。基础内容涵盖了变量、数据种类(例如整型、浮点型、字符串、布尔型、列表、元组、字典、集合)、逻辑控制(比如条件判断if-else,循环控制for、while)、函数的声明及使用、模块的引入等。 2. Python高级应用:Python的进阶内容涉及异常管理(try-except-finally结构),类与实例(面向对象编程的基础,包含类的构造、对象的生成、属性与方法的运用、继承机制、多态表现),装饰器(用于调整函数或类的功能特性),上下文管理器(借助with语句实现资源管理)等。 3. 数据文件处理:Python配备了全面的文件操作功能,涉及文件的开启、数据读写、关闭操作,以及多种操作模式(例如r模式用于读取,w模式用于写入,a模式用于追加内容等)。此外,还包括文本文件与二进制文件的转换处理,以及文件的位置调整、复制和删除等操作。 4. 标准库的运用:Python的标准库资源极为丰富,比如os模块提供操作系统接口,sys模块用于获取系统参数,random模块可用于生成随机数值,datetime模块负责处...

93

社区成员

发帖
与我相关
我的任务
社区描述
Python程序设计作业
软件构建 高校 北京·丰台区
社区管理员
  • blackwall0321
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧