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())

Leave a comment

Log in with itch.io to leave a comment.