编程语言
首页 > 编程语言> > 20212108《Python程序设计》实验四 Python综合实践实验报告

20212108《Python程序设计》实验四 Python综合实践实验报告

作者:互联网

20212108《Python程序设计》实验四 Python综合实践实验报告 

课程:        《Python程序设计》
班级:        2121
姓名:        王季延
学号:        20212108
实验教师:  王志强
实验日期:  2022年5月21日
必修/选修: 公选课

 

一、实验内容

用Python做一个小游戏i wanna flippy bird

1.想法介绍:

       大一上学期从课代表那里了解到可以使用pygame模块制作游戏,本学期在舍友那里接触到了i wanna类的游戏(被坑哭了),最后是在云班课中老师发的资料里找到了用pygame制作经典flippy bird游戏的视频,所以就有了用python做一个简单的两者结合的小游戏。

2.主要内容:

      玩家控制小鸟(画成了一个脑袋)前进和跳跃(标准的flippy bird游戏中小鸟是自动前进,玩家只需要操控小鸟的跳跃即可,但是由于此游戏含有坑,前进需要玩家手动操控),通过管道获得尽可能多的分数,但是在这个经典玩法中掺杂了挡路的怪物和坑的元素。(游戏刚开始时玩家就是处于下坠状态,只是单纯为了让玩家观看死亡界面的游戏规则,接下来每次重新开始游戏后不会自动下坠,只有按下跳跃键后才会正常下落)

           

 二、实验过程及结果

 

1.图片素材准备

      在电脑附件“画图”中直接编辑,背景使用截图

 

 

 2.pygame包下载和安装

 pip install pygame -i https://pypi.mirrors.ustc.edu.cn/simple安装pygame

pip show pygame查看pygame是否安装完成

重启后电脑成功检测到pygame

3.游戏架构分析

 游戏即让图片在一个窗口内运动,在执行对应操作时做出对应的动作。

关于类的创建,使用class函数实现,参考资料

①https://blog.csdn.net/weixin_34177886/article/details/111963062

②本学期python课堂对class知识的讲授

关于窗口和检测按键的使用,使用pygame相关代码和自定义变量实现,参考资料

 

(3)实验过程

a.代码

复制代码
import sys
import pygame
import random
import math

