首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >菜单上有按钮使用游戏。

菜单上有按钮使用游戏。
EN

Code Review用户
提问于 2019-10-21 00:28:08
回答 1查看 1K关注 0票数 6

我写这篇文章是为了教自己如何制作带有按钮的菜单,我想知道我是否做得很好,有没有办法使菜单更短、更有效率。

代码语言:javascript
运行
复制
import pygame, sys
from pygame import *
run = True
global newBG
newBG = False

#-------------------------------------------------------------------------------

def mainLoop():
    global win, newW, newH, newBG
    newW, newH = (960 , 508)
    win = pygame.display.set_mode ((newW, newH) , pygame.RESIZABLE)
    pygame.display.set_caption("SMC")

    backGround = 0


    while run:


        global mouse, currentScreen
        mouse = pygame.mouse.get_pos()

        currentScreen()

        while newBG:
            drawBackground()
            newBG = False

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.VIDEORESIZE:
                win = pygame.display.set_mode ( (event.w, event.h) , pygame.RESIZABLE )       
                newW, newH = event.w, event.h
                drawBackground()
                uiPlate()
            if event.type == pygame.MOUSEBUTTONDOWN:
                for b in buttonList:
                    b.click()

        pygame.display.update()

#------------------------------------------------------------------------------

def mainMenu():
    global backGroundImage, buttonList, currentScreen

    backGroundImage = pygame.image.load('Background.jpg')
    ButtonPic = pygame.image.load('Button.jpg')
    ButtonHoverPic = pygame.image.load('ButtonHover.jpg')
    ButtonPressPic = pygame.image.load('ButtonPress.jpg')

    buttonList = [
    button(screenSwap, secondMenu, ButtonPic, ButtonHoverPic, ButtonPressPic, .1, .1, .1, .1),
    button('Hello', None, ButtonPic, ButtonHoverPic, ButtonPressPic, .1, .25, .1, .1),
    button('Hello to you!', None, ButtonPic, ButtonHoverPic, ButtonPressPic, .1, .50, .1, .1)
]

    for b in buttonList:
        b.drawButton()

#------------------------------------------------------------------------------

def secondMenu():
    global backGroundImage, buttonList

    backGroundImage = pygame.image.load('Button.jpg')
    ButtonPic = pygame.image.load('Background.jpg')
    ButtonHoverPic = pygame.image.load('ButtonHover.jpg')
    ButtonPressPic = pygame.image.load('ButtonPress.jpg')

    buttonList = [
    button(screenSwap, mainMenu, ButtonPic, ButtonHoverPic, ButtonPressPic, .75, .1, .1, .1),
    button('Goodbye', None, ButtonPic, ButtonHoverPic, ButtonPressPic, .75, .25, .1, .1),
    button('Goodbye to you friend!', None, ButtonPic, ButtonHoverPic, ButtonPressPic, .75, .50, .1, .1)
]

    for b in buttonList:
        b.drawButton()

#------------------------------------------------------------------------------

uiX = 0
uiY = 0
uiW = 960
uiH = 508
def uiPlate():
    global uiW, uiH, uiX, uiY
    uiW = (int(newW))
    uiH = (int(uiW*0.5296875))
    if uiH > newH:
        uiH = int(newH)
        uiW = (int(uiH/0.5296875))
    uiX = (int((newW - uiW)/2))
    uiY = (int((newH - uiH)/2))
##    pygame.draw.rect(win, (100, 255, 100,), (uiX, uiY, uiW, uiH))
##    print(uiW, uiH, uiX, uiY)

#------------------------------------------------------------------------------

def drawBackground():
    global backGround
    backGround = pygame.transform.scale(backGroundImage, (newW, newH))
    win.blit((backGround), (0,0))

#------------------------------------------------------------------------------

class button:
    global uiX, uiY, uiW, uiH
    def __init__(self, action, actionProps, ButtonPic, ButtonHoverPic, ButtonPressPic,  x, y, w, h):
        self.ButtonPic = ButtonPic
        self.ButtonHoverPic = ButtonHoverPic
        self.ButtonPressPic = ButtonPressPic

        self.bx = int(uiX + (x * uiW))
        self.by = int(uiY + (y * uiH))
        self.bw = int(w * uiW)
        self.bh = int(h * uiH)

        self.action = action
        self.actionProps = actionProps

    def drawButton(self):
        click = pygame.mouse.get_pressed()

        ButtonPic = pygame.transform.scale(self.ButtonPic, (self.bw, self.bh))
        ButtonHoverPic = pygame.transform.scale(self.ButtonHoverPic, (self.bw, self.bh))
        ButtonPressPic = pygame.transform.scale(self.ButtonPressPic, (self.bw, self.bh))

        win.blit(ButtonPic, (self.bx, self.by))
        if ((self.bx < mouse[0] < (self.bx + self.bw)) and (self.by < mouse[1] < (self.by + self.bh))):
            win.blit(ButtonHoverPic, (self.bx, self.by))
            if click[0]:
                win.blit(ButtonPressPic, (self.bx, self.by))

    def click(self):
        if ((self.bx < mouse[0] < (self.bx + self.bw)) and (self.by < mouse[1] < (self.by + self.bh))):
            if self.actionProps != None:
                self.action(self.actionProps)
            else:
                print(self.action)

