Video version of the code
This commit is contained in:
		
							
								
								
									
										2
									
								
								bounce_c/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								bounce_c/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +0,0 @@ | |||||||
| *.exe |  | ||||||
| *.pdb |  | ||||||
| @@ -1,72 +0,0 @@ | |||||||
| from ctypes import POINTER, WINFUNCTYPE, byref, windll |  | ||||||
| from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, POINT |  | ||||||
| import time |  | ||||||
| import math |  | ||||||
|  |  | ||||||
| user32 = windll.user32 |  | ||||||
| gdi32 = windll.gdi32 |  | ||||||
|  |  | ||||||
| user32.GetSystemMetrics.argtypes = [INT] |  | ||||||
|  |  | ||||||
| user32.GetCursorPos.argtypes = [LPPOINT] |  | ||||||
| user32.SetCursorPos.argtypes = [INT, INT] |  | ||||||
|  |  | ||||||
| CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) |  | ||||||
|  |  | ||||||
| def get_mouse() -> tuple[int, int]: |  | ||||||
|     point = POINT() |  | ||||||
|     user32.GetCursorPos(byref(point)) |  | ||||||
|     x, y = point.x, point.y |  | ||||||
|     return x, y |  | ||||||
|  |  | ||||||
| def get_resolution() -> tuple[int, int]: |  | ||||||
|     SM_CXSCREEN = 0 |  | ||||||
|     SM_CYSCREEN = 1 |  | ||||||
|  |  | ||||||
|     return ( |  | ||||||
|         user32.GetSystemMetrics(SM_CXSCREEN), |  | ||||||
|         user32.GetSystemMetrics(SM_CYSCREEN) |  | ||||||
|     ) |  | ||||||
|  |  | ||||||
| def set_mouse(x: int, y: int): |  | ||||||
|     user32.SetCursorPos(x, y) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class MouseBody(object): |  | ||||||
|     def __init__(self): |  | ||||||
|         self._last_mouse = None |  | ||||||
|         self.velocity = 0.0 |  | ||||||
|      |  | ||||||
|     def update(self): |  | ||||||
|         mouse_x, mouse_y = get_mouse() |  | ||||||
|         if self._last_mouse: |  | ||||||
|             last_x, last_y = self._last_mouse |  | ||||||
|             dx = mouse_x - last_x |  | ||||||
|             dy = mouse_y - last_y |  | ||||||
|             dist = math.sqrt(dx * dx + dy * dy) |  | ||||||
|  |  | ||||||
|             # if they move the mouse they can fight it |  | ||||||
|             # (but they have to move it a lot) |  | ||||||
|             self.velocity *= 1.0 - min(dist / 64, 1.0) |  | ||||||
|  |  | ||||||
|         _, res_y = get_resolution() |  | ||||||
|         self.velocity += 1 |  | ||||||
|  |  | ||||||
|         new_y = int(mouse_y + self.velocity) |  | ||||||
|  |  | ||||||
|         if new_y > res_y: |  | ||||||
|             # simulate an inelastic collision |  | ||||||
|             self.velocity = -self.velocity * 0.75 |  | ||||||
|             new_y = int(new_y + self.velocity) |  | ||||||
|  |  | ||||||
|         set_mouse(mouse_x, new_y) |  | ||||||
|         self._last_mouse = (mouse_x, new_y) |  | ||||||
|  |  | ||||||
| def main(): |  | ||||||
|     body = MouseBody() |  | ||||||
|     while True: |  | ||||||
|         time.sleep(1/120.0) |  | ||||||
|         body.update() |  | ||||||
|  |  | ||||||
| if __name__ == "__main__": |  | ||||||
|     main() |  | ||||||
| @@ -2,48 +2,36 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <windows.h> | #include <windows.h> | ||||||
| #include <time.h> |  | ||||||
| 
 | 
 | ||||||
| #define MAX_WINDOWS 1024 | #define MAX_WINDOWS 1024 | ||||||
| 
 | 
 | ||||||
