写 diy .ing

This commit is contained in:
shenjack 2024-04-06 17:45:30 +08:00
parent cc0420d8f4
commit 4b0eb2aa08
Signed by: shenjack
GPG Key ID: 7B1134A979775551
5 changed files with 396 additions and 2 deletions

View File

@ -2,8 +2,7 @@
resolver = "2"
members = [
"rust-namer",
"miner"
]
"miner"]
# [miner.profile.release]
# opt-level = 3

5
maker-py/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
env
venv
*__pycache__*

75
maker-py/camera.py Normal file
View File

@ -0,0 +1,75 @@
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

106
maker-py/control.py Normal file
View File

@ -0,0 +1,106 @@
from typing import Callable, Union, Tuple, Dict, TYPE_CHECKING, TypeVar, Optional
if TYPE_CHECKING:
from pyglet.text import Label
from pyglet.window import Window
from pyglet.sprite import Sprite
from pyglet.shapes import ShapeBase
from pyglet.gui.widgets import WidgetBase
Repositionable = Union[ShapeBase, Label, Sprite, WidgetBase] # just for typing
else:
Window = TypeVar("Window") # for type checking
Repositionable = TypeVar("Repositionable") # for type checking
Num = Union[int, float]
PotitionTuple = Union[Tuple[Num, Num], Tuple[Num, Num, Num]]
CallBackFunc = Callable[[Repositionable, int, int, Window], None]
CalculateFunc = Callable[[Repositionable, int, int, Window], PotitionTuple]
CallBack = Union[CallBackFunc, CalculateFunc]
IndexType = Union[int, str]
__all__ = [
"RePositionFrame",
]
class RePositionFrame:
"""A Frame Like Object that allows for repositioning of widgets
you can give A function and A widget/shape to let it reposition itself
when the function is called
>>> import pyglet
>>> window = pyglet.window.Window(resizable=True)
>>> reposition_frame = pyglet.gui.frame.RePositionFrame(window)
>>> label = pyglet.text.Label("Hello World", x=0, y=0)
>>> b_label = pyglet.text.Label("Hello World with call back", x=0, y=0)
>>> def callback(obj, width, height, window):
>>> obj.x = width/3
>>> obj.y = height/3
>>> obj.text = f"Hello World with call back, width: {width}, height: {height}"
>>> reposition_frame.add_calculate_func(label, lambda obj, width, height, window: (width/2, height/2, 0))
>>> reposition_frame.add_callback_func(b_label, callback)
>>> @window.event
>>> def on_draw():
>>> window.clear()
>>> label.draw()
>>> b_label.draw()
>>> pyglet.app.run()
"""
def __init__(self, window):
window.push_handlers(self)
self.window = window
self.callback_dict: Dict[IndexType, Tuple[Repositionable, CallBackFunc]] = {}
self.calculate_dict: Dict[IndexType, Tuple[Repositionable, CalculateFunc]] = {}
def add_callback_func(
self, obj: Repositionable, func: CallBackFunc, index: Optional[IndexType] = None
) -> IndexType:
"""Add A callback function to the frame
:param obj: The object that will be repositioned
:param func: The function that will be called
:param index: The index of the object
"""
if index is None:
index = hash(obj)
self.callback_dict[index] = (obj, func)
return index
def add_calculate_func(
self,
obj: Repositionable,
func: CalculateFunc,
index: Optional[IndexType] = None,
) -> IndexType:
"""Add A calculate function to the frame
:param obj: The object that will be repositioned
:param func: The function that will be called
:param index: The index of the object
"""
if index is None:
index = hash(obj)
self.calculate_dict[index] = (obj, func)
return index
def remove_callback_func(self, index: IndexType):
if index in self.callback_dict:
self.callback_dict.pop(index)
def remove_calculate_func(self, index: IndexType):
if index in self.calculate_dict:
self.calculate_dict.pop(index)
def on_resize(self, width: int, height: int):
"""Call all the functions when the window is resized"""
for _, (obj, func) in self.callback_dict.items():
func(obj, width, height, self.window)
for _, (obj, func) in self.calculate_dict.items():
obj.position = func(obj, width, height, self.window) # type: ignore

209
maker-py/main.py Normal file
View File

@ -0,0 +1,209 @@
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 = 0
# 血量
hp = 1
# 攻击
attack = 2
# 防御
defense = 3
# 速度
speed = 4
# 敏捷
agility = 5
# 魔法
magic = 6
# 抗性
resistance = 7
# 智慧
wisdom = 8
class NumWidget:
def __init__(self, num: int, batch: Batch, group: Group, x: int, y: int) -> None:
self.x = x
self.y = y
font = load_font("黑体", 15)
font_height = font.ascent - font.descent
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=group,
)
self.background = Rectangle(
x=x,
y=y,
width=35,
height=font_height + 4,
color=gray,
batch=batch,
group=group,
)
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
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)
# 从大到小
for i in range(256):
widget = NumWidget(
num=i, batch=self.num_batch, group=self.num_group, x=40, y=50
)
self.num_dict[i] = widget
# 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 = 智慧
self.display_dict: dict[NumStatus, list[int]] = {
NumStatus.hp: [self.num_dict[i] for i in range(3, 7)],
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(0, 3)),
*(self.num_dict[i] for i in range(7, 10)),
*(self.num_dict[i] for i in range(31, 256)),
],
}
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 start(self) -> None:
pyglet.app.run(interval=1 / 30)
if __name__ == "__main__":
window = MainWindow()
glClearColor(1, 1, 1, 1)
window.start()