我对rect有以下类定义:
class Rect(object):
def __init__(self, *args):
# Again with the weird non-pythonic mess
if len(args) == 1: # copy another rect
return args[0].copy()
elif len(args) == 2:
self._x, self._y = args[0]
self._w, self._h = args[1]
elif len(args) == 4:
self.left, self.top, self.width, self.height = args
else:
raise ValueError("You done goofed.")
def __getattr__(self, name):
if name == "right":
return self._x + self._w
if name == "left" or name == "x":
return self._x
if name == "top" or name == "y":
return self._y
if name == "bottom":
return self._y + self._h
if name == "topright":
return (self._x + self._w, self._y)
if name == "bottomleft":
return (self._x, self._y + self._h)
if name == "topleft":
return (self._x, self._y)
if name == "bottomright":
return (self._x + self._w, self._y + self._h)
if name == "centerx":
return (self._x + self._w / 2.)
if name == "centery":
return (self._y + self._h / 2.)
if name == "center":
return (self._x + self._w / 2., self._y + self._h / 2.)
if name == "midleft":
return (self._x, self._y + self._h / 2.)
if name == "midright":
return (self._x + self._w, self._y + self._h / 2.)
if name == "midtop":
return (self._x + self._w / 2., self._y)
if name == "midbottom":
return (self._x + self._w / 2., self._y + self._h)
if name == "size":
return (self._w, self._h)
if name == "width" or name == "w":
return self._w
if name == "height" or name == "h":
return self._h
raise AttributeError("type object 'rect' has no attribute '" + name + "'")
def __setattr__(self, name, val):
# This could use _a lot_ more error checking
if name[0] == "_":
self.__dict__[name] = int(val)
return
if name == "right":
self._x = val - self._w
elif name == "left":
self._x = val
elif name == "top":
self._y = val
elif name == "bottom":
self._y = val - self._h
elif name == "topleft":
self._x, self._y = val
elif name == "topright":
self._x = val[0] - self._w
self._y = val[1]
elif name == "bottomleft":
self._x = val[0]
self._y = val[1] - self._h
elif name == "bottomright":
self._x = val[0] - self._w
self._y = val[0] - self._h
elif name == "width" or name == "w":
self._w = val
elif name == "height" or name == "h":
self._h = val
elif name == "size":
self._w, self._h = val
elif name == "centerx":
self._x = val - self._w / 2.
elif name == "centery":
self._y = val - self._h / 2.
elif name == "center":
self._x = val[0] - self._w / 2.
self._y = val[1] - self._h / 2.
elif name == "midtop":
self._x = val[0] - self._w / 2.
self._y = val[1]
elif name == "midleft":
self._x = val[0]
self._y = val[1] - self._h / 2.
elif name == "midbottom":
self._x = val[0] - self._w / 2.
self._y = val[1] - self._h
elif name == "midright":
self._x = val[0] - self._w
self._y = val[1] - self._h / 2.
else:
raise AttributeError("You done goofed!")
def copy(self):
return Rect(self._x, self._y, self._w, self._h)
def move(self, x, y):
return Rect(x, y, self._w, self._h)
def move_ip(self, x, y):
self._x, self._y = x,y
def inflate(self, x, y):
c = self.center
n = self.copy()
n.size = (self._w + x, self._h + y)
n.center = c
return n
def inflate_ip(self, x, y):
c = self.center
self.size = (self._w + x, self._h + y)
self.center = c
def clip(self, B):
A = self
try:
B._x
except TypeError:
B = Rect(B)
if A._x >= B._x and A._x < (B._x + B._w):
x = A._x
elif B._x >= A._x and B._x < (A._x + A._w):
x = B._x
else:
return Rect(A._x, A._y, 0, 0)
if ((A._x + A._w) > B._x) and ((A._x + A._w) <= (B._x + B._w)):
w = A._x + A._w - x
elif ((B._x + B._w) < A._x) and ((B._x + B._w) <= A._x + A._w):
w = B._x + B._w - x
else:
return Rect(A._x, A._y, 0, 0)
if A._y >= B._y and A._y < (B._y + B._h):
y = A._y
elif B._y >= A._y and B._y < (A._y + A._h):
y = B._y
else:
return Rect(A._x, A._y, 0, 0)
if ((A._y + A._h) > B._y) and ((A._y + A._h) <= (B._y + B._h)):
h = A._y + A._h - y
elif ((B._y + B._h) > A._y) and ((B._y + B._h) <= (A._y + A._h)):
h = B._y + B._h - y
else:
return Rect(A._x, A._y, 0, 0)
return Rect(x, y, w, h)
def contains(self, r):
if self.clip(r).size == r.size:
return True
return False
def collide_rect(self, r):
# Probably write a better optimized version of this later
return self.clip(r).size != (0,0) or r.clip(self).size != (0,0)
def collide_point(self, point):
# This could probably be optimized as well
return point[0] > self.left and point[0] < self.right and \
point[1] > self.top and point[1] < self.bottom
def __str__(self):
return ''.join(['<rect(',
str(self._x),
',',
str(self._y),
',',
str(self._w),
',',
str(self._h),
')>'])
def __repr__(self):
return self.__str__()
##NEW CODE
def setLocation(self, x, y):
float(self._x)
float(self._y)
self._x = x
self._y = y
def intersects(self, r):
if self.getBottom() < r.getTop: return False
if self.getTop() < r.getBottom: return False
if self.getRight() < r.getLeft: return False
if self.getLeft() < r.getRight: return False
return True
def getTop(self):
return self._y
def getBottom(self):
return self._y+self._h
def getLeft(self):
return self._x
def getRight(self):
return self._x+self._w
def getTopRect(self):
return Rect(self.X+.1, self.getTop(), self.WIDTH-.2, 1)
def getBottomRect(self):
return Rect(self.X+.1, self.getBottom(), self.WIDTH-.2, 1)
def getLeftRect(self):
return Rect(self.getLeft(), self.getTop()+.1, 1, self.HEIGHT-.2)
def getRightRect(self):
return Rect(self.getRight(), self.getTop()+.1, 1, self.HEIGHT-.2)
当我从另一个文件调用以下代码块时:
def move(self, terrainObjects):
#Moving ground related test to see if you
#overcome the velocity that you leave the piece of land with.
#Possible physics conceptual error here.
if (not self.grounded) and math.fabs(self.xGroundVel+self.vel_y) <= .1:
self.xGroundVel = 0
xV = 0
yV = 0
optimalLimit = 0
xVel = self.xGroundVel+self.vel_x
yVel = self.vel_y
if math.fabs(xVel) > math.fabs(yVel):
optimalLimit = math.fabs(xVel*self.collisionAccuracy)
else: optimalLimit = math.fabs(yVel*self.collisionAccuracy)
if optimalLimit != 0:
xV = 1.0*xVel/optimalLimit
yV = 1.0*yVel/optimalLimit
self.makeMove(xV, yV, optimalLimit, terrainObjects)
self.pos = (self.X, self.Y)
def makeMove(self, xI, yI, limit, terrainObjects):
currentRect = spyral.Rect(self.x,self.y,self.WIDTH,self.HEIGHT)
collisions = []
for i in range(0,int(limit)):
currentRect.move_ip(currentRect._x+xI, currentRect._y+yI)
for c in terrainObjects:
if c.get_rect().intersects(currentRect):
collisions.append(c)
if self.handleCollision(collisions, currentRect):
del collisions[0:len(collisions)]
它始终打印出y位置没有改变,尽管我在for循环的每次迭代都添加了.1。
基本上,代码所做的是,基于一定的准确度,您可以迭代地测试是否会发生从您当前位置到下一个位置的碰撞,具体取决于您的速度。它的前瞻性碰撞检测。较高的值,collisionAccuracy是,较小的xV和yV将是如此我们文本较小的增量,以便在移动之间获得更高的准确度。我有这个代码在Java中工作,我正在尝试将其转换为Python,但我是一个初学者,无法弄清楚为什么添加继续转换为int。
任何可能导致这种情况的想法?是每次都将它转换回int吗?