Compare commits

...

10 Commits

Author SHA1 Message Date
239284c70c
cx freeze 2024-04-06 21:50:29 +08:00
1facb40172
rmt 2024-04-06 21:34:34 +08:00
721e9ab2ef
添加 requirements 2024-04-06 21:32:28 +08:00
e1d7771d5a
Update version number in main.py 2024-04-06 21:20:22 +08:00
1c1a37c6d7
ruaaa 2024-04-06 21:16:24 +08:00
d021c2ae9e
ruaaaa 2024-04-06 21:13:19 +08:00
d41b41b883
马上做好了啊啊啊啊 2024-04-06 20:44:03 +08:00
6ea0407275
啊? 2024-04-06 19:58:48 +08:00
b2056039bc
可算处理完滑动条 2024-04-06 19:50:00 +08:00
2d2982c546
camera 没啥必要,扬了 2024-04-06 18:53:10 +08:00
5 changed files with 247 additions and 84 deletions

2
maker-py/.gitignore vendored
View File

@ -1,5 +1,7 @@
env
venv
build
*__pycache__*

View File

@ -1,75 +0,0 @@
from typing import Tuple, Optional
# from pyglet.gl import gl
from pyglet.math import Mat4, Vec3
from pyglet.graphics import Group
class GroupCamera(Group):
"""
A camera by group
can be used by just added to your widget
"""
def __init__(
self,
window,
order: int = 0,
parent: Optional[Group] = None,
view_x: Optional[int] = 0,
view_y: Optional[int] = 0,
zoom: Optional[float] = 1.0,
min_zoom: Optional[float] = 1.0,
max_zoom: Optional[float] = 1.0,
):
super().__init__(order=order, parent=parent)
self._window = window
self._previous_view = None
self._view_x = view_x or 0
self._view_y = view_y or 0
self._zoom = zoom or 1.0
self.min_zoom = min_zoom or 1.0
self.max_zoom = max_zoom or 1.0
@property
def view_x(self) -> int:
return self._view_x
@view_x.setter
def view_x(self, value: int):
self._view_x = value
@property
def view_y(self) -> int:
return self._view_y
@view_y.setter
def view_y(self, value: int):
self._view_y = value
@property
def zoom(self) -> float:
return min(max(self._zoom, self.min_zoom), self.max_zoom)
@zoom.setter
def zoom(self, value: float):
self._zoom = value
def reset(self):
self._view_x = 0
self._view_y = 0
self.zoom = 1
def set_state(self):
self._previous_view = self._window.view
view = Mat4.from_translation(Vec3(self._view_x, self._view_y, 0))
if self._zoom == 1.0:
self._window.view = view
else:
view = view.scale(Vec3(self._zoom, self._zoom, 1))
self._window.view = view
def unset_state(self):
self._window.view = self._previous_view

View File

@ -2,17 +2,20 @@ import pyglet
from pyglet.font import load as load_font
from pyglet.text import Label
from pyglet.gui import TextEntry
from pyglet.window import Window
from pyglet.window import Window, mouse
from pyglet.gl import glClearColor
from pyglet.shapes import Rectangle
from pyglet.graphics import Batch, Group
from control import RePositionFrame
from typing import List, Dict
from enum import IntEnum
gray = (200, 200, 200)
_version_ = "1.0.0"
class NumStatus(IntEnum):
"""未被选中"""
@ -41,6 +44,7 @@ class NumWidget:
def __init__(self, num: int, batch: Batch, group: Group, x: int, y: int) -> None:
self._y = y
self._x = x
self._display = True
font = load_font("黑体", 15)
font_height = font.ascent - font.descent
self.label_group = Group(parent=group, order=20)
@ -72,6 +76,20 @@ class NumWidget:
def value(self) -> int:
return int(self.label.text)
@value.setter
def value(self, value: int) -> None:
self.label.text = str(value)
@property
def display(self) -> bool:
return self._display
@display.setter
def display(self, value: bool) -> None:
self._display = value
self.label_group.visible = value
self.background_group.visible = value
@property
def x(self) -> int:
return self._x
@ -124,24 +142,83 @@ class MainWindow(Window):
self.main_batch = Batch()
self.main_group = Group()
self.main_frame = RePositionFrame(self)
self.on_middle = False
self.middle_base = (0, 0)
self.drag_speed = 0
self.drag_start = None
self.name_data = []
self.name_info_displays = {}
self.init_info()
self.init_name_dispaly()
self.init_name_diy()
def init_info(self) -> None:
"""初始化信息显示"""
self.info_label = Label(
x=20,
y=self.height - 50,
text=f"名字竞技场, 八围制造器v{_version_} by shenjackyuanjie(点完导出看控制台)",
multiline=False,
font_name="黑体",
font_size=17,
batch=self.main_batch,
group=self.main_group,
color=(0, 0, 0, 255),
)
self.output_button = Rectangle(
x=400,
y=200,
width=100,
height=50,
color=(0, 0, 255, 200),
batch=self.main_batch,
group=self.main_group,
)
self.output_label = Label(
x=400 + 50,
y=200 + 25,
text="导出",
width=100,
height=50,
multiline=False,
anchor_x="center",
font_name="黑体",
font_size=20,
color=(255, 255, 255, 255),
batch=self.main_batch,
group=self.main_group,
)
def init_name_diy(self) -> None:
"""
初始化 名字自定义
"""
# 0-255
self.num_dict = {}
self.num_batch = Batch()
self.num_group = Group(parent=self.main_group, order=10)
# 用于覆盖掉 num 顶上多出来的部分
cover_group = Group(parent=self.main_group, order=20)
# 滚动条数值
self.num_slide = 0
self.num_cover = Rectangle(
x=37 + 8 * 65,
y=self.height - 143,
width=41,
height=40,
color=(0, 255, 255, 255),
batch=self.main_batch,
group=cover_group,
)
self.main_frame.add_calculate_func(
self.num_cover,
lambda rec, width, height, window: (37 + 8 * 65, height - 143),
)
# 从大到小
num_group = Group(parent=self.num_group, order=10)
for i in range(256):
num_name = NumWidget(
num=i, batch=self.num_batch, group=num_group, x=40, y=50
num=i, batch=self.main_batch, group=num_group, x=40, y=50
)
self.num_dict[i] = num_name
self.num_hints = []
@ -159,7 +236,7 @@ class MainWindow(Window):
height=(font_height + 4 + 5) * 4,
# 浅蓝色背景
color=(0, 0, 255, 100),
batch=self.num_batch,
batch=self.main_batch,
group=num_hint_group,
)
)
@ -173,7 +250,7 @@ class MainWindow(Window):
height=font_height + 4 + 5,
# 浅蓝色背景
color=(0, 0, 255, 100),
batch=self.num_batch,
batch=self.main_batch,
group=num_hint_group,
)
)
@ -188,7 +265,7 @@ class MainWindow(Window):
# index 22~24 中值 + 36 = 魔法
# index 25~27 中值 + 36 = 抗性
# index 28~30 中值 + 36 = 智慧
self.display_dict: dict[NumStatus, list[NumWidget]] = {
self.display_dict: Dict[NumStatus, List[NumWidget]] = {
NumStatus.hp: [self.num_dict[i] for i in range(0, 10)],
NumStatus.attack: [self.num_dict[i] for i in range(10, 13)],
NumStatus.defense: [self.num_dict[i] for i in range(13, 16)],
@ -209,10 +286,25 @@ class MainWindow(Window):
for status, widgets in self.display_dict.items():
num_count = 0
if status == NumStatus.wait:
continue
for widget in widgets:
widget.x = 40 + (65 * status.value)
widget.y = self.height - (170 + 30 * num_count)
num_count += 1
# wait 的单独处理, 因为有滚动条
num_count = 0
for widget in self.display_dict[NumStatus.wait]:
widget.x = 40 + (65 * NumStatus.wait.value)
widget.y = self.height - (170 + 30 * num_count) + self.num_slide
# 如果太高了, 就不显示了
if widget.y > self.height - 200:
# 给我不显示啊啊啊啊啊啊
widget.display = False
else:
widget.display = True
num_count += 1
# 计算数据
hp = sum(widget.value for widget in self.display_dict[NumStatus.hp][3:6]) + 154
attack = middle_widget(*self.display_dict[NumStatus.attack]) + 36
@ -225,6 +317,16 @@ class MainWindow(Window):
gather = sum(
(int(hp / 3), attack, defense, speed, agility, magic, resistance, wisdom)
)
self.name_data = [
attack,
defense,
speed,
agility,
magic,
resistance,
wisdom,
hp,
]
self.name_info_displays[
"label"
].text = f"HP|{hp} 攻|{attack} 防|{defense} 速|{speed} 敏|{agility} 魔|{magic} 抗|{resistance} 智|{wisdom} 八围:{gather}"
@ -233,7 +335,10 @@ class MainWindow(Window):
self.num_hints[0].y = self.height - (173 + 30 * 6)
# 剩下的需要先判断那个是中间的
for i in range(1, 8):
data = sorted(enumerate(x.value for x in self.display_dict[NumStatus(i)]))
data = sorted(
enumerate(x.value for x in self.display_dict[NumStatus(i)]),
key=lambda x: x[1],
)
middle_index = data[1][0]
self.num_hints[i].y = self.height - (173 + 30 * middle_index)
@ -241,7 +346,7 @@ class MainWindow(Window):
"""
初始化 名字显示 这块内容
"""
name_group = Group(parent=self.main_group)
name_group = Group(parent=self.main_group, order=30)
self.name_info_displays["group"] = name_group
font = load_font("黑体", 20)
@ -300,8 +405,98 @@ class MainWindow(Window):
def on_draw(self) -> None:
self.clear()
if self.on_middle:
# 正在滑动
self.update_slide(self.drag_speed)
self.main_batch.draw()
self.num_batch.draw()
def update_slide(self, dy: int) -> None:
# 保证不会太下
if (self.num_slide + dy) < 0:
self.num_slide = 0
self.update_num_display()
return
# 再保证不会太上
num_len = len(self.display_dict[NumStatus.wait])
if (self.num_slide + dy) > (30 * num_len - 100):
self.num_slide = 30 * num_len - 100
self.update_num_display()
return
self.num_slide += dy
self.update_num_display()
def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
self.update_slide(int(scroll_y) * -10)
def on_mouse_press(self, x, y, button, modifiers):
self.middle_base = (x, y)
if not button & mouse.MIDDLE: # 中键
self.on_middle = False
if button & mouse.LEFT:
# 捏起
if (x, y) in self.output_button:
# 导出
print("导出")
for status, widgets in self.display_dict.items():
if status == NumStatus.wait:
continue
print(f"{status.name}: {', '.join(str(x.value) for x in widgets)}")
name = self.name_info_displays["entry"].value
print("名字: ", name)
# +diy[50,51,90,130,150,70,89,210]
print(f"{name}+diy{self.name_data}")
return
for idx, widget in self.num_dict.items():
if widget.aabb(x, y):
self.drag_start = idx
# print(f"捏起 {idx}")
break
def on_mouse_release(self, x, y, button, modifiers):
self.on_middle = False
if button & mouse.LEFT:
find = []
if self.drag_start: # 有开始目标
for idx, target_widget in self.num_dict.items():
if target_widget.aabb(x, y):
if idx == self.drag_start:
# 如果是自己, 就不做任何操作
continue
# 搜索对面那个, 修改双方显示内容
# 交换 value
find = [self.drag_start, idx]
break
if find:
print(f"交换 {find}")
(
self.num_dict[find[0]].value,
self.num_dict[find[1]].value,
) = find[1], find[0]
# 交换键
self.num_dict[find[0]], self.num_dict[find[1]] = (
self.num_dict[find[1]],
self.num_dict[find[0]],
)
self.drag_start = None
self.update_num_display()
def on_mouse_leave(self, x, y):
self.on_middle = False
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
if dy != 0 and y != self.middle_base[1] and buttons & mouse.MIDDLE:
if not self.on_middle:
self.middle_base = (x, y)
self.drag_speed = 0
self.on_middle = True
return
drag_y = y - self.middle_base[1]
# 取个对数, 保证不会太快
self.drag_speed = int(drag_y)
if self.drag_start:
# 拖动
self.num_dict[self.drag_start].x = x - 17
self.num_dict[self.drag_start].y = y - 7
def on_resize(self, width, height):
super().on_resize(width, height)

View File

@ -0,0 +1 @@
pyglet >= 2.0.15

40
maker-py/setup.py Normal file
View File

@ -0,0 +1,40 @@
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need
# fine tuning.
build_options = {
"packages": [],
"excludes": [
"test",
"asyncio",
"xml",
"tcl",
"tkinker",
"multiprocessing",
"http",
"html",
"logging",
"email",
"distutils",
"unittest",
"concurrent",
"pydoc_data",
"socket",
"random",
"lzma",
"bz2",
"decimal"
],
}
base = "console"
executables = [Executable("main.py", base=base)]
setup(
name="namerena-maker",
version="1.0.0",
description="名字竞技场-八围制造器",
options={"build_exe": build_options},
executables=executables,
)