gamekit2d 0.2.0__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.
- gamekit2d-0.2.0/LICENSE +21 -0
- gamekit2d-0.2.0/MANIFEST.in +9 -0
- gamekit2d-0.2.0/PKG-INFO +316 -0
- gamekit2d-0.2.0/README.md +292 -0
- gamekit2d-0.2.0/TUTORIAL.html +908 -0
- gamekit2d-0.2.0/TUTORIAL.md +871 -0
- gamekit2d-0.2.0/examples/01_hello.py +64 -0
- gamekit2d-0.2.0/examples/02_pong.py +88 -0
- gamekit2d-0.2.0/examples/03_breakout.py +174 -0
- gamekit2d-0.2.0/examples/04_sprite_image.py +91 -0
- gamekit2d-0.2.0/examples/05_space_shooter.py +175 -0
- gamekit2d-0.2.0/examples/assets/coin1.png +0 -0
- gamekit2d-0.2.0/examples/assets/coin2.png +0 -0
- gamekit2d-0.2.0/examples/assets/player.png +0 -0
- gamekit2d-0.2.0/examples/assets/star.png +0 -0
- gamekit2d-0.2.0/examples/make_assets.py +75 -0
- gamekit2d-0.2.0/gamekit/__init__.py +63 -0
- gamekit2d-0.2.0/gamekit/audio/__init__.py +1 -0
- gamekit2d-0.2.0/gamekit/audio/sound.py +69 -0
- gamekit2d-0.2.0/gamekit/core/__init__.py +1 -0
- gamekit2d-0.2.0/gamekit/core/game.py +600 -0
- gamekit2d-0.2.0/gamekit/core/keys.py +122 -0
- gamekit2d-0.2.0/gamekit/core/scene.py +97 -0
- gamekit2d-0.2.0/gamekit/fx/__init__.py +1 -0
- gamekit2d-0.2.0/gamekit/fx/draw.py +243 -0
- gamekit2d-0.2.0/gamekit/fx/particles.py +85 -0
- gamekit2d-0.2.0/gamekit/physics/__init__.py +1 -0
- gamekit2d-0.2.0/gamekit/physics/collision.py +99 -0
- gamekit2d-0.2.0/gamekit/sprites/__init__.py +1 -0
- gamekit2d-0.2.0/gamekit/sprites/animation.py +61 -0
- gamekit2d-0.2.0/gamekit/sprites/image.py +158 -0
- gamekit2d-0.2.0/gamekit/sprites/sprite.py +382 -0
- gamekit2d-0.2.0/gamekit/ui/__init__.py +1 -0
- gamekit2d-0.2.0/gamekit/ui/text.py +61 -0
- gamekit2d-0.2.0/gamekit/ui/widgets.py +140 -0
- gamekit2d-0.2.0/gamekit/utils/__init__.py +1 -0
- gamekit2d-0.2.0/gamekit/utils/color.py +108 -0
- gamekit2d-0.2.0/gamekit/utils/vector.py +81 -0
- gamekit2d-0.2.0/gamekit2d.egg-info/PKG-INFO +316 -0
- gamekit2d-0.2.0/gamekit2d.egg-info/SOURCES.txt +46 -0
- gamekit2d-0.2.0/gamekit2d.egg-info/dependency_links.txt +1 -0
- gamekit2d-0.2.0/gamekit2d.egg-info/top_level.txt +1 -0
- gamekit2d-0.2.0/pyproject.toml +34 -0
- gamekit2d-0.2.0/setup.cfg +4 -0
- gamekit2d-0.2.0/tests/run_selftest.py +128 -0
- gamekit2d-0.2.0/tests/test_collision.py +107 -0
- gamekit2d-0.2.0/tests/test_draw.py +99 -0
- gamekit2d-0.2.0/tests/test_utils.py +102 -0
gamekit2d-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 gamekit contributors
|
|
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.
|
gamekit2d-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gamekit2d
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A tiny zero-dependency 2D game library (standard library only, tkinter + winsound). A simpler pygame.
|
|
5
|
+
Author: gamekit contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/your-name/gamekit
|
|
8
|
+
Project-URL: Repository, https://github.com/your-name/gamekit
|
|
9
|
+
Keywords: game,2d,game-engine,tkinter,zero-dependency,pygame-alternative
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Games/Entertainment
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# gamekit
|
|
26
|
+
|
|
27
|
+
> 一个**零第三方依赖**的极简 2D 游戏库 —— 只使用 Python 标准库,API 简单到极致,功能却相当齐全。
|
|
28
|
+
|
|
29
|
+
gamekit 的目标是:**让任何人用最少的代码,最快做出一个能玩的 2D 小游戏**。不需要懂窗口、事件循环、坐标系等底层细节,一个文件就能跑起一个完整游戏。
|
|
30
|
+
|
|
31
|
+
- 🚫 **零依赖**:只用 Python 标准库(`tkinter` 渲染 / `winsound` 音频),装好 Python 就能跑
|
|
32
|
+
- ✨ **极简 API**:`Game` 一个类搞定窗口、输入、精灵、碰撞、物理、音效、粒子、场景
|
|
33
|
+
- 🎮 **功能齐全**:精灵 / 图像 / 动画 / 碰撞 / 重力 / 音效 / 文字 / 按钮 / 进度条 / 粒子 / 场景切换
|
|
34
|
+
- 🪶 **轻量**:纯 Python 实现,核心约 2000 行,结构清晰可读
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 安装
|
|
39
|
+
|
|
40
|
+
### 方式一:直接使用源码(推荐,零配置)
|
|
41
|
+
|
|
42
|
+
把 `gamekit/` 目录放到你的项目旁边,然后直接 `import gamekit`:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/your-name/gamekit.git
|
|
46
|
+
cd gamekit
|
|
47
|
+
python examples/01_hello.py # 直接运行示例
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 方式二:pip 安装
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install gamekit
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> 无论哪种方式都**不需要安装任何第三方包**。运行环境只需 Python 3.9+(Windows / Linux / macOS 均可,音频仅 Windows 支持,其他平台自动静默降级)。
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 快速上手
|
|
61
|
+
|
|
62
|
+
这是你能写出的最短游戏 —— **40 秒学会**:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from gamekit import Game, Key
|
|
66
|
+
|
|
67
|
+
# 1. 创建游戏
|
|
68
|
+
game = Game(title="我的第一个游戏", width=800, height=600, fps=60)
|
|
69
|
+
|
|
70
|
+
# 2. 创建精灵(一个红色矩形)
|
|
71
|
+
player = game.sprite(color="red", x=400, y=300, width=60, height=40)
|
|
72
|
+
|
|
73
|
+
# 3. 绑定按键
|
|
74
|
+
@game.on_key(Key.LEFT)
|
|
75
|
+
def left():
|
|
76
|
+
player.vx = -300
|
|
77
|
+
|
|
78
|
+
@game.on_key(Key.RIGHT)
|
|
79
|
+
def right():
|
|
80
|
+
player.vx = 300
|
|
81
|
+
|
|
82
|
+
@game.on_key(Key.SPACE)
|
|
83
|
+
def stop():
|
|
84
|
+
player.vx = 0
|
|
85
|
+
|
|
86
|
+
# 4. 启动游戏
|
|
87
|
+
game.run()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
运行后:按 ← → 移动方块,按空格停下。**一个可玩的游戏就完成了。**
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 功能总览
|
|
95
|
+
|
|
96
|
+
| 功能 | 说明 | 快速示例 |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| 🖼 精灵 | 图像 / 纯色 / 圆形,位置速度、旋转缩放 | `game.sprite("player.png", x=100, y=100)` |
|
|
99
|
+
| ⌨️ 键盘 | 按下 / 抬起 / 持续按住 | `@game.on_key(Key.SPACE)` |
|
|
100
|
+
| 🖱 鼠标 | 移动 / 点击 / 滚轮 | `@game.on_mouse_click` |
|
|
101
|
+
| 💥 碰撞 | 矩形 + 圆形,自动检测进入瞬间 | `@game.on_collide(player, "coin")` |
|
|
102
|
+
| 🌍 物理 | 重力、摩擦、反弹、屏幕边界 | `sprite.gravity_scale = 1.0` |
|
|
103
|
+
| 🎞 动画 | 多帧图像循环播放 | `sprite.play(["a.png", "b.png"], fps=8)` |
|
|
104
|
+
| 🔊 音频 | WAV 音效 / 循环背景乐 | `game.sound("hit.wav").play()` |
|
|
105
|
+
| 📝 文字 | 任意字体 / 字号 / 加粗 | `game.text("得分 0", x=30, y=30)` |
|
|
106
|
+
| 🔘 UI | 按钮(悬停高亮)、进度条 | `game.button("开始", on_click=fn)` |
|
|
107
|
+
| ✨ 粒子 | 爆炸 / 火花 / 飘雪 | `game.burst(x, y, count=40)` |
|
|
108
|
+
| 🎬 场景 | 菜单 / 关卡 / 结束画面切换 | `game.switch_scene(MyScene())` |
|
|
109
|
+
| ⏱ 定时器 | 延迟调用 / 周期调用 | `game.every(0.5, fn)` |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 完整示例:收集金币
|
|
114
|
+
|
|
115
|
+
一个集精灵、物理、碰撞、粒子、计分于一体的微型游戏(约 30 行):
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from gamekit import Game, Key
|
|
119
|
+
|
|
120
|
+
game = Game(title="收集金币", width=800, height=600, fps=60)
|
|
121
|
+
game.bg_color = "#141a24"
|
|
122
|
+
game.gravity = 600
|
|
123
|
+
|
|
124
|
+
# 玩家(受重力)
|
|
125
|
+
player = game.sprite(color="#4ac0f0", x=400, y=300, width=44, height=44)
|
|
126
|
+
player.gravity_scale = 1.0
|
|
127
|
+
player.keep_on_screen = True
|
|
128
|
+
|
|
129
|
+
# 地面
|
|
130
|
+
ground = game.sprite(color="#2a3342", x=400, y=580, width=800, height=40)
|
|
131
|
+
|
|
132
|
+
# 金币
|
|
133
|
+
score = [0]
|
|
134
|
+
score_text = game.text("金币:0", x=400, y=30, size=24, bold=True)
|
|
135
|
+
coin_n = [0]
|
|
136
|
+
|
|
137
|
+
def spawn_coin():
|
|
138
|
+
coin_n[0] += 1
|
|
139
|
+
return game.sprite(color="#ffd700", x=60 + (coin_n[0] * 61) % 680,
|
|
140
|
+
y=400 + (coin_n[0] * 23) % 130,
|
|
141
|
+
width=26, height=26, shape="circle", tag="coin")
|
|
142
|
+
|
|
143
|
+
for _ in range(8):
|
|
144
|
+
spawn_coin()
|
|
145
|
+
|
|
146
|
+
@game.on_key(Key.SPACE)
|
|
147
|
+
def jump():
|
|
148
|
+
if player.bottom >= ground.top - 2:
|
|
149
|
+
player.vy = -420
|
|
150
|
+
|
|
151
|
+
@game.on_key_hold(Key.LEFT)
|
|
152
|
+
def move_left():
|
|
153
|
+
player.vx = -260
|
|
154
|
+
|
|
155
|
+
@game.on_key_hold(Key.RIGHT)
|
|
156
|
+
def move_right():
|
|
157
|
+
player.vx = 260
|
|
158
|
+
|
|
159
|
+
@game.on_key(Key.ESCAPE)
|
|
160
|
+
def quit_game():
|
|
161
|
+
game.stop()
|
|
162
|
+
|
|
163
|
+
@game.on_collide(player, ground)
|
|
164
|
+
def land(p, g):
|
|
165
|
+
if p.vy > 0: # 只在向下落时落地
|
|
166
|
+
p.y = g.top - p.height / 2
|
|
167
|
+
p.vy = 0
|
|
168
|
+
|
|
169
|
+
@game.on_collide(player, "coin")
|
|
170
|
+
def collect(p, c):
|
|
171
|
+
c.remove()
|
|
172
|
+
score[0] += 1
|
|
173
|
+
game.burst(c.x, c.y, count=18, colors=("gold", "white", "orange"))
|
|
174
|
+
score_text.set("金币:%d" % score[0])
|
|
175
|
+
|
|
176
|
+
game.run()
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## 运行示例小游戏
|
|
182
|
+
|
|
183
|
+
项目自带 4 个由浅入深的完整示例(`examples/` 目录):
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
python examples/01_hello.py # 最小游戏:反弹小球 + 暂停/变色
|
|
187
|
+
python examples/02_pong.py # 双人乒乓球(键盘对战)
|
|
188
|
+
python examples/03_breakout.py # 打砖块(完整小游戏:场景/UI/粒子/计分/生命)
|
|
189
|
+
python examples/04_sprite_image.py # 图像精灵:旋转/缩放/帧动画
|
|
190
|
+
python examples/05_space_shooter.py# 太空射击(综合实战:键盘/碰撞/粒子/场景)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
> 使用图像精灵的示例请先运行 `python examples/make_assets.py` 生成素材。
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 📖 完整教程
|
|
198
|
+
|
|
199
|
+
想从零系统学习?请看 **[TUTORIAL.md](TUTORIAL.md)** —— 13 章手把手教程,
|
|
200
|
+
从"第一个窗口"到"完整太空射击游戏",每章代码都可直接运行。
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## API 速查
|
|
205
|
+
|
|
206
|
+
### Game(游戏)
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
Game(title="标题", width=800, height=600, fps=60, bg_color="#14141a")
|
|
210
|
+
game.run() / game.stop()
|
|
211
|
+
game.sprite(...) # 创建精灵
|
|
212
|
+
game.text(...) # 创建文字
|
|
213
|
+
game.button(...) # 创建按钮
|
|
214
|
+
game.progress_bar(...)# 创建进度条
|
|
215
|
+
game.sound(path) # 加载音效
|
|
216
|
+
game.music(path) # 加载循环背景乐
|
|
217
|
+
game.particles(...) # 粒子系统
|
|
218
|
+
game.burst(x, y, ...) # 一次粒子爆发
|
|
219
|
+
game.add_scene(s) / game.switch_scene(s) # 场景管理
|
|
220
|
+
game.after(sec, fn) / game.every(sec, fn) # 定时器
|
|
221
|
+
game.gravity # 全局重力(像素/秒²)
|
|
222
|
+
game.dt / game.time # 帧耗时 / 累计时间
|
|
223
|
+
game.is_key_down(key) # 按键是否按住
|
|
224
|
+
game.find(tag) # 按标签查找精灵
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 事件装饰器
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
@game.on_update # 每帧更新 fn(dt)
|
|
231
|
+
@game.on_key(Key.SPACE) # 按键按下 fn()
|
|
232
|
+
@game.on_key_up(Key.SPACE) # 按键抬起 fn()
|
|
233
|
+
@game.on_key_hold(Key.LEFT) # 按住持续 fn(dt)
|
|
234
|
+
@game.on_mouse_click # 左键点击 fn(x, y)
|
|
235
|
+
@game.on_mouse_move # 鼠标移动 fn(x, y)
|
|
236
|
+
@game.on_mouse_down / up # 按下/抬起 fn(x, y, button)
|
|
237
|
+
@game.on_mouse_wheel # 滚轮 fn(delta, x, y)
|
|
238
|
+
@game.on_collide(a, b) # 碰撞进入 fn(a, b) a/b 可为精灵或标签
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Sprite(精灵)
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
s = game.sprite(image="a.png" | color="red", x=0, y=0,
|
|
245
|
+
width=40, height=40, shape="rect|circle", tag="enemy")
|
|
246
|
+
s.x / s.y / s.vx / s.vy # 位置与速度(像素/秒)
|
|
247
|
+
s.move(dx, dy) / s.move_to(x, y)
|
|
248
|
+
s.set_scale(f) / s.set_angle(deg) # 缩放 / 旋转(图像精灵)
|
|
249
|
+
s.play([f1, f2], fps=8, loop=True) # 帧动画
|
|
250
|
+
s.hide() / s.show() / s.remove()
|
|
251
|
+
s.collides_with(other) # 是否碰撞
|
|
252
|
+
s.bounce_off(other) # 按重叠方向反弹
|
|
253
|
+
s.gravity_scale / s.friction / s.bounce / s.keep_on_screen
|
|
254
|
+
s.on_update = lambda dt: ... # 单精灵每帧逻辑
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Key(按键常量)
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
Key.SPACE / Key.UP / Key.DOWN / Key.LEFT / Key.RIGHT
|
|
261
|
+
Key.ENTER / Key.ESC / Key.TAB / Key.BACKSPACE
|
|
262
|
+
Key.SHIFT / Key.CTRL / Key.ALT
|
|
263
|
+
Key.A ~ Key.Z / Key.F1 ~ Key.F12
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
也可以直接传字符串:`"space"`、`"a"`、`"F5"`(大小写均可)。
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## 项目结构
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
gamekit/
|
|
274
|
+
├── gamekit/
|
|
275
|
+
│ ├── core/ # 核心引擎:Game 主类、场景、事件、按键
|
|
276
|
+
│ ├── sprites/ # 精灵、图像处理(自研缩放/旋转)、帧动画
|
|
277
|
+
│ ├── physics/ # 碰撞检测(矩形/圆形)
|
|
278
|
+
│ ├── audio/ # WAV 音效(winsound)
|
|
279
|
+
│ ├── ui/ # 文字、按钮、进度条
|
|
280
|
+
│ ├── fx/ # 粒子系统
|
|
281
|
+
│ └── utils/ # 颜色、向量工具
|
|
282
|
+
├── examples/ # 4 个完整示例 + 素材生成脚本
|
|
283
|
+
├── tests/ # 单元测试 + GUI 冒烟测试
|
|
284
|
+
├── pyproject.toml # 发布配置(零依赖)
|
|
285
|
+
└── README.md
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 已知限制(标准库方案的能力边界)
|
|
291
|
+
|
|
292
|
+
由于坚持零第三方依赖,有以下取舍,**请按需评估**:
|
|
293
|
+
|
|
294
|
+
| 能力 | 限制 | 说明 |
|
|
295
|
+
|---|---|---|
|
|
296
|
+
| 音频 | 仅 `.wav`,仅 Windows,一次一个 | 标准库 `winsound` 的能力边界;其他平台自动静默 |
|
|
297
|
+
| 图像格式 | PNG / GIF / PPM / BMP | 不支持 JPG(Tk 无解码器),可用 PNG 替代 |
|
|
298
|
+
| 旋转/缩放 | 最近邻算法,大图较慢 | 适合 200×200 以下的小图,在加载时调用一次 |
|
|
299
|
+
| 渲染性能 | 每帧全量重绘 | 适合教学、原型、小规模游戏;大量精灵(>500)会掉帧 |
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## 测试
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
python -m unittest discover -s tests -p "test_*.py" # 单元测试(碰撞/颜色/向量/按键)
|
|
307
|
+
python tests/run_selftest.py # GUI 冒烟测试(自动运行 120 帧)
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## 许可
|
|
313
|
+
|
|
314
|
+
[MIT](LICENSE) © gamekit contributors
|
|
315
|
+
|
|
316
|
+
用游戏kit,做个游戏吧 🎮
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# gamekit
|
|
2
|
+
|
|
3
|
+
> 一个**零第三方依赖**的极简 2D 游戏库 —— 只使用 Python 标准库,API 简单到极致,功能却相当齐全。
|
|
4
|
+
|
|
5
|
+
gamekit 的目标是:**让任何人用最少的代码,最快做出一个能玩的 2D 小游戏**。不需要懂窗口、事件循环、坐标系等底层细节,一个文件就能跑起一个完整游戏。
|
|
6
|
+
|
|
7
|
+
- 🚫 **零依赖**:只用 Python 标准库(`tkinter` 渲染 / `winsound` 音频),装好 Python 就能跑
|
|
8
|
+
- ✨ **极简 API**:`Game` 一个类搞定窗口、输入、精灵、碰撞、物理、音效、粒子、场景
|
|
9
|
+
- 🎮 **功能齐全**:精灵 / 图像 / 动画 / 碰撞 / 重力 / 音效 / 文字 / 按钮 / 进度条 / 粒子 / 场景切换
|
|
10
|
+
- 🪶 **轻量**:纯 Python 实现,核心约 2000 行,结构清晰可读
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
### 方式一:直接使用源码(推荐,零配置)
|
|
17
|
+
|
|
18
|
+
把 `gamekit/` 目录放到你的项目旁边,然后直接 `import gamekit`:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
git clone https://github.com/your-name/gamekit.git
|
|
22
|
+
cd gamekit
|
|
23
|
+
python examples/01_hello.py # 直接运行示例
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 方式二:pip 安装
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install gamekit
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
> 无论哪种方式都**不需要安装任何第三方包**。运行环境只需 Python 3.9+(Windows / Linux / macOS 均可,音频仅 Windows 支持,其他平台自动静默降级)。
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 快速上手
|
|
37
|
+
|
|
38
|
+
这是你能写出的最短游戏 —— **40 秒学会**:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from gamekit import Game, Key
|
|
42
|
+
|
|
43
|
+
# 1. 创建游戏
|
|
44
|
+
game = Game(title="我的第一个游戏", width=800, height=600, fps=60)
|
|
45
|
+
|
|
46
|
+
# 2. 创建精灵(一个红色矩形)
|
|
47
|
+
player = game.sprite(color="red", x=400, y=300, width=60, height=40)
|
|
48
|
+
|
|
49
|
+
# 3. 绑定按键
|
|
50
|
+
@game.on_key(Key.LEFT)
|
|
51
|
+
def left():
|
|
52
|
+
player.vx = -300
|
|
53
|
+
|
|
54
|
+
@game.on_key(Key.RIGHT)
|
|
55
|
+
def right():
|
|
56
|
+
player.vx = 300
|
|
57
|
+
|
|
58
|
+
@game.on_key(Key.SPACE)
|
|
59
|
+
def stop():
|
|
60
|
+
player.vx = 0
|
|
61
|
+
|
|
62
|
+
# 4. 启动游戏
|
|
63
|
+
game.run()
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
运行后:按 ← → 移动方块,按空格停下。**一个可玩的游戏就完成了。**
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 功能总览
|
|
71
|
+
|
|
72
|
+
| 功能 | 说明 | 快速示例 |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| 🖼 精灵 | 图像 / 纯色 / 圆形,位置速度、旋转缩放 | `game.sprite("player.png", x=100, y=100)` |
|
|
75
|
+
| ⌨️ 键盘 | 按下 / 抬起 / 持续按住 | `@game.on_key(Key.SPACE)` |
|
|
76
|
+
| 🖱 鼠标 | 移动 / 点击 / 滚轮 | `@game.on_mouse_click` |
|
|
77
|
+
| 💥 碰撞 | 矩形 + 圆形,自动检测进入瞬间 | `@game.on_collide(player, "coin")` |
|
|
78
|
+
| 🌍 物理 | 重力、摩擦、反弹、屏幕边界 | `sprite.gravity_scale = 1.0` |
|
|
79
|
+
| 🎞 动画 | 多帧图像循环播放 | `sprite.play(["a.png", "b.png"], fps=8)` |
|
|
80
|
+
| 🔊 音频 | WAV 音效 / 循环背景乐 | `game.sound("hit.wav").play()` |
|
|
81
|
+
| 📝 文字 | 任意字体 / 字号 / 加粗 | `game.text("得分 0", x=30, y=30)` |
|
|
82
|
+
| 🔘 UI | 按钮(悬停高亮)、进度条 | `game.button("开始", on_click=fn)` |
|
|
83
|
+
| ✨ 粒子 | 爆炸 / 火花 / 飘雪 | `game.burst(x, y, count=40)` |
|
|
84
|
+
| 🎬 场景 | 菜单 / 关卡 / 结束画面切换 | `game.switch_scene(MyScene())` |
|
|
85
|
+
| ⏱ 定时器 | 延迟调用 / 周期调用 | `game.every(0.5, fn)` |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 完整示例:收集金币
|
|
90
|
+
|
|
91
|
+
一个集精灵、物理、碰撞、粒子、计分于一体的微型游戏(约 30 行):
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from gamekit import Game, Key
|
|
95
|
+
|
|
96
|
+
game = Game(title="收集金币", width=800, height=600, fps=60)
|
|
97
|
+
game.bg_color = "#141a24"
|
|
98
|
+
game.gravity = 600
|
|
99
|
+
|
|
100
|
+
# 玩家(受重力)
|
|
101
|
+
player = game.sprite(color="#4ac0f0", x=400, y=300, width=44, height=44)
|
|
102
|
+
player.gravity_scale = 1.0
|
|
103
|
+
player.keep_on_screen = True
|
|
104
|
+
|
|
105
|
+
# 地面
|
|
106
|
+
ground = game.sprite(color="#2a3342", x=400, y=580, width=800, height=40)
|
|
107
|
+
|
|
108
|
+
# 金币
|
|
109
|
+
score = [0]
|
|
110
|
+
score_text = game.text("金币:0", x=400, y=30, size=24, bold=True)
|
|
111
|
+
coin_n = [0]
|
|
112
|
+
|
|
113
|
+
def spawn_coin():
|
|
114
|
+
coin_n[0] += 1
|
|
115
|
+
return game.sprite(color="#ffd700", x=60 + (coin_n[0] * 61) % 680,
|
|
116
|
+
y=400 + (coin_n[0] * 23) % 130,
|
|
117
|
+
width=26, height=26, shape="circle", tag="coin")
|
|
118
|
+
|
|
119
|
+
for _ in range(8):
|
|
120
|
+
spawn_coin()
|
|
121
|
+
|
|
122
|
+
@game.on_key(Key.SPACE)
|
|
123
|
+
def jump():
|
|
124
|
+
if player.bottom >= ground.top - 2:
|
|
125
|
+
player.vy = -420
|
|
126
|
+
|
|
127
|
+
@game.on_key_hold(Key.LEFT)
|
|
128
|
+
def move_left():
|
|
129
|
+
player.vx = -260
|
|
130
|
+
|
|
131
|
+
@game.on_key_hold(Key.RIGHT)
|
|
132
|
+
def move_right():
|
|
133
|
+
player.vx = 260
|
|
134
|
+
|
|
135
|
+
@game.on_key(Key.ESCAPE)
|
|
136
|
+
def quit_game():
|
|
137
|
+
game.stop()
|
|
138
|
+
|
|
139
|
+
@game.on_collide(player, ground)
|
|
140
|
+
def land(p, g):
|
|
141
|
+
if p.vy > 0: # 只在向下落时落地
|
|
142
|
+
p.y = g.top - p.height / 2
|
|
143
|
+
p.vy = 0
|
|
144
|
+
|
|
145
|
+
@game.on_collide(player, "coin")
|
|
146
|
+
def collect(p, c):
|
|
147
|
+
c.remove()
|
|
148
|
+
score[0] += 1
|
|
149
|
+
game.burst(c.x, c.y, count=18, colors=("gold", "white", "orange"))
|
|
150
|
+
score_text.set("金币:%d" % score[0])
|
|
151
|
+
|
|
152
|
+
game.run()
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 运行示例小游戏
|
|
158
|
+
|
|
159
|
+
项目自带 4 个由浅入深的完整示例(`examples/` 目录):
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
python examples/01_hello.py # 最小游戏:反弹小球 + 暂停/变色
|
|
163
|
+
python examples/02_pong.py # 双人乒乓球(键盘对战)
|
|
164
|
+
python examples/03_breakout.py # 打砖块(完整小游戏:场景/UI/粒子/计分/生命)
|
|
165
|
+
python examples/04_sprite_image.py # 图像精灵:旋转/缩放/帧动画
|
|
166
|
+
python examples/05_space_shooter.py# 太空射击(综合实战:键盘/碰撞/粒子/场景)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
> 使用图像精灵的示例请先运行 `python examples/make_assets.py` 生成素材。
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 📖 完整教程
|
|
174
|
+
|
|
175
|
+
想从零系统学习?请看 **[TUTORIAL.md](TUTORIAL.md)** —— 13 章手把手教程,
|
|
176
|
+
从"第一个窗口"到"完整太空射击游戏",每章代码都可直接运行。
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## API 速查
|
|
181
|
+
|
|
182
|
+
### Game(游戏)
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
Game(title="标题", width=800, height=600, fps=60, bg_color="#14141a")
|
|
186
|
+
game.run() / game.stop()
|
|
187
|
+
game.sprite(...) # 创建精灵
|
|
188
|
+
game.text(...) # 创建文字
|
|
189
|
+
game.button(...) # 创建按钮
|
|
190
|
+
game.progress_bar(...)# 创建进度条
|
|
191
|
+
game.sound(path) # 加载音效
|
|
192
|
+
game.music(path) # 加载循环背景乐
|
|
193
|
+
game.particles(...) # 粒子系统
|
|
194
|
+
game.burst(x, y, ...) # 一次粒子爆发
|
|
195
|
+
game.add_scene(s) / game.switch_scene(s) # 场景管理
|
|
196
|
+
game.after(sec, fn) / game.every(sec, fn) # 定时器
|
|
197
|
+
game.gravity # 全局重力(像素/秒²)
|
|
198
|
+
game.dt / game.time # 帧耗时 / 累计时间
|
|
199
|
+
game.is_key_down(key) # 按键是否按住
|
|
200
|
+
game.find(tag) # 按标签查找精灵
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 事件装饰器
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
@game.on_update # 每帧更新 fn(dt)
|
|
207
|
+
@game.on_key(Key.SPACE) # 按键按下 fn()
|
|
208
|
+
@game.on_key_up(Key.SPACE) # 按键抬起 fn()
|
|
209
|
+
@game.on_key_hold(Key.LEFT) # 按住持续 fn(dt)
|
|
210
|
+
@game.on_mouse_click # 左键点击 fn(x, y)
|
|
211
|
+
@game.on_mouse_move # 鼠标移动 fn(x, y)
|
|
212
|
+
@game.on_mouse_down / up # 按下/抬起 fn(x, y, button)
|
|
213
|
+
@game.on_mouse_wheel # 滚轮 fn(delta, x, y)
|
|
214
|
+
@game.on_collide(a, b) # 碰撞进入 fn(a, b) a/b 可为精灵或标签
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Sprite(精灵)
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
s = game.sprite(image="a.png" | color="red", x=0, y=0,
|
|
221
|
+
width=40, height=40, shape="rect|circle", tag="enemy")
|
|
222
|
+
s.x / s.y / s.vx / s.vy # 位置与速度(像素/秒)
|
|
223
|
+
s.move(dx, dy) / s.move_to(x, y)
|
|
224
|
+
s.set_scale(f) / s.set_angle(deg) # 缩放 / 旋转(图像精灵)
|
|
225
|
+
s.play([f1, f2], fps=8, loop=True) # 帧动画
|
|
226
|
+
s.hide() / s.show() / s.remove()
|
|
227
|
+
s.collides_with(other) # 是否碰撞
|
|
228
|
+
s.bounce_off(other) # 按重叠方向反弹
|
|
229
|
+
s.gravity_scale / s.friction / s.bounce / s.keep_on_screen
|
|
230
|
+
s.on_update = lambda dt: ... # 单精灵每帧逻辑
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Key(按键常量)
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
Key.SPACE / Key.UP / Key.DOWN / Key.LEFT / Key.RIGHT
|
|
237
|
+
Key.ENTER / Key.ESC / Key.TAB / Key.BACKSPACE
|
|
238
|
+
Key.SHIFT / Key.CTRL / Key.ALT
|
|
239
|
+
Key.A ~ Key.Z / Key.F1 ~ Key.F12
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
也可以直接传字符串:`"space"`、`"a"`、`"F5"`(大小写均可)。
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 项目结构
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
gamekit/
|
|
250
|
+
├── gamekit/
|
|
251
|
+
│ ├── core/ # 核心引擎:Game 主类、场景、事件、按键
|
|
252
|
+
│ ├── sprites/ # 精灵、图像处理(自研缩放/旋转)、帧动画
|
|
253
|
+
│ ├── physics/ # 碰撞检测(矩形/圆形)
|
|
254
|
+
│ ├── audio/ # WAV 音效(winsound)
|
|
255
|
+
│ ├── ui/ # 文字、按钮、进度条
|
|
256
|
+
│ ├── fx/ # 粒子系统
|
|
257
|
+
│ └── utils/ # 颜色、向量工具
|
|
258
|
+
├── examples/ # 4 个完整示例 + 素材生成脚本
|
|
259
|
+
├── tests/ # 单元测试 + GUI 冒烟测试
|
|
260
|
+
├── pyproject.toml # 发布配置(零依赖)
|
|
261
|
+
└── README.md
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## 已知限制(标准库方案的能力边界)
|
|
267
|
+
|
|
268
|
+
由于坚持零第三方依赖,有以下取舍,**请按需评估**:
|
|
269
|
+
|
|
270
|
+
| 能力 | 限制 | 说明 |
|
|
271
|
+
|---|---|---|
|
|
272
|
+
| 音频 | 仅 `.wav`,仅 Windows,一次一个 | 标准库 `winsound` 的能力边界;其他平台自动静默 |
|
|
273
|
+
| 图像格式 | PNG / GIF / PPM / BMP | 不支持 JPG(Tk 无解码器),可用 PNG 替代 |
|
|
274
|
+
| 旋转/缩放 | 最近邻算法,大图较慢 | 适合 200×200 以下的小图,在加载时调用一次 |
|
|
275
|
+
| 渲染性能 | 每帧全量重绘 | 适合教学、原型、小规模游戏;大量精灵(>500)会掉帧 |
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## 测试
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
python -m unittest discover -s tests -p "test_*.py" # 单元测试(碰撞/颜色/向量/按键)
|
|
283
|
+
python tests/run_selftest.py # GUI 冒烟测试(自动运行 120 帧)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## 许可
|
|
289
|
+
|
|
290
|
+
[MIT](LICENSE) © gamekit contributors
|
|
291
|
+
|
|
292
|
+
用游戏kit,做个游戏吧 🎮
|