"""
本程序新建一个矩形类,它继承自Turtle。实例化后碰到边缘就会反弹,碰到其它方块后会反向移动。
不过有时候会交叉,这是一个bug,暂时无时间去修复。
"""
from time import sleep
from turtle import *
from random import randint
class Rectangle(Turtle):
def __init__(self,position,width,height,color='navy'):
Turtle.__init__(self,shape='square',visible=False)
self.penup()
self.dx = randint(-5,5)/10.0 # 水平方向单位位移
self.dy = randint(-5,5)/10.0 # 垂直方向单位位移
self.color(color) # 矩形颜色
self.sw = self.screen.window_width() # 窗口屏幕宽度
self.sh = self.screen.window_height() # 窗口屏幕高度
self.set_size(width,height) # 设置尺寸
self.goto(position) # 定位坐标
self.st() # 显示出来
def _pointlist(self):
"""获取矩形的顶点坐标列表,这个方法可以在get_rect中用,但是没有使用,留着吧"""
return self.screen._pointlist(self.turtle._item)
def set_size(self,width,height):
"""设置尺寸,能动态的设置矩形的大小"""
self.width = width # 重定义width
self.height = height # 定义height
self.shapesize(height/20.0,width/20.0)
def get_rect(self):
"""获取矩形上下左右边界的坐标"""
self.left = self.xcor() - self.width/2.0 # 最左x坐标
self.right = self.xcor() + self.width/2.0 # 最右x坐标
self.top = self.ycor() + self.height/2.0 # 最上y坐标
self.bottom = self.ycor() - self.height/2.0 # 最下y坐标
def move(self):
"""移动矩形"""
x = self.xcor() + self.dx
y = self.ycor() + self.dy
self.goto(x,y)
def bounce_on_edge(self):
"""碰到边缘就反弹"""
self.get_rect() # 获取上下左右边界坐标
if self.left <= -self.sw//2 : self.dx = -self.dx
if self.right >= self.sw//2 : self.dx = -self.dx
if self.top >= self.sh//2 : self.dy = -self.dy
if self.bottom <= -self.sh//2 : self.dy = -self.dy
def collide(self,group):
"""和其它矩形的碰撞"""
for other in group:
if self==other:continue
self.get_rect()
other.get_rect()
c1 = self.right < other.left
c2 = self.left > other.right
c3 = self.bottom > other.top
c4 = self.top < other.bottom
collision = not(c1 or c2 or c3 or c4)
if collision: # 碰到就把单位位移取反
self.dx = -self.dx # 并非真正的碰撞
other.dx = -other.dx
self.dy = -self.dy
other.dy = -other.dy
self.move()
other.move()
return
if __name__ == "__main__":
screen = Screen()
screen.delay(0)
screen.title("turtle制作的一种简单的完全矩形碰撞示例程序by lixingqiu")
screen.bgcolor("cyan")
screen.setup(480,360)
squares = []
positions = [(100,100),(-100,100),(0,0),(-100,-100),(100,-100)]
amounts = len(positions)
# 生成方块
[squares.append( Rectangle(p,50,50)) for p in positions]
index = 0
while True:
s = squares[index]
s.move()
s.bounce_on_edge() # 碰到边缘就反弹
s.collide(squares)
index = index + 1
index = index % amounts