XMWAI 0.4.5__py3-none-any.whl → 0.4.7__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.
Potentially problematic release.
This version of XMWAI might be problematic. Click here for more details.
- XMWAI/snake_core.py +57 -29
- {xmwai-0.4.5.dist-info → xmwai-0.4.7.dist-info}/METADATA +1 -1
- {xmwai-0.4.5.dist-info → xmwai-0.4.7.dist-info}/RECORD +6 -7
- XMWAI/assets/__init__.py +0 -0
- {xmwai-0.4.5.dist-info → xmwai-0.4.7.dist-info}/WHEEL +0 -0
- {xmwai-0.4.5.dist-info → xmwai-0.4.7.dist-info}/licenses/LICENSE.txt +0 -0
- {xmwai-0.4.5.dist-info → xmwai-0.4.7.dist-info}/top_level.txt +0 -0
XMWAI/snake_core.py
CHANGED
|
@@ -5,18 +5,15 @@ import cvzone
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
from cvzone.HandTrackingModule import HandDetector
|
|
7
7
|
from PIL import ImageFont, ImageDraw, Image
|
|
8
|
-
import os
|
|
9
8
|
import time
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import XMWAI.assets as assets
|
|
9
|
+
from importlib.resources import files
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import os
|
|
14
12
|
|
|
15
13
|
|
|
16
|
-
def
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
return str(p)
|
|
14
|
+
def get_resource_path(filename: str) -> str:
|
|
15
|
+
"""返回 snake_core 模块内资源的绝对路径"""
|
|
16
|
+
return str(files("XMWAI.assets").joinpath(filename))
|
|
20
17
|
|
|
21
18
|
|
|
22
19
|
class SnakeGame:
|
|
@@ -30,21 +27,16 @@ class SnakeGame:
|
|
|
30
27
|
self._snakeHeadSize = snakeHeadSize
|
|
31
28
|
self._foodScores = foodScores if foodScores is not None else [3, 2, 1]
|
|
32
29
|
self.snakeLineWidth = snakeLineWidth
|
|
30
|
+
self.fontPath = fontPath or get_resource_path("微软雅黑.ttf")
|
|
33
31
|
|
|
34
|
-
# 字体路径(默认取包内字体)
|
|
35
|
-
self.fontPath = fontPath or get_asset_path("微软雅黑.ttf")
|
|
36
|
-
|
|
37
|
-
# 默认资源路径
|
|
38
32
|
if foodPaths is None:
|
|
39
|
-
foodPaths = [
|
|
40
|
-
|
|
41
|
-
get_asset_path("t.png")]
|
|
33
|
+
foodPaths = [get_resource_path(f)
|
|
34
|
+
for f in ["h.png", "s.png", "t.png"]]
|
|
42
35
|
if foodNames is None:
|
|
43
36
|
foodNames = ["汉堡", "薯条", "甜甜圈"]
|
|
44
37
|
if obstaclePaths is None:
|
|
45
|
-
obstaclePaths = [
|
|
46
|
-
|
|
47
|
-
get_asset_path("m.png")]
|
|
38
|
+
obstaclePaths = [get_resource_path(f)
|
|
39
|
+
for f in ["g.png", "l.png", "m.png"]]
|
|
48
40
|
|
|
49
41
|
self.foodPaths = foodPaths
|
|
50
42
|
self.foodNames = foodNames
|
|
@@ -64,7 +56,7 @@ class SnakeGame:
|
|
|
64
56
|
self._init_game_objects()
|
|
65
57
|
self.open_window()
|
|
66
58
|
|
|
67
|
-
#
|
|
59
|
+
# ---------------- 属性自动同步 ----------------
|
|
68
60
|
@property
|
|
69
61
|
def snakeHeadSize(self):
|
|
70
62
|
return self._snakeHeadSize
|
|
@@ -113,6 +105,8 @@ class SnakeGame:
|
|
|
113
105
|
self.obstacleManager.randomObstacles()
|
|
114
106
|
|
|
115
107
|
def _render_frame(self, show_food=True, show_obstacle=True):
|
|
108
|
+
if self.cap is None:
|
|
109
|
+
return
|
|
116
110
|
success, self.img = self.cap.read()
|
|
117
111
|
if not success:
|
|
118
112
|
return
|
|
@@ -134,8 +128,7 @@ class SnakeGame:
|
|
|
134
128
|
|
|
135
129
|
if show_obstacle:
|
|
136
130
|
self.img = self.obstacleManager.draw(self.img)
|
|
137
|
-
self.obstacleManager.moveObstacles(
|
|
138
|
-
self.resolution[0], self.resolution[1])
|
|
131
|
+
self.obstacleManager.moveObstacles(*self.resolution)
|
|
139
132
|
|
|
140
133
|
if show_food:
|
|
141
134
|
self.img = self.foodManager.draw(self.img)
|
|
@@ -154,6 +147,39 @@ class SnakeGame:
|
|
|
154
147
|
cv2.imshow("AI Snake", self.img)
|
|
155
148
|
cv2.waitKey(1)
|
|
156
149
|
|
|
150
|
+
def hand(self):
|
|
151
|
+
if self.cap is None:
|
|
152
|
+
print("请先调用 open_window()")
|
|
153
|
+
return
|
|
154
|
+
if self.detector is None:
|
|
155
|
+
self.detector = HandDetector(detectionCon=0.8, maxHands=1)
|
|
156
|
+
while True:
|
|
157
|
+
success, self.img = self.cap.read()
|
|
158
|
+
if not success:
|
|
159
|
+
break
|
|
160
|
+
self.img = cv2.flip(self.img, 1)
|
|
161
|
+
hands, self.img = self.detector.findHands(self.img, flipType=False)
|
|
162
|
+
cv2.imshow("AI Snake", self.img)
|
|
163
|
+
key = cv2.waitKey(1) & 0xFF
|
|
164
|
+
if hands or key == ord('q'):
|
|
165
|
+
break
|
|
166
|
+
|
|
167
|
+
def display(self):
|
|
168
|
+
if self.img is None:
|
|
169
|
+
self._render_frame(show_food=False)
|
|
170
|
+
self.foodManager.randomFoodLocation(self.obstacleManager)
|
|
171
|
+
self._render_frame(show_food=True)
|
|
172
|
+
self.overlayTexts = [
|
|
173
|
+
(f'玩家分数:{self.snake.score}', (50, 50), 30, (255, 0, 255)),
|
|
174
|
+
(f'倒计时:{self.timer} 秒', (50, 120), 30, (255, 0, 255))
|
|
175
|
+
]
|
|
176
|
+
img_copy = self.img.copy()
|
|
177
|
+
for txt, pos, size, color in self.overlayTexts:
|
|
178
|
+
img_copy = self._putChineseText(img_copy, txt, pos, size, color)
|
|
179
|
+
cv2.imshow("AI Snake", img_copy)
|
|
180
|
+
cv2.waitKey(1)
|
|
181
|
+
|
|
182
|
+
# ---------------- 重置游戏 ----------------
|
|
157
183
|
def reset_game(self):
|
|
158
184
|
self.snake.reset()
|
|
159
185
|
self.snake.headSize = self._snakeHeadSize
|
|
@@ -165,9 +191,10 @@ class SnakeGame:
|
|
|
165
191
|
if self.cap is None or not self.cap.isOpened():
|
|
166
192
|
self.open_window()
|
|
167
193
|
|
|
194
|
+
# ---------------- 游戏结束 ----------------
|
|
168
195
|
def gameover(self, path=None, size=(100, 100)):
|
|
169
196
|
if path is None:
|
|
170
|
-
path =
|
|
197
|
+
path = get_resource_path("1.png")
|
|
171
198
|
|
|
172
199
|
if os.path.exists(path):
|
|
173
200
|
gameover_img = cv2.imread(path)
|
|
@@ -194,6 +221,7 @@ class SnakeGame:
|
|
|
194
221
|
cv2.destroyAllWindows()
|
|
195
222
|
break
|
|
196
223
|
|
|
224
|
+
# ---------------- 游戏主循环 ----------------
|
|
197
225
|
def start(self):
|
|
198
226
|
if self.cap is None or not self.cap.isOpened():
|
|
199
227
|
self.open_window()
|
|
@@ -222,7 +250,7 @@ class SnakeGame:
|
|
|
222
250
|
cv2.imshow("AI Snake", img_copy)
|
|
223
251
|
|
|
224
252
|
key = cv2.waitKey(1)
|
|
225
|
-
if key == ord('r'):
|
|
253
|
+
if key == ord('r'): # 游戏中途重置
|
|
226
254
|
self.reset_game()
|
|
227
255
|
elif key == ord('q'):
|
|
228
256
|
if self.cap is not None:
|
|
@@ -230,7 +258,7 @@ class SnakeGame:
|
|
|
230
258
|
cv2.destroyAllWindows()
|
|
231
259
|
break
|
|
232
260
|
|
|
233
|
-
# ----------------
|
|
261
|
+
# ---------------- 内部类 ----------------
|
|
234
262
|
class Snake:
|
|
235
263
|
def __init__(self, color, initLength=150, lineWidth=10, headSize=15):
|
|
236
264
|
self.points = []
|
|
@@ -309,7 +337,7 @@ class SnakeGame:
|
|
|
309
337
|
if ox <= cx <= ox + ow and oy <= cy <= oy + oh:
|
|
310
338
|
self.gameOver = True
|
|
311
339
|
|
|
312
|
-
# ----------------
|
|
340
|
+
# ---------------- 内部类 ----------------
|
|
313
341
|
class FoodManager:
|
|
314
342
|
def __init__(self, foodPaths, foodNames, foodScores):
|
|
315
343
|
self.foodImages = []
|
|
@@ -349,7 +377,7 @@ class SnakeGame:
|
|
|
349
377
|
(rx - self.wFood//2, ry - self.hFood//2))
|
|
350
378
|
return imgMain
|
|
351
379
|
|
|
352
|
-
# ----------------
|
|
380
|
+
# ---------------- 内部类 ----------------
|
|
353
381
|
class ObstacleManager:
|
|
354
382
|
def __init__(self, obstaclePaths):
|
|
355
383
|
self.obstacleImages = []
|
|
@@ -365,8 +393,8 @@ class SnakeGame:
|
|
|
365
393
|
self.obstacles.clear()
|
|
366
394
|
for img in self.obstacleImages:
|
|
367
395
|
h, w, _ = img.shape
|
|
368
|
-
x = random.randint(150,
|
|
369
|
-
y = random.randint(50,
|
|
396
|
+
x = random.randint(150, 570)
|
|
397
|
+
y = random.randint(50, 570)
|
|
370
398
|
dx = random.choice([-5, 5])
|
|
371
399
|
dy = random.choice([-5, 5])
|
|
372
400
|
self.obstacles.append([x, y, w, h, dx, dy, img])
|
|
@@ -3,11 +3,10 @@ XMWAI/bomb_core.py,sha256=h2ZPH3SuoG2L_XOf1dcK8p3lhw5QzhneWl2yMLj1RiU,1819
|
|
|
3
3
|
XMWAI/core.py,sha256=rOXj7FnewSdnzBcFLjpnBtrOTCsvMfiycIcdPDagxho,10012
|
|
4
4
|
XMWAI/idiom_core.py,sha256=yU-VHhqqoutVm6GVikcjL3m9yuB1hUsFBpPYvwY4n5g,1689
|
|
5
5
|
XMWAI/magic_core.py,sha256=Ms4b12PJ8rjsmceg1VUqWCWx2ebvdhLp4sIF6K_Vaok,3491
|
|
6
|
-
XMWAI/snake_core.py,sha256=
|
|
6
|
+
XMWAI/snake_core.py,sha256=fMm65EUfEmJK9nat9EBKz-ysmo8luTDx8N3vZ320aZE,16055
|
|
7
7
|
XMWAI/trial_class.py,sha256=fPsl7BZvhzch2FOIG4azr999kjtoly53Acm3LqL8f98,9724
|
|
8
8
|
XMWAI/web_core.py,sha256=7awPg1kYW3lYrbgylqJvUF3g050bn6H21PgmQ7Kv1wA,10927
|
|
9
9
|
XMWAI/assets/1.png,sha256=eEuKH_M_q3tc_O2bYnuLOsRP-NlJHIbNg0pgrKXEEjw,139720
|
|
10
|
-
XMWAI/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
10
|
XMWAI/assets/g.png,sha256=hr9hlKJ7y95X-g6-tllrzDNgL1WQkbq5cA5L4jASEAM,11686
|
|
12
11
|
XMWAI/assets/h.png,sha256=qO-kJJOPA8qUth5rqLeOVa_6_n7tU-ABQ14O0EW_YCE,14929
|
|
13
12
|
XMWAI/assets/l.png,sha256=Urm6LxH33HID6ZZbs2oMViUk4GiZ3upLPdsrNU8FlP0,9921
|
|
@@ -117,8 +116,8 @@ XMWAI/static/images/tomato.png,sha256=FEOEAOdUhW_BDFgTpxOkYc0I5Iu29_gtHb3RIPEej0
|
|
|
117
116
|
XMWAI/templates/burger.html,sha256=vDnxpSW8phetyScySsalScZnFKl3LNpy5lJjKxGXgbI,3320
|
|
118
117
|
XMWAI/templates/nutrition_pie.html,sha256=yJVXI28i-UfvF0xOXGSNLMb8oCJNhh2J3zoRDr5_7DM,5567
|
|
119
118
|
XMWAI/templates/创意菜谱.html,sha256=RcDgH58QLyUJ9A59wobu3wvchGBY1snVsXcZQZam5M0,4805
|
|
120
|
-
xmwai-0.4.
|
|
121
|
-
xmwai-0.4.
|
|
122
|
-
xmwai-0.4.
|
|
123
|
-
xmwai-0.4.
|
|
124
|
-
xmwai-0.4.
|
|
119
|
+
xmwai-0.4.7.dist-info/licenses/LICENSE.txt,sha256=bcaIQMrIhdQ3O-PoZlexjmW6h-wLGvHxh5Oksl4ohtc,1066
|
|
120
|
+
xmwai-0.4.7.dist-info/METADATA,sha256=TFk6r7_ikJKUfVXu41zaNzzL1LppOUdYJGplWcZHQeg,1227
|
|
121
|
+
xmwai-0.4.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
122
|
+
xmwai-0.4.7.dist-info/top_level.txt,sha256=yvGcDI-sggK5jqd9wz0saipZvk3oIE3hNGHlqUjxf0c,6
|
|
123
|
+
xmwai-0.4.7.dist-info/RECORD,,
|
XMWAI/assets/__init__.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|