mima-engine 0.3.2__tar.gz → 0.3.3__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 (317) hide show
  1. {mima_engine-0.3.2 → mima_engine-0.3.3}/PKG-INFO +1 -1
  2. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/__init__.py +1 -1
  3. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/advanced/shape.py +3 -0
  4. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/spatial.py +76 -54
  5. mima_engine-0.3.3/tests/unit/test_spatial_grid.py +211 -0
  6. {mima_engine-0.3.2 → mima_engine-0.3.3}/.gitignore +0 -0
  7. {mima_engine-0.3.2 → mima_engine-0.3.3}/CHANGELOG +0 -0
  8. {mima_engine-0.3.2 → mima_engine-0.3.3}/README.md +0 -0
  9. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/data/gfx/tilemap.png +0 -0
  10. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/data/gfx/tilemap_packed.png +0 -0
  11. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/data/propertytypes.json +0 -0
  12. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/data/sampleMap.tmx +0 -0
  13. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/data/sampleSheet.tsx +0 -0
  14. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/data/tilesets/sampleSheet.tsx +0 -0
  15. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/License.txt +0 -0
  16. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Preview.png +0 -0
  17. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Sample.png +0 -0
  18. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiled/sampleMap.tmx +0 -0
  19. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiled/sampleSheet.tsx +0 -0
  20. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tilemap/tilemap.png +0 -0
  21. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tilemap/tilemap_packed.png +0 -0
  22. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0000.png +0 -0
  23. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0001.png +0 -0
  24. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0002.png +0 -0
  25. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0003.png +0 -0
  26. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0004.png +0 -0
  27. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0005.png +0 -0
  28. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0006.png +0 -0
  29. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0007.png +0 -0
  30. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0008.png +0 -0
  31. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0009.png +0 -0
  32. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0010.png +0 -0
  33. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0011.png +0 -0
  34. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0012.png +0 -0
  35. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0013.png +0 -0
  36. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0014.png +0 -0
  37. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0015.png +0 -0
  38. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0016.png +0 -0
  39. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0017.png +0 -0
  40. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0018.png +0 -0
  41. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0019.png +0 -0
  42. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0020.png +0 -0
  43. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0021.png +0 -0
  44. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0022.png +0 -0
  45. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0023.png +0 -0
  46. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0024.png +0 -0
  47. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0025.png +0 -0
  48. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0026.png +0 -0
  49. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0027.png +0 -0
  50. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0028.png +0 -0
  51. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0029.png +0 -0
  52. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0030.png +0 -0
  53. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0031.png +0 -0
  54. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0032.png +0 -0
  55. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0033.png +0 -0
  56. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0034.png +0 -0
  57. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0035.png +0 -0
  58. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0036.png +0 -0
  59. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0037.png +0 -0
  60. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0038.png +0 -0
  61. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0039.png +0 -0
  62. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0040.png +0 -0
  63. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0041.png +0 -0
  64. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0042.png +0 -0
  65. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0043.png +0 -0
  66. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0044.png +0 -0
  67. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0045.png +0 -0
  68. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0046.png +0 -0
  69. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0047.png +0 -0
  70. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0048.png +0 -0
  71. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0049.png +0 -0
  72. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0050.png +0 -0
  73. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0051.png +0 -0
  74. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0052.png +0 -0
  75. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0053.png +0 -0
  76. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0054.png +0 -0
  77. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0055.png +0 -0
  78. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0056.png +0 -0
  79. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0057.png +0 -0
  80. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0058.png +0 -0
  81. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0059.png +0 -0
  82. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0060.png +0 -0
  83. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0061.png +0 -0
  84. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0062.png +0 -0
  85. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0063.png +0 -0
  86. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0064.png +0 -0
  87. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0065.png +0 -0
  88. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0066.png +0 -0
  89. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0067.png +0 -0
  90. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0068.png +0 -0
  91. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0069.png +0 -0
  92. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0070.png +0 -0
  93. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0071.png +0 -0
  94. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0072.png +0 -0
  95. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0073.png +0 -0
  96. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0074.png +0 -0
  97. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0075.png +0 -0
  98. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0076.png +0 -0
  99. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0077.png +0 -0
  100. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0078.png +0 -0
  101. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0079.png +0 -0
  102. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0080.png +0 -0
  103. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0081.png +0 -0
  104. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0082.png +0 -0
  105. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0083.png +0 -0
  106. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0084.png +0 -0
  107. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0085.png +0 -0
  108. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0086.png +0 -0
  109. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0087.png +0 -0
  110. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0088.png +0 -0
  111. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0089.png +0 -0
  112. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0090.png +0 -0
  113. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0091.png +0 -0
  114. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0092.png +0 -0
  115. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0093.png +0 -0
  116. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0094.png +0 -0
  117. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0095.png +0 -0
  118. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0096.png +0 -0
  119. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0097.png +0 -0
  120. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0098.png +0 -0
  121. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0099.png +0 -0
  122. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0100.png +0 -0
  123. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0101.png +0 -0
  124. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0102.png +0 -0
  125. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0103.png +0 -0
  126. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0104.png +0 -0
  127. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0105.png +0 -0
  128. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0106.png +0 -0
  129. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0107.png +0 -0
  130. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0108.png +0 -0
  131. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0109.png +0 -0
  132. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0110.png +0 -0
  133. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0111.png +0 -0
  134. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0112.png +0 -0
  135. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0113.png +0 -0
  136. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0114.png +0 -0
  137. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0115.png +0 -0
  138. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0116.png +0 -0
  139. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0117.png +0 -0
  140. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0118.png +0 -0
  141. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0119.png +0 -0
  142. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0120.png +0 -0
  143. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0121.png +0 -0
  144. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0122.png +0 -0
  145. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0123.png +0 -0
  146. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0124.png +0 -0
  147. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0125.png +0 -0
  148. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0126.png +0 -0
  149. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0127.png +0 -0
  150. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0128.png +0 -0
  151. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0129.png +0 -0
  152. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0130.png +0 -0
  153. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tiles/tile_0131.png +0 -0
  154. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Tilesheet.txt +0 -0
  155. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Visit Kenney.url +0 -0
  156. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon/Visit Patreon.url +0 -0
  157. {mima_engine-0.3.2 → mima_engine-0.3.3}/examples/kenney_tiny-dungeon.zip +0 -0
  158. {mima_engine-0.3.2 → mima_engine-0.3.3}/mima_config.ini +0 -0
  159. {mima_engine-0.3.2 → mima_engine-0.3.3}/mima_log.json +0 -0
  160. {mima_engine-0.3.2 → mima_engine-0.3.3}/pyproject.toml +0 -0
  161. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/advanced/__init__.py +0 -0
  162. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/advanced/assets.py +0 -0
  163. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/advanced/scene.py +0 -0
  164. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/advanced/shaped_sprite.py +0 -0
  165. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/backend/__init__.py +0 -0
  166. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/backend/pygame_assets.py +0 -0
  167. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/backend/pygame_audio.py +0 -0
  168. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/backend/pygame_backend.py +0 -0
  169. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/backend/pygame_camera.py +0 -0
  170. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/backend/pygame_events.py +0 -0
  171. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/backend/touch_control_scheme_a.py +0 -0
  172. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/backend/touch_control_scheme_b.py +0 -0
  173. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/core/__init__.py +0 -0
  174. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/core/collision.py +0 -0
  175. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/core/database.py +0 -0
  176. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/core/engine.py +0 -0
  177. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/core/mode_engine.py +0 -0
  178. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/core/scene_engine.py +0 -0
  179. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/__init__.py +0 -0
  180. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/template.py +0 -0
  181. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tile.py +0 -0
  182. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tile_animation.py +0 -0
  183. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tile_info.py +0 -0
  184. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tile_layer.py +0 -0
  185. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tiled/__init__.py +0 -0
  186. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tiled/tiled_layer.py +0 -0
  187. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tiled/tiled_map.py +0 -0
  188. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tiled/tiled_object.py +0 -0
  189. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tiled/tiled_objectgroup.py +0 -0
  190. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tiled/tiled_template.py +0 -0
  191. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tiled/tiled_tile.py +0 -0
  192. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tiled/tiled_tileset.py +0 -0
  193. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tilemap.py +0 -0
  194. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tileset.py +0 -0
  195. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/tileset_info.py +0 -0
  196. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/maps/transition_map.py +0 -0
  197. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/__init__.py +0 -0
  198. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/animated_sprite.py +0 -0
  199. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/attribute_effect.py +0 -0
  200. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/attributes.py +0 -0
  201. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/creature.py +0 -0
  202. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/dynamic.py +0 -0
  203. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/effects/__init__.py +0 -0
  204. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/effects/colorize_screen.py +0 -0
  205. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/effects/debug_box.py +0 -0
  206. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/effects/light.py +0 -0
  207. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/effects/show_sprite.py +0 -0
  208. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/effects/walking_on_grass.py +0 -0
  209. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/effects/walking_on_water.py +0 -0
  210. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/loader.py +0 -0
  211. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/projectile.py +0 -0
  212. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/sprite.py +0 -0
  213. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/__init__.py +0 -0
  214. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/color_gate.py +0 -0
  215. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/color_switch.py +0 -0
  216. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/container.py +0 -0
  217. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/floor_switch.py +0 -0
  218. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/gate.py +0 -0
  219. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/light_source.py +0 -0
  220. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/logic_gate.py +0 -0
  221. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/movable.py +0 -0
  222. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/oneway.py +0 -0
  223. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/pickup.py +0 -0
  224. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/switch.py +0 -0
  225. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/objects/world/teleport.py +0 -0
  226. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/py.typed +0 -0
  227. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/__init__.py +0 -0
  228. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/command.py +0 -0
  229. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/__init__.py +0 -0
  230. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/add_quest.py +0 -0
  231. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/change_map.py +0 -0
  232. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/close_dialog.py +0 -0
  233. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/equip_weapon.py +0 -0
  234. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/give_item.py +0 -0
  235. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/give_resource.py +0 -0
  236. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/move_map.py +0 -0
  237. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/move_to.py +0 -0
  238. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/oneway_move.py +0 -0
  239. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/parallel.py +0 -0
  240. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/play_sound.py +0 -0
  241. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/present_item.py +0 -0
  242. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/progress_quest.py +0 -0
  243. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/quit_game.py +0 -0
  244. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/save_game.py +0 -0
  245. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/screen_fade.py +0 -0
  246. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/serial.py +0 -0
  247. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/set_facing_direction.py +0 -0
  248. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/set_spawn_map.py +0 -0
  249. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/show_choices.py +0 -0
  250. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/show_dialog.py +0 -0
  251. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/commands/take_coins.py +0 -0
  252. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/scripts/script_processor.py +0 -0
  253. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/__init__.py +0 -0
  254. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/camera.py +0 -0
  255. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/geometry.py +0 -0
  256. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/multicolumn_list.py +0 -0
  257. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/pixel_font.py +0 -0
  258. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/scripting.py +0 -0
  259. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/sprite.py +0 -0
  260. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/tiled_map.py +0 -0
  261. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/transformed_view.py +0 -0
  262. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/standalone/user_input.py +0 -0
  263. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/states/__init__.py +0 -0
  264. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/states/game_state.py +0 -0
  265. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/states/memory.py +0 -0
  266. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/states/quest.py +0 -0
  267. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/__init__.py +0 -0
  268. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/alignment.py +0 -0
  269. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/blend.py +0 -0
  270. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/damage.py +0 -0
  271. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/direction.py +0 -0
  272. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/gate_color.py +0 -0
  273. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/graphic_state.py +0 -0
  274. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/keys.py +0 -0
  275. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/mode.py +0 -0
  276. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/nature.py +0 -0
  277. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/object.py +0 -0
  278. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/player.py +0 -0
  279. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/position.py +0 -0
  280. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/start.py +0 -0
  281. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/terrain.py +0 -0
  282. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/tile_collision.py +0 -0
  283. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/weapon_slot.py +0 -0
  284. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/types/window.py +0 -0
  285. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/usables/__init__.py +0 -0
  286. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/usables/item.py +0 -0
  287. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/usables/weapon.py +0 -0
  288. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/__init__.py +0 -0
  289. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/colors.py +0 -0
  290. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/constants.py +0 -0
  291. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/functions.py +0 -0
  292. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/input_defaults.py +0 -0
  293. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/logging.py +0 -0
  294. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/property.py +0 -0
  295. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/runtime_config.py +0 -0
  296. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/util/trading_item.py +0 -0
  297. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/view/__init__.py +0 -0
  298. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/view/camera.py +0 -0
  299. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/view/mima_mode.py +0 -0
  300. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/view/mima_scene.py +0 -0
  301. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/view/mima_view.py +0 -0
  302. {mima_engine-0.3.2 → mima_engine-0.3.3}/src/mima/view/mima_window.py +0 -0
  303. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/fixtures/assets.txt +0 -0
  304. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/fixtures/healing_dragon_color.png +0 -0
  305. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/fixtures/icon.png +0 -0
  306. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/fixtures/norana-sheet.png +0 -0
  307. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/fixtures/norana-sheet.tsx +0 -0
  308. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/fixtures/test.tiled-project +0 -0
  309. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/fixtures/test_map.tmx +0 -0
  310. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/fixtures/test_template.py +0 -0
  311. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/system/test_engine.py +0 -0
  312. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/system/test_map.py +0 -0
  313. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/system/test_ttv_with_map.py +0 -0
  314. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/system/test_two_players.py +0 -0
  315. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/system/test_window_manager.py +0 -0
  316. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/unit/test_multicolumn_list.py +0 -0
  317. {mima_engine-0.3.2 → mima_engine-0.3.3}/tests/unit/test_shape_collection.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mima-engine
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: A game engine based on pygame.
5
5
  Author-email: Stephan Balduin <stephan.balduin@mailbox.org>
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -1,4 +1,4 @@
1
- __version__ = "0.3.2"
1
+ __version__ = "0.3.3"
2
2
 
