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