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.