pygameP 0.0.1__py3-none-any.whl
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.
- pygameP/__init__.py +36 -0
- pygameP/input.py +548 -0
- pygameP/performance.py +382 -0
- pygameP/physics.py +548 -0
- pygameP/scene.py +445 -0
- pygameP/shaders.py +351 -0
- pygamep-0.0.1.dist-info/METADATA +405 -0
- pygamep-0.0.1.dist-info/RECORD +11 -0
- pygamep-0.0.1.dist-info/WHEEL +5 -0
- pygamep-0.0.1.dist-info/licenses/LICENSE +21 -0
- pygamep-0.0.1.dist-info/top_level.txt +1 -0
pygameP/__init__.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""pygameP - Pygame Plus 高级游戏开发框架"""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.0.1"
|
|
4
|
+
__author__ = "pygameP contributors"
|
|
5
|
+
|
|
6
|
+
from .shaders import Shader, ShaderEffect, BuiltInEffects
|
|
7
|
+
from .performance import ObjectPool, SpatialHash, FPSMonitor, BatchRenderer
|
|
8
|
+
from .scene import Scene, SceneManager, SceneEntity
|
|
9
|
+
from .physics import RigidBody, PhysicsWorld, Collider, BoxCollider, CircleCollider
|
|
10
|
+
from .input import InputManager, GamepadHandler, TouchHandler
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
# Shaders
|
|
14
|
+
"Shader",
|
|
15
|
+
"ShaderEffect",
|
|
16
|
+
"BuiltInEffects",
|
|
17
|
+
# Performance
|
|
18
|
+
"ObjectPool",
|
|
19
|
+
"SpatialHash",
|
|
20
|
+
"FPSMonitor",
|
|
21
|
+
"BatchRenderer",
|
|
22
|
+
# Scene
|
|
23
|
+
"Scene",
|
|
24
|
+
"SceneManager",
|
|
25
|
+
"SceneEntity",
|
|
26
|
+
# Physics
|
|
27
|
+
"RigidBody",
|
|
28
|
+
"PhysicsWorld",
|
|
29
|
+
"Collider",
|
|
30
|
+
"BoxCollider",
|
|
31
|
+
"CircleCollider",
|
|
32
|
+
# Input
|
|
33
|
+
"InputManager",
|
|
34
|
+
"GamepadHandler",
|
|
35
|
+
"TouchHandler",
|
|
36
|
+
]
|
pygameP/input.py
ADDED
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
"""扩展输入设备支持模块"""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, List, Optional, Tuple, Callable, Any
|
|
4
|
+
import pygame
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class InputManager:
|
|
8
|
+
"""输入管理器 - 统一管理所有输入设备
|
|
9
|
+
|
|
10
|
+
支持键盘、鼠标、手柄、触摸等多种输入方式。
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self):
|
|
14
|
+
"""初始化输入管理器"""
|
|
15
|
+
self.keyboard = KeyboardHandler()
|
|
16
|
+
self.mouse = MouseHandler()
|
|
17
|
+
self.gamepads: Dict[int, GamepadHandler] = {}
|
|
18
|
+
self.touch = TouchHandler()
|
|
19
|
+
|
|
20
|
+
# 输入映射
|
|
21
|
+
self.action_mappings: Dict[str, List[Tuple[str, Any]]] = {}
|
|
22
|
+
|
|
23
|
+
# 初始化手柄
|
|
24
|
+
self._init_gamepads()
|
|
25
|
+
|
|
26
|
+
def _init_gamepads(self):
|
|
27
|
+
"""初始化手柄设备"""
|
|
28
|
+
pygame.joystick.init()
|
|
29
|
+
for i in range(pygame.joystick.get_count()):
|
|
30
|
+
joystick = pygame.joystick.Joystick(i)
|
|
31
|
+
joystick.init()
|
|
32
|
+
self.gamepads[i] = GamepadHandler(joystick)
|
|
33
|
+
|
|
34
|
+
def update(self, events: List[pygame.event.Event]):
|
|
35
|
+
"""更新所有输入设备状态
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
events: pygame 事件列表
|
|
39
|
+
"""
|
|
40
|
+
self.keyboard.update(events)
|
|
41
|
+
self.mouse.update(events)
|
|
42
|
+
self.touch.update(events)
|
|
43
|
+
|
|
44
|
+
for gamepad in self.gamepads.values():
|
|
45
|
+
gamepad.update(events)
|
|
46
|
+
|
|
47
|
+
def is_action_pressed(self, action: str) -> bool:
|
|
48
|
+
"""检查动作是否被按下
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
action: 动作名称
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
是否按下
|
|
55
|
+
"""
|
|
56
|
+
if action not in self.action_mappings:
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
for device, binding in self.action_mappings[action]:
|
|
60
|
+
if device == 'keyboard' and self.keyboard.is_key_pressed(binding):
|
|
61
|
+
return True
|
|
62
|
+
elif device == 'mouse' and self.mouse.is_button_pressed(binding):
|
|
63
|
+
return True
|
|
64
|
+
elif device == 'gamepad':
|
|
65
|
+
pad_id, button = binding
|
|
66
|
+
if pad_id in self.gamepads:
|
|
67
|
+
return self.gamepads[pad_id].is_button_pressed(button)
|
|
68
|
+
|
|
69
|
+
return False
|
|
70
|
+
|
|
71
|
+
def is_action_just_pressed(self, action: str) -> bool:
|
|
72
|
+
"""检查动作是否刚刚被按下
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
action: 动作名称
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
是否刚刚按下
|
|
79
|
+
"""
|
|
80
|
+
if action not in self.action_mappings:
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
for device, binding in self.action_mappings[action]:
|
|
84
|
+
if device == 'keyboard' and self.keyboard.is_key_just_pressed(binding):
|
|
85
|
+
return True
|
|
86
|
+
elif device == 'mouse' and self.mouse.is_button_just_pressed(binding):
|
|
87
|
+
return True
|
|
88
|
+
elif device == 'gamepad':
|
|
89
|
+
pad_id, button = binding
|
|
90
|
+
if pad_id in self.gamepads:
|
|
91
|
+
return self.gamepads[pad_id].is_button_just_pressed(button)
|
|
92
|
+
|
|
93
|
+
return False
|
|
94
|
+
|
|
95
|
+
def is_action_just_released(self, action: str) -> bool:
|
|
96
|
+
"""检查动作是否刚刚被释放
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
action: 动作名称
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
是否刚刚释放
|
|
103
|
+
"""
|
|
104
|
+
if action not in self.action_mappings:
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
for device, binding in self.action_mappings[action]:
|
|
108
|
+
if device == 'keyboard' and self.keyboard.is_key_just_released(binding):
|
|
109
|
+
return True
|
|
110
|
+
elif device == 'mouse' and self.mouse.is_button_just_released(binding):
|
|
111
|
+
return True
|
|
112
|
+
elif device == 'gamepad':
|
|
113
|
+
pad_id, button = binding
|
|
114
|
+
if pad_id in self.gamepads:
|
|
115
|
+
return self.gamepads[pad_id].is_button_just_released(button)
|
|
116
|
+
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
def get_action_value(self, action: str) -> float:
|
|
120
|
+
"""获取动作的模拟值(用于手柄摇杆等)
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
action: 动作名称
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
动作值 (-1.0 到 1.0)
|
|
127
|
+
"""
|
|
128
|
+
if action not in self.action_mappings:
|
|
129
|
+
return 0.0
|
|
130
|
+
|
|
131
|
+
for device, binding in self.action_mappings[action]:
|
|
132
|
+
if device == 'gamepad':
|
|
133
|
+
pad_id, axis = binding
|
|
134
|
+
if pad_id in self.gamepads:
|
|
135
|
+
return self.gamepads[pad_id].get_axis(axis)
|
|
136
|
+
|
|
137
|
+
# 数字输入返回 0 或 1
|
|
138
|
+
return 1.0 if self.is_action_pressed(action) else 0.0
|
|
139
|
+
|
|
140
|
+
def map_action(self, action: str, device: str, binding: Any):
|
|
141
|
+
"""映射动作到输入
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
action: 动作名称
|
|
145
|
+
device: 设备类型 ('keyboard', 'mouse', 'gamepad')
|
|
146
|
+
binding: 绑定值(键码、按钮索引等)
|
|
147
|
+
"""
|
|
148
|
+
if action not in self.action_mappings:
|
|
149
|
+
self.action_mappings[action] = []
|
|
150
|
+
|
|
151
|
+
self.action_mappings[action].append((device, binding))
|
|
152
|
+
|
|
153
|
+
def unmap_action(self, action: str):
|
|
154
|
+
"""移除动作映射
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
action: 动作名称
|
|
158
|
+
"""
|
|
159
|
+
if action in self.action_mappings:
|
|
160
|
+
del self.action_mappings[action]
|
|
161
|
+
|
|
162
|
+
def get_gamepad_count(self) -> int:
|
|
163
|
+
"""获取连接的手柄数量"""
|
|
164
|
+
return len(self.gamepads)
|
|
165
|
+
|
|
166
|
+
def get_gamepad(self, index: int) -> Optional['GamepadHandler']:
|
|
167
|
+
"""获取指定索引的手柄
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
index: 手柄索引
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
手柄处理器或 None
|
|
174
|
+
"""
|
|
175
|
+
return self.gamepads.get(index)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class KeyboardHandler:
|
|
179
|
+
"""键盘输入处理器"""
|
|
180
|
+
|
|
181
|
+
def __init__(self):
|
|
182
|
+
"""初始化键盘处理器"""
|
|
183
|
+
self.keys_pressed = set()
|
|
184
|
+
self.keys_just_pressed = set()
|
|
185
|
+
self.keys_just_released = set()
|
|
186
|
+
|
|
187
|
+
def update(self, events: List[pygame.event.Event]):
|
|
188
|
+
"""更新键盘状态
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
events: pygame 事件列表
|
|
192
|
+
"""
|
|
193
|
+
self.keys_just_pressed.clear()
|
|
194
|
+
self.keys_just_released.clear()
|
|
195
|
+
|
|
196
|
+
for event in events:
|
|
197
|
+
if event.type == pygame.KEYDOWN:
|
|
198
|
+
self.keys_pressed.add(event.key)
|
|
199
|
+
self.keys_just_pressed.add(event.key)
|
|
200
|
+
elif event.type == pygame.KEYUP:
|
|
201
|
+
self.keys_pressed.discard(event.key)
|
|
202
|
+
self.keys_just_released.add(event.key)
|
|
203
|
+
|
|
204
|
+
def is_key_pressed(self, key: int) -> bool:
|
|
205
|
+
"""检查键是否被按下
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
key: pygame 键码
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
是否按下
|
|
212
|
+
"""
|
|
213
|
+
return key in self.keys_pressed
|
|
214
|
+
|
|
215
|
+
def is_key_just_pressed(self, key: int) -> bool:
|
|
216
|
+
"""检查键是否刚刚被按下
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
key: pygame 键码
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
是否刚刚按下
|
|
223
|
+
"""
|
|
224
|
+
return key in self.keys_just_pressed
|
|
225
|
+
|
|
226
|
+
def is_key_just_released(self, key: int) -> bool:
|
|
227
|
+
"""检查键是否刚刚被释放
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
key: pygame 键码
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
是否刚刚释放
|
|
234
|
+
"""
|
|
235
|
+
return key in self.keys_just_released
|
|
236
|
+
|
|
237
|
+
def get_pressed_keys(self) -> set:
|
|
238
|
+
"""获取所有按下的键"""
|
|
239
|
+
return self.keys_pressed.copy()
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class MouseHandler:
|
|
243
|
+
"""鼠标输入处理器"""
|
|
244
|
+
|
|
245
|
+
def __init__(self):
|
|
246
|
+
"""初始化鼠标处理器"""
|
|
247
|
+
self.position = (0, 0)
|
|
248
|
+
self.rel_motion = (0, 0)
|
|
249
|
+
self.buttons_pressed = set()
|
|
250
|
+
self.buttons_just_pressed = set()
|
|
251
|
+
self.buttons_just_released = set()
|
|
252
|
+
self.scroll_amount = 0
|
|
253
|
+
|
|
254
|
+
def update(self, events: List[pygame.event.Event]):
|
|
255
|
+
"""更新鼠标状态
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
events: pygame 事件列表
|
|
259
|
+
"""
|
|
260
|
+
self.buttons_just_pressed.clear()
|
|
261
|
+
self.buttons_just_released.clear()
|
|
262
|
+
self.rel_motion = (0, 0)
|
|
263
|
+
self.scroll_amount = 0
|
|
264
|
+
|
|
265
|
+
for event in events:
|
|
266
|
+
if event.type == pygame.MOUSEMOTION:
|
|
267
|
+
self.position = event.pos
|
|
268
|
+
self.rel_motion = event.rel
|
|
269
|
+
elif event.type == pygame.MOUSEBUTTONDOWN:
|
|
270
|
+
self.buttons_pressed.add(event.button)
|
|
271
|
+
self.buttons_just_pressed.add(event.button)
|
|
272
|
+
self.position = event.pos
|
|
273
|
+
elif event.type == pygame.MOUSEBUTTONUP:
|
|
274
|
+
self.buttons_pressed.discard(event.button)
|
|
275
|
+
self.buttons_just_released.add(event.button)
|
|
276
|
+
self.position = event.pos
|
|
277
|
+
elif event.type == pygame.MOUSEWHEEL:
|
|
278
|
+
self.scroll_amount = event.y
|
|
279
|
+
|
|
280
|
+
def is_button_pressed(self, button: int) -> bool:
|
|
281
|
+
"""检查鼠标按钮是否被按下
|
|
282
|
+
|
|
283
|
+
Args:
|
|
284
|
+
button: 按钮索引 (1=左, 2=中, 3=右)
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
是否按下
|
|
288
|
+
"""
|
|
289
|
+
return button in self.buttons_pressed
|
|
290
|
+
|
|
291
|
+
def is_button_just_pressed(self, button: int) -> bool:
|
|
292
|
+
"""检查鼠标按钮是否刚刚被按下
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
button: 按钮索引
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
是否刚刚按下
|
|
299
|
+
"""
|
|
300
|
+
return button in self.buttons_just_pressed
|
|
301
|
+
|
|
302
|
+
def is_button_just_released(self, button: int) -> bool:
|
|
303
|
+
"""检查鼠标按钮是否刚刚被释放
|
|
304
|
+
|
|
305
|
+
Args:
|
|
306
|
+
button: 按钮索引
|
|
307
|
+
|
|
308
|
+
Returns:
|
|
309
|
+
是否刚刚释放
|
|
310
|
+
"""
|
|
311
|
+
return button in self.buttons_just_released
|
|
312
|
+
|
|
313
|
+
def get_position(self) -> Tuple[int, int]:
|
|
314
|
+
"""获取鼠标位置"""
|
|
315
|
+
return self.position
|
|
316
|
+
|
|
317
|
+
def get_relative_motion(self) -> Tuple[int, int]:
|
|
318
|
+
"""获取相对运动"""
|
|
319
|
+
return self.rel_motion
|
|
320
|
+
|
|
321
|
+
def get_scroll(self) -> int:
|
|
322
|
+
"""获取滚轮滚动量"""
|
|
323
|
+
return self.scroll_amount
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
class GamepadHandler:
|
|
327
|
+
"""手柄输入处理器"""
|
|
328
|
+
|
|
329
|
+
def __init__(self, joystick: pygame.joystick.Joystick):
|
|
330
|
+
"""初始化手柄处理器
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
joystick: pygame Joystick 对象
|
|
334
|
+
"""
|
|
335
|
+
self.joystick = joystick
|
|
336
|
+
self.buttons_pressed = set()
|
|
337
|
+
self.buttons_just_pressed = set()
|
|
338
|
+
self.buttons_just_released = set()
|
|
339
|
+
self.axes = {}
|
|
340
|
+
self.hats = {}
|
|
341
|
+
|
|
342
|
+
# 初始化轴和帽子状态
|
|
343
|
+
for i in range(joystick.get_numaxes()):
|
|
344
|
+
self.axes[i] = 0.0
|
|
345
|
+
for i in range(joystick.get_numhats()):
|
|
346
|
+
self.hats[i] = (0, 0)
|
|
347
|
+
|
|
348
|
+
def update(self, events: List[pygame.event.Event]):
|
|
349
|
+
"""更新手柄状态
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
events: pygame 事件列表
|
|
353
|
+
"""
|
|
354
|
+
self.buttons_just_pressed.clear()
|
|
355
|
+
self.buttons_just_released.clear()
|
|
356
|
+
|
|
357
|
+
for event in events:
|
|
358
|
+
if event.type == pygame.JOYBUTTONDOWN:
|
|
359
|
+
if event.joy == self.joystick.get_id():
|
|
360
|
+
self.buttons_pressed.add(event.button)
|
|
361
|
+
self.buttons_just_pressed.add(event.button)
|
|
362
|
+
elif event.type == pygame.JOYBUTTONUP:
|
|
363
|
+
if event.joy == self.joystick.get_id():
|
|
364
|
+
self.buttons_pressed.discard(event.button)
|
|
365
|
+
self.buttons_just_released.add(event.button)
|
|
366
|
+
elif event.type == pygame.JOYAXISMOTION:
|
|
367
|
+
if event.joy == self.joystick.get_id():
|
|
368
|
+
self.axes[event.axis] = event.value
|
|
369
|
+
elif event.type == pygame.JOYHATMOTION:
|
|
370
|
+
if event.joy == self.joystick.get_id():
|
|
371
|
+
self.hats[event.hat] = event.value
|
|
372
|
+
|
|
373
|
+
def is_button_pressed(self, button: int) -> bool:
|
|
374
|
+
"""检查按钮是否被按下
|
|
375
|
+
|
|
376
|
+
Args:
|
|
377
|
+
button: 按钮索引
|
|
378
|
+
|
|
379
|
+
Returns:
|
|
380
|
+
是否按下
|
|
381
|
+
"""
|
|
382
|
+
return button in self.buttons_pressed
|
|
383
|
+
|
|
384
|
+
def is_button_just_pressed(self, button: int) -> bool:
|
|
385
|
+
"""检查按钮是否刚刚被按下
|
|
386
|
+
|
|
387
|
+
Args:
|
|
388
|
+
button: 按钮索引
|
|
389
|
+
|
|
390
|
+
Returns:
|
|
391
|
+
是否刚刚按下
|
|
392
|
+
"""
|
|
393
|
+
return button in self.buttons_just_pressed
|
|
394
|
+
|
|
395
|
+
def is_button_just_released(self, button: int) -> bool:
|
|
396
|
+
"""检查按钮是否刚刚被释放
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
button: 按钮索引
|
|
400
|
+
|
|
401
|
+
Returns:
|
|
402
|
+
是否刚刚释放
|
|
403
|
+
"""
|
|
404
|
+
return button in self.buttons_just_released
|
|
405
|
+
|
|
406
|
+
def get_axis(self, axis: int) -> float:
|
|
407
|
+
"""获取摇杆轴的值
|
|
408
|
+
|
|
409
|
+
Args:
|
|
410
|
+
axis: 轴索引
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
轴值 (-1.0 到 1.0)
|
|
414
|
+
"""
|
|
415
|
+
return self.axes.get(axis, 0.0)
|
|
416
|
+
|
|
417
|
+
def get_left_stick(self) -> Tuple[float, float]:
|
|
418
|
+
"""获取左摇杆值
|
|
419
|
+
|
|
420
|
+
Returns:
|
|
421
|
+
(x, y) 摇杆值
|
|
422
|
+
"""
|
|
423
|
+
return (self.axes.get(0, 0.0), self.axes.get(1, 0.0))
|
|
424
|
+
|
|
425
|
+
def get_right_stick(self) -> Tuple[float, float]:
|
|
426
|
+
"""获取右摇杆值
|
|
427
|
+
|
|
428
|
+
Returns:
|
|
429
|
+
(x, y) 摇杆值
|
|
430
|
+
"""
|
|
431
|
+
return (self.axes.get(2, 0.0), self.axes.get(3, 0.0))
|
|
432
|
+
|
|
433
|
+
def get_hat(self, hat: int = 0) -> Tuple[int, int]:
|
|
434
|
+
"""获取方向帽值
|
|
435
|
+
|
|
436
|
+
Args:
|
|
437
|
+
hat: 帽子索引
|
|
438
|
+
|
|
439
|
+
Returns:
|
|
440
|
+
(x, y) 方向值 (-1, 0, 1)
|
|
441
|
+
"""
|
|
442
|
+
return self.hats.get(hat, (0, 0))
|
|
443
|
+
|
|
444
|
+
def get_name(self) -> str:
|
|
445
|
+
"""获取手柄名称"""
|
|
446
|
+
return self.joystick.get_name()
|
|
447
|
+
|
|
448
|
+
def rumble(self, low_freq: float, high_freq: float, duration: int):
|
|
449
|
+
"""手柄震动(如果支持)
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
low_freq: 低频震动强度 (0.0-1.0)
|
|
453
|
+
high_freq: 高频震动强度 (0.0-1.0)
|
|
454
|
+
duration: 持续时间(毫秒)
|
|
455
|
+
"""
|
|
456
|
+
try:
|
|
457
|
+
self.joystick.rumble(low_freq, high_freq, duration)
|
|
458
|
+
except:
|
|
459
|
+
# 某些手柄不支持震动
|
|
460
|
+
pass
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
class TouchHandler:
|
|
464
|
+
"""触摸输入处理器"""
|
|
465
|
+
|
|
466
|
+
def __init__(self):
|
|
467
|
+
"""初始化触摸处理器"""
|
|
468
|
+
self.touches: Dict[int, Tuple[int, int]] = {}
|
|
469
|
+
self.touches_just_started: Dict[int, Tuple[int, int]] = {}
|
|
470
|
+
self.touches_just_ended: List[int] = []
|
|
471
|
+
|
|
472
|
+
def update(self, events: List[pygame.event.Event]):
|
|
473
|
+
"""更新触摸状态
|
|
474
|
+
|
|
475
|
+
Args:
|
|
476
|
+
events: pygame 事件列表
|
|
477
|
+
"""
|
|
478
|
+
self.touches_just_started.clear()
|
|
479
|
+
self.touches_just_ended.clear()
|
|
480
|
+
|
|
481
|
+
for event in events:
|
|
482
|
+
if event.type == pygame.FINGERDOWN:
|
|
483
|
+
touch_id = event.finger_id
|
|
484
|
+
pos = (int(event.x * pygame.display.get_surface().get_width()),
|
|
485
|
+
int(event.y * pygame.display.get_surface().get_height()))
|
|
486
|
+
self.touches[touch_id] = pos
|
|
487
|
+
self.touches_just_started[touch_id] = pos
|
|
488
|
+
elif event.type == pygame.FINGERUP:
|
|
489
|
+
touch_id = event.finger_id
|
|
490
|
+
if touch_id in self.touches:
|
|
491
|
+
del self.touches[touch_id]
|
|
492
|
+
self.touches_just_ended.append(touch_id)
|
|
493
|
+
elif event.type == pygame.FINGERMOTION:
|
|
494
|
+
touch_id = event.finger_id
|
|
495
|
+
if touch_id in self.touches:
|
|
496
|
+
pos = (int(event.x * pygame.display.get_surface().get_width()),
|
|
497
|
+
int(event.y * pygame.display.get_surface().get_height()))
|
|
498
|
+
self.touches[touch_id] = pos
|
|
499
|
+
|
|
500
|
+
def is_touching(self) -> bool:
|
|
501
|
+
"""检查是否有触摸"""
|
|
502
|
+
return len(self.touches) > 0
|
|
503
|
+
|
|
504
|
+
def get_touch_count(self) -> int:
|
|
505
|
+
"""获取当前触摸点数量"""
|
|
506
|
+
return len(self.touches)
|
|
507
|
+
|
|
508
|
+
def get_touch_position(self, finger_id: int = 0) -> Optional[Tuple[int, int]]:
|
|
509
|
+
"""获取触摸位置
|
|
510
|
+
|
|
511
|
+
Args:
|
|
512
|
+
finger_id: 手指 ID(默认为第一个触摸点)
|
|
513
|
+
|
|
514
|
+
Returns:
|
|
515
|
+
触摸位置或 None
|
|
516
|
+
"""
|
|
517
|
+
if finger_id in self.touches:
|
|
518
|
+
return self.touches[finger_id]
|
|
519
|
+
|
|
520
|
+
# 返回第一个触摸点
|
|
521
|
+
if self.touches:
|
|
522
|
+
return list(self.touches.values())[0]
|
|
523
|
+
|
|
524
|
+
return None
|
|
525
|
+
|
|
526
|
+
def get_all_touches(self) -> Dict[int, Tuple[int, int]]:
|
|
527
|
+
"""获取所有触摸点
|
|
528
|
+
|
|
529
|
+
Returns:
|
|
530
|
+
{finger_id: position} 字典
|
|
531
|
+
"""
|
|
532
|
+
return self.touches.copy()
|
|
533
|
+
|
|
534
|
+
def is_touch_just_started(self) -> bool:
|
|
535
|
+
"""检查是否有新的触摸开始"""
|
|
536
|
+
return len(self.touches_just_started) > 0
|
|
537
|
+
|
|
538
|
+
def is_touch_just_ended(self) -> bool:
|
|
539
|
+
"""检查是否有触摸结束"""
|
|
540
|
+
return len(self.touches_just_ended) > 0
|
|
541
|
+
|
|
542
|
+
def get_new_touches(self) -> Dict[int, Tuple[int, int]]:
|
|
543
|
+
"""获取新开始的触摸
|
|
544
|
+
|
|
545
|
+
Returns:
|
|
546
|
+
{finger_id: position} 字典
|
|
547
|
+
"""
|
|
548
|
+
return self.touches_just_started.copy()
|