From 8c377c0bd5242bd1520eeb37ef718189646db21b Mon Sep 17 00:00:00 2001 From: Damiano <97639432+damusss@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:31:41 +0200 Subject: [PATCH] Add main guard to examples + very small fixes --- examples/README.rst | 3 + examples/audiocapture.py | 63 ++++--- examples/font_viewer.py | 7 +- examples/go_over_there.py | 64 ++++--- examples/multiplayer_joystick.py | 212 +++++++++++---------- examples/ninepatch.py | 3 +- examples/prevent_display_stretching.py | 123 +++++++------ examples/resizing_new.py | 80 ++++---- examples/scrap_clipboard.py | 102 ++++++----- examples/setmodescale.py | 133 +++++++------- examples/sprite_texture.py | 133 +++++++------- examples/video.py | 243 +++++++++++++------------ examples/window_opengl.py | 136 +++++++------- 13 files changed, 682 insertions(+), 620 deletions(-) diff --git a/examples/README.rst b/examples/README.rst index fce9b30b90..1e38461b5d 100644 --- a/examples/README.rst +++ b/examples/README.rst @@ -78,6 +78,9 @@ music_drop_fade.py several events. Uses fade_ms added in pygame2, as well as set_endevent, set_volume, drag and drop events, and the scrap module. +ninepatch.py + Demonstrate the purpose of the 9-patch scale method and a way to implement it. + pixelarray.py Process whole arrays of pixels at a time. Like numpy, but for pixels, and also built into pygame. diff --git a/examples/audiocapture.py b/examples/audiocapture.py index 3811a20567..c4026516f9 100644 --- a/examples/audiocapture.py +++ b/examples/audiocapture.py @@ -18,14 +18,6 @@ ) from pygame._sdl2.mixer import set_post_mix - -pygame.mixer.pre_init(44100, 32, 2, 512) -pygame.init() - -# init_subsystem(INIT_AUDIO) -names = get_audio_device_names(True) -print(names) - sounds = [] sound_chunks = [] @@ -49,31 +41,42 @@ def postmix_callback(postmix, audiomemoryview): print(postmix) -set_post_mix(postmix_callback) +def main(): + pygame.mixer.pre_init(44100, 32, 2, 512) + pygame.init() -audio = AudioDevice( - devicename=names[0], - iscapture=True, - frequency=44100, - audioformat=AUDIO_F32, - numchannels=2, - chunksize=512, - allowed_changes=AUDIO_ALLOW_FORMAT_CHANGE, - callback=callback, -) -# start recording. -audio.pause(0) + # init_subsystem(INIT_AUDIO) + names = get_audio_device_names(True) + print(names) + + set_post_mix(postmix_callback) + + audio = AudioDevice( + devicename=names[0], + iscapture=True, + frequency=44100, + audioformat=AUDIO_F32, + numchannels=2, + chunksize=512, + allowed_changes=AUDIO_ALLOW_FORMAT_CHANGE, + callback=callback, + ) + # start recording. + audio.pause(0) + + print(audio) -print(audio) + print(f"recording with '{names[0]}'") + time.sleep(5) -print(f"recording with '{names[0]}'") -time.sleep(5) + print("Turning data into a pygame.mixer.Sound") + sound = pygame.mixer.Sound(buffer=b"".join(sound_chunks)) + print("playing back recorded sound") + sound.play() + time.sleep(5) + pygame.quit() -print("Turning data into a pygame.mixer.Sound") -sound = pygame.mixer.Sound(buffer=b"".join(sound_chunks)) -print("playing back recorded sound") -sound.play() -time.sleep(5) -pygame.quit() +if __name__ == "__main__": + main() diff --git a/examples/font_viewer.py b/examples/font_viewer.py index 67569e4351..3acd24c034 100644 --- a/examples/font_viewer.py +++ b/examples/font_viewer.py @@ -122,7 +122,7 @@ def render_fonts(self, text="A display of font &N"): line = text.replace("&N", name) try: surf = font.render( - line, 1, color, self.back_color, self.screen_size[0] - 20 + line, True, color, self.back_color, self.screen_size[0] - 20 ) except pygame.error as e: print(e) @@ -281,5 +281,6 @@ def handle_events(self): return True -viewer = FontViewer() -pygame.quit() +if __name__ == "__main__": + viewer = FontViewer() + pygame.quit() diff --git a/examples/go_over_there.py b/examples/go_over_there.py index 10ff3742ee..7284134190 100644 --- a/examples/go_over_there.py +++ b/examples/go_over_there.py @@ -19,10 +19,6 @@ SCREEN_SIZE = pygame.Vector2(1000, 600) CIRCLE_RADIUS = 5 -pygame.init() -screen = pygame.display.set_mode(SCREEN_SIZE) -clock = pygame.Clock() - target_position = None balls = [] @@ -49,35 +45,47 @@ def reset(): balls.append(b) -reset() -delta_time = 0 -running = True -while running: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False +def main(): + global target_position + global balls - if event.type == pygame.MOUSEBUTTONUP: - target_position = pygame.mouse.get_pos() + pygame.init() + screen = pygame.display.set_mode(SCREEN_SIZE) + clock = pygame.Clock() - if event.type == pygame.KEYUP: - if event.key == pygame.K_ESCAPE: + reset() + delta_time = 0 + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: running = False - if event.key == pygame.K_r: - reset() + if event.type == pygame.MOUSEBUTTONUP: + target_position = pygame.mouse.get_pos() + + if event.type == pygame.KEYUP: + if event.key == pygame.K_ESCAPE: + running = False - screen.fill((31, 143, 65)) + if event.key == pygame.K_r: + reset() + + screen.fill((31, 143, 65)) + + for o in balls: + if target_position is not None: + o.position.move_towards_ip(target_position, o.speed * delta_time) + pygame.draw.circle(screen, (118, 207, 145), o.position, CIRCLE_RADIUS) + + pygame.display.flip() + delta_time = clock.tick(60) + pygame.display.set_caption( + f"fps: {round(clock.get_fps(), 2)}, ball count: {len(balls)}" + ) - for o in balls: - if target_position is not None: - o.position.move_towards_ip(target_position, o.speed * delta_time) - pygame.draw.circle(screen, (118, 207, 145), o.position, CIRCLE_RADIUS) + pygame.quit() - pygame.display.flip() - delta_time = clock.tick(60) - pygame.display.set_caption( - f"fps: {round(clock.get_fps(), 2)}, ball count: {len(balls)}" - ) -pygame.quit() +if __name__ == "__main__": + main() diff --git a/examples/multiplayer_joystick.py b/examples/multiplayer_joystick.py index a95d652b6e..6c8eac7a07 100644 --- a/examples/multiplayer_joystick.py +++ b/examples/multiplayer_joystick.py @@ -1,8 +1,10 @@ import sys import pygame +WIDTH, HEIGHT = 500, 500 + -def connect_joystick(index): +def connect_joystick(index, active_players, players, colors): if len(active_players) < len(players): joy = pygame.Joystick(index) index = players.index(None) @@ -18,7 +20,7 @@ def connect_joystick(index): print(f"P{index + 1} Connected") -def disconnect_joystick(instance_id: int): +def disconnect_joystick(instance_id: int, active_players, players): index = active_players[instance_id] players[index] = None del active_players[instance_id] @@ -39,106 +41,116 @@ def create_surf(size, color): return surf -pygame.init() +def main(): + pygame.init() + + screen = pygame.display.set_mode((WIDTH, HEIGHT)) + pygame.display.set_caption("Multiplayer Joystick example") + clock = pygame.Clock() + font_b = pygame.font.SysFont(None, 25) + font_a = pygame.font.SysFont(None, 16) + + players = [None, None] # two players limit + active_players = {} + + colors = [ + create_surf((32, 32), (220, 180, 10)), + create_surf((32, 32), (60, 230, 170)), + create_surf((32, 32), (230, 20, 70)), + create_surf((32, 32), (20, 170, 230)), + ] + are_no_controllers_connected = True + + while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + elif event.type == pygame.JOYDEVICEADDED: + if len(active_players) < len(players): + # connect controller + connect_joystick( + event.device_index, active_players, players, colors + ) + are_no_controllers_connected = False + elif event.type == pygame.JOYDEVICEREMOVED: + # disconnect controller + if event.instance_id in active_players: + disconnect_joystick(event.instance_id, active_players, players) + # check if there is at least one controller connected + are_no_controllers_connected = True + for player in players: + if player: + are_no_controllers_connected = False + break + elif event.type == pygame.JOYBUTTONDOWN: + if event.instance_id in active_players: + # join player + if event.button == 0: + index = active_players[event.instance_id] + players[index]["joined"] = True + print(f"P{index + 1} joined") + # leave player + if event.button == 1: + index = active_players[event.instance_id] + if players[index]["joined"]: + players[index]["joined"] = False + players[index]["pos"] = [WIDTH * 0.25 + index * 64, 128] + print(f"P{index + 1} leave") + elif event.type == pygame.JOYAXISMOTION: + if event.instance_id in active_players: + # change the color if player still hasn't joined + if event.axis == 0: + index = active_players[event.instance_id] + player = players[index] + if not player["joined"]: + if event.value >= 1.0: + player["surf_idx"] += 1 + elif event.value <= -1.0: + player["surf_idx"] -= 1 + player["surf_idx"] = player["surf_idx"] % len(colors) + player["surf"] = colors[player["surf_idx"]] + + screen.fill((30, 30, 30)) + pygame.draw.line(screen, (230, 230, 230), (0, 96), (WIDTH, 96), 2) + + # update and draw players + for player in players: + if player: + control_player(player) + screen.blit(player["surf"], player["pos"]) + + # draw available colors + for i, surf in enumerate(colors): + screen.blit(surf, (WIDTH * 0.25 + i * 64, 32)) + + # show message for connecting a controller + if are_no_controllers_connected: + screen.blit( + font_b.render( + "Please connect a controller.", + True, + (230, 230, 230), + None, + 500 - 20, + ), + (WIDTH * 0.3, HEIGHT * 0.5), + ) -WIDTH, HEIGHT = 500, 500 -screen = pygame.display.set_mode((WIDTH, HEIGHT)) -pygame.display.set_caption("Multiplayer Joystick example") -clock = pygame.Clock() -font_b = pygame.font.SysFont(None, 25) -font_a = pygame.font.SysFont(None, 16) - -players = [None, None] # two players limit -active_players = {} - -colors = [ - create_surf((32, 32), (220, 180, 10)), - create_surf((32, 32), (60, 230, 170)), - create_surf((32, 32), (230, 20, 70)), - create_surf((32, 32), (20, 170, 230)), -] -are_no_controllers_connected = True - -while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - sys.exit() - elif event.type == pygame.JOYDEVICEADDED: - if len(active_players) < len(players): - # connect controller - connect_joystick(event.device_index) - are_no_controllers_connected = False - elif event.type == pygame.JOYDEVICEREMOVED: - # disconnect controller - if event.instance_id in active_players: - disconnect_joystick(event.instance_id) - # check if there is at least one controller connected - are_no_controllers_connected = True - for player in players: - if player: - are_no_controllers_connected = False - break - elif event.type == pygame.JOYBUTTONDOWN: - if event.instance_id in active_players: - # join player - if event.button == 0: - index = active_players[event.instance_id] - players[index]["joined"] = True - print(f"P{index + 1} joined") - # leave player - if event.button == 1: - index = active_players[event.instance_id] - if players[index]["joined"]: - players[index]["joined"] = False - players[index]["pos"] = [WIDTH * 0.25 + index * 64, 128] - print(f"P{index + 1} leave") - elif event.type == pygame.JOYAXISMOTION: - if event.instance_id in active_players: - # change the color if player still hasn't joined - if event.axis == 0: - index = active_players[event.instance_id] - player = players[index] - if not player["joined"]: - if event.value >= 1.0: - player["surf_idx"] += 1 - elif event.value <= -1.0: - player["surf_idx"] -= 1 - player["surf_idx"] = player["surf_idx"] % len(colors) - player["surf"] = colors[player["surf_idx"]] - - screen.fill((30, 30, 30)) - pygame.draw.line(screen, (230, 230, 230), (0, 96), (WIDTH, 96), 2) - - # update and draw players - for player in players: - if player: - control_player(player) - screen.blit(player["surf"], player["pos"]) - - # draw available colors - for i, surf in enumerate(colors): - screen.blit(surf, (WIDTH * 0.25 + i * 64, 32)) - - # show message for connecting a controller - if are_no_controllers_connected: screen.blit( - font_b.render( - "Please connect a controller.", True, (230, 230, 230), None, 500 - 20 + font_a.render( + "A: join B: leave Joystick: move / change color", + True, + (230, 230, 230), + None, + WIDTH - 20, ), - (WIDTH * 0.3, HEIGHT * 0.5), + (10, HEIGHT - 20), ) - screen.blit( - font_a.render( - "A: join B: leave Joystick: move / change color", - True, - (230, 230, 230), - None, - WIDTH - 20, - ), - (10, HEIGHT - 20), - ) - - clock.tick(60) - pygame.display.update() + clock.tick(60) + pygame.display.update() + + +if __name__ == "__main__": + main() diff --git a/examples/ninepatch.py b/examples/ninepatch.py index ddcfdb9220..ccdac7dc4f 100644 --- a/examples/ninepatch.py +++ b/examples/ninepatch.py @@ -17,7 +17,6 @@ import os import pygame -import typing SCREEN_SIZE = pygame.Vector2(600, 500) SCALE_SIZE = pygame.Vector2(500, 150) @@ -28,7 +27,7 @@ def ninepatch_scale( surface: pygame.Surface, - size: typing.Sequence[int], + size: pygame.typing.Point, corner_size: int, alpha: bool = True, smooth: bool = False, diff --git a/examples/prevent_display_stretching.py b/examples/prevent_display_stretching.py index 53dafafa88..35c0ad5d1f 100644 --- a/examples/prevent_display_stretching.py +++ b/examples/prevent_display_stretching.py @@ -29,64 +29,69 @@ raise NotImplementedError("this script requires Windows Vista or newer") import pygame - import ctypes -# Determine whether or not the user would like to prevent stretching -if os.path.basename(sys.executable) == "pythonw.exe": - selection = "y" -else: - selection = None - while selection not in ("y", "n"): - selection = input("Prevent stretching? (y/n): ").strip().lower() - -if selection == "y": - msg = "Stretching is prevented." -else: - msg = "Stretching is not prevented." - -# Prevent stretching -if selection == "y": - user32 = ctypes.windll.user32 - user32.SetProcessDPIAware() - -# Show screen -pygame.display.init() -RESOLUTION = (350, 350) -screen = pygame.display.set_mode(RESOLUTION) - -# Render message onto a surface -pygame.font.init() -font = pygame.Font(None, 36) -msg_surf = font.render(msg, 1, TEXTCOLOR) -res_surf = font.render("Intended resolution: %ix%i" % RESOLUTION, 1, TEXTCOLOR) - -# Control loop -running = True -clock = pygame.Clock() -counter = 0 -while running: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - - screen.fill(BACKGROUNDCOLOR) - - # Draw lines which will be blurry if the window is stretched - # or clear if the window is not stretched. - pygame.draw.line(screen, AXISCOLOR, (0, counter), (RESOLUTION[0] - 1, counter)) - pygame.draw.line(screen, AXISCOLOR, (counter, 0), (counter, RESOLUTION[1] - 1)) - - # Blit message onto screen surface - msg_blit_rect = screen.blit(msg_surf, (0, 0)) - screen.blit(res_surf, (0, msg_blit_rect.bottom)) - - clock.tick(10) - - pygame.display.flip() - - counter += 1 - if counter == RESOLUTION[0]: - counter = 0 - -pygame.quit() + +def main(): + # Determine whether or not the user would like to prevent stretching + if os.path.basename(sys.executable) == "pythonw.exe": + selection = "y" + else: + selection = None + while selection not in ("y", "n"): + selection = input("Prevent stretching? (y/n): ").strip().lower() + + if selection == "y": + msg = "Stretching is prevented." + else: + msg = "Stretching is not prevented." + + # Prevent stretching + if selection == "y": + user32 = ctypes.windll.user32 + user32.SetProcessDPIAware() + + # Show screen + pygame.display.init() + RESOLUTION = (350, 350) + screen = pygame.display.set_mode(RESOLUTION) + + # Render message onto a surface + pygame.font.init() + font = pygame.Font(None, 36) + msg_surf = font.render(msg, True, TEXTCOLOR) + res_surf = font.render("Intended resolution: %ix%i" % RESOLUTION, 1, TEXTCOLOR) + + # Control loop + running = True + clock = pygame.Clock() + counter = 0 + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + screen.fill(BACKGROUNDCOLOR) + + # Draw lines which will be blurry if the window is stretched + # or clear if the window is not stretched. + pygame.draw.line(screen, AXISCOLOR, (0, counter), (RESOLUTION[0] - 1, counter)) + pygame.draw.line(screen, AXISCOLOR, (counter, 0), (counter, RESOLUTION[1] - 1)) + + # Blit message onto screen surface + msg_blit_rect = screen.blit(msg_surf, (0, 0)) + screen.blit(res_surf, (0, msg_blit_rect.bottom)) + + clock.tick(10) + + pygame.display.flip() + + counter += 1 + if counter == RESOLUTION[0]: + counter = 0 + + pygame.quit() + + +if __name__ == "__main__": + main() diff --git a/examples/resizing_new.py b/examples/resizing_new.py index cccde5badd..48eeadf06a 100644 --- a/examples/resizing_new.py +++ b/examples/resizing_new.py @@ -1,41 +1,49 @@ #!/usr/bin/env python import pygame -pygame.init() RESOLUTION = (160, 120) FPS = 30 -clock = pygame.Clock() - -screen = pygame.display.set_mode(RESOLUTION, pygame.RESIZABLE) -pygame.display._set_autoresize(False) - -# MAIN LOOP - -done = False - -i = 0 -j = 0 - -while not done: - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN and event.key == pygame.K_q: - done = True - elif event.type == pygame.VIDEORESIZE: - screen = pygame.display.get_surface() - elif event.type == pygame.QUIT: - done = True - i += 1 - i = i % screen.get_width() - j += i % 2 - j = j % screen.get_height() - - screen.fill((255, 0, 255)) - pygame.draw.circle(screen, (0, 0, 0), (100, 100), 20) - pygame.draw.circle(screen, (0, 0, 200), (0, 0), 10) - pygame.draw.circle(screen, (200, 0, 0), (160, 120), 30) - pygame.draw.line(screen, (250, 250, 0), (0, 120), (160, 0)) - pygame.draw.circle(screen, (255, 255, 255), (i, j), 5) - - pygame.display.flip() - clock.tick(FPS) -pygame.quit() + + +def main(): + pygame.init() + + clock = pygame.Clock() + + screen = pygame.display.set_mode(RESOLUTION, pygame.RESIZABLE) + pygame.display._set_autoresize(False) + + # MAIN LOOP + + done = False + + i = 0 + j = 0 + + while not done: + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN and event.key == pygame.K_q: + done = True + elif event.type == pygame.VIDEORESIZE: + screen = pygame.display.get_surface() + elif event.type == pygame.QUIT: + done = True + i += 1 + i = i % screen.get_width() + j += i % 2 + j = j % screen.get_height() + + screen.fill((255, 0, 255)) + pygame.draw.circle(screen, (0, 0, 0), (100, 100), 20) + pygame.draw.circle(screen, (0, 0, 200), (0, 0), 10) + pygame.draw.circle(screen, (200, 0, 0), (160, 120), 30) + pygame.draw.line(screen, (250, 250, 0), (0, 120), (160, 0)) + pygame.draw.circle(screen, (255, 255, 255), (i, j), 5) + + pygame.display.flip() + clock.tick(FPS) + pygame.quit() + + +if __name__ == "__main__": + main() diff --git a/examples/scrap_clipboard.py b/examples/scrap_clipboard.py index db37250e31..f5f957c381 100644 --- a/examples/scrap_clipboard.py +++ b/examples/scrap_clipboard.py @@ -16,54 +16,58 @@ import pygame -pygame.init() -pygame.display.set_caption("Clipboard Example") -width, height = (960, 540) -screen = pygame.display.set_mode((width, height)) -clock = pygame.Clock() -font = pygame.Font(None, 30) - - -clipboard_text = "" -running = True - -while running: - screen.fill("black") - - instruction = "Keyboard Controls:\nV - View the current clipboard data.\nC - Copy some text into the clipboard.\nEscape - Quit" - text = font.render(instruction, True, "white") - screen.blit(text, (0, 0)) - - text = font.render( - f"Text on the clipboard:\n{clipboard_text}", True, "white", None, width - 20 - ) - screen.blit(text, (0, 100)) - - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - - elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_v: - # Look for any text data in the clipboard. - print("Looking for text in the clipboard.") - if pygame.scrap.has_text(): - print("Text found in the clipboard.") - clipboard_text = pygame.scrap.get_text() - else: - print("No text in the clipboard.") - - elif event.key == pygame.K_c: - # put some text into the clipboard. - print("Putting text into the clipboard.") - - pygame.scrap.put_text( - "Hello World! This is some text from the pygame scrap example.", - ) - - elif event.key == pygame.K_ESCAPE: +def main(): + pygame.init() + pygame.display.set_caption("Clipboard Example") + width, height = (960, 540) + screen = pygame.display.set_mode((width, height)) + clock = pygame.Clock() + font = pygame.Font(None, 30) + + clipboard_text = "" + running = True + + while running: + screen.fill("black") + + instruction = "Keyboard Controls:\nV - View the current clipboard data.\nC - Copy some text into the clipboard.\nEscape - Quit" + text = font.render(instruction, True, "white") + screen.blit(text, (0, 0)) + + text = font.render( + f"Text on the clipboard:\n{clipboard_text}", True, "white", None, width - 20 + ) + screen.blit(text, (0, 100)) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: running = False - pygame.display.flip() - clock.tick(60) -pygame.quit() + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_v: + # Look for any text data in the clipboard. + print("Looking for text in the clipboard.") + if pygame.scrap.has_text(): + print("Text found in the clipboard.") + clipboard_text = pygame.scrap.get_text() + else: + print("No text in the clipboard.") + + elif event.key == pygame.K_c: + # put some text into the clipboard. + print("Putting text into the clipboard.") + + pygame.scrap.put_text( + "Hello World! This is some text from the pygame scrap example.", + ) + + elif event.key == pygame.K_ESCAPE: + running = False + + pygame.display.flip() + clock.tick(60) + pygame.quit() + + +if __name__ == "__main__": + main() diff --git a/examples/setmodescale.py b/examples/setmodescale.py index 2e58f50868..b8d119da77 100644 --- a/examples/setmodescale.py +++ b/examples/setmodescale.py @@ -13,71 +13,78 @@ import pygame import sys -pygame.init() - RES = (160, 120) FPS = 30 -clock = pygame.Clock() - -print("desktops", pygame.display.get_desktop_sizes()) - -do_vsync = bool("--vsync" in sys.argv) - -if do_vsync: - screen = pygame.display.set_mode(RES, pygame.SCALED | pygame.RESIZABLE, vsync=1) -else: - screen = pygame.display.set_mode(RES, pygame.SCALED | pygame.RESIZABLE) - -# MAIN LOOP - -done = False - -i = 0 -j = 0 - -r_name, r_flags = pygame.display._get_renderer_info() -print("renderer:", r_name, "flags:", bin(r_flags)) -for flag, name in [ - (1, "software"), - (2, "accelerated"), - (4, "VSync"), - (8, "render to texture"), -]: - if flag & r_flags: - print(name) - -while not done: - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN and event.key == pygame.K_q: - done = True - if event.type == pygame.QUIT: - done = True - if event.type == pygame.KEYDOWN and event.key == pygame.K_f: - pygame.display.toggle_fullscreen() - i += 1 - i = i % screen.get_width() - j += i % 2 - j = j % screen.get_height() - - screen.fill((255, 0, 255)) - pygame.draw.circle(screen, (0, 0, 0), (100, 100), 20) - pygame.draw.circle(screen, (0, 0, 200), (0, 0), 10) - pygame.draw.circle(screen, (200, 0, 0), (160, 120), 30) - if do_vsync: - # vertical line that moves horizontally to make screen tearing obvious - pygame.draw.line(screen, (250, 250, 0), (i, 0), (i, 120)) - else: - pygame.draw.line(screen, (250, 250, 0), (0, 120), (160, 0)) - pygame.draw.circle(screen, (255, 255, 255), (i, j), 5) - pygame.display.set_caption("FPS:" + str(clock.get_fps())) + +def main(): + pygame.init() + + clock = pygame.Clock() + + print("desktops", pygame.display.get_desktop_sizes()) + + do_vsync = bool("--vsync" in sys.argv) + if do_vsync: - pygame.display.flip() - # FPS should be limited by vsync, so we tick really fast - # we only need to have the clock tick to track FPS - clock.tick() + screen = pygame.display.set_mode(RES, pygame.SCALED | pygame.RESIZABLE, vsync=1) else: - clock.tick(FPS) - pygame.display.flip() - -pygame.quit() + screen = pygame.display.set_mode(RES, pygame.SCALED | pygame.RESIZABLE) + + # MAIN LOOP + + done = False + + i = 0 + j = 0 + + r_name, r_flags = pygame.display._get_renderer_info() + print("renderer:", r_name, "flags:", bin(r_flags)) + for flag, name in [ + (1, "software"), + (2, "accelerated"), + (4, "VSync"), + (8, "render to texture"), + ]: + if flag & r_flags: + print(name) + + while not done: + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN and event.key == pygame.K_q: + done = True + if event.type == pygame.QUIT: + done = True + if event.type == pygame.KEYDOWN and event.key == pygame.K_f: + pygame.display.toggle_fullscreen() + i += 1 + i = i % screen.get_width() + j += i % 2 + j = j % screen.get_height() + + screen.fill((255, 0, 255)) + pygame.draw.circle(screen, (0, 0, 0), (100, 100), 20) + pygame.draw.circle(screen, (0, 0, 200), (0, 0), 10) + pygame.draw.circle(screen, (200, 0, 0), (160, 120), 30) + if do_vsync: + # vertical line that moves horizontally to make screen tearing obvious + pygame.draw.line(screen, (250, 250, 0), (i, 0), (i, 120)) + else: + pygame.draw.line(screen, (250, 250, 0), (0, 120), (160, 0)) + pygame.draw.circle(screen, (255, 255, 255), (i, j), 5) + + pygame.display.set_caption("FPS:" + str(clock.get_fps())) + if do_vsync: + pygame.display.flip() + # FPS should be limited by vsync, so we tick really fast + # we only need to have the clock tick to track FPS + clock.tick() + else: + clock.tick(FPS) + pygame.display.flip() + + pygame.quit() + + +if __name__ == "__main__": + main() diff --git a/examples/sprite_texture.py b/examples/sprite_texture.py index 72eb5bfd16..34539c833f 100644 --- a/examples/sprite_texture.py +++ b/examples/sprite_texture.py @@ -24,81 +24,84 @@ def load_img(file): return pygame.image.load(os.path.join(data_dir, file)) -pygame.display.init() -pygame.key.set_repeat(10, 10) +def main(): + pygame.display.init() + pygame.key.set_repeat(10, 10) -win = Window("asdf", resizable=True) -renderer = Renderer(win) -tex = Texture.from_surface(renderer, load_img("alien1.gif")) + win = Window("asdf", resizable=True) + renderer = Renderer(win) + tex = Texture.from_surface(renderer, load_img("alien1.gif")) + class Something(pygame.sprite.Sprite): + def __init__(self, img): + pygame.sprite.Sprite.__init__(self) -class Something(pygame.sprite.Sprite): - def __init__(self, img): - pygame.sprite.Sprite.__init__(self) + self.rect = img.get_rect() + self.image = img - self.rect = img.get_rect() - self.image = img + self.rect.w *= 5 + self.rect.h *= 5 - self.rect.w *= 5 - self.rect.h *= 5 + img.origin = self.rect.w / 2, self.rect.h / 2 - img.origin = self.rect.w / 2, self.rect.h / 2 + sprite = Something(Image(tex, (0, 0, tex.width / 2, tex.height / 2))) + sprite.rect.x = 250 + sprite.rect.y = 50 + # sprite2 = Something(Image(sprite.image)) + sprite2 = Something(Image(tex)) + sprite2.rect.x = 250 + sprite2.rect.y = 250 + sprite2.rect.w /= 2 + sprite2.rect.h /= 2 -sprite = Something(Image(tex, (0, 0, tex.width / 2, tex.height / 2))) -sprite.rect.x = 250 -sprite.rect.y = 50 + group = pygame.sprite.Group() + group.add(sprite2) + group.add(sprite) -# sprite2 = Something(Image(sprite.image)) -sprite2 = Something(Image(tex)) -sprite2.rect.x = 250 -sprite2.rect.y = 250 -sprite2.rect.w /= 2 -sprite2.rect.h /= 2 + import math -group = pygame.sprite.Group() -group.add(sprite2) -group.add(sprite) + t = 0 + running = True + clock = pygame.Clock() + renderer.draw_color = (255, 0, 0, 255) -import math + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE: + running = False + elif event.key == pygame.K_LEFT: + sprite.rect.x -= 5 + elif event.key == pygame.K_RIGHT: + sprite.rect.x += 5 + elif event.key == pygame.K_DOWN: + sprite.rect.y += 5 + elif event.key == pygame.K_UP: + sprite.rect.y -= 5 -t = 0 -running = True -clock = pygame.Clock() -renderer.draw_color = (255, 0, 0, 255) + renderer.clear() + t += 1 -while running: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_ESCAPE: - running = False - elif event.key == pygame.K_LEFT: - sprite.rect.x -= 5 - elif event.key == pygame.K_RIGHT: - sprite.rect.x += 5 - elif event.key == pygame.K_DOWN: - sprite.rect.y += 5 - elif event.key == pygame.K_UP: - sprite.rect.y -= 5 - - renderer.clear() - t += 1 - - img = sprite.image - img.angle += 1 - img.flip_x = t % 50 < 25 - img.flip_y = t % 100 < 50 - img.color[0] = int(255.0 * (0.5 + math.sin(0.5 * t + 10.0) / 2.0)) - img.alpha = int(255.0 * (0.5 + math.sin(0.1 * t) / 2.0)) - # img.draw(dstrect=(x, y, 5 * img.srcrect['w'], 5 * img.srcrect['h'])) - - group.draw(renderer) - - renderer.present() - - clock.tick(60) - win.title = str(f"FPS: {clock.get_fps()}") - -pygame.quit() + img = sprite.image + img.angle += 1 + img.flip_x = t % 50 < 25 + img.flip_y = t % 100 < 50 + img.color[0] = int(255.0 * (0.5 + math.sin(0.5 * t + 10.0) / 2.0)) + img.alpha = int(255.0 * (0.5 + math.sin(0.1 * t) / 2.0)) + # img.draw(dstrect=(x, y, 5 * img.srcrect['w'], 5 * img.srcrect['h'])) + + group.draw(renderer) + + renderer.present() + + clock.tick(60) + win.title = str(f"FPS: {clock.get_fps()}") + + pygame.quit() + + +if __name__ == "__main__": + main() diff --git a/examples/video.py b/examples/video.py index e4da1aded2..81b11f03dc 100644 --- a/examples/video.py +++ b/examples/video.py @@ -22,139 +22,142 @@ def load_img(file): return pygame.image.load(os.path.join(data_dir, file)) -pygame.display.init() -pygame.key.set_repeat(1000, 10) +def main(): + pygame.display.init() + pygame.key.set_repeat(1000, 10) -for driver in get_drivers(): - print(driver) + for driver in get_drivers(): + print(driver) -import random + import random -answer = pygame.display.message_box( - "I will open two windows! Continue?", - "Hello!", - message_type="info", - buttons=("Yes", "No", "Chance"), - return_button=0, - escape_button=1, -) + answer = pygame.display.message_box( + "I will open two windows! Continue?", + "Hello!", + message_type="info", + buttons=("Yes", "No", "Chance"), + return_button=0, + escape_button=1, + ) -if answer == 1 or (answer == 2 and random.random() < 0.5): - import sys + if answer == 1 or (answer == 2 and random.random() < 0.5): + import sys - sys.exit(0) + sys.exit(0) -win = Window("asdf", resizable=True) -renderer = Renderer(win) -tex = Texture.from_surface(renderer, load_img("alien1.gif")) + win = Window("asdf", resizable=True) + renderer = Renderer(win) + tex = Texture.from_surface(renderer, load_img("alien1.gif")) -running = True + running = True -x, y = 250, 50 -clock = pygame.Clock() + x, y = 250, 50 + clock = pygame.Clock() -backgrounds = [(255, 0, 0, 255), (0, 255, 0, 255), (0, 0, 255, 255)] -bg_index = 0 + backgrounds = [(255, 0, 0, 255), (0, 255, 0, 255), (0, 0, 255, 255)] + bg_index = 0 -renderer.draw_color = backgrounds[bg_index] - -win2 = Window("2nd window", size=(256, 256), always_on_top=True) -win2.opacity = 0.5 -win2.set_icon(load_img("bomb.gif")) -renderer2 = Renderer(win2) -tex2 = Texture.from_surface(renderer2, load_img("asprite.bmp")) -renderer2.clear() -tex2.draw() -renderer2.present() -del tex2 - -full = 0 + renderer.draw_color = backgrounds[bg_index] -tex = Image(tex) + win2 = Window("2nd window", size=(256, 256), always_on_top=True) + win2.opacity = 0.5 + win2.set_icon(load_img("bomb.gif")) + renderer2 = Renderer(win2) + tex2 = Texture.from_surface(renderer2, load_img("asprite.bmp")) + renderer2.clear() + tex2.draw() + renderer2.present() + del tex2 + full = 0 -surf = pygame.Surface((64, 64)) -streamtex = Texture(renderer, (64, 64), streaming=True) -tex_update_interval = 1000 -next_tex_update = pygame.time.get_ticks() + tex = Image(tex) + surf = pygame.Surface((64, 64)) + streamtex = Texture(renderer, (64, 64), streaming=True) + tex_update_interval = 1000 + next_tex_update = pygame.time.get_ticks() -while running: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - elif getattr(event, "window", None) == win2: - if ( - event.type == pygame.KEYDOWN - and event.key == pygame.K_ESCAPE - or event.type == pygame.WINDOWCLOSE - ): - win2.destroy() - elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_ESCAPE: + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: running = False - elif event.key == pygame.K_LEFT: - x -= 5 - elif event.key == pygame.K_RIGHT: - x += 5 - elif event.key == pygame.K_DOWN: - y += 5 - elif event.key == pygame.K_UP: - y -= 5 - elif event.key == pygame.K_f: - if full == 0: - win.set_fullscreen(True) - full = 1 - else: - win.set_windowed() - full = 0 - elif event.key == pygame.K_s: - readsurf = renderer.to_surface() - pygame.image.save(readsurf, "test.png") - - elif event.key == pygame.K_SPACE: - bg_index = (bg_index + 1) % len(backgrounds) - renderer.draw_color = backgrounds[bg_index] - - renderer.clear() - - # update texture - curtime = pygame.time.get_ticks() - if curtime >= next_tex_update: - for x_ in range(streamtex.width // 4): - for y_ in range(streamtex.height // 4): - newcol = ( - random.randint(0, 255), - random.randint(0, 255), - random.randint(0, 255), - 255, - ) - area = (4 * x_, 4 * y_, 4, 4) - surf.fill(newcol, area) - streamtex.update(surf) - next_tex_update = curtime + tex_update_interval - streamtex.draw(dstrect=pygame.Rect(64, 128, 64, 64)) - - tex.draw(dstrect=(x, y)) - - # TODO: should these be? - # - line instead of draw_line - # - point instead of draw_point - # - rect(rect, width=1)->draw 1 pixel, instead of draw_rect - # - rect(rect, width=0)->filled ? , instead of fill_rect - # - # TODO: should these work with pygame.draw.line(renderer, ...) functions? - renderer.draw_color = (255, 255, 255, 255) - renderer.draw_line((0, 0), (64, 64)) - renderer.draw_line((64, 64), (128, 0)) - renderer.draw_point((72, 32)) - renderer.draw_rect(pygame.Rect(0, 64, 64, 64)) - renderer.fill_rect(pygame.Rect(0, 128, 64, 64)) - renderer.draw_color = backgrounds[bg_index] - - renderer.present() - - clock.tick(60) - win.title = str(f"FPS: {clock.get_fps()}") - -pygame.quit() + elif getattr(event, "window", None) == win2: + if ( + event.type == pygame.KEYDOWN + and event.key == pygame.K_ESCAPE + or event.type == pygame.WINDOWCLOSE + ): + win2.destroy() + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE: + running = False + elif event.key == pygame.K_LEFT: + x -= 5 + elif event.key == pygame.K_RIGHT: + x += 5 + elif event.key == pygame.K_DOWN: + y += 5 + elif event.key == pygame.K_UP: + y -= 5 + elif event.key == pygame.K_f: + if full == 0: + win.set_fullscreen(True) + full = 1 + else: + win.set_windowed() + full = 0 + elif event.key == pygame.K_s: + readsurf = renderer.to_surface() + pygame.image.save(readsurf, "test.png") + + elif event.key == pygame.K_SPACE: + bg_index = (bg_index + 1) % len(backgrounds) + renderer.draw_color = backgrounds[bg_index] + + renderer.clear() + + # update texture + curtime = pygame.time.get_ticks() + if curtime >= next_tex_update: + for x_ in range(streamtex.width // 4): + for y_ in range(streamtex.height // 4): + newcol = ( + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255), + 255, + ) + area = (4 * x_, 4 * y_, 4, 4) + surf.fill(newcol, area) + streamtex.update(surf) + next_tex_update = curtime + tex_update_interval + streamtex.draw(dstrect=pygame.Rect(64, 128, 64, 64)) + + tex.draw(dstrect=(x, y)) + + # TODO: should these be? + # - line instead of draw_line + # - point instead of draw_point + # - rect(rect, width=1)->draw 1 pixel, instead of draw_rect + # - rect(rect, width=0)->filled ? , instead of fill_rect + # + # TODO: should these work with pygame.draw.line(renderer, ...) functions? + renderer.draw_color = (255, 255, 255, 255) + renderer.draw_line((0, 0), (64, 64)) + renderer.draw_line((64, 64), (128, 0)) + renderer.draw_point((72, 32)) + renderer.draw_rect(pygame.Rect(0, 64, 64, 64)) + renderer.fill_rect(pygame.Rect(0, 128, 64, 64)) + renderer.draw_color = backgrounds[bg_index] + + renderer.present() + + clock.tick(60) + win.title = str(f"FPS: {clock.get_fps()}") + + pygame.quit() + + +if __name__ == "__main__": + main() diff --git a/examples/window_opengl.py b/examples/window_opengl.py index 9f10e4b400..253e5def48 100644 --- a/examples/window_opengl.py +++ b/examples/window_opengl.py @@ -9,68 +9,74 @@ import pygame import zengl -window_size = (1280, 720) - -pygame.init() -window = pygame.Window(size=window_size, opengl=True) - -ctx = zengl.context() - -image = ctx.image(window_size, "rgba8unorm", samples=4) - -pipeline = ctx.pipeline( - vertex_shader=""" - #version 330 core - - out vec3 v_color; - - vec2 vertices[3] = vec2[]( - vec2(0.0, 0.8), - vec2(-0.6, -0.8), - vec2(0.6, -0.8) - ); - - vec3 colors[3] = vec3[]( - vec3(1.0, 0.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, 1.0) - ); - - void main() { - gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0); - v_color = colors[gl_VertexID]; - } - """, - fragment_shader=""" - #version 330 core - - in vec3 v_color; - - layout (location = 0) out vec4 out_color; - - void main() { - out_color = vec4(v_color, 1.0); - out_color.rgb = pow(out_color.rgb, vec3(1.0 / 2.2)); - } - """, - framebuffer=[image], - topology="triangles", - vertex_count=3, -) - -clock = pygame.Clock() - -while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - quit() - - ctx.new_frame() - image.clear() - pipeline.render() - image.blit() - ctx.end_frame() - - window.flip() - clock.tick(60) + +def main(): + window_size = (1280, 720) + + pygame.init() + window = pygame.Window(size=window_size, opengl=True) + + ctx = zengl.context() + + image = ctx.image(window_size, "rgba8unorm", samples=4) + + pipeline = ctx.pipeline( + vertex_shader=""" + #version 330 core + + out vec3 v_color; + + vec2 vertices[3] = vec2[]( + vec2(0.0, 0.8), + vec2(-0.6, -0.8), + vec2(0.6, -0.8) + ); + + vec3 colors[3] = vec3[]( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) + ); + + void main() { + gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0); + v_color = colors[gl_VertexID]; + } + """, + fragment_shader=""" + #version 330 core + + in vec3 v_color; + + layout (location = 0) out vec4 out_color; + + void main() { + out_color = vec4(v_color, 1.0); + out_color.rgb = pow(out_color.rgb, vec3(1.0 / 2.2)); + } + """, + framebuffer=[image], + topology="triangles", + vertex_count=3, + ) + + clock = pygame.Clock() + + while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + quit() + + ctx.new_frame() + image.clear() + pipeline.render() + image.blit() + ctx.end_frame() + + window.flip() + clock.tick(60) + + +if __name__ == "__main__": + main()