| // resolution
 | // == globals ==
 | ||||||
| uint32_t res_y; | uint32_t res_y; | ||||||
| void globals_init() { | void globals_update() { | ||||||
|     res_y = GetSystemMetrics(SM_CYSCREEN); |     res_y = GetSystemMetrics(SM_CYSCREEN); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // bodies
 | // == bodies ==
 | ||||||
| typedef struct body_t { | typedef struct body_t { | ||||||
|     int32_t last_x; |  | ||||||
|     int32_t last_y; |  | ||||||
|     float offset_x; |  | ||||||
|     float offset_y; |     float offset_y; | ||||||
|     float velocity; |     float velocity; | ||||||
| } body_t; | } body_t; | ||||||
| 
 | 
 | ||||||
| void body_init(body_t* body) { | void body_init(body_t* body) { | ||||||
|     body->last_x = -1; |  | ||||||
|     body->last_y = -1; |  | ||||||
|     body->offset_x = 0.5; |  | ||||||
|     body->offset_y = 0.5; |     body->offset_y = 0.5; | ||||||
|     body->velocity = 0.0; |     body->velocity = 0.0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void body_update(body_t* body, int32_t x, int32_t y, int32_t* x_new, int32_t* y_new) { | void body_update(body_t* body, int32_t *y_ptr) { | ||||||
|     if (body->last_x != -1 && body->last_y != -1) { |     int32_t y = *y_ptr; | ||||||
|         int32_t dx = x - body->last_x; |  | ||||||
|         int32_t dy = y - body->last_y; |  | ||||||
|         double dist = sqrt((double) dx * dx + dy * dy); |  | ||||||
|         body->velocity *= 1.0 - min(dist / 128, 1.0); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     float float_x = x + body->offset_x; |     float y_float = y + body->offset_y; | ||||||
|     float float_y = y + body->offset_y; | 
 | ||||||
|     for (uint8_t step = 0; step < 100; step += 1) { |     for (size_t step = 0; step < 100; step++) { | ||||||
|         body->velocity += 0.0002; |         body->velocity += 0.0002; | ||||||
|  |         y_float += body->velocity; | ||||||
| 
 | 
 | ||||||
|         float_y += body->velocity; |         if (y_float > res_y && body->velocity > 0) { | ||||||
|         if (float_y > res_y && body->velocity > 0) { |  | ||||||
|             body->velocity = -body->velocity * 0.75; |             body->velocity = -body->velocity * 0.75; | ||||||
|             if (-body->velocity < 0.05) { |             if (-body->velocity < 0.05) { | ||||||
|                 body->velocity = 0; |                 body->velocity = 0; | ||||||
| @@ -51,12 +39,9 @@ void body_update(body_t* body, int32_t x, int32_t y, int32_t* x_new, int32_t* y_ | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     *x_new = (int) float_x; |     *y_ptr = min((int) y_float, res_y); | ||||||
|     *y_new = (int) float_y; | 
 | ||||||
|     body->last_x = *x_new; |     body->offset_y = y_float - *y_ptr; | ||||||
|     body->last_y = *y_new; |  | ||||||
|     body->offset_x = float_x - *x_new; |  | ||||||
|     body->offset_y = float_y - *y_new; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // == mouse ==
 | // == mouse ==
 | ||||||
| @@ -73,9 +58,9 @@ void mouse_init() { | |||||||
| void mouse_update() { | void mouse_update() { | ||||||
|     POINT xy; |     POINT xy; | ||||||
|     GetCursorPos(&xy); |     GetCursorPos(&xy); | ||||||
|     int32_t new_x, new_y; |     int32_t x = xy.x, y = xy.y; | ||||||
|     body_update(&mouse_body.body, xy.x, xy.y, &new_x, &new_y); |     body_update(&mouse_body.body, &y); | ||||||
|     SetCursorPos(new_x, new_y); |     SetCursorPos(x, y); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // == window ==
 | // == window ==
 | ||||||
| @@ -97,12 +82,9 @@ void window_init() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOL CALLBACK window_handle_enum(HWND window, LPARAM _) { | BOOL CALLBACK window_handle_enum(HWND window, LPARAM _) { | ||||||
|     if (_n_new_windows >= MAX_WINDOWS) { |     if (_n_new_windows >= MAX_WINDOWS) { return 0; } | ||||||
|         return 0; |     if (!IsWindowVisible(window)) { return 1; } | ||||||
|     } | 
 | ||||||
|     if (!IsWindowVisible(window)) { |  | ||||||
|         return 1; |  | ||||||
|     } |  | ||||||
|     window_body_t new; |     window_body_t new; | ||||||
|     new.window = window; |     new.window = window; | ||||||
|     body_init(&new.body); |     body_init(&new.body); | ||||||
| @@ -119,7 +101,6 @@ BOOL CALLBACK window_handle_enum(HWND window, LPARAM _) { | |||||||
| void window_enumerate() { | void window_enumerate() { | ||||||
|     EnumWindows(window_handle_enum, 0); |     EnumWindows(window_handle_enum, 0); | ||||||
| 
 | 
 | ||||||
|     // do the swap
 |  | ||||||
|     window_body_t* tmp_windows = windows; |     window_body_t* tmp_windows = windows; | ||||||
| 
 | 
 | ||||||
|     n_windows = _n_new_windows; |     n_windows = _n_new_windows; | ||||||
| @@ -138,22 +119,28 @@ void window_update() { | |||||||
|         int32_t x = rect.left; |         int32_t x = rect.left; | ||||||
|         int32_t y = rect.bottom; |         int32_t y = rect.bottom; | ||||||
| 
 | 
 | ||||||
|         body_update(&windows[i].body, x, y, &x, &y); |         body_update(&windows[i].body, &y); | ||||||
| 
 | 
 | ||||||
|         int32_t height = rect.bottom - rect.top; |         int32_t height = rect.bottom - rect.top; | ||||||
|         uint32_t flags = SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_ASYNCWINDOWPOS; |         SetWindowPos( | ||||||
|         SetWindowPos(windows[i].window, 0, x, y - height, -1, -1, flags); |             windows[i].window, 0,  | ||||||
|  |             x, y - height, | ||||||
|  |             -1, -1, | ||||||
|  |             SWP_NOACTIVATE | SWP_NOSIZE | | ||||||
|  |             SWP_NOZORDER | SWP_ASYNCWINDOWPOS | ||||||
|  |         ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // == main ==
 | ||||||
| int main() { | int main() { | ||||||
|     globals_init(); |  | ||||||
| 
 |  | ||||||
|     mouse_init(); |     mouse_init(); | ||||||
|     window_init(); |     window_init(); | ||||||
| 
 | 
 | ||||||
|     while (1) { |     while (1) { | ||||||
|         // mouse_update();
 |         globals_update(); | ||||||
|  | 
 | ||||||
|  |         mouse_update(); | ||||||
|         window_update(); |         window_update(); | ||||||
| 
 | 
 | ||||||
|         Sleep(1000/120); |         Sleep(1000/120); | ||||||
							
								
								
									
										
											BIN
										
									
								
								c/bounce.exe
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								c/bounce.exe
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								c/bounce.pdb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								c/bounce.pdb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										88
									
								
								main.py.old
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								main.py.old
									
									
									
									
									
								
							| @@ -1,88 +0,0 @@ | |||||||
| from ctypes import POINTER, WINFUNCTYPE, WinError, create_unicode_buffer, get_last_error, windll |  | ||||||
| from ctypes.wintypes import BOOL, DWORD, HBRUSH, HDC, HINSTANCE, HMENU, HWND, LPARAM, LPCWSTR, LPVOID, LPWSTR, INT, RECT |  | ||||||
| import time |  | ||||||
|  |  | ||||||
| user32 = windll.user32 |  | ||||||
| gdi32 = windll.gdi32 |  | ||||||
|  |  | ||||||
| CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) |  | ||||||
|  |  | ||||||
| # thanks: https://stackoverflow.com/questions/37501191/how-to-get-windows-window-names-with-ctypes-in-python |  | ||||||
| def check_zero(result, func, args): |  | ||||||
|     if not result: |  | ||||||
|         err = get_last_error() |  | ||||||
|         if err: |  | ||||||
|             raise WinError(err) |  | ||||||
|     return args |  | ||||||
|  |  | ||||||
| user32.CreateWindowExW.argtypes = [ |  | ||||||
|     DWORD, LPCWSTR, LPCWSTR, DWORD, |  | ||||||
|     INT, INT, INT, INT,  |  | ||||||
|     HWND, HMENU, HINSTANCE, LPVOID |  | ||||||
| ] |  | ||||||
| user32.CreateWindowExW.errcheck = check_zero |  | ||||||
|  |  | ||||||
| user32.FillRect.argtypes = [HDC, POINTER(RECT), HBRUSH] |  | ||||||
|  |  | ||||||
| user32.GetWindowDC.argtypes = [HWND] |  | ||||||
| user32.GetWindowDC.errcheck = check_zero |  | ||||||
|  |  | ||||||
| user32.GetWindowTextLengthW.argtypes = [HWND] |  | ||||||
| user32.GetWindowTextLengthW.errcheck = check_zero |  | ||||||
|  |  | ||||||
| user32.GetWindowTextW.argtypes = [HWND, LPWSTR, INT] |  | ||||||
| user32.GetWindowTextW.errcheck = check_zero |  | ||||||
|  |  | ||||||
| def find_all_windows(): |  | ||||||
|     windows = [] |  | ||||||
|  |  | ||||||
|     @CB_ENUM_WINDOWS |  | ||||||
|     def _handle_window(hwnd, lparam): |  | ||||||
|         # +1: make room for the null  |  | ||||||
|         length = user32.GetWindowTextLengthW(hwnd) + 1 |  | ||||||
|         buffer = create_unicode_buffer(length) |  | ||||||
|         user32.GetWindowTextW(hwnd, buffer, length) |  | ||||||
|         windows.append((hwnd, buffer.value)) |  | ||||||
|         return True |  | ||||||
|  |  | ||||||
|     user32.EnumWindows(_handle_window, 0) |  | ||||||
|     return windows |  | ||||||
|  |  | ||||||
| def fix_window(window): |  | ||||||
|     """ |  | ||||||
|     hdc = user32.GetWindowDC(window) |  | ||||||
|     rect = RECT(0, 0, 10000, 10000) |  | ||||||
|     brush = gdi32.CreateSolidBrush(0x00FF0000) |  | ||||||
|     user32.FillRect(hdc, rect, brush) |  | ||||||
|     gdi32.DeleteObject(brush) |  | ||||||
|     print(window) |  | ||||||
|     """ |  | ||||||
|     classname = create_unicode_buffer("overlapper\x00") |  | ||||||
|     windowname = create_unicode_buffer("overlapper\x00") |  | ||||||
|     window = user32.CreateWindowExW( |  | ||||||
|         0x08000000 |  # WS_EX_NOACTIVATE |  | ||||||
|         0x8 |  # WS_EX_TOPMOST |  | ||||||
|         0x0, # 0x20,  # WS_EX_TRANSPARENT |  | ||||||
|         classname, |  | ||||||
|         windowname, |  | ||||||
|         0x10000000,  # WS_VISIBLE |  | ||||||
|         0, 0, 128, 128,  # x y w h |  | ||||||
|         None, None, |  | ||||||
|         None, None |  | ||||||
|     ) |  | ||||||
|     user32.ShowWindow(window, 5)  # SW_SHOW |  | ||||||
|  |  | ||||||
| def fix_step(): |  | ||||||
|     windows = find_all_windows() |  | ||||||
|     for window_id, window_name in windows: |  | ||||||
|         if window_name.endswith("Visual Studio Code"): |  | ||||||
|             fix_window(window_id) |  | ||||||
|  |  | ||||||
| def main(): |  | ||||||
|     fix_step() |  | ||||||
|  |  | ||||||
|     while True: |  | ||||||
|         time.sleep(1) |  | ||||||
|  |  | ||||||
| if __name__ == "__main__": |  | ||||||
|     main() |  | ||||||
| @@ -2,16 +2,14 @@ from abc import ABC, abstractmethod | |||||||
| from ctypes import WINFUNCTYPE, byref, windll | from ctypes import WINFUNCTYPE, byref, windll | ||||||
| from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, LPRECT, POINT, RECT | from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, LPRECT, POINT, RECT | ||||||
| import time | import time | ||||||
| import math |  | ||||||
| 
 | 
 | ||||||
| user32 = windll.user32 | user32 = windll.user32 | ||||||
| gdi32 = windll.gdi32 |  | ||||||
| 
 |  | ||||||
| user32.GetSystemMetrics.argtypes = [INT] |  | ||||||
| 
 | 
 | ||||||
| user32.GetCursorPos.argtypes = [LPPOINT] | user32.GetCursorPos.argtypes = [LPPOINT] | ||||||
| user32.SetCursorPos.argtypes = [INT, INT] | user32.SetCursorPos.argtypes = [INT, INT] | ||||||
| 
 | 
 | ||||||
|  | user32.GetSystemMetrics.argtypes = [INT] | ||||||
|  | 
 | ||||||
| CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) | CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) | ||||||
| 
 | 
 | ||||||
| user32.EnumWindows.argtypes = [CB_ENUM_WINDOWS, LPARAM] | user32.EnumWindows.argtypes = [CB_ENUM_WINDOWS, LPARAM] | ||||||
| @@ -20,13 +18,18 @@ user32.GetWindowRect.argtypes = [HWND, LPRECT] | |||||||
| user32.SetWindowPos.argtypes = [HWND, INT, INT, INT, INT, INT, INT] | user32.SetWindowPos.argtypes = [HWND, INT, INT, INT, INT, INT, INT] | ||||||
| user32.IsWindowVisible.argtypes = [HWND] | user32.IsWindowVisible.argtypes = [HWND] | ||||||
| 
 | 
 | ||||||
|  | def get_resolution_y() -> int: | ||||||
|  |     SM_CYSCREEN = 1 | ||||||
|  |     return user32.GetSystemMetrics(SM_CYSCREEN) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class BouncyObject(ABC): | class BouncyObject(ABC): | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     def get_position(self) -> tuple[int, int]: |     def get_position(self) -> tuple[int, int]: | ||||||
|         raise NotImplementedError |         raise NotImplementedError | ||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     def set_position(self, xy: tuple[int, int]): |     def set_position(self, xy: tuple[int, int]) -> None: | ||||||
|         raise NotImplementedError |         raise NotImplementedError | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -34,7 +37,7 @@ class Mouse(BouncyObject): | |||||||
|     def get_position(self) -> tuple[int, int]: |     def get_position(self) -> tuple[int, int]: | ||||||
|         point = POINT() |         point = POINT() | ||||||
|         user32.GetCursorPos(byref(point)) |         user32.GetCursorPos(byref(point)) | ||||||
|         return point.x, point.y  |         return point.x, point.y | ||||||
| 
 | 
 | ||||||
|     def set_position(self, xy: tuple[int, int]): |     def set_position(self, xy: tuple[int, int]): | ||||||
|         x, y = xy |         x, y = xy | ||||||
| @@ -44,95 +47,78 @@ class Mouse(BouncyObject): | |||||||
| class Window(BouncyObject): | class Window(BouncyObject): | ||||||
|     def __init__(self, handle: int): |     def __init__(self, handle: int): | ||||||
|         self._handle = handle |         self._handle = handle | ||||||
|      | 
 | ||||||
|     def get_position(self) -> tuple[int, int]: |     def get_position(self) -> tuple[int, int]: | ||||||
|         rect = RECT() |         rect = RECT() | ||||||
|         user32.GetWindowRect(self._handle, byref(rect)) |         user32.GetWindowRect(self._handle, byref(rect)) | ||||||
|         return (rect.left, rect.bottom) |         return (rect.left, rect.bottom) | ||||||
|      | 
 | ||||||
|     def set_position(self, xy: tuple[int, int]): |     def set_position(self, xy: tuple[int, int]) -> None: | ||||||
|         rect = RECT() |         rect = RECT() | ||||||
|         user32.GetWindowRect(self._handle, byref(rect)) |         user32.GetWindowRect(self._handle, byref(rect)) | ||||||
|         width = rect.right - rect.left |  | ||||||
|         height = rect.bottom - rect.top |         height = rect.bottom - rect.top | ||||||
|         x, y = xy |         x, y = xy | ||||||
|         user32.SetWindowPos( |         user32.SetWindowPos( | ||||||
|             self._handle, 0, x, y - height, -1, -1,  |             self._handle, 0, x, y - height, -1, -1, | ||||||
|             0x0010 |  # SWP_NOACTIVATE |             0x0010 |  # SWP_NOACTIVATE | ||||||
|             0x0001 |  # SWP_NOSIZE |             0x0001 |  # SWP_NOSIZE | ||||||
|             0x0004 |  # SWP_NOZORDER |             0x0004 |  # SWP_NOZORDER | ||||||
|             0x4000  # SWP_ASYNCWINDOWPOS |             0x4000    # SWP_ASYNCWINDOWPOS | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class Body(object): | ||||||
|  |     def __init__(self, controlled_object: BouncyObject): | ||||||
|  |         self._last_offset: tuple[float, float] = (0.5, 0.5) | ||||||
|  |         self._velocity = 0.0 | ||||||
|  |         self._controlled_object = controlled_object | ||||||
|  | 
 | ||||||
|  |     def update(self, res_y: int) -> None: | ||||||
|  |         x, y = self._controlled_object.get_position() | ||||||
|  |         ox, oy = self._last_offset | ||||||
|  |         x += ox | ||||||
|  |         y += oy | ||||||
|  | 
 | ||||||
|  |         for _ in range(100): | ||||||
|  |             self._velocity += 0.0002 | ||||||
|  |             y += self._velocity | ||||||
|  | 
 | ||||||
|  |             if y > res_y and self._velocity > 0: | ||||||
|  |                 self._velocity = -self._velocity * 0.75 | ||||||
|  |                 if abs(self._velocity) < 0.05: | ||||||
|  |                     self._velocity = 0 | ||||||
|  | 
 | ||||||
|  |         x_int, y_int = int(x), min(int(y), res_y) | ||||||
|  |         self._controlled_object.set_position((x_int, y_int)) | ||||||
|  |         self._last_offset = x - x_int, y - y_int | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def enumerate_windows() -> list[int]: | def enumerate_windows() -> list[int]: | ||||||
|     windows: list[int] = [] |     windows: list[int] = [] | ||||||
| 
 | 
 | ||||||
|     @CB_ENUM_WINDOWS |     @CB_ENUM_WINDOWS | ||||||
|     def _handle_window(hwnd, lparam): |     def _handle_window(hwnd: int, _lparam: int): | ||||||
|         if user32.IsWindowVisible(hwnd): |         if user32.IsWindowVisible(hwnd): | ||||||
|             windows.append(hwnd) |             windows.append(hwnd) | ||||||
|         return True |         return True | ||||||
| 
 | 
 | ||||||
|     user32.EnumWindows(_handle_window, 0) |     user32.EnumWindows(_handle_window, 0) | ||||||
|     return windows |     return windows | ||||||
|          |  | ||||||
| 
 |  | ||||||
| def get_resolution_y() -> int: |  | ||||||
|     SM_CYSCREEN = 1 |  | ||||||
|     return user32.GetSystemMetrics(SM_CYSCREEN) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class Body(object): |  | ||||||
|     def __init__(self, controlled_object: BouncyObject): |  | ||||||
|         self._last_xy: tuple[int, int] | None =None |  | ||||||
|         self._last_offset: tuple[float, float] = (0.5, 0.5) |  | ||||||
|         self._velocity = 0.0 |  | ||||||
|         self._controlled_object = controlled_object |  | ||||||
|      |  | ||||||
|     def update(self, res_y): |  | ||||||
|         x, y = self._controlled_object.get_position() |  | ||||||
|         ox, oy = self._last_offset |  | ||||||
|         x += ox |  | ||||||
|         y += oy |  | ||||||
| 
 |  | ||||||
|         if self._last_xy: |  | ||||||
|             last_x, last_y = self._last_xy |  | ||||||
|             dx = x - last_x |  | ||||||
|             dy = y - last_y |  | ||||||
|             dist = math.sqrt(dx * dx + dy * dy) |  | ||||||
| 
 |  | ||||||
|             # if they move the mouse they can fight it |  | ||||||
|             # (but they have to move it a lot) |  | ||||||
|             self._velocity *= 1.0 - min(dist / 128, 1.0) |  | ||||||
| 
 |  | ||||||
|         for _ in range(100): |  | ||||||
|             self._velocity += 0.0002 |  | ||||||
| 
 |  | ||||||
|             y += self._velocity |  | ||||||
|             if y > res_y and self._velocity > 0: |  | ||||||
|                 self._velocity = -self._velocity * 0.75 |  | ||||||
|                 if abs(self._velocity) < 0.05: |  | ||||||
|                     self._velocity = 0 |  | ||||||
| 
 |  | ||||||
|         self._controlled_object.set_position((int(x), int(y))) |  | ||||||
|         self._last_xy = (int(x), int(y)) |  | ||||||
|         self._last_offset = (x % 1, y % 1) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Bodies(object): | class Bodies(object): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         self._mouse = Body(Mouse()) |         self._mouse = Body(Mouse()) | ||||||
|         self._windows = {} |         self._windows = {} | ||||||
|      | 
 | ||||||
|     def update_list(self): |     def enumerate(self): | ||||||
|         windows2 = {} |         windows_2 = {} | ||||||
|         for i in enumerate_windows(): |         for i in enumerate_windows(): | ||||||
|             if existing := self._windows.get(i): |             if existing := self._windows.get(i): | ||||||
|                 windows2[i] = existing |                 windows_2[i] = existing | ||||||
|             else: |             else: | ||||||
|                 windows2[i] = Body(Window(i)) |                 windows_2[i] = Body(Window(i)) | ||||||
|         self._windows = windows2 |         self._windows = windows_2 | ||||||
| 
 | 
 | ||||||
|     def get(self) -> list[Body]: |     def get(self) -> list[Body]: | ||||||
|         return [self._mouse, *self._windows.values()] |         return [self._mouse, *self._windows.values()] | ||||||
| @@ -143,11 +129,13 @@ def main(): | |||||||
| 
 | 
 | ||||||
|     while True: |     while True: | ||||||
|         res_y = get_resolution_y() |         res_y = get_resolution_y() | ||||||
|         bodies.update_list() |         bodies.enumerate() | ||||||
|         print(len(bodies.get())); | 
 | ||||||
|         for b in bodies.get(): |         for b in bodies.get(): | ||||||
|             b.update(res_y) |             b.update(res_y) | ||||||
|         time.sleep(1/120.0) | 
 | ||||||
|  |         time.sleep(1.0/120.0) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     main() |     main() | ||||||
		Reference in New Issue
	
	Block a user