写 diy .ing
This commit is contained in:
parent
cc0420d8f4
commit
4b0eb2aa08
@ -2,8 +2,7 @@
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"rust-namer",
|
"rust-namer",
|
||||||
"miner"
|
"miner"]
|
||||||
]
|
|
||||||
|
|
||||||
# [miner.profile.release]
|
# [miner.profile.release]
|
||||||
# opt-level = 3
|
# opt-level = 3
|
||||||
|
5
maker-py/.gitignore
vendored
Normal file
5
maker-py/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
env
|
||||||
|
venv
|
||||||
|
|
||||||
|
*__pycache__*
|
||||||
|
|
75
maker-py/camera.py
Normal file
75
maker-py/camera.py
Normal 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
106
maker-py/control.py
Normal 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
209
maker-py/main.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user