我刚刚检查了here以确保这个问题是允许的,似乎是这样,我来了:
我目前正在做一个二维物理引擎作为一个小项目。我有一个名为circle
的类,它具有半径、旋转、位置和速度等属性:
class circle():
def __init__(self, radius = 10, r = 0.0, x = 0, y = 0, Vr = 0, Vx = 0, Vy = 0):
self.radius = radius
self.r = r
self.x = x
self.y = y
self.Vr = Vr
self.Vx = Vx
self.Vy = Vy
该类有一个名为CheckCollisions()
的方法,用于检查圆心与另一个圆的圆心之间的距离是否小于它们的半径之和:
def CheckCollisions(self):
for c in circles:
distance = math.sqrt((c.x - self.x)*(c.x - self.x) + (c.y - self.y)*(c.y - self.y))
if distance < self.radius + c.radius:
print('!')
else:
print('')
其思想是,在检测碰撞时,可以将力作为向量施加到每个物体上,作为对碰撞的响应。你知道吗
当我的代码运行时,我看到shell中不断出现感叹号,尽管圆圈没有碰撞。是什么原因造成的?也许我计算距离时有些地方不正确?你知道吗
完整代码:
import pygame, random, math
from pygame.locals import*
# set up pygame window
(width, height) = (1000, 800)
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption('Impulse Physics v0.1 BETA')
pen = pygame.image.load('Pen.png').convert()
background = (0, 0, 0)
class circle():
def __init__(self, radius = 10, r = 0.0, x = 0, y = 0, Vr = 0, Vx = 0, Vy = 0):
self.radius = radius
# position and rotation
self.r = r
self.x = x
self.y = y
# velocity
self.Vr = Vr
self.Vx = Vx
self.Vy = Vy
def CheckCollisions(self):
for c in circles:
# use pythagoras to find direct distance between centres
distance = math.sqrt((c.x - self.x)*(c.x - self.x) + (c.y - self.y)*(c.y - self.y))
if distance < self.radius + c.radius:
print('!')
else:
print('')
def Move(self):
# apply slight "air resistance"
self.Vx = self.Vx * 0.9999
# gravity. REMEMBER y axis is inverted in pygame!
self.Vy = self.Vy + 0.15
# move object
self.x = self.x + self.Vx
self.y = self.y + self.Vy
self.r = self.r + self.Vr
self.CheckCollisions()
# check if colliding with the sides of the window
if self.y + self.radius > height:
self.Vy = self.Vy * -0.98
self.y = self.y + self.Vy
if (self.x + self.radius > width) or (self.x - self.radius < 0):
self.Vx = self.Vx * -0.98
self.x = self.x + self.Vx
def Render(self):
penX = self.x
penY = self.y
penR = self.r
screen.blit(pen, (penX, penY))
# draw the radius of the circle
for counter in range(self.radius):
penX = self.x + (math.sin(penR) * counter)
penY = self.y - (math.cos(penR) * counter)
screen.blit(pen, (penX, penY))
# draw the circumference of the circle
for counter in range(self.radius * 20):
penR = counter * (360 / self.radius * 20)
penX = self.x + (math.sin(penR) * self.radius)
penY = self.y + (math.cos(penR) * self.radius)
screen.blit(pen, (penX, penY))
circles = []
#create objects here
c1 = circle(100, 0, 400, 400, 0.1, 4)
circles.append(c1)
c2 = circle(50, 0, 50, 50, 0.08, 10)
circles.append(c2)
c3 = circle(10, 0, 300, 200, 0.02, -3)
circles.append(c3)
running = True
while running:
screen.fill(background)
for obj in circles:
obj.Move()
obj.Render()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
pygame.quit()
简而言之:一个圆与其自身相撞。原因很简单,因为
circles
列表包含[c1,c2,c3]
,因此对圆本身进行检查。你知道吗现在对于
c1
检查是否有冲突,因此它在circles
上迭代,首先检查它是否与自身冲突(因为c1
是列表中的第一个元素)。显然是这样的(你的测试看起来距离是否小于圆半径之和,但距离为零)。如果没有一个圆发生碰撞,则会有三个感叹号(每个圆一个感叹号)。你知道吗您可以通过先执行引用相等性检查来解决此错误:
相关问题 更多 >
编程相关推荐