python - 出于某种原因,PyGame 物理模拟所有物体都以相同的速度移动
问题描述
我目前正在学习可汗学院的一些自然模拟课程,并试图在 python 中重现他们的 JavaScript 代码。在下面的代码中,我试图在两个不同质量的物体上模拟重力和风。但是,即使在apply_force()
我除以物体质量的方法中,当我运行模拟时,两个物体都以完全相同的速度移动。风应该使较小的身体比较大的身体移动得更快,但事实并非如此。
#init pygame library
import pygame
import random
pygame.init()
window_width = 800
window_height = 800
FPS = 500
screen = pygame.display.set_mode([window_width, window_height])
clock = pygame.time.Clock()
running = True
#basic vector class class
class Vector2f:
def __init__(self, x, y):
self.x = x
self.y = y
def add(self, v2):
self.x = self.x + v2.x
self.y = self.y + v2.y
def mult(self, v2):
self.x = self.x * v2.x
self.y = self.y * v2.y
#mover class
class Mover:
def __init__(self, mass, position, velocity, acceleration):
self.mass = mass
self.position = position
self.velocity = velocity
self.acceleration = acceleration
def apply_force(self, force):
f = Vector2f((force.x/float(self.mass)), (force.y/float(self.mass)))
self.acceleration.add(f)
def update(self):
self.velocity.add(self.acceleration)
self.position.add(Vector2f(self.velocity.x, self.velocity.y))
self.acceleration.mult(Vector2f(0,0))
def draw(self):
pygame.draw.circle(screen, (50, 50, 50), (int(round(self.position.x)), int(round(self.position.y))), self.mass)
def check_edges(self):
if self.position.x > window_width:
self.position.x = window_width
self.velocity.x = self.velocity.x * -1
elif self.position.x < 0:
self.position.x = 0
self.velocity.x = self.velocity.x * -1
if self.position.y > window_height:
self.velocity.y = self.velocity.y * -1
self.position.y = window_height
m_position = Vector2f(30, 30)
m_velocity = Vector2f(0, 0)
m_acceleration = Vector2f(0, 0)
m1 = Mover(30, m_position, m_velocity, m_acceleration)
m2 = Mover(5, m_position, m_velocity, m_acceleration)
#simulation loop
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((255,255,255))
wind = Vector2f(.003, 0)
gravity = Vector2f(0, .005)
m1.apply_force(wind)
m1.apply_force(gravity*m1.mass)
m1.update()
m1.draw()
m1.check_edges()
m2.apply_force(wind)
m2.apply_force(gravity*m2.mass)
m2.update()
m2.draw()
m2.check_edges()
pygame.display.flip()
pygame.quit()
此外,当我减小较小动子 ( m2
) 的质量时,不知何故,速度m1
正在增加。
解决方案
m_position
您为、m_velocity
和创建向量m_acceleration
。实例对象m1
和m2
共享这个向量。,position
和属性指的是相同的对象velocity
。 acceleration
如果您更改其中一个对象的属性,其他对象的属性似乎也会发生神奇的变化。
m1
创建和m2
对象时,为参数制作向量的副本:
class Vector2f:
def __init__(self, x, y):
self.x = x
self.y = y
def copy(self):
return Vector2f(self.x, self.y)
# [...]
m_position = Vector2f(30, 30)
m_velocity = Vector2f(0, 0)
m_acceleration = Vector2f(0, 0)
m1 = Mover(30, m_position.copy(), m_velocity.copy(), m_acceleration.copy())
m2 = Mover(5, m_position.copy(), m_velocity.copy(), m_acceleration.copy())
旁注:PyGame分别为二维和三维向量提供类pygame.math.Vector2
和。pygame.math.Vector3
推荐阅读
- google-cloud-platform - 在项目级别数据集强制执行 acl
- javascript - 使用角度删除firebase auth中的用户
- javascript - 在香草javascript中将月份名称转换为多种语言的数字
- java - setimage alapha 在 android 5.1 中不起作用
- tkinter - 如何在 Multilistbox 中隐藏一列
- reactjs - 从另一个文件夹导入反应组件
- android - Retrofit2 API 请求永远不会返回。为什么?
- javascript - “npm run build”失败并出现 SyntaxError:Unexpected token
- css - 波浪下划线在铬中表现异常
- reactjs - 如何使用 React 从其子组件单击按钮时显示一组数组