3
3
  from .core.engine import MimaEngine as MimaEngine
4
4
  from .core.mode_engine import MimaModeEngine as MimaModeEngine
@@ -94,3 +94,6 @@ class ShapeCollection:
94
94
 
95
95
  def get_br_pos(self) -> Vector2:
96
96
  return self.pos + self.br
97
+
98
+ def get_bounding_size(self) -> Vector2:
99
+ return self.bounding_box.size
@@ -17,69 +17,67 @@ class SpatialGrid(Generic[T]):
17
17
  self._n_cols = int(math.ceil(world_size.x / cell_size))
18
18
  self._n_rows = int(math.ceil(world_size.y / cell_size))
19
19
 
20
- # self._cells: dict[int, list[T]] = {
21
- # i: [] for i in range(self._n_cols * self._n_rows)
22
- # }
23
20
  self._cells: list[list[T]] = [[] for _ in range(self._n_cols * self._n_rows)]
24
- self._object_map: dict[T, int] = {}
21
+ self._object_map: dict[T, list[int]] = {}
25
22
  self.n_objects = 0
26
23
 
27
- def insert(self, obj: T, pos: Vector2) -> None:
24
+ def insert(self, obj: T, pos: Vector2, size: Vector2 | None = None) -> None:
28
25
  """Insert object at given position in the grid."""