if __name__ == '__main__':
    pygame.init()
    
    #
    def text_amazing(screen):
        text5 = "注意!按键反转"
        font5 = pygame.font.SysFont("simsun",32)
        font_surface5 = font5.render(text5,True,(0,0,0))
        font_rect5 = font_surface5.get_rect()
        font_rect5.center = (200,100)
        screen.blit(font_surface5,font_rect5)
    def die(screen,score):
        text = "你无了!"
        font = pygame.font.SysFont("simsun",32)
        font_surface = font.render(text,True,(255,0,0))
        font_rect = font_surface.get_rect()
        font_rect.center = (200,100)
        screen.blit(font_surface,font_rect)


        text1 = "你的得分是" + str(score)
        font1 = pygame.font.SysFont("simsun",16)
        font_surface1 = font1.render(text1,True,(0,0,0))
        font_rect1 = font_surface1.get_rect()
        font_rect1.center = (180,150)
        screen.blit(font_surface1,font_rect1)

        text2 = "规则:右键前进,空格跳跃"
        font2 = pygame.font.SysFont("simsun",16)
        font_surface2 = font2.render(text2,True,(255,0,0))
        font_rect2 = font_surface2.get_rect()
        font_rect2.center = (180,250)
        screen.blit(font_surface2,font_rect2)

        text3 = "注意有坑,两个按键可能交换"
        font3 = pygame.font.SysFont("simsun",16)
        font_surface3 = font3.render(text3,True,(0,0,0))
        font_rect3 = font_surface3.get_rect()
        font_rect3.center = (180,300)
        screen.blit(font_surface3,font_rect3)

    class bird(object):
        def __init__(self):
            self.sprite = [pygame.image.load("player0.png").convert_alpha(),#
                            pygame.image.load("player1.png").convert_alpha()]#死
            self.sprite_index = 0
            self.x = 120
            self.y = 350
            self.speed = 0
            self.jump = False
            self.gravity = 0.2
            self.gravity_distance = 0.1
            self.whether_dead = False

        def move(self):
            self.speed -= self.gravity
            self.y -= self.speed
            if not self.jump:
                self.gravity += self.gravity_distance
                self.gravity_distance = self.gravity_distance/2
    #######################
    class pipeline(object):
        def __init__(self):
            self.x = 400
            self.y_up = random.randint(-530,-100)
            self.y_distance = random.randint(140,300)
            self.sprite_up = pygame.image.load("up.png")
            self.sprite_down = pygame.image.load("down.png")
            self.move_state = 0
            #
            self.amazing = 0
            self.amazing3 = 4
            self.amazing1_state = 1
            self.score_state = 1
            self.x_scale = 94
            self.y_down = self.y_up + self.y_distance
            self.move_total = 0

        def pipeline_update(self):
            if self.move_state == 1 and self.move_total == 1:
                self.x -= 2
            if self.x <= -100:
                self.x = 400
                self.y_up = random.randint(-530,-100)
                self.y_distance = random.randint(140,300)
                self.y_down = self.y_up + self.y_distance
                self.yscale = random.randint(60,100)
                self.sprite_up = pygame.transform.scale(self.sprite_up,(self.x_scale,499))
                self.sprite_down = pygame.transform.scale(self.sprite_down,(self.x_scale,499))
                self.amazing = random.randint(0,3)
                self.score_state = 1
                self.amazing1_state = 1
                self.amazing3 = random.randint(0,3)
    ###################
    class demon(object):
        def __init__(self):
            self.sprite = [pygame.image.load("demon1.png"),
                            pygame.image.load("demon2.png")]
            self.sprite_index = 0
            self.sprite_state = 1
            self.x = 200
            self.y = random.randint(100,470)
            self.move_state = 0
            self.move_time = 100
            self.move_time2 = 100
            self.move_time_state = 0
            #
            self.amazing = 0
            self.attack = 0
            self.speed = 2
            self.time = self.move_time
            self.speed2 = 2
            self.time2 = self.move_time2
            self.move_time_state2 = 0
            self.amazing2_y = self.y + random.randint(-200,200)
            self.amazing2_y_state = 0
            self.step = 0

        def move(self):
            self.sprite_state -= 1
            if self.amazing >= 1:
                if self.time > 0 and self.amazing2_y_state == 0:
                    if self.move_time_state == 0:
                        self.y += self.speed
                    else:
                        self.y -= self.speed
                    self.time -= 1
                if self.time <= 0 and self.amazing2_y_state == 0:
                    self.time = self.move_time
                    if self.move_time_state == 0:
                        self.move_time_state = 1
                    elif self.move_time_state == 1:
                        self.move_time_state = 0
                if self.amazing == 2:
                    if self.amazing2_y_state == 0 and abs(self.y - self.amazing2_y) <= random.randint(10,15):
                        self.amazing2_y_state = 1
                    if self.amazing2_y_state == 1:
                        if self.time2 > 0 and self.amazing2_y_state == 1:
                            if self.move_time_state2 == 1:
                                self.x += self.speed2
                            else:
                                self.x -= self.speed2
                            self.time2 -= 1
                        if self.time2 <= 0 and self.amazing2_y_state == 1:
                            self.time2 = self.move_time2
                            if self.move_time_state2 == 0:
                                self.move_time_state2 = 1
                            elif self.move_time_state2 == 1:
                                self.move_time_state2 = 0
                            self.step += 1
                    if self.step == 2:
                        self.amazing2_y_state = 0
                        self.amazing2_y = self.y + random.randint(-120,200)
                        self.step = 0

            if self.sprite_index == 0 and self.sprite_state == 0:
                self.sprite_index = 1
                self.sprite_state = 30
            if self.sprite_index == 1 and self.sprite_state == 0:
                self.sprite_index = 0
                self.sprite_state = 30
            if self.move_state == 1:
                self.x -= 2
            if self.x <= -100:
                self.x = 400
                self.y = random.randint(200,450)
                self.attack = random.randint(0,3)
                self.move_time = random.randint(40,60)
                self.time = self.move_time
                self.amazing = random.randint(0,2)
                self.move_time_state = random.randint(0,1)
                self.speed = random.randint(2,5)
                self.amazing2_y = self.y + random.randint(-120,200)
                self.amazing2_y_state = 0
                #
                self.move_time2 = random.randint(20,30)
                self.move_time_state2 = random.randint(0,1)
                self.speed = random.randint(2,5)
                self.time2 = self.move_time2
                self.step = 0
    #

    size = width,height = 400,650
    screen = pygame.display.set_mode(size)
    clock = pygame.time.Clock()
    score = 0
    cooldown = 0

    player = bird()
    pipe = pipeline()
    demon = demon()
    while True:
        clock.tick(100)

        pygame.display.set_caption("你的得分:"+str(score))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            if not player.whether_dead:
                if (pipe.amazing == pipe.amazing3 or pipe.amazing == 3) and player.x >= 20:
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_RIGHT:
                            player.jump = True
                            player.gravity = 0.2
                            player.speed = 5
                            player.gravity_distance = 0.02
                        if event.key == pygame.K_SPACE:
                            pipe.move_state = 1
                            demon.move_state = 1
                    elif event.type == pygame.KEYUP:
                        if event.key == pygame.K_RIGHT:
                            player.jump = False
                        if event.key == pygame.K_SPACE:
                            pipe.move_state = 0
                            demon.move_state = 0
                
                else:
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_SPACE:
                            pipe.move_total = 1
                            player.jump = True
                            player.gravity = 0.2
                            player.speed = 5
                            player.gravity_distance = 0.02
                        if event.key == pygame.K_RIGHT:
                            pipe.move_state = 1
                            demon.move_state = 1
                    elif event.type == pygame.KEYUP:
                        if event.key == pygame.K_SPACE:
                            player.jump = False
                        if event.key == pygame.K_RIGHT:
                            pipe.move_state = 0
                            demon.move_state = 0
            else:
                player.sprite_index = 1
        
        if player.x > pipe.x + pipe.x_scale and pipe.score_state == 1:
            score += 1
            pipe.score_state = 0
        background = pygame.image.load("background.png")
        screen.blit(background,(0,0))

        if not player.whether_dead:
            pipe.pipeline_update()
            #第一个坑
            if pipe.amazing == 1 and player.x >= pipe.x - random.randint(58,62):
                if pipe.y_up < pipe.y_down and pipe.amazing1_state == 1:
                    pipe.y_up += pipe.y_distance/10
                if pipe.y_up >= pipe.y_down:
                    pipe.amazing1_state = 0
                if pipe.amazing1_state == 0 and pipe.y_up > pipe.y_down - pipe.y_distance:
                    pipe.y_up -=  pipe.y_distance/10
            #第二个坑
            if pipe.amazing == 2 and pipe.amazing1_state == 1 and player.x >= pipe.x - random.randint(58,62):
                pipe.y_up = random.randint(-530,-100)
                pipe.y_distance = random.randint(140,300)
                pipe.y_down = pipe.y_up + pipe.y_distance
                pipe.amazing1_state = 0
        
        screen.blit(pipe.sprite_up,(pipe.x,pipe.y_up))
        if demon.attack != 0:
            screen.blit(demon.sprite[demon.sprite_index],(demon.x,demon.y))
        screen.blit(pipe.sprite_down,(pipe.x,pipe.y_down + 499))
        #反转提示
        if (pipe.amazing == pipe.amazing3 or pipe.amazing == 3) and player.x >= 20 and score >= 1:
            text_amazing(screen)
        
        if player.whether_dead:
            player.sprite_index = 1
        else:
            player.sprite_index = 0
        screen.blit(player.sprite[player.sprite_index],(player.x,player.y))
        if cooldown != 1:
            player.move()
        if not player.whether_dead:
            demon.move()
        #死亡
        if player.y <= 0 or player.y >= 614:
            player.whether_dead = True
        if player.x > pipe.x - 48 and player.x < pipe.x + pipe.x_scale:
            if player.y < pipe.y_up + 499 or player.y > pipe.y_up + pipe.y_distance + 463:
                player.whether_dead = True
        if player.x >= demon.x - 48 and player.x <demon.x + 64 and demon.attack != 0:
            if player.y >= demon.y - 36 and player.y <= demon.y + 64:
                player.whether_dead = True
        if cooldown == 0 and player.y >= 614:
            cooldown = 1  
        if player.whether_dead:
            die(screen,score)
            pipe.amazing = 4 
            mouse_x,mouse_y = pygame.mouse.get_pos()
            #重生
            if mouse_x <= 296 and mouse_x >= 104 and mouse_y >= 184 and mouse_y <= 216:
                color = (255,255,255)
                for event in pygame.event.get():
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        score = 0
                        cooldown = 0
                        #
                        player.sprite_index = 0
                        player.x = 120
                        player.y = 350
                        player.speed = 0
                        player.jump = False
                        player.gravity = 0
                        player.gravity_distance = 0
                        player.whether_dead = False
                        #
                        pipe.x = 400
                        pipe.y_up = random.randint(-530,-100)
                        pipe.y_distance = random.randint(140,300)
                        pipe.move_state = 0
                        pipe.move_total = 0
                        #
                        pipe.amazing = 0
                        pipe.amazing3 = 4
                        pipe.amazing1_state = 1
                        pipe.score_state = 1
                        pipe.x_scale = 94
                        pipe.y_down = pipe.y_up + pipe.y_distance
                        #
                        demon.sprite_index = 0
                        demon.sprite_state = 1
                        demon.x = 200
                        demon.y = random.randint(100,470)
                        demon.move_state = 0
                        demon.move_time = 100
                        demon.move_time2 = 100
                        demon.move_time_state = 0
                        #
                        demon.amazing = 0
                        demon.attack = 0
                        demon.speed = 2
                        demon.time = demon.move_time
                        demon.speed2 = 2
                        demon.time2 = demon.move_time2
                        demon.move_time_state2 = 0
                        demon.amazing2_y = demon.y + random.randint(-200,200)
                        demon.amazing2_y_state = 0
                        demon.step = 0
            else:
                color = None
            text4 = "点我重新开始"
            font4 = pygame.font.SysFont("simsun",32)
            font_surface4 = font4.render(text4,True,(255,0,0),color)
            font_rect4 = font_surface4.get_rect()
            font_rect4.center = (200,200)
            screen.blit(font_surface4,font_rect4)
