Я смоделировал трение в моем простом физическом движке в Python, но оно не самое лучшее. Моя проблема в том, что при определенных скоростях объект испытывает трение, замедляется и останавливается, но после остановки он продолжает колебаться взад и вперед. Я думаю, проблема в том, что скорость не уменьшается плавно, как в реальной жизни, она уменьшается с шагом в зависимости от ускорения, вызванного силой трения.
Пытаясь создать этот простой физический движок, я Я столкнулся с двумя проблемами: первая связана с границами, а вторая - с трением. Я могу решить их, но мои решения не так хороши, они неаккуратны, мое решение похоже на численные решения (оно приблизительное), но ваши решения похожи на аналитические решения (они идеальны), как мне предотвратить это?
Вот код.
import pygame as pyg
# from math import *
pyg.init()
win = pyg.display.set_mode((1500, 900))
pyg.display.set_caption('physics engine')
mainloop = True
jump = False
class Objects:
def __init__(self, x, y, vel_x, vel_y, acc_x, acc_y, mass):
self.x = x
self.y = y
self.vel_x = vel_x
self.vel_y = vel_y
self.acc_x = acc_x
self.acc_y = acc_y
self.mass = mass
circ = Objects(400, 750, 0, 0, 0, 0, 100)
rect = Objects(0, 890, 0, 0, 0, 0, 100)
F_x = 1250
F_y = 1750
coeff_fric = 0.3
friction_x = 0
friction_y = 0
g = 9.8
while mainloop:
pyg.time.delay(50)
for event in pyg.event.get():
if event.type == pyg.QUIT:
mainloop = False
keys = pyg.key.get_pressed()
if keys[pyg.K_LEFT]:
circ.acc_x = -1 * F_x / circ.mass
if keys[pyg.K_RIGHT]:
circ.acc_x = F_x / circ.mass
if keys[pyg.K_UP]:
circ.acc_y = -1 * F_y / circ.mass
if keys[pyg.K_DOWN]:
circ.acc_y = F_y / circ.mass
if keys[pyg.K_SPACE]:
circ.vel_y = 0
circ.vel_x = 0
circ.vel_y += g
circ.vel_x += circ.acc_x
circ.vel_x += circ.acc_x
circ.vel_y += circ.acc_y
circ.vel_y += circ.acc_y
win.fill((0, 0, 0))
circ.x += circ.vel_x
circ.y += circ.vel_y
if circ.x < 50 or circ.x > 1450:
circ.x = max(50, min(1450, circ.x))
circ.vel_x = 0
if circ.y < 50 or circ.y > 840:
circ.y = max(50, min(840, circ.y))
circ.vel_y = 0
F_x = 1250
F_y = 1750
circ.acc_x = 0
circ.acc_y = 0
friction_x = coeff_fric * circ.mass * g
friction_y = coeff_fric * circ.mass * g
fric_force_x = F_x - friction_x
fric_force_y = F_y - friction_y
if circ.y >= 840:
if circ.acc_x == 0:
if round(circ.vel_x) == 0:
circ.vel_x = 0
if round(circ.vel_x) > 0:
circ.acc_x = -1 * friction_x / circ.mass
circ.vel_x += circ.acc_x
if circ.vel_x < 0:
circ.vel_x = 0
circ.acc_x = 0
if round(circ.vel_x) < 0:
circ.acc_x = friction_x / circ.mass
circ.vel_x += circ.acc_x
if circ.vel_x > 0:
circ.vel_x = 0
circ.acc_x = 0
print(circ.vel_x)
objct = pyg.draw.circle(win, (50, 50, 255), (round(circ.x), round(circ.y)), 50)
floor = pyg.draw.rect(win, (150, 75, 0), (rect.x, rect.y, 1500, 10))
pyg.display.update()
pyg.quit()