72 lines
1.7 KiB
Python
72 lines
1.7 KiB
Python
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() |