29
- idx = self.get_grid_index(pos)
30
- self._cells[idx].append(obj)
31
- self._object_map[obj] = idx
26
+ size = Vector2(1, 1) if size is None else size
27
+ indices = cells_for_aabb(pos, size, self._cell_size, self._n_rows, self._n_cols)
28
+
29
+ for idx in indices:
30
+ self._cells[idx].append(obj)
31
+
32
+ self._object_map[obj] = indices
32
33
  self.n_objects += 1
33
34
 
34
- def remove(self, obj: T, pos: Vector2) -> None:
35
- """Remove object at given position from the grid."""
36
- idx = self.get_grid_index(pos)
37
- self._cells[idx].remove(obj)
35
+ def remove(self, obj: T) -> None:
36
+ """Remove object from all grid cells it occupies."""
37
+ indices = self._object_map.get(obj)
38
+ if indices is None:
39
+ return
40
+
41
+ for idx in indices:
42
+ if obj in self._cells[idx]:
43
+ self._cells[idx].remove(obj)
44
+
38
45
  self._object_map.pop(obj)
39
46
  self.n_objects -= 1
40
47
 
41
- def relocate(self, obj: T, old_pos: Vector2, new_pos: Vector2) -> None:
42
- """Move object from old position to new position in the grid."""
43
- if old_pos == new_pos:
44
- return
48
+ def relocate(self, obj: T, new_pos: Vector2, size: Vector2 | None = None) -> None:
49
+ """Move object to a new position in the grid."""
45
50
 
