写 diy .ing
This commit is contained in:
parent
cc0420d8f4
commit
4b0eb2aa08
@ -2,8 +2,7 @@
|
||||
resolver = "2"
|
||||
members = [
|
||||
"rust-namer",
|
||||
"miner"
|
||||
]
|
||||
"miner"]
|
||||
|
||||
# [miner.profile.release]
|
||||
# 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