|
1 | 1 | # Arcade Screen Saver Framework
|
2 | 2 |
|
3 |
| -A very simple Python framework for making screen savers for Windows. Uses the [Arcade](https://github.com/pythonarcade/arcade) library. |
| 3 | +A very simple Python framework for making screen savers for Windows. Uses the [Arcade](https://github.com/pythonarcade/arcade) 2D video game library. |
4 | 4 |
|
| 5 | +Most Arcade applications that use the class-centric Arcade API (ex: derive a window from `arcade.Window`) can be made into a Windows screen saver. |
| 6 | +Usually, it is as simple as adding the framework import to your existing application and creating your window with `window = screensaver_framework.create_saver_win(MyGameClass)` |
| 7 | + |
| 8 | +This framework provides your app: |
| 9 | +* What it needs to interface with Windows so your Arcade application is seen as an official Windows screen saver. |
| 10 | +* Input event handling to automatically exit the application when any keyboard or mouse input is detected. |
| 11 | +* Handling of multi-monitor setups (draws screen saver on largest screen) |
| 12 | +* An included installation script that takes your Arcade application and: |
| 13 | + * Bundles it into a one-file executable (via PyInstaller) necessary for Windows screen savers |
| 14 | + * Installs the bundle in the appropriate place with the appropriate name so that Windows can find it. |
5 | 15 |
|
6 |
| -# Install and manually run screen saver example |
| 16 | +# Quick start |
7 | 17 |
|
8 |
| - # From root of repo checkout... |
9 |
| - py -3 -m venv venv |
10 |
| - venv\Scripts\activate |
11 |
| - pip install -e . |
12 |
| - python -m arcade_screensaver_framework.examples.minimal_saver |
13 |
| - python -m arcade_screensaver_framework.examples.flying_lines |
14 |
| - python -m arcade_screensaver_framework.examples.oval_screensaver |
15 |
| - python -m arcade_screensaver_framework.examples.raindrops |
16 |
| - |
17 |
| - # add "/s" to any screen saver to launch it in fullscreen mode |
| 18 | +Install framework: |
| 19 | + |
| 20 | + pip install git+https://github.com/SirGnip/arcade_screensaver_framework |
| 21 | + |
| 22 | +Manually run screen saver examples (`/s` runs app in fullscreen) |
| 23 | + |
| 24 | + python -m arcade_screensaver_framework.examples.minimal_saver /s |
18 | 25 | python -m arcade_screensaver_framework.examples.flying_lines /s
|
| 26 | + python -m arcade_screensaver_framework.examples.oval_screensaver /s |
| 27 | + python -m arcade_screensaver_framework.examples.raindrops /s |
| 28 | + |
| 29 | +Create a fully functional Windows screen saver by installing one of the provided example screen savers. |
| 30 | +Must run this command from a Command Prompt that was opened with "Run as administrator". |
| 31 | + |
| 32 | + # The example scripts are often located in a path similar to the following. |
| 33 | + # Your actual path may vary... |
| 34 | + |
| 35 | + install_screensaver venv\Lib\site-packages\arcade_screensaver_framework\examples\minimal_saver.py |
| 36 | + |
| 37 | +After installation, you need to go into Window's "Screen Saver Settings" dialog and |
| 38 | +select your newly installed screen saver. Click the "Preview" button on the dialog |
| 39 | +and you should see your screen saver appear after a couple seconds. |
| 40 | + |
| 41 | +*Note: The "Screen Saver Settings" dialog will feel very sluggish while your have a custom |
| 42 | +screen saver selected. This is because Windows is running the screen saver application |
| 43 | +in the background as you click through the options in the dialog. Each run of the |
| 44 | +application takes a couple seconds to complete.* |
19 | 45 |
|
| 46 | +# Write your own screen saver |
20 | 47 |
|
21 |
| -# How to install your screen saver to Windows |
| 48 | +Install framework: |
22 | 49 |
|
23 |
| - # cd into repo's top directory (not src\!) |
24 |
| - cd <MY_REPO> |
| 50 | + pip install git+https://github.com/SirGnip/arcade_screensaver_framework |
| 51 | + |
| 52 | +Save the following script as "my_test.py" |
| 53 | + |
| 54 | + import arcade |
| 55 | + from arcade_screensaver_framework import screensaver_framework |
| 56 | + |
| 57 | + class MinimalSaver(arcade.Window): |
| 58 | + def __init__(self, *args, **kwargs): |
| 59 | + super().__init__(*args, **kwargs) |
| 60 | + self.x = 0 |
| 61 | + |
| 62 | + def on_draw(self): |
| 63 | + self.x = (self.x + 10) % self.get_size()[0] |
| 64 | + arcade.start_render() |
| 65 | + arcade.draw_rectangle_filled(self.x, self.get_size()[1] / 2, 200, 200, arcade.color.BLUE) |
| 66 | + |
| 67 | + if __name__ == "__main__": |
| 68 | + screensaver_framework.create_screensaver_window(MinimalSaver) |
| 69 | + arcade.run() |
| 70 | + |
| 71 | +Run script manually to test (notice how it exists when you cause any input events): |
| 72 | + |
| 73 | + python my_test.py /s |
25 | 74 |
|
26 |
| - # Open a Windows Command Prompt with "Run as administrator" and |
27 |
| - # run this command... |
28 |
| - install_screensaver src\arcade_screensaver_framework\examples\minimal_saver.py |
| 75 | +Open a Command Prompt terminal with "Run as administrator", make sure the proper Python environment is active and then run: |
| 76 | + |
| 77 | + install_screensaver my_test.py |
| 78 | + |
| 79 | +As the `arcade_screensaver_framework` handles input events, your code shouldn't have any `on_keyboard_press`, `on_mouse_press`, `on_mouse_motion` event handlers. |
| 80 | + |
| 81 | +# Technical reference |
| 82 | + |
| 83 | +## What is required in a screen saver |
| 84 | + |
| 85 | +To write an Arcade script that can be used as a screen saver, just a few things need to be done. |
| 86 | +Refer to the `my_test.py` example above for a concrete illustration of the points below. |
| 87 | + |
| 88 | +First, import the module at the top of your script: |
| 89 | + |
| 90 | + from arcade_screensaver_framework import screensaver_framework |
29 | 91 |
|
30 |
| - # Once complete, open up the "Screen Saver Settings" Windows dialog and |
31 |
| - # choose your screensaver from the dropdown list. |
| 92 | +Second, the window class for your app must derive from `arcade.Window`: |
| 93 | + |
| 94 | + class MyWindow(arcade.Window): |
| 95 | + |
| 96 | +Third, write an `__init__` method for the `Window` class that accepts `*args` and `**kwargs` |
| 97 | +and pass them to the `super()` class. This is required to allow the `arcade_screensaver_framework` |
| 98 | +to pass a couple arguments into the `__init__` method: |
| 99 | + |
| 100 | + def __init__(self, *args, **kwargs): |
| 101 | + super().__init__(*args, **kwargs) |
| 102 | + self.x = 0 |
| 103 | + |
| 104 | +Fourth, instead of creating the Arcade window with the typical `win = MyWindow()`, you need to |
| 105 | +use the `arcade_screensaver_framework` to create the window for you: |
| 106 | + |
| 107 | + win = screensaver_framework.create_screensaver_window(MyWindow) |
| 108 | + arcade.run() |
| 109 | + |
| 110 | +## Details: |
| 111 | + |
| 112 | +### Input Events |
| 113 | + |
| 114 | + The framework handles closing the application when receiving input. So, do not |
| 115 | +try to provide input event handlers like `on_mouse_motion` or `on_keyboard_press` |
| 116 | +as these could interfere with arcade_screensaver_framework's operation. |
| 117 | + |
| 118 | +### Resolution selection |
| 119 | +When the screensaver is run in fullscreen mode, the framework chooses the most |
| 120 | +appropriate screen resolution. This way, your application can run on computers |
| 121 | +with screens of any size. This means your screen saver should query the size of |
| 122 | +the screen when it starts with a function like `.get_size()` and adjust to the |
| 123 | +height and width dynamically. |
| 124 | + |
| 125 | +### Parameters for `create_screensaver_window()` |
| 126 | + |
| 127 | + create_screensaver_window(WINDOW_CLASS, **kwargs) |
32 | 128 |
|
33 |
| - # Note: The "Screen Saver Settings" dialog will feel very sluggish when your custom |
34 |
| - # screen saver is selected. This is because Windows is running the screen saver application |
35 |
| - # in the background as you click through the options in the dialog. Each run of the |
36 |
| - # application takes a couple seconds to complete. |
| 129 | +- first parameter: the class of the Window that runs your screen saver |
| 130 | +- second parameter (optional): can specify keyword arguments that will be passed to the |
| 131 | +`Windows` constructor |
37 | 132 |
|
38 | 133 | 
|
0 commit comments