20192419 2019-2020-2 《Python程序设计》实验4报告
课程:《Python程序设计》
班级:1924
姓名: 万腾阳
学号:20192419
实验教师:王志强
实验日期:2020年6月3日
必修/选修: 公选课
1.实验内容
Python综合应用:运用pygame尝试编写flappy bird代码
2. 实验过程及结果
一开始,我打算照着课本将飞机大战的代码稍作更改,差不多就相当于flappy bird代码。但是经过一段时间编写后,我发现课本上的代码一环扣一环,稍作更改一处,就会导致出现错误,甚至有时候不报错,但是整个程序连图片的不产生,十分令人心烦。后面,我上网查找了视频,参照视频我编出了flappy bird,视频中也存在一些小错误,这在稍后再讲。
代码:
import pygame
import sys
import time
class Bird(object):
#定义小鸟
def __init__(self):
#定义初始化方法
self.birdRect = pygame.Rect(65,50,50,50)
self.birdStatus = [pygame.image.load(r'picture/1.png'),
pygame.image.load(r'picture/2.png'),
pygame.image.load(r'picture/dead.png')]
self.status = 0
self.birdx = 120
self.birdy = 350
self.jump = False
self.jumpSpeed = 10
self.gravity = 5
self.dead = False
def birdUpdate(self):
#定义移动方法
if self.jump:
self.jumpSpeed -= 1
self.birdy -= self.jumpSpeed
else:
self.gravity += 0.2
self.birdy += self.gravity
self.birdRect[1] = self.birdy
class Pipeline(object):
#定义管道类
def __init__(self):
self.wallx = 400
self.pineUp = pygame.image.load(r'picture/top.png')
self.pineDown = pygame.image.load(r'picture/bottom.png')
def updatePipeline(self):
#定义移动方法
self.wallx -= 5
if self.wallx < -80 :
global score
score +=1
self.wallx = 400
def createMap():
screen.blit(background,(0,0))
#显示管道
screen.blit(Pipeline.pineUp,(Pipeline.wallx,-300))
screen.blit(Pipeline.pineDown,(Pipeline.wallx, 500))
Pipeline.updatePipeline()
#显示小鸟
if Bird.dead:
Bird.status = 2
elif Bird.jump:
Bird.status = 1
screen.blit(Bird.birdStatus[Bird.status] , (Bird.birdx,Bird.birdy))
Bird.birdUpdate() #更新小鸟状态
font.render('Score'+str(score),-1,(255,255,255))
screen.blit(font.render('Score'+str(score),-1,(255,255,255)),(100,50))
pygame.display.update()
def checkDead():
upRect = pygame.Rect(Pipeline.wallx,-300,Pipeline.pineUp.get_width(),Pipeline.pineUp.get_height())
downRect = pygame.Rect(Pipeline.wallx, 500, Pipeline.pineDown.get_width(), Pipeline.pineDown.get_height())
#检测矩形碰撞
if upRect.colliderect(Bird.birdRect) or downRect.colliderect(Bird.birdRect):
Bird.dead = True
#边界检测
else:
if 0 < Bird.birdRect[1] < height:
Bird.dead = False
return True
else:
return False
def getResult():
#获取总分
final_text1 = "Game Over"
final_text2 = "Your Score:" + str(score)
ft1_font = pygame.font.SysFont("Arial",70)
ft1_surf = font.render(final_text1,1,(242,3,36))
ft2_font = pygame.font.SysFont("Arial", 50)
ft2_surf = font.render(final_text2, 1, (253, 177, 6))
screenwidth = int (screen.get_width() / 2)
surf1 = int(ft1_surf.get_width()/2)
surf2 = int(ft2_surf.get_width() / 2)
screen.blit(ft1_surf,[screenwidth- surf1,100])
screen.blit(ft2_surf, [screenwidth- surf2, 200])
pygame.display.update()
if __name__ == '__main__':
pygame.init()
pygame.font.init()#初始化字体类
font = pygame.font.SysFont(None,50)
size = width,height = 400,650
screen = pygame.display.set_mode(size) #设置窗口
clock = pygame.time.Clock() #设置时钟
color = (255,255,255)
Bird = Bird()#实例小鸟类
Pipeline = Pipeline()
score = 0
while True:
clock.tick(60)#每秒执行60次
#轮询事件监测
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN or pygame.MOUSEBUTTONDOWN and not Bird.dead:
Bird.jump = True
Bird.gravity = 5
Bird.jumpSpeed = 10
# screen.fill(color)
background = pygame.image.load(r'picture/background.png')
if checkDead():
pass
else:
createMap()
getResult()
time.sleep(2)
createMap() #生成地图
pygame.quit()```
以上是本次实验的代码,一开始需要通过代码显示窗口,并设置其背景及宽度和长度,然后循环绘制屏幕,更新屏幕。
实验的虽然能显示窗口和背景了,但还需要小鸟和管道在屏幕上显示,所以建立一个小鸟类和管道类是至关重要的,然后设置小鸟的上升和下降速度,当按任意键是小鸟升起,松开时小鸟下降。管道则是不断向左移动。
创建完小鸟和管道后,几乎代码就要完成了。此时还有一个重要的事情:小鸟碰撞到管道时和小鸟离开界面时,应该显示小鸟死亡,所以用colliderect检测碰撞,用判断小鸟所在处的y值就可以判断是否离开界面。这样,代码就完成了。
## 3. 实验过程中遇到的问题和解决过程
实验过程中主要遇到两个问题:
问题1:一开始,在检测碰撞时,我用if语句判断当小鸟接触到管道,小鸟则死亡。但是却没有注意到在判断完后我又立即进行判断小鸟是否离开边界,如果离开死亡值又恢复True。
![](https://img2020.cnblogs.com/blog/1813638/202006/1813638-20200603212633576-9455198.png)
所以,当小鸟碰撞到管道时是这样的:
![](https://img2020.cnblogs.com/blog/1813638/202006/1813638-20200603212753518-1544128177.png)
之后我变进行了调试,才发现这一问题所在。所以我进行了改正:
![](https://img2020.cnblogs.com/blog/1813638/202006/1813638-20200603212733475-1677442103.png)
![](https://img2020.cnblogs.com/blog/1813638/202006/1813638-20200603212745931-1921864150.png)
结果也运行正常。
问题2:视频中代码是这样子的:
![](https://img2020.cnblogs.com/blog/1813638/202006/1813638-20200603212803645-339099912.png)
然后我跟着视频编写后,运行反复出错。我也苦恼了很久。它显示的错误是screen.blit里应为整数,而代码是浮点数。后面说在未来Python很有可能删除这个错误(我也不是很懂这里)随后我就试着将其强制转换,果然成功了,代码:
![](https://img2020.cnblogs.com/blog/1813638/202006/1813638-20200603212809797-967244483.png)
可能之前版本可以使用浮点型吧,后面版本改了就不可以,对于这点也只是我的猜测,之后我会去寻找更准确的答案。
## 课堂总结
一开始我选这门课时我是觉得我上学期接触了一些python,自我认为上手很快,这门选修随便过。但是当我听到舍友说貌似这门课老师有点严,作业也多,我就不免担心起来。当真正上课时,可能作业确实有点多,一开始还要自己去看视频,但是跟王老师能学到挺多东西,而且老师讲课有趣。
通过这门课的学习,我不仅学习了关于python的程序设计,我学到的更多是自我学习,自我检测,没有人一开始就一蹴而就,编程更是如此。经过不断的实践和调试,最终程序完成的成就感可能正是他人无法想象的。
## 参考资料
视频:https://www.bilibili.com/video/BV1Vx411Z7w5/?p=6