这次用Python实现的是一个接球打砖块的小游戏,最核心的就是:碰撞检测的数学模型
程序运行截图:

其实,编程问题到最后就是数学问题,这个游戏涉及到2D圆形与矩形的碰撞检测问题:

碰撞检测原理:通过找出矩形上离圆心最近的点,然后通过判断该点与圆心的距离是否小于圆的半径,若小于则为碰撞。

那如何找出矩形上离圆心最近的点呢?下面我们从 x 轴、y 轴两个方向分别进行寻找。为了方便描述,我们先约定以下变量:

(1)矩形上离圆心最近的点为变量:closestpoint = [x, y]
(2)矩形 rect = [x, y, l, w] 左上角与长宽 length,wide
(3)圆形 circle = [x, y, r] 圆心与半径

首先是 x 轴:
如果圆心在矩形的左侧(if circle_x < rect_x),那么 closestpoint_x = rect_x。
如果圆心在矩形的右侧(elif circle_x > rect_x + rect_l),那么 closestpoint_x = rect_x + rect_l。
如果圆心在矩形的正上下方(else),那么 closestpoint_x = circle_x。

同理,对于 y 轴:
如果圆心在矩形的上方(if circle_y < rect_y),那么 closestpoint_y = rect_y。
如果圆心在矩形的下方(elif circle_y > rect_y + rect_w)),那么 closestpoint_y = rect_y + rect_w。
圆形圆心在矩形的正左右两侧(else),那么 closestpoint_y = circle_y。

因此,通过上述方法即可找出矩形上离圆心最近的点了,然后通过“两点之间的距离公式”得出“最近点”与“圆心”的距离,最后将其与圆的半径相比,即可判断是否发生碰撞。
distance=math.sqrt(math.pow(closestpoint_x-circle_x,2)+math.pow(closestpoint_y-circle_y,2))

if distance < circle.r :
return True – 发生碰撞
else :
return False – 未发生碰撞

完整程序