pygame.display.update()#
pygame.display.flip()效果一样

 

b.解释

     sys用于对系统进行操作,在游戏制作中主要用于结束游戏;math库提供许多数学函数,在游戏中主要用于变量运算和判断;random库用于随机数的使用,在用python做游戏时可以避免变量的;pygame是用python做游戏的主要库,提供绘制窗口、显示图片、检测按键等功能的函数。

 

     pygame.init()

     功能:用于对pygame库进行初始化。

 

     pygame.display.set_mode(size)

     功能:用于创建游戏的主屏幕,尺寸为size参数,为一个二元组(width,height),分别为房间的宽度和高度。

 

     class bird(object)(对其他类的定义同理):

     功能:定义鸟类(玩家类),__init__(self)函数用于定义该类的create变量(初始创建实例时获得的变量),__move__(self)函数用于操控实例的运动。

     其中许多不常见的变量(比如self.amazing)用于制作游戏坑的元素,比如self.amazing在每次管道从左侧消失后会刷新一次,用于决定在跳下一个管道时是

     否会有坑以及坑的类型,self.move_time和self.move_state等等在class demon()中的变量用于定义怪物的运动状态。

 

     pygame.

 

     def die(screen,score):

     功能:此函数用于当玩家失败后在屏幕screen上显示的屏幕字样,同时显示玩家的得分score。

 

     for event in pygame.event.get():

     功能:用于历遍pygame中的所有事件

     在此循环下用if pygame.type == ***来判断事件的类型

     用if pygame.key == pygame.K_*来判断具体按键

     以此在if语句下执行对应的效果,从而实现游戏的效果。

 

     pygame.image.load(image)

     功能:用于导入图片

     image为图片所在位置的地址(这里的地址是相对主文件所在的位置,如果和主文件在同一文件夹下,则可以直接写成图片的名字,支持png和jpg)。

     注:image也可以是一个列表,里面列举多个图片的路径,在需要取用相应的图片的时候用列表的标号取用即可,从而实现简单的图片变换过程。

 

     screen.blit(image,location)

     功能:用于在screen上将image在屏幕的location位置绘制出来

     其中location是一个二元组(x,y),参数分别为x和y坐标。

    

     pygame.display.update()

     功能:用于更新屏幕画面,没有此条语句的话屏幕会保留上一次绘制的图片的残留象,让整个屏幕一片混乱。

 

     clock = pygame.time.Clock():

     功能:用于定义一个时钟,结合clock.tick(time)可以控制游戏屏幕更新的速度,time参数是指每秒屏幕更新的次数

     该参数越大,游戏运行的流畅度越高,同时,对电脑配置的要求也越高。(正常参数设置为60就差不多了)

 

     if __name__ == '__main__':

     功能:主函数:程序入口

     如果主文件被当成模块导入时,以下的代码将不会被运行

 

