今日目标:
利用python编写一个笨鸟先飞的小程序。
主要思路:
1.从网络中下载需要的图片资源
2.设置背景图片
3.制作移动的管道
4.实现小鸟扑腾翅膀效果
5.判断小鸟是否触碰到管道或是离开画面
6.实现动画效果
操作详细:
从网络中下载需要的图片资源:
下载所需要的库
在联网的情况进行以下操作:
WIN+R–>CMD=>输入“pip install pygame”
设置背景图片
因为要建立一个游戏,这里要运用到pygame。
首先要制作一个屏幕:
import pygame # 调用pygame库
pygame.init() # pygame库初始化
map_width = 284 # 容器的宽
map_height = 512 # 容器的高
gameScreen = pygame.display.set_mode((map_width, map_height)) # 初始化一个屏幕
然后设置背景图片:
background = pygame.image.load("background.png") # 设置背景图片
制作移动的管道:
from random import randrange
pipes = [[180, 4]] # 定义一个队列(用于绘制管道)
pipe_body = pygame.image.load("pipe_body.png")
pipe_end = pygame.image.load("pipe_end.png")
def draw_pipes():
global pipes
for n in range(len(pipes)):
for m in range(pipes[n][1]):
gameScreen.blit(pipe_body, (pipes[n][0], m*32))
for m in range(pipes[n][1]+6, 16):
gameScreen.blit(pipe_body, (pipes[n][0], m*32))
gameScreen.blit(pipe_end, (pipes[n][0], (pipes[n][1])*32))
gameScreen.blit(pipe_end, (pipes[n][0], (pipes[n][1]+5)*32))
pipes[n][0] -= 1 # 使管道向左移动
实现小鸟翅膀扑动
我们的思路是利用翅膀一上一下的图片交互出现实现扑动
bird_wing_up = bird_wing_up_copy = pygame.image.load("bird_wing_up.png") # 小鸟翅膀向上和向下的图片,其中copy用于实现小鸟翻转
bird_wing_down = bird_wing_down_copy = pygame.image.load("bird_wing_down.png")
bird = [40, map_height//2-50]
def draw_bird(x, y): # 定义一个函数使得在(x,y)处显示小鸟图片
global frame # 引用全局变量frame
if 0 <= frame <= 30:
gameScreen.blit(bird_wing_up, (x, y)) # 在屏幕中(x,y)处显示小鸟
frame += 1
elif 30 < frame <= 60:
gameScreen.blit(bird_wing_down, (x, y))
frame += 1
if frame == 60: # 满帧归零
frame = 0
为了使我们的“笨鸟”不是只会直飞的真笨鸟
为它增加下坠和翻滚两个功能
这样它就会蹦了,代码如下
frame = 0 # 判断值(实现扑腾翅膀用的)
gravity = 0.2 # 重力参数
velocity = 0 # 小鸟下坠速度
velocity += gravity # 实现小鸟加速下坠
bird[1] += velocity
bird_wing_down = pygame.transform.rotate(bird_wing_down_copy, -90*(velocity/15)) # 实现小鸟边下坠边旋转
bird_wing_up = pygame.transform.rotate(bird_wing_up_copy, -90*(velocity/15))
判断小鸟是否动作违规:
def safe():
if bird[1] > map_height-35: # 判断小鸟是否撞到底部
print("hit floor")
return False
if bird[1] < 0: # 判断小鸟是否超出顶部
print("hit celling")
return False
if pipes[0][0]-30 < bird[0] < pipes[0][0]+79: # 小鸟出现在管道范围
if bird[1] < (pipes[0][1]+1)*32 or bird[1] > (pipes[0][1])*32: # 判断小鸟是否触碰到管道
print("hit pipe")
return False
return True
存储初始化数据:
def reset(): # 初始化数据
global frame, map_width, map_height, FPS, pipes, bird, gravity, velocity
map_width = 284
map_height = 512
frame = 0
FPS = 60
pipes.clear()
bird.clear()
pipes = [[180, 4]]
bird = [40, map_height//2-50]
gravity = 0.2
velocity = 0
综合制作:
def gameloop(): # 这句话之前要有两个空行,否则会出现PEP 8: E302 expected 2 blank lines, found 0
global velocity, bird_wing_down, bird_wing_up
gameScreen.blit(background, (0, 0)) # 在屏幕的(0,0)位置显示背景
draw_bird(20, map_height // 2) # 初始的小鸟初始位置
while True:
if len(pipes) < 4: # 因为屏幕大小只能显示4个管道,所以当管道个数小于4就要添加管道
x = pipes[-1][0]+200 # 最后一个管道的x坐标加上200
open_pos = randrange(1, 9) # 开口的位置用一个随机数计算
pipes.append([x, open_pos]) # 将中括号中的元素传回队列
if pipes[0][0] < -80: # 剔除移动到最左侧的管道
pipes.pop(0)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
bird[1] -= 40
velocity = 0
if event.type == pygame.QUIT:
pygame.quit()
return
velocity += gravity # 实现小鸟加速下坠
bird[1] += velocity
bird_wing_down = pygame.transform.rotate(bird_wing_down_copy, -90*(velocity/15)) # 实现小鸟边下坠边旋转
bird_wing_up = pygame.transform.rotate(bird_wing_up_copy, -90*(velocity/15))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
pygame.display.update() # 更新屏幕
draw_pipes()
pygame.display.update()
if not safe():
sleep(3)
reset()
clock.tick(FPS) # 每分钟60帧
gameloop()
最后的成品如下:
import pygame # 调用pygame库
from random import randrange
from time import sleep
pygame.init() # pygame库初始化
map_width = 284 # 容器的宽
map_height = 512 # 容器的高
frame = 0 # 判断值(实现扑腾翅膀用)
FPS = 60 # 屏幕刷新率
bird = [40, map_height//2-50]
gravity = 0.2 # 重力参数
velocity = 0 # 小鸟下坠速度
pipes = [[180, 4]] # 定义一个队列(用于绘制管道)
gameScreen = pygame.display.set_mode((map_width, map_height)) # 初始化一个屏幕
clock = pygame.time.Clock() # pygame中的时间函数(控制每分钟帧数)
background = pygame.image.load("background.png") # 设置背景图片
bird_wing_up = bird_wing_up_copy = pygame.image.load("bird_wing_up.png") # 小鸟翅膀向上和向下的图片,其中copy用于实现小鸟翻转
bird_wing_down = bird_wing_down_copy = pygame.image.load("bird_wing_down.png")
pipe_body = pygame.image.load("pipe_body.png")
pipe_end = pygame.image.load("pipe_end.png")
def draw_pipes():
global pipes
for n in range(len(pipes)):
for m in range(pipes[n][1]):
gameScreen.blit(pipe_body, (pipes[n][0], m*32))
for m in range(pipes[n][1]+6, 16):
gameScreen.blit(pipe_body, (pipes[n][0], m*32))
gameScreen.blit(pipe_end, (pipes[n][0], (pipes[n][1])*32))
gameScreen.blit(pipe_end, (pipes[n][0], (pipes[n][1]+5)*32))
pipes[n][0] -= 1 # 使管道向左移动
def draw_bird(x, y): # 定义一个函数使得在(x,y)处显示小鸟图片
global frame # 引用全局变量frame
if 0 <= frame <= 30:
gameScreen.blit(bird_wing_up, (x, y)) # 在屏幕中(x,y)处显示小鸟
frame += 1
elif 30 < frame <= 60:
gameScreen.blit(bird_wing_down, (x, y))
frame += 1
if frame == 60: # 满帧归零
frame = 0
def safe():
if bird[1] > map_height-35: # 判断小鸟是否撞到底部
print("hit floor")
return False
if bird[1] < 0: # 判断小鸟是否超出顶部
print("hit celling")
return False
if pipes[0][0]-30 < bird[0] < pipes[0][0]+79: # 小鸟出现在管道范围
if bird[1] < (pipes[0][1]+1)*32 or bird[1] > (pipes[0][1])*32: # 判断小鸟是否触碰到管道
print("hit pipe")
return False
return True
def reset(): # 初始化数据
global frame, map_width, map_height, FPS, pipes, bird, gravity, velocity
map_width = 284
map_height = 512
frame = 0
FPS = 60
pipes.clear()
bird.clear()
pipes = [[180, 4]]
bird = [40, map_height//2-50]
gravity = 0.2
velocity = 0
def gameloop(): # 这句话之前要有两个空行,否则会出现PEP 8: E302 expected 2 blank lines, found 0
global velocity, bird_wing_down, bird_wing_up
gameScreen.blit(background, (0, 0)) # 在屏幕的(0,0)位置显示背景
draw_bird(20, map_height // 2) # 初始的小鸟初始位置
while True:
if len(pipes) < 4: # 因为屏幕大小只能显示4个管道,所以当管道个数小于4就要添加管道
x = pipes[-1][0]+200 # 最后一个管道的x坐标加上200
open_pos = randrange(1, 9) # 开口的位置用一个随机数计算
pipes.append([x, open_pos]) # 将中括号中的元素传回队列
if pipes[0][0] < -80: # 剔除移动到最左侧的管道
pipes.pop(0)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
bird[1] -= 40
velocity = 0
if event.type == pygame.QUIT:
pygame.quit()
return
velocity += gravity # 实现小鸟加速下坠
bird[1] += velocity
bird_wing_down = pygame.transform.rotate(bird_wing_down_copy, -90*(velocity/15)) # 实现小鸟边下坠边旋转
bird_wing_up = pygame.transform.rotate(bird_wing_up_copy, -90*(velocity/15))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
pygame.display.update() # 更新屏幕
draw_pipes()
pygame.display.update()
if not safe():
sleep(3)
reset()
clock.tick(FPS) # 每分钟60帧
gameloop()
学自:哔哩哔哩中的胶皮睿
简单易学,但是遇到了一个问题尚未解决,代码是没有错误的。但是,显示不出动画效果。如下:
D:\Python\python.exe D:/Python/日常/笨鸟先飞/笨鸟先飞.py
pygame 2.0.0 (SDL 2.0.12, python 3.9.0)
Hello from the pygame community. https://www.pygame.org/contribute.html
Process finished with exit code 0
这是运行结果,现在觉得好像是闪退,不太懂。两天了
解决了我就分享解决方法庆祝一下,祝我好运