Я пытаюсь заставить шар отскочить навсегда, на одной и той же высоте всегда, как это было бы, если бы энергия отскока не была потеряна.
Я не знаю почему, в зависимости от того, что я делаюсо временем подпрыгивает выше или падает при каждом прыжке.Я ожидаю, что в каждом скачке он всегда должен достигать одинаковой высоты, а не выше или ниже.
Это мой код (код написан на pyglet, но его действительно легко прочитать, даже если вы этого не сделаете)знаю библиотеку).Здесь с середины экрана выпадает квадрат, отмеченный стрелкой, и я ожидаю, что куб отскочит в полу и точно вернется к исходной высоте при возвращении:
import pyglet
class Polygon(object):
def __init__(self, vertices, color, velocity=0, acceleration=-600):
self.vertices = vertices
self.y_idx = 1
self.num_vertices = int(len(self.vertices) // 2)
self.colors = color * self.num_vertices
self.velocity = velocity
self.acceleration = acceleration
self.bottom_edge = 0
def draw(self):
self.vertex_list = pyglet.graphics.vertex_list(self.num_vertices,
("v2f", self.vertices),
("c3B", self.colors))
self.vertex_list.draw(pyglet.gl.GL_POLYGON)
def move_by_offset(self, offset):
for i in range(1, len(self.vertices), 2):
self.vertices[i] += offset # only modify y values
def bounce(self, dt):
if self.vertices[self.y_idx] < self.bottom_edge:
self.velocity = abs(self.velocity)
return True
return False
def update(self, dt):
# move
self.move_by_offset(self.velocity * dt)
# check if bounce
self.bounce(dt)
# accelerate
self.velocity += self.acceleration * dt
class GameWindow(pyglet.window.Window):
def __init__(self, objects=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.objects = objects
def update(self, dt):
for obj in self.objects:
obj.update(dt)
def on_draw(self):
self.clear()
for obj in self.objects:
obj.draw()
class Game(object):
def __init__(self, w=400, h=400, title="My game", resizable=False):
self.w = w
self.h = h
objects = [
# square
Polygon(vertices=[w/2-20, h/2, w/2-20, h/2+40, w/2+20, h/2+40, w/2+20, h/2],
color=[0, 128, 32], # green
velocity=0,
acceleration=-6000),
# arrow, marks exactly how high the square should bounce
Polygon(vertices=[w/2, h/2, w/2+40, h/2+20, w/2+30, h/2, w/2+40, h/2-20],
color=[255, 255, 0], # yellow
velocity=0,
acceleration=0)
]
self.window = GameWindow(objects, self.w, self.h, title, resizable)
def update(self, dt):
self.window.update(dt)
if __name__ == "__main__":
game = Game(resizable=False)
pyglet.clock.schedule_interval(game.update, 1/120)
pyglet.app.run()
Я пыталсяразличные порядки обновления, такие как изменение скорости в соответствии с ускорением до изменения скорости после отскока, или даже не ускорение вообще после отскока (что, кажется, работает лучше), но все же отскок не является точным и постоянно изменяет высоту:
def update2(self, dt):
# move
self.move_by_offset(self.velocity * dt)
# accelerate
self.velocity += self.acceleration * dt
# check if bounce
self.bounce(dt)
def update3(self, dt):
# move
self.move_by_offset(self.velocity * dt)
# check if bounce
bounced = self.bounce(dt)
if not bounced:
# accelerate (only if no bounce happened)
self.velocity += self.acceleration * dt
Я даже попробовал что-то более сложное: создать 2 точки, одну до и одну после отскока, и сделать 2 обновления ускорения, но это тоже не сработало.
Можете ли вы, ребята, помочь мне?Как программировать игровую физику для такого простого сценария?