# 导入模块import pygamefrom pygame.locals import *import sys, random, time, mathclass GameWindow(object):    '''创建游戏窗口类'''    def __init__(self, *args, **kw):        self.window_length = 600        self.window_wide = 500        # 绘制游戏窗口,设置窗口尺寸        self.game_window = pygame.display.set_mode((self.window_length, self.window_wide))        # 设置游戏窗口标题        pygame.display.set_caption("打砖块-Python代码大全")        # 定义游戏窗口背景颜色参数        self.window_color = (135, 206, 250)    def backgroud(self):        # 绘制游戏窗口背景颜色        self.game_window.fill(self.window_color)class Ball(object):    '''创建球类'''    def __init__(self, *args, **kw):        # 设置球的半径、颜色、移动速度参数        self.ball_color = (255, 215, 0)        self.move_x = 1        self.move_y = 1        self.radius = 10    def ballready(self):        # 设置球的初始位置、        self.ball_x = self.mouse_x        self.ball_y = self.window_wide - self.rect_wide - self.radius        # 绘制球,设置反弹触发条件        pygame.draw.circle(self.game_window, self.ball_color, (self.ball_x, self.ball_y), self.radius)    def ballmove(self):        # 绘制球,设置反弹触发条件        pygame.draw.circle(self.game_window, self.ball_color, (self.ball_x, self.ball_y), self.radius)        self.ball_x += self.move_x        self.ball_y -= self.move_y        # 调用碰撞检测函数        self.ball_window()        self.ball_rect()        # 每接5次球球速增加一倍        if self.distance < self.radius:            self.frequency += 1            if self.frequency == 5:                self.frequency = 0                self.move_x += self.move_x                self.move_y += self.move_y                self.point += self.point        # 设置游戏失败条件        if self.ball_y > 520:            self.gameover = self.over_font.render("Game Over", False, (0, 0, 0))            self.game_window.blit(self.gameover, (100, 130))            self.over_sign = 1class Rect(object):    '''创建球拍类'''    def __init__(self, *args, **kw):        # 设置球拍颜色参数        self.rect_color = (255, 0, 0)        self.rect_length = 100        self.rect_wide = 10    def rectmove(self):        # 获取鼠标位置参数        self.mouse_x, self.mouse_y = pygame.mouse.get_pos()        # 绘制球拍,限定横向边界        if self.mouse_x >= self.window_length - self.rect_length // 2:            self.mouse_x = self.window_length - self.rect_length // 2        if self.mouse_x <= self.rect_length // 2:            self.mouse_x = self.rect_length // 2        pygame.draw.rect(self.game_window, self.rect_color, (        (self.mouse_x - self.rect_length // 2), (self.window_wide - self.rect_wide), self.rect_length, self.rect_wide))class Brick(object):    def __init__(self, *args, **kw):        # 设置砖块颜色参数        self.brick_color = (139, 126, 102)        self.brick_list = [[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1],                           [1, 1, 1, 1, 1, 1]]        self.brick_length = 80        self.brick_wide = 20    def brickarrange(self):        for i in range(5):            for j in range(6):                self.brick_x = j * (self.brick_length + 24)                self.brick_y = i * (self.brick_wide + 20) + 40                if self.brick_list[i][j] == 1:                    # 绘制砖块                    pygame.draw.rect(self.game_window, self.brick_color,                                     (self.brick_x, self.brick_y, self.brick_length, self.brick_wide))                    # 调用碰撞检测函数                    self.ball_brick()                    if self.distanceb < self.radius:                        self.brick_list[i][j] = 0                        self.score += self.point        # 设置游戏胜利条件        if self.brick_list == [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],                               [0, 0, 0, 0, 0, 0]]:            self.win = self.win_font.render("You Win", False, (0, 0, 0))            self.game_window.blit(self.win, (100, 130))            self.win_sign = 1class Score(object):    '''创建分数类'''    def __init__(self, *args, **kw):        # 设置初始分数        self.score = 0        # 设置分数字体        self.score_font = pygame.font.SysFont('arial', 20)        # 设置初始加分点数        self.point = 1        # 设置初始接球次数        self.frequency = 0    def countscore(self):        # 绘制玩家分数        my_score = self.score_font.render(str(self.score), False, (255, 255, 255))        self.game_window.blit(my_score, (555, 15))class GameOver(object):    '''创建游戏结束类'''    def __init__(self, *args, **kw):        # 设置Game Over字体        self.over_font = pygame.font.SysFont('arial', 80)        # 定义GameOver标识        self.over_sign = 0class Win(object):    '''创建游戏胜利类'''    def __init__(self, *args, **kw):        # 设置You Win字体        self.win_font = pygame.font.SysFont('arial', 80)        # 定义Win标识        self.win_sign = 0class Collision(object):    '''碰撞检测类'''    # 球与窗口边框的碰撞检测    def ball_window(self):        if self.ball_x <= self.radius or self.ball_x >= (self.window_length - self.radius):            self.move_x = -self.move_x        if self.ball_y <= self.radius:            self.move_y = -self.move_y    # 球与球拍的碰撞检测    def ball_rect(self):        # 定义碰撞标识        self.collision_sign_x = 0        self.collision_sign_y = 0        if self.ball_x < (self.mouse_x - self.rect_length // 2):            self.closestpoint_x = self.mouse_x - self.rect_length // 2            self.collision_sign_x = 1        elif self.ball_x > (self.mouse_x + self.rect_length // 2):            self.closestpoint_x = self.mouse_x + self.rect_length // 2            self.collision_sign_x = 2        else:            self.closestpoint_x = self.ball_x            self.collision_sign_x = 3        if self.ball_y < (self.window_wide - self.rect_wide):            self.closestpoint_y = (self.window_wide - self.rect_wide)            self.collision_sign_y = 1        elif self.ball_y > self.window_wide:            self.closestpoint_y = self.window_wide            self.collision_sign_y = 2        else:            self.closestpoint_y = self.ball_y            self.collision_sign_y = 3        # 定义球拍到圆心最近点与圆心的距离        self.distance = math.sqrt(            math.pow(self.closestpoint_x - self.ball_x, 2) + math.pow(self.closestpoint_y - self.ball_y, 2))        # 球在球拍上左、上中、上右3种情况的碰撞检测        if self.distance < self.radius and self.collision_sign_y == 1 and (                self.collision_sign_x == 1 or self.collision_sign_x == 2):            if self.collision_sign_x == 1 and self.move_x > 0:                self.move_x = - self.move_x                self.move_y = - self.move_y            if self.collision_sign_x == 1 and self.move_x < 0:                self.move_y = - self.move_y            if self.collision_sign_x == 2 and self.move_x < 0:                self.move_x = - self.move_x                self.move_y = - self.move_y            if self.collision_sign_x == 2 and self.move_x > 0:                self.move_y = - self.move_y        if self.distance < self.radius and self.collision_sign_y == 1 and self.collision_sign_x == 3:            self.move_y = - self.move_y        # 球在球拍左、右两侧中间的碰撞检测        if self.distance < self.radius and self.collision_sign_y == 3:            self.move_x = - self.move_x    # 球与砖块的碰撞检测    def ball_brick(self):        # 定义碰撞标识        self.collision_sign_bx = 0        self.collision_sign_by = 0        if self.ball_x < self.brick_x:            self.closestpoint_bx = self.brick_x            self.collision_sign_bx = 1        elif self.ball_x > self.brick_x + self.brick_length:            self.closestpoint_bx = self.brick_x + self.brick_length            self.collision_sign_bx = 2        else:            self.closestpoint_bx = self.ball_x            self.collision_sign_bx = 3        if self.ball_y < self.brick_y:            self.closestpoint_by = self.brick_y            self.collision_sign_by = 1        elif self.ball_y > self.brick_y + self.brick_wide:            self.closestpoint_by = self.brick_y + self.brick_wide            self.collision_sign_by = 2        else:            self.closestpoint_by = self.ball_y            self.collision_sign_by = 3        # 定义砖块到圆心最近点与圆心的距离        self.distanceb = math.sqrt(            math.pow(self.closestpoint_bx - self.ball_x, 2) + math.pow(self.closestpoint_by - self.ball_y, 2))        # 球在砖块上左、上中、上右3种情况的碰撞检测        if self.distanceb < self.radius and self.collision_sign_by == 1 and (                self.collision_sign_bx == 1 or self.collision_sign_bx == 2):            if self.collision_sign_bx == 1 and self.move_x > 0:                self.move_x = - self.move_x                self.move_y = - self.move_y            if self.collision_sign_bx == 1 and self.move_x < 0:                self.move_y = - self.move_y            if self.collision_sign_bx == 2 and self.move_x < 0:                self.move_x = - self.move_x                self.move_y = - self.move_y            if self.collision_sign_bx == 2 and self.move_x > 0:                self.move_y = - self.move_y        if self.distanceb < self.radius and self.collision_sign_by == 1 and self.collision_sign_bx == 3:            self.move_y = - self.move_y        # 球在砖块下左、下中、下右3种情况的碰撞检测        if self.distanceb < self.radius and self.collision_sign_by == 2 and (                self.collision_sign_bx == 1 or self.collision_sign_bx == 2):            if self.collision_sign_bx == 1 and self.move_x > 0:                self.move_x = - self.move_x                self.move_y = - self.move_y            if self.collision_sign_bx == 1 and self.move_x < 0:                self.move_y = - self.move_y            if self.collision_sign_bx == 2 and self.move_x < 0:                self.move_x = - self.move_x                self.move_y = - self.move_y            if self.collision_sign_bx == 2 and self.move_x > 0:                self.move_y = - self.move_y        if self.distanceb < self.radius and self.collision_sign_by == 2 and self.collision_sign_bx == 3:            self.move_y = - self.move_y        # 球在砖块左、右两侧中间的碰撞检测        if self.distanceb < self.radius and self.collision_sign_by == 3:            self.move_x = - self.move_xclass Main(GameWindow, Rect, Ball, Brick, Collision, Score, Win, GameOver):    '''创建主程序类'''    def __init__(self, *args, **kw):        super(Main, self).__init__(*args, **kw)        super(GameWindow, self).__init__(*args, **kw)        super(Rect, self).__init__(*args, **kw)        super(Ball, self).__init__(*args, **kw)        super(Brick, self).__init__(*args, **kw)        super(Collision, self).__init__(*args, **kw)        super(Score, self).__init__(*args, **kw)        super(Win, self).__init__(*args, **kw)        # 定义游戏开始标识        start_sign = 0        while True:            self.backgroud()            self.rectmove()            self.countscore()            if self.over_sign == 1 or self.win_sign == 1:                break            # 获取游戏窗口状态            for event in pygame.event.get():                if event.type == pygame.QUIT:                    sys.exit()                if event.type == MOUSEBUTTONDOWN:                    pressed_array = pygame.mouse.get_pressed()                    if pressed_array[0]:                        start_sign = 1            if start_sign == 0:                self.ballready()            else:                self.ballmove()            self.brickarrange()            # 更新游戏窗口            pygame.display.update()            # 控制游戏窗口刷新频率            time.sleep(0.010)if __name__ == '__main__':    pygame.init()    pygame.font.init()    catchball = Main()