#------------------------------------------------------------------------------

def screenSwap(screen):
    global currentScreen, newBG
    currentScreen = screen
    newBG = True

#------------------------------------------------------------------------------
currentScreen = mainMenu
mainLoop()

不好意思,如果太费心看了,我想给你看一些我可以比较的精心制作的菜单系统的代码。

EN

回答 1

Code Review用户

发布于 2019-10-21 17:51:47

PEP-0008

遵循佩普-0008准则。使用自动检查器(pylint,pyflakes,.)检查您的代码是否违规。

问题包括:

  • 变量、函数和方法名称应该是snake_case。例如,newBG应该是new_backgroundmainLoop应该是main_loopdrawButton应该是draw_button
  • 函数/方法名称和括号之间没有空格。set_mode (应该是set_mode(
  • 逗号前没有空格,相邻括号之间没有空格,在开始括号之后或结束括号之前没有空格。set_mode ( (event.w, event.h) , pygame.RESIZABLE )应该是set_mode((event.w, event.h), pygame.RESIZABLE)
  • 类名应以大写字母开头。所以Button而不是button

举几个例子。运行一个检查程序来查看所有这些。

导入*

代码语言:javascript
运行
复制
import pygame, sys
from pygame import *

您是导入pygame,还是从pygame内部导入所有内容?做一个或另一个,最好是前者,但绝对不能两者兼而有之!

全局变量是全局

代码语言:javascript
运行
复制
global newBG
newBG = False

newBG是在全局范围内定义的。global newBG是不需要的,也是无用的。

型一致性

backGround的类型是什么?是图像吗?如果是,请解释:

代码语言:javascript
运行
复制
    backGround = 0

看起来,您正在尝试将一个整数分配给通常保存图像的东西。但是等等!它是一个局部变量,在任何地方都不使用。

而不是

这是一个循环还是一个if语句?

代码语言:javascript
运行
复制
    while newBG:
        drawBackground()
        newBG = False

它不能执行不止一次,因为它将循环条件设置为False。更清楚的是:

代码语言:javascript
运行
复制
    if newBG:
        drawBackground()
        newBG = False

整数算法

如果你不想要浮点值,不要除以2。相反,整数-除以二!

而不是这样:

代码语言:javascript
运行
复制
uiX = (int((newW - uiW)/2))
uiY = (int((newH - uiH)/2))

写这个:

代码语言:javascript
运行
复制
uiX = (newW - uiW) // 2
uiY = (newH - uiH) // 2

持久性

您的主循环大致如下:

代码语言:javascript
运行
复制
while run:

    currentScreen()

    # Handle events

    pygame.display.update()

currentScreen()或者调用mainMenu()secondMenu()

代码语言:javascript
运行
复制
def mainMenu():
    # load 4 images
    # create 3 button objects in a list
    # draw button objects

def secondMenu():
    # load 4 images
    # create 3 button objects in a list
    # draw button objects

所以..。主事件循环的每一次迭代(例如,每秒30至60次)是:

  • 加载多幅图像
  • 创建UI元素
  • 画一些东西
  • 丢弃图像和UI元素

原谅上面的尖叫声。您不希望在绘制UI时浪费时间进行重复的冗余文件I/O。在启动时或第一次使用映像时加载一次。只创建一次按钮,或者最多只在切换到新屏幕时创建按钮。切换到新屏幕时填充按钮列表。由于此按钮列表必须在事件循环的多个迭代中维护其值,因此需要将其作为全局变量,或者.

停止使用全局变量

为应用程序创建一个主类,并将“全局”信息存储为主类self成员。

创建一个屏幕类,并创建两个实例:一个用于主菜单屏幕,另一个用于第二个菜单。屏幕类将保存:

  • 那个屏幕的按钮列表。
  • 该屏幕的背景图像。
  • 背景图像的缩放副本(所以您不必在事件循环的每一次迭代中重新处理它!)

如果应用程序检测到VIDEORESIZE,并且在更改屏幕时,它会告诉屏幕对象,因此屏幕对象可以重新布局其对象并重新绘制背景图像。

单面漆

这是干什么用的?

代码语言:javascript
运行
复制
    win.blit(ButtonPic, (self.bx, self.by))
    if ...:
        win.blit(ButtonHoverPic, (self.bx, self.by))
        if ...:
            win.blit(ButtonPressPic, (self.bx, self.by))

除非ButtonPicButtonHoverPicButtonPressPic不是完全相同的大小,或者如果ButtonHoverPicButtonPressPic有透明的区域,那么上面的代码只能绘制按钮,然后立即重新绘制按钮,或者立即第三次重新绘制按钮。鉴于Premium涂层保证涂料™很可能被使用,这是两倍或三倍的油漆成本,没有任何收益。

相反,我推荐一些更像:

代码语言:javascript
运行
复制
    image = self._image
    if ...:
        if ...:
            image = self._press_image
        else:
            image = self._hover_image
    win.blit(image, (self.bx, self.by)
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/231072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档