c.本地运行

死亡界面及重新开始游戏正常

跳跃、怪物、坑和计算得分正常

 

 

 

 

d.在ECS服务器运行

 

 

 

       登陆PUTTY

 

 

 

 

 

       上传文件

 

 

 

 

 

       在服务器上下载所需要的包

 运行成功

 

 

 

四、遇到的问题和解决办法

1.下载安装pygame后无法使用

       询问课代表之后得知需要重启才可以使用

2.运行时报错找不到图片

       没把图片和主文件放在同一个文件夹下,参数也没有写成地址形式

3.无法在ESC云服务器上用python3来运行程序,且无法找到pygame包(最大的问题)

      版本不匹配,pygame是用python3.9编写,而服务器上的python版本是3.7

      试过pip3 install pygame但是出现报错,试过把电脑上的pygame文件直接拖进服务器文件中,仍然显示报错

 

五、实验感悟

       首先,我想在此表达对王老师和几位课代表的由衷感谢。本学期的python课堂幽默有趣,教的知识细致全面,尤其是每节课老师都会亲自为我们做实践的演示,我也从这一学期学到了很多东西。

  我接触编程是从初中教的Visual Basic开始的,但是当时老师只是让我们对着书抄代码,只是单纯觉得运行出来的跳青蛙游戏很好玩,但是并没有理解代码。在高中三年期间,同学给我推荐了一款名叫MinecraftVSZombies2的游戏,制作新颖,游戏体验感强,最吸引我的是作者——是一个和我同一级的高中生,从那会儿我开始接触编程领域(学校里的Python课只教了一节就被其他课占光了)。我了解到他使用的游戏制作的平台是GamemakerStudio2(现在正在使用Unity平台制作重制版),于是我学着用GamemakerStudio8.1平台也做了一个弹幕射击游戏(做的比较low),然后对python和C++等编程语言开始有更多的学习(但是由于高考和疫情等原因,总的学习时间还是不长)。进入大学之后,大一上学期也在自学python,学艺不精,但是在这学期的python公选课之后,感觉此方面有了新的提升(老师的实验作业和各种python实践让我从理论阶段开始跨入实践阶段)。

  以上就是我和编程语言相遇、相识、相知的过程。这学期的python学习除了巩固Python中基本函数、模块、列表元组等知识之外,还让我了解了一直觉得很遥远的socket和游戏领域,虽然没能把老师教的全部知识都掌握,但是彻底打开了我的视野。虽然python公选课已经圆满结课了,但是我对python的热情不会消失,最后就以一句我第一次接触的python代码结束吧!

  print("Hello Python!Thank you,Mr Wang!")

