Collision test with delta time and time step
A simple 1D collision for testing purposes
Code:
import pygame as pg
import asyncio
import random
async def main():
pg.init()
screen = pg.display.set_mode((800, 600))
ball_x, ball_y, ball_vy, ball_radius = 400, 0, 0, 10
floor_rect = pg.rect.Rect(20, 530, 760, 15)
sound = pg.mixer.Sound("impact.ogg")
modes = ["No time scaling", "Capped 85 fps", "Delta time", "Time steps"]
current_mode = "No time scaling"
buttons = []
for i, mode in enumerate(modes):
buttons.append(Button(600, 20 + i * 40, mode))
bad_framerate = 0
button_bad = Button(20, 20, "Bad framerate")
clock = pg.Clock()
bounces = 0
while 1: # game loop
screen.fill((0, 0, 0))
if bad_framerate:
pg.time.wait(random.randint(10, 50))
time_scaler = 1 / 85
if current_mode == modes[1]:
clock.tick(85)
elif current_mode in modes[2:]:
time_scaler = max(0.1, clock.tick()) / 1000
clicked = 0
pointer_pos = pg.mouse.get_pos()
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
return
if event.type == pg.MOUSEBUTTONDOWN:
clicked = 1
iterations = 1
if current_mode == modes[3]:
time_step = min(1 / 120, time_scaler)
iterations = int(round(time_scaler / time_step))
time_scaler = time_step
for i in range(iterations):
ball_vy = ball_vy + time_scaler * 980
ball_y += ball_vy * time_scaler
if floor_rect.collidepoint(ball_x, ball_y + ball_radius):
ball_y = floor_rect.top - ball_radius
ball_vy = -ball_vy * 0.8
sound.play(0)
bounces += 1
else:
bounces = 0
if bounces > 25 or ball_y > 600:
ball_y, ball_vy = 0, 0
pg.time.wait(500)
clock.tick()
for button in buttons:
if clicked and button.rect.collidepoint(pointer_pos):
current_mode = button.text
clock.tick()
pg.time.wait(16)
button.render(screen, current_mode)
if clicked and button_bad.rect.collidepoint(pointer_pos):
bad_framerate = not (bad_framerate)
button_bad.render(screen, bad_framerate * button_bad.text)
pg.draw.circle(screen, (200, 200, 200), (ball_x, ball_y), ball_radius)
pg.draw.rect(screen, (120, 80, 25), floor_rect)
pg.display.update()
await asyncio.sleep(0)
class Button:
def __init__(self, x, y, text):
font = pg.font.Font(None, 30)
self.x = x
self.y = y
self.text = text
self.texture = font.render(text, 1, (255, 255, 255))
self.rect = pg.rect.Rect(x - 5, y - 5, 190, 25)
def render(self, screen, current):
active = int(current == self.text)
pg.draw.rect(screen, (50, active * 150, 50), self.rect, border_radius=10)
screen.blit(self.texture, (self.x, self.y))
if __name__ == "__main__":
asyncio.run(main())
| Status | Released |
| Platforms | HTML5 |
| Author | FinFET channel |
Leave a comment
Log in with itch.io to leave a comment.