ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-05-28 20:34:13  阅读:265  来源: 互联网

标签:20212108 font Python self pipe player state pygame 实验报告


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有