六、小建议

     如果下学期还开设这门课的话,希望能详细地讲一讲socket和华为云服务器上的知识,然后也可以多争取一些和这学期写CSDN博客然后评小奖励的活动。老师上课的幽默感也希望能继续保持下去

 

 

 

参考资料:

[1]: https://www.cnblogs.com/yuhaowang/p/10485185.html

[2]:https://www.pygame.org/download.shtml

[3]:https://pan.baidu.com/s/1wMDA-8zqd8eiu6iGWGPqFQ?_at_=1653577595955

[4]:https://www.linuxidc.com/Linux/2017-01/139241.htm

[5]:https://www.freesion.com/article/73691086600/

[6]:https://www.daehub.com/archives/9949.html#:~:text=%E5%85%B6%E4%B8%AD%20PuTTY%20%E6%98%AF%20SSH%20%E5%AE%A2%E6%88%B7%E7%AB%AF%EF%BC%8C%E8%80%8C,Xming%20%E5%88%99%E6%98%AF%20Windows%20%E5%B9%B3%E5%8F%B0%E7%9A%84%20X%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E3%80%82

[7]:https://www.jianshu.com/p/23ba123ee874

 

标签:20212108,font,Python,self,pipe,player,state,pygame,实验报告
来源: https://www.cnblogs.com/wangjiyan/p/16310962.html