pyg-engine 1.0.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. pyg_engine-1.0.0a1/LICENSE +21 -0
  2. pyg_engine-1.0.0a1/MANIFEST.in +8 -0
  3. pyg_engine-1.0.0a1/PKG-INFO +171 -0
  4. pyg_engine-1.0.0a1/README.md +132 -0
  5. pyg_engine-1.0.0a1/docs/MOUSE_INPUT_GUIDE.md +337 -0
  6. pyg_engine-1.0.0a1/docs/PHYSICS_CONTROLS_GUIDE.md +236 -0
  7. pyg_engine-1.0.0a1/docs/README.md +68 -0
  8. pyg_engine-1.0.0a1/docs/SPRITE_SYSTEM_UPGRADE.md +216 -0
  9. pyg_engine-1.0.0a1/examples/__init__.py +43 -0
  10. pyg_engine-1.0.0a1/examples/basic_example.py +66 -0
  11. pyg_engine-1.0.0a1/examples/enhanced_mouse_example.py +379 -0
  12. pyg_engine-1.0.0a1/examples/main.py +346 -0
  13. pyg_engine-1.0.0a1/examples/mouse_example.py +185 -0
  14. pyg_engine-1.0.0a1/examples/scripts/player.py +294 -0
  15. pyg_engine-1.0.0a1/pyg_engine.egg-info/PKG-INFO +171 -0
  16. pyg_engine-1.0.0a1/pyg_engine.egg-info/SOURCES.txt +51 -0
  17. pyg_engine-1.0.0a1/pyg_engine.egg-info/dependency_links.txt +1 -0
  18. pyg_engine-1.0.0a1/pyg_engine.egg-info/entry_points.txt +2 -0
  19. pyg_engine-1.0.0a1/pyg_engine.egg-info/requires.txt +8 -0
  20. pyg_engine-1.0.0a1/pyg_engine.egg-info/top_level.txt +1 -0
  21. pyg_engine-1.0.0a1/requirements.txt +2 -0
  22. pyg_engine-1.0.0a1/setup.cfg +4 -0
  23. pyg_engine-1.0.0a1/setup.py +53 -0
  24. pyg_engine-1.0.0a1/src/__init__.py +65 -0
  25. pyg_engine-1.0.0a1/src/camera.py +119 -0
  26. pyg_engine-1.0.0a1/src/cli.py +109 -0
  27. pyg_engine-1.0.0a1/src/collider.py +443 -0
  28. pyg_engine-1.0.0a1/src/collision_detector.py +157 -0
  29. pyg_engine-1.0.0a1/src/colors.py +0 -0
  30. pyg_engine-1.0.0a1/src/component.py +22 -0
  31. pyg_engine-1.0.0a1/src/engine.py +301 -0
  32. pyg_engine-1.0.0a1/src/gameobject.py +305 -0
  33. pyg_engine-1.0.0a1/src/material.py +22 -0
  34. pyg_engine-1.0.0a1/src/mouse_input.py +394 -0
  35. pyg_engine-1.0.0a1/src/object_types.py +23 -0
  36. pyg_engine-1.0.0a1/src/physics_system.py +350 -0
  37. pyg_engine-1.0.0a1/src/pymunk_collider.py +209 -0
  38. pyg_engine-1.0.0a1/src/pymunk_physics_system.py +390 -0
  39. pyg_engine-1.0.0a1/src/pymunk_rigidbody.py +273 -0
  40. pyg_engine-1.0.0a1/src/rigidbody.py +258 -0
  41. pyg_engine-1.0.0a1/src/script.py +71 -0
  42. pyg_engine-1.0.0a1/src/scriptrunner.py +50 -0
  43. pyg_engine-1.0.0a1/tests/README.md +73 -0
  44. pyg_engine-1.0.0a1/tests/test_basic_imports.py +70 -0
  45. pyg_engine-1.0.0a1/tests/test_comprehensive_rotation.py +226 -0
  46. pyg_engine-1.0.0a1/tests/test_mouse_system.py +72 -0
  47. pyg_engine-1.0.0a1/tests/test_rectangle_rotation.py +182 -0
  48. pyg_engine-1.0.0a1/tests/test_rigidbody.py +53 -0
  49. pyg_engine-1.0.0a1/tests/test_rotation_direction.py +127 -0
  50. pyg_engine-1.0.0a1/tests/test_rotation_fix.py +139 -0
  51. pyg_engine-1.0.0a1/tests/test_rotation_system.py +178 -0
  52. pyg_engine-1.0.0a1/tests/test_sprite_system.py +69 -0
  53. pyg_engine-1.0.0a1/tests/test_world_movement.py +78 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Aram Aprahamian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ include README.md
