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.
- pyg_engine-1.0.0a1/LICENSE +21 -0
- pyg_engine-1.0.0a1/MANIFEST.in +8 -0
- pyg_engine-1.0.0a1/PKG-INFO +171 -0
- pyg_engine-1.0.0a1/README.md +132 -0
- pyg_engine-1.0.0a1/docs/MOUSE_INPUT_GUIDE.md +337 -0
- pyg_engine-1.0.0a1/docs/PHYSICS_CONTROLS_GUIDE.md +236 -0
- pyg_engine-1.0.0a1/docs/README.md +68 -0
- pyg_engine-1.0.0a1/docs/SPRITE_SYSTEM_UPGRADE.md +216 -0
- pyg_engine-1.0.0a1/examples/__init__.py +43 -0
- pyg_engine-1.0.0a1/examples/basic_example.py +66 -0
- pyg_engine-1.0.0a1/examples/enhanced_mouse_example.py +379 -0
- pyg_engine-1.0.0a1/examples/main.py +346 -0
- pyg_engine-1.0.0a1/examples/mouse_example.py +185 -0
- pyg_engine-1.0.0a1/examples/scripts/player.py +294 -0
- pyg_engine-1.0.0a1/pyg_engine.egg-info/PKG-INFO +171 -0
- pyg_engine-1.0.0a1/pyg_engine.egg-info/SOURCES.txt +51 -0
- pyg_engine-1.0.0a1/pyg_engine.egg-info/dependency_links.txt +1 -0
- pyg_engine-1.0.0a1/pyg_engine.egg-info/entry_points.txt +2 -0
- pyg_engine-1.0.0a1/pyg_engine.egg-info/requires.txt +8 -0
- pyg_engine-1.0.0a1/pyg_engine.egg-info/top_level.txt +1 -0
- pyg_engine-1.0.0a1/requirements.txt +2 -0
- pyg_engine-1.0.0a1/setup.cfg +4 -0
- pyg_engine-1.0.0a1/setup.py +53 -0
- pyg_engine-1.0.0a1/src/__init__.py +65 -0
- pyg_engine-1.0.0a1/src/camera.py +119 -0
- pyg_engine-1.0.0a1/src/cli.py +109 -0
- pyg_engine-1.0.0a1/src/collider.py +443 -0
- pyg_engine-1.0.0a1/src/collision_detector.py +157 -0
- pyg_engine-1.0.0a1/src/colors.py +0 -0
- pyg_engine-1.0.0a1/src/component.py +22 -0
- pyg_engine-1.0.0a1/src/engine.py +301 -0
- pyg_engine-1.0.0a1/src/gameobject.py +305 -0
- pyg_engine-1.0.0a1/src/material.py +22 -0
- pyg_engine-1.0.0a1/src/mouse_input.py +394 -0
- pyg_engine-1.0.0a1/src/object_types.py +23 -0
- pyg_engine-1.0.0a1/src/physics_system.py +350 -0
- pyg_engine-1.0.0a1/src/pymunk_collider.py +209 -0
- pyg_engine-1.0.0a1/src/pymunk_physics_system.py +390 -0
- pyg_engine-1.0.0a1/src/pymunk_rigidbody.py +273 -0
- pyg_engine-1.0.0a1/src/rigidbody.py +258 -0
- pyg_engine-1.0.0a1/src/script.py +71 -0
- pyg_engine-1.0.0a1/src/scriptrunner.py +50 -0
- pyg_engine-1.0.0a1/tests/README.md +73 -0
- pyg_engine-1.0.0a1/tests/test_basic_imports.py +70 -0
- pyg_engine-1.0.0a1/tests/test_comprehensive_rotation.py +226 -0
- pyg_engine-1.0.0a1/tests/test_mouse_system.py +72 -0
- pyg_engine-1.0.0a1/tests/test_rectangle_rotation.py +182 -0
- pyg_engine-1.0.0a1/tests/test_rigidbody.py +53 -0
- pyg_engine-1.0.0a1/tests/test_rotation_direction.py +127 -0
- pyg_engine-1.0.0a1/tests/test_rotation_fix.py +139 -0
- pyg_engine-1.0.0a1/tests/test_rotation_system.py +178 -0
- pyg_engine-1.0.0a1/tests/test_sprite_system.py +69 -0
- 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,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
|