好久不见,pygameGUI开发日志又回来啦!
鸽了这么长时间,大家有没有想我啊~这次的开发目前很顺利,并且这次假期带教程的2.0正式版本会发出来{:10_302:}
如果发不出来我就爆金币
先不公布开发进度,给大伙看个代码块(不全的)看看各位鱼油可以从代码里分析出什么来{:10_310:}
import pygame
from pygame.locals import *
from pygameGUI.error import UIError
from pygameGUI.group import Group, BottomGroup
class Widget:
"""组件基类"""
# states控件状态表
NORMAL = 0# 正常
HOVER = 1# 激活
PRESSED = 2# 按下
def __init__(self, group):
"""自动加入group组"""
# 自身组件交互状态
self.states = self.NORMAL
# 自身矩形位置(默认
self.rect = pygame.Rect()
# 属于的组
self.group = group
if type(group) is BottomGroup:# 是底层组
self.group = group
self.group.add(self)
elif isinstance(self.group, Frame):
self.group = group.group# 是Frame大类
self.master = group
self.group.add(self)
else:
raise UIError("group参数应该是一个Frame类")
def update(self, *args, **kwargs):
"""每帧调用"""
return
def draw(self, screen):
"""每帧绘制"""
pass
def get_rect(self):
"""获取组件在最底层surface对象中的矩形位置(帝龟)"""
if hasattr(self, "master"):
rect = + self.master.get_rect(),
self.rect + self.master.get_rect(),
self.rect,
self.rect]
return pygame.Rect(rect)
else:
screen_rect = self.group.screen.get_rect()
rect = + self.rect,
screen_rect + self.rect,
self.rect,
self.rect]
return pygame.Rect(rect)
@staticmethod
def draw_texture(texture, size):
"""绘制纹理"""
image = pygame.Surface(size, pygame.SRCALPHA)
if type(texture) is tuple or type(texture) is list:
image.fill(texture)
elif callable(texture):
image = texture(image)
elif type(texture) is pygame.Surface:
image = texture
else:
raise UIError("texture的类型应该是一个元组/列表、返回image函数 或 一个Surface对象")
return image
@staticmethod
def replace_rect(rect, image):
"""在改变纹理后刷新矩形位置
| rect : 原位置
| image : 新图片
~ 新位置中心点设为与原位置的中心点重合"""
x, y = rect.center
rect = image.get_rect()
rect.center = x, y
return rect
@staticmethod
def default_rect_detection(widget, *args, **kwargs):
if (not BottomGroup.block or widget.unblock) \
and widget.get_rect().collidepoint(kwargs["pos"]):
# 开启阻断
if widget.block is True:
BottomGroup.block = True
return widget.HOVER
else:
return widget.NORMAL
class Frame(Widget):
"""框架结构"""
def __init__(self, group, pos=(0, 0), size=(100, 100), texture=(0, 0, 0), block=True, unblock=False):
super().__init__(group)
# 阻断与阻断免疫
self.block = block
self.unblock = unblock
# 默认交互检测
self.detection = super().default_rect_detection
# 默认控制行为
def command(states, *args, **kwargs):
if states == self.HOVER:
pass
self.states = states
self.command = command
# 生成图像和纹理
self.image = self.draw_texture(texture, size)
# 设置矩形
self.rect = self.image.get_rect()
self.rect.x, self.rect.y = pos
# 内置组
self.widgets = Group(self)
def update(self, *args, **kwargs):
"""刷新"""
# 刷新内部组的组件
self.widgets.update(*args, **kwargs)
# 判定
states = self.detection(self, *args, **kwargs)
# 执行交互行为
self.command(states)
def draw(self, surface):
"""绘制"""
image = self.image.copy()
self.widgets.draw(image)
surface.blit(image, )
def set_image(self, size=(100, 100), texture=(0, 0, 0)):
"""设置图片,自动将新图片的中心与就图片中心重合"""
self.image = self.draw_texture(texture, size)
self.rect = self.replace_rect(self.rect, self.image)
def delete(self):
self.group.widgets.remove(self)
class Button(Widget):
def __init__(self, group, pos=(0, 0), size=(50, 25), texture=(230, 230, 230),
block=True, unblock=False):
super().__init__(group)
# 阻断与阻断免疫
self.block = block
self.unblock = unblock
# 生成图像和纹理
self.image = self.draw_texture(texture, size)
# 设置矩形
self.rect = self.image.get_rect()
self.rect.x, self.rect.y = pos
# 默认的交互检测
def detection(widget, *args, **kwargs):
if widget.default_rect_detection(widget, *args, **kwargs):
# 判断输出交互状态
if pygame.mouse.get_pressed():
return widget.PRESSED
else:
return widget.HOVER
else:
return widget.NORMAL
self.detection = detection
# 默认控制行为
def command(states, *args, **kwargs):
if states == self.NORMAL:# 正常
self.set_image()
elif states == self.HOVER:# 交互状态
self.set_image(texture=(240, 240, 240))
if self.states == self.PRESSED:# 从按下状态返回交互状态
print("按钮完成了一次点击")
elif states == self.PRESSED:# 按下状态
self.set_image(texture=(220, 220, 220))
self.states = states
self.command = command
def update(self, *args, **kwargs):
"""刷新"""
# 判定
states = self.detection(self, *args, **kwargs)
# 执行交互行为
self.command(states)
def draw(self, surface):
"""绘制"""
surface.blit(self.image, )
def set_image(self, size=(50, 25), texture=(230, 230, 230)):
"""设置图片,自动将新图片的中心与就图片中心重合"""
self.image = self.draw_texture(texture, size)
self.rect = self.replace_rect(self.rect, self.image)
**** Hidden Message *****
由于这次使用了pycharm作为编辑器,所以效率提高了不少{:10_257:}
哈哈,鱼油们,好久不见啊!咱们的pygameGUI开发日志又回来啦!鸽了这么久,你们有没有想我呀?{:10_307:} 如果你们不想我,我可是会伤心的哦~
这一次,我可带来了好消息:我们2.0正式版本要在假期发布啦!如果发不出来,我就爆金币!{:10_304:}
看到大伙儿如此期待,我也不卖关子了,虽然不公开具体进度,但今天给大家看一小段代码,看看你们能从中分析出什么来。瞧瞧我的新作,别客气,尽情发表你们的高见哈!
import pygame
from pygame.locals import *
from pygameGUI.error import UIError
from pygameGUI.group import Group, BottomGroup
class Widget:
"""组件基类"""
NORMAL = 0# 正常
HOVER = 1 # 激活
PRESSED = 2 # 按下
def __init__(self, group):
self.states = self.NORMAL
self.rect = pygame.Rect()
self.group = group
if type(group) is BottomGroup:
self.group.add(self)
elif isinstance(self.group, Frame):
self.master = group
self.group.add(self)
else:
raise UIError("group参数应该是一个Frame类")
def update(self, *args, **kwargs):
return
def draw(self, screen):
pass
def get_rect(self):
if hasattr(self, "master"):
rect =
return pygame.Rect(rect)
else:
screen_rect = self.group.screen.get_rect()
rect =
return pygame.Rect(rect)
@staticmethod
def draw_texture(texture, size):
image = pygame.Surface(size, pygame.SRCALPHA)
if type(texture) in (tuple, list):
image.fill(texture)
elif callable(texture):
image = texture(image)
elif isinstance(texture, pygame.Surface):
image = texture
else:
raise UIError("texture的类型应该是一个元组/列表、返回image函数 或 一个Surface对象")
return image
@staticmethod
def replace_rect(rect, image):
x, y = rect.center
rect = image.get_rect()
rect.center = x, y
return rect
@staticmethod
def default_rect_detection(widget, *args, **kwargs):
if (not BottomGroup.block or widget.unblock) and widget.get_rect().collidepoint(kwargs):
if widget.block:
BottomGroup.block = True
return widget.HOVER
else:
return widget.NORMAL
看到了吗,这是一个基础的组件类`Widget`。它有三种状态:正常(`NORMAL`),激活(`HOVER`),和按下(`PRESSED`)。我们还定义了一些方法,比如`draw_texture`绘制纹理,`replace_rect`刷新矩形位置等。
接下来再看看我们特别设计的两个组件类,`Frame`和`Button`,它们都是从`Widget`继承而来:
class Frame(Widget):
def __init__(self, group, pos=(0, 0), size=(100, 100), texture=(0, 0, 0), block=True, unblock=False):
super().__init__(group)
self.block = block
self.unblock = unblock
self.detection = super().default_rect_detection
def command(states, *args, **kwargs):
if states == self.HOVER:
pass
self.states = states
self.command = command
self.image = self.draw_texture(texture, size)
self.rect = self.image.get_rect()
self.rect.x, self.rect.y = pos
self.widgets = Group(self)
def update(self, *args, **kwargs):
self.widgets.update(*args, **kwargs)
states = self.detection(self, *args, **kwargs)
self.command(states)
def draw(self, surface):
image = self.image.copy()
self.widgets.draw(image)
surface.blit(image, )
def set_image(self, size=(100, 100), texture=(0, 0, 0)):
self.image = self.draw_texture(texture, size)
self.rect = self.replace_rect(self.rect, self.image)
def delete(self):
self.group.widgets.remove(self)
`Frame`类是一个框架结构组件,它有一个内部组`widgets`可以容纳其它组件,同时提供了阻断与免疫机制,以及默认控制和交互检测。
class Button(Widget):
def __init__(self, group, pos=(0, 0), size=(50, 25), texture=(230, 230, 230), block=True, unblock=False):
super().__init__(group)
self.block = block
self.unblock = unblock
self.image = self.draw_texture(texture, size)
self.rect = self.image.get_rect()
self.rect.x, self.rect.y = pos
def detection(widget, *args, **kwargs):
if widget.default_rect_detection(widget, *args, **kwargs):
if pygame.mouse.get_pressed():
return widget.PRESSED
else:
return widget.HOVER
else:
return widget.NORMAL
self.detection = detection
def command(states, *args, **kwargs):
if states == self.NORMAL:
self.set_image()
elif states == self.HOVER:
self.set_image(texture=(240, 240, 240))
if self.states == self.PRESSED:
print("按钮完成了一次点击")
elif states == self.PRESSED:
self.set_image(texture=(220, 220, 220))
self.states = states
self.command = command
def update(self, *args, **kwargs):
states = self.detection(self, *args, **kwargs)
self.command(states)
def draw(self, surface):
surface.blit(self.image, )
def set_image(self, size=(50, 25), texture=(230, 230, 230)):
self.image = self.draw_texture(texture, size)
self.rect = self.replace_rect(self.rect, self.image)
`Button`类是一个按钮组件,同样具有阻断与免疫机制,还新增了按钮状态的视觉反馈,比如在不同状态下改变颜色,并且已经默认实现了简单的点击逻辑。
怎么样,鱼油们,看懂了吗?这是个很灵活的模板,通过分离交互检测和行为执行部分,以减少重复代码,提高开发效率。用PyCharm编辑器码代码效率也蹭蹭往上涨~
希望这些代码能为你们提供一些启发,等我的2.0版本发布出来后,一定会更加详细地介绍每一个模块的使用方法,所以大家敬请期待吧!{:10_303:}
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 FishC 发表于 2024-7-10 22:57
哈哈,鱼油们,好久不见啊!咱们的pygameGUI开发日志又回来啦!鸽了这么久,你们有没有想我呀?...
不是,哥们{:10_282:} 支持{:10_305:} 支持,看来更新的内容不少嘛{:10_256:},加油呀{:10_265:} 站在使用者角度考虑,精简使用者所费代码,妙啊
{:10_298:}好耶 纯新手,这个pygame是干啥的昂 abiao_fishc 发表于 2024-7-11 11:38
纯新手,这个pygame是干啥的昂
写游戏用的{:10_257:} 本帖最后由 zhangchenyvn 于 2024-7-11 13:23 编辑
感觉这次的代码更新比上次的工程化了好多,功能也丰富了好多,上面这段代码应该是UI的框架和一个按钮的代码,写成了类似TK的模板化代码,使用起来比上一代更加高效亿些
真心表示:真的不错 路过
页:
[1]