Pygame(十二)打砖块
目标
- 小球撞击响应
- 砖块撞击响应
- 挡板撞击响应
完整示例代码
# /usr/bin/python3
# Author: 爱编程的章老师
# @Time: 2021/1/9 0009
# E-mail: Bluesand2010@163.com
'''设计一个打砖块的游戏'''
# 1. 开局屏幕上方有4行每行10个砖块
# 2. 在屏幕下方有一个长100 的挡板
# 3. 有一个小球从挡板中间出发,45角方向
import pygame
import sys
import time
# 主程序
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("打砖块V.01 by 爱编程的章老师")
# 定义颜色
color1 = 255, 0 ,0 # 目标砖块的颜色
color2 = 0, 255, 0 # 挡板的颜色
color3 = 0, 0, 255 # 球的颜色
font_color = 255, 255, 255 # 字体颜色
# 生成目标砖块
rect_list = []
for i in range(10):
for j in range(6):
rect_temp = pygame.Rect(i * 78 + 10, j*20 + 60, 75, 17)
rect_list.append(rect_temp)
# 定义挡板
rect_b = pygame.Rect(350, 550, 100, 15)
# 定义小球
ball = pygame.Rect(380, 520, 30, 30)
# 定义分数字体对象
font = pygame.font.SysFont("fangsong", 20)
# 画初始图形
for r in rect_list: # 画目标砖块
pygame.draw.rect(screen, color1, r)
pygame.draw.rect(screen,color2, rect_b) # 画挡板
pygame.draw.ellipse(screen, color3, ball) # 画小球
# 绘制分数
score_surface = font.render("分数:0", True, font_color)
screen.blit(score_surface, (10, 15))
# 更新屏幕
pygame.display.update()
# 小球移动方向
dx = dy = -1
# 小球移动幅度
step = 5
# 分数
score = 0
# 主程序
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 按键检测
keys = pygame.key.get_pressed()
# 左移挡板
if keys[pygame.K_LEFT] or keys[pygame.K_a]:
if rect_b.left - 10 >= 0:
rect_b.left -= 10
# 右移挡板
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
if rect_b.right + 10 <= 800:
rect_b.right += 10
# 小球移动
ball.move_ip(dx * step, dy * step)
# 小球碰撞检测
# 撞到挡板, 或者撞到屏幕上边缘就上下反方向
if ball.colliderect(rect_b) or ball.top <=0 :
dy *= -1
# 撞到左右屏幕边缘就左右反向
if ball.left <= 0 or ball.right >= 800:
dx *= -1
# 检测有没有撞到目标砖
for each in rect_list:
if ball.colliderect(each):
if ball.left <= each.right and each.center[0] > each.center[0]:
dx *= -1
elif ball.right >= each.left and each.center[0] < each.center[0]:
dx *= -1
elif ball.top <= each.bottom and ball.center[1] > each.center[1]:
dy *= -1
elif ball.bottom >= each.top and ball.center[1] < each.center[1]:
dy *= -1
rect_list.remove(each)
score += 100
break
# 没接到球,游戏失败
if ball.bottom > rect_b.bottom:
font = pygame.font.SysFont("fangsong",50)
font_surface = font.render("游戏失败", True, color1)
screen.blit(font_surface, (400- 100, 300-25))
pygame.display.update()
break
# 方块打完了,游戏胜利
if not rect_list:
font = pygame.font.SysFont("fangsong",50)
font_surface = font.render("游戏胜利", True, color1)
screen.blit(font_surface, (400- 100, 300-25))
pygame.display.update()
break
# 清空屏幕
screen.fill((0,0,0))
# 绘制图形
font_surface = font.render("分数:" + str(score), True, font_color)
screen.blit(font_surface, (10, 15))
for each in rect_list:
pygame.draw.rect(screen, color1, each)
pygame.draw.rect(screen, color2, rect_b)
pygame.draw.ellipse(screen, color3, ball)
pygame.display.update()
time.sleep(0.05)
# 主程序
if __name__ == '__main__':
main()
游戏效果:
代码分析
游戏的基本流程:
- 绘制图形
- 角色移动(运动)
- 角色互动
- 绘制新的图形
基于以上流程
游戏中两个会动的角色: 小球, 挡板
挡板只有左右移动.代码比较简单
小球的运动,这里选择了45度角恒定不变的运动方式,简化编程难度
小球的运动方向有右上,左上,右下,左下四个方向.用dx与dy来控件
根据碰撞的情形来改变运动的方向
游戏失败的条件是小球落地
游戏胜利的条件是砖块清空