tinyecs-compsys-dynamics 0.0.1__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Michael Lamertz
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 @@
1
+ graft src/*/assets
@@ -0,0 +1,66 @@
1
+ Metadata-Version: 2.4
2
+ Name: tinyecs-compsys-dynamics
3
+ Version: 0.0.1
4
+ Summary: Dynamics component and system library for tinyecs
5
+ Author-email: Michael Lamertz <michael.lamertz@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: homepage, https://github.com/dickerdackel/tinyecs-compsys/dynamics
8
+ Project-URL: bugtracker, https://github.com/DickerDackel/tinyecs-compsys/dynamics/issues
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Topic :: Games/Entertainment
12
+ Classifier: Topic :: Software Development :: Libraries :: pygame
13
+ Description-Content-Type: text/x-rst
14
+ License-File: LICENSE
15
+ Requires-Dist: aenum
16
+ Requires-Dist: pyglm
17
+ Requires-Dist: pgcooldown
18
+ Requires-Dist: tinyecs-compsys
19
+ Dynamic: license-file
20
+
21
+ tinyecs-compsys-dynamics
22
+ ========================
23
+
24
+ Thise are some very basic and framework independent components.
25
+
26
+ Synopsis
27
+ --------
28
+
29
+ .. code:: python
30
+
31
+ from tinyecs.compsys.dynamics import ...
32
+
33
+ Usage
34
+ -----
35
+
36
+ This package contains platform independent components and systems regarding
37
+ entity dynamics.
38
+
39
+ Installation
40
+ ------------
41
+
42
+ Installation instructions + requirements (should come automagically with
43
+ pyproject.toml)
44
+
45
+ .. code:: console
46
+
47
+ pip install tinyecs[dynamics]
48
+ # or
49
+ pip install tinyecs
50
+ pip install tinyecs-compsys
51
+ pip install tinyecs-compsys-dynamics
52
+
53
+ Support / Contributing
54
+ ----------------------
55
+
56
+ Issues can be opened on `github issues`_
57
+
58
+ .. _github issues: https://forgejo.indieandmore.photography/dickerdackel/tinyecs-compsys/issues
59
+
60
+
61
+ License
62
+ -------
63
+
64
+ This software is provided under the MIT license.
65
+
66
+ See LICENSE file for details.
@@ -0,0 +1,46 @@
1
+ tinyecs-compsys-dynamics
2
+ ========================
3
+
4
+ Thise are some very basic and framework independent components.
5
+
6
+ Synopsis
7
+ --------
8
+
9
+ .. code:: python
10
+
11
+ from tinyecs.compsys.dynamics import ...
12
+
13
+ Usage
14
+ -----
15
+
16
+ This package contains platform independent components and systems regarding
17
+ entity dynamics.
18
+
19
+ Installation
20
+ ------------
21
+
22
+ Installation instructions + requirements (should come automagically with
23
+ pyproject.toml)
24
+
25
+ .. code:: console
26
+
27
+ pip install tinyecs[dynamics]
28
+ # or
29
+ pip install tinyecs
30
+ pip install tinyecs-compsys
31
+ pip install tinyecs-compsys-dynamics
32
+
33
+ Support / Contributing
34
+ ----------------------
35
+
36
+ Issues can be opened on `github issues`_
37
+
38
+ .. _github issues: https://forgejo.indieandmore.photography/dickerdackel/tinyecs-compsys/issues
39
+
40
+
41
+ License
42
+ -------
43
+
44
+ This software is provided under the MIT license.
45
+
46
+ See LICENSE file for details.
@@ -0,0 +1,37 @@
1
+ [project]
2
+ name = "tinyecs-compsys-dynamics"
3
+ description = "Dynamics component and system library for tinyecs"
4
+ version = "0.0.1"
5
+ readme = "README.rst"
6
+
7
+ authors = [
8
+ { name="Michael Lamertz", email="michael.lamertz@gmail.com" }
9
+ ]
10
+
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Intended Audience :: Developers",
14
+ "Topic :: Games/Entertainment",
15
+ "Topic :: Software Development :: Libraries :: pygame",
16
+ ]
17
+
18
+ license = "MIT"
19
+ license-files = ["LICENSE"]
20
+
21
+ dependencies = [
22
+ 'aenum',
23
+ 'pyglm',
24
+ 'pgcooldown',
25
+ 'tinyecs-compsys',
26
+ ]
27
+
28
+ [project.urls]
29
+ homepage = "https://github.com/dickerdackel/tinyecs-compsys/dynamics"
30
+ bugtracker = "https://github.com/DickerDackel/tinyecs-compsys/dynamics/issues"
31
+
32
+ [build-system]
33
+ requires = ["setuptools"]
34
+ build-backend = "setuptools.build_meta"
35
+
36
+ [tool.setuptools]
37
+ include-package-data = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,346 @@
1
+ from collections.abc import Iterator, Sequence
2
+ from dataclasses import dataclass, field
3
+ from math import copysign
4
+
5
+ import glm
6
+ import tinyecs as ecs
7
+
8
+ from aenum import extend_enum
9
+ from glm import vec2
10
+ from pgcooldown import LerpThing
11
+ from tinyecs import EntityID
12
+ from tinyecs.compsys import Comp
13
+
14
+ extend_enum(Comp, 'AIM_AT')
15
+ extend_enum(Comp, 'ALIGN_MOMENTUM')
16
+ extend_enum(Comp, 'ALIGN_WITH')
17
+ extend_enum(Comp, 'ANCHOR')
18
+ extend_enum(Comp, 'FRICTION')
19
+ extend_enum(Comp, 'LERP_ALPHA')
20
+ extend_enum(Comp, 'LERP_ANGLE')
21
+ extend_enum(Comp, 'LERP_MOMENTUM')
22
+ extend_enum(Comp, 'LERP_POSITION')
23
+ extend_enum(Comp, 'LERP_SCALE')
24
+ extend_enum(Comp, 'MOMENTUM')
25
+ extend_enum(Comp, 'PRSA')
26
+ extend_enum(Comp, 'TRACK_PROPNAV')
27
+ extend_enum(Comp, 'TRACK_DIRECT')
28
+
29
+
30
+ @dataclass
31
+ class Anchor:
32
+ """A component to position one entity relative to another.
33
+
34
+ :param parent: The entity ID of the entity to hook on
35
+ :param offset: The offset relative to the parent
36
+
37
+ """
38
+
39
+ parent: EntityID
40
+ offset: vec2
41
+
42
+
43
+ @dataclass
44
+ class LerpPosition:
45
+ """A component for a timed move between two points.
46
+
47
+ :param start: The start position
48
+ :param direction: A normalized direction vector
49
+ :param progress: A LerpThing to track the distance over time
50
+
51
+ """
52
+
53
+ start: vec2
54
+ direction: vec2
55
+ progress: LerpThing
56
+
57
+
58
+ class PRSA:
59
+ """Rotation, Scale, Alpha, Position in one container"""
60
+ pos: vec2
61
+ rotation: float
62
+ scale: float
63
+ alpha: float
64
+
65
+ def __init__(self, pos: vec2, rotation: float = 0, scale: Sequence | float = 1, alpha: float = 255) -> None:
66
+ self.pos = vec2(pos) if pos is not None else vec2()
67
+ self.rotation = rotation
68
+ self.scale = scale
69
+ self.alpha = alpha
70
+
71
+ def __iter__(self) -> Iterator[object]:
72
+ yield self.pos
73
+ yield self.rotation
74
+ yield self.scale
75
+ yield self.alpha
76
+
77
+ def __repr__(self) -> str:
78
+ return f'PRSA(pos={self.pos}, rotation={self.rotation}, scale={self.scale}, alpha={self.alpha})'
79
+
80
+
81
+ @dataclass
82
+ class TrackDirect:
83
+ """Configuration data for direct tracking
84
+
85
+ :param target: EntityID of the target to track
86
+ :param splash_radius: Distance at which the target is considered caught
87
+
88
+ """
89
+
90
+ target: EntityID
91
+ splash_radius: float = 0
92
+
93
+
94
+ @dataclass
95
+ class TrackPropNav:
96
+ """Configuration data for proportional navigation tracking
97
+
98
+ :param target: EntityID of the target to track
99
+ :param allowed_angle: The angle the entity can turn between steps
100
+ :param splash_radius: Distance at which the target is considered caught
101
+
102
+ """
103
+
104
+ target: EntityID
105
+ allowed_angle: float = 180
106
+ splash_radius: float = 0
107
+ _prev_los: float | None = field(init=False, default_factory=lambda: None)
108
+ # ^ Internal, line of sight during the previous call.
109
+
110
+
111
+ def _angle_of(v: vec2) -> float:
112
+ """Return the angle of ``v`` in degrees, since glm lacks that.
113
+
114
+ :param v: The vector in question
115
+ :return: Angle of ``v`` in degrees
116
+
117
+ """
118
+
119
+ return glm.degrees(glm.atan2(v.y, v.x))
120
+
121
+
122
+ def sys_aim_at(eid: EntityID, prsa: PRSA, aim_at: EntityID) -> None:
123
+ """Update prsa.rotation to point towards the target.
124
+
125
+ :param eid: The entity ID
126
+ :param prsa: The PRSA transform object of the entity
127
+
128
+ """
129
+
130
+ pprsa = ecs.comp_of_eid(aim_at, Comp.PRSA)
131
+ delta = pprsa.pos - prsa.pos
132
+ prsa.rotation = _angle_of(delta)
133
+
134
+
135
+ def sys_align_momentum(eid: EntityID, prsa: PRSA, momentum: vec2, align_momentum: bool):
136
+ """Align the entity with its own momentum.
137
+
138
+ :param eid: The entity ID
139
+
140
+ """
141
+
142
+ if not momentum: return
143
+
144
+ prsa.rotation = _angle_of(momentum)
145
+
146
+
147
+ def sys_align_with(eid: EntityID, prsa: PRSA, align_with: EntityID) -> None:
148
+ """Align rotation with rotation of parent.
149
+
150
+ :param eid: The entity ID
151
+
152
+ """
153
+
154
+ pprsa = ecs.comp_of_eid(align_with, Comp.PRSA)
155
+ prsa.rotation = pprsa.rotation
156
+
157
+
158
+ def sys_anchor(eid: EntityID, prsa: PRSA, anchor: Anchor) -> None:
159
+ """Position the entity relative to its parent.
160
+
161
+ :param eid: The entity ID
162
+
163
+ """
164
+
165
+ pprsa = ecs.comp_of_eid(anchor.parent, Comp.PRSA)
166
+ rad = glm.radians(pprsa.rotation)
167
+ real_offset = glm.rotate(anchor.offset, rad) * pprsa.scale
168
+ prsa.pos = pprsa.pos + real_offset
169
+
170
+
171
+ def sys_friction(eid: EntityID, momentum: vec2, friction: float, *, dt: float) -> None:
172
+ """Apply friction to the momentum.
173
+
174
+ :param eid: The entity ID
175
+ :param eid: The momentum of the entity
176
+ :param friction: The friction to apply
177
+ :param dt: Deltatime
178
+
179
+ FIXME implementation undecided
180
+ """
181
+
182
+ if not friction: return
183
+ if not momentum: return
184
+
185
+ reduce = (1 - friction * dt)
186
+ momentum *= reduce
187
+
188
+
189
+ def sys_gravity(eid: EntityID, momentum: vec2, gravity: vec2, *, dt: float) -> None:
190
+ """Apply gavity to both momentum and position.
191
+
192
+ :param eid: The entity ID
193
+ :param prsa: The PRSA transform object of the entity
194
+ :param momentum: The momentum of the entity
195
+ :param gravity: The world gravity to apply
196
+ :param dt: Delta time
197
+
198
+ """
199
+
200
+ momentum += gravity * dt
201
+
202
+
203
+ def sys_lerp_alpha(eid: EntityID, lerp: LerpThing, prsa: PRSA) -> None:
204
+ """Lerp the alpha of the entity.
205
+
206
+ :param eid: The entity ID
207
+ :param lerp: A `pgcooldown.LerpThing` for the alpha change.
208
+
209
+ """
210
+
211
+ prsa.alpha = lerp()
212
+ if lerp.finished():
213
+ ecs.remove_component(Comp.LERP_ALPHA)
214
+
215
+
216
+ def sys_lerp_angle(eid: EntityID, lerp: LerpThing, prsa: PRSA) -> None:
217
+ """Lerp the orientation of the entity.
218
+
219
+ :param eid: The entity ID
220
+ :param lerp: A `pgcooldown.LerpThing` for the rotation change.
221
+
222
+ """
223
+
224
+ prsa.rotation = lerp()
225
+ if lerp.finished():
226
+ ecs.remove_component(Comp.LERP_ANGLE)
227
+
228
+
229
+ def sys_lerp_momentum(eid: EntityID, lerp: LerpThing, momentum: vec2) -> None:
230
+ """Lerp the scale of the entity.
231
+
232
+ :param eid: The entity ID
233
+ :param lerp: A `pgcooldown.LerpThing` for the momentum change.
234
+
235
+ """
236
+
237
+ momentum.xy = glm.normalize(momentum) * lerp()
238
+ if lerp.finished():
239
+ ecs.remove_component(Comp.LERP_MOMENTUM)
240
+
241
+
242
+ def sys_lerp_position(eid: EntityID, prsa: PRSA, lerp: LerpPosition):
243
+ """Update position based on a LerpPosition object.
244
+
245
+ :param eid: The entity ID
246
+ :param prsa: The PRSA transform object of the entity
247
+ :param lerp: The ``LerpPosition`` object tracking the distance
248
+
249
+ .. note:: Moving an object with this method conflicts doing it by momentum.
250
+ """
251
+
252
+ progress = lerp.progress
253
+ prsa.pos = lerp.start + lerp.direction * progress
254
+ if lerp.progress.finished():
255
+ ecs.remove_component(eid, Comp.LERP_POSITION)
256
+
257
+
258
+ def sys_lerp_scale(eid: EntityID, lerp: LerpThing, prsa: PRSA) -> None:
259
+ """Lerp the scale of the entity.
260
+
261
+ :param eid: The entity ID
262
+ :param lerp: A `pgcooldown.LerpThing` for the scale change.
263
+
264
+ """
265
+
266
+ prsa.scale = lerp()
267
+ if lerp.finished():
268
+ ecs.remove_component(Comp.LERP_SCALE)
269
+
270
+
271
+ def sys_momentum(eid: EntityID, prsa: PRSA, momentum: vec2, *, dt: float) -> None:
272
+ """Apply momentum to the PRSA.
273
+
274
+ :param eid: The entity ID
275
+ :param prsa: The PRSA transform object of the entity
276
+ :param momentum: The momentum of the entity
277
+ :param dt: Delta time
278
+
279
+ """
280
+
281
+ prsa.pos += momentum * dt
282
+
283
+
284
+ def sys_track_direct(eid: EntityID, prsa: PRSA, momentum: vec2, target: TrackDirect) -> None:
285
+ """Track another target, make the momentum point directly towards it.
286
+
287
+ :param eid: The entity ID
288
+ :param prsa: The PRSA transform object of the entity
289
+ :param momentum: The momentum of the entity
290
+ :param target: The entity ID of the target
291
+
292
+ """
293
+
294
+ pprsa = ecs.comp_of_eid(target, Comp.PRSA)
295
+ delta = pprsa.pos - prsa.pos
296
+
297
+ if glm.length(delta) < 32:
298
+ ecs.add_component(eid, Comp.IS_KILLED, True)
299
+ return
300
+
301
+ rad = glm.atan2(delta.y, delta.x)
302
+ direction = glm.rotate(vec2(1, 0), rad)
303
+ direction *= glm.length(momentum)
304
+ momentum.xy = direction.xy
305
+
306
+
307
+ def sys_track_propnav(eid: EntityID, prsa: PRSA, momentum: vec2, prop_nav: TrackPropNav, *, dt: float):
308
+ """Make the entity track another entity by proportional navigation.
309
+
310
+ :param eid: The entity ID
311
+ :param prsa: The PRSA transform object of the entity
312
+ :param momentum: The momentum of the entity
313
+ :param prop_nav: The configuration object for the targetting
314
+ :param dt: Delta time
315
+
316
+ """
317
+
318
+ position = prsa.pos
319
+ pprsa = ecs.comp_of_eid(prop_nav.target, Comp.PRSA)
320
+ target = pprsa.pos
321
+
322
+ def normalize(phi):
323
+ return (phi % 360) - 180
324
+
325
+ los = target - position
326
+ angle = _angle_of(los)
327
+ los_phi = normalize(angle)
328
+
329
+ if glm.length(los) < 8:
330
+ ecs.add_component(eid, Comp.IS_KILLED, True)
331
+ return
332
+
333
+ if prop_nav._prev_los is None:
334
+ prop_nav._prev_los = los_phi
335
+ return
336
+
337
+ delta_phi = normalize(prop_nav._prev_los - los_phi)
338
+ if delta_phi == 0:
339
+ return
340
+
341
+ prop_nav._prev_los = los_phi
342
+
343
+ rotation = min(prop_nav.allowed_angle * dt, abs(delta_phi))
344
+ rad = glm.radians(rotation)
345
+ new_momentum = glm.rotate(momentum, copysign(rad, delta_phi))
346
+ momentum.xy = new_momentum.xy
@@ -0,0 +1,66 @@
1
+ Metadata-Version: 2.4
2
+ Name: tinyecs-compsys-dynamics
3
+ Version: 0.0.1
4
+ Summary: Dynamics component and system library for tinyecs
5
+ Author-email: Michael Lamertz <michael.lamertz@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: homepage, https://github.com/dickerdackel/tinyecs-compsys/dynamics
8
+ Project-URL: bugtracker, https://github.com/DickerDackel/tinyecs-compsys/dynamics/issues
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Topic :: Games/Entertainment
12
+ Classifier: Topic :: Software Development :: Libraries :: pygame
13
+ Description-Content-Type: text/x-rst
14
+ License-File: LICENSE
15
+ Requires-Dist: aenum
16
+ Requires-Dist: pyglm
17
+ Requires-Dist: pgcooldown
18
+ Requires-Dist: tinyecs-compsys
19
+ Dynamic: license-file
20
+
21
+ tinyecs-compsys-dynamics
22
+ ========================
23
+
24
+ Thise are some very basic and framework independent components.
25
+
26
+ Synopsis
27
+ --------
28
+
29
+ .. code:: python
30
+
31
+ from tinyecs.compsys.dynamics import ...
32
+
33
+ Usage
34
+ -----
35
+
36
+ This package contains platform independent components and systems regarding
37
+ entity dynamics.
38
+
39
+ Installation
40
+ ------------
41
+
42
+ Installation instructions + requirements (should come automagically with
43
+ pyproject.toml)
44
+
45
+ .. code:: console
46
+
47
+ pip install tinyecs[dynamics]
48
+ # or
49
+ pip install tinyecs
50
+ pip install tinyecs-compsys
51
+ pip install tinyecs-compsys-dynamics
52
+
53
+ Support / Contributing
54
+ ----------------------
55
+
56
+ Issues can be opened on `github issues`_
57
+
58
+ .. _github issues: https://forgejo.indieandmore.photography/dickerdackel/tinyecs-compsys/issues
59
+
60
+
61
+ License
62
+ -------
63
+
64
+ This software is provided under the MIT license.
65
+
66
+ See LICENSE file for details.
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.rst
4
+ pyproject.toml
5
+ src/tinyecs/compsys/dynamics/__init__.py
6
+ src/tinyecs_compsys_dynamics.egg-info/PKG-INFO
7
+ src/tinyecs_compsys_dynamics.egg-info/SOURCES.txt
8
+ src/tinyecs_compsys_dynamics.egg-info/dependency_links.txt
9
+ src/tinyecs_compsys_dynamics.egg-info/requires.txt
10
+ src/tinyecs_compsys_dynamics.egg-info/top_level.txt
11
+ tests/test_FIXME.py
@@ -0,0 +1,4 @@
1
+ aenum
2
+ pyglm
3
+ pgcooldown
4
+ tinyecs-compsys
@@ -0,0 +1,12 @@
1
+ import pytest
2
+
3
+ from contextlib import nullcontext as does_not_raise
4
+
5
+
6
+ def test_FIXME():
7
+ assert True is True
8
+ ...
9
+
10
+ with pytest.raises(FIXME_ExpectedException_FIXME) as e: # noqa
11
+ FIXME_function_expected_to_raise_exception() # noqa
12
+ assert 'FIXME_string_expected_in_exception' in str(e.value)