Thanks to visit codestin.com
Credit goes to github.com

Skip to content
149 changes: 149 additions & 0 deletions doc/builtins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,155 @@ can use the :func:`on_music_end() hook <on_music_end>` to do something when the
music ends - for example, to pick another track at random.


.. _mouse:

Mouse
-----

The built-in mouse object can be used to get information of various current
states of the mouse in the game: where it is, what buttons are pressed,
whether it is visible and many more...

It can also be used to manipulate the mouse, for example changing its position.


.. class:: Mouse

.. attribute:: pressed

Returns a tuple of three booleans for the left, middle and right
mouse buttons in order. True means the button is currently pressed.

.. attribute:: pressed_left

Returns True if the left mouse button is currently pressed,
False else.

.. attribute:: pressed_middle

Returns True if the middle mouse button is currently pressed,
False else.

.. attribute:: pressed_right

Returns True if the right mouse button is currently pressed,
False else.

.. attribute:: pos

Returns the current position of the mouse.

Setting this will teleport the mouse to the supplied position
inside the game window.

.. attribute:: last_called_pos

Returns the position of the mouse at the time this value
was last read.

.. attribute:: recent_pos

Returns a tuple of the n last positions the mouse had moved
to starting from the most recent. Default for n is 60 and
can be changed via recent_pos_max.

.. attribute:: recent_pos_max

Returns the total number of positions tracked via recent_pos.

Increasing this value simply extends the length of the queue
of tracked positions. Decreasing it also cuts the queue to the
new maximum number of elements.

.. attribute:: rel

Returns the relative position change of the mouse over the last
frame.

.. attribute:: last_called_rel

Returns the relative position change of the mouse since this
value was last read.

.. attribute:: recent_rel

Returns a tuple of the n last position changes the mouse had,
starting from the most recent. Default for n is 60 and
can be changed via recent_rel_max.

.. attribute:: recent_rel_max

Returns the total number of position changed tracked via
recent_pos.

Increasing this value simply extends the length of the queue
of tracked positions. Decreasing it also cuts the queue to the
new maximum number of elements.

.. attribute:: visible

Returns a boolean of whether the mouse cursor is currently
visible.

Setting this to either a boolean or 0 or 1 makes the mouse
visible or invisible.

.. attribute:: focused

Returns a boolean of whether the game window is currently
focused.


Recent pos and rel
''''''''''''''''''

The ``mouse.recent_pos`` and ``mouse.recent_rel`` attributes allow
you to get the last recorded positions and relative movements from
any mouse movement event. This can be used among other things to
make visual effects of things "following" the mouse. Here is an
example that draws a trail of circles behind the mouse::

def draw():
for p in mouse.recent_pos:
screen.draw.circle(p, 5, "red")

How many events back are recorded is controlled by ``recent_pos_max``
and ``recent_rel_max``. It's important to note here that these
attributes don't record the position and relative movement for each
frame, like ``mouse.rel`` for example does, but rather the positions
and changes for each individual mouse movement event. Since multiple
mouse movement events can happen in a single frame, there is no fixed
relationship between the number of frames passed and the recorded
positions and relative changes. In general though, a higher maximum
value means positions and changes from longer before will still be
recorded.


LEFT or pressed_left
''''''''''''''''''''

While both are accessed via ``mouse``, ``mouse.LEFT`` and
``mouse.pressed_left`` are different things. ``mouse.LEFT`` is used
in your custom functions that handle mouse events, e.g.
``if button == mouse.LEFT`` whereas ``mouse.pressed`` and its variants
can be used outside of these, for example in the ``update()`` function to
check whether a mouse button is pressed at that moment.

Example::

def on_mouse_down(button):
if button == mouse.LEFT:
play_tune()

def update():
if mouse.pressed_right:
fireworks()


``mouse.WHEELUP`` and ``mouse.WHEELDOWN`` have no equivalent outside of
``on_mouse`` functions since these can't be held down.


.. _clock:

Clock
Expand Down
5 changes: 4 additions & 1 deletion src/pgzero/builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
from .animation import animate
from .rect import Rect, ZRect
from .loaders import images, sounds
from .constants import mouse, keys, keymods
# Removed the former mouse enum import
from .constants import keys, keymods
from .game import exit

# The actual screen will be installed here
from .screen import screen_instance as screen
# Make mouse globally available
from .mouse import mouse_instance as mouse


__all__ = [
Expand Down
30 changes: 29 additions & 1 deletion src/pgzero/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import pgzero.keyboard
import pgzero.screen
import pgzero.loaders
import pgzero.screen

from . import constants

Expand Down Expand Up @@ -63,6 +62,7 @@ def __init__(
self.icon = None
self.fps = fps
self.keyboard = pgzero.keyboard.keyboard
self.mouse = pgzero.mouse.mouse_instance
self.handlers = {}

def reinit_screen(self) -> bool:
Expand Down Expand Up @@ -251,6 +251,9 @@ def inject_global_handlers(self):

user_key_down = self.handlers.get(pygame.KEYDOWN)
user_key_up = self.handlers.get(pygame.KEYUP)
user_mouse_down = self.handlers.get(pygame.MOUSEBUTTONDOWN)
user_mouse_up = self.handlers.get(pygame.MOUSEBUTTONUP)
user_mouse_move = self.handlers.get(pygame.MOUSEMOTION)

def key_down(event):
if event.key == pygame.K_q and \
Expand All @@ -265,8 +268,27 @@ def key_up(event):
if user_key_up:
return user_key_up(event)

def mouse_down(event):
self.mouse._press(event.button)
if user_mouse_down:
return user_mouse_down(event)

def mouse_up(event):
self.mouse._release(event.button)
if user_mouse_up:
return user_mouse_up(event)

def mouse_move(event):
self.mouse._set_pos(event.pos)
self.mouse._add_rel(event.rel)
if user_mouse_move:
return user_mouse_move(event)

self.handlers[pygame.KEYDOWN] = key_down
self.handlers[pygame.KEYUP] = key_up
self.handlers[pygame.MOUSEBUTTONDOWN] = mouse_down
self.handlers[pygame.MOUSEBUTTONUP] = mouse_up
self.handlers[pygame.MOUSEMOTION] = mouse_move

def handle_events(self, dt, update) -> bool:
"""Handle all events for the current frame.
Expand All @@ -275,6 +297,12 @@ def handle_events(self, dt, update) -> bool:
"""
updated = False

# If no mouse movement occured, the rel state of the
# mouse is set to (0, 0). This is necessary since it
# otherwise retains the rel of the last movement
# even if the mouse hasn't been moved.
self.mouse._null_rel()

for event in pygame.event.get():
handler = self.handlers.get(event.type)
if handler:
Expand Down
Loading