Pygame gadget: Checkbox

Home, addicted to pyGame programming, this article will share some simple small features based on pygame, which can be well embedded in the game to increase game interactivity.

This article focuses on how to implement checkboxes with pygame.

The article reuses some of the classes and methods from previous articles.

Catalog

1. Effect

2. Code

2.1. Buttons

2.2. Processing input

2.3. Display

2.3. Running examples

3. Conclusion

Begin the text below.

1. Effect

Checkboxes can be used in many places in a game, such as when the game starts to select roles, groups, multiple items, and so on. Say nothing and show the code below.

 

2. Code

2.1. Buttons

Each item in a check box can be thought of as a button, but after clicking, the button takes a tick and becomes locked.So we can inherit the KeyboardButton class from the previous article to write buttons in our Checkbox.

class KeyboardCheckbox(KeyboardButton):
    def __init__(self, **kwargs):
        KeyboardButton.__init__(self, **kwargs)
        self.locked = False # Is Locked
        self.render_image_locked() # The picture after the render button is locked

    def render_image_locked(self):
        check_img = pygame.image.load('check.jpg').convert_alpha() # Upper right corner hook after button is locked
        # Zoom in on our hook and draw it in the top right corner of the button
        check_img_l = min(*self.size) // 5 
        check_img_pos = self.size[0] - check_img_l, 0
        check_img = pygame.transform.smoothscale(check_img, (check_img_l, check_img_l))
        self.image_locked = self.image_org.copy()
        self.image_locked.blit(check_img, check_img_pos)

    def update(self):
        if self.clicked:
            self.image = self.image_clicked
        else:
            if self.locked: # When the button is locked, we show the locked picture
                self.image = self.image_locked
            else:
                self.image = self.image_org

The PriteGroup used to manage the buttons in Checkbox is similar to the previous KeyboardButtonGroup, where we need the additional locked property of the Manage Button.

class KeyboardCheckboxGroup(pygame.sprite.Group):
    def __init__(self):
        pygame.sprite.Group.__init__(self)

    def update(self, *args):
        mouse_x, mouse_y, mouse_clicked = args
        for s in self.sprites():
            if s.rect.collidepoint(mouse_x, mouse_y):
                if mouse_clicked == True:
                    s.clicked = True
                elif mouse_clicked == False:
                    if s.clicked:
                        s.clicked = False
                        s.locked = not s.locked # Lock state of flip button
                        if s.locked:
                            add_checkbox_value(s.value) # If the button is locked at this time, add a value
                        else:
                            delete_checkbox_value(s.value) # Delete the value if the button is unlocked at this time
            else:
                if mouse_clicked == False:
                    s.clicked = False
            s.update()

2.2. Processing input

class Keyboard():
    keyboard_input = []
    keyboard_checkbox = []
    output = False


def get_checkbox_value():
    return Keyboard.keyboard_checkbox


def add_checkbox_value(value):
    Keyboard.keyboard_checkbox.append(value)


def delete_checkbox_value(value):
    Keyboard.keyboard_checkbox.remove(value)


def empty_keyboard():
    # Initialize variables in Keyboard
    Keyboard.keyboard_checkbox = []
    Keyboard.keyboard_input = []
    Keyboard.output = False

2.3. Display

def checkbox(screen, item_names, **kwargs):
    '''
    //Draw Checkbox interface
    :param screen: screen
    :param item_names: Check box button display text
    :param kwargs: size : Size of each button
    :return:
    '''
    empty_keyboard()
    keyboard_checkbox_size = kwargs.get('size')

    mouse_x, mouse_y, mouse_clicked = 0, 0, None
    # Initialize and position each check box button button
    keyboard_checkbox_grp = KeyboardCheckboxGroup()
    for value in item_names:
        keyboard_checkbox_grp.add(KeyboardCheckbox(size=keyboard_checkbox_size, value=value))
    keyboard_checkbox_per_row = (screen.get_size()[0] - (keyboard_checkbox_size[0] * 2 + PAD)) // (
            keyboard_checkbox_size[0] + PAD)
    keyboard_rows = (len(keyboard_checkbox_grp) - 1) // keyboard_checkbox_per_row + 1
    keyboard_size = keyboard_checkbox_size[0] * keyboard_checkbox_per_row + PAD * (keyboard_checkbox_per_row - 1), \
                    keyboard_checkbox_size[1] * keyboard_rows + PAD * (keyboard_rows - 1)
    keyboard_position = (screen.get_size()[0] - keyboard_size[0]) // 2, (screen.get_size()[1] - keyboard_size[1]) // 2

    x, y = keyboard_position
    start_x = x
    for i, button in enumerate(keyboard_checkbox_grp):
        button.rect.topleft = x, y
        if (i + 1) % keyboard_checkbox_per_row:
            x += keyboard_checkbox_size[0] + PAD
        else:
            x = start_x
            y += keyboard_checkbox_size[1] + PAD

    # Initialization and positioning confirm button
    x, y = start_x, y + keyboard_checkbox_size[1] + PAD
    btn_confirm = KeyboardButton(id='end', value='confirm', size=(100, 50))  # Button id is'end', display text is'confirm'
    btn_confirm.rect.topleft = x + keyboard_size[0] - btn_confirm.size[0], y
    btn_confirm_grp = KeyboardButtonGroup()
    btn_confirm_grp.add(btn_confirm)

    def draw_area_keyboard(screen, keyboard_checkbox_grp, *args):
        keyboard_checkbox_grp.update(*args)
        keyboard_checkbox_grp.draw(screen)

    def draw_btn_confirm(screen, btn_confirm_grp, *args):
        btn_confirm_grp.update(*args)
        btn_confirm_grp.draw(screen)

    fps_clock = pygame.time.Clock()
    while True:
        if end_of_input():
            return get_checkbox_value()
        mouse_clicked = None
        for event in pygame.event.get():
            if event.type == QUIT:
                exit()
            elif event.type == MOUSEBUTTONDOWN:
                mouse_clicked = True
            elif event.type == MOUSEBUTTONUP:
                mouse_clicked = False
            elif event.type == MOUSEMOTION:
                mouse_x, mouse_y = event.pos

        screen.fill(BLACK)
        args = mouse_x, mouse_y, mouse_clicked
        draw_area_keyboard(screen, keyboard_checkbox_grp, *args)
        draw_btn_confirm(screen, btn_confirm_grp, *args)

        fps_clock.tick(FPS)
        pygame.display.update()

2.3. Running examples

if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE)
    result = checkbox(screen, ['expert', 'doctor', 'medecin', 'driver', 'cartoon'], size=(200, 50))
    print(result)
    pygame.quit()

3. Conclusion

Some changes you can try:

In the actual game, Checkbox may not be a simple text picture, so we can customize the image we want to show by rewriting render_image() in KeyboardCheckbox

Have fun!

 

 

 

 

 

 

 

Published 3 original articles, won approval 2, visited 35
Private letter follow

Tags: Programming

Posted on Tue, 04 Feb 2020 19:33:01 -0800 by everogrin