bat小游戏代码大全_Python打砖块小游戏源代码相关推荐

  1. c语言250行游戏代码大全,最经典的PASCAL游戏!300行程序代码,超爽!

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 program joyxy; type player = record level:integer;   gjl:integer; fyl:integer ...

  2. python小游戏代码大全-Python编写的点灯小游戏代码

    Python语言编写的点灯小游戏代码及思路如下: 点灯游戏及其求解的方法, 点灯游戏的游戏规则: (1)有个N行N列的灯板,当你开关其中一盏灯: (2)它和上下左右的灯的状态全部反转,目标是将全部的灯 ...

  3. python小游戏代码大全-Python实现打砖块小游戏代码实例

    这次用Python实现的是一个接球打砖块的小游戏,需要导入pygame模块,有以下两条经验总结: 1.多父类的继承2.碰撞检测的数学模型 知识点稍后再说,我们先看看游戏的效果和实现: 一.游戏效果 二 ...

  4. c++游戏代码大全_还在学少儿编程?不如来玩工厂编程师,免费学编程逻辑的小游戏...

    40000+游戏爱好者已加入我们! 每天推荐好玩游戏! 加入我们,沐沐带你发现好游戏! <工厂编程师>游戏小程序好玩吗? <工厂编程师>小游戏怎么玩? 只有你想不到, 没有我找 ...

  5. python手机版做小游戏代码大全-python简单小游戏代码 怎么用Python制作简单小游戏...

    1.Python猜拳小游戏代码: 2.import random #导入随机模块 3. 4.num = 1 5.yin_num = 0 6.shu_num = 0 7.while num <= ...

  6. python小游戏代码大全-Python小游戏之300行代码实现俄罗斯方块

    前言 本文代码基于 python3.6 和 pygame1.9.4. 俄罗斯方块是儿时最经典的游戏之一,刚开始接触 pygame 的时候就想写一个俄罗斯方块.但是想到旋转,停靠,消除等操作,感觉好像很 ...

  7. python小游戏代码大全-python贪吃蛇游戏代码

    本文实例为大家分享了python贪吃蛇游戏的具体代码,供大家参考,具体内容如下 贪吃蛇游戏截图: 首先安装pygame,可以使用pip安装pygame: pip install pygame 运行以下 ...

  8. python小游戏代码大全-python简单小游戏代码 怎么用Python制作简单小游戏

    1.Python猜拳小游戏代码: 2.import random #导入随机模块 3. 4.num = 1 5.yin_num = 0 6.shu_num = 0 7.while num <= ...

  9. 游戏代码大全_Switch新游推荐之世界游戏大全51,茶余饭后的消遣

    任天堂于2020年6月5日在Nintendo Switch平台推出<世界游戏大全51>,并且支持了中文!这款游戏收录了51种世界流行的桌面游戏,支持在线.离线联机对战.买了一款游戏却享受了 ...

最新文章

  1. [原] 探索 EventEmitter 在 Node.js 中的实现
  2. leetcode 200.岛屿数量 c代码
  3. 函数指针,以及用函数指针的好用之处(回调函数)
  4. maven国内镜像配置
  5. genymotion局域网访问_请问一下genymotion如何连接到内网上一个网站
  6. Python和Java就业前景对比
  7. CISCO PIX防火墙的配置
  8. 运行地址与加载地址估计大部分人没弄明白~
  9. 《计算机应用基础》模拟试卷三,2015年《计算机应用基础》模拟试题及答案(一)...
  10. 高通发布一系列新型WiFi芯片:兼容WiFi 6技术
  11. 解决方法:SQL Server 检测到基于一致性的逻辑 I/O 错误 校验和不正
  12. Skin++ 使用教程(VC软件外观美化工具)
  13. python函数作用域_Python命名空间和作用域的基本认识和一点小魔法
  14. php验证码图片看不清更换代码,php如何实现验证码看不清换一张的效果
  15. Mac硬盘格式转化好帮手——Tuxera NTFS
  16. 20200718每日一句
  17. 190124每日一句
  18. #paypay付款测试#
  19. android夏时令问题
  20. Velodyne VLP16 WIN下配置

热门文章

  1. 解决manjaro更新后pacman: error while loading shared libraries
  2. Django 中间件
  3. 上海市高校精品课程“网络安全技术”
  4. HTML的br/标签和hr/标签
  5. Office资源汇 | Office 365 微助理功能介绍 4
  6. Keras + Ubuntu环境搭建
  7. fir.im Weekly - iOS 保持界面流畅的技巧 1
  8. 企业级应用WebLogic11g集群配置与项目实施_WebLogic部署培训教程
  9. 用户sa 登陆失败 SQLServer 错误18456 图解
  10. 【UCHome二次开发】全局变量