Compare commits
No commits in common. "master" and "0.9.1.0" have entirely different histories.
7
.github/workflows/build-pr.yml
vendored
7
.github/workflows/build-pr.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python_version:
|
python_version:
|
||||||
- "3.12"
|
- "3.11"
|
||||||
name: Windows Python ${{ matrix.python_version }}
|
name: Windows Python ${{ matrix.python_version }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@ -46,7 +46,6 @@ jobs:
|
|||||||
-i ./pypvz.ico
|
-i ./pypvz.ico
|
||||||
|
|
||||||
- name: Release the version built by pyinstaller
|
- name: Release the version built by pyinstaller
|
||||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
@ -78,7 +77,6 @@ jobs:
|
|||||||
pypvz.py
|
pypvz.py
|
||||||
|
|
||||||
- name: Release the version built by nuitka
|
- name: Release the version built by nuitka
|
||||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
@ -93,7 +91,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python_version:
|
python_version:
|
||||||
- "3.12"
|
- "3.11"
|
||||||
name: Ubuntu Python ${{ matrix.python_version }}
|
name: Ubuntu Python ${{ matrix.python_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: 🛎️ Checkout
|
- name: 🛎️ Checkout
|
||||||
@ -133,7 +131,6 @@ jobs:
|
|||||||
pypvz.py
|
pypvz.py
|
||||||
|
|
||||||
- name: Release the version built by nuitka
|
- name: Release the version built by nuitka
|
||||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
|
|||||||
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python_version:
|
python_version:
|
||||||
- "3.12"
|
- "3.11"
|
||||||
name: Windows Python ${{ matrix.python_version }}
|
name: Windows Python ${{ matrix.python_version }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@ -93,7 +93,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python_version:
|
python_version:
|
||||||
- "3.12"
|
- "3.11"
|
||||||
name: Ubuntu Python ${{ matrix.python_version }}
|
name: Ubuntu Python ${{ matrix.python_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: 🛎️ Checkout
|
- name: 🛎️ Checkout
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -4,11 +4,7 @@ test-build/
|
|||||||
release/
|
release/
|
||||||
# 忽略调试内容
|
# 忽略调试内容
|
||||||
.vscode/
|
.vscode/
|
||||||
# 忽略 Pycharm 项目文件
|
|
||||||
.idea/
|
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*/__pycache__/
|
*/__pycache__/
|
||||||
# 忽略测试文件
|
# 忽略测试文件
|
||||||
test*.py
|
test*.py
|
||||||
# uv 管理的虚拟环境
|
|
||||||
.venv
|
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
3.12
|
|
||||||
12
README.md
12
README.md
@ -38,17 +38,7 @@
|
|||||||
* 光标移动到向日葵奖杯上是显示当前各个模式通关次数
|
* 光标移动到向日葵奖杯上是显示当前各个模式通关次数
|
||||||
* 含有游戏帮助界面 QwQ
|
* 含有游戏帮助界面 QwQ
|
||||||
|
|
||||||
## 环境安装
|
## 环境要求
|
||||||
|
|
||||||
建议使用 [uv](https://docs.astral.sh/uv/) 安装依赖:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/wszqkzqk/pypvz.git
|
|
||||||
cd pypvz
|
|
||||||
uv sync
|
|
||||||
```
|
|
||||||
|
|
||||||
或者参考:
|
|
||||||
|
|
||||||
* `Python3` (建议 >= 3.10,最好使用最新版)
|
* `Python3` (建议 >= 3.10,最好使用最新版)
|
||||||
* `Python-Pygame` (建议 >= 2.0,最好使用最新版)
|
* `Python-Pygame` (建议 >= 2.0,最好使用最新版)
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
[project]
|
|
||||||
name = "pypvz"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = "Add your description here"
|
|
||||||
readme = "README.md"
|
|
||||||
requires-python = ">=3.12"
|
|
||||||
dependencies = [
|
|
||||||
"blue>=0.9.1",
|
|
||||||
"pygame>=2.6.1",
|
|
||||||
"setuptools>=80.9.0",
|
|
||||||
"wheel>=0.45.1",
|
|
||||||
]
|
|
||||||
29
pypvz.py
29
pypvz.py
@ -1,30 +1,24 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import traceback
|
import traceback
|
||||||
from logging.handlers import RotatingFileHandler
|
import os
|
||||||
|
|
||||||
import pygame as pg
|
import pygame as pg
|
||||||
|
from logging.handlers import RotatingFileHandler
|
||||||
# 由于在后续本地模块中存在对pygame的调用,在此处必须完成pygame的初始化
|
# 由于在后续本地模块中存在对pygame的调用,在此处必须完成pygame的初始化
|
||||||
os.environ[
|
os.environ["SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"]="0" # 设置临时环境变量以避免Linux下禁用x11合成器
|
||||||
'SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR'
|
|
||||||
] = '0' # 设置临时环境变量以避免Linux下禁用x11合成器
|
|
||||||
pg.init()
|
pg.init()
|
||||||
|
|
||||||
from source import constants as c
|
|
||||||
from source import tool
|
from source import tool
|
||||||
from source.state import level, mainmenu, screen
|
from source import constants as c
|
||||||
|
from source.state import mainmenu, screen, level
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
# 日志设置
|
# 日志设置
|
||||||
if not os.path.exists(os.path.dirname(c.USERLOG_PATH)):
|
if not os.path.exists(os.path.dirname(c.USERLOG_PATH)):
|
||||||
os.makedirs(os.path.dirname(c.USERLOG_PATH))
|
os.makedirs(os.path.dirname(c.USERLOG_PATH))
|
||||||
logger = logging.getLogger('main')
|
logger = logging.getLogger("main")
|
||||||
formatter = logging.Formatter('%(asctime)s - %(levelname)s: %(message)s')
|
formatter = logging.Formatter("%(asctime)s - %(levelname)s: %(message)s")
|
||||||
fileHandler = RotatingFileHandler(
|
fileHandler = RotatingFileHandler(c.USERLOG_PATH, "a", 1_000_000, 0, "utf-8")
|
||||||
c.USERLOG_PATH, 'a', 1_000_000, 0, 'utf-8'
|
|
||||||
)
|
|
||||||
# 设置日志文件权限,Unix为644,Windows为可读写;Python的os.chmod与Unix chmod相同,但要显式说明8进制
|
# 设置日志文件权限,Unix为644,Windows为可读写;Python的os.chmod与Unix chmod相同,但要显式说明8进制
|
||||||
os.chmod(c.USERLOG_PATH, 0o644)
|
os.chmod(c.USERLOG_PATH, 0o644)
|
||||||
fileHandler.setFormatter(formatter)
|
fileHandler.setFormatter(formatter)
|
||||||
@ -36,8 +30,7 @@ if __name__ == '__main__':
|
|||||||
try:
|
try:
|
||||||
# 控制状态机运行
|
# 控制状态机运行
|
||||||
game = tool.Control()
|
game = tool.Control()
|
||||||
state_dict = {
|
state_dict = { c.MAIN_MENU: mainmenu.Menu(),
|
||||||
c.MAIN_MENU: mainmenu.Menu(),
|
|
||||||
c.GAME_VICTORY: screen.GameVictoryScreen(),
|
c.GAME_VICTORY: screen.GameVictoryScreen(),
|
||||||
c.GAME_LOSE: screen.GameLoseScreen(),
|
c.GAME_LOSE: screen.GameLoseScreen(),
|
||||||
c.LEVEL: level.Level(),
|
c.LEVEL: level.Level(),
|
||||||
@ -48,4 +41,4 @@ if __name__ == '__main__':
|
|||||||
game.run()
|
game.run()
|
||||||
except:
|
except:
|
||||||
print() # 将日志输出与上文内容分隔开,增加可读性
|
print() # 将日志输出与上文内容分隔开,增加可读性
|
||||||
logger.error(f'\n{traceback.format_exc()}')
|
logger.error(f"\n{traceback.format_exc()}")
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
from .. import constants as c
|
from .. import constants as c
|
||||||
|
|
||||||
|
|
||||||
# 记录植物种植情况的地图管理工具
|
# 记录植物种植情况的地图管理工具
|
||||||
class Map:
|
class Map():
|
||||||
def __init__(self, background_type:int):
|
def __init__(self, background_type:int):
|
||||||
self.background_type = background_type
|
self.background_type = background_type
|
||||||
# 注意:从0开始编号
|
# 注意:从0开始编号
|
||||||
@ -12,10 +10,7 @@ class Map:
|
|||||||
self.width = c.GRID_POOL_X_LEN
|
self.width = c.GRID_POOL_X_LEN
|
||||||
self.height = c.GRID_POOL_Y_LEN
|
self.height = c.GRID_POOL_Y_LEN
|
||||||
self.grid_height_size = c.GRID_POOL_Y_SIZE
|
self.grid_height_size = c.GRID_POOL_Y_SIZE
|
||||||
self.map = [
|
self.map = [ [self.initMapGrid(c.MAP_WATER) if 2 <= y <= 3
|
||||||
[
|
|
||||||
self.initMapGrid(c.MAP_WATER)
|
|
||||||
if 2 <= y <= 3
|
|
||||||
else self.initMapGrid(c.MAP_GRASS)
|
else self.initMapGrid(c.MAP_GRASS)
|
||||||
for x in range(self.width)
|
for x in range(self.width)
|
||||||
]
|
]
|
||||||
@ -25,18 +20,16 @@ class Map:
|
|||||||
self.width = c.GRID_ROOF_X_LEN
|
self.width = c.GRID_ROOF_X_LEN
|
||||||
self.height = c.GRID_ROOF_Y_LEN
|
self.height = c.GRID_ROOF_Y_LEN
|
||||||
self.grid_height_size = c.GRID_ROOF_Y_SIZE
|
self.grid_height_size = c.GRID_ROOF_Y_SIZE
|
||||||
self.map = [
|
self.map = [ [self.initMapGrid(c.MAP_TILE)
|
||||||
[self.initMapGrid(c.MAP_TILE) for x in range(self.width)]
|
for x in range(self.width)
|
||||||
|
]
|
||||||
for y in range(self.height)
|
for y in range(self.height)
|
||||||
]
|
]
|
||||||
elif self.background_type == c.BACKGROUND_SINGLE:
|
elif self.background_type == c.BACKGROUND_SINGLE:
|
||||||
self.width = c.GRID_X_LEN
|
self.width = c.GRID_X_LEN
|
||||||
self.height = c.GRID_Y_LEN
|
self.height = c.GRID_Y_LEN
|
||||||
self.grid_height_size = c.GRID_Y_SIZE
|
self.grid_height_size = c.GRID_Y_SIZE
|
||||||
self.map = [
|
self.map = [ [self.initMapGrid(c.MAP_GRASS) if y ==2
|
||||||
[
|
|
||||||
self.initMapGrid(c.MAP_GRASS)
|
|
||||||
if y == 2
|
|
||||||
else self.initMapGrid(c.MAP_UNAVAILABLE)
|
else self.initMapGrid(c.MAP_UNAVAILABLE)
|
||||||
for x in range(self.width)
|
for x in range(self.width)
|
||||||
]
|
]
|
||||||
@ -46,10 +39,7 @@ class Map:
|
|||||||
self.width = c.GRID_X_LEN
|
self.width = c.GRID_X_LEN
|
||||||
self.height = c.GRID_Y_LEN
|
self.height = c.GRID_Y_LEN
|
||||||
self.grid_height_size = c.GRID_Y_SIZE
|
self.grid_height_size = c.GRID_Y_SIZE
|
||||||
self.map = [
|
self.map = [ [self.initMapGrid(c.MAP_GRASS) if 1 <= y <= 3
|
||||||
[
|
|
||||||
self.initMapGrid(c.MAP_GRASS)
|
|
||||||
if 1 <= y <= 3
|
|
||||||
else self.initMapGrid(c.MAP_UNAVAILABLE)
|
else self.initMapGrid(c.MAP_UNAVAILABLE)
|
||||||
for x in range(self.width)
|
for x in range(self.width)
|
||||||
]
|
]
|
||||||
@ -59,13 +49,15 @@ class Map:
|
|||||||
self.width = c.GRID_X_LEN
|
self.width = c.GRID_X_LEN
|
||||||
self.height = c.GRID_Y_LEN
|
self.height = c.GRID_Y_LEN
|
||||||
self.grid_height_size = c.GRID_Y_SIZE
|
self.grid_height_size = c.GRID_Y_SIZE
|
||||||
self.map = [
|
self.map = [ [self.initMapGrid(c.MAP_GRASS)
|
||||||
[self.initMapGrid(c.MAP_GRASS) for x in range(self.width)]
|
for x in range(self.width)
|
||||||
|
]
|
||||||
for y in range(self.height)
|
for y in range(self.height)
|
||||||
]
|
]
|
||||||
|
|
||||||
def isValid(self, map_x:int, map_y:int) -> bool:
|
def isValid(self, map_x:int, map_y:int) -> bool:
|
||||||
if (0 <= map_x < self.width) and (0 <= map_y < self.height):
|
if ((0 <= map_x < self.width)
|
||||||
|
and (0 <= map_y < self.height)):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -73,11 +65,7 @@ class Map:
|
|||||||
# 注意是可变对象,不能直接引用
|
# 注意是可变对象,不能直接引用
|
||||||
# 由于同一格显然不可能种两个相同的植物,所以用集合
|
# 由于同一格显然不可能种两个相同的植物,所以用集合
|
||||||
def initMapGrid(self, plot_type:str) -> set:
|
def initMapGrid(self, plot_type:str) -> set:
|
||||||
return {
|
return {c.MAP_PLANT:set(), c.MAP_SLEEP:False, c.MAP_PLOT_TYPE:plot_type}
|
||||||
c.MAP_PLANT: set(),
|
|
||||||
c.MAP_SLEEP: False,
|
|
||||||
c.MAP_PLOT_TYPE: plot_type,
|
|
||||||
}
|
|
||||||
|
|
||||||
# 判断位置是否可用
|
# 判断位置是否可用
|
||||||
# 暂时没有写紫卡植物的判断方法
|
# 暂时没有写紫卡植物的判断方法
|
||||||
@ -85,40 +73,30 @@ class Map:
|
|||||||
def isAvailable(self, map_x:int, map_y:int, plant_name:str) -> bool:
|
def isAvailable(self, map_x:int, map_y:int, plant_name:str) -> bool:
|
||||||
# 咖啡豆和墓碑吞噬者的判别最为特殊
|
# 咖啡豆和墓碑吞噬者的判别最为特殊
|
||||||
if plant_name == c.COFFEEBEAN:
|
if plant_name == c.COFFEEBEAN:
|
||||||
if self.map[map_y][map_x][c.MAP_SLEEP] and (
|
if (self.map[map_y][map_x][c.MAP_SLEEP]
|
||||||
plant_name not in self.map[map_y][map_x][c.MAP_PLANT]
|
and (plant_name not in self.map[map_y][map_x][c.MAP_PLANT])):
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
if plant_name == c.GRAVEBUSTER:
|
if plant_name == c.GRAVEBUSTER:
|
||||||
if c.GRAVE in self.map[map_y][map_x][c.MAP_PLANT] and (
|
if (c.GRAVE in self.map[map_y][map_x][c.MAP_PLANT]
|
||||||
plant_name not in self.map[map_y][map_x][c.MAP_PLANT]
|
and (plant_name not in self.map[map_y][map_x][c.MAP_PLANT])):
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
# 被非植物障碍占据的格子对于一般植物不可种植
|
# 被非植物障碍占据的格子对于一般植物不可种植
|
||||||
if any(
|
if any((i in c.NON_PLANT_OBJECTS) for i in self.map[map_y][map_x][c.MAP_PLANT]):
|
||||||
(i in c.NON_PLANT_OBJECTS)
|
|
||||||
for i in self.map[map_y][map_x][c.MAP_PLANT]
|
|
||||||
):
|
|
||||||
return False
|
return False
|
||||||
if self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_GRASS: # 草地
|
if self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_GRASS: # 草地
|
||||||
# 首先需要判断植物是否是水生植物,水生植物不能种植在陆地上
|
# 首先需要判断植物是否是水生植物,水生植物不能种植在陆地上
|
||||||
if plant_name not in c.WATER_PLANTS:
|
if plant_name not in c.WATER_PLANTS:
|
||||||
if not self.map[map_y][map_x][c.MAP_PLANT]: # 没有植物肯定可以种植
|
if not self.map[map_y][map_x][c.MAP_PLANT]: # 没有植物肯定可以种植
|
||||||
return True
|
return True
|
||||||
elif all(
|
elif (all((i in {"花盆(未实现)", c.PUMPKINHEAD}) for i in self.map[map_y][map_x][c.MAP_PLANT])
|
||||||
(i in {'花盆(未实现)', c.PUMPKINHEAD})
|
and (plant_name not in self.map[map_y][map_x][c.MAP_PLANT])): # 例外植物:集合中填花盆和南瓜头,只要这里没有这种植物就能种植
|
||||||
for i in self.map[map_y][map_x][c.MAP_PLANT]
|
|
||||||
) and (
|
|
||||||
plant_name not in self.map[map_y][map_x][c.MAP_PLANT]
|
|
||||||
): # 例外植物:集合中填花盆和南瓜头,只要这里没有这种植物就能种植
|
|
||||||
return True
|
return True
|
||||||
elif (plant_name == c.PUMPKINHEAD) and (
|
elif ((plant_name == c.PUMPKINHEAD)
|
||||||
c.PUMPKINHEAD not in self.map[map_y][map_x][c.MAP_PLANT]
|
and (c.PUMPKINHEAD not in self.map[map_y][map_x][c.MAP_PLANT])): # 没有南瓜头就能种南瓜头
|
||||||
): # 没有南瓜头就能种南瓜头
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@ -127,25 +105,19 @@ class Map:
|
|||||||
elif self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_TILE: # 屋顶
|
elif self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_TILE: # 屋顶
|
||||||
# 首先需要判断植物是否是水生植物,水生植物不能种植在陆地上
|
# 首先需要判断植物是否是水生植物,水生植物不能种植在陆地上
|
||||||
if plant_name not in c.WATER_PLANTS:
|
if plant_name not in c.WATER_PLANTS:
|
||||||
if '花盆(未实现)' in self.map[map_y][map_x][c.MAP_PLANT]:
|
if "花盆(未实现)" in self.map[map_y][map_x][c.MAP_PLANT]:
|
||||||
if all(
|
if (all((i in {"花盆(未实现)", c.PUMPKINHEAD}) for i in self.map[map_y][map_x][c.MAP_PLANT])
|
||||||
(i in {'花盆(未实现)', c.PUMPKINHEAD})
|
and (plant_name not in self.map[map_y][map_x][c.MAP_PLANT])): # 例外植物:集合中填花盆和南瓜头,只要这里没有这种植物就能种植
|
||||||
for i in self.map[map_y][map_x][c.MAP_PLANT]
|
|
||||||
) and (
|
|
||||||
plant_name not in self.map[map_y][map_x][c.MAP_PLANT]
|
|
||||||
): # 例外植物:集合中填花盆和南瓜头,只要这里没有这种植物就能种植
|
|
||||||
if plant_name in {c.SPIKEWEED}: # 不能在花盆上种植的植物
|
if plant_name in {c.SPIKEWEED}: # 不能在花盆上种植的植物
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
elif (plant_name == c.PUMPKINHEAD) and (
|
elif ((plant_name == c.PUMPKINHEAD)
|
||||||
c.PUMPKINHEAD
|
and (c.PUMPKINHEAD not in self.map[map_y][map_x][c.MAP_PLANT])): # 有花盆且没有南瓜头就能种南瓜头
|
||||||
not in self.map[map_y][map_x][c.MAP_PLANT]
|
|
||||||
): # 有花盆且没有南瓜头就能种南瓜头
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
elif plant_name == '花盆(未实现)': # 这一格本来没有花盆而且新来的植物是花盆,可以种
|
elif plant_name == "花盆(未实现)": # 这一格本来没有花盆而且新来的植物是花盆,可以种
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@ -153,32 +125,20 @@ class Map:
|
|||||||
return False
|
return False
|
||||||
elif self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_WATER: # 水里
|
elif self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_WATER: # 水里
|
||||||
if plant_name in c.WATER_PLANTS: # 是水生植物
|
if plant_name in c.WATER_PLANTS: # 是水生植物
|
||||||
if not self.map[map_y][map_x][
|
if not self.map[map_y][map_x][c.MAP_PLANT]: # 只有无植物时才能在水里种植水生植物
|
||||||
c.MAP_PLANT
|
|
||||||
]: # 只有无植物时才能在水里种植水生植物
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
else: # 非水生植物,依赖睡莲
|
else: # 非水生植物,依赖睡莲
|
||||||
if c.LILYPAD in self.map[map_y][map_x][c.MAP_PLANT]:
|
if c.LILYPAD in self.map[map_y][map_x][c.MAP_PLANT]:
|
||||||
if all(
|
if (all((i in {c.LILYPAD, c.PUMPKINHEAD}) for i in self.map[map_y][map_x][c.MAP_PLANT])
|
||||||
(i in {c.LILYPAD, c.PUMPKINHEAD})
|
and (plant_name not in self.map[map_y][map_x][c.MAP_PLANT])):
|
||||||
for i in self.map[map_y][map_x][c.MAP_PLANT]
|
if plant_name in {c.SPIKEWEED, c.POTATOMINE, "花盆(未实现)"}: # 不能在睡莲上种植的植物
|
||||||
) and (
|
|
||||||
plant_name not in self.map[map_y][map_x][c.MAP_PLANT]
|
|
||||||
):
|
|
||||||
if plant_name in {
|
|
||||||
c.SPIKEWEED,
|
|
||||||
c.POTATOMINE,
|
|
||||||
'花盆(未实现)',
|
|
||||||
}: # 不能在睡莲上种植的植物
|
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
elif (plant_name == c.PUMPKINHEAD) and (
|
elif ((plant_name == c.PUMPKINHEAD)
|
||||||
c.PUMPKINHEAD
|
and (c.PUMPKINHEAD not in self.map[map_y][map_x][c.MAP_PLANT])): # 在睡莲上且没有南瓜头就能种南瓜头
|
||||||
not in self.map[map_y][map_x][c.MAP_PLANT]
|
|
||||||
): # 在睡莲上且没有南瓜头就能种南瓜头
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@ -208,38 +168,19 @@ class Map:
|
|||||||
|
|
||||||
def getMapGridPos(self, map_x:int, map_y:int) -> tuple[int, int]:
|
def getMapGridPos(self, map_x:int, map_y:int) -> tuple[int, int]:
|
||||||
if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS:
|
if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS:
|
||||||
return (
|
return (map_x * c.GRID_POOL_X_SIZE + c.GRID_POOL_X_SIZE//2 + c.MAP_POOL_OFFSET_X,
|
||||||
map_x * c.GRID_POOL_X_SIZE
|
map_y * c.GRID_POOL_Y_SIZE + c.GRID_POOL_Y_SIZE//5 * 3 + c.MAP_POOL_OFFSET_Y)
|
||||||
+ c.GRID_POOL_X_SIZE // 2
|
|
||||||
+ c.MAP_POOL_OFFSET_X,
|
|
||||||
map_y * c.GRID_POOL_Y_SIZE
|
|
||||||
+ c.GRID_POOL_Y_SIZE // 5 * 3
|
|
||||||
+ c.MAP_POOL_OFFSET_Y,
|
|
||||||
)
|
|
||||||
elif self.background_type in c.ON_ROOF_BACKGROUNDS:
|
elif self.background_type in c.ON_ROOF_BACKGROUNDS:
|
||||||
return (
|
return (map_x * c.GRID_ROOF_X_SIZE + c.GRID_ROOF_X_SIZE//2 + c.MAP_ROOF_OFFSET_X,
|
||||||
map_x * c.GRID_ROOF_X_SIZE
|
map_y * c.GRID_ROOF_Y_SIZE + 20 * max(0, (6 - map_y)) + c.GRID_ROOF_Y_SIZE//5 * 3 + c.MAP_POOL_OFFSET_Y)
|
||||||
+ c.GRID_ROOF_X_SIZE // 2
|
|
||||||
+ c.MAP_ROOF_OFFSET_X,
|
|
||||||
map_y * c.GRID_ROOF_Y_SIZE
|
|
||||||
+ 20 * max(0, (6 - map_y))
|
|
||||||
+ c.GRID_ROOF_Y_SIZE // 5 * 3
|
|
||||||
+ c.MAP_POOL_OFFSET_Y,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
return (
|
return (map_x * c.GRID_X_SIZE + c.GRID_X_SIZE//2 + c.MAP_OFFSET_X,
|
||||||
map_x * c.GRID_X_SIZE + c.GRID_X_SIZE // 2 + c.MAP_OFFSET_X,
|
map_y * c.GRID_Y_SIZE + c.GRID_Y_SIZE//5 * 3 + c.MAP_OFFSET_Y)
|
||||||
map_y * c.GRID_Y_SIZE
|
|
||||||
+ c.GRID_Y_SIZE // 5 * 3
|
|
||||||
+ c.MAP_OFFSET_Y,
|
|
||||||
)
|
|
||||||
|
|
||||||
def setMapGridType(self, map_x:int, map_y:int, plot_type:str):
|
def setMapGridType(self, map_x:int, map_y:int, plot_type:str):
|
||||||
self.map[map_y][map_x][c.MAP_PLOT_TYPE] = plot_type
|
self.map[map_y][map_x][c.MAP_PLOT_TYPE] = plot_type
|
||||||
|
|
||||||
def addMapPlant(
|
def addMapPlant(self, map_x:int, map_y:int, plant_name:int, sleep:bool=False):
|
||||||
self, map_x: int, map_y: int, plant_name: int, sleep: bool = False
|
|
||||||
):
|
|
||||||
self.map[map_y][map_x][c.MAP_PLANT].add(plant_name)
|
self.map[map_y][map_x][c.MAP_PLANT].add(plant_name)
|
||||||
self.map[map_y][map_x][c.MAP_SLEEP] = sleep
|
self.map[map_y][map_x][c.MAP_SLEEP] = sleep
|
||||||
|
|
||||||
@ -251,144 +192,125 @@ class Map:
|
|||||||
map_y = random.randint(0, self.height-1)
|
map_y = random.randint(0, self.height-1)
|
||||||
return (map_x, map_y)
|
return (map_x, map_y)
|
||||||
|
|
||||||
def checkPlantToSeed(
|
def checkPlantToSeed(self, x:int, y:int, plant_name:str) -> tuple[int, int]:
|
||||||
self, x: int, y: int, plant_name: str
|
|
||||||
) -> tuple[int, int]:
|
|
||||||
pos = None
|
pos = None
|
||||||
map_x, map_y = self.getMapIndex(x, y)
|
map_x, map_y = self.getMapIndex(x, y)
|
||||||
if self.isValid(map_x, map_y) and self.isAvailable(
|
if self.isValid(map_x, map_y) and self.isAvailable(map_x, map_y, plant_name):
|
||||||
map_x, map_y, plant_name
|
|
||||||
):
|
|
||||||
pos = self.getMapGridPos(map_x, map_y)
|
pos = self.getMapGridPos(map_x, map_y)
|
||||||
return pos
|
return pos
|
||||||
|
|
||||||
|
|
||||||
# 保存具体关卡地图信息常数
|
# 保存具体关卡地图信息常数
|
||||||
# 冒险模式地图
|
# 冒险模式地图
|
||||||
LEVEL_MAP_DATA = (
|
LEVEL_MAP_DATA = (
|
||||||
# 第0关:测试模式地图
|
# 第0关:测试模式地图
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 2,
|
c.BACKGROUND_TYPE: 2,
|
||||||
c.GAME_TITLE: '隐藏测试关卡',
|
c.GAME_TITLE: "隐藏测试关卡",
|
||||||
c.INIT_SUN_NAME: 5000,
|
c.INIT_SUN_NAME: 5000,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES: c.SPAWN_ZOMBIES_LIST,
|
c.SPAWN_ZOMBIES: c.SPAWN_ZOMBIES_LIST,
|
||||||
c.ZOMBIE_LIST:(
|
c.ZOMBIE_LIST:(
|
||||||
{'time': 0, 'map_y': 5, 'name': 'Zomboni'},
|
{"time":0, "map_y":5, "name":"Zomboni"},
|
||||||
{'time': 1000, 'map_y': 4, 'name': 'ScreenDoorZombie'},
|
{"time":1000, "map_y":4, "name":"ScreenDoorZombie"},
|
||||||
{'time': 2000, 'map_y': 4, 'name': 'ScreenDoorZombie'},
|
{"time":2000, "map_y":4, "name":"ScreenDoorZombie"},
|
||||||
{'time': 3100, 'map_y': 4, 'name': 'ScreenDoorZombie'},
|
{"time":3100, "map_y":4, "name":"ScreenDoorZombie"},
|
||||||
{'time': 4500, 'map_y': 4, 'name': 'ScreenDoorZombie'},
|
{"time":4500, "map_y":4, "name":"ScreenDoorZombie"},
|
||||||
{'time': 5000, 'map_y': 4, 'name': 'ScreenDoorZombie'},
|
{"time":5000, "map_y":4, "name":"ScreenDoorZombie"},
|
||||||
{'time': 6000, 'map_y': 4, 'name': 'ScreenDoorZombie'},
|
{"time":6000, "map_y":4, "name":"ScreenDoorZombie"},
|
||||||
{'time': 7000, 'map_y': 4, 'name': 'ScreenDoorZombie'},
|
{"time":7000, "map_y":4, "name":"ScreenDoorZombie"},
|
||||||
{'time': 8000, 'map_y': 4, 'name': 'ScreenDoorZombie'},
|
{"time":8000, "map_y":4, "name":"ScreenDoorZombie"},
|
||||||
{'time': 0, 'map_y': 1, 'name': 'NewspaperZombie'},
|
{"time":0, "map_y":1, "name":"NewspaperZombie"},
|
||||||
{'time': 0, 'map_y': 0, 'name': 'PoleVaultingZombie'},
|
{"time":0, "map_y":0, "name":"PoleVaultingZombie"},
|
||||||
{'time': 6000, 'map_y': 0, 'name': 'FootballZombie'},
|
{"time":6000, "map_y":0, "name":"FootballZombie"},
|
||||||
{'time': 0, 'map_y': 3, 'name': 'ConeheadDuckyTubeZombie'},
|
{"time":0, "map_y":3, "name":"ConeheadDuckyTubeZombie"},
|
||||||
{'time': 0, 'map_y': 2, 'name': 'SnorkelZombie'},
|
{"time":0, "map_y":2, "name":"SnorkelZombie"},
|
||||||
{'time': 90000, 'map_y': 2, 'name': 'ConeheadDuckyTubeZombie'},
|
{"time":90000, "map_y":2, "name":"ConeheadDuckyTubeZombie"}
|
||||||
),
|
)
|
||||||
},
|
},
|
||||||
# 第1关:单行草皮
|
# 第1关:单行草皮
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 7,
|
c.BACKGROUND_TYPE: 7,
|
||||||
c.GAME_TITLE: '白天 1-1',
|
c.GAME_TITLE: "白天 1-1",
|
||||||
c.INIT_SUN_NAME: 150,
|
c.INIT_SUN_NAME: 150,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES:(c.NORMAL_ZOMBIE,),
|
c.INCLUDED_ZOMBIES:(c.NORMAL_ZOMBIE,),
|
||||||
c.NUM_FLAGS: 1,
|
c.NUM_FLAGS:1
|
||||||
},
|
},
|
||||||
# 第2关:三行草皮
|
# 第2关:三行草皮
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 8,
|
c.BACKGROUND_TYPE: 8,
|
||||||
c.GAME_TITLE: '白天 1-2',
|
c.GAME_TITLE: "白天 1-2",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES:(c.NORMAL_ZOMBIE,),
|
c.INCLUDED_ZOMBIES:(c.NORMAL_ZOMBIE,),
|
||||||
c.NUM_FLAGS: 1,
|
c.NUM_FLAGS:1
|
||||||
},
|
},
|
||||||
# 第3关
|
# 第3关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 0,
|
c.BACKGROUND_TYPE: 0,
|
||||||
c.GAME_TITLE: '白天 1-3',
|
c.GAME_TITLE: "白天 1-3",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES:(c.NORMAL_ZOMBIE,),
|
c.INCLUDED_ZOMBIES:(c.NORMAL_ZOMBIE,),
|
||||||
c.NUM_FLAGS: 2,
|
c.NUM_FLAGS:2
|
||||||
},
|
},
|
||||||
# 第4关
|
# 第4关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 0,
|
c.BACKGROUND_TYPE: 0,
|
||||||
c.GAME_TITLE: '白天 1-4',
|
c.GAME_TITLE: "白天 1-4",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: (c.NORMAL_ZOMBIE, c.CONEHEAD_ZOMBIE, c.POLE_VAULTING_ZOMBIE),
|
||||||
c.NORMAL_ZOMBIE,
|
c.NUM_FLAGS:2
|
||||||
c.CONEHEAD_ZOMBIE,
|
|
||||||
c.POLE_VAULTING_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS: 2,
|
|
||||||
},
|
},
|
||||||
# 第5关 目前白天最后一关
|
# 第5关 目前白天最后一关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 0,
|
c.BACKGROUND_TYPE: 0,
|
||||||
c.GAME_TITLE: '白天 1-5',
|
c.GAME_TITLE: "白天 1-5",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.CONEHEAD_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.POLE_VAULTING_ZOMBIE, c.BUCKETHEAD_ZOMBIE),
|
||||||
c.CONEHEAD_ZOMBIE,
|
c.NUM_FLAGS:3
|
||||||
c.POLE_VAULTING_ZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS: 3,
|
|
||||||
},
|
},
|
||||||
# 第6关 目前夜晚第一关
|
# 第6关 目前夜晚第一关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 1,
|
c.BACKGROUND_TYPE: 1,
|
||||||
c.GAME_TITLE: '黑夜 2-1',
|
c.GAME_TITLE: "黑夜 2-1",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (c.NORMAL_ZOMBIE, c.NEWSPAPER_ZOMBIE),
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE,
|
||||||
c.NUM_FLAGS: 2,
|
c.NEWSPAPER_ZOMBIE),
|
||||||
|
c.NUM_FLAGS:2
|
||||||
},
|
},
|
||||||
# 第7关
|
# 第7关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 1,
|
c.BACKGROUND_TYPE: 1,
|
||||||
c.GAME_TITLE: '黑夜 2-2',
|
c.GAME_TITLE: "黑夜 2-2",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.SCREEN_DOOR_ZOMBIE,),
|
||||||
c.SCREEN_DOOR_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS: 2,
|
c.NUM_FLAGS: 2,
|
||||||
c.GRADE_GRAVES: 2,
|
c.GRADE_GRAVES: 2,
|
||||||
},
|
},
|
||||||
# 第8关 目前为夜晚最后一关
|
# 第8关 目前为夜晚最后一关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 1,
|
c.BACKGROUND_TYPE: 1,
|
||||||
c.GAME_TITLE: '黑夜 2-3',
|
c.GAME_TITLE: "黑夜 2-3",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.NEWSPAPER_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.CONEHEAD_ZOMBIE, c.BUCKETHEAD_ZOMBIE,
|
||||||
c.NEWSPAPER_ZOMBIE,
|
c.SCREEN_DOOR_ZOMBIE, c.FOOTBALL_ZOMBIE),
|
||||||
c.CONEHEAD_ZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
c.SCREEN_DOOR_ZOMBIE,
|
|
||||||
c.FOOTBALL_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.INEVITABLE_ZOMBIE_DICT: { # 这里改用python实现了以后,键不再用字符串,改用数字
|
c.INEVITABLE_ZOMBIE_DICT: { # 这里改用python实现了以后,键不再用字符串,改用数字
|
||||||
# 仍然要注意字典值是元组
|
# 仍然要注意字典值是元组
|
||||||
10: (c.NEWSPAPER_ZOMBIE,),
|
10: (c.NEWSPAPER_ZOMBIE,),
|
||||||
@ -401,224 +323,171 @@ LEVEL_MAP_DATA = (
|
|||||||
# 第9关 目前为泳池模式第一关
|
# 第9关 目前为泳池模式第一关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 2,
|
c.BACKGROUND_TYPE: 2,
|
||||||
c.GAME_TITLE: '泳池 3-1',
|
c.GAME_TITLE: "泳池 3-1",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.BUCKETHEAD_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.CONEHEAD_ZOMBIE,),
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
c.NUM_FLAGS:2
|
||||||
c.CONEHEAD_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS: 2,
|
|
||||||
},
|
},
|
||||||
# 第10关
|
# 第10关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 2,
|
c.BACKGROUND_TYPE: 2,
|
||||||
c.GAME_TITLE: '泳池 3-2',
|
c.GAME_TITLE: "泳池 3-2",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.BUCKETHEAD_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.CONEHEAD_ZOMBIE, c.SNORKELZOMBIE),
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
c.CONEHEAD_ZOMBIE,
|
|
||||||
c.SNORKELZOMBIE,
|
|
||||||
),
|
|
||||||
c.INEVITABLE_ZOMBIE_DICT: {30: (c.SNORKELZOMBIE,)},
|
c.INEVITABLE_ZOMBIE_DICT: {30: (c.SNORKELZOMBIE,)},
|
||||||
c.NUM_FLAGS: 3,
|
c.NUM_FLAGS:3
|
||||||
},
|
},
|
||||||
# 第11关
|
# 第11关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 2,
|
c.BACKGROUND_TYPE: 2,
|
||||||
c.GAME_TITLE: '泳池 3-3',
|
c.GAME_TITLE: "泳池 3-3",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (c.NORMAL_ZOMBIE, c.ZOMBONI),
|
c.INCLUDED_ZOMBIES: (c.NORMAL_ZOMBIE, c.ZOMBONI),
|
||||||
c.INEVITABLE_ZOMBIE_DICT: {30: (c.ZOMBONI,)},
|
c.INEVITABLE_ZOMBIE_DICT: {30: (c.ZOMBONI,)},
|
||||||
c.NUM_FLAGS: 3,
|
c.NUM_FLAGS:3
|
||||||
},
|
},
|
||||||
# 第12关 目前为泳池最后一关
|
# 第12关 目前为泳池最后一关
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 2,
|
c.BACKGROUND_TYPE: 2,
|
||||||
c.GAME_TITLE: '泳池 3-4',
|
c.GAME_TITLE: "泳池 3-4",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.ZOMBONI,
|
||||||
c.NORMAL_ZOMBIE,
|
|
||||||
c.ZOMBONI,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
c.BUCKETHEAD_ZOMBIE,
|
||||||
c.CONEHEAD_ZOMBIE,
|
c.CONEHEAD_ZOMBIE, c.SNORKELZOMBIE),
|
||||||
c.SNORKELZOMBIE,
|
|
||||||
),
|
|
||||||
c.INEVITABLE_ZOMBIE_DICT: {40: (c.ZOMBONI,)},
|
c.INEVITABLE_ZOMBIE_DICT: {40: (c.ZOMBONI,)},
|
||||||
c.NUM_FLAGS: 4,
|
c.NUM_FLAGS:4
|
||||||
},
|
},
|
||||||
# 第13关 目前为浓雾第一关 尚未完善
|
# 第13关 目前为浓雾第一关 尚未完善
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 3,
|
c.BACKGROUND_TYPE: 3,
|
||||||
c.GAME_TITLE: '浓雾 4-1',
|
c.GAME_TITLE: "浓雾 4-1",
|
||||||
c.INIT_SUN_NAME: 50,
|
c.INIT_SUN_NAME: 50,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.NEWSPAPER_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.ZOMBONI, c.FOOTBALL_ZOMBIE,
|
||||||
c.NEWSPAPER_ZOMBIE,
|
c.CONEHEAD_ZOMBIE, c.BUCKETHEAD_ZOMBIE),
|
||||||
c.ZOMBONI,
|
c.NUM_FLAGS:4
|
||||||
c.FOOTBALL_ZOMBIE,
|
|
||||||
c.CONEHEAD_ZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS: 4,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 玩玩小游戏地图
|
# 玩玩小游戏地图
|
||||||
LITTLE_GAME_MAP_DATA = (
|
LITTLE_GAME_MAP_DATA = (
|
||||||
# 第0关 测试
|
# 第0关 测试
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 3,
|
c.BACKGROUND_TYPE: 3,
|
||||||
c.GAME_TITLE: '隐藏测试关卡',
|
c.GAME_TITLE: "隐藏测试关卡",
|
||||||
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_MOVE,
|
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_MOVE,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.NEWSPAPER_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.ZOMBONI, c.FOOTBALL_ZOMBIE,
|
||||||
c.NEWSPAPER_ZOMBIE,
|
c.CONEHEAD_ZOMBIE, c.BUCKETHEAD_ZOMBIE),
|
||||||
c.ZOMBONI,
|
|
||||||
c.FOOTBALL_ZOMBIE,
|
|
||||||
c.CONEHEAD_ZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS:4,
|
c.NUM_FLAGS:4,
|
||||||
c.CARD_POOL: {
|
c.CARD_POOL: { c.LILYPAD: 300,
|
||||||
c.LILYPAD: 300,
|
|
||||||
c.STARFRUIT: 400,
|
c.STARFRUIT: 400,
|
||||||
c.PUMPKINHEAD: 100,
|
c.PUMPKINHEAD: 100,
|
||||||
c.SEASHROOM: 100,
|
c.SEASHROOM: 100,
|
||||||
c.SPIKEWEED: 100,
|
c.SPIKEWEED: 100,
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
# 第1关 坚果保龄球
|
# 第1关 坚果保龄球
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 6,
|
c.BACKGROUND_TYPE: 6,
|
||||||
c.GAME_TITLE: '坚果保龄球',
|
c.GAME_TITLE: "坚果保龄球",
|
||||||
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_BOWLING,
|
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_BOWLING,
|
||||||
c.SHOVEL: 0,
|
c.SHOVEL: 0,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.CONEHEAD_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.POLE_VAULTING_ZOMBIE, c.BUCKETHEAD_ZOMBIE,),
|
||||||
c.CONEHEAD_ZOMBIE,
|
|
||||||
c.POLE_VAULTING_ZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS:2,
|
c.NUM_FLAGS:2,
|
||||||
c.CARD_POOL: {
|
c.CARD_POOL: { c.WALLNUTBOWLING: 300,
|
||||||
c.WALLNUTBOWLING: 300,
|
c.REDWALLNUTBOWLING: 100,}
|
||||||
c.REDWALLNUTBOWLING: 100,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
# 第2关 白天 大决战
|
# 第2关 白天 大决战
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 0,
|
c.BACKGROUND_TYPE: 0,
|
||||||
c.GAME_TITLE: '大决战(白天)',
|
c.GAME_TITLE: "大决战(白天)",
|
||||||
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_MOVE,
|
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_MOVE,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.CONEHEAD_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.POLE_VAULTING_ZOMBIE, c.BUCKETHEAD_ZOMBIE,),
|
||||||
c.CONEHEAD_ZOMBIE,
|
|
||||||
c.POLE_VAULTING_ZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS:3,
|
c.NUM_FLAGS:3,
|
||||||
c.CARD_POOL: {
|
c.CARD_POOL: { c.PEASHOOTER: 200,
|
||||||
c.PEASHOOTER: 200,
|
|
||||||
c.SNOWPEASHOOTER: 100,
|
c.SNOWPEASHOOTER: 100,
|
||||||
c.WALLNUT: 100,
|
c.WALLNUT: 100,
|
||||||
c.CHERRYBOMB: 100,
|
c.CHERRYBOMB: 100,
|
||||||
c.REPEATERPEA: 200,
|
c.REPEATERPEA: 200,
|
||||||
c.CHOMPER: 100,
|
c.CHOMPER: 100,
|
||||||
c.POTATOMINE: 100,
|
c.POTATOMINE: 100,}
|
||||||
},
|
|
||||||
},
|
},
|
||||||
# 第3关 夜晚 大决战
|
# 第3关 夜晚 大决战
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 1,
|
c.BACKGROUND_TYPE: 1,
|
||||||
c.GAME_TITLE: '大决战(黑夜)',
|
c.GAME_TITLE: "大决战(黑夜)",
|
||||||
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_MOVE,
|
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_MOVE,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.CONEHEAD_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.FOOTBALL_ZOMBIE, c.BUCKETHEAD_ZOMBIE,
|
||||||
c.CONEHEAD_ZOMBIE,
|
c.NEWSPAPER_ZOMBIE, c.SCREEN_DOOR_ZOMBIE),
|
||||||
c.FOOTBALL_ZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
c.NEWSPAPER_ZOMBIE,
|
|
||||||
c.SCREEN_DOOR_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS:3,
|
c.NUM_FLAGS:3,
|
||||||
c.CARD_POOL: {
|
c.CARD_POOL: { c.PUFFSHROOM: 100,
|
||||||
c.PUFFSHROOM: 100,
|
|
||||||
c.SCAREDYSHROOM: 100,
|
c.SCAREDYSHROOM: 100,
|
||||||
c.ICESHROOM: 70,
|
c.ICESHROOM: 70,
|
||||||
c.HYPNOSHROOM: 100,
|
c.HYPNOSHROOM: 100,
|
||||||
c.DOOMSHROOM: 50,
|
c.DOOMSHROOM: 50,
|
||||||
c.GRAVEBUSTER: 100,
|
c.GRAVEBUSTER: 100,
|
||||||
c.FUMESHROOM: 200,
|
c.FUMESHROOM: 200},
|
||||||
},
|
c.GRADE_GRAVES:3
|
||||||
c.GRADE_GRAVES: 3,
|
|
||||||
},
|
},
|
||||||
# 第4关 泳池 大决战
|
# 第4关 泳池 大决战
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 2,
|
c.BACKGROUND_TYPE: 2,
|
||||||
c.GAME_TITLE: '大决战(泳池)',
|
c.GAME_TITLE: "大决战(泳池)",
|
||||||
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_MOVE,
|
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_MOVE,
|
||||||
c.SHOVEL: 1,
|
c.SHOVEL: 1,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.CONEHEAD_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.SNORKELZOMBIE, c.BUCKETHEAD_ZOMBIE,
|
||||||
c.CONEHEAD_ZOMBIE,
|
c.ZOMBONI,),
|
||||||
c.SNORKELZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
c.ZOMBONI,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS:4,
|
c.NUM_FLAGS:4,
|
||||||
c.CARD_POOL: {
|
c.CARD_POOL: { c.LILYPAD: 300,
|
||||||
c.LILYPAD: 300,
|
|
||||||
c.TORCHWOOD: 100,
|
c.TORCHWOOD: 100,
|
||||||
c.TALLNUT: 100,
|
c.TALLNUT: 100,
|
||||||
c.TANGLEKLEP: 100,
|
c.TANGLEKLEP: 100,
|
||||||
c.SPIKEWEED: 100,
|
c.SPIKEWEED: 100,
|
||||||
c.SQUASH: 100,
|
c.SQUASH: 100,
|
||||||
c.JALAPENO: 50,
|
c.JALAPENO: 50,
|
||||||
c.THREEPEASHOOTER: 400,
|
c.THREEPEASHOOTER: 400,}
|
||||||
},
|
|
||||||
},
|
},
|
||||||
# 第5关 坚果保龄球2
|
# 第5关 坚果保龄球2
|
||||||
{
|
{
|
||||||
c.BACKGROUND_TYPE: 6,
|
c.BACKGROUND_TYPE: 6,
|
||||||
c.GAME_TITLE: '坚果保龄球(II)',
|
c.GAME_TITLE: "坚果保龄球(II)",
|
||||||
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_BOWLING,
|
c.CHOOSEBAR_TYPE: c.CHOOSEBAR_BOWLING,
|
||||||
c.SHOVEL: 0,
|
c.SHOVEL: 0,
|
||||||
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
c.SPAWN_ZOMBIES:c.SPAWN_ZOMBIES_AUTO,
|
||||||
c.INCLUDED_ZOMBIES: (
|
c.INCLUDED_ZOMBIES: ( c.NORMAL_ZOMBIE, c.CONEHEAD_ZOMBIE,
|
||||||
c.NORMAL_ZOMBIE,
|
c.POLE_VAULTING_ZOMBIE, c.BUCKETHEAD_ZOMBIE,
|
||||||
c.CONEHEAD_ZOMBIE,
|
c.NEWSPAPER_ZOMBIE, c.SCREEN_DOOR_ZOMBIE),
|
||||||
c.POLE_VAULTING_ZOMBIE,
|
|
||||||
c.BUCKETHEAD_ZOMBIE,
|
|
||||||
c.NEWSPAPER_ZOMBIE,
|
|
||||||
c.SCREEN_DOOR_ZOMBIE,
|
|
||||||
),
|
|
||||||
c.NUM_FLAGS:3,
|
c.NUM_FLAGS:3,
|
||||||
c.CARD_POOL: {
|
c.CARD_POOL: { c.WALLNUTBOWLING: 500,
|
||||||
c.WALLNUTBOWLING: 500,
|
|
||||||
c.REDWALLNUTBOWLING: 100,
|
c.REDWALLNUTBOWLING: 100,
|
||||||
c.GIANTWALLNUT: 100,
|
c.GIANTWALLNUT:100,}
|
||||||
},
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
import pygame as pg
|
import pygame as pg
|
||||||
|
|
||||||
from .. import constants as c
|
|
||||||
from .. import tool
|
from .. import tool
|
||||||
|
from .. import constants as c
|
||||||
|
|
||||||
|
|
||||||
def getSunValueImage(sun_value):
|
def getSunValueImage(sun_value):
|
||||||
@ -23,19 +21,13 @@ def getSunValueImage(sun_value):
|
|||||||
image.set_colorkey(c.BLACK)
|
image.set_colorkey(c.BLACK)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
|
||||||
def getCardPool(data):
|
def getCardPool(data):
|
||||||
card_pool = {
|
card_pool = {c.PLANT_CARD_INFO[c.PLANT_CARD_INDEX[card_name]]: data[card_name]
|
||||||
c.PLANT_CARD_INFO[c.PLANT_CARD_INDEX[card_name]]: data[card_name]
|
for card_name in data}
|
||||||
for card_name in data
|
|
||||||
}
|
|
||||||
return card_pool
|
return card_pool
|
||||||
|
|
||||||
|
class Card():
|
||||||
class Card:
|
def __init__(self, x:int, y:int, index:int, scale:float=0.5, not_recommend=0):
|
||||||
def __init__(
|
|
||||||
self, x: int, y: int, index: int, scale: float = 0.5, not_recommend=0
|
|
||||||
):
|
|
||||||
self.info = c.PLANT_CARD_INFO[index]
|
self.info = c.PLANT_CARD_INFO[index]
|
||||||
self.loadFrame(self.info[c.CARD_INDEX], scale)
|
self.loadFrame(self.info[c.CARD_INDEX], scale)
|
||||||
self.rect = self.orig_image.get_rect()
|
self.rect = self.orig_image.get_rect()
|
||||||
@ -43,20 +35,11 @@ class Card:
|
|||||||
self.rect.y = y
|
self.rect.y = y
|
||||||
# 绘制植物阳光消耗大小
|
# 绘制植物阳光消耗大小
|
||||||
font = pg.font.Font(c.FONT_PATH, 12)
|
font = pg.font.Font(c.FONT_PATH, 12)
|
||||||
self.sun_cost_img = font.render(
|
self.sun_cost_img = font.render(str(self.info[c.SUN_INDEX]), True, c.BLACK)
|
||||||
str(self.info[c.SUN_INDEX]), True, c.BLACK
|
|
||||||
)
|
|
||||||
self.sun_cost_img_rect = self.sun_cost_img.get_rect()
|
self.sun_cost_img_rect = self.sun_cost_img.get_rect()
|
||||||
sun_cost_img_x = 32 - self.sun_cost_img_rect.w
|
sun_cost_img_x = 32 - self.sun_cost_img_rect.w
|
||||||
self.orig_image.blit(
|
self.orig_image.blit(self.sun_cost_img,
|
||||||
self.sun_cost_img,
|
(sun_cost_img_x, 52, self.sun_cost_img_rect.w, self.sun_cost_img_rect.h))
|
||||||
(
|
|
||||||
sun_cost_img_x,
|
|
||||||
52,
|
|
||||||
self.sun_cost_img_rect.w,
|
|
||||||
self.sun_cost_img_rect.h,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.index = index
|
self.index = index
|
||||||
self.sun_cost = self.info[c.SUN_INDEX]
|
self.sun_cost = self.info[c.SUN_INDEX]
|
||||||
@ -69,9 +52,7 @@ class Card:
|
|||||||
if self.not_recommend:
|
if self.not_recommend:
|
||||||
self.orig_image.set_alpha(128)
|
self.orig_image.set_alpha(128)
|
||||||
self.image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
self.image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
||||||
self.image.blit(
|
self.image.blit(self.orig_image, (0,0), (0, 0, self.rect.w, self.rect.h))
|
||||||
self.orig_image, (0, 0), (0, 0, self.rect.w, self.rect.h)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
self.image = self.orig_image
|
self.image = self.orig_image
|
||||||
self.image.set_alpha(255)
|
self.image.set_alpha(255)
|
||||||
@ -81,25 +62,18 @@ class Card:
|
|||||||
rect = frame.get_rect()
|
rect = frame.get_rect()
|
||||||
width, height = rect.w, rect.h
|
width, height = rect.w, rect.h
|
||||||
|
|
||||||
self.orig_image = tool.get_image(
|
self.orig_image = tool.get_image(frame, 0, 0, width, height, c.BLACK, scale)
|
||||||
frame, 0, 0, width, height, c.BLACK, scale
|
|
||||||
)
|
|
||||||
self.image = self.orig_image
|
self.image = self.orig_image
|
||||||
|
|
||||||
def checkMouseClick(self, mouse_pos):
|
def checkMouseClick(self, mouse_pos):
|
||||||
x, y = mouse_pos
|
x, y = mouse_pos
|
||||||
if (
|
if (self.rect.x <= x <= self.rect.right and
|
||||||
self.rect.x <= x <= self.rect.right
|
self.rect.y <= y <= self.rect.bottom):
|
||||||
and self.rect.y <= y <= self.rect.bottom
|
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def canClick(self, sun_value, current_time):
|
def canClick(self, sun_value, current_time):
|
||||||
if (
|
if self.sun_cost <= sun_value and (current_time - self.frozen_timer) > self.frozen_time:
|
||||||
self.sun_cost <= sun_value
|
|
||||||
and (current_time - self.frozen_timer) > self.frozen_time
|
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -112,18 +86,14 @@ class Card:
|
|||||||
if self.not_recommend % 2:
|
if self.not_recommend % 2:
|
||||||
self.orig_image.set_alpha(128)
|
self.orig_image.set_alpha(128)
|
||||||
self.image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
self.image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
||||||
self.image.blit(
|
self.image.blit(self.orig_image, (0,0), (0, 0, self.rect.w, self.rect.h))
|
||||||
self.orig_image, (0, 0), (0, 0, self.rect.w, self.rect.h)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
self.image = self.orig_image
|
self.image = self.orig_image
|
||||||
self.image.set_alpha(255)
|
self.image.set_alpha(255)
|
||||||
else:
|
else:
|
||||||
self.orig_image.set_alpha(64)
|
self.orig_image.set_alpha(64)
|
||||||
self.image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
self.image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
||||||
self.image.blit(
|
self.image.blit(self.orig_image, (0,0), (0, 0, self.rect.w, self.rect.h))
|
||||||
self.orig_image, (0, 0), (0, 0, self.rect.w, self.rect.h)
|
|
||||||
)
|
|
||||||
|
|
||||||
def setFrozenTime(self, current_time):
|
def setFrozenTime(self, current_time):
|
||||||
self.frozen_timer = current_time
|
self.frozen_timer = current_time
|
||||||
@ -135,25 +105,16 @@ class Card:
|
|||||||
image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
||||||
frozen_image = self.orig_image
|
frozen_image = self.orig_image
|
||||||
frozen_image.set_alpha(128)
|
frozen_image.set_alpha(128)
|
||||||
frozen_height = (
|
frozen_height = ((self.frozen_time - time)/self.frozen_time) * self.rect.h
|
||||||
(self.frozen_time - time) / self.frozen_time
|
|
||||||
) * self.rect.h
|
|
||||||
|
|
||||||
image.blit(
|
image.blit(frozen_image, (0,0), (0, 0, self.rect.w, frozen_height))
|
||||||
frozen_image, (0, 0), (0, 0, self.rect.w, frozen_height)
|
|
||||||
)
|
|
||||||
self.orig_image.set_alpha(192)
|
self.orig_image.set_alpha(192)
|
||||||
image.blit(
|
image.blit(self.orig_image, (0,frozen_height),
|
||||||
self.orig_image,
|
(0, frozen_height, self.rect.w, self.rect.h - frozen_height))
|
||||||
(0, frozen_height),
|
|
||||||
(0, frozen_height, self.rect.w, self.rect.h - frozen_height),
|
|
||||||
)
|
|
||||||
elif self.sun_cost > sun_value: #disable status
|
elif self.sun_cost > sun_value: #disable status
|
||||||
image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
||||||
self.orig_image.set_alpha(192)
|
self.orig_image.set_alpha(192)
|
||||||
image.blit(
|
image.blit(self.orig_image, (0,0), (0, 0, self.rect.w, self.rect.h))
|
||||||
self.orig_image, (0, 0), (0, 0, self.rect.w, self.rect.h)
|
|
||||||
)
|
|
||||||
elif self.clicked:
|
elif self.clicked:
|
||||||
image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
image = pg.Surface((self.rect.w, self.rect.h)) # 黑底
|
||||||
chosen_image = self.orig_image
|
chosen_image = self.orig_image
|
||||||
@ -173,9 +134,8 @@ class Card:
|
|||||||
def draw(self, surface):
|
def draw(self, surface):
|
||||||
surface.blit(self.image, self.rect)
|
surface.blit(self.image, self.rect)
|
||||||
|
|
||||||
|
|
||||||
# 植物栏
|
# 植物栏
|
||||||
class MenuBar:
|
class MenuBar():
|
||||||
def __init__(self, card_list, sun_value):
|
def __init__(self, card_list, sun_value):
|
||||||
self.loadFrame(c.MENUBAR_BACKGROUND)
|
self.loadFrame(c.MENUBAR_BACKGROUND)
|
||||||
self.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
@ -227,10 +187,7 @@ class MenuBar:
|
|||||||
for card in self.card_list:
|
for card in self.card_list:
|
||||||
if card.checkMouseClick(mouse_pos):
|
if card.checkMouseClick(mouse_pos):
|
||||||
if card.canClick(self.sun_value, self.current_time):
|
if card.canClick(self.sun_value, self.current_time):
|
||||||
result = (
|
result = (c.PLANT_CARD_INFO[card.index][c.PLANT_NAME_INDEX], card)
|
||||||
c.PLANT_CARD_INFO[card.index][c.PLANT_NAME_INDEX],
|
|
||||||
card,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# 播放无法使用该卡片的警告音
|
# 播放无法使用该卡片的警告音
|
||||||
c.SOUND_CANNOT_CHOOSE_WARNING.play()
|
c.SOUND_CANNOT_CHOOSE_WARNING.play()
|
||||||
@ -239,10 +196,8 @@ class MenuBar:
|
|||||||
|
|
||||||
def checkMenuBarClick(self, mouse_pos):
|
def checkMenuBarClick(self, mouse_pos):
|
||||||
x, y = mouse_pos
|
x, y = mouse_pos
|
||||||
if (
|
if (self.rect.x <= x <= self.rect.right and
|
||||||
self.rect.x <= x <= self.rect.right
|
self.rect.y <= y <= self.rect.bottom):
|
||||||
and self.rect.y <= y <= self.rect.bottom
|
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -274,9 +229,8 @@ class MenuBar:
|
|||||||
for card in self.card_list:
|
for card in self.card_list:
|
||||||
card.draw(surface)
|
card.draw(surface)
|
||||||
|
|
||||||
|
|
||||||
# 关卡模式选植物的界面
|
# 关卡模式选植物的界面
|
||||||
class Panel:
|
class Panel():
|
||||||
def __init__(self, card_list, sun_value, background_type=c.BACKGROUND_DAY):
|
def __init__(self, card_list, sun_value, background_type=c.BACKGROUND_DAY):
|
||||||
self.loadImages(sun_value)
|
self.loadImages(sun_value)
|
||||||
self.selected_cards = []
|
self.selected_cards = []
|
||||||
@ -302,6 +256,7 @@ class Panel:
|
|||||||
self.panel_rect.x = 0
|
self.panel_rect.x = 0
|
||||||
self.panel_rect.y = c.PANEL_Y_START
|
self.panel_rect.y = c.PANEL_Y_START
|
||||||
|
|
||||||
|
|
||||||
self.value_image = getSunValueImage(sun_value)
|
self.value_image = getSunValueImage(sun_value)
|
||||||
self.value_rect = self.value_image.get_rect()
|
self.value_rect = self.value_image.get_rect()
|
||||||
self.value_rect.x = 21
|
self.value_rect.x = 21
|
||||||
@ -322,25 +277,17 @@ class Panel:
|
|||||||
y += c.PANEL_Y_INTERNAL
|
y += c.PANEL_Y_INTERNAL
|
||||||
x += c.PANEL_X_INTERNAL
|
x += c.PANEL_X_INTERNAL
|
||||||
plant_name = c.PLANT_CARD_INFO[index][c.PLANT_NAME_INDEX]
|
plant_name = c.PLANT_CARD_INFO[index][c.PLANT_NAME_INDEX]
|
||||||
if (
|
if (plant_name in c.WATER_PLANTS
|
||||||
plant_name in c.WATER_PLANTS
|
and self.background_type not in c.POOL_EQUIPPED_BACKGROUNDS):
|
||||||
and self.background_type not in c.POOL_EQUIPPED_BACKGROUNDS
|
|
||||||
):
|
|
||||||
not_recommend = c.REASON_OTHER
|
not_recommend = c.REASON_OTHER
|
||||||
elif (
|
elif (plant_name == c.GRAVEBUSTER
|
||||||
plant_name == c.GRAVEBUSTER
|
and self.background_type != c.BACKGROUND_NIGHT):
|
||||||
and self.background_type != c.BACKGROUND_NIGHT
|
|
||||||
):
|
|
||||||
not_recommend = c.REASON_OTHER
|
not_recommend = c.REASON_OTHER
|
||||||
elif (
|
elif (plant_name in c.CAN_SLEEP_PLANTS
|
||||||
plant_name in c.CAN_SLEEP_PLANTS
|
and self.background_type in c.DAYTIME_BACKGROUNDS):
|
||||||
and self.background_type in c.DAYTIME_BACKGROUNDS
|
|
||||||
):
|
|
||||||
not_recommend = c.REASON_WILL_SLEEP
|
not_recommend = c.REASON_WILL_SLEEP
|
||||||
elif (
|
elif (plant_name == c.COFFEEBEAN
|
||||||
plant_name == c.COFFEEBEAN
|
and self.background_type not in c.DAYTIME_BACKGROUNDS):
|
||||||
and self.background_type not in c.DAYTIME_BACKGROUNDS
|
|
||||||
):
|
|
||||||
not_recommend = c.REASON_OTHER
|
not_recommend = c.REASON_OTHER
|
||||||
# 还有屋顶场景,以及其他植物没有实现的植物没有写进来
|
# 还有屋顶场景,以及其他植物没有实现的植物没有写进来
|
||||||
else:
|
else:
|
||||||
@ -367,9 +314,7 @@ class Panel:
|
|||||||
i.not_recommend = c.REASON_WILL_SLEEP
|
i.not_recommend = c.REASON_WILL_SLEEP
|
||||||
i.orig_image.set_alpha(128)
|
i.orig_image.set_alpha(128)
|
||||||
i.image = pg.Surface((i.rect.w, i.rect.h)) # 黑底
|
i.image = pg.Surface((i.rect.w, i.rect.h)) # 黑底
|
||||||
i.image.blit(
|
i.image.blit(i.orig_image, (0,0), (0, 0, i.rect.w, i.rect.h))
|
||||||
i.orig_image, (0, 0), (0, 0, i.rect.w, i.rect.h)
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.selected_num >= c.CARD_MAX_NUM:
|
if self.selected_num >= c.CARD_MAX_NUM:
|
||||||
return
|
return
|
||||||
@ -383,9 +328,7 @@ class Panel:
|
|||||||
if card.info[c.PLANT_NAME_INDEX] == c.COFFEEBEAN:
|
if card.info[c.PLANT_NAME_INDEX] == c.COFFEEBEAN:
|
||||||
for i in self.card_list:
|
for i in self.card_list:
|
||||||
if i.not_recommend == c.REASON_WILL_SLEEP:
|
if i.not_recommend == c.REASON_WILL_SLEEP:
|
||||||
i.not_recommend = (
|
i.not_recommend = c.REASON_SLEEP_BUT_COFFEE_BEAN
|
||||||
c.REASON_SLEEP_BUT_COFFEE_BEAN
|
|
||||||
)
|
|
||||||
i.image = i.orig_image
|
i.image = i.orig_image
|
||||||
i.image.set_alpha(255)
|
i.image.set_alpha(255)
|
||||||
break
|
break
|
||||||
@ -405,10 +348,8 @@ class Panel:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
x, y = mouse_pos
|
x, y = mouse_pos
|
||||||
if (
|
if (self.button_rect.x <= x <= self.button_rect.right and
|
||||||
self.button_rect.x <= x <= self.button_rect.right
|
self.button_rect.y <= y <= self.button_rect.bottom):
|
||||||
and self.button_rect.y <= y <= self.button_rect.bottom
|
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -430,9 +371,8 @@ class Panel:
|
|||||||
if self.selected_num >= c.CARD_LIST_NUM:
|
if self.selected_num >= c.CARD_LIST_NUM:
|
||||||
surface.blit(self.button_image, self.button_rect)
|
surface.blit(self.button_image, self.button_rect)
|
||||||
|
|
||||||
|
|
||||||
# 传送带模式的卡片
|
# 传送带模式的卡片
|
||||||
class MoveCard:
|
class MoveCard():
|
||||||
def __init__(self, x, y, card_name, plant_name, scale=0.5):
|
def __init__(self, x, y, card_name, plant_name, scale=0.5):
|
||||||
self.loadFrame(card_name, scale)
|
self.loadFrame(card_name, scale)
|
||||||
self.rect = self.orig_image.get_rect()
|
self.rect = self.orig_image.get_rect()
|
||||||
@ -452,18 +392,14 @@ class MoveCard:
|
|||||||
rect = frame.get_rect()
|
rect = frame.get_rect()
|
||||||
width, height = rect.w, rect.h
|
width, height = rect.w, rect.h
|
||||||
|
|
||||||
self.orig_image = tool.get_image(
|
self.orig_image = tool.get_image(frame, 0, 0, width, height, c.BLACK, scale)
|
||||||
frame, 0, 0, width, height, c.BLACK, scale
|
|
||||||
)
|
|
||||||
self.orig_rect = self.orig_image.get_rect()
|
self.orig_rect = self.orig_image.get_rect()
|
||||||
self.image = self.orig_image
|
self.image = self.orig_image
|
||||||
|
|
||||||
def checkMouseClick(self, mouse_pos):
|
def checkMouseClick(self, mouse_pos):
|
||||||
x, y = mouse_pos
|
x, y = mouse_pos
|
||||||
if (
|
if (self.rect.x <= x <= self.rect.right and
|
||||||
self.rect.x <= x <= self.rect.right
|
self.rect.y <= y <= self.rect.bottom):
|
||||||
and self.rect.y <= y <= self.rect.bottom
|
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -475,18 +411,14 @@ class MoveCard:
|
|||||||
self.orig_image.set_alpha(128)
|
self.orig_image.set_alpha(128)
|
||||||
else:
|
else:
|
||||||
self.orig_image.set_alpha(255)
|
self.orig_image.set_alpha(255)
|
||||||
image.blit(
|
image.blit(self.orig_image, (0, 0), (0, 0, self.rect.w, self.rect.h))
|
||||||
self.orig_image, (0, 0), (0, 0, self.rect.w, self.rect.h)
|
|
||||||
)
|
|
||||||
self.rect.w += 1
|
self.rect.w += 1
|
||||||
else:
|
else:
|
||||||
if self.clicked:
|
if self.clicked:
|
||||||
image = pg.Surface([self.rect.w, self.rect.h]) # 黑底
|
image = pg.Surface([self.rect.w, self.rect.h]) # 黑底
|
||||||
self.orig_image.set_alpha(128)
|
self.orig_image.set_alpha(128)
|
||||||
|
|
||||||
image.blit(
|
image.blit(self.orig_image, (0,0), (0, 0, self.rect.w, self.rect.h))
|
||||||
self.orig_image, (0, 0), (0, 0, self.rect.w, self.rect.h)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
self.orig_image.set_alpha(255)
|
self.orig_image.set_alpha(255)
|
||||||
image = self.orig_image
|
image = self.orig_image
|
||||||
@ -504,9 +436,8 @@ class MoveCard:
|
|||||||
def draw(self, surface):
|
def draw(self, surface):
|
||||||
surface.blit(self.image, self.rect)
|
surface.blit(self.image, self.rect)
|
||||||
|
|
||||||
|
|
||||||
# 传送带
|
# 传送带
|
||||||
class MoveBar:
|
class MoveBar():
|
||||||
def __init__(self, card_pool):
|
def __init__(self, card_pool):
|
||||||
self.loadFrame(c.MOVEBAR_BACKGROUND)
|
self.loadFrame(c.MOVEBAR_BACKGROUND)
|
||||||
self.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
@ -529,24 +460,12 @@ class MoveBar:
|
|||||||
self.image = tool.get_image(tool.GFX[name], *frame_rect, c.WHITE, 1)
|
self.image = tool.get_image(tool.GFX[name], *frame_rect, c.WHITE, 1)
|
||||||
|
|
||||||
def createCard(self):
|
def createCard(self):
|
||||||
if (
|
if len(self.card_list) > 0 and self.card_list[-1].rect.right > self.card_end_x:
|
||||||
len(self.card_list) > 0
|
|
||||||
and self.card_list[-1].rect.right > self.card_end_x
|
|
||||||
):
|
|
||||||
return False
|
return False
|
||||||
x = self.card_end_x
|
x = self.card_end_x
|
||||||
y = 6
|
y = 6
|
||||||
selected_card = random.choices(
|
selected_card = random.choices(self.card_pool_name, self.card_pool_weight)[0]
|
||||||
self.card_pool_name, self.card_pool_weight
|
self.card_list.append(MoveCard(x, y, selected_card[c.CARD_INDEX], selected_card[c.PLANT_NAME_INDEX]))
|
||||||
)[0]
|
|
||||||
self.card_list.append(
|
|
||||||
MoveCard(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
selected_card[c.CARD_INDEX],
|
|
||||||
selected_card[c.PLANT_NAME_INDEX],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update(self, current_time):
|
def update(self, current_time):
|
||||||
@ -570,10 +489,8 @@ class MoveBar:
|
|||||||
|
|
||||||
def checkMenuBarClick(self, mouse_pos):
|
def checkMenuBarClick(self, mouse_pos):
|
||||||
x, y = mouse_pos
|
x, y = mouse_pos
|
||||||
if (
|
if (self.rect.x <= x <= self.rect.right and
|
||||||
self.rect.x <= x <= self.rect.right
|
self.rect.y <= y <= self.rect.bottom):
|
||||||
and self.rect.y <= y <= self.rect.bottom
|
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,49 +1,30 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
import pygame as pg
|
import pygame as pg
|
||||||
|
|
||||||
# 用户数据及日志存储路径
|
# 用户数据及日志存储路径
|
||||||
if os.name == 'nt': # Windows系统存储路径
|
if os.name == "nt": # Windows系统存储路径
|
||||||
USERDATA_PATH = os.path.expandvars(
|
USERDATA_PATH = os.path.expandvars(os.path.join("%APPDATA%", "pypvz", "userdata.json"))
|
||||||
os.path.join('%APPDATA%', 'pypvz', 'userdata.json')
|
USERLOG_PATH = os.path.expandvars(os.path.join("%APPDATA%", "pypvz", "run.log"))
|
||||||
)
|
|
||||||
USERLOG_PATH = os.path.expandvars(
|
|
||||||
os.path.join('%APPDATA%', 'pypvz', 'run.log')
|
|
||||||
)
|
|
||||||
else: # 非Windows系统存储路径
|
else: # 非Windows系统存储路径
|
||||||
USERDATA_PATH = os.path.expanduser(
|
USERDATA_PATH = os.path.expanduser(os.path.join("~", ".config", "pypvz", "userdata.json"))
|
||||||
os.path.join('~', '.config', 'pypvz', 'userdata.json')
|
USERLOG_PATH = os.path.expanduser(os.path.join("~", ".config", "pypvz", "run.log"))
|
||||||
)
|
|
||||||
USERLOG_PATH = os.path.expanduser(
|
|
||||||
os.path.join('~', '.config', 'pypvz', 'run.log')
|
|
||||||
)
|
|
||||||
|
|
||||||
# 游戏图片资源路径
|
# 游戏图片资源路径
|
||||||
PATH_IMG_DIR = os.path.join(
|
PATH_IMG_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources", "graphics")
|
||||||
os.path.dirname(os.path.dirname(__file__)), 'resources', 'graphics'
|
|
||||||
)
|
|
||||||
# 游戏音乐文件夹路径
|
# 游戏音乐文件夹路径
|
||||||
PATH_MUSIC_DIR = os.path.join(
|
PATH_MUSIC_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources","music")
|
||||||
os.path.dirname(os.path.dirname(__file__)), 'resources', 'music'
|
|
||||||
)
|
|
||||||
# 窗口图标
|
# 窗口图标
|
||||||
ORIGINAL_LOGO = os.path.join(
|
ORIGINAL_LOGO = os.path.join(os.path.dirname(os.path.dirname(__file__)), "pypvz-exec-logo.png")
|
||||||
os.path.dirname(os.path.dirname(__file__)), 'pypvz-exec-logo.png'
|
|
||||||
)
|
|
||||||
# 字体路径
|
# 字体路径
|
||||||
FONT_PATH = os.path.join(
|
FONT_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources", "DroidSansFallback.ttf")
|
||||||
os.path.dirname(os.path.dirname(__file__)),
|
|
||||||
'resources',
|
|
||||||
'DroidSansFallback.ttf',
|
|
||||||
)
|
|
||||||
|
|
||||||
# 窗口标题
|
# 窗口标题
|
||||||
ORIGINAL_CAPTION = 'pypvz'
|
ORIGINAL_CAPTION = "pypvz"
|
||||||
|
|
||||||
# 游戏模式
|
# 游戏模式
|
||||||
GAME_MODE = 'mode'
|
GAME_MODE = "mode"
|
||||||
MODE_ADVENTURE = 'adventure'
|
MODE_ADVENTURE = "adventure"
|
||||||
MODE_LITTLEGAME = 'littleGame'
|
MODE_LITTLEGAME = "littleGame"
|
||||||
|
|
||||||
# 窗口大小
|
# 窗口大小
|
||||||
SCREEN_WIDTH = 800
|
SCREEN_WIDTH = 800
|
||||||
@ -89,63 +70,63 @@ LIGHTGRAY = (107, 108, 145)
|
|||||||
PARCHMENT_YELLOW = (207, 146, 83)
|
PARCHMENT_YELLOW = (207, 146, 83)
|
||||||
|
|
||||||
# 退出游戏按钮
|
# 退出游戏按钮
|
||||||
EXIT = 'exit'
|
EXIT = "exit"
|
||||||
HELP = 'help'
|
HELP = "help"
|
||||||
# 游戏界面可选的菜单
|
# 游戏界面可选的菜单
|
||||||
LITTLE_MENU = 'littleMenu'
|
LITTLE_MENU = "littleMenu"
|
||||||
BIG_MENU = 'bigMenu'
|
BIG_MENU = "bigMenu"
|
||||||
RESTART_BUTTON = 'restartButton'
|
RESTART_BUTTON = "restartButton"
|
||||||
MAINMENU_BUTTON = 'mainMenuButton'
|
MAINMENU_BUTTON = "mainMenuButton"
|
||||||
LITTLEGAME_BUTTON = 'littleGameButton'
|
LITTLEGAME_BUTTON = "littleGameButton"
|
||||||
OPTION_BUTTON = 'optionButton'
|
OPTION_BUTTON = "optionButton"
|
||||||
SOUND_VOLUME_BUTTON = 'volumeButton'
|
SOUND_VOLUME_BUTTON = "volumeButton"
|
||||||
UNIVERSAL_BUTTON = 'universalButton'
|
UNIVERSAL_BUTTON = "universalButton"
|
||||||
# 金银向日葵奖杯
|
# 金银向日葵奖杯
|
||||||
TROPHY_SUNFLOWER = 'sunflowerTrophy'
|
TROPHY_SUNFLOWER = "sunflowerTrophy"
|
||||||
# 小铲子
|
# 小铲子
|
||||||
SHOVEL = 'shovel'
|
SHOVEL = "shovel"
|
||||||
SHOVEL_BOX = 'shovelBox'
|
SHOVEL_BOX = "shovelBox"
|
||||||
# 一大波僵尸来袭图片
|
# 一大波僵尸来袭图片
|
||||||
HUGE_WAVE_APPROCHING = 'Approching'
|
HUGE_WAVE_APPROCHING = "Approching"
|
||||||
# 关卡进程图片
|
# 关卡进程图片
|
||||||
LEVEL_PROGRESS_BAR = 'LevelProgressBar'
|
LEVEL_PROGRESS_BAR = "LevelProgressBar"
|
||||||
LEVEL_PROGRESS_ZOMBIE_HEAD = 'LevelProgressZombieHead'
|
LEVEL_PROGRESS_ZOMBIE_HEAD = "LevelProgressZombieHead"
|
||||||
LEVEL_PROGRESS_FLAG = 'LevelProgressFlag'
|
LEVEL_PROGRESS_FLAG = "LevelProgressFlag"
|
||||||
|
|
||||||
|
|
||||||
# GAME INFO字典键值
|
# GAME INFO字典键值
|
||||||
CURRENT_TIME = 'current time'
|
CURRENT_TIME = "current time"
|
||||||
PASSED_ALL = 'passed all' # 已完成该模式下的所有游戏,应当显示向日葵奖杯获得界面
|
PASSED_ALL = "passed all" # 已完成该模式下的所有游戏,应当显示向日葵奖杯获得界面
|
||||||
LEVEL_NUM = 'level num'
|
LEVEL_NUM = "level num"
|
||||||
LITTLEGAME_NUM = 'littleGame num'
|
LITTLEGAME_NUM = "littleGame num"
|
||||||
LEVEL_COMPLETIONS = 'level completions'
|
LEVEL_COMPLETIONS = "level completions"
|
||||||
LITTLEGAME_COMPLETIONS = 'littleGame completions'
|
LITTLEGAME_COMPLETIONS = "littleGame completions"
|
||||||
GAME_RATE = 'game rate'
|
GAME_RATE = "game rate"
|
||||||
SOUND_VOLUME = 'volume'
|
SOUND_VOLUME = "volume"
|
||||||
|
|
||||||
# 整个游戏的状态
|
# 整个游戏的状态
|
||||||
MAIN_MENU = 'main menu'
|
MAIN_MENU = "main menu"
|
||||||
LOAD_SCREEN = 'load screen'
|
LOAD_SCREEN = "load screen"
|
||||||
GAME_LOSE = 'game lose'
|
GAME_LOSE = "game lose"
|
||||||
GAME_VICTORY = 'game victory'
|
GAME_VICTORY = "game victory"
|
||||||
LEVEL = 'level'
|
LEVEL = "level"
|
||||||
AWARD_SCREEN = 'award screen'
|
AWARD_SCREEN = "award screen"
|
||||||
HELP_SCREEN = 'help screen'
|
HELP_SCREEN = "help screen"
|
||||||
|
|
||||||
# 界面图片文件名
|
# 界面图片文件名
|
||||||
MAIN_MENU_IMAGE = 'MainMenu'
|
MAIN_MENU_IMAGE = "MainMenu"
|
||||||
OPTION_ADVENTURE = 'Adventure'
|
OPTION_ADVENTURE = "Adventure"
|
||||||
GAME_LOSE_IMAGE = 'GameLose'
|
GAME_LOSE_IMAGE = "GameLose"
|
||||||
GAME_VICTORY_IMAGE = 'GameVictory'
|
GAME_VICTORY_IMAGE = "GameVictory"
|
||||||
AWARD_SCREEN_IMAGE = 'AwardScreen'
|
AWARD_SCREEN_IMAGE = "AwardScreen"
|
||||||
HELP_SCREEN_IMAGE = 'HelpScreen'
|
HELP_SCREEN_IMAGE = "HelpScreen"
|
||||||
|
|
||||||
# 地图相关内容
|
# 地图相关内容
|
||||||
BACKGROUND_NAME = 'Background'
|
BACKGROUND_NAME = "Background"
|
||||||
BACKGROUND_TYPE = 'background_type'
|
BACKGROUND_TYPE = "background_type"
|
||||||
INIT_SUN_NAME = 'init_sun_value'
|
INIT_SUN_NAME = "init_sun_value"
|
||||||
ZOMBIE_LIST = 'zombie_list'
|
ZOMBIE_LIST = "zombie_list"
|
||||||
GAME_TITLE = 'title'
|
GAME_TITLE = "title"
|
||||||
|
|
||||||
# 地图类型
|
# 地图类型
|
||||||
BACKGROUND_DAY = 0
|
BACKGROUND_DAY = 0
|
||||||
@ -161,56 +142,50 @@ BACKGROUND_TRIPLE = 8
|
|||||||
# 地图类型集合
|
# 地图类型集合
|
||||||
# 白天场地(泛指蘑菇睡觉的场地)
|
# 白天场地(泛指蘑菇睡觉的场地)
|
||||||
DAYTIME_BACKGROUNDS = {
|
DAYTIME_BACKGROUNDS = {
|
||||||
BACKGROUND_DAY,
|
BACKGROUND_DAY, BACKGROUND_POOL,
|
||||||
BACKGROUND_POOL,
|
BACKGROUND_ROOF, BACKGROUND_WALLNUTBOWLING,
|
||||||
BACKGROUND_ROOF,
|
BACKGROUND_SINGLE, BACKGROUND_TRIPLE,
|
||||||
BACKGROUND_WALLNUTBOWLING,
|
|
||||||
BACKGROUND_SINGLE,
|
|
||||||
BACKGROUND_TRIPLE,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 带有泳池的场地
|
# 带有泳池的场地
|
||||||
POOL_EQUIPPED_BACKGROUNDS = {
|
POOL_EQUIPPED_BACKGROUNDS = {
|
||||||
BACKGROUND_POOL,
|
BACKGROUND_POOL, BACKGROUND_FOG,
|
||||||
BACKGROUND_FOG,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 屋顶上的场地
|
# 屋顶上的场地
|
||||||
ON_ROOF_BACKGROUNDS = {
|
ON_ROOF_BACKGROUNDS = {
|
||||||
BACKGROUND_ROOF,
|
BACKGROUND_ROOF, BACKGROUND_ROOFNIGHT,
|
||||||
BACKGROUND_ROOFNIGHT,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# BACKGROUND_DAY场地的变体
|
# BACKGROUND_DAY场地的变体
|
||||||
BACKGROUND_DAY_LIKE_BACKGROUNDS = {
|
BACKGROUND_DAY_LIKE_BACKGROUNDS = {
|
||||||
BACKGROUND_DAY,
|
BACKGROUND_DAY, BACKGROUND_SINGLE,
|
||||||
BACKGROUND_SINGLE,
|
|
||||||
BACKGROUND_TRIPLE,
|
BACKGROUND_TRIPLE,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 夜晚地图的墓碑数量等级
|
# 夜晚地图的墓碑数量等级
|
||||||
GRADE_GRAVES = 'grade_graves'
|
GRADE_GRAVES = "grade_graves"
|
||||||
# 不同墓碑等级对应的信息,列表位置对应的是墓碑等级
|
# 不同墓碑等级对应的信息,列表位置对应的是墓碑等级
|
||||||
GRAVES_GRADE_INFO = (0, 4, 7, 11)
|
GRAVES_GRADE_INFO = (0, 4, 7, 11)
|
||||||
|
|
||||||
# 僵尸生成方式
|
# 僵尸生成方式
|
||||||
SPAWN_ZOMBIES = 'spawn_zombies'
|
SPAWN_ZOMBIES = "spawn_zombies"
|
||||||
SPAWN_ZOMBIES_AUTO = 1
|
SPAWN_ZOMBIES_AUTO = 1
|
||||||
SPAWN_ZOMBIES_LIST = 0
|
SPAWN_ZOMBIES_LIST = 0
|
||||||
INCLUDED_ZOMBIES = 'included_zombies'
|
INCLUDED_ZOMBIES = "included_zombies"
|
||||||
NUM_FLAGS = 'num_flags'
|
NUM_FLAGS = "num_flags"
|
||||||
INEVITABLE_ZOMBIE_DICT = 'inevitable_zombie_list'
|
INEVITABLE_ZOMBIE_DICT = "inevitable_zombie_list"
|
||||||
SURVIVAL_ROUNDS = 'survival_rounds'
|
SURVIVAL_ROUNDS = "survival_rounds"
|
||||||
|
|
||||||
# 地图单元格属性
|
# 地图单元格属性
|
||||||
MAP_PLANT = 'plantnames'
|
MAP_PLANT = "plantnames"
|
||||||
MAP_SLEEP = 'sleep' # 有没有休眠的蘑菇,作是否能种植咖啡豆的判断
|
MAP_SLEEP = "sleep" # 有没有休眠的蘑菇,作是否能种植咖啡豆的判断
|
||||||
MAP_PLOT_TYPE = 'plot_type'
|
MAP_PLOT_TYPE = "plot_type"
|
||||||
# 地图单元格区域类型
|
# 地图单元格区域类型
|
||||||
MAP_GRASS = 'grass'
|
MAP_GRASS = "grass"
|
||||||
MAP_WATER = 'water'
|
MAP_WATER = "water"
|
||||||
MAP_TILE = 'tile' # 指屋顶上的瓦片
|
MAP_TILE = "tile" # 指屋顶上的瓦片
|
||||||
MAP_UNAVAILABLE = 'unavailable' # 指完全不能种植物的地方,包括无草皮的荒地和坚果保龄球等红线右侧
|
MAP_UNAVAILABLE = "unavailable" # 指完全不能种植物的地方,包括无草皮的荒地和坚果保龄球等红线右侧
|
||||||
|
|
||||||
# 地图相关像素数据
|
# 地图相关像素数据
|
||||||
BACKGROUND_OFFSET_X = 220
|
BACKGROUND_OFFSET_X = 220
|
||||||
@ -225,15 +200,15 @@ MAP_ROOF_OFFSET_Y = 105 # 暂时还不清楚数据
|
|||||||
MAP_POOL_FRONT_X = SCREEN_WIDTH - 15
|
MAP_POOL_FRONT_X = SCREEN_WIDTH - 15
|
||||||
|
|
||||||
# 植物选择菜单栏、传送带菜单栏等类型设定
|
# 植物选择菜单栏、传送带菜单栏等类型设定
|
||||||
CHOOSEBAR_TYPE = 'choosebar_type'
|
CHOOSEBAR_TYPE = "choosebar_type"
|
||||||
CHOOSEBAR_STATIC = 0
|
CHOOSEBAR_STATIC = 0
|
||||||
CHOOSEBAR_MOVE = 1
|
CHOOSEBAR_MOVE = 1
|
||||||
CHOOSEBAR_BOWLING = 2
|
CHOOSEBAR_BOWLING = 2
|
||||||
MENUBAR_BACKGROUND = 'ChooserBackground'
|
MENUBAR_BACKGROUND = "ChooserBackground"
|
||||||
MOVEBAR_BACKGROUND = 'MoveBackground'
|
MOVEBAR_BACKGROUND = "MoveBackground"
|
||||||
PANEL_BACKGROUND = 'PanelBackground'
|
PANEL_BACKGROUND = "PanelBackground"
|
||||||
START_BUTTON = 'StartButton'
|
START_BUTTON = "StartButton"
|
||||||
CARD_POOL = 'card_pool'
|
CARD_POOL = "card_pool"
|
||||||
|
|
||||||
# 关于植物栏的像素设置
|
# 关于植物栏的像素设置
|
||||||
PANEL_Y_START = 87
|
PANEL_Y_START = 87
|
||||||
@ -253,147 +228,155 @@ MOVEBAR_CARD_FRESH_TIME = 6000
|
|||||||
CARD_MOVE_TIME = 60
|
CARD_MOVE_TIME = 60
|
||||||
|
|
||||||
# 其他显示物
|
# 其他显示物
|
||||||
CAR = 'car'
|
CAR = "car"
|
||||||
SUN = 'Sun'
|
SUN = "Sun"
|
||||||
|
|
||||||
# plant子类非植物对象(这里的是不包括阳光、子弹的拟植物对象)
|
# plant子类非植物对象(这里的是不包括阳光、子弹的拟植物对象)
|
||||||
NON_PLANT_OBJECTS = {
|
NON_PLANT_OBJECTS = {
|
||||||
HOLE := 'Hole',
|
HOLE := "Hole",
|
||||||
ICEFROZENPLOT := 'IceFrozenPlot',
|
ICEFROZENPLOT := "IceFrozenPlot",
|
||||||
GRAVE := 'Grave',
|
GRAVE := "Grave",
|
||||||
}
|
}
|
||||||
|
|
||||||
# 植物相关信息
|
# 植物相关信息
|
||||||
PLANT_IMAGE_RECT = 'plant_image_rect'
|
PLANT_IMAGE_RECT = "plant_image_rect"
|
||||||
BOOM_IMAGE = 'Boom'
|
BOOM_IMAGE = "Boom"
|
||||||
|
|
||||||
# 植物卡片信息汇总(包括植物名称, 卡片名称, 阳光, 冷却时间)
|
# 植物卡片信息汇总(包括植物名称, 卡片名称, 阳光, 冷却时间)
|
||||||
PLANT_CARD_INFO = (# 元组 (植物名称, 卡片名称, 阳光, 冷却时间)
|
PLANT_CARD_INFO = (# 元组 (植物名称, 卡片名称, 阳光, 冷却时间)
|
||||||
(
|
(PEASHOOTER := "Peashooter",
|
||||||
PEASHOOTER := 'Peashooter',
|
CARD_PEASHOOTER := "card_peashooter",
|
||||||
CARD_PEASHOOTER := 'card_peashooter',
|
|
||||||
100,
|
100,
|
||||||
7500,
|
7500),
|
||||||
),
|
(SUNFLOWER := "SunFlower",
|
||||||
(SUNFLOWER := 'SunFlower', CARD_SUNFLOWER := 'card_sunflower', 50, 7500),
|
CARD_SUNFLOWER := "card_sunflower",
|
||||||
(
|
50,
|
||||||
CHERRYBOMB := 'CherryBomb',
|
7500),
|
||||||
CARD_CHERRYBOMB := 'card_cherrybomb',
|
(CHERRYBOMB := "CherryBomb",
|
||||||
|
CARD_CHERRYBOMB := "card_cherrybomb",
|
||||||
150,
|
150,
|
||||||
50000,
|
50000),
|
||||||
),
|
(WALLNUT := "WallNut",
|
||||||
(WALLNUT := 'WallNut', CARD_WALLNUT := 'card_wallnut', 50, 30000),
|
CARD_WALLNUT := "card_wallnut",
|
||||||
(
|
50,
|
||||||
POTATOMINE := 'PotatoMine',
|
30000),
|
||||||
CARD_POTATOMINE := 'card_potatomine',
|
(POTATOMINE := "PotatoMine",
|
||||||
|
CARD_POTATOMINE := "card_potatomine",
|
||||||
25,
|
25,
|
||||||
30000,
|
30000),
|
||||||
),
|
(SNOWPEASHOOTER := "SnowPea",
|
||||||
(
|
CARD_SNOWPEASHOOTER := "card_snowpea",
|
||||||
SNOWPEASHOOTER := 'SnowPea',
|
|
||||||
CARD_SNOWPEASHOOTER := 'card_snowpea',
|
|
||||||
175,
|
175,
|
||||||
7500,
|
7500),
|
||||||
),
|
(CHOMPER := "Chomper",
|
||||||
(CHOMPER := 'Chomper', CARD_CHOMPER := 'card_chomper', 150, 7500),
|
CARD_CHOMPER := "card_chomper",
|
||||||
(
|
150,
|
||||||
REPEATERPEA := 'RepeaterPea',
|
7500),
|
||||||
CARD_REPEATERPEA := 'card_repeaterpea',
|
(REPEATERPEA := "RepeaterPea",
|
||||||
|
CARD_REPEATERPEA := "card_repeaterpea",
|
||||||
200,
|
200,
|
||||||
7500,
|
7500),
|
||||||
),
|
(PUFFSHROOM := "PuffShroom",
|
||||||
(
|
CARD_PUFFSHROOM := "card_puffshroom",
|
||||||
PUFFSHROOM := 'PuffShroom',
|
|
||||||
CARD_PUFFSHROOM := 'card_puffshroom',
|
|
||||||
0,
|
0,
|
||||||
7500,
|
7500),
|
||||||
),
|
(SUNSHROOM := "SunShroom",
|
||||||
(SUNSHROOM := 'SunShroom', CARD_SUNSHROOM := 'card_sunshroom', 25, 7500),
|
CARD_SUNSHROOM := "card_sunshroom",
|
||||||
(
|
|
||||||
FUMESHROOM := 'FumeShroom',
|
|
||||||
CARD_FUMESHROOM := 'card_fumeshroom',
|
|
||||||
75,
|
|
||||||
7500,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
GRAVEBUSTER := 'GraveBuster',
|
|
||||||
CARD_GRAVEBUSTER := 'card_gravebuster',
|
|
||||||
75,
|
|
||||||
7500,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
HYPNOSHROOM := 'HypnoShroom',
|
|
||||||
CARD_HYPNOSHROOM := 'card_hypnoshroom',
|
|
||||||
75,
|
|
||||||
30000,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
SCAREDYSHROOM := 'ScaredyShroom',
|
|
||||||
CARD_SCAREDYSHROOM := 'card_scaredyshroom',
|
|
||||||
25,
|
25,
|
||||||
7500,
|
7500),
|
||||||
),
|
(FUMESHROOM := "FumeShroom",
|
||||||
(ICESHROOM := 'IceShroom', CARD_ICESHROOM := 'card_iceshroom', 75, 50000),
|
CARD_FUMESHROOM := "card_fumeshroom",
|
||||||
(
|
75,
|
||||||
DOOMSHROOM := 'DoomShroom',
|
7500),
|
||||||
CARD_DOOMSHROOM := 'card_doomshroom',
|
(GRAVEBUSTER := "GraveBuster",
|
||||||
|
CARD_GRAVEBUSTER := "card_gravebuster",
|
||||||
|
75,
|
||||||
|
7500),
|
||||||
|
(HYPNOSHROOM := "HypnoShroom",
|
||||||
|
CARD_HYPNOSHROOM := "card_hypnoshroom",
|
||||||
|
75,
|
||||||
|
30000),
|
||||||
|
(SCAREDYSHROOM := "ScaredyShroom",
|
||||||
|
CARD_SCAREDYSHROOM := "card_scaredyshroom",
|
||||||
|
25,
|
||||||
|
7500),
|
||||||
|
(ICESHROOM := "IceShroom",
|
||||||
|
CARD_ICESHROOM := "card_iceshroom",
|
||||||
|
75,
|
||||||
|
50000),
|
||||||
|
(DOOMSHROOM := "DoomShroom",
|
||||||
|
CARD_DOOMSHROOM := "card_doomshroom",
|
||||||
125,
|
125,
|
||||||
50000,
|
50000),
|
||||||
),
|
(LILYPAD := "LilyPad",
|
||||||
(LILYPAD := 'LilyPad', CARD_LILYPAD := 'card_lilypad', 25, 7500),
|
CARD_LILYPAD := "card_lilypad",
|
||||||
(SQUASH := 'Squash', CARD_SQUASH := 'card_squash', 50, 30000),
|
|
||||||
(
|
|
||||||
TANGLEKLEP := 'TangleKlep',
|
|
||||||
CARD_TANGLEKLEP := 'card_tangleklep',
|
|
||||||
25,
|
25,
|
||||||
30000,
|
7500),
|
||||||
),
|
(SQUASH := "Squash",
|
||||||
(
|
CARD_SQUASH := "card_squash",
|
||||||
THREEPEASHOOTER := 'Threepeater',
|
50,
|
||||||
CARD_THREEPEASHOOTER := 'card_threepeashooter',
|
30000),
|
||||||
|
(TANGLEKLEP := "TangleKlep",
|
||||||
|
CARD_TANGLEKLEP := "card_tangleklep",
|
||||||
|
25,
|
||||||
|
30000),
|
||||||
|
(THREEPEASHOOTER := "Threepeater",
|
||||||
|
CARD_THREEPEASHOOTER := "card_threepeashooter",
|
||||||
325,
|
325,
|
||||||
7500,
|
7500),
|
||||||
),
|
(JALAPENO := "Jalapeno",
|
||||||
(JALAPENO := 'Jalapeno', CARD_JALAPENO := 'card_jalapeno', 125, 50000),
|
CARD_JALAPENO := "card_jalapeno",
|
||||||
(SPIKEWEED := 'Spikeweed', CARD_SPIKEWEED := 'card_spikeweed', 100, 7500),
|
|
||||||
(TORCHWOOD := 'TorchWood', CARD_TORCHWOOD := 'card_torchwood', 175, 7500),
|
|
||||||
(TALLNUT := 'TallNut', CARD_TALLNUT := 'card_tallnut', 125, 30000),
|
|
||||||
(SEASHROOM := 'SeaShroom', CARD_SEASHROOM := 'card_seashroom', 0, 30000),
|
|
||||||
(STARFRUIT := 'StarFruit', CARD_STARFRUIT := 'card_starfruit', 125, 7500),
|
|
||||||
(
|
|
||||||
PUMPKINHEAD := 'PumpkinHead',
|
|
||||||
CARD_PUMPKINHEAD := 'card_pumpkinhead',
|
|
||||||
125,
|
125,
|
||||||
30000,
|
50000),
|
||||||
),
|
(SPIKEWEED := "Spikeweed",
|
||||||
(
|
CARD_SPIKEWEED := "card_spikeweed",
|
||||||
COFFEEBEAN := 'CoffeeBean',
|
100,
|
||||||
CARD_COFFEEBEAN := 'card_coffeebean',
|
7500),
|
||||||
|
(TORCHWOOD := "TorchWood",
|
||||||
|
CARD_TORCHWOOD := "card_torchwood",
|
||||||
|
175,
|
||||||
|
7500),
|
||||||
|
(TALLNUT := "TallNut",
|
||||||
|
CARD_TALLNUT := "card_tallnut",
|
||||||
|
125,
|
||||||
|
30000),
|
||||||
|
(SEASHROOM := "SeaShroom",
|
||||||
|
CARD_SEASHROOM := "card_seashroom",
|
||||||
|
0,
|
||||||
|
30000),
|
||||||
|
(STARFRUIT := "StarFruit",
|
||||||
|
CARD_STARFRUIT := "card_starfruit",
|
||||||
|
125,
|
||||||
|
7500),
|
||||||
|
(PUMPKINHEAD := "PumpkinHead",
|
||||||
|
CARD_PUMPKINHEAD := "card_pumpkinhead",
|
||||||
|
125,
|
||||||
|
30000),
|
||||||
|
(COFFEEBEAN := "CoffeeBean",
|
||||||
|
CARD_COFFEEBEAN := "card_coffeebean",
|
||||||
75,
|
75,
|
||||||
7500,
|
7500),
|
||||||
),
|
(GARLIC := "Garlic",
|
||||||
(GARLIC := 'Garlic', CARD_GARLIC := 'card_garlic', 50, 7500),
|
CARD_GARLIC := "card_garlic",
|
||||||
|
50,
|
||||||
|
7500),
|
||||||
# 应当保证这3个在一般模式下不可选的特殊植物恒在最后
|
# 应当保证这3个在一般模式下不可选的特殊植物恒在最后
|
||||||
(WALLNUTBOWLING := 'WallNutBowling', CARD_WALLNUT := 'card_wallnut', 0, 0),
|
(WALLNUTBOWLING := "WallNutBowling",
|
||||||
(
|
CARD_WALLNUT := "card_wallnut",
|
||||||
REDWALLNUTBOWLING := 'RedWallNutBowling',
|
|
||||||
CARD_REDWALLNUT := 'card_redwallnut',
|
|
||||||
0,
|
0,
|
||||||
|
0),
|
||||||
|
(REDWALLNUTBOWLING := "RedWallNutBowling",
|
||||||
|
CARD_REDWALLNUT := "card_redwallnut",
|
||||||
0,
|
0,
|
||||||
),
|
0),
|
||||||
(
|
(GIANTWALLNUT := "GiantWallNut",
|
||||||
GIANTWALLNUT := 'GiantWallNut',
|
CARD_GIANTWALLNUT := "card_giantwallnut",
|
||||||
CARD_GIANTWALLNUT := 'card_giantwallnut',
|
|
||||||
0,
|
0,
|
||||||
0,
|
0),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 卡片中的植物名称与索引序号的对应关系,指定名称以得到索引值
|
# 卡片中的植物名称与索引序号的对应关系,指定名称以得到索引值
|
||||||
PLANT_CARD_INDEX = {
|
PLANT_CARD_INDEX = {item[PLANT_NAME_INDEX]: index for (index, item) in enumerate(PLANT_CARD_INFO)}
|
||||||
item[PLANT_NAME_INDEX]: index
|
|
||||||
for (index, item) in enumerate(PLANT_CARD_INFO)
|
|
||||||
}
|
|
||||||
|
|
||||||
# 指定了哪些卡可选(排除坚果保龄球特殊植物)
|
# 指定了哪些卡可选(排除坚果保龄球特殊植物)
|
||||||
CARDS_TO_CHOOSE = range(len(PLANT_CARD_INFO) - 3)
|
CARDS_TO_CHOOSE = range(len(PLANT_CARD_INFO) - 3)
|
||||||
@ -404,12 +387,9 @@ CARDS_TO_CHOOSE = range(len(PLANT_CARD_INFO) - 3)
|
|||||||
# 在生效时不用与僵尸进行碰撞检测的对象(即生效时不可发生被僵尸啃食的事件)
|
# 在生效时不用与僵尸进行碰撞检测的对象(即生效时不可发生被僵尸啃食的事件)
|
||||||
SKIP_ZOMBIE_COLLISION_CHECK_WHEN_WORKING = {
|
SKIP_ZOMBIE_COLLISION_CHECK_WHEN_WORKING = {
|
||||||
# 注意爆炸坚果的触发也是啃食类碰撞,因此只能算作爆炸后不检测
|
# 注意爆炸坚果的触发也是啃食类碰撞,因此只能算作爆炸后不检测
|
||||||
SQUASH,
|
SQUASH, ICESHROOM,
|
||||||
ICESHROOM,
|
REDWALLNUTBOWLING, CHERRYBOMB,
|
||||||
REDWALLNUTBOWLING,
|
JALAPENO, DOOMSHROOM,
|
||||||
CHERRYBOMB,
|
|
||||||
JALAPENO,
|
|
||||||
DOOMSHROOM,
|
|
||||||
POTATOMINE,
|
POTATOMINE,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,35 +397,27 @@ SKIP_ZOMBIE_COLLISION_CHECK_WHEN_WORKING = {
|
|||||||
CAN_SKIP_ZOMBIE_COLLISION_CHECK = ( # 这里运用了集合运算
|
CAN_SKIP_ZOMBIE_COLLISION_CHECK = ( # 这里运用了集合运算
|
||||||
# 注意这个外围的小括号是用来换行的
|
# 注意这个外围的小括号是用来换行的
|
||||||
# 各个部分末!尾!千!万!不!能!加!逗!号!!!
|
# 各个部分末!尾!千!万!不!能!加!逗!号!!!
|
||||||
|
|
||||||
# 生效时不检测的植物
|
# 生效时不检测的植物
|
||||||
SKIP_ZOMBIE_COLLISION_CHECK_WHEN_WORKING
|
SKIP_ZOMBIE_COLLISION_CHECK_WHEN_WORKING |
|
||||||
|
|
|
||||||
# 非植物对象
|
# 非植物对象
|
||||||
NON_PLANT_OBJECTS
|
NON_PLANT_OBJECTS |
|
||||||
|
|
|
||||||
# 地刺类
|
# 地刺类
|
||||||
{
|
{SPIKEWEED, }
|
||||||
SPIKEWEED,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 死亡时不触发音效的对象
|
# 死亡时不触发音效的对象
|
||||||
PLANT_DIE_SOUND_EXCEPTIONS = {
|
PLANT_DIE_SOUND_EXCEPTIONS = {
|
||||||
WALLNUTBOWLING,
|
WALLNUTBOWLING, TANGLEKLEP,
|
||||||
TANGLEKLEP,
|
ICEFROZENPLOT, HOLE,
|
||||||
ICEFROZENPLOT,
|
GRAVE, JALAPENO,
|
||||||
HOLE,
|
REDWALLNUTBOWLING, CHERRYBOMB,
|
||||||
GRAVE,
|
|
||||||
JALAPENO,
|
|
||||||
REDWALLNUTBOWLING,
|
|
||||||
CHERRYBOMB,
|
|
||||||
GIANTWALLNUT,
|
GIANTWALLNUT,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 直接水生植物
|
# 直接水生植物
|
||||||
WATER_PLANTS = {
|
WATER_PLANTS = {
|
||||||
LILYPAD,
|
LILYPAD, SEASHROOM,
|
||||||
SEASHROOM,
|
|
||||||
TANGLEKLEP,
|
TANGLEKLEP,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,23 +427,17 @@ CHECK_ATTACK_ALWAYS = 1
|
|||||||
|
|
||||||
# 范围爆炸植物,即灰烬植物与寒冰菇
|
# 范围爆炸植物,即灰烬植物与寒冰菇
|
||||||
ASH_PLANTS_AND_ICESHROOM = {
|
ASH_PLANTS_AND_ICESHROOM = {
|
||||||
REDWALLNUTBOWLING,
|
REDWALLNUTBOWLING, CHERRYBOMB,
|
||||||
CHERRYBOMB,
|
JALAPENO, DOOMSHROOM,
|
||||||
JALAPENO,
|
|
||||||
DOOMSHROOM,
|
|
||||||
ICESHROOM,
|
ICESHROOM,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 白天要睡觉的植物
|
# 白天要睡觉的植物
|
||||||
CAN_SLEEP_PLANTS = {
|
CAN_SLEEP_PLANTS = {
|
||||||
PUFFSHROOM,
|
PUFFSHROOM, SUNSHROOM,
|
||||||
SUNSHROOM,
|
FUMESHROOM, HYPNOSHROOM,
|
||||||
FUMESHROOM,
|
SCAREDYSHROOM, ICESHROOM,
|
||||||
HYPNOSHROOM,
|
DOOMSHROOM, SEASHROOM,
|
||||||
SCAREDYSHROOM,
|
|
||||||
ICESHROOM,
|
|
||||||
DOOMSHROOM,
|
|
||||||
SEASHROOM,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 选卡不推荐选择理由
|
# 选卡不推荐选择理由
|
||||||
@ -502,69 +468,66 @@ SUN_VALUE = 25
|
|||||||
# 僵尸冷冻
|
# 僵尸冷冻
|
||||||
ICE_SLOW_TIME = 10000
|
ICE_SLOW_TIME = 10000
|
||||||
MIN_FREEZE_TIME = 4000
|
MIN_FREEZE_TIME = 4000
|
||||||
ICETRAP = 'IceTrap'
|
ICETRAP = "IceTrap"
|
||||||
|
|
||||||
# 子弹信息
|
# 子弹信息
|
||||||
# 子弹类型
|
# 子弹类型
|
||||||
BULLET_PEA = 'PeaNormal'
|
BULLET_PEA = "PeaNormal"
|
||||||
BULLET_PEA_ICE = 'PeaIce'
|
BULLET_PEA_ICE = "PeaIce"
|
||||||
BULLET_FIREBALL = 'Fireball'
|
BULLET_FIREBALL = "Fireball"
|
||||||
BULLET_MUSHROOM = 'BulletMushRoom'
|
BULLET_MUSHROOM = "BulletMushRoom"
|
||||||
BULLET_SEASHROOM = 'BulletSeaShroom'
|
BULLET_SEASHROOM = "BulletSeaShroom"
|
||||||
FUME = 'Fume'
|
FUME = "Fume"
|
||||||
# 子弹伤害
|
# 子弹伤害
|
||||||
BULLET_DAMAGE_NORMAL = 20
|
BULLET_DAMAGE_NORMAL = 20
|
||||||
BULLET_DAMAGE_FIREBALL_BODY = 27 # 这是火球本体的伤害,注意不是40,本体(27) + 溅射(13)才是40
|
BULLET_DAMAGE_FIREBALL_BODY = 27 # 这是火球本体的伤害,注意不是40,本体(27) + 溅射(13)才是40
|
||||||
BULLET_DAMAGE_FIREBALL_RANGE = 13 # 原版溅射伤害会随着僵尸数量增多而减少,这里相当于做了一个增强
|
BULLET_DAMAGE_FIREBALL_RANGE = 13 # 原版溅射伤害会随着僵尸数量增多而减少,这里相当于做了一个增强
|
||||||
# 子弹效果
|
# 子弹效果
|
||||||
BULLET_EFFECT_ICE = 'ice'
|
BULLET_EFFECT_ICE = "ice"
|
||||||
BULLET_EFFECT_UNICE = 'unice'
|
BULLET_EFFECT_UNICE = "unice"
|
||||||
|
|
||||||
# 特殊子弹
|
# 特殊子弹
|
||||||
# 杨桃子弹
|
# 杨桃子弹
|
||||||
# 子弹名称
|
# 子弹名称
|
||||||
BULLET_STAR = 'StarBullet'
|
BULLET_STAR = "StarBullet"
|
||||||
# 子弹方向
|
# 子弹方向
|
||||||
STAR_FORWARD_UP = 'forwardUp' # 向前上方
|
STAR_FORWARD_UP = "forwardUp" # 向前上方
|
||||||
STAR_FORWARD_DOWN = 'forwardDown' # 向前下方
|
STAR_FORWARD_DOWN = "forwardDown" #向前下方
|
||||||
STAR_BACKWARD = 'backward' # 向后
|
STAR_BACKWARD = "backward" #向后
|
||||||
STAR_UPWARD = 'upward' # 向上
|
STAR_UPWARD = "upward" # 向上
|
||||||
STAR_DOWNWARD = 'downward' # 向下
|
STAR_DOWNWARD = "downward" # 向下
|
||||||
|
|
||||||
# 有爆炸图片的子弹
|
# 有爆炸图片的子弹
|
||||||
BULLET_INDEPENDENT_BOOM_IMG = {
|
BULLET_INDEPENDENT_BOOM_IMG = { BULLET_PEA, BULLET_PEA_ICE,
|
||||||
BULLET_PEA,
|
BULLET_MUSHROOM, BULLET_SEASHROOM,
|
||||||
BULLET_PEA_ICE,
|
|
||||||
BULLET_MUSHROOM,
|
|
||||||
BULLET_SEASHROOM,
|
|
||||||
BULLET_STAR,
|
BULLET_STAR,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 僵尸信息
|
# 僵尸信息
|
||||||
ZOMBIE_IMAGE_RECT = 'zombie_image_rect'
|
ZOMBIE_IMAGE_RECT = "zombie_image_rect"
|
||||||
ZOMBIE_HEAD = 'ZombieHead'
|
ZOMBIE_HEAD = "ZombieHead"
|
||||||
NORMAL_ZOMBIE = 'Zombie'
|
NORMAL_ZOMBIE = "Zombie"
|
||||||
CONEHEAD_ZOMBIE = 'ConeheadZombie'
|
CONEHEAD_ZOMBIE = "ConeheadZombie"
|
||||||
BUCKETHEAD_ZOMBIE = 'BucketheadZombie'
|
BUCKETHEAD_ZOMBIE = "BucketheadZombie"
|
||||||
FLAG_ZOMBIE = 'FlagZombie'
|
FLAG_ZOMBIE = "FlagZombie"
|
||||||
NEWSPAPER_ZOMBIE = 'NewspaperZombie'
|
NEWSPAPER_ZOMBIE = "NewspaperZombie"
|
||||||
FOOTBALL_ZOMBIE = 'FootballZombie'
|
FOOTBALL_ZOMBIE = "FootballZombie"
|
||||||
DUCKY_TUBE_ZOMBIE = 'DuckyTubeZombie'
|
DUCKY_TUBE_ZOMBIE = "DuckyTubeZombie"
|
||||||
CONEHEAD_DUCKY_TUBE_ZOMBIE = 'ConeheadDuckyTubeZombie'
|
CONEHEAD_DUCKY_TUBE_ZOMBIE = "ConeheadDuckyTubeZombie"
|
||||||
BUCKETHEAD_DUCKY_TUBE_ZOMBIE = 'BucketheadDuckyTubeZombie'
|
BUCKETHEAD_DUCKY_TUBE_ZOMBIE = "BucketheadDuckyTubeZombie"
|
||||||
SCREEN_DOOR_ZOMBIE = 'ScreenDoorZombie'
|
SCREEN_DOOR_ZOMBIE = "ScreenDoorZombie"
|
||||||
POLE_VAULTING_ZOMBIE = 'PoleVaultingZombie'
|
POLE_VAULTING_ZOMBIE = "PoleVaultingZombie"
|
||||||
ZOMBONI = 'Zomboni'
|
ZOMBONI = "Zomboni"
|
||||||
SNORKELZOMBIE = 'SnorkelZombie'
|
SNORKELZOMBIE = "SnorkelZombie"
|
||||||
|
|
||||||
BOOMDIE = 'BoomDie'
|
BOOMDIE = "BoomDie"
|
||||||
|
|
||||||
# 对僵尸的攻击类型设置
|
# 对僵尸的攻击类型设置
|
||||||
ZOMBIE_DEAFULT_DAMAGE = ZOMBIE_HELMET_2_FIRST = 'helmet2First' # 优先攻击二类防具
|
ZOMBIE_DEAFULT_DAMAGE = ZOMBIE_HELMET_2_FIRST = "helmet2First" # 优先攻击二类防具
|
||||||
ZOMBIE_COMMON_DAMAGE = 'commonDamage' # 优先攻击僵尸与一类防具的整体
|
ZOMBIE_COMMON_DAMAGE = "commonDamage" # 优先攻击僵尸与一类防具的整体
|
||||||
ZOMBIE_RANGE_DAMAGE = 'rangeDamage' # 范围攻击,同时伤害二类防具与(僵尸与一类防具的整体)
|
ZOMBIE_RANGE_DAMAGE = "rangeDamage" # 范围攻击,同时伤害二类防具与(僵尸与一类防具的整体)
|
||||||
ZOMBIE_ASH_DAMAGE = 'ashDamage' # 灰烬植物攻击,直接伤害本体
|
ZOMBIE_ASH_DAMAGE = "ashDamage" # 灰烬植物攻击,直接伤害本体
|
||||||
ZOMBIE_WALLNUT_BOWLING_DANMAGE = 'wallnutBowlingDamage' # 坚果保龄球冲撞伤害
|
ZOMBIE_WALLNUT_BOWLING_DANMAGE = "wallnutBowlingDamage" # 坚果保龄球冲撞伤害
|
||||||
|
|
||||||
# 僵尸生命值设置
|
# 僵尸生命值设置
|
||||||
# 有关本体
|
# 有关本体
|
||||||
@ -621,143 +584,128 @@ CONVERT_ZOMBIE_IN_POOL = {
|
|||||||
|
|
||||||
# 水上僵尸集合
|
# 水上僵尸集合
|
||||||
WATER_ZOMBIE = {
|
WATER_ZOMBIE = {
|
||||||
DUCKY_TUBE_ZOMBIE,
|
DUCKY_TUBE_ZOMBIE, CONEHEAD_DUCKY_TUBE_ZOMBIE,
|
||||||
CONEHEAD_DUCKY_TUBE_ZOMBIE,
|
BUCKETHEAD_DUCKY_TUBE_ZOMBIE, SNORKELZOMBIE,
|
||||||
BUCKETHEAD_DUCKY_TUBE_ZOMBIE,
|
|
||||||
SNORKELZOMBIE,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# 状态类型
|
# 状态类型
|
||||||
IDLE = 'idle'
|
IDLE = "idle"
|
||||||
FLY = 'fly'
|
FLY = "fly"
|
||||||
EXPLODE = 'explode'
|
EXPLODE = "explode"
|
||||||
ATTACK = 'attack'
|
ATTACK = "attack"
|
||||||
ATTACKED = 'attacked'
|
ATTACKED = "attacked"
|
||||||
DIGEST = 'digest'
|
DIGEST = "digest"
|
||||||
WALK = 'walk'
|
WALK = "walk"
|
||||||
DIE = 'die'
|
DIE = "die"
|
||||||
CRY = 'cry'
|
CRY = "cry"
|
||||||
FREEZE = 'freeze'
|
FREEZE = "freeze"
|
||||||
SLEEP = 'sleep'
|
SLEEP = "sleep"
|
||||||
|
|
||||||
# 关卡状态
|
# 关卡状态
|
||||||
CHOOSE = 'choose'
|
CHOOSE = "choose"
|
||||||
PLAY = 'play'
|
PLAY = "play"
|
||||||
|
|
||||||
# 加载矩形碰撞范围 用于消除文件边框影响
|
# 加载矩形碰撞范围 用于消除文件边框影响
|
||||||
# 植物
|
# 植物
|
||||||
PLANT_RECT = {
|
PLANT_RECT = {
|
||||||
BULLET_PEA: {'x': 28, 'y': 0, 'width': 28, 'height': 34},
|
BULLET_PEA: {"x":28, "y":0, "width":28, "height":34},
|
||||||
BULLET_PEA_ICE: {'x': 26, 'y': 0, 'width': 30, 'height': 34},
|
BULLET_PEA_ICE: {"x":26, "y":0, "width":30, "height":34},
|
||||||
CHOMPER: {'x': 0, 'y': 0, 'width': 100, 'height': 114},
|
CHOMPER: {"x":0, "y":0, "width":100, "height":114},
|
||||||
PUFFSHROOM: {'x': 0, 'y': 28, 'width': 35, 'height': 38},
|
PUFFSHROOM: {"x":0, "y":28, "width":35, "height":38},
|
||||||
f'{PUFFSHROOM}Sleep': {'x': 1, 'y': 0, 'width': 39, 'height': 65},
|
f"{PUFFSHROOM}Sleep": {"x":1, "y":0, "width":39, "height":65},
|
||||||
BULLET_MUSHROOM: {'x': 0, 'y': 1, 'width': 55, 'height': 21},
|
BULLET_MUSHROOM: {"x":0, "y":1, "width":55, "height":21},
|
||||||
BULLET_SEASHROOM: {'x': 0, 'y': 1, 'width': 55, 'height': 21},
|
BULLET_SEASHROOM: {"x":0, "y":1, "width":55, "height":21},
|
||||||
POTATOMINE: {'x': 0, 'y': 0, 'width': 75, 'height': 55},
|
POTATOMINE: {"x":0, "y":0, "width":75, "height":55},
|
||||||
SQUASH: {'x': 10, 'y': 140, 'width': 80, 'height': 86},
|
SQUASH: {"x":10, "y":140, "width":80, "height":86},
|
||||||
f'{SQUASH}Aim': {'x': 10, 'y': 140, 'width': 80, 'height': 86},
|
f"{SQUASH}Aim": {"x":10, "y":140, "width":80, "height":86},
|
||||||
SPIKEWEED: {'x': 3, 'y': 0, 'width': 80, 'height': 35},
|
SPIKEWEED: {"x":3, "y":0, "width":80, "height":35}
|
||||||
}
|
}
|
||||||
# 僵尸
|
# 僵尸
|
||||||
ZOMBIE_RECT = {
|
ZOMBIE_RECT = {
|
||||||
NORMAL_ZOMBIE: {'x': 62, 'width': 90},
|
NORMAL_ZOMBIE: {"x":62, "width":90},
|
||||||
f'{NORMAL_ZOMBIE}Attack': {'x': 62, 'width': 90},
|
f"{NORMAL_ZOMBIE}Attack": {"x":62, "width":90},
|
||||||
f'{NORMAL_ZOMBIE}LostHead': {'x': 62, 'width': 90},
|
f"{NORMAL_ZOMBIE}LostHead": {"x":62, "width":90},
|
||||||
f'{NORMAL_ZOMBIE}LostHeadAttack': {'x': 62, 'width': 90},
|
f"{NORMAL_ZOMBIE}LostHeadAttack":{"x":62, "width":90},
|
||||||
f'{NORMAL_ZOMBIE}Die': {'x': 0, 'width': 164},
|
f"{NORMAL_ZOMBIE}Die": {"x":0, "width":164},
|
||||||
BOOMDIE: {'x': 68, 'width': 80},
|
BOOMDIE: {"x":68, "width":80},
|
||||||
CONEHEAD_ZOMBIE: {'x': 80, 'width': 80},
|
CONEHEAD_ZOMBIE: {"x":80, "width":80},
|
||||||
f'{CONEHEAD_ZOMBIE}Attack': {'x': 79, 'width': 87},
|
f"{CONEHEAD_ZOMBIE}Attack": {"x":79, "width":87},
|
||||||
BUCKETHEAD_ZOMBIE: {'x': 54, 'width': 90},
|
BUCKETHEAD_ZOMBIE: {"x":54, "width":90},
|
||||||
f'{BUCKETHEAD_ZOMBIE}Attack': {'x': 46, 'width': 90},
|
f"{BUCKETHEAD_ZOMBIE}Attack": {"x":46, "width":90},
|
||||||
FLAG_ZOMBIE: {'x': 56, 'width': 110},
|
FLAG_ZOMBIE: {"x":56, "width":110},
|
||||||
f'{FLAG_ZOMBIE}Attack': {'x': 60, 'width': 100},
|
f"{FLAG_ZOMBIE}Attack": {"x":60, "width":100},
|
||||||
f'{FLAG_ZOMBIE}LostHead': {'x': 55, 'width': 110},
|
f"{FLAG_ZOMBIE}LostHead": {"x":55, "width":110},
|
||||||
f'{FLAG_ZOMBIE}LostHeadAttack': {'x': 55, 'width': 110},
|
f"{FLAG_ZOMBIE}LostHeadAttack": {"x":55, "width":110},
|
||||||
NEWSPAPER_ZOMBIE: {'x': 48, 'width': 92},
|
NEWSPAPER_ZOMBIE: {"x":48, "width":92},
|
||||||
f'{NEWSPAPER_ZOMBIE}Attack': {'x': 48, 'width': 92},
|
f"{NEWSPAPER_ZOMBIE}Attack": {"x":48, "width":92},
|
||||||
f'{NEWSPAPER_ZOMBIE}NoPaper': {'x': 40, 'width': 98},
|
f"{NEWSPAPER_ZOMBIE}NoPaper": {"x":40, "width":98},
|
||||||
f'{NEWSPAPER_ZOMBIE}NoPaperAttack': {'x': 48, 'width': 92},
|
f"{NEWSPAPER_ZOMBIE}NoPaperAttack":{"x":48, "width":92},
|
||||||
f'{NEWSPAPER_ZOMBIE}LostHead': {'x': 44, 'width': 96},
|
f"{NEWSPAPER_ZOMBIE}LostHead": {"x":44, "width":96},
|
||||||
f'{NEWSPAPER_ZOMBIE}LostHeadAttack': {'x': 48, 'width': 92},
|
f"{NEWSPAPER_ZOMBIE}LostHeadAttack":{"x":48, "width":92},
|
||||||
f'{NEWSPAPER_ZOMBIE}Die': {'x': 0, 'width': 100},
|
f"{NEWSPAPER_ZOMBIE}Die": {"x":0, "width":100},
|
||||||
f'{DUCKY_TUBE_ZOMBIE}Die': {'x': 55, 'width': 105},
|
f"{DUCKY_TUBE_ZOMBIE}Die": {"x":55, "width":105},
|
||||||
f'{DUCKY_TUBE_ZOMBIE}LostHead': {'x': 55, 'width': 105},
|
f"{DUCKY_TUBE_ZOMBIE}LostHead": {"x":55, "width":105},
|
||||||
SCREEN_DOOR_ZOMBIE: {'x': 41, 'width': 100},
|
SCREEN_DOOR_ZOMBIE: {"x":41, "width":100},
|
||||||
f'{SCREEN_DOOR_ZOMBIE}Attack': {'x': 41, 'width': 100},
|
f"{SCREEN_DOOR_ZOMBIE}Attack": {"x":41, "width":100},
|
||||||
} # 这里还有懒得写代码的补加,用循环实现
|
} # 这里还有懒得写代码的补加,用循环实现
|
||||||
for _part1 in (
|
for _part1 in (DUCKY_TUBE_ZOMBIE, CONEHEAD_DUCKY_TUBE_ZOMBIE, BUCKETHEAD_DUCKY_TUBE_ZOMBIE):
|
||||||
DUCKY_TUBE_ZOMBIE,
|
for _part2 in ("", "Attack", "Swim"):
|
||||||
CONEHEAD_DUCKY_TUBE_ZOMBIE,
|
ZOMBIE_RECT[f"{_part1}{_part2}"] = {"x":55, "width":105}
|
||||||
BUCKETHEAD_DUCKY_TUBE_ZOMBIE,
|
|
||||||
):
|
|
||||||
for _part2 in ('', 'Attack', 'Swim'):
|
|
||||||
ZOMBIE_RECT[f'{_part1}{_part2}'] = {'x': 55, 'width': 105}
|
|
||||||
|
|
||||||
|
|
||||||
# 音效
|
# 音效
|
||||||
def _getSound(filename):
|
def _getSound(filename):
|
||||||
return pg.mixer.Sound(
|
return pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(__file__)) ,"resources", "sound", filename))
|
||||||
os.path.join(
|
|
||||||
os.path.dirname(os.path.dirname(__file__)),
|
|
||||||
'resources',
|
|
||||||
'sound',
|
|
||||||
filename,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# 所有音效的元组,用一波海象算子表达,免得要维护两个
|
# 所有音效的元组,用一波海象算子表达,免得要维护两个
|
||||||
SOUNDS = ( # 程序交互等
|
SOUNDS = ( # 程序交互等
|
||||||
SOUND_TAPPING_CARD := _getSound('tap.ogg'),
|
SOUND_TAPPING_CARD := _getSound("tap.ogg"),
|
||||||
SOUND_HELP_SCREEN := _getSound('helpScreen.ogg'),
|
SOUND_HELP_SCREEN := _getSound("helpScreen.ogg"),
|
||||||
# 植物
|
# 植物
|
||||||
SOUND_FIREPEA_EXPLODE := _getSound('firepea.ogg'),
|
SOUND_FIREPEA_EXPLODE := _getSound("firepea.ogg"),
|
||||||
SOUND_BULLET_EXPLODE := _getSound('bulletExplode.ogg'),
|
SOUND_BULLET_EXPLODE := _getSound("bulletExplode.ogg"),
|
||||||
SOUND_SHOOT := _getSound('shoot.ogg'),
|
SOUND_SHOOT := _getSound("shoot.ogg"),
|
||||||
SOUND_SNOWPEA_SPARKLES := _getSound('snowPeaSparkles.ogg'),
|
SOUND_SNOWPEA_SPARKLES := _getSound("snowPeaSparkles.ogg"),
|
||||||
SOUND_BOMB := _getSound('bomb.ogg'),
|
SOUND_BOMB := _getSound("bomb.ogg"),
|
||||||
SOUND_BIGCHOMP := _getSound('bigchomp.ogg'),
|
SOUND_BIGCHOMP := _getSound("bigchomp.ogg"),
|
||||||
SOUND_PUFF := _getSound('puff.ogg'),
|
SOUND_PUFF := _getSound("puff.ogg"),
|
||||||
SOUND_POTATOMINE := _getSound('potatomine.ogg'),
|
SOUND_POTATOMINE := _getSound("potatomine.ogg"),
|
||||||
SOUND_SQUASHING := _getSound('squashing.ogg'),
|
SOUND_SQUASHING := _getSound("squashing.ogg"),
|
||||||
SOUND_SQUASH_HMM := _getSound('squashHmm.ogg'),
|
SOUND_SQUASH_HMM := _getSound("squashHmm.ogg"),
|
||||||
SOUND_PLANT_GROW := _getSound('plantGrow.ogg'),
|
SOUND_PLANT_GROW := _getSound("plantGrow.ogg"),
|
||||||
SOUND_MUSHROOM_WAKEUP := _getSound('mushroomWakeup.ogg'),
|
SOUND_MUSHROOM_WAKEUP := _getSound("mushroomWakeup.ogg"),
|
||||||
SOUND_TANGLE_KELP_DRAG := _getSound('tangleKelpDrag.ogg'),
|
SOUND_TANGLE_KELP_DRAG := _getSound("tangleKelpDrag.ogg"),
|
||||||
SOUND_DOOMSHROOM := _getSound('doomshroom.ogg'),
|
SOUND_DOOMSHROOM := _getSound("doomshroom.ogg"),
|
||||||
SOUND_GRAVEBUSTER_CHOMP := _getSound('gravebusterchomp.ogg'),
|
SOUND_GRAVEBUSTER_CHOMP := _getSound("gravebusterchomp.ogg"),
|
||||||
SOUND_FUME := _getSound('fume.ogg'),
|
SOUND_FUME := _getSound("fume.ogg"),
|
||||||
# 僵尸
|
# 僵尸
|
||||||
SOUND_ZOMBIE_ENTERING_WATER := _getSound('zombieEnteringWater.ogg'),
|
SOUND_ZOMBIE_ENTERING_WATER := _getSound("zombieEnteringWater.ogg"),
|
||||||
SOUND_ZOMBIE_ATTACKING := _getSound('zombieAttack.ogg'),
|
SOUND_ZOMBIE_ATTACKING := _getSound("zombieAttack.ogg"),
|
||||||
SOUND_FREEZE := _getSound('freeze.ogg'),
|
SOUND_FREEZE := _getSound("freeze.ogg"),
|
||||||
SOUND_HYPNOED := _getSound('hypnoed.ogg'),
|
SOUND_HYPNOED := _getSound("hypnoed.ogg"),
|
||||||
SOUND_NEWSPAPER_RIP := _getSound('newspaperRip.ogg'),
|
SOUND_NEWSPAPER_RIP := _getSound("newspaperRip.ogg"),
|
||||||
SOUND_NEWSPAPER_ZOMBIE_ANGRY := _getSound('newspaperZombieAngry.ogg'),
|
SOUND_NEWSPAPER_ZOMBIE_ANGRY := _getSound("newspaperZombieAngry.ogg"),
|
||||||
SOUND_POLEVAULT_JUMP := _getSound('polevaultjump.ogg'),
|
SOUND_POLEVAULT_JUMP := _getSound("polevaultjump.ogg"),
|
||||||
SOUND_ZOMBONI := _getSound('zomboni.ogg'),
|
SOUND_ZOMBONI := _getSound("zomboni.ogg"),
|
||||||
SOUND_ZOMBONI_EXPLOSION := _getSound('zomboniExplosion.ogg'),
|
SOUND_ZOMBONI_EXPLOSION := _getSound("zomboniExplosion.ogg"),
|
||||||
# 关卡中
|
# 关卡中
|
||||||
SOUND_CAR_WALKING := _getSound('carWalking.ogg'),
|
SOUND_CAR_WALKING := _getSound("carWalking.ogg"),
|
||||||
SOUND_ZOMBIE_COMING := _getSound('zombieComing.ogg'),
|
SOUND_ZOMBIE_COMING := _getSound("zombieComing.ogg"),
|
||||||
SOUND_ZOMBIE_VOICE := _getSound('zombieVoice.ogg'),
|
SOUND_ZOMBIE_VOICE := _getSound("zombieVoice.ogg"),
|
||||||
SOUND_HUGE_WAVE_APPROCHING := _getSound('hugeWaveApproching.ogg'),
|
SOUND_HUGE_WAVE_APPROCHING := _getSound("hugeWaveApproching.ogg"),
|
||||||
SOUND_BUTTON_CLICK := _getSound('buttonclick.ogg'),
|
SOUND_BUTTON_CLICK := _getSound("buttonclick.ogg"),
|
||||||
SOUND_COLLECT_SUN := _getSound('collectSun.ogg'),
|
SOUND_COLLECT_SUN := _getSound("collectSun.ogg"),
|
||||||
SOUND_CLICK_CARD := _getSound('clickCard.ogg'),
|
SOUND_CLICK_CARD := _getSound("clickCard.ogg"),
|
||||||
SOUND_SHOVEL := _getSound('shovel.ogg'),
|
SOUND_SHOVEL := _getSound("shovel.ogg"),
|
||||||
SOUND_PLANT := _getSound('plant.ogg'),
|
SOUND_PLANT := _getSound("plant.ogg"),
|
||||||
SOUND_BOWLING_IMPACT := _getSound('bowlingimpact.ogg'),
|
SOUND_BOWLING_IMPACT := _getSound("bowlingimpact.ogg"),
|
||||||
SOUND_PLANT_DIE := _getSound('plantDie.ogg'),
|
SOUND_PLANT_DIE := _getSound("plantDie.ogg"),
|
||||||
SOUND_EVILLAUGH := _getSound('evillaugh.ogg'),
|
SOUND_EVILLAUGH := _getSound("evillaugh.ogg"),
|
||||||
SOUND_LOSE := _getSound('lose.ogg'),
|
SOUND_LOSE := _getSound("lose.ogg"),
|
||||||
SOUND_WIN := _getSound('win.ogg'),
|
SOUND_WIN := _getSound("win.ogg"),
|
||||||
SOUND_SCREAM := _getSound('scream.ogg'),
|
SOUND_SCREAM := _getSound("scream.ogg"),
|
||||||
SOUND_CANNOT_CHOOSE_WARNING := _getSound('cannotChooseWarning.ogg'),
|
SOUND_CANNOT_CHOOSE_WARNING := _getSound("cannotChooseWarning.ogg"),
|
||||||
SOUND_FINAL_FANFARE := _getSound('finalfanfare.ogg'),
|
SOUND_FINAL_FANFARE := _getSound("finalfanfare.ogg"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# 记录本地存储文件初始值
|
# 记录本地存储文件初始值
|
||||||
@ -771,4 +719,4 @@ INIT_USERDATA = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 无穷大常量
|
# 无穷大常量
|
||||||
INF = float('inf') # python传递字符串性能较低,故在这里对inf声明一次,以后仅需调用即可,虽然真正的用处是可以自动补全(
|
INF = float("inf") # python传递字符串性能较低,故在这里对inf声明一次,以后仅需调用即可,虽然真正的用处是可以自动补全(
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,10 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
import pygame as pg
|
import pygame as pg
|
||||||
|
import os
|
||||||
from .. import constants as c
|
|
||||||
from .. import tool
|
from .. import tool
|
||||||
|
from .. import constants as c
|
||||||
|
|
||||||
class Menu(tool.State):
|
class Menu(tool.State):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
tool.State.__init__(self)
|
tool.State.__init__(self)
|
||||||
|
|
||||||
@ -19,7 +17,7 @@ class Menu(tool.State):
|
|||||||
self.setupOptionMenu()
|
self.setupOptionMenu()
|
||||||
self.setupSunflowerTrophy()
|
self.setupSunflowerTrophy()
|
||||||
pg.mixer.music.stop()
|
pg.mixer.music.stop()
|
||||||
pg.mixer.music.load(os.path.join(c.PATH_MUSIC_DIR, 'intro.opus'))
|
pg.mixer.music.load(os.path.join(c.PATH_MUSIC_DIR, "intro.opus"))
|
||||||
pg.mixer.music.play(-1, 0)
|
pg.mixer.music.play(-1, 0)
|
||||||
pg.display.set_caption(c.ORIGINAL_CAPTION)
|
pg.display.set_caption(c.ORIGINAL_CAPTION)
|
||||||
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
||||||
@ -32,9 +30,7 @@ class Menu(tool.State):
|
|||||||
# 2、双星号同上,区别是x视为字典。
|
# 2、双星号同上,区别是x视为字典。
|
||||||
# 3、在变量前加单星号表示将元组(列表、集合)拆分为单个元素。
|
# 3、在变量前加单星号表示将元组(列表、集合)拆分为单个元素。
|
||||||
# 4、双星号同上,区别是目标为字典,字典前加单星号的话可以得到“键”。
|
# 4、双星号同上,区别是目标为字典,字典前加单星号的话可以得到“键”。
|
||||||
self.bg_image = tool.get_image(
|
self.bg_image = tool.get_image(tool.GFX[c.MAIN_MENU_IMAGE], *frame_rect)
|
||||||
tool.GFX[c.MAIN_MENU_IMAGE], *frame_rect
|
|
||||||
)
|
|
||||||
self.bg_rect = self.bg_image.get_rect()
|
self.bg_rect = self.bg_image.get_rect()
|
||||||
self.bg_rect.x = 0
|
self.bg_rect.x = 0
|
||||||
self.bg_rect.y = 0
|
self.bg_rect.y = 0
|
||||||
@ -43,12 +39,7 @@ class Menu(tool.State):
|
|||||||
# 冒险模式
|
# 冒险模式
|
||||||
frame_rect = (0, 0, 330, 144)
|
frame_rect = (0, 0, 330, 144)
|
||||||
# 写成列表生成器方便IDE识别与自动补全
|
# 写成列表生成器方便IDE识别与自动补全
|
||||||
self.adventure_frames = [
|
self.adventure_frames = [tool.get_image_alpha(tool.GFX[f"{c.OPTION_ADVENTURE}_{i}"], *frame_rect) for i in range(2)]
|
||||||
tool.get_image_alpha(
|
|
||||||
tool.GFX[f'{c.OPTION_ADVENTURE}_{i}'], *frame_rect
|
|
||||||
)
|
|
||||||
for i in range(2)
|
|
||||||
]
|
|
||||||
self.adventure_image = self.adventure_frames[0]
|
self.adventure_image = self.adventure_frames[0]
|
||||||
self.adventure_rect = self.adventure_image.get_rect()
|
self.adventure_rect = self.adventure_image.get_rect()
|
||||||
self.adventure_rect.x = 400
|
self.adventure_rect.x = 400
|
||||||
@ -57,12 +48,7 @@ class Menu(tool.State):
|
|||||||
|
|
||||||
# 小游戏
|
# 小游戏
|
||||||
littleGame_frame_rect = (0, 7, 317, 135)
|
littleGame_frame_rect = (0, 7, 317, 135)
|
||||||
self.littleGame_frames = [
|
self.littleGame_frames = [tool.get_image_alpha(tool.GFX[f"{c.LITTLEGAME_BUTTON}_{i}"], *littleGame_frame_rect) for i in range(2)]
|
||||||
tool.get_image_alpha(
|
|
||||||
tool.GFX[f'{c.LITTLEGAME_BUTTON}_{i}'], *littleGame_frame_rect
|
|
||||||
)
|
|
||||||
for i in range(2)
|
|
||||||
]
|
|
||||||
self.littleGame_image = self.littleGame_frames[0]
|
self.littleGame_image = self.littleGame_frames[0]
|
||||||
self.littleGame_rect = self.littleGame_image.get_rect()
|
self.littleGame_rect = self.littleGame_image.get_rect()
|
||||||
self.littleGame_rect.x = 397
|
self.littleGame_rect.x = 397
|
||||||
@ -71,12 +57,7 @@ class Menu(tool.State):
|
|||||||
|
|
||||||
# 退出按钮
|
# 退出按钮
|
||||||
exit_frame_rect = (0, 0, 47, 27)
|
exit_frame_rect = (0, 0, 47, 27)
|
||||||
self.exit_frames = [
|
self.exit_frames = [tool.get_image_alpha(tool.GFX[f"{c.EXIT}_{i}"], *exit_frame_rect, scale=1.1) for i in range(2)]
|
||||||
tool.get_image_alpha(
|
|
||||||
tool.GFX[f'{c.EXIT}_{i}'], *exit_frame_rect, scale=1.1
|
|
||||||
)
|
|
||||||
for i in range(2)
|
|
||||||
]
|
|
||||||
self.exit_image = self.exit_frames[0]
|
self.exit_image = self.exit_frames[0]
|
||||||
self.exit_rect = self.exit_image.get_rect()
|
self.exit_rect = self.exit_image.get_rect()
|
||||||
self.exit_rect.x = 730
|
self.exit_rect.x = 730
|
||||||
@ -85,12 +66,7 @@ class Menu(tool.State):
|
|||||||
|
|
||||||
# 选项按钮
|
# 选项按钮
|
||||||
option_button_frame_rect = (0, 0, 81, 31)
|
option_button_frame_rect = (0, 0, 81, 31)
|
||||||
self.option_button_frames = [
|
self.option_button_frames = [tool.get_image_alpha(tool.GFX[f"{c.OPTION_BUTTON}_{i}"], *option_button_frame_rect) for i in range(2)]
|
||||||
tool.get_image_alpha(
|
|
||||||
tool.GFX[f'{c.OPTION_BUTTON}_{i}'], *option_button_frame_rect
|
|
||||||
)
|
|
||||||
for i in range(2)
|
|
||||||
]
|
|
||||||
self.option_button_image = self.option_button_frames[0]
|
self.option_button_image = self.option_button_frames[0]
|
||||||
self.option_button_rect = self.option_button_image.get_rect()
|
self.option_button_rect = self.option_button_image.get_rect()
|
||||||
self.option_button_rect.x = 560
|
self.option_button_rect.x = 560
|
||||||
@ -99,10 +75,7 @@ class Menu(tool.State):
|
|||||||
|
|
||||||
# 帮助菜单
|
# 帮助菜单
|
||||||
help_frame_rect = (0, 0, 48, 22)
|
help_frame_rect = (0, 0, 48, 22)
|
||||||
self.help_frames = [
|
self.help_frames = [tool.get_image_alpha(tool.GFX[f"{c.HELP}_{i}"], *help_frame_rect) for i in range(2)]
|
||||||
tool.get_image_alpha(tool.GFX[f'{c.HELP}_{i}'], *help_frame_rect)
|
|
||||||
for i in range(2)
|
|
||||||
]
|
|
||||||
self.help_image = self.help_frames[0]
|
self.help_image = self.help_frames[0]
|
||||||
self.help_rect = self.help_image.get_rect()
|
self.help_rect = self.help_image.get_rect()
|
||||||
self.help_rect.x = 653
|
self.help_rect.x = 653
|
||||||
@ -133,21 +106,11 @@ class Menu(tool.State):
|
|||||||
self.help_hilight_time = self.current_time
|
self.help_hilight_time = self.current_time
|
||||||
|
|
||||||
# 处理按钮高亮情况
|
# 处理按钮高亮情况
|
||||||
self.adventure_image = self.chooseHilightImage(
|
self.adventure_image = self.chooseHilightImage(self.adventure_highlight_time, self.adventure_frames)
|
||||||
self.adventure_highlight_time, self.adventure_frames
|
self.exit_image = self.chooseHilightImage(self.exit_highlight_time, self.exit_frames)
|
||||||
)
|
self.option_button_image = self.chooseHilightImage(self.option_button_highlight_time, self.option_button_frames)
|
||||||
self.exit_image = self.chooseHilightImage(
|
self.littleGame_image = self.chooseHilightImage(self.littleGame_highlight_time, self.littleGame_frames)
|
||||||
self.exit_highlight_time, self.exit_frames
|
self.help_image = self.chooseHilightImage(self.help_hilight_time, self.help_frames)
|
||||||
)
|
|
||||||
self.option_button_image = self.chooseHilightImage(
|
|
||||||
self.option_button_highlight_time, self.option_button_frames
|
|
||||||
)
|
|
||||||
self.littleGame_image = self.chooseHilightImage(
|
|
||||||
self.littleGame_highlight_time, self.littleGame_frames
|
|
||||||
)
|
|
||||||
self.help_image = self.chooseHilightImage(
|
|
||||||
self.help_hilight_time, self.help_frames
|
|
||||||
)
|
|
||||||
|
|
||||||
def chooseHilightImage(self, hilightTime:int, frames):
|
def chooseHilightImage(self, hilightTime:int, frames):
|
||||||
if (self.current_time - hilightTime) < 80:
|
if (self.current_time - hilightTime) < 80:
|
||||||
@ -185,9 +148,7 @@ class Menu(tool.State):
|
|||||||
def setupOptionMenu(self):
|
def setupOptionMenu(self):
|
||||||
# 选项菜单框
|
# 选项菜单框
|
||||||
frame_rect = (0, 0, 500, 500)
|
frame_rect = (0, 0, 500, 500)
|
||||||
self.big_menu = tool.get_image_alpha(
|
self.big_menu = tool.get_image_alpha(tool.GFX[c.BIG_MENU], *frame_rect, c.BLACK, 1.1)
|
||||||
tool.GFX[c.BIG_MENU], *frame_rect, c.BLACK, 1.1
|
|
||||||
)
|
|
||||||
self.big_menu_rect = self.big_menu.get_rect()
|
self.big_menu_rect = self.big_menu.get_rect()
|
||||||
self.big_menu_rect.x = 150
|
self.big_menu_rect.x = 150
|
||||||
self.big_menu_rect.y = 0
|
self.big_menu_rect.y = 0
|
||||||
@ -201,7 +162,7 @@ class Menu(tool.State):
|
|||||||
self.return_button_rect.y = 440
|
self.return_button_rect.y = 440
|
||||||
font = pg.font.Font(c.FONT_PATH, 40)
|
font = pg.font.Font(c.FONT_PATH, 40)
|
||||||
font.bold = True
|
font.bold = True
|
||||||
text = font.render('返回游戏', True, c.YELLOWGREEN)
|
text = font.render("返回游戏", True, c.YELLOWGREEN)
|
||||||
text_rect = text.get_rect()
|
text_rect = text.get_rect()
|
||||||
text_rect.x = 105
|
text_rect.x = 105
|
||||||
text_rect.y = 18
|
text_rect.y = 18
|
||||||
@ -212,52 +173,34 @@ class Menu(tool.State):
|
|||||||
font = pg.font.Font(c.FONT_PATH, 35)
|
font = pg.font.Font(c.FONT_PATH, 35)
|
||||||
font.bold = True
|
font.bold = True
|
||||||
# 音量+
|
# 音量+
|
||||||
self.sound_volume_plus_button = tool.get_image_alpha(
|
self.sound_volume_plus_button = tool.get_image_alpha(tool.GFX[c.SOUND_VOLUME_BUTTON], *frame_rect, c.BLACK)
|
||||||
tool.GFX[c.SOUND_VOLUME_BUTTON], *frame_rect, c.BLACK
|
sign = font.render("+", True, c.YELLOWGREEN)
|
||||||
)
|
|
||||||
sign = font.render('+', True, c.YELLOWGREEN)
|
|
||||||
sign_rect = sign.get_rect()
|
sign_rect = sign.get_rect()
|
||||||
sign_rect.x = 8
|
sign_rect.x = 8
|
||||||
sign_rect.y = -4
|
sign_rect.y = -4
|
||||||
self.sound_volume_plus_button.blit(sign, sign_rect)
|
self.sound_volume_plus_button.blit(sign, sign_rect)
|
||||||
self.sound_volume_plus_button_rect = (
|
self.sound_volume_plus_button_rect = self.sound_volume_plus_button.get_rect()
|
||||||
self.sound_volume_plus_button.get_rect()
|
|
||||||
)
|
|
||||||
self.sound_volume_plus_button_rect.x = 500
|
self.sound_volume_plus_button_rect.x = 500
|
||||||
# 音量-
|
# 音量-
|
||||||
self.sound_volume_minus_button = tool.get_image_alpha(
|
self.sound_volume_minus_button = tool.get_image_alpha(tool.GFX[c.SOUND_VOLUME_BUTTON], *frame_rect, c.BLACK)
|
||||||
tool.GFX[c.SOUND_VOLUME_BUTTON], *frame_rect, c.BLACK
|
sign = font.render("-", True, c.YELLOWGREEN)
|
||||||
)
|
|
||||||
sign = font.render('-', True, c.YELLOWGREEN)
|
|
||||||
sign_rect = sign.get_rect()
|
sign_rect = sign.get_rect()
|
||||||
sign_rect.x = 12
|
sign_rect.x = 12
|
||||||
sign_rect.y = -6
|
sign_rect.y = -6
|
||||||
self.sound_volume_minus_button.blit(sign, sign_rect)
|
self.sound_volume_minus_button.blit(sign, sign_rect)
|
||||||
self.sound_volume_minus_button_rect = (
|
self.sound_volume_minus_button_rect = self.sound_volume_minus_button.get_rect()
|
||||||
self.sound_volume_minus_button.get_rect()
|
|
||||||
)
|
|
||||||
self.sound_volume_minus_button_rect.x = 450
|
self.sound_volume_minus_button_rect.x = 450
|
||||||
# 音量+、-应当处于同一高度
|
# 音量+、-应当处于同一高度
|
||||||
self.sound_volume_minus_button_rect.y = (
|
self.sound_volume_minus_button_rect.y = self.sound_volume_plus_button_rect.y = 250
|
||||||
self.sound_volume_plus_button_rect.y
|
|
||||||
) = 250
|
|
||||||
|
|
||||||
def setupSunflowerTrophy(self):
|
def setupSunflowerTrophy(self):
|
||||||
# 设置金银向日葵图片信息
|
# 设置金银向日葵图片信息
|
||||||
if (
|
if (self.game_info[c.LEVEL_COMPLETIONS] or self.game_info[c.LITTLEGAME_COMPLETIONS]):
|
||||||
self.game_info[c.LEVEL_COMPLETIONS]
|
if (self.game_info[c.LEVEL_COMPLETIONS] and self.game_info[c.LITTLEGAME_COMPLETIONS]):
|
||||||
or self.game_info[c.LITTLEGAME_COMPLETIONS]
|
|
||||||
):
|
|
||||||
if (
|
|
||||||
self.game_info[c.LEVEL_COMPLETIONS]
|
|
||||||
and self.game_info[c.LITTLEGAME_COMPLETIONS]
|
|
||||||
):
|
|
||||||
frame_rect = (157, 0, 157, 269)
|
frame_rect = (157, 0, 157, 269)
|
||||||
else:
|
else:
|
||||||
frame_rect = (0, 0, 157, 269)
|
frame_rect = (0, 0, 157, 269)
|
||||||
self.sunflower_trophy = tool.get_image_alpha(
|
self.sunflower_trophy = tool.get_image_alpha(tool.GFX[c.TROPHY_SUNFLOWER], *frame_rect, c.BLACK)
|
||||||
tool.GFX[c.TROPHY_SUNFLOWER], *frame_rect, c.BLACK
|
|
||||||
)
|
|
||||||
self.sunflower_trophy_rect = self.sunflower_trophy.get_rect()
|
self.sunflower_trophy_rect = self.sunflower_trophy.get_rect()
|
||||||
self.sunflower_trophy_rect.x = 0
|
self.sunflower_trophy_rect.x = 0
|
||||||
self.sunflower_trophy_rect.y = 280
|
self.sunflower_trophy_rect.y = 280
|
||||||
@ -268,15 +211,12 @@ class Menu(tool.State):
|
|||||||
self.sunflower_trophy_show_info_time = self.current_time
|
self.sunflower_trophy_show_info_time = self.current_time
|
||||||
if (self.current_time - self.sunflower_trophy_show_info_time) < 80:
|
if (self.current_time - self.sunflower_trophy_show_info_time) < 80:
|
||||||
font = pg.font.Font(c.FONT_PATH, 14)
|
font = pg.font.Font(c.FONT_PATH, 14)
|
||||||
if (
|
if (self.game_info[c.LEVEL_COMPLETIONS] and self.game_info[c.LITTLEGAME_COMPLETIONS]):
|
||||||
self.game_info[c.LEVEL_COMPLETIONS]
|
infoText = f"目前您一共完成了:冒险模式{self.game_info[c.LEVEL_COMPLETIONS]}轮,玩玩小游戏{self.game_info[c.LITTLEGAME_COMPLETIONS]}轮"
|
||||||
and self.game_info[c.LITTLEGAME_COMPLETIONS]
|
|
||||||
):
|
|
||||||
infoText = f'目前您一共完成了:冒险模式{self.game_info[c.LEVEL_COMPLETIONS]}轮,玩玩小游戏{self.game_info[c.LITTLEGAME_COMPLETIONS]}轮'
|
|
||||||
elif self.game_info[c.LEVEL_COMPLETIONS]:
|
elif self.game_info[c.LEVEL_COMPLETIONS]:
|
||||||
infoText = f'目前您一共完成了:冒险模式{self.game_info[c.LEVEL_COMPLETIONS]}轮;完成其他所有游戏模式以获得金向日葵奖杯!'
|
infoText = f"目前您一共完成了:冒险模式{self.game_info[c.LEVEL_COMPLETIONS]}轮;完成其他所有游戏模式以获得金向日葵奖杯!"
|
||||||
else:
|
else:
|
||||||
infoText = f'目前您一共完成了:玩玩小游戏{self.game_info[c.LITTLEGAME_COMPLETIONS]}轮;完成其他所有游戏模式以获得金向日葵奖杯!'
|
infoText = f"目前您一共完成了:玩玩小游戏{self.game_info[c.LITTLEGAME_COMPLETIONS]}轮;完成其他所有游戏模式以获得金向日葵奖杯!"
|
||||||
infoImg = font.render(infoText , True, c.BLACK, c.LIGHTYELLOW)
|
infoImg = font.render(infoText , True, c.BLACK, c.LIGHTYELLOW)
|
||||||
infoImg_rect = infoImg.get_rect()
|
infoImg_rect = infoImg.get_rect()
|
||||||
infoImg_rect.x = self.sunflower_trophy_rect.x
|
infoImg_rect.x = self.sunflower_trophy_rect.x
|
||||||
@ -291,23 +231,13 @@ class Menu(tool.State):
|
|||||||
def showCurrentVolumeImage(self, surface:pg.Surface):
|
def showCurrentVolumeImage(self, surface:pg.Surface):
|
||||||
# 由于音量可变,因此这一内容不能在一开始就结束加载,而应当不断刷新不断显示
|
# 由于音量可变,因此这一内容不能在一开始就结束加载,而应当不断刷新不断显示
|
||||||
font = pg.font.Font(c.FONT_PATH, 30)
|
font = pg.font.Font(c.FONT_PATH, 30)
|
||||||
volume_tips = font.render(
|
volume_tips = font.render(f"音量:{round(self.game_info[c.SOUND_VOLUME]*100):3}%", True, c.LIGHTGRAY)
|
||||||
f'音量:{round(self.game_info[c.SOUND_VOLUME]*100):3}%',
|
|
||||||
True,
|
|
||||||
c.LIGHTGRAY,
|
|
||||||
)
|
|
||||||
volume_tips_rect = volume_tips.get_rect()
|
volume_tips_rect = volume_tips.get_rect()
|
||||||
volume_tips_rect.x = 275
|
volume_tips_rect.x = 275
|
||||||
volume_tips_rect.y = 247
|
volume_tips_rect.y = 247
|
||||||
surface.blit(volume_tips, volume_tips_rect)
|
surface.blit(volume_tips, volume_tips_rect)
|
||||||
|
|
||||||
def update(
|
def update(self, surface:pg.Surface, current_time:int, mouse_pos:list, mouse_click):
|
||||||
self,
|
|
||||||
surface: pg.Surface,
|
|
||||||
current_time: int,
|
|
||||||
mouse_pos: list,
|
|
||||||
mouse_click,
|
|
||||||
):
|
|
||||||
self.current_time = self.game_info[c.CURRENT_TIME] = current_time
|
self.current_time = self.game_info[c.CURRENT_TIME] = current_time
|
||||||
|
|
||||||
surface.blit(self.bg_image, self.bg_rect)
|
surface.blit(self.bg_image, self.bg_rect)
|
||||||
@ -316,10 +246,7 @@ class Menu(tool.State):
|
|||||||
surface.blit(self.exit_image, self.exit_rect)
|
surface.blit(self.exit_image, self.exit_rect)
|
||||||
surface.blit(self.option_button_image, self.option_button_rect)
|
surface.blit(self.option_button_image, self.option_button_rect)
|
||||||
surface.blit(self.help_image, self.help_rect)
|
surface.blit(self.help_image, self.help_rect)
|
||||||
if (
|
if self.game_info[c.LEVEL_COMPLETIONS] or self.game_info[c.LITTLEGAME_COMPLETIONS]:
|
||||||
self.game_info[c.LEVEL_COMPLETIONS]
|
|
||||||
or self.game_info[c.LITTLEGAME_COMPLETIONS]
|
|
||||||
):
|
|
||||||
surface.blit(self.sunflower_trophy, self.sunflower_trophy_rect)
|
surface.blit(self.sunflower_trophy, self.sunflower_trophy_rect)
|
||||||
|
|
||||||
# 点到冒险模式后播放动画
|
# 点到冒险模式后播放动画
|
||||||
@ -335,14 +262,8 @@ class Menu(tool.State):
|
|||||||
elif self.option_button_clicked:
|
elif self.option_button_clicked:
|
||||||
surface.blit(self.big_menu, self.big_menu_rect)
|
surface.blit(self.big_menu, self.big_menu_rect)
|
||||||
surface.blit(self.return_button, self.return_button_rect)
|
surface.blit(self.return_button, self.return_button_rect)
|
||||||
surface.blit(
|
surface.blit(self.sound_volume_plus_button, self.sound_volume_plus_button_rect)
|
||||||
self.sound_volume_plus_button,
|
surface.blit(self.sound_volume_minus_button, self.sound_volume_minus_button_rect)
|
||||||
self.sound_volume_plus_button_rect,
|
|
||||||
)
|
|
||||||
surface.blit(
|
|
||||||
self.sound_volume_minus_button,
|
|
||||||
self.sound_volume_minus_button_rect,
|
|
||||||
)
|
|
||||||
self.showCurrentVolumeImage(surface)
|
self.showCurrentVolumeImage(surface)
|
||||||
if mouse_pos:
|
if mouse_pos:
|
||||||
# 返回
|
# 返回
|
||||||
@ -350,12 +271,8 @@ class Menu(tool.State):
|
|||||||
self.option_button_clicked = False
|
self.option_button_clicked = False
|
||||||
c.SOUND_BUTTON_CLICK.play()
|
c.SOUND_BUTTON_CLICK.play()
|
||||||
# 音量+
|
# 音量+
|
||||||
elif self.inArea(
|
elif self.inArea(self.sound_volume_plus_button_rect, *mouse_pos):
|
||||||
self.sound_volume_plus_button_rect, *mouse_pos
|
self.game_info[c.SOUND_VOLUME] = round(min(self.game_info[c.SOUND_VOLUME] + 0.05, 1), 2)
|
||||||
):
|
|
||||||
self.game_info[c.SOUND_VOLUME] = round(
|
|
||||||
min(self.game_info[c.SOUND_VOLUME] + 0.05, 1), 2
|
|
||||||
)
|
|
||||||
# 一般不会有人想把音乐和音效分开设置,故pg.mixer.Sound.set_volume()和pg.mixer.music.set_volume()需要一起用
|
# 一般不会有人想把音乐和音效分开设置,故pg.mixer.Sound.set_volume()和pg.mixer.music.set_volume()需要一起用
|
||||||
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
||||||
for i in c.SOUNDS:
|
for i in c.SOUNDS:
|
||||||
@ -363,12 +280,8 @@ class Menu(tool.State):
|
|||||||
c.SOUND_BUTTON_CLICK.play()
|
c.SOUND_BUTTON_CLICK.play()
|
||||||
self.saveUserData()
|
self.saveUserData()
|
||||||
# 音量-
|
# 音量-
|
||||||
elif self.inArea(
|
elif self.inArea(self.sound_volume_minus_button_rect, *mouse_pos):
|
||||||
self.sound_volume_minus_button_rect, *mouse_pos
|
self.game_info[c.SOUND_VOLUME] = round(max(self.game_info[c.SOUND_VOLUME] - 0.05, 0), 2)
|
||||||
):
|
|
||||||
self.game_info[c.SOUND_VOLUME] = round(
|
|
||||||
max(self.game_info[c.SOUND_VOLUME] - 0.05, 0), 2
|
|
||||||
)
|
|
||||||
# 一般不会有人想把音乐和音效分开设置,故pg.mixer.Sound.set_volume()和pg.mixer.music.set_volume()需要一起用
|
# 一般不会有人想把音乐和音效分开设置,故pg.mixer.Sound.set_volume()和pg.mixer.music.set_volume()需要一起用
|
||||||
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
||||||
for i in c.SOUNDS:
|
for i in c.SOUNDS:
|
||||||
@ -380,10 +293,7 @@ class Menu(tool.State):
|
|||||||
# 先检查选项高亮预览
|
# 先检查选项高亮预览
|
||||||
x, y = pg.mouse.get_pos()
|
x, y = pg.mouse.get_pos()
|
||||||
self.checkHilight(x, y)
|
self.checkHilight(x, y)
|
||||||
if (
|
if (self.game_info[c.LEVEL_COMPLETIONS] or self.game_info[c.LITTLEGAME_COMPLETIONS]):
|
||||||
self.game_info[c.LEVEL_COMPLETIONS]
|
|
||||||
or self.game_info[c.LITTLEGAME_COMPLETIONS]
|
|
||||||
):
|
|
||||||
self.checkSunflowerTrophyInfo(surface, x, y)
|
self.checkSunflowerTrophyInfo(surface, x, y)
|
||||||
if mouse_pos:
|
if mouse_pos:
|
||||||
if self.inArea(self.adventure_rect, *mouse_pos):
|
if self.inArea(self.adventure_rect, *mouse_pos):
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
from abc import abstractmethod
|
|
||||||
|
|
||||||
import pygame as pg
|
import pygame as pg
|
||||||
|
from abc import abstractmethod
|
||||||
from .. import constants as c
|
|
||||||
from .. import tool
|
from .. import tool
|
||||||
|
from .. import constants as c
|
||||||
|
|
||||||
class Screen(tool.State):
|
class Screen(tool.State):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -17,9 +14,7 @@ class Screen(tool.State):
|
|||||||
|
|
||||||
def setupImage(self, name, frame_rect=(0, 0, 800, 600), color_key=c.BLACK):
|
def setupImage(self, name, frame_rect=(0, 0, 800, 600), color_key=c.BLACK):
|
||||||
# 背景图本身
|
# 背景图本身
|
||||||
self.image = tool.get_image(
|
self.image = tool.get_image(tool.GFX[name], *frame_rect, colorkey=color_key)
|
||||||
tool.GFX[name], *frame_rect, colorkey=color_key
|
|
||||||
)
|
|
||||||
self.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
self.rect.x = 0
|
self.rect.x = 0
|
||||||
self.rect.y = 0
|
self.rect.y = 0
|
||||||
@ -27,45 +22,33 @@ class Screen(tool.State):
|
|||||||
# 按钮
|
# 按钮
|
||||||
frame_rect = (0, 0, 111, 26)
|
frame_rect = (0, 0, 111, 26)
|
||||||
## 主菜单按钮
|
## 主菜单按钮
|
||||||
self.main_menu_button_image = tool.get_image_alpha(
|
self.main_menu_button_image = tool.get_image_alpha(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect)
|
||||||
tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect
|
self.main_menu_button_image_rect = self.main_menu_button_image.get_rect()
|
||||||
)
|
|
||||||
self.main_menu_button_image_rect = (
|
|
||||||
self.main_menu_button_image.get_rect()
|
|
||||||
)
|
|
||||||
self.main_menu_button_image_rect.x = 620
|
self.main_menu_button_image_rect.x = 620
|
||||||
### 主菜单按钮上的文字
|
### 主菜单按钮上的文字
|
||||||
font = pg.font.Font(c.FONT_PATH, 18)
|
font = pg.font.Font(c.FONT_PATH, 18)
|
||||||
main_menu_text = font.render('主菜单', True, c.NAVYBLUE)
|
main_menu_text = font.render("主菜单", True, c.NAVYBLUE)
|
||||||
main_menu_text_rect = main_menu_text.get_rect()
|
main_menu_text_rect = main_menu_text.get_rect()
|
||||||
main_menu_text_rect.x = 29
|
main_menu_text_rect.x = 29
|
||||||
## 继续按钮
|
## 继续按钮
|
||||||
self.next_button_image = tool.get_image_alpha(
|
self.next_button_image = tool.get_image_alpha(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect)
|
||||||
tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect
|
|
||||||
)
|
|
||||||
self.next_button_image_rect = self.next_button_image.get_rect()
|
self.next_button_image_rect = self.next_button_image.get_rect()
|
||||||
self.next_button_image_rect.x = 70
|
self.next_button_image_rect.x = 70
|
||||||
### 继续按钮上的文字
|
### 继续按钮上的文字
|
||||||
if name == c.GAME_VICTORY_IMAGE:
|
if name == c.GAME_VICTORY_IMAGE:
|
||||||
next_text = font.render('下一关', True, c.NAVYBLUE)
|
next_text = font.render("下一关", True, c.NAVYBLUE)
|
||||||
next_text_rect = next_text.get_rect()
|
next_text_rect = next_text.get_rect()
|
||||||
next_text_rect.x = 29
|
next_text_rect.x = 29
|
||||||
self.next_button_image_rect.y = (
|
self.next_button_image_rect.y = self.main_menu_button_image_rect.y = 555
|
||||||
self.main_menu_button_image_rect.y
|
|
||||||
) = 555
|
|
||||||
else:
|
else:
|
||||||
next_text = font.render('重新开始', True, c.NAVYBLUE)
|
next_text = font.render("重新开始", True, c.NAVYBLUE)
|
||||||
next_text_rect = next_text.get_rect()
|
next_text_rect = next_text.get_rect()
|
||||||
next_text_rect.x = 21
|
next_text_rect.x = 21
|
||||||
self.next_button_image_rect.y = (
|
self.next_button_image_rect.y = self.main_menu_button_image_rect.y = 530
|
||||||
self.main_menu_button_image_rect.y
|
|
||||||
) = 530
|
|
||||||
self.next_button_image.blit(next_text, next_text_rect)
|
self.next_button_image.blit(next_text, next_text_rect)
|
||||||
self.main_menu_button_image.blit(main_menu_text, main_menu_text_rect)
|
self.main_menu_button_image.blit(main_menu_text, main_menu_text_rect)
|
||||||
self.image.blit(self.next_button_image, self.next_button_image_rect)
|
self.image.blit(self.next_button_image, self.next_button_image_rect)
|
||||||
self.image.blit(
|
self.image.blit(self.main_menu_button_image, self.main_menu_button_image_rect)
|
||||||
self.main_menu_button_image, self.main_menu_button_image_rect
|
|
||||||
)
|
|
||||||
|
|
||||||
def update(self, surface, current_time, mouse_pos, mouse_click):
|
def update(self, surface, current_time, mouse_pos, mouse_click):
|
||||||
surface.fill(c.WHITE)
|
surface.fill(c.WHITE)
|
||||||
@ -80,7 +63,6 @@ class Screen(tool.State):
|
|||||||
self.next = c.MAIN_MENU
|
self.next = c.MAIN_MENU
|
||||||
self.done = True
|
self.done = True
|
||||||
|
|
||||||
|
|
||||||
class GameVictoryScreen(Screen):
|
class GameVictoryScreen(Screen):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Screen.__init__(self)
|
Screen.__init__(self)
|
||||||
@ -91,13 +73,12 @@ class GameVictoryScreen(Screen):
|
|||||||
self.persist = persist
|
self.persist = persist
|
||||||
self.game_info = persist
|
self.game_info = persist
|
||||||
self.setupImage(self.image_name)
|
self.setupImage(self.image_name)
|
||||||
pg.display.set_caption('pypvz: 战斗胜利!')
|
pg.display.set_caption("pypvz: 战斗胜利!")
|
||||||
pg.mixer.music.stop()
|
pg.mixer.music.stop()
|
||||||
pg.mixer.music.load(os.path.join(c.PATH_MUSIC_DIR, 'zenGarden.opus'))
|
pg.mixer.music.load(os.path.join(c.PATH_MUSIC_DIR, "zenGarden.opus"))
|
||||||
pg.mixer.music.play(-1, 0)
|
pg.mixer.music.play(-1, 0)
|
||||||
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
||||||
|
|
||||||
|
|
||||||
class GameLoseScreen(Screen):
|
class GameLoseScreen(Screen):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Screen.__init__(self)
|
Screen.__init__(self)
|
||||||
@ -108,11 +89,10 @@ class GameLoseScreen(Screen):
|
|||||||
self.persist = persist
|
self.persist = persist
|
||||||
self.game_info = persist
|
self.game_info = persist
|
||||||
self.setupImage(self.image_name, (-118, -40, 800, 600), c.WHITE)
|
self.setupImage(self.image_name, (-118, -40, 800, 600), c.WHITE)
|
||||||
pg.display.set_caption('pypvz: 战斗失败!')
|
pg.display.set_caption("pypvz: 战斗失败!")
|
||||||
# 停止播放原来关卡中的音乐
|
# 停止播放原来关卡中的音乐
|
||||||
pg.mixer.music.stop()
|
pg.mixer.music.stop()
|
||||||
|
|
||||||
|
|
||||||
class AwardScreen(tool.State):
|
class AwardScreen(tool.State):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
tool.State.__init__(self)
|
tool.State.__init__(self)
|
||||||
@ -120,9 +100,7 @@ class AwardScreen(tool.State):
|
|||||||
def setupImage(self):
|
def setupImage(self):
|
||||||
# 主体
|
# 主体
|
||||||
frame_rect = (0, 0, 800, 600)
|
frame_rect = (0, 0, 800, 600)
|
||||||
self.image = tool.get_image(
|
self.image = tool.get_image(tool.GFX[c.AWARD_SCREEN_IMAGE], *frame_rect)
|
||||||
tool.GFX[c.AWARD_SCREEN_IMAGE], *frame_rect
|
|
||||||
)
|
|
||||||
self.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
self.rect.x = 0
|
self.rect.x = 0
|
||||||
self.rect.y = 0
|
self.rect.y = 0
|
||||||
@ -130,7 +108,7 @@ class AwardScreen(tool.State):
|
|||||||
# 文字
|
# 文字
|
||||||
# 标题处文字
|
# 标题处文字
|
||||||
font = pg.font.Font(c.FONT_PATH, 37)
|
font = pg.font.Font(c.FONT_PATH, 37)
|
||||||
title_text = font.render('您获得了新的战利品!', True, c.PARCHMENT_YELLOW)
|
title_text = font.render("您获得了新的战利品!", True, c.PARCHMENT_YELLOW)
|
||||||
title_text_rect = title_text.get_rect()
|
title_text_rect = title_text.get_rect()
|
||||||
title_text_rect.x = 220
|
title_text_rect.x = 220
|
||||||
title_text_rect.y = 23
|
title_text_rect.y = 23
|
||||||
@ -140,44 +118,31 @@ class AwardScreen(tool.State):
|
|||||||
frame_rect = (0, 0, 111, 26)
|
frame_rect = (0, 0, 111, 26)
|
||||||
if self.show_only_one_option:
|
if self.show_only_one_option:
|
||||||
## 主菜单按钮
|
## 主菜单按钮
|
||||||
self.main_menu_button_image = tool.get_image_alpha(
|
self.main_menu_button_image = tool.get_image_alpha(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect)
|
||||||
tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect
|
self.main_menu_button_image_rect = self.main_menu_button_image.get_rect()
|
||||||
)
|
|
||||||
self.main_menu_button_image_rect = (
|
|
||||||
self.main_menu_button_image.get_rect()
|
|
||||||
)
|
|
||||||
self.main_menu_button_image_rect.x = 343
|
self.main_menu_button_image_rect.x = 343
|
||||||
self.main_menu_button_image_rect.y = 520
|
self.main_menu_button_image_rect.y = 520
|
||||||
### 主菜单按钮上的文字
|
### 主菜单按钮上的文字
|
||||||
font = pg.font.Font(c.FONT_PATH, 18)
|
font = pg.font.Font(c.FONT_PATH, 18)
|
||||||
main_menu_text = font.render('主菜单', True, c.NAVYBLUE)
|
main_menu_text = font.render("主菜单", True, c.NAVYBLUE)
|
||||||
main_menu_text_rect = main_menu_text.get_rect()
|
main_menu_text_rect = main_menu_text.get_rect()
|
||||||
main_menu_text_rect.x = 29
|
main_menu_text_rect.x = 29
|
||||||
self.main_menu_button_image.blit(
|
self.main_menu_button_image.blit(main_menu_text, main_menu_text_rect)
|
||||||
main_menu_text, main_menu_text_rect
|
self.image.blit(self.main_menu_button_image, self.main_menu_button_image_rect)
|
||||||
)
|
|
||||||
self.image.blit(
|
|
||||||
self.main_menu_button_image, self.main_menu_button_image_rect
|
|
||||||
)
|
|
||||||
|
|
||||||
# 绘制向日葵奖杯
|
# 绘制向日葵奖杯
|
||||||
if (
|
if (self.game_info[c.LEVEL_COMPLETIONS] and self.game_info[c.LITTLEGAME_COMPLETIONS]):
|
||||||
self.game_info[c.LEVEL_COMPLETIONS]
|
|
||||||
and self.game_info[c.LITTLEGAME_COMPLETIONS]
|
|
||||||
):
|
|
||||||
frame_rect = (157, 0, 157, 269)
|
frame_rect = (157, 0, 157, 269)
|
||||||
intro_title = '金向日葵奖杯'
|
intro_title = "金向日葵奖杯"
|
||||||
intro_content = '您已通过所有关卡,获得此奖励!'
|
intro_content = "您已通过所有关卡,获得此奖励!"
|
||||||
else:
|
else:
|
||||||
frame_rect = (0, 0, 157, 269)
|
frame_rect = (0, 0, 157, 269)
|
||||||
intro_title = '银向日葵奖杯'
|
intro_title = "银向日葵奖杯"
|
||||||
if self.game_info[c.LEVEL_COMPLETIONS]:
|
if self.game_info[c.LEVEL_COMPLETIONS]:
|
||||||
intro_content = '您已完成冒险模式,获得此奖励!'
|
intro_content = "您已完成冒险模式,获得此奖励!"
|
||||||
else:
|
else:
|
||||||
intro_content = '您已完成玩玩小游戏,获得此奖励!'
|
intro_content = "您已完成玩玩小游戏,获得此奖励!"
|
||||||
sunflower_trophy_image = tool.get_image_alpha(
|
sunflower_trophy_image = tool.get_image_alpha(tool.GFX[c.TROPHY_SUNFLOWER], *frame_rect, scale=0.7)
|
||||||
tool.GFX[c.TROPHY_SUNFLOWER], *frame_rect, scale=0.7
|
|
||||||
)
|
|
||||||
sunflower_trophy_rect = sunflower_trophy_image.get_rect()
|
sunflower_trophy_rect = sunflower_trophy_image.get_rect()
|
||||||
sunflower_trophy_rect.x = 348
|
sunflower_trophy_rect.x = 348
|
||||||
sunflower_trophy_rect.y = 108
|
sunflower_trophy_rect.y = 108
|
||||||
@ -185,9 +150,7 @@ class AwardScreen(tool.State):
|
|||||||
|
|
||||||
# 绘制介绍标题
|
# 绘制介绍标题
|
||||||
font = pg.font.Font(c.FONT_PATH, 22)
|
font = pg.font.Font(c.FONT_PATH, 22)
|
||||||
intro_title_img = font.render(
|
intro_title_img = font.render(intro_title, True, c.PARCHMENT_YELLOW)
|
||||||
intro_title, True, c.PARCHMENT_YELLOW
|
|
||||||
)
|
|
||||||
intro_title_rect = intro_title_img.get_rect()
|
intro_title_rect = intro_title_img.get_rect()
|
||||||
intro_title_rect.x = 333
|
intro_title_rect.x = 333
|
||||||
intro_title_rect.y = 305
|
intro_title_rect.y = 305
|
||||||
@ -202,56 +165,40 @@ class AwardScreen(tool.State):
|
|||||||
self.image.blit(intro_content_img, intro_content_rect)
|
self.image.blit(intro_content_img, intro_content_rect)
|
||||||
else:
|
else:
|
||||||
## 继续按钮
|
## 继续按钮
|
||||||
self.next_button_image = tool.get_image_alpha(
|
self.next_button_image = tool.get_image_alpha(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect)
|
||||||
tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect
|
|
||||||
)
|
|
||||||
self.next_button_image_rect = self.next_button_image.get_rect()
|
self.next_button_image_rect = self.next_button_image.get_rect()
|
||||||
self.next_button_image_rect.x = 70
|
self.next_button_image_rect.x = 70
|
||||||
### 继续按钮上的文字
|
### 继续按钮上的文字
|
||||||
font = pg.font.Font(c.FONT_PATH, 18)
|
font = pg.font.Font(c.FONT_PATH, 18)
|
||||||
next_text = font.render('继续', True, c.NAVYBLUE)
|
next_text = font.render("继续", True, c.NAVYBLUE)
|
||||||
next_text_rect = next_text.get_rect()
|
next_text_rect = next_text.get_rect()
|
||||||
next_text_rect.x = 37
|
next_text_rect.x = 37
|
||||||
## 主菜单按钮
|
## 主菜单按钮
|
||||||
self.main_menu_button_image = tool.get_image_alpha(
|
self.main_menu_button_image = tool.get_image_alpha(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect)
|
||||||
tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect
|
self.main_menu_button_image_rect = self.main_menu_button_image.get_rect()
|
||||||
)
|
|
||||||
self.main_menu_button_image_rect = (
|
|
||||||
self.main_menu_button_image.get_rect()
|
|
||||||
)
|
|
||||||
self.main_menu_button_image_rect.x = 620
|
self.main_menu_button_image_rect.x = 620
|
||||||
self.next_button_image_rect.y = (
|
self.next_button_image_rect.y = self.main_menu_button_image_rect.y = 540
|
||||||
self.main_menu_button_image_rect.y
|
|
||||||
) = 540
|
|
||||||
### 主菜单按钮上的文字
|
### 主菜单按钮上的文字
|
||||||
main_menu_text = font.render('主菜单', True, c.NAVYBLUE)
|
main_menu_text = font.render("主菜单", True, c.NAVYBLUE)
|
||||||
main_menu_text_rect = main_menu_text.get_rect()
|
main_menu_text_rect = main_menu_text.get_rect()
|
||||||
main_menu_text_rect.x = 29
|
main_menu_text_rect.x = 29
|
||||||
self.next_button_image.blit(next_text, next_text_rect)
|
self.next_button_image.blit(next_text, next_text_rect)
|
||||||
self.main_menu_button_image.blit(
|
self.main_menu_button_image.blit(main_menu_text, main_menu_text_rect)
|
||||||
main_menu_text, main_menu_text_rect
|
self.image.blit(self.next_button_image, self.next_button_image_rect)
|
||||||
)
|
self.image.blit(self.main_menu_button_image, self.main_menu_button_image_rect)
|
||||||
self.image.blit(
|
|
||||||
self.next_button_image, self.next_button_image_rect
|
|
||||||
)
|
|
||||||
self.image.blit(
|
|
||||||
self.main_menu_button_image, self.main_menu_button_image_rect
|
|
||||||
)
|
|
||||||
|
|
||||||
def startup(self, current_time, persist):
|
def startup(self, current_time, persist):
|
||||||
self.start_time = current_time
|
self.start_time = current_time
|
||||||
self.persist = persist
|
self.persist = persist
|
||||||
self.game_info = persist
|
self.game_info = persist
|
||||||
if (c.PASSED_ALL in self.game_info) and (
|
if (c.PASSED_ALL in self.game_info) and (not self.game_info[c.PASSED_ALL]):
|
||||||
not self.game_info[c.PASSED_ALL]
|
|
||||||
):
|
|
||||||
self.show_only_one_option = False
|
self.show_only_one_option = False
|
||||||
else:
|
else:
|
||||||
self.show_only_one_option = True
|
self.show_only_one_option = True
|
||||||
self.setupImage()
|
self.setupImage()
|
||||||
pg.display.set_caption('pypvz: 您获得了新的战利品!')
|
pg.display.set_caption("pypvz: 您获得了新的战利品!")
|
||||||
pg.mixer.music.stop()
|
pg.mixer.music.stop()
|
||||||
pg.mixer.music.load(os.path.join(c.PATH_MUSIC_DIR, 'zenGarden.opus'))
|
pg.mixer.music.load(os.path.join(c.PATH_MUSIC_DIR, "zenGarden.opus"))
|
||||||
pg.mixer.music.play(-1, 0)
|
pg.mixer.music.play(-1, 0)
|
||||||
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
pg.mixer.music.set_volume(self.game_info[c.SOUND_VOLUME])
|
||||||
|
|
||||||
@ -267,7 +214,6 @@ class AwardScreen(tool.State):
|
|||||||
self.next = c.LEVEL
|
self.next = c.LEVEL
|
||||||
self.done = True
|
self.done = True
|
||||||
|
|
||||||
|
|
||||||
class HelpScreen(tool.State):
|
class HelpScreen(tool.State):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
tool.State.__init__(self)
|
tool.State.__init__(self)
|
||||||
@ -277,39 +223,31 @@ class HelpScreen(tool.State):
|
|||||||
self.persist = persist
|
self.persist = persist
|
||||||
self.game_info = persist
|
self.game_info = persist
|
||||||
self.setupImage()
|
self.setupImage()
|
||||||
pg.display.set_caption('pypvz: 帮助')
|
pg.display.set_caption("pypvz: 帮助")
|
||||||
pg.mixer.music.stop()
|
pg.mixer.music.stop()
|
||||||
c.SOUND_HELP_SCREEN.play()
|
c.SOUND_HELP_SCREEN.play()
|
||||||
|
|
||||||
def setupImage(self):
|
def setupImage(self):
|
||||||
# 主体
|
# 主体
|
||||||
frame_rect = (-100, -50, 800, 600)
|
frame_rect = (-100, -50, 800, 600)
|
||||||
self.image = tool.get_image(
|
self.image = tool.get_image(tool.GFX[c.HELP_SCREEN_IMAGE], *frame_rect, colorkey=(0, 255, 255))
|
||||||
tool.GFX[c.HELP_SCREEN_IMAGE], *frame_rect, colorkey=(0, 255, 255)
|
|
||||||
)
|
|
||||||
self.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
self.rect.x = 0
|
self.rect.x = 0
|
||||||
self.rect.y = 0
|
self.rect.y = 0
|
||||||
|
|
||||||
# 主菜单按钮
|
# 主菜单按钮
|
||||||
frame_rect = (0, 0, 111, 26)
|
frame_rect = (0, 0, 111, 26)
|
||||||
self.main_menu_button_image = tool.get_image_alpha(
|
self.main_menu_button_image = tool.get_image_alpha(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect)
|
||||||
tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect
|
self.main_menu_button_image_rect = self.main_menu_button_image.get_rect()
|
||||||
)
|
|
||||||
self.main_menu_button_image_rect = (
|
|
||||||
self.main_menu_button_image.get_rect()
|
|
||||||
)
|
|
||||||
self.main_menu_button_image_rect.x = 343
|
self.main_menu_button_image_rect.x = 343
|
||||||
self.main_menu_button_image_rect.y = 500
|
self.main_menu_button_image_rect.y = 500
|
||||||
### 主菜单按钮上的文字
|
### 主菜单按钮上的文字
|
||||||
font = pg.font.Font(c.FONT_PATH, 18)
|
font = pg.font.Font(c.FONT_PATH, 18)
|
||||||
main_menu_text = font.render('主菜单', True, c.NAVYBLUE)
|
main_menu_text = font.render("主菜单", True, c.NAVYBLUE)
|
||||||
main_menu_text_rect = main_menu_text.get_rect()
|
main_menu_text_rect = main_menu_text.get_rect()
|
||||||
main_menu_text_rect.x = 29
|
main_menu_text_rect.x = 29
|
||||||
self.main_menu_button_image.blit(main_menu_text, main_menu_text_rect)
|
self.main_menu_button_image.blit(main_menu_text, main_menu_text_rect)
|
||||||
self.image.blit(
|
self.image.blit(self.main_menu_button_image, self.main_menu_button_image_rect)
|
||||||
self.main_menu_button_image, self.main_menu_button_image_rect
|
|
||||||
)
|
|
||||||
|
|
||||||
def update(self, surface, current_time, mouse_pos, mouse_click):
|
def update(self, surface, current_time, mouse_pos, mouse_click):
|
||||||
surface.fill(c.BLACK)
|
surface.fill(c.BLACK)
|
||||||
|
|||||||
120
source/tool.py
120
source/tool.py
@ -1,17 +1,14 @@
|
|||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
import pygame as pg
|
import pygame as pg
|
||||||
from pygame.locals import *
|
from pygame.locals import *
|
||||||
|
|
||||||
from . import constants as c
|
from . import constants as c
|
||||||
|
logger = logging.getLogger("main")
|
||||||
logger = logging.getLogger('main')
|
|
||||||
|
|
||||||
# 状态机 抽象基类
|
# 状态机 抽象基类
|
||||||
class State:
|
class State():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.start_time = 0
|
self.start_time = 0
|
||||||
self.current_time = 0
|
self.current_time = 0
|
||||||
@ -24,12 +21,10 @@ class State:
|
|||||||
def startup(self, current_time:int, persist:dict):
|
def startup(self, current_time:int, persist:dict):
|
||||||
# 前面加了@abstractmethod表示抽象基类中必须要重新定义的method(method是对象和函数的结合)
|
# 前面加了@abstractmethod表示抽象基类中必须要重新定义的method(method是对象和函数的结合)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# 当从这个状态退出时,需要进行的清除操作
|
# 当从这个状态退出时,需要进行的清除操作
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
self.done = False
|
self.done = False
|
||||||
return self.persist
|
return self.persist
|
||||||
|
|
||||||
# 在这个状态运行时进行的更新操作
|
# 在这个状态运行时进行的更新操作
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def update(self, surface:pg.Surface, keys, current_time:int):
|
def update(self, surface:pg.Surface, keys, current_time:int):
|
||||||
@ -38,14 +33,15 @@ class State:
|
|||||||
|
|
||||||
# 工具:范围判断函数,用于判断点击
|
# 工具:范围判断函数,用于判断点击
|
||||||
def inArea(self, rect:pg.Rect, x:int, y:int):
|
def inArea(self, rect:pg.Rect, x:int, y:int):
|
||||||
if rect.x <= x <= rect.right and rect.y <= y <= rect.bottom:
|
if (rect.x <= x <= rect.right and
|
||||||
|
rect.y <= y <= rect.bottom):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 工具:用户数据保存函数
|
# 工具:用户数据保存函数
|
||||||
def saveUserData(self):
|
def saveUserData(self):
|
||||||
with open(c.USERDATA_PATH, 'w', encoding='utf-8') as f:
|
with open(c.USERDATA_PATH, "w", encoding="utf-8") as f:
|
||||||
userdata = {}
|
userdata = {}
|
||||||
for i in self.game_info:
|
for i in self.game_info:
|
||||||
if i in c.INIT_USERDATA:
|
if i in c.INIT_USERDATA:
|
||||||
@ -53,19 +49,15 @@ class State:
|
|||||||
data_to_save = json.dumps(userdata, sort_keys=True, indent=4)
|
data_to_save = json.dumps(userdata, sort_keys=True, indent=4)
|
||||||
f.write(data_to_save)
|
f.write(data_to_save)
|
||||||
|
|
||||||
|
|
||||||
# 进行游戏控制 循环 事件响应
|
# 进行游戏控制 循环 事件响应
|
||||||
class Control:
|
class Control():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.screen = pg.display.get_surface()
|
self.screen = pg.display.get_surface()
|
||||||
self.done = False
|
self.done = False
|
||||||
self.clock = pg.time.Clock() # 创建一个对象来帮助跟踪时间
|
self.clock = pg.time.Clock() # 创建一个对象来帮助跟踪时间
|
||||||
self.keys = pg.key.get_pressed()
|
self.keys = pg.key.get_pressed()
|
||||||
self.mouse_pos = None
|
self.mouse_pos = None
|
||||||
self.mouse_click = [
|
self.mouse_click = [False, False] # value:[left mouse click, right mouse click]
|
||||||
False,
|
|
||||||
False,
|
|
||||||
] # value:[left mouse click, right mouse click]
|
|
||||||
self.current_time = 0.0
|
self.current_time = 0.0
|
||||||
self.state_dict = {}
|
self.state_dict = {}
|
||||||
self.state_name = None
|
self.state_name = None
|
||||||
@ -74,12 +66,12 @@ class Control:
|
|||||||
# 存在存档即导入
|
# 存在存档即导入
|
||||||
# 先自动修复读写权限(Python权限规则和Unix不一样,420表示unix的644,Windows自动忽略不支持项)
|
# 先自动修复读写权限(Python权限规则和Unix不一样,420表示unix的644,Windows自动忽略不支持项)
|
||||||
os.chmod(c.USERDATA_PATH, 420)
|
os.chmod(c.USERDATA_PATH, 420)
|
||||||
with open(c.USERDATA_PATH, encoding='utf-8') as f:
|
with open(c.USERDATA_PATH, encoding="utf-8") as f:
|
||||||
userdata = json.load(f)
|
userdata = json.load(f)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self.setupUserData()
|
self.setupUserData()
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
logger.warning('用户存档解码错误!程序将新建初始存档!\n')
|
logger.warning("用户存档解码错误!程序将新建初始存档!\n")
|
||||||
self.setupUserData()
|
self.setupUserData()
|
||||||
else: # 没有引发异常才执行
|
else: # 没有引发异常才执行
|
||||||
self.game_info = {}
|
self.game_info = {}
|
||||||
@ -92,10 +84,8 @@ class Control:
|
|||||||
self.game_info[key] = c.INIT_USERDATA[key]
|
self.game_info[key] = c.INIT_USERDATA[key]
|
||||||
need_to_rewrite = True
|
need_to_rewrite = True
|
||||||
if need_to_rewrite:
|
if need_to_rewrite:
|
||||||
with open(c.USERDATA_PATH, 'w', encoding='utf-8') as f:
|
with open(c.USERDATA_PATH, "w", encoding="utf-8") as f:
|
||||||
savedata = json.dumps(
|
savedata = json.dumps(self.game_info, sort_keys=True, indent=4)
|
||||||
self.game_info, sort_keys=True, indent=4
|
|
||||||
)
|
|
||||||
f.write(savedata)
|
f.write(savedata)
|
||||||
# 存档内不包含即时游戏时间信息,需要新建
|
# 存档内不包含即时游戏时间信息,需要新建
|
||||||
self.game_info[c.CURRENT_TIME] = 0
|
self.game_info[c.CURRENT_TIME] = 0
|
||||||
@ -106,7 +96,7 @@ class Control:
|
|||||||
def setupUserData(self):
|
def setupUserData(self):
|
||||||
if not os.path.exists(os.path.dirname(c.USERDATA_PATH)):
|
if not os.path.exists(os.path.dirname(c.USERDATA_PATH)):
|
||||||
os.makedirs(os.path.dirname(c.USERDATA_PATH))
|
os.makedirs(os.path.dirname(c.USERDATA_PATH))
|
||||||
with open(c.USERDATA_PATH, 'w', encoding='utf-8') as f:
|
with open(c.USERDATA_PATH, "w", encoding="utf-8") as f:
|
||||||
savedata = json.dumps(c.INIT_USERDATA, sort_keys=True, indent=4)
|
savedata = json.dumps(c.INIT_USERDATA, sort_keys=True, indent=4)
|
||||||
f.write(savedata)
|
f.write(savedata)
|
||||||
self.game_info = c.INIT_USERDATA.copy() # 内部全是不可变对象,浅拷贝即可
|
self.game_info = c.INIT_USERDATA.copy() # 内部全是不可变对象,浅拷贝即可
|
||||||
@ -124,9 +114,7 @@ class Control:
|
|||||||
if self.state.done:
|
if self.state.done:
|
||||||
self.flip_state()
|
self.flip_state()
|
||||||
|
|
||||||
self.state.update(
|
self.state.update(self.screen, self.current_time, self.mouse_pos, self.mouse_click)
|
||||||
self.screen, self.current_time, self.mouse_pos, self.mouse_click
|
|
||||||
)
|
|
||||||
self.mouse_pos = None
|
self.mouse_pos = None
|
||||||
self.mouse_click[0] = False
|
self.mouse_click[0] = False
|
||||||
self.mouse_click[1] = False
|
self.mouse_click[1] = False
|
||||||
@ -148,24 +136,17 @@ class Control:
|
|||||||
elif event.type == pg.KEYDOWN:
|
elif event.type == pg.KEYDOWN:
|
||||||
self.keys = pg.key.get_pressed()
|
self.keys = pg.key.get_pressed()
|
||||||
if event.key == pg.K_f:
|
if event.key == pg.K_f:
|
||||||
pg.display.set_mode(
|
pg.display.set_mode(c.SCREEN_SIZE, pg.HWSURFACE|pg.FULLSCREEN)
|
||||||
c.SCREEN_SIZE, pg.HWSURFACE | pg.FULLSCREEN
|
|
||||||
)
|
|
||||||
elif event.key == pg.K_u:
|
elif event.key == pg.K_u:
|
||||||
pg.display.set_mode(c.SCREEN_SIZE)
|
pg.display.set_mode(c.SCREEN_SIZE)
|
||||||
elif event.type == pg.KEYUP:
|
elif event.type == pg.KEYUP:
|
||||||
self.keys = pg.key.get_pressed()
|
self.keys = pg.key.get_pressed()
|
||||||
elif event.type == pg.MOUSEBUTTONDOWN:
|
elif event.type == pg.MOUSEBUTTONDOWN:
|
||||||
self.mouse_pos = pg.mouse.get_pos()
|
self.mouse_pos = pg.mouse.get_pos()
|
||||||
(
|
self.mouse_click[0], _, self.mouse_click[1] = pg.mouse.get_pressed()
|
||||||
self.mouse_click[0],
|
|
||||||
_,
|
|
||||||
self.mouse_click[1],
|
|
||||||
) = pg.mouse.get_pressed()
|
|
||||||
# self.mouse_click[0]表示左键,self.mouse_click[1]表示右键
|
# self.mouse_click[0]表示左键,self.mouse_click[1]表示右键
|
||||||
print(
|
print(f"点击位置: ({self.mouse_pos[0]:3}, {self.mouse_pos[1]:3}) 左右键点击情况: {self.mouse_click}")
|
||||||
f'点击位置: ({self.mouse_pos[0]:3}, {self.mouse_pos[1]:3}) 左右键点击情况: {self.mouse_click}'
|
|
||||||
)
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while not self.done:
|
while not self.done:
|
||||||
@ -174,16 +155,8 @@ class Control:
|
|||||||
pg.display.update()
|
pg.display.update()
|
||||||
self.clock.tick(self.fps)
|
self.clock.tick(self.fps)
|
||||||
|
|
||||||
|
def get_image( sheet:pg.Surface, x:int, y:int, width:int, height:int,
|
||||||
def get_image(
|
colorkey:tuple[int]=c.BLACK, scale:int=1) -> pg.Surface:
|
||||||
sheet: pg.Surface,
|
|
||||||
x: int,
|
|
||||||
y: int,
|
|
||||||
width: int,
|
|
||||||
height: int,
|
|
||||||
colorkey: tuple[int] = c.BLACK,
|
|
||||||
scale: int = 1,
|
|
||||||
) -> pg.Surface:
|
|
||||||
# 不保留alpha通道的图片导入
|
# 不保留alpha通道的图片导入
|
||||||
image = pg.Surface([width, height])
|
image = pg.Surface([width, height])
|
||||||
rect = image.get_rect()
|
rect = image.get_rect()
|
||||||
@ -191,36 +164,26 @@ def get_image(
|
|||||||
image.blit(sheet, (0, 0), (x, y, width, height))
|
image.blit(sheet, (0, 0), (x, y, width, height))
|
||||||
if colorkey:
|
if colorkey:
|
||||||
image.set_colorkey(colorkey)
|
image.set_colorkey(colorkey)
|
||||||
image = pg.transform.scale(
|
image = pg.transform.scale(image,
|
||||||
image, (int(rect.width * scale), int(rect.height * scale))
|
(int(rect.width*scale),
|
||||||
)
|
int(rect.height*scale)))
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
def get_image_alpha(sheet:pg.Surface, x:int, y:int, width:int, height:int,
|
||||||
def get_image_alpha(
|
colorkey:tuple[int]=c.BLACK, scale:int=1) -> pg.Surface:
|
||||||
sheet: pg.Surface,
|
|
||||||
x: int,
|
|
||||||
y: int,
|
|
||||||
width: int,
|
|
||||||
height: int,
|
|
||||||
colorkey: tuple[int] = c.BLACK,
|
|
||||||
scale: int = 1,
|
|
||||||
) -> pg.Surface:
|
|
||||||
# 保留alpha通道的图片导入
|
# 保留alpha通道的图片导入
|
||||||
image = pg.Surface([width, height], SRCALPHA)
|
image = pg.Surface([width, height], SRCALPHA)
|
||||||
rect = image.get_rect()
|
rect = image.get_rect()
|
||||||
|
|
||||||
image.blit(sheet, (0, 0), (x, y, width, height))
|
image.blit(sheet, (0, 0), (x, y, width, height))
|
||||||
image.set_colorkey(colorkey)
|
image.set_colorkey(colorkey)
|
||||||
image = pg.transform.scale(
|
image = pg.transform.scale(image,
|
||||||
image, (int(rect.width * scale), int(rect.height * scale))
|
(int(rect.width*scale),
|
||||||
)
|
int(rect.height*scale)))
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
def load_image_frames( directory:str, image_name:str,
|
||||||
def load_image_frames(
|
colorkey:tuple[int], accept:tuple[str]) -> list[pg.Surface]:
|
||||||
directory: str, image_name: str, colorkey: tuple[int], accept: tuple[str]
|
|
||||||
) -> list[pg.Surface]:
|
|
||||||
frame_list = []
|
frame_list = []
|
||||||
tmp = {}
|
tmp = {}
|
||||||
# image_name is "Peashooter", pic name is "Peashooter_1", get the index 1
|
# image_name is "Peashooter", pic name is "Peashooter_1", get the index 1
|
||||||
@ -243,13 +206,9 @@ def load_image_frames(
|
|||||||
frame_list.append(tmp[i])
|
frame_list.append(tmp[i])
|
||||||
return frame_list
|
return frame_list
|
||||||
|
|
||||||
|
|
||||||
# colorkeys 是设置图像中的某个颜色值为透明,这里用来消除白边
|
# colorkeys 是设置图像中的某个颜色值为透明,这里用来消除白边
|
||||||
def load_all_gfx(
|
def load_all_gfx( directory:str, colorkey:tuple[int]=c.WHITE,
|
||||||
directory: str,
|
accept:tuple[str]=(".png", ".jpg", ".bmp", ".gif", ".webp")) -> dict[str:pg.Surface]:
|
||||||
colorkey: tuple[int] = c.WHITE,
|
|
||||||
accept: tuple[str] = ('.png', '.jpg', '.bmp', '.gif', '.webp'),
|
|
||||||
) -> dict[str : pg.Surface]:
|
|
||||||
graphics = {}
|
graphics = {}
|
||||||
for name1 in os.listdir(directory):
|
for name1 in os.listdir(directory):
|
||||||
# subfolders under the folder resources\graphics
|
# subfolders under the folder resources\graphics
|
||||||
@ -265,15 +224,11 @@ def load_all_gfx(
|
|||||||
if os.path.isdir(dir3):
|
if os.path.isdir(dir3):
|
||||||
# e.g. it"s the folder resources\graphics\Zombies\ConeheadZombie\ConeheadZombieAttack
|
# e.g. it"s the folder resources\graphics\Zombies\ConeheadZombie\ConeheadZombieAttack
|
||||||
image_name, _ = os.path.splitext(name3)
|
image_name, _ = os.path.splitext(name3)
|
||||||
graphics[image_name] = load_image_frames(
|
graphics[image_name] = load_image_frames(dir3, image_name, colorkey, accept)
|
||||||
dir3, image_name, colorkey, accept
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# e.g. pics under the folder resources\graphics\Plants\Peashooter
|
# e.g. pics under the folder resources\graphics\Plants\Peashooter
|
||||||
image_name, _ = os.path.splitext(name2)
|
image_name, _ = os.path.splitext(name2)
|
||||||
graphics[image_name] = load_image_frames(
|
graphics[image_name] = load_image_frames(dir2, image_name, colorkey, accept)
|
||||||
dir2, image_name, colorkey, accept
|
|
||||||
)
|
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# e.g. pics under the folder resources\graphics\Screen
|
# e.g. pics under the folder resources\graphics\Screen
|
||||||
@ -288,13 +243,10 @@ def load_all_gfx(
|
|||||||
graphics[name] = img
|
graphics[name] = img
|
||||||
return graphics
|
return graphics
|
||||||
|
|
||||||
|
|
||||||
pg.display.set_caption(c.ORIGINAL_CAPTION) # 设置标题
|
pg.display.set_caption(c.ORIGINAL_CAPTION) # 设置标题
|
||||||
SCREEN = pg.display.set_mode(c.SCREEN_SIZE, pg.SCALED) # 设置初始屏幕
|
SCREEN = pg.display.set_mode(c.SCREEN_SIZE) # 设置初始屏幕
|
||||||
pg.mixer.set_num_channels(255) # 设置可以同时播放的音频数量,默认为8,经常不够用
|
pg.mixer.set_num_channels(255) # 设置可以同时播放的音频数量,默认为8,经常不够用
|
||||||
if os.path.exists(
|
if os.path.exists(c.ORIGINAL_LOGO): # 设置窗口图标,仅对非Nuitka时生效,Nuitka不需要包括额外的图标文件,自动跳过这一过程即可
|
||||||
c.ORIGINAL_LOGO
|
|
||||||
): # 设置窗口图标,仅对非Nuitka时生效,Nuitka不需要包括额外的图标文件,自动跳过这一过程即可
|
|
||||||
pg.display.set_icon(pg.image.load(c.ORIGINAL_LOGO))
|
pg.display.set_icon(pg.image.load(c.ORIGINAL_LOGO))
|
||||||
|
|
||||||
GFX = load_all_gfx(c.PATH_IMG_DIR)
|
GFX = load_all_gfx(c.PATH_IMG_DIR)
|
||||||
|
|||||||
209
uv.lock
generated
209
uv.lock
generated
@ -1,209 +0,0 @@
|
|||||||
version = 1
|
|
||||||
revision = 2
|
|
||||||
requires-python = ">=3.12"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "black"
|
|
||||||
version = "22.1.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "click" },
|
|
||||||
{ name = "mypy-extensions" },
|
|
||||||
{ name = "pathspec" },
|
|
||||||
{ name = "platformdirs" },
|
|
||||||
{ name = "tomli" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/42/58/8a3443a5034685152270f9012a9d196c9f165791ed3f2777307708b15f6c/black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5", size = 559521, upload-time = "2022-01-29T20:38:08.749Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a5/59/bd6d44da2b364fd2bd7a0b2ce2edfe200b79faad1cde14ce5ef13d504393/black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d", size = 160408, upload-time = "2022-01-29T20:38:07.336Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "blue"
|
|
||||||
version = "0.9.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "black" },
|
|
||||||
{ name = "flake8" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/68/5a/ef15e7accbe49dbeeb8e7c01e13b8459006c6fed4db8fe833f2ae4924fd7/blue-0.9.1.tar.gz", hash = "sha256:76b4f26884a8425042356601d80773db6e0e14bebaa7a59d7c54bf8cef2e2af5", size = 10594, upload-time = "2022-08-01T16:38:53.798Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c5/7b/e6bfbe69b8b22abbfbdd993142bcabd1b2ce237a42c250181c5152052feb/blue-0.9.1-py3-none-any.whl", hash = "sha256:037742c072c58a2ff024f59fb9164257b907f97f8f862008db3b013d1f27cc22", size = 10590, upload-time = "2022-08-01T16:38:51.556Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "click"
|
|
||||||
version = "8.2.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "colorama"
|
|
||||||
version = "0.4.6"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "flake8"
|
|
||||||
version = "4.0.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "mccabe" },
|
|
||||||
{ name = "pycodestyle" },
|
|
||||||
{ name = "pyflakes" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/e6/84/d8db922289195c435779b4ca3a3f583f263f87e67954f7b2e83c8da21f48/flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d", size = 154905, upload-time = "2021-10-11T12:42:48.941Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/34/39/cde2c8a227abb4f9ce62fe55586b920f438f1d2903a1a22514d0b982c333/flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d", size = 64091, upload-time = "2021-10-11T12:42:47.401Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mccabe"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/06/18/fa675aa501e11d6d6ca0ae73a101b2f3571a565e0f7d38e062eec18a91ee/mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f", size = 8612, upload-time = "2017-01-26T22:13:15.699Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/87/89/479dc97e18549e21354893e4ee4ef36db1d237534982482c3681ee6e7b57/mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", size = 8556, upload-time = "2017-01-26T22:13:14.36Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mypy-extensions"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pathspec"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "platformdirs"
|
|
||||||
version = "4.3.8"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pycodestyle"
|
|
||||||
version = "2.8.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/08/dc/b29daf0a202b03f57c19e7295b60d1d5e1281c45a6f5f573e41830819918/pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f", size = 102299, upload-time = "2021-10-11T00:56:27.496Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/15/94/bc43a2efb7b8615e38acde2b6624cae8c9ec86faf718ff5676c5179a7714/pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20", size = 42112, upload-time = "2021-10-11T00:56:25.599Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyflakes"
|
|
||||||
version = "2.4.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/15/60/c577e54518086e98470e9088278247f4af1d39cb43bcbd731e2c307acd6a/pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c", size = 69101, upload-time = "2021-10-06T20:39:50.936Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/43/fb/38848eb494af7df9aeb2d7673ace8b213313eb7e391691a79dbaeb6a838f/pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e", size = 69704, upload-time = "2021-10-06T20:39:49.185Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pygame"
|
|
||||||
version = "2.6.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/49/cc/08bba60f00541f62aaa252ce0cfbd60aebd04616c0b9574f755b583e45ae/pygame-2.6.1.tar.gz", hash = "sha256:56fb02ead529cee00d415c3e007f75e0780c655909aaa8e8bf616ee09c9feb1f", size = 14808125, upload-time = "2024-09-29T13:41:34.698Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/92/16/2c602c332f45ff9526d61f6bd764db5096ff9035433e2172e2d2cadae8db/pygame-2.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4ee7f2771f588c966fa2fa8b829be26698c9b4836f82ede5e4edc1a68594942e", size = 13118279, upload-time = "2024-09-29T14:26:30.427Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/53/77ccbc384b251c6e34bfd2e734c638233922449a7844e3c7a11ef91cee39/pygame-2.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8040ea2ab18c6b255af706ec01355c8a6b08dc48d77fd4ee783f8fc46a843bf", size = 12384524, upload-time = "2024-09-29T14:26:49.996Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/06/be/3ed337583f010696c3b3435e89a74fb29d0c74d0931e8f33c0a4246307a9/pygame-2.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47a6938de93fa610accd4969e638c2aebcb29b2fca518a84c3a39d91ab47116", size = 13587123, upload-time = "2024-09-29T11:10:50.072Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fd/ca/b015586a450db59313535662991b34d24c1f0c0dc149cc5f496573900f4e/pygame-2.6.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33006f784e1c7d7e466fcb61d5489da59cc5f7eb098712f792a225df1d4e229d", size = 14275532, upload-time = "2024-09-29T11:39:59.356Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b9/f2/d31e6ad42d657af07be2ffd779190353f759a07b51232b9e1d724f2cda46/pygame-2.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1206125f14cae22c44565c9d333607f1d9f59487b1f1432945dfc809aeaa3e88", size = 13952653, upload-time = "2024-09-29T11:40:01.781Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f3/42/8ea2a6979e6fa971702fece1747e862e2256d4a8558fe0da6364dd946c53/pygame-2.6.1-cp312-cp312-win32.whl", hash = "sha256:84fc4054e25262140d09d39e094f6880d730199710829902f0d8ceae0213379e", size = 10252421, upload-time = "2024-09-29T11:14:26.877Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5f/90/7d766d54bb95939725e9a9361f9c06b0cfbe3fe100aa35400f0a461a278a/pygame-2.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:3a9e7396be0d9633831c3f8d5d82dd63ba373ad65599628294b7a4f8a5a01a65", size = 10624591, upload-time = "2024-09-29T11:52:54.489Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e1/91/718acf3e2a9d08a6ddcc96bd02a6f63c99ee7ba14afeaff2a51c987df0b9/pygame-2.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6039f3a55d800db80e8010f387557b528d34d534435e0871326804df2a62f2", size = 13090765, upload-time = "2024-09-29T14:27:02.377Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0e/c6/9cb315de851a7682d9c7568a41ea042ee98d668cb8deadc1dafcab6116f0/pygame-2.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2a3a1288e2e9b1e5834e425bedd5ba01a3cd4902b5c2bff8ed4a740ccfe98171", size = 12381704, upload-time = "2024-09-29T14:27:10.228Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9f/8f/617a1196e31ae3b46be6949fbaa95b8c93ce15e0544266198c2266cc1b4d/pygame-2.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27eb17e3dc9640e4b4683074f1890e2e879827447770470c2aba9f125f74510b", size = 13581091, upload-time = "2024-09-29T11:30:27.653Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3b/87/2851a564e40a2dad353f1c6e143465d445dab18a95281f9ea458b94f3608/pygame-2.6.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c1623180e70a03c4a734deb9bac50fc9c82942ae84a3a220779062128e75f3b", size = 14273844, upload-time = "2024-09-29T11:40:04.138Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/85/b5/aa23aa2e70bcba42c989c02e7228273c30f3b44b9b264abb93eaeff43ad7/pygame-2.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef07c0103d79492c21fced9ad68c11c32efa6801ca1920ebfd0f15fb46c78b1c", size = 13951197, upload-time = "2024-09-29T11:40:06.785Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a6/06/29e939b34d3f1354738c7d201c51c250ad7abefefaf6f8332d962ff67c4b/pygame-2.6.1-cp313-cp313-win32.whl", hash = "sha256:3acd8c009317190c2bfd81db681ecef47d5eb108c2151d09596d9c7ea9df5c0e", size = 10249309, upload-time = "2024-09-29T11:10:23.329Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7e/11/17f7f319ca91824b86557e9303e3b7a71991ef17fd45286bf47d7f0a38e6/pygame-2.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:813af4fba5d0b2cb8e58f5d95f7910295c34067dcc290d34f1be59c48bd1ea6a", size = 10620084, upload-time = "2024-09-29T11:48:51.587Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pypvz"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = { virtual = "." }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "blue" },
|
|
||||||
{ name = "pygame" },
|
|
||||||
{ name = "setuptools" },
|
|
||||||
{ name = "wheel" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.metadata]
|
|
||||||
requires-dist = [
|
|
||||||
{ name = "blue", specifier = ">=0.9.1" },
|
|
||||||
{ name = "pygame", specifier = ">=2.6.1" },
|
|
||||||
{ name = "setuptools", specifier = ">=80.9.0" },
|
|
||||||
{ name = "wheel", specifier = ">=0.45.1" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "setuptools"
|
|
||||||
version = "80.9.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tomli"
|
|
||||||
version = "2.2.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wheel"
|
|
||||||
version = "0.45.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/8a/98/2d9906746cdc6a6ef809ae6338005b3f21bb568bea3165cfc6a243fdc25c/wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729", size = 107545, upload-time = "2024-11-23T00:18:23.513Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248", size = 72494, upload-time = "2024-11-23T00:18:21.207Z" },
|
|
||||||
]
|
|
||||||
Loading…
x
Reference in New Issue
Block a user