如何允许用户仅在pygame中的某些条件下键入?

问题描述

当您单击文本框时,我希望用户能够通过将self.active设置为True来键入字母。当您单击文本框时,我希望玩家通过将self.active设置为False来失去该能力。但是,当我单击文本框时,self.active在短暂变为true之前再次变为False。我该如何解决

from pygame import *

init()
screen = display.set_mode((800,600))

name_font = font.Font(None,32)
name_text = ''


class Rectangle:

    def __init__(self,x,y):
        self.active = False
        self.x = x
        self.y = y
        self.text_surface = name_font.render(name_text,True,(255,255,255))
        self.rect_width = max(140,10 + self.text_surface.get_width())
        self.input_rect = Rect(x,y,self.rect_width,32)
        draw.rect(screen,(0,0),self.input_rect,0)
        draw.rect(screen,255),2)
        self.input_rect.w = self.text_surface.get_width() + 10
        screen.blit(self.text_surface,(self.input_rect.x + 5,self.input_rect.y + 5))

    def naming(self):
        global rect_1
        global name_text

        if events.type == MOUSEBUTTONDOWN:
            if self.input_rect.x + 150 >= mx >= self.input_rect.x - 10:
                if self.input_rect.y + 40 >= my >= self.input_rect.y - 10:
                    self.active = True
            if not self.input_rect.x + 150 >= mx >= self.input_rect.x - 10:
                if not self.input_rect.y + 40 >= my >= self.input_rect.y - 10:
                    self.active = False

        if self.active:
            if events.type == KEYDOWN:
                if keys[K_BACKSPACE]:
                    name_text = name_text[:-1]
                    screen.fill((0,0))
                    rect_1 = Rectangle(200,200)
                else:
                    name_text += events.unicode


while True:
    rect_1 = Rectangle(200,200)
    mx,my = mouse.get_pos()
    for events in event.get():
        keys = key.get_pressed()
        rect_1.naming()
        if events.type == QUIT:
            quit()

    display.update()
    time.delay(1)

解决方法

在应用程序循环之前创建Rectangle的实例,但是您必须将事件列表传递给方法naming,并处理该方法中的所有相关事件。 在类中添加一个draw方法,并在每一帧中绘制对象:

class Rectangle:
    # [...]

    def naming(self,events):
        # [...]

        for event in evetnts:
            if e.type == KEYDOWN:
                # [...]

        
            if e.type == # [...]

    def draw(self,screen):
        # [...]
rect_1 = Rectangle(200,200)

run = True
while run :
    
    events = event.get()
    for e in events:
        if e.type == QUIT:
            run = False
    
    rect_1.naming(events)

    # [...]

    rect_1.draw(screen)      

完整示例:

import pygame
from pygame import *

init()
screen = display.set_mode((800,600))

name_font = font.Font(None,32)
name_text = ''


class Rectangle:

    def __init__(self,x,y):
        self.active = False
        self.x = x
        self.y = y
        self.text_surface = name_font.render(name_text,True,(255,255,255))
        self.rect_width = max(140,10 + self.text_surface.get_width())
        self.input_rect = Rect(x,y,self.rect_width,32)
        draw.rect(screen,(0,0),self.input_rect,0)
        draw.rect(screen,255),2)
        self.input_rect.w = self.text_surface.get_width() + 10
        screen.blit(self.text_surface,(self.input_rect.x + 5,self.input_rect.y + 5))

    def naming(self,events):
        global rect_1
        global name_text

        for e in events:
            if e.type == MOUSEBUTTONDOWN:
                mx,my = e.pos
                if self.input_rect.x + 150 >= mx >= self.input_rect.x - 10:
                    if self.input_rect.y + 40 >= my >= self.input_rect.y - 10:
                        self.active = True
                if not self.input_rect.x + 150 >= mx >= self.input_rect.x - 10:
                    if not self.input_rect.y + 40 >= my >= self.input_rect.y - 10:
                        self.active = False

            if e.type == KEYDOWN:
                if self.active:
                    if e.key == K_BACKSPACE:
                        name_text = name_text[:-1]
                    else:
                        name_text += e.unicode
                    self.text_surface = name_font.render(name_text,255))
    
    def draw(self,screen):
        draw.rect(screen,self.input_rect.y + 5))


rect_1 = Rectangle(200,200)

run = True
while run :
    
    events = event.get()
    for e in events:
        if e.type == QUIT:
            run = False
    
    rect_1.naming(events)

    screen.fill(0)
    rect_1.draw(screen)  
    display.update()
    time.delay(1)  
,

在我看来,您需要从while循环中取出第47行“ rect_1 = Rectangle(200,200)”,因为您一直在重新创建该框,并用一个等于false的有效值实例化了一个新框。 / p>

,

您获得的是鼠标位置,但是却没有做任何事情,例如将其与盒子的位置进行比较。如果您以self.active = True开头,则无论光标在哪里,都可以在框中键入内容。