【pygame系列 第四课 弹球游戏-下 】
python我们可以做文字版的游戏,比如猜数字游戏,21点游戏。那python可以做图形界面的游戏吗?偷偷告诉你,用pygame库就可以实现了。pygame是python中专门用来编写游戏的一个引擎库,通过使用它,就可以很快的实现编写图形化的游戏。
本课任务在上一课基础上,实现下面几个任务。
第五步:窗体底部绘制一个挡板
第六步:用鼠标控制挡板左右移动
第七步:小球碰到挡板反弹,碰到底部结束
第八步:绘制游戏得分
第八步:绘制游戏结束界面文字
1.窗体底部绘制一个挡板
代码:
import pygame
import sys
import random
pygame.init()
size =width,height=400,300
screen = pygame.display.set_mode(size)
pygame.display.set_caption("弹球游戏")
# 背景白色
bg = (255,255,255)
# 球的颜色 红色
ball_color = (255,0,0)
# 球的大小 半径
ball_size = 20
# 球的初始位置 设置在窗口中心位置
pos_x,pos_y = width//2-ball_size,height//2-ball_size
# 设置球的 初始速度
speed_x=random.randint(1,5)
speed_y=random.randint(1,5)
# 设置挡板的 颜色 蓝色
board_color = (0,0,255)
# 设置挡板的 宽和高
board_width,board_height=50,10
# 设置挡板的初始位置
board_x,board_y = (width-board_width)//2,height-board_height
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(bg)
# 在窗口上绘制一个圆形 球
pygame.draw.circle(screen,ball_color,[pos_x,pos_y],ball_size)
# 在窗口上绘制一个挡板
pygame.draw.rect(screen,board_color,[board_x,board_y,board_width,board_height])
pygame.display.flip()
# 等待 100ms 避免刷新太快
pygame.time.wait(100)
if pos_x <ball_size or pos_x > width-ball_size:
speed_x = -speed_x
if pos_y <ball_size or pos_y > height-ball_size:
speed_y = -speed_y
# 更改位置
pos_x += speed_x
pos_y += speed_y
效果:
2.用鼠标控制挡板左右移动
代码:
import pygame
import sys
import random
pygame.init()
size =width,height=400,300
screen = pygame.display.set_mode(size)
pygame.display.set_caption("弹球游戏")
# 背景白色
bg = (255,255,255)
# 球的颜色 红色
ball_color = (255,0,0)
# 球的大小 半径
ball_size = 20
# 球的初始位置 设置在窗口中心位置
pos_x,pos_y = width//2-ball_size,height//2-ball_size
# 设置球的 初始速度
speed_x=random.randint(1,5)
speed_y=random.randint(1,5)
# 设置挡板的 颜色 蓝色
board_color = (0,0,255)
# 设置挡板的 宽和高
board_width,board_height=50,4
# 设置挡板的初始位置
board_x,board_y = (width-board_width)//2,height-board_height
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 检测鼠标移动事件
if event.type ==pygame.MOUSEMOTION:
# 获取鼠标移动的位置
mouse_x,mouse_y=pygame.mouse.get_pos()
# 防止挡板出右边的边界
if mouse_x>(width-board_width):
mouse_x=width-board_width
# 设置挡板的x坐标为鼠标位置,跟着鼠标移动
board_x=mouse_x
screen.fill(bg)
# 在窗口上绘制一个圆形 球
pygame.draw.circle(screen,ball_color,[pos_x,pos_y],ball_size)
# 在窗口上绘制一个挡板
pygame.draw.rect(screen,board_color,[board_x,board_y,board_width,board_height])
pygame.display.flip()
# 等待 100ms 避免刷新太快
pygame.time.wait(100)
if pos_x <ball_size or pos_x > width-ball_size:
speed_x = -speed_x
if pos_y <ball_size or pos_y > height-ball_size:
speed_y = -speed_y
# 更改位置
pos_x += speed_x
pos_y += speed_y
效果:
3.小球碰到挡板反弹,碰到底部结束
代码:
import pygame
import sys
import random
pygame.init()
size =width,height=400,300
screen = pygame.display.set_mode(size)
pygame.display.set_caption("弹球游戏")
# 背景白色
bg = (255,255,255)
# 球的颜色 红色
ball_color = (255,0,0)
# 球的大小 半径
ball_size = 20
# 球的初始位置 设置在窗口中心位置
pos_x,pos_y = width//2-ball_size,height//2-ball_size
# 设置球的 初始速度
speed_x=random.randint(1,5)
speed_y=random.randint(1,5)
# 设置挡板的 颜色 蓝色
board_color = (0,0,255)
# 设置挡板的 宽和高
board_width,board_height=50,4
# 设置挡板的初始位置
board_x,board_y = (width-board_width)//2,height-board_height
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 检测鼠标移动事件
if event.type ==pygame.MOUSEMOTION:
# 获取鼠标移动的位置
mouse_x,mouse_y=pygame.mouse.get_pos()
# 防止挡板出右边的边界
if mouse_x>(width-board_width):
mouse_x=width-board_width
# 设置挡板的x坐标为鼠标位置,跟着鼠标移动
board_x=mouse_x
screen.fill(bg)
# 在窗口上绘制一个圆形 球
pygame.draw.circle(screen,ball_color,[pos_x,pos_y],ball_size)
# 在窗口上绘制一个挡板
pygame.draw.rect(screen,board_color,[board_x,board_y,board_width,board_height])
pygame.display.flip()
# 等待 100ms 避免刷新太快
pygame.time.wait(100)
if pos_x <ball_size or pos_x > width-ball_size:
speed_x = -speed_x
if pos_y <ball_size:
speed_y = -speed_y
# 如果球已经进入到board厚度以下就要开始检测是否碰撞
elif pos_y>=height-ball_size-board_height:
# 如果球与board接触,就反弹
if board_x <= pos_x <= board_x+50:
speed_y=-speed_y
# 如果球已经碰到窗体底部,则游戏结束
elif pos_y>height-ball_size:
# 退出游戏
sys.exit
# 更改位置
pos_x += speed_x
pos_y += speed_y
4.绘制游戏得分
代码:
import pygame
import sys
import random
pygame.init()
size =width,height=400,300
screen = pygame.display.set_mode(size)
pygame.display.set_caption("弹球游戏")
# 背景白色
bg = (255,255,255)
# 球的颜色 红色
ball_color = (255,0,0)
# 球的大小 半径
ball_size = 20
# 球的初始位置 设置在窗口中心位置
pos_x,pos_y = width//2-ball_size,height//2-ball_size
# 设置球的 初始速度
speed_x=random.randint(1,5)
speed_y=random.randint(1,5)
# 设置挡板的 颜色 蓝色
board_color = (0,0,255)
# 设置挡板的 宽和高
board_width,board_height=50,4
# 设置挡板的初始位置
board_x,board_y = (width-board_width)//2,height-board_height
# 字体设置
font=pygame.font.SysFont("Arial",24)
# 分数
score = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 检测鼠标移动事件
if event.type ==pygame.MOUSEMOTION:
# 获取鼠标移动的位置
mouse_x,mouse_y=pygame.mouse.get_pos()
# 防止挡板出右边的边界
if mouse_x>(width-board_width):
mouse_x=width-board_width
# 设置挡板的x坐标为鼠标位置,跟着鼠标移动
board_x=mouse_x
screen.fill(bg)
# 在窗口上绘制一个圆形 球
pygame.draw.circle(screen,ball_color,[pos_x,pos_y],ball_size)
# 在窗口上绘制一个挡板
pygame.draw.rect(screen,board_color,[board_x,board_y,board_width,board_height])
# 显示计分
text = font.render("score:"+str(score), True, (255,0,0))
screen.blit(text,(10,10))
pygame.display.flip()
# 等待 100ms 避免刷新太快
pygame.time.wait(100)
if pos_x <ball_size or pos_x > width-ball_size:
speed_x = -speed_x
if pos_y <ball_size:
speed_y = -speed_y
# 如果球已经进入到board厚度以下就要开始检测是否碰撞
elif pos_y>=height-ball_size-board_height:
# 如果球与board接触,就反弹
if board_x <= pos_x <= board_x+50:
score += 1
speed_y=-speed_y
# 如果球已经碰到窗体底部,则游戏结束
else:
# 退出游戏
sys.exit()
# 更改位置
pos_x += speed_x
pos_y += speed_y
效果:
5.绘制游戏结束界面文字和重新开始
代码:
import pygame
import sys
import random
pygame.init()
size =width,height=400,300
screen = pygame.display.set_mode(size)
pygame.display.set_caption("弹球游戏")
# 背景白色
bg = (255,255,255)
# 球的颜色 红色
ball_color = (255,0,0)
# 球的大小 半径
ball_size = 20
# 球的初始位置 设置在窗口中心位置
pos_x,pos_y = width//2-ball_size,height//2-ball_size
# 设置球的 初始速度
speed_x=random.randint(1,5)
speed_y=random.randint(1,5)
# 设置挡板的 颜色 蓝色
board_color = (0,0,255)
# 设置挡板的 宽和高
board_width,board_height=50,4
# 设置挡板的初始位置
board_x,board_y = (width-board_width)//2,height-board_height
# 字体设置
font=pygame.font.SysFont("Arial",24)
# 游戏结束字体设置
gameover_font=pygame.font.SysFont("Arial",48)
# 分数
score = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 检测鼠标移动事件
if event.type ==pygame.MOUSEMOTION:
# 获取鼠标移动的位置
mouse_x,mouse_y=pygame.mouse.get_pos()
# 防止挡板出右边的边界
if mouse_x>(width-board_width):
mouse_x=width-board_width
# 设置挡板的x坐标为鼠标位置,跟着鼠标移动
board_x=mouse_x
screen.fill(bg)
# 在窗口上绘制一个圆形 球
pygame.draw.circle(screen,ball_color,[pos_x,pos_y],ball_size)
# 在窗口上绘制一个挡板
pygame.draw.rect(screen,board_color,[board_x,board_y,board_width,board_height])
# 显示计分
text = font.render("score:"+str(score), True, (255,0,0))
screen.blit(text,(10,10))
pygame.display.flip()
# 等待 100ms 避免刷新太快
pygame.time.wait(100)
if pos_x <ball_size or pos_x > width-ball_size:
speed_x = -speed_x
if pos_y <ball_size:
speed_y = -speed_y
# 如果球已经进入到board厚度以下就要开始检测是否碰撞
elif pos_y>=height-ball_size-board_height:
# 如果球与board接触,就反弹
if board_x <= pos_x <= board_x+50:
score += 1
speed_y=-speed_y
# 如果球已经碰到窗体底部,则游戏结束
else:
# 设置结束文本
gameover_text = gameover_font.render("Game Over", True, (255,0,0))
gamecontinue_text =font.render("Enter space to continue",True,(0,255,0))
# 获取结束surface 大小
surface_x,surface_y=gameover_text.get_size()
continue_x,continue_y=gamecontinue_text.get_size()
while True:
# 显示结束文本
screen.blit(gameover_text,((width-surface_x)//2,(height-surface_y)//2))
screen.blit(gamecontinue_text,((width-continue_x)//2,(height-continue_y)//2+40))
# 如果触发结束事件,就结束游戏
if len(pygame.event.get(pygame.QUIT)) >0:
pygame.quit()
sys.exit()
KeyUpEvents = pygame.event.get(pygame.KEYUP)
if KeyUpEvents:
if KeyUpEvents[0].key == pygame.K_SPACE:
pos_x,pos_y = width//2-ball_size,height//2-ball_size
speed_x=random.randint(1,5)
speed_y=random.randint(1,5)
score = 0
break
pygame.display.flip()
pygame.time.wait(500)
# 更改位置
pos_x += speed_x
pos_y += speed_y
结果:
总结:
本文主要讲了如何用鼠标控制挡板移动,小球与挡板的一个相互碰撞处理,游戏得分以及游戏结束重新开始等功能。
pygame.MOUSEMOTION # 鼠标移动事件
mouse_x,mouse_y=pygame.mouse.get_pos() # 获取鼠标的位置
KeyUpEvents = pygame.event.get(pygame.KEYUP) # 获取按键事件
pygame.K_SPACE # 空格事件
font=pygame.font.SysFont("Arial",24) # 使用系统字体,和设置字体大小
text = font.render("score:"+str(score), True, (255,0,0)) # 将文字渲染成一个surface对象
screen.blit(text,(10,10)) # 将surface字体对象渲染到窗体上
缺陷:
本游戏后面的逻辑看上去比较乱,难以一眼看上去很清晰,除了控制重新开始的方法不好外,还有就是面向过程的一个方式,当代码比较多时,一下很难看清楚代码逻辑。后面会用更好的方法重构本游戏,会用到标志变量和面向对象的方法。
欢迎转载,转载请注明出处!
欢迎关注公众微信号:叶子陪你玩
分享自己的python学习之路