2
+ include requirements.txt
3
+ include LICENSE
4
+ recursive-include pyg_engine *.py
5
+ recursive-include examples *.py
6
+ recursive-include docs *.md
7
+ recursive-include tests *.py
8
+ recursive-include tests *.md
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyg-engine
3
+ Version: 1.0.0a1
4
+ Summary: A Python game engine with physics, rendering, and input systems
5
+ Home-page:
6
+ Author: Aram Aprahamian
7
+ Author-email:
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Topic :: Games/Entertainment
18
+ Classifier: Topic :: Multimedia :: Graphics
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.8
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: pygame>=2.5.0
24
+ Requires-Dist: pymunk>=6.4.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
27
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
28
+ Requires-Dist: black>=22.0.0; extra == "dev"
29
+ Requires-Dist: flake8>=5.0.0; extra == "dev"
30
+ Dynamic: author
31
+ Dynamic: classifier
32
+ Dynamic: description
33
+ Dynamic: description-content-type
34
+ Dynamic: license-file
35
+ Dynamic: provides-extra
36
+ Dynamic: requires-dist
37
+ Dynamic: requires-python
38
+ Dynamic: summary
39
+
40
+ # Pyg Engine
41
+
42
+ A Python game engine built with Pygame and Pymunk for 2D physics, rendering, and game development.
43
+ Inspired by the Unity game engine's Monobehavior system with scriptable game objects, rigidbody and collider system.
44
+ Built in physics materials, update system, and mouse+keyboard input system. Built-in window resizing.
45
+
46
+
47
+ > **NOTE:** This is in alpha development stage. Everything is under active development and large changes will likely be made.
48
+ > _Also,_ its pronounced _**pig engine**_ :)
49
+
50
+ ## Features
51
+
52
+ - **OOP Model**: Easy and simple game object implementation system. Create players, environment, enemies, etc. with ease
53
+ - **2D Physics**: Built-in physics via Pymunk
54
+ - **Input**: Mouse and keyboard input handling
55
+ - **Components**: Modular component-based architecture
56
+ - **Scripts**: Dynamic script loading and execution
57
+ - **Camera**: Flexible camera with multiple scaling modes
58
+ - **Collision**: Advanced collision detection and response
59
+
60
+ ## Installation
61
+
62
+ ```bash
63
+ pip install pyg-engine
64
+ ```
65
+
66
+ Or install from source:
67
+
68
+ ```bash
69
+ git clone <repository-url>
70
+ cd pyg-engine
71
+ pip install -e .
72
+ ```
73
+
74
+ ## Quick Start
75
+
76
+ ```python
77
+ from pyg_engine import Engine, GameObject, Size
78
+ from pygame import Color
79
+
80
+ # Create the engine
81
+ engine = Engine(
82
+ size=Size(w=800, h=600),
83
+ backgroundColor=Color(0, 0, 0),
84
+ windowName="My Game"
85
+ )
86
+
87
+ # Create a game object
88
+ player = GameObject(
89
+ name="Player",
90
+ position=(400, 300),
91
+ size=(50, 50),
92
+ color=Color(255, 0, 0)
93
+ )
94
+
95
+ # Add to engine
96
+ engine.addGameObject(player)
97
+
98
+ # Start the game loop
99
+ engine.start()
100
+ ```
101
+
102
+ ## Examples
103
+
104
+ Run examples directly:
105
+
106
+ ```bash
107
+ # List all available examples
108
+ python examples/__init__.py
109
+
110
+ # Run a specific example
111
+ python examples/basic_example.py
112
+ python examples/mouse_example.py
113
+ python examples/enhanced_mouse_example.py
114
+ python examples/main_physics_test.py
115
+ python examples/simple_drag_test.py
116
+ ```
117
+
118
+ Available examples:
119
+ - `basic_example.py` - Basic engine setup and object creation
120
+ - `main.py` - Complete physics demo with collision detection, mouse and keyboard input, multiple game objects, and physics materials.
121
+ - `enhanced_mouse_example.py` - Advanced mouse interactions with physics
122
+ - `mouse_example.py` - Mouse input handling and interaction
123
+
124
+ ## Documentation
125
+
126
+ See the `docs/` directory for detailed guides:
127
+
128
+ - `README.md` - General documentation
129
+ - `PHYSICS_CONTROLS_GUIDE.md` - Physics system guide
130
+ - `MOUSE_INPUT_GUIDE.md` - Input system guide
131
+ - `SPRITE_SYSTEM_UPGRADE.md` - Sprite system documentation
132
+
133
+ ## Testing
134
+
135
+ Run the test suite:
136
+
137
+ ```bash
138
+ cd pyg_engine
139
+ python -m pytest tests/
140
+ ```
141
+
142
+ ## Development
143
+
144
+ To set up the development environment:
145
+
146
+ ```bash
147
+ pip install -e .
148
+ ```
149
+
150
+ ## TODO
151
+ ##### In Development:
152
+ - State machine
153
+ - Animation system
154
+ - Sprite colliders
155
+ - Audio system
156
+ - Coroutines and async services
157
+ - More basic shapes
158
+
159
+ ##### Planned:
160
+ - Debug interface
161
+ - File storage system
162
+ - 2D lighting system
163
+
164
+
165
+ ## License
166
+
167
+ MIT License
168
+
169
+ ## Contributing
170
+
171
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,132 @@
1
+ # Pyg Engine
2
+
3
+ A Python game engine built with Pygame and Pymunk for 2D physics, rendering, and game development.
4
+ Inspired by the Unity game engine's Monobehavior system with scriptable game objects, rigidbody and collider system.
5
+ Built in physics materials, update system, and mouse+keyboard input system. Built-in window resizing.
6
+
7
+
8
+ > **NOTE:** This is in alpha development stage. Everything is under active development and large changes will likely be made.
9
+ > _Also,_ its pronounced _**pig engine**_ :)
10
+
11
+ ## Features
12
+
13
+ - **OOP Model**: Easy and simple game object implementation system. Create players, environment, enemies, etc. with ease
14
+ - **2D Physics**: Built-in physics via Pymunk
15
+ - **Input**: Mouse and keyboard input handling
16
+ - **Components**: Modular component-based architecture
17
+ - **Scripts**: Dynamic script loading and execution
18
+ - **Camera**: Flexible camera with multiple scaling modes
19
+ - **Collision**: Advanced collision detection and response
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ pip install pyg-engine
25
+ ```
26
+
27
+ Or install from source:
28
+
29
+ ```bash
30
+ git clone <repository-url>
31
+ cd pyg-engine
32
+ pip install -e .
33
+ ```
34
+
35
+ ## Quick Start
36
+
37
+ ```python
38
+ from pyg_engine import Engine, GameObject, Size
39
+ from pygame import Color
40
+
41
+ # Create the engine
42
+ engine = Engine(
43
+ size=Size(w=800, h=600),
44
+ backgroundColor=Color(0, 0, 0),
45
+ windowName="My Game"
46
+ )
47
+
48
+ # Create a game object
49
+ player = GameObject(
50
+ name="Player",
51
+ position=(400, 300),
52
+ size=(50, 50),
53
+ color=Color(255, 0, 0)
54
+ )
55
+
56
+ # Add to engine
57
+ engine.addGameObject(player)
58
+
59
+ # Start the game loop
60
+ engine.start()
61
+ ```
62
+
63
+ ## Examples
64
+
65
+ Run examples directly:
66
+
67
+ ```bash
68
+ # List all available examples
69
+ python examples/__init__.py
70
+
71
+ # Run a specific example
72
+ python examples/basic_example.py
73
+ python examples/mouse_example.py
74
+ python examples/enhanced_mouse_example.py
75
+ python examples/main_physics_test.py
76
+ python examples/simple_drag_test.py
77
+ ```
78
+
79
+ Available examples:
80
+ - `basic_example.py` - Basic engine setup and object creation
81
+ - `main.py` - Complete physics demo with collision detection, mouse and keyboard input, multiple game objects, and physics materials.
82
+ - `enhanced_mouse_example.py` - Advanced mouse interactions with physics
83
+ - `mouse_example.py` - Mouse input handling and interaction
84
+
85
+ ## Documentation
86
+
87
+ See the `docs/` directory for detailed guides:
88
+
89
+ - `README.md` - General documentation
90
+ - `PHYSICS_CONTROLS_GUIDE.md` - Physics system guide
91
+ - `MOUSE_INPUT_GUIDE.md` - Input system guide
92
+ - `SPRITE_SYSTEM_UPGRADE.md` - Sprite system documentation
93
+
94
+ ## Testing
95
+
96
+ Run the test suite:
97
+
98
+ ```bash
99
+ cd pyg_engine
100
+ python -m pytest tests/
101
+ ```
102
+
103
+ ## Development
104
+
105
+ To set up the development environment:
106
+
107
+ ```bash
108
+ pip install -e .
109
+ ```
110
+
111
+ ## TODO
112
+ ##### In Development:
113
+ - State machine
114
+ - Animation system
115
+ - Sprite colliders
116
+ - Audio system
117
+ - Coroutines and async services
118
+ - More basic shapes
119
+
120
+ ##### Planned:
121
+ - Debug interface
122
+ - File storage system
123
+ - 2D lighting system
124
+
125
+
126
+ ## License
127
+
128
+ MIT License
129
+
130
+ ## Contributing
131
+
132
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,337 @@
1
+ # Mouse Input System Guide
2
+
3
+ The mouse input system provides a comprehensive way to handle mouse interactions in your game engine. It includes support for hover detection, clicking, dragging, and mouse wheel events.
4
+
5
+ ## Features
6
+
7
+ - **Mouse Position Tracking**: Get mouse position in both screen and world coordinates
8
+ - **Button State Management**: Track mouse button presses, releases, and held states
9
+ - **Hover Detection**: Detect when mouse enters or exits object bounds
10
+ - **Click Detection**: Handle clicks on specific objects
11
+ - **Drag Detection**: Detect and handle mouse dragging with customizable thresholds
12
+ - **Mouse Wheel Support**: Handle scroll wheel events
13
+ - **Camera Integration**: Works seamlessly with the camera system for world coordinates
14
+ - **Component-Based**: Easy to add to any GameObject using components
15
+
16
+ ## Quick Start
17
+
18
+ ### Basic Usage
19
+
20
+ ```python
21
+ from mouse_input import MouseHoverComponent, MouseClickComponent, MouseButton
22
+
23
+ # Add mouse components to a GameObject
24
+ game_object.add_component(MouseHoverComponent(game_object))
25
+ game_object.add_component(MouseClickComponent(game_object))
26
+
27
+ # Set up callbacks
28
+ hover_comp = game_object.get_component(MouseHoverComponent)
29
+ click_comp = game_object.get_component(MouseClickComponent)
30
+
31
+ hover_comp.add_hover_callback(lambda event, pos, world_pos: print(f"Hover {event}"))
32
+ click_comp.add_click_callback(MouseButton.LEFT, lambda btn, pos, world_pos: print("Left clicked!"))
33
+ ```
34
+
35
+ ### Complete Example
36
+
37
+ ```python
38
+ import pygame as pg
39
+ from pygame import Color, Vector2
40
+ from engine import Engine
41
+ from gameobject import BasicObject
42
+ from object_types import Size, BasicShape
43
+ from mouse_input import MouseHoverComponent, MouseClickComponent, MouseButton
44
+
45
+ class InteractiveObject(BasicObject):
46
+ def __init__(self, name, position, size, color):
47
+ super().__init__(name, position, size, color)
48
+
49
+ # Add mouse components
50
+ self.add_component(MouseHoverComponent(self))
51
+ self.add_component(MouseClickComponent(self))
52
+
53
+ # Set up callbacks
54
+ hover_comp = self.get_component(MouseHoverComponent)
55
+ click_comp = self.get_component(MouseClickComponent)
56
+
57
+ hover_comp.add_hover_callback(self._on_hover)
58
+ click_comp.add_click_callback(MouseButton.LEFT, self._on_click)
59
+
60
+ self.original_color = color
61
+
62
+ def _on_hover(self, event_type, mouse_pos, world_pos):
63
+ if event_type == 'enter':
64
+ self.color = Color(255, 255, 0) # Yellow
65
+ elif event_type == 'exit':
66
+ self.color = self.original_color
67
+
68
+ def _on_click(self, button, mouse_pos, world_pos):
69
+ print(f"{self.name} was clicked at {mouse_pos}")
70
+
71
+ # Create engine and objects
72
+ engine = Engine(size=Size(w=800, h=600))
73
+ obj = InteractiveObject("Test", Vector2(400, 300), Vector2(100, 100), Color(255, 0, 0))
74
+ engine.addGameObject(obj)
75
+ engine.start()
76
+ ```
77
+
78
+ ## Components
79
+
80
+ ### MouseHoverComponent
81
+
82
+ Detects when the mouse enters or exits an object's bounds.
83
+
84
+ ```python
85
+ from mouse_input import MouseHoverComponent
86
+
87
+ # Add to GameObject
88
+ hover_comp = MouseHoverComponent(game_object)
89
+ game_object.add_component(hover_comp)
90
+
91
+ # Add callback
92
+ hover_comp.add_hover_callback(lambda event, pos, world_pos: print(f"Hover {event}"))
93
+
94
+ # Custom hover area (optional)
95
+ custom_area = pg.Rect(0, 0, 200, 200)
96
+ hover_comp = MouseHoverComponent(game_object, hover_area=custom_area)
97
+ ```
98
+
99
+ **Methods:**
100
+ - `add_hover_callback(callback)`: Add a callback for hover events
101
+
102
+ ### MouseClickComponent
103
+
104
+ Handles mouse clicks and drags on objects.
105
+
106
+ ```python
107
+ from mouse_input import MouseClickComponent, MouseButton
108
+
109
+ # Add to GameObject
110
+ click_comp = MouseClickComponent(game_object)
111
+ game_object.add_component(click_comp)
112
+
113
+ # Add click callbacks
114
+ click_comp.add_click_callback(MouseButton.LEFT, lambda btn, pos, world_pos: print("Left click"))
115
+ click_comp.add_click_callback(MouseButton.RIGHT, lambda btn, pos, world_pos: print("Right click"))
116
+
117
+ # Add drag callbacks
118
+ click_comp.add_drag_callback(lambda pos, world_pos, distance, direction: print(f"Dragging {distance}"))
119
+
120
+ # Custom click area (optional)
121
+ custom_area = pg.Rect(0, 0, 200, 200)
122
+ click_comp = MouseClickComponent(game_object, click_area=custom_area)
123
+ ```
124
+
125
+ **Methods:**
126
+ - `add_click_callback(button, callback)`: Add a callback for click events
127
+ - `add_drag_callback(callback)`: Add a callback for drag events
128
+
129
+ ### MouseWheelComponent
130
+
131
+ Handles mouse wheel events over objects.
132
+
133
+ ```python
134
+ from mouse_input import MouseWheelComponent
135
+
136
+ # Add to GameObject
137
+ wheel_comp = MouseWheelComponent(game_object)
138
+ game_object.add_component(wheel_comp)
139
+
140
+ # Add wheel callback
141
+ wheel_comp.add_wheel_callback(lambda delta, pos, world_pos: print(f"Wheel {delta}"))
142
+
143
+ # Custom wheel area (optional)
144
+ custom_area = pg.Rect(0, 0, 200, 200)
145
+ wheel_comp = MouseWheelComponent(game_object, wheel_area=custom_area)
146
+ ```
147
+
148
+ **Methods:**
149
+ - `add_wheel_callback(callback)`: Add a callback for wheel events
150
+
151
+ ## Mouse Button Enum
152
+
153
+ ```python
154
+ from mouse_input import MouseButton
155
+
156
+ # Available buttons
157
+ MouseButton.LEFT # Left mouse button
158
+ MouseButton.RIGHT # Right mouse button
159
+ MouseButton.MIDDLE # Middle mouse button (scroll wheel click)
160
+ ```
161
+
162
+ ## Callback Functions
163
+
164
+ ### Hover Callbacks
165
+ ```python
166
+ def hover_callback(is_entering, mouse_pos, world_pos):
167
+ """
168
+ Args:
169
+ is_entering (bool): True if mouse is entering, False if exiting
170
+ mouse_pos (Vector2): Mouse position in screen coordinates
171
+ world_pos (Vector2): Mouse position in world coordinates
172
+ """
173
+ if is_entering:
174
+ print("Mouse entered object")
175
+ else:
176
+ print("Mouse exited object")
177
+ ```
178
+
179
+ ### Click Callbacks
180
+ ```python
181
+ def click_callback(button, mouse_pos, world_pos):
182
+ """
183
+ Args:
184
+ button (MouseButton): Which button was clicked
185
+ mouse_pos (Vector2): Mouse position in screen coordinates
186
+ world_pos (Vector2): Mouse position in world coordinates
187
+ """
188
+ print(f"Clicked {button} at {mouse_pos}")
189
+ ```
190
+
191
+ ### Drag Callbacks
192
+ ```python
193
+ def drag_callback(mouse_pos, world_pos, drag_distance, drag_direction):
194
+ """
195
+ Args:
196
+ mouse_pos (Vector2): Current mouse position in screen coordinates
197
+ world_pos (Vector2): Current mouse position in world coordinates
198
+ drag_distance (float): Distance dragged from start point
199
+ drag_direction (Vector2): Normalized direction of drag
200
+ """
201
+ print(f"Dragging {drag_distance} units in direction {drag_direction}")
202
+ ```
203
+
204
+ ### Wheel Callbacks
205
+ ```python
206
+ def wheel_callback(delta, mouse_pos, world_pos):
207
+ """
208
+ Args:
209
+ delta (int): Wheel scroll amount (positive = up, negative = down)
210
+ mouse_pos (Vector2): Mouse position in screen coordinates
211
+ world_pos (Vector2): Mouse position in world coordinates
212
+ """
213
+ print(f"Wheel scrolled {delta}")
214
+ ```
215
+
216
+ ## Advanced Usage
217
+
218
+ ### Custom Areas
219
+
220
+ You can specify custom areas for mouse detection instead of using the object's bounds:
221
+
222
+ ```python
223
+ # Custom rectangular area
224
+ custom_area = pg.Rect(100, 100, 200, 150)
225
+ hover_comp = MouseHoverComponent(game_object, hover_area=custom_area)
226
+ ```
227
+
228
+ ### Multiple Components
229
+
230
+ You can add multiple mouse components to the same object:
231
+
232
+ ```python
233
+ # Add both hover and click components
234
+ game_object.add_component(MouseHoverComponent(game_object))
235
+ game_object.add_component(MouseClickComponent(game_object))
236
+ game_object.add_component(MouseWheelComponent(game_object))
237
+ ```
238
+
239
+ ### Dynamic Callbacks
240
+
241
+ You can add and remove callbacks dynamically:
242
+
243
+ ```python
244
+ hover_comp = game_object.get_component(MouseHoverComponent)
245
+
246
+ # Add callback
247
+ def my_callback(is_entering, mouse_pos, world_pos):
248
+ print("Hover event")
249
+
250
+ hover_comp.add_hover_callback(my_callback)
251
+
252
+ # Remove callback (if needed)
253
+ # Note: The system doesn't currently support callback removal
254
+ # You can modify the callback to do nothing instead
255
+ ```
256
+
257
+ ## Coordinate Systems
258
+
259
+ ### Screen Coordinates
260
+ - Origin at top-left corner of window
261
+ - X increases right, Y increases down
262
+ - Used for UI elements and screen-space calculations
263
+
264
+ ### World Coordinates
265
+ - Origin at world center (or camera position)
266
+ - Affected by camera position and zoom
267
+ - Used for game logic and physics
268
+
269
+ ### Converting Between Systems
270
+
271
+ The mouse system automatically handles coordinate conversion:
272
+
273
+ ```python
274
+ # Get mouse position in screen coordinates
275
+ screen_pos = engine.mouse_input.get_position()
276
+
277
+ # Get mouse position in world coordinates
278
+ world_pos = engine.mouse_input.get_world_position()
279
+
280
+ # Convert manually if needed
281
+ world_pos = engine.camera.screen_to_world(screen_pos)
282
+ screen_pos = engine.camera.world_to_screen(world_pos)
283
+ ```
284
+
285
+ ## Performance Considerations
286
+
287
+ ### Efficient Callbacks
288
+ Keep callback functions lightweight:
289
+
290
+ ```python
291
+ # ✅ GOOD: Lightweight callback
292
+ def hover_callback(is_entering, mouse_pos, world_pos):
293
+ self.highlighted = is_entering
294
+
295
+ # ❌ BAD: Heavy callback
296
+ def hover_callback(is_entering, mouse_pos, world_pos):
297
+ # Don't do heavy processing in callbacks
298
+ self.complex_calculation()
299
+ self.database_query()
300
+ self.network_request()
301
+ ```
302
+
303
+ ### Component Management
304
+ Remove components when not needed:
305
+
306
+ ```python
307
+ # Remove component when object is destroyed
308
+ def on_destroy(self):
309
+ if hasattr(self, 'hover_comp'):
310
+ self.hover_comp = None
311
+ ```
312
+
313
+ ## Troubleshooting
314
+
315
+ ### Common Issues
316
+
317
+ 1. **Mouse events not firing**: Check if component is enabled and object is active
318
+ 2. **Wrong coordinates**: Verify you're using the right coordinate system
319
+ 3. **Drag not working**: Check drag threshold and button state
320
+ 4. **Performance issues**: Keep callbacks lightweight
321
+
322
+ ### Debug Tips
323
+
324
+ ```python
325
+ # Print mouse state for debugging
326
+ print(f"Mouse position: {engine.mouse_input.get_position()}")
327
+ print(f"Mouse buttons: {engine.mouse_input.current_state.buttons}")
328
+ print(f"Is dragging: {engine.mouse_input.is_dragging()}")
329
+ ```
330
+
331
+ ## Best Practices
332
+
333
+ 1. **Use appropriate components**: Choose the right component for your needs
334
+ 2. **Keep callbacks simple**: Don't do heavy processing in callbacks
335
+ 3. **Handle errors**: Wrap callback logic in try-catch blocks
336
+ 4. **Test thoroughly**: Test mouse interactions with different scenarios
337
+ 5. **Consider accessibility**: Provide keyboard alternatives for mouse-only features