46
- old_idx_from_pos = self.get_grid_index(old_pos)
47
- if (old_idx := self._object_map[obj]) != old_idx_from_pos:
48
- LOG.error(
49
- "Cell mismatch for object %s: saved index %d != %d",
50
- str(obj),
51
- self._object_map[obj],
52
- old_idx,
51
+ old_indices = self._object_map.get(obj)
52
+ if old_indices is None:
53
+ LOG.warning(
54
+ "Objects %s not in grid. Performing insertion instead.", str(obj)
53
55
  )
54
- new_idx = self.get_grid_index(new_pos)
56
+ return self.insert(obj, new_pos, size)
55
57
 
56
- if old_idx == new_idx:
58
+ size = Vector2(1, 1) if size is None else size
59
+
60
+ new_indices = cells_for_aabb(
61
+ new_pos, size, self._cell_size, self._n_rows, self._n_cols
62
+ )
63
+ if old_indices == new_indices:
57
64
  return
58
65
 
59
66
  LOG.debug(
60
- "%s moving from (%.1f, %.1f) (cell %d) to (%.1f, %.1f) (cell %d)",
67
+ "Object %s (%s) moving from cells %s to %s",
61
68
  str(obj),
62
- old_pos.x,
63
- old_pos.y,
64
- old_idx,
65
- new_pos.x,
66
- new_pos.y,
67
- new_idx,
69
+ new_pos,
70
+ old_indices,
71
+ new_indices,
68
72
  )
73
+ for idx in old_indices:
74
+ if obj in self._cells[idx]:
75
+ self._cells[idx].remove(obj)
69
76
 
70
- if old_idx < 0 or old_idx >= len(self._cells):
71
- LOG.error(
72
- "Old cell %d of object does not exist. Number of cells %d.",
73
- old_idx,
74
- len(self._cells),
75
- )
77
+ for idx in new_indices:
78
+ self._cells[idx].append(obj)
76
79
 
77
- if obj not in self._cells[old_idx]:
78
- LOG.error("Object %s not in cell %d", str(obj), old_idx)
79
-
80
- self._cells[old_idx].remove(obj)
81
- self._cells[new_idx].append(obj)
82
- self._object_map[obj] = new_idx
80
+ self._object_map[obj] = new_indices
83
81
 
84
82
  def get_grid_index(self, pos: Vector2) -> int:
85
83
  x, y = self.get_grid_coords(pos)
@@ -93,7 +91,7 @@ class SpatialGrid(Generic[T]):
93
91
 
94
92
  def get_all_objects(self) -> list[T]:
95
93
  """Return all objects stored in the grid."""
96
- return [val for vals in self._cells for val in vals]
94
+ return list(self._object_map.keys())
97
95
 
98
96
  def get_objects_in_region(self, pos: Vector2, size: Vector2) -> list[T]:
99
97
  """Return all objects in the area defined by pos and size."""
@@ -105,15 +103,14 @@ class SpatialGrid(Generic[T]):
105
103
  ex = int(min(self._n_cols - 1, (pos.x + size.x - 1e-9) // self._cell_size))
106
104
  ey = int(min(self._n_rows - 1, (pos.y + size.y - 1e-9) // self._cell_size))
107
105
 
108
- return list(
109
- itertools.chain(
110
- *[
111
- self._cells[gx + gy * self._n_cols]
112
- for gy in range(sy, ey + 1) # include last index
113
- for gx in range(sx, ex + 1)
114
- ]
115
- )
116
- )
106
+ result: set[T] = set()
107
+
108
+ for gy in range(sy, ey + 1):
109
+ row_offset = gy * self._n_cols
110
+ for gx in range(sx, ex + 1):
111
+ result.update(self._cells[gx + row_offset])
112
+
113
+ return list(result)
117
114
 
118
115
  def get_cells_in_region(
119
116
  self, pos: Vector2, size: Vector2
@@ -163,3 +160,28 @@ def clamp(val: float, low: float, high: float) -> float: ...
163
160
 
164
161
  def clamp(val: int | float, low: int | float, high: int | float) -> int | float:
165
162
  return max(low, min(high, val))
163
+
164
+
165
+ def vmax(val: Vector2, other: Vector2) -> Vector2:
166
+ return Vector2(max(val.x, other.x), max(val.y, other.y))
167
+
168
+
169
+ def vmin(val: Vector2, other: Vector2) -> Vector2:
170
+ return Vector2(min(val.x, other.x), min(val.y, other.y))
171
+
172
+
173
+ def cells_for_aabb(
174
+ pos: Vector2, size: Vector2, cell_size: int, n_rows: int, n_cols: int
175
+ ) -> list[int]:
176
+ tl = pos // cell_size
177
+ br = (pos + size) // cell_size
178
+ v_cols = Vector2(n_cols - 1, n_rows - 1)
179
+ tl = vmax(Vector2(), vmin(tl, v_cols))
180
+ br = vmax(Vector2(), vmin(br, v_cols))
181
+
182
+ indices: list[int] = []
183
+ for y in range(int(tl.y), int(br.y) + 1):
184
+ for x in range(int(tl.x), int(br.x) + 1):
185
+ indices.append(x + y * n_cols)
186
+
187
+ return indices
@@ -0,0 +1,211 @@
1
+ import pytest
2
+ from pygame import Vector2
3
+
4
+ from mima.standalone.spatial import SpatialGrid
5
+
6
+
7
+ @pytest.fixture
8
+ def empty_grid() -> SpatialGrid[int]:
9
+ return SpatialGrid[int](Vector2(10, 10), 2)
10
+
11
+
12
+ @pytest.fixture()
13
+ def spatial_grid() -> SpatialGrid[int]:
14
+ grid = SpatialGrid[int](Vector2(10, 10), 2)
15
+ grid.insert(0, Vector2(3, 4), Vector2(0.2, 0.2)) # Cell 11
16
+ grid.insert(1, Vector2(1.5, 7), Vector2(0.2, 0.2)) # Cell 15
17
+ grid.insert(2, Vector2(8, 5), Vector2(0.2, 0.2)) # Cell 14
18
+ grid.insert(3, Vector2(2, 1), Vector2(0.2, 0.2)) # Cell 1
19
+ grid.insert(4, Vector2(2, 1), Vector2(0.2, 0.2)) # Cell 1
20
+ grid.insert(5, Vector2(2, 3), Vector2(0.2, 0.2)) # Cell 2
21
+ return grid
22
+
23
+
24
+ @pytest.fixture()
25
+ def large_object_grid() -> SpatialGrid[int]:
26
+ grid = SpatialGrid[int](Vector2(10, 10), 2)
27
+
28
+ grid.insert(0, Vector2(3, 4), Vector2(1, 1)) # cell 11
29
+ grid.insert(1, Vector2(0, 5), Vector2(4, 4))
30
+ grid.insert(2, Vector2(0, 9), Vector2(0.2, 0.2))
31
+ return grid
32
+
33
+
34
+ @pytest.mark.parametrize(
35
+ "pos, expected_cell", [((1.5, 1), 0), ((2.5, 1), 1), ((20, 20), 24)]
36
+ )
37
+ def test_insert(
38
+ empty_grid: SpatialGrid[int], pos: tuple[int, int], expected_cell: int
39
+ ) -> None:
40
+ """Test insertion of objects.
41
+
42
+ Todo:
43
+ * Inserting out-of-bounds will add objects to border cells. Check if
44
+ this is the expected behavior for spatial grids.
45
+
46
+ """
47
+ empty_grid.insert(0, Vector2(pos))
48
+
49
+ assert empty_grid.n_objects == 1
50
+ assert 0 in empty_grid._cells[expected_cell]
51
+
52
+
53
+ def test_insert_large_object(empty_grid: SpatialGrid[int]) -> None:
54
+ pos = Vector2(3, 3)
55
+ size = Vector2(4, 5.5)
56
+ indices = [6, 7, 8, 11, 12, 13, 16, 17, 18, 21, 22, 23]
57
+
58
+ empty_grid.insert(0, pos, size)
59
+
60
+ assert empty_grid.n_objects == 1
61
+ assert empty_grid._object_map[0] == indices
62
+ for idx in indices:
63
+ assert 0 in empty_grid._cells[idx]
64
+
65
+
66
+ @pytest.mark.parametrize("obj, expected_cell", [(0, 11)])
67
+ def test_remove(spatial_grid: SpatialGrid[int], obj: int, expected_cell: int) -> None:
68
+ """Test removal of objects."""
69
+
70
+ assert spatial_grid.n_objects == 6
71
+ assert len(spatial_grid._cells[expected_cell]) == 1
72
+ assert obj in spatial_grid._object_map
73
+
74
+ spatial_grid.remove(obj)
75
+
76
+ assert spatial_grid.n_objects == 5
77
+ assert len(spatial_grid._cells[expected_cell]) == 0
78
+ assert obj not in spatial_grid._object_map
79
+
80
+
81
+ def test_remove_object_not_in_grid(spatial_grid: SpatialGrid[int]) -> None:
82
+ assert spatial_grid.n_objects == 6
83
+ assert 6 not in spatial_grid._object_map
84
+
85
+ spatial_grid.remove(6)
86
+
87
+ assert spatial_grid.n_objects == 6
88
+ assert 6 not in spatial_grid._object_map
89
+
90
+
91
+ @pytest.mark.parametrize(
92
+ "obj,indices", [(0, [11, 12]), (1, [10, 11, 12, 15, 16, 17, 20, 21, 22]), (2, [20])]
93
+ )
94
+ def test_remove_large_object(
95
+ large_object_grid: SpatialGrid[int], obj: int, indices: list[int]
96
+ ) -> None:
97
+ for idx in indices:
98
+ assert obj in large_object_grid._cells[idx]
99
+ assert large_object_grid.n_objects == 3
100
+
101
+ large_object_grid.remove(obj)
102
+
103
+ for idx in indices:
104
+ assert obj not in large_object_grid._cells[idx]
105
+ assert large_object_grid.n_objects == 2
106
+
107
+
108
+ def test_relocate(spatial_grid):
109
+ assert spatial_grid._object_map[3] == [1]
110
+ assert len(spatial_grid._cells[1]) == 2
111
+ assert 3 in spatial_grid._cells[1]
112
+ assert len(spatial_grid._cells[2]) == 0
113
+
114
+ spatial_grid.relocate(3, Vector2(4, 1), Vector2(0.2, 0.2))
115
+
116
+ assert spatial_grid._object_map[3] == [2]
117
+ assert len(spatial_grid._cells[1]) == 1
118
+ assert 3 not in spatial_grid._cells[1]
119
+ assert len(spatial_grid._cells[2]) == 1
120
+ assert 3 in spatial_grid._cells[2]
121
+
122
+
123
+ @pytest.mark.parametrize("new_pos, expected_indices", [((4, 1), [2]), ((0, 0), [0])])
124
+ def test_relocate_object_not_in_grid(
125
+ spatial_grid: SpatialGrid[int],
126
+ new_pos: tuple[int, int],
127
+ expected_indices: list[int],
128
+ ) -> None:
129
+ assert spatial_grid.n_objects == 6
130
+ assert 6 not in spatial_grid._object_map
131
+
132
+ spatial_grid.relocate(6, Vector2(new_pos), Vector2(0.2, 0.2))
133
+
134
+ assert spatial_grid.n_objects == 7
135
+ assert 6 in spatial_grid._object_map
136
+ assert spatial_grid._object_map[6] == expected_indices
137
+ assert 6 in spatial_grid._cells[expected_indices[0]]
138
+
139
+
140
+ @pytest.mark.parametrize(
141
+ "obj,pos,size,old_indices, new_indices",
142
+ [
143
+ (0, (6, 2), (1, 1), [11, 12], [8]),
144
+ (
145
+ 1,
146
+ (4, 4),
147
+ (4, 4),
148
+ [10, 11, 12, 15, 16, 17, 20, 21, 22],
149
+ [12, 13, 14, 17, 18, 19, 22, 23, 24],
150
+ ),
151
+ ],
152
+ )
153
+ def test_relocate_large_object(
154
+ large_object_grid: SpatialGrid[int],
155
+ obj: int,
156
+ pos: tuple[float, float],
157
+ size: tuple[float, float],
158
+ old_indices: list[int],
159
+ new_indices: list[int],
160
+ ) -> None:
161
+ for idx in old_indices:
162
+ assert obj in large_object_grid._cells[idx]
163
+ for idx in new_indices:
164
+ if idx not in old_indices:
165
+ assert obj not in large_object_grid._cells[idx]
166
+
167
+ large_object_grid.relocate(obj, Vector2(pos), Vector2(size))
168
+
169
+ for idx in old_indices:
170
+ if idx not in new_indices:
171
+ assert obj not in large_object_grid._cells[idx]
172
+ for idx in new_indices:
173
+ assert obj in large_object_grid._cells[idx]
174
+
175
+
176
+ @pytest.mark.parametrize(
177
+ "pos, size, n_objects",
178
+ [((2.5, 2), (2, 3), 2), ((1.5, 0), (4, 4), 3), ((4, 5), (4, 4), 0)],
179
+ )
180
+ def test_get_objects_in_region(
181
+ spatial_grid: SpatialGrid[int],
182
+ pos: tuple[float, float],
183
+ size: tuple[float, float],
184
+ n_objects: int,
185
+ ) -> None:
186
+ objects = spatial_grid.get_objects_in_region(Vector2(pos), Vector2(size))
187
+
188
+ assert len(objects) == n_objects
189
+
190
+
191
+ @pytest.mark.parametrize("pos, size, n_objects", [((0, 3), (4, 4), 2)])
192
+ def test_get_large_objects_in_region(
193
+ large_object_grid,
194
+ pos: tuple[float, float],
195
+ size: tuple[float, float],
196
+ n_objects: int,
197
+ ) -> None:
198
+ objects = large_object_grid.get_objects_in_region(Vector2(pos), Vector2(size))
199
+
200
+ assert len(objects) == n_objects
201
+
202
+
203
+ def print_grid(spatial_grid: SpatialGrid[int]) -> str:
204
+ s = ""
205
+ for y in range(spatial_grid._n_rows):
206
+ for x in range(spatial_grid._n_cols):
207
+ idx = x + y * spatial_grid._n_cols
208
+ s += f"{str(spatial_grid._cells[idx]):>7}"
209
+ s += "\n"
210
+ print(s)
211
+ return s
File without changes
File without changes
File without changes