Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/01_event_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ async def main(*, sdlevent: apg.SDLEvent, **kwargs):
pygame.display.set_mode((400, 400))

while True:
e = await sdlevent.wait(pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP)
e = await sdlevent.wait(pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP, priority=0x100)
print(e)


Expand Down
6 changes: 3 additions & 3 deletions examples/03_countdown_on_gui.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pygame
import pygame.font
from pygame.colordict import THECOLORS as COLORS
from pygame.colordict import THECOLORS
import asyncpygame as apg


Expand All @@ -10,8 +10,8 @@ async def main(*, clock: apg.Clock, **kwargs):
screen = pygame.display.set_mode((400, 400))
screen_center = screen.get_rect().center
font = pygame.font.SysFont(None, 400)
fgcolor = COLORS["black"]
bgcolor = COLORS["white"]
fgcolor = THECOLORS["black"]
bgcolor = THECOLORS["white"]

count_from = 3
for i in range(count_from, -1, -1):
Expand Down
6 changes: 3 additions & 3 deletions examples/04_countdown_in_a_more_practical_way.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from functools import partial
import pygame
import pygame.font
from pygame.colordict import THECOLORS as COLORS
from pygame.colordict import THECOLORS
import asyncpygame as apg


Expand All @@ -11,10 +11,10 @@ async def main(*, clock: apg.Clock, executor: apg.PriorityExecutor, **kwargs):
screen = pygame.display.set_mode((400, 400))
screen_center = screen.get_rect().center
font = pygame.font.SysFont(None, 400)
fgcolor = COLORS["black"]
fgcolor = THECOLORS["black"]

# Functions with a lower priority will be called earlier.
executor.register(partial(screen.fill, COLORS["white"]), priority=0)
executor.register(partial(screen.fill, THECOLORS["white"]), priority=0)
req = executor.register(None, priority=0x100)
executor.register(pygame.display.flip, priority=0xFFFFFF00)

Expand Down
17 changes: 9 additions & 8 deletions examples/05_countdown_in_an_even_more_practical_way.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
from typing import Unpack
from functools import partial
import pygame
import pygame.font
from pygame.colordict import THECOLORS as COLORS
from pygame.colordict import THECOLORS
import asyncpygame as apg


async def countdown(*, count_from: int, draw_target: pygame.Surface, clock: apg.Clock, executor: apg.PriorityExecutor, priority, **kwargs):
async def countdown(*, count_from: int, draw_target: pygame.Surface, clock: apg.Clock, executor: apg.PriorityExecutor, priority, **__):
center = draw_target.get_rect().center
font = pygame.font.SysFont(None, 400)
fgcolor = COLORS["black"]
fgcolor = THECOLORS["black"]

with executor.register(None, priority=priority) as req:
with executor.register(None, priority) as req:
for i in range(count_from, -1, -1):
img = font.render(str(i), True, fgcolor).convert_alpha()
req.callback = partial(draw_target.blit, img, img.get_rect(center=center))
await clock.sleep(1000)


async def main(**kwargs):
async def main(**kwargs: Unpack[apg.CommonParams]):
pygame.init()
pygame.display.set_caption("Countdown")
screen = pygame.display.set_mode((400, 400))
kwargs["draw_target"] = screen = pygame.display.set_mode((400, 400))

r = kwargs["executor"].register
r(partial(screen.fill, COLORS["white"]), priority=0)
r(partial(screen.fill, THECOLORS["white"]), priority=0)
r(pygame.display.flip, priority=0xFFFFFF00)

await countdown(count_from=3, draw_target=screen, priority=0x100, **kwargs)
await countdown(count_from=3, priority=0x100, **kwargs)


if __name__ == "__main__":
Expand Down
45 changes: 24 additions & 21 deletions examples/06_full_blown_app_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

import pygame
import pygame.font
from pygame.colordict import THECOLORS as COLORS
from pygame.colordict import THECOLORS
import pygame.constants as C

import asyncpygame as apg
from asyncpygame.scene_switcher import SceneSwitcher, FadeTransition
from _uix.touch_indicator import touch_indicator
from _uix.anchor_layout import AnchorLayout
from _uix.ripple_button import RippleButton
from _uix.anchor_layout import anchor_layout
from _uix.ripple_button import ripple_button
from _uix.modal_dialog import ask_yes_no_question


Expand All @@ -19,7 +19,7 @@ async def main(**kwargs: Unpack[apg.CommonParams]):
pygame.display.set_caption("<Your App Title>")
kwargs["draw_target"] = screen = pygame.display.set_mode((800, 600))

bgcolor = COLORS["black"]
bgcolor = THECOLORS["black"]
r = kwargs["executor"].register
r(partial(screen.fill, bgcolor), priority=0)
r(pygame.display.flip, priority=0xFFFFFF00)
Expand Down Expand Up @@ -47,17 +47,20 @@ async def title_scene(*, scene_switcher, userdata, **kwargs: Unpack[apg.CommonPa
target_rect = draw_target.get_rect()
font = userdata['font']
async with apg.open_nursery() as nursery:
AnchorLayout(
nursery,
e_start = apg.Event()
s = nursery.start
s(anchor_layout(
font.render("<Your App Title>", True, "white", userdata["bgcolor"]).convert(draw_target),
target_rect.scale_by(1.0, 0.5).move_to(y=target_rect.y),
priority=0x100, **kwargs)
start_button = RippleButton(
nursery,
priority=0x100,
**kwargs))
s(ripple_button(
button_image := font.render("Start", True, "white").convert_alpha(),
button_image.get_rect(center=target_rect.scale_by(1.0, 0.5).move_to(bottom=target_rect.bottom).center).inflate(80, 80),
priority=0x100, **kwargs)
await start_button.to_be_clicked()
on_click=e_start.fire,
priority=0x100,
**kwargs))
await e_start.wait()
scene_switcher.switch_to(menu_scene, FadeTransition())
await apg.sleep_forever()

Expand All @@ -67,20 +70,20 @@ async def menu_scene(*, scene_switcher, userdata, **kwargs: Unpack[apg.CommonPar
target_rect = draw_target.get_rect()
font = userdata['font']
async with apg.open_nursery() as nursery:
play_button = RippleButton(
nursery,
e_play = apg.Event()
e_back = apg.Event()
s = nursery.start
s(ripple_button(
button_image := font.render("Play Game", True, "white").convert_alpha(),
button_image.get_rect(center=target_rect.scale_by(1.0, 0.5).move_to(y=target_rect.y).center).inflate(80, 80),
priority=0x100, **kwargs)
back_button = RippleButton(
nursery,
on_click=e_play.fire,
priority=0x100, **kwargs))
s(ripple_button(
button_image := font.render("Back to Title", True, "white").convert_alpha(),
button_image.get_rect(center=target_rect.scale_by(1.0, 0.5).move_to(bottom=target_rect.bottom).center).inflate(80, 80),
priority=0x100, **kwargs)
tasks = await apg.wait_any(
play_button.to_be_clicked(),
back_button.to_be_clicked(),
)
on_click=e_back.fire,
priority=0x100, **kwargs))
tasks = await apg.wait_any(e_play.wait(), e_back.wait())
next_scene = title_scene if tasks[1].finished else game_scene
scene_switcher.switch_to(next_scene, FadeTransition())
await apg.sleep_forever()
Expand Down
59 changes: 12 additions & 47 deletions examples/_uix/anchor_layout.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,30 @@
__all__ = ('AnchorLayout', )
__all__ = ('anchor_layout', )

from typing import Self
from functools import partial

from asyncgui import Nursery, sleep_forever
import asyncgui
from pygame import Surface, Rect


class AnchorLayout:
async def anchor_layout(
image: Surface, dest: Rect, priority, *, anchor_image="center", anchor_dest="center",
executor, draw_target, **__):
'''
.. code-block::

async with asyncpygame.open_nursery() as nursery:
image = Surface(...)
dest = Rect(...)
layout = AnchorLayout(nursery, image, dest, **common_params)

# Aligns the right edge of the image with the right edge of the layout.
layout.anchor_src = "right"
layout.anchor_dest = "right"

# Aligns the center of the image with the midtop of the layout.
layout.anchor_src = "center"
layout.anchor_dest = "midtop"

# You can change its image anytime.
layout.image = another_image

# You can move or resize the layout by updating the ``dest``.
dest.right = ...
dest.width = ...

# but you cannot assign another Rect instance to the layout.
layout.dest = another_rect # NOT ALLOWED
nursery.start(anchor_layout(image, dest, priority=..., **common_params))
'''
def __init__(self, owner: Nursery, image: Surface, dest: Rect,
*, anchor_src="center", anchor_dest="center", **common_params):
'''
:param owner: AnchorLayout cannot outlive its owner. When the owner is closed, the sprite is destroyed.
:param anchor_src: This must be any of the ``Rect``s positional attribute names. (e.g. "topleft", "bottomleft", ...)
:param anchor_dest: Same as ``anchor_src``.
'''
self._dest = dest
self.image = image
self.anchor_src = anchor_src
self.anchor_dest = anchor_dest
self._main_task = owner.start(self._main(**common_params), daemon=True)

def kill(self):
self._main_task.cancel()
with executor.register(partial(_draw, draw_target.blit, image, image.get_rect(), dest, anchor_image, anchor_dest), priority):
await asyncgui.sleep_forever()

@property
def dest(self) -> Rect:
return self._dest

async def _main(self, *, priority, draw_target, executor, **unused):
with executor.register(partial(self._draw, draw_target.blit, self._dest, self), priority=priority):
await sleep_forever()
def _draw(getattr, setattr, blit, image, src: Rect, dest: Rect, anchor_image, anchor_dest):
setattr(src, anchor_image, getattr(dest, anchor_dest))
blit(image, src)

def _draw(getattr, blit, dest, self: Self):
image = self.image
blit(image, image.get_rect(**{self.anchor_src: getattr(dest, self.anchor_dest)}))

_draw = partial(_draw, getattr)
_draw = partial(_draw, getattr, setattr)
Loading
Loading