namerena-rs/maker-py/main.py

318 lines
9.8 KiB
Python
Raw Normal View History

2024-04-06 17:45:30 +08:00
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.gl import glClearColor
from pyglet.shapes import Rectangle
from pyglet.graphics import Batch, Group
from control import RePositionFrame
from enum import IntEnum
gray = (200, 200, 200)
class NumStatus(IntEnum):
"""未被选中"""
wait = 8
2024-04-06 17:45:30 +08:00
# 血量
hp = 0
2024-04-06 17:45:30 +08:00
# 攻击
attack = 1
2024-04-06 17:45:30 +08:00
# 防御
defense = 2
2024-04-06 17:45:30 +08:00
# 速度
speed = 3
2024-04-06 17:45:30 +08:00
# 敏捷
agility = 4
2024-04-06 17:45:30 +08:00
# 魔法
magic = 5
2024-04-06 17:45:30 +08:00
# 抗性
resistance = 6
2024-04-06 17:45:30 +08:00
# 智慧
wisdom = 7
2024-04-06 17:45:30 +08:00
class NumWidget:
def __init__(self, num: int, batch: Batch, group: Group, x: int, y: int) -> None:
2024-04-06 17:55:36 +08:00
self._y = y
self._x = x
2024-04-06 17:45:30 +08:00
font = load_font("黑体", 15)
font_height = font.ascent - font.descent
self.label_group = Group(parent=group, order=20)
self.background_group = Group(parent=group, order=10)
2024-04-06 17:45:30 +08:00
self.label = Label(
x=x + 17,
y=y + 7,
color=(0, 0, 0, 255),
text=f"{num}",
font_name="黑体",
font_size=15,
width=35,
height=font_height + 4,
anchor_x="center",
batch=batch,
group=self.label_group,
2024-04-06 17:45:30 +08:00
)
self.background = Rectangle(
x=x,
y=y,
width=35,
height=font_height + 4,
color=gray,
batch=batch,
group=self.background_group,
2024-04-06 17:45:30 +08:00
)
@property
def value(self) -> int:
return int(self.label.text)
2024-04-06 17:55:36 +08:00
@property
def x(self) -> int:
return self._x
2024-04-06 17:55:36 +08:00
@x.setter
def x(self, value: int) -> None:
self._x = value
self.label.x = value + 17
self.background.x = value
2024-04-06 17:55:36 +08:00
@property
def y(self) -> int:
return self._y
2024-04-06 17:55:36 +08:00
@y.setter
def y(self, value: int) -> None:
self._y = value
self.label.y = value + 7
self.background.y = value
2024-04-06 17:45:30 +08:00
def aabb(self, x: int, y: int) -> bool:
# 判断是否在范围内
width = 35
height = 20
return self.x <= x <= self.x + width and self.y <= y <= self.y + height
def middle_widget(: NumWidget, : NumWidget, : NumWidget) -> int:
"""返回中间值"""
a, b, c = .value, .value, .value
if a < b < c or c < b < a:
return b
if b < a < c or c < a < b:
return a
return c
2024-04-06 17:45:30 +08:00
class MainWindow(Window):
def __init__(self, *args, **kwargs):
super().__init__(
resizable=True,
width=800,
height=600,
caption="Maker",
vsync=True,
*args,
**kwargs,
)
self.main_batch = Batch()
self.main_group = Group()
self.main_frame = RePositionFrame(self)
self.name_info_displays = {}
self.init_name_dispaly()
self.init_name_diy()
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_group = Group(parent=self.num_group, order=10)
2024-04-06 17:45:30 +08:00
for i in range(256):
2024-04-06 17:55:36 +08:00
num_name = NumWidget(
num=i, batch=self.num_batch, group=num_group, x=40, y=50
2024-04-06 17:45:30 +08:00
)
2024-04-06 17:55:36 +08:00
self.num_dict[i] = num_name
self.num_hints = []
# 每个部分的取值提示
font = load_font("黑体", 15)
font_height = font.ascent - font.descent
num_hint_group = Group(parent=self.main_group, order=20)
# hp: 3~6 len = 4
# 要覆盖住 4 个数字
self.num_hints.append(
Rectangle(
x=40 - 3,
y=self.height - (173 + 30 * 6),
width=41,
height=(font_height + 4 + 5) * 4,
# 浅蓝色背景
color=(0, 0, 255, 100),
batch=self.num_batch,
group=num_hint_group,
)
)
# 剩下 7 个, 每个都是中间
for x in range(1, 8):
self.num_hints.append(
Rectangle(
x=40 - 3 + (65 * x),
y=self.height - (173 + 30),
width=41,
height=font_height + 4 + 5,
# 浅蓝色背景
color=(0, 0, 255, 100),
batch=self.num_batch,
group=num_hint_group,
)
)
2024-04-06 17:45:30 +08:00
# 0-9 sorted
# 取前9个拿到血量这边
# index 3~6 之和 + 154 = 血量
# index 10~12 中值 + 36 = 攻击
# index 13~15 中值 + 36 = 防御
# index 16~18 中值 + 36 = 速度
# index 19~21 中值 + 36 = 敏捷
# index 22~24 中值 + 36 = 魔法
# index 25~27 中值 + 36 = 抗性
# index 28~30 中值 + 36 = 智慧
2024-04-06 17:55:36 +08:00
self.display_dict: dict[NumStatus, list[NumWidget]] = {
NumStatus.hp: [self.num_dict[i] for i in range(0, 10)],
2024-04-06 17:45:30 +08:00
NumStatus.attack: [self.num_dict[i] for i in range(10, 13)],
NumStatus.defense: [self.num_dict[i] for i in range(13, 16)],
NumStatus.speed: [self.num_dict[i] for i in range(16, 19)],
NumStatus.agility: [self.num_dict[i] for i in range(19, 22)],
NumStatus.magic: [self.num_dict[i] for i in range(22, 25)],
NumStatus.resistance: [self.num_dict[i] for i in range(25, 28)],
NumStatus.wisdom: [self.num_dict[i] for i in range(28, 31)],
NumStatus.wait: [self.num_dict[i] for i in range(31, 256)],
2024-04-06 17:45:30 +08:00
}
2024-04-06 17:55:36 +08:00
self.update_num_display()
2024-04-06 17:55:36 +08:00
def update_num_display(self) -> None:
# sort hp
self.display_dict[NumStatus.hp].sort(key=lambda x: x.value)
# sort wait
self.display_dict[NumStatus.wait].sort(key=lambda x: x.value)
2024-04-06 17:55:36 +08:00
for status, widgets in self.display_dict.items():
num_count = 0
for widget in widgets:
widget.x = 40 + (65 * status.value)
2024-04-06 17:55:36 +08:00
widget.y = self.height - (170 + 30 * num_count)
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
defense = middle_widget(*self.display_dict[NumStatus.defense]) + 36
speed = middle_widget(*self.display_dict[NumStatus.speed]) + 36
agility = middle_widget(*self.display_dict[NumStatus.agility]) + 36
magic = middle_widget(*self.display_dict[NumStatus.magic]) + 36
resistance = middle_widget(*self.display_dict[NumStatus.resistance]) + 36
wisdom = middle_widget(*self.display_dict[NumStatus.wisdom]) + 36
gather = sum(
(int(hp / 3), attack, defense, speed, agility, magic, resistance, wisdom)
)
self.name_info_displays[
"label"
].text = f"HP|{hp} 攻|{attack} 防|{defense} 速|{speed} 敏|{agility} 魔|{magic} 抗|{resistance} 智|{wisdom} 八围:{gather}"
# 更新提示框
# hp 提示框是固定的
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)]))
middle_index = data[1][0]
self.num_hints[i].y = self.height - (173 + 30 * middle_index)
2024-04-06 17:45:30 +08:00
def init_name_dispaly(self) -> None:
"""
初始化 名字显示 这块内容
"""
name_group = Group(parent=self.main_group)
self.name_info_displays["group"] = name_group
font = load_font("黑体", 20)
font_height = font.ascent - font.descent
name_rec = Rectangle(
x=20,
y=self.height - 135,
width=600, # 在 callback 中定义
height=font_height,
# 颜色: 灰色
color=gray,
batch=self.main_batch,
group=name_group,
)
name_info_label = Label(
x=25,
y=self.height - 127,
text="HP|{} 攻|{} 防|{} 速|{} 敏|{} 魔|{} 抗|{} 智|{} 八围:{}",
width=400,
multiline=False,
font_name="黑体",
font_size=15,
color=(0, 0, 0, 255),
batch=self.main_batch,
group=name_group,
)
name_entry = TextEntry(
x=40,
y=self.height - 100,
width=200,
text="x@x",
# 灰色背景
color=(*gray, 255),
text_color=(0, 0, 0, 255),
batch=self.main_batch,
group=name_group,
)
def rec_callback(rec, width: int, height: int, window: Window):
# rec.x = 20
rec.y = height - 135
self.main_frame.add_callback_func(name_rec, rec_callback)
self.main_frame.add_calculate_func(
name_info_label,
lambda obj, width, height, window: (25, height - 127, 0),
)
self.main_frame.add_calculate_func(
name_entry,
lambda obj, width, height, window: (40, height - 100),
)
self.push_handlers(name_entry)
self.name_info_displays["rec"] = name_rec
self.name_info_displays["label"] = name_info_label
self.name_info_displays["entry"] = name_entry
def on_draw(self) -> None:
self.clear()
self.main_batch.draw()
self.num_batch.draw()
def on_resize(self, width, height):
super().on_resize(width, height)
self.update_num_display()
2024-04-06 17:45:30 +08:00
def start(self) -> None:
pyglet.app.run(interval=1 / 30)
if __name__ == "__main__":
window = MainWindow()
glClearColor(1, 1, 1, 1)
window.start()