"""多个弹球与矩形碰撞示例程序,本程序用海龟画图模块演示基本的矩形碰撞原理""" from turtle import Turtle, Screen from random import choice,randint class Board(Turtle): def __init__(self): """初始化不可见的矩形""" Turtle.__init__(self, shape='square', visible=False) self.penup() self.color('yellow') self.shapesize(10, 10) self.st() def up_move(self): """向上移动10个单位""" y = self.ycor() + 10 self.sety(y) def down_move(self): """向下移动10个单位""" y = self.ycor() - 10 self.sety(y) def left_move(self): """向左移动10个单位""" x = self.xcor() - 10 self.setx(x) def right_move(self): """向右移动10个单位""" x = self.xcor() + 10 self.setx(x) class Ball(Turtle): def __init__(self,board): """初始化不可见圆形,参数为矩形""" Turtle.__init__(self, shape='circle', visible=False) self.board = board rect = self.screen.cv.coords(self.board.turtle._item) self.board_width = abs(rect[0] - rect[2]) # 求矩形宽度 self.board_height = abs(rect[1] - rect[5]) # 求矩形高度 self.penup() # 抬笔 self.color('red') # 设置小球颜色 self.radius = 10 # 海龟画图默认圆形的半径为10 self.sh = self.screen.window_height() # 获取屏幕高度 self.sw = self.screen.window_width() # 获取屏幕的宽度 self.ht() self.init_move() def init_move(self): x = randint(-self.sw // 2, self.sh // 2) y = randint(-self.sh // 2, self.sw // 2) # 有些小球会生成在矩形内,可以重新调整位置让小球都生成在矩形外面 self.goto(x, y) # 设置小球的单位移动距离 self.xspeed = choice([-1,-2,-3,-4,-5,1,2,3,4,5]) self.yspeed = choice([-1,-2,-3,-4,-5,1,2,3,4,5]) self.st() def move(self): """移动""" x = self.xcor() + self.xspeed y = self.ycor() + self.yspeed self.goto(x, y) # 边缘检测 if abs(self.xcor()) + self.radius >= self.sw // 2: self.xspeed = -self.xspeed if abs(self.ycor()) + self.radius >= self.sh // 2: self.yspeed = -self.yspeed # 碰到矩形检测 self.collide_board_check() def collide_board_check(self): """矩形碰撞检测""" board_left = self.board.xcor() - self.board_width//2 board_right = self.board.xcor() + self.board_width//2 board_top = self.board.ycor() + self.board_height//2 board_bottom = self.board.ycor() - self.board_height//2 ball_left = self.xcor() - self.radius ball_right = self.xcor() + self.radius ball_top = self.ycor() + self.radius ball_bottom = self.ycor() - self.radius # 没有碰到矩形的条件 c1 = ball_right < board_left or ball_left > board_right c2 = ball_bottom > board_top or ball_top<board_bottom # 如果没有碰到,直接返回 if c1 or c2 :return # 在矩形的左边,向右碰撞过去的 if ball_right > board_left and ball_bottom > board_bottom and ball_top<board_top: self.xspeed = -self.xspeed return # 在矩形的右边,向左移动碰撞过去 if ball_left < board_right and ball_bottom > board_bottom and ball_top<board_top: self.xspeed = -self.xspeed return # 在矩形的上边,向下撞过去 if ball_bottom < board_top and ball_left > board_left and ball_right<board_right: self.yspeed = -self.yspeed return # 在矩形的下边,向上撞过去 if ball_top > board_bottom and ball_left > board_left and ball_right<board_right: self.yspeed = -self.yspeed return if __name__ == '__main__': # 声明一个空列表,用于存放小球对象 ps = [] # 计数 count = 0 # 设置小球总数 amount = 20 # 新建一个屏幕 screen = Screen() # 设置屏幕背景色 screen.bgcolor('white') # 设置屏幕宽高 screen.setup(700, 500) # 设置屏幕标题 screen.title('多个弹球与矩形碰撞示例程序,作者:李兴球') screen.delay(0) # 创建挡板对象 d = Board() screen.onkeypress(d.up_move, 'Up') screen.onkeypress(d.down_move, 'Down') screen.onkeypress(d.left_move, 'Left') screen.onkeypress(d.right_move, 'Right') screen.update() screen.listen() while True: if count < amount: p = Ball(d) ps.append(p) count += 1 [p.move() for p in ps] screen.update()
李兴球
李兴球的博客是Python创意编程原创博客