본문 바로가기

Development/Tetris

Python - 테트리스(Tetris) 만들기 (13) - Setting Screen

이전시간에는 Main Screen 껍데기를 만들었습니다. 이번에는 Setting Screen을 만들고, 연결하는 작업을 해보도록 하겠습니다.

이전에 만들었던 Main Screen

 

Setting Screen 그리기

Setting Screen은 어떤 내용이 있어야 할까요? 요구사항을 살펴보면 다음과 같은 항목들이 Setting Screen에서 설정해야 하는 값이 됩니다.

 

1. 키보드 맵핑

2. 홀드 시스템 On/Off

3. 고스트 시스템 On/Off

4. 미리보기 1 ~ 6 개 조정

5. 소리 볼륨

6. Lock Delay : mino가 Lock 된 이후 다음 블럭이 나오는데 걸리는 시간

7. Gravity : 아무 동작을 안하고 있을 때 블럭이 내려오는 속도

8. ARE : 락 되고 다음 생성까지의 지연시간

9. DAS : 자동 이동까지 걸리는 키보드 누르는 시간

10. ARR : 좌우로 자동 이동될 때 한 칸 이동하는 시간

11. SDF : 아래로 자동 이동할 때의 속도

 

이정도 설정값을 만질 수 있다면 테트리스 설정으로 충분할 듯 합니다.

 

Setting Screen 초안

대략적으로 만들어 보았지만... 화면이 넘처 흐른다??

 

지금 화면이 넘쳐 흐르는 모습을 보실 수 있습니다. 이런 경우에는 어떻게 할 수 있을까요? 바로 Scroll bar 도입입니다.

이렇게 하면 많은 컨텐츠를 집어 넣을 수 있다.

 

그리고, 편의성을 위해 버튼은 언제든지 누를 수 있도록 하단에 고정시킬 수도 있을 것입니다.

 

버튼이 살짝 boostrap style같아졌습니다...ㅎㅎㅎ

 

 

간단하게 길이측정부터 해봅시다

이 화면부터 만들어 볼까요??

 


그림판처럼 하나하나 그린다고 생각하면 쉽습니다. 천천히 만들어 봅시다.

class SettingDisplay:
    BACKGROUND_COLOR = (255, 255, 255)
    TITLE_COLOR = (0, 0, 0)
    CONTENTS_COLOR = (127, 127, 127)
    BTN_CONTENTS_COLOR = (255, 255, 255)
    CANCEL_BTN_COLOR = (191, 191, 191)
    SAVE_BTN_COLOR = (2, 188, 125)
    LINE_COLOR = (192, 192, 192)
    TITLE = "Setting"
    CANCLE = "Cancel"
    SAVE = "Save"
    MARGIN_W = 0.05
    TOP_H = BOTTOM_H = 0.2
    BTN_W = 0.2
    BTN_H = 0.1

    def __init__(self, width, height):
        self.width, self.height = width, height
        self.display_surface = None
        self.title_font = pg.font.SysFont("calibri", 56, bold=True)
        self.btn_font = pg.font.SysFont("calibri", 28, bold=True)

        ## text setting
        self.text_title_surface = self.title_font.render(self.TITLE, True, self.TITLE_COLOR)
        w, h = self.title_font.size(self.TITLE)
        self.text_title_x = (width - w)/2
        self.text_title_y = (self.TOP_H * height - h)/2

        self.text_cancel_surface = self.btn_font.render(self.CANCLE, True, self.BTN_CONTENTS_COLOR)
        w, h = self.btn_font.size(self.CANCLE)
        self.text_cancel_x = self.MARGIN_W * width + (self.BTN_W * width - w)/2
        self.text_cancel_y = (1 - self.BOTTOM_H) * height + (self.BOTTOM_H * height - h)/2

        self.text_save_surface = self.btn_font.render(self.SAVE, True, self.BTN_CONTENTS_COLOR)
        w, h = self.btn_font.size(self.SAVE)
        self.text_save_x = (1 - self.MARGIN_W - self.BTN_W) * width + (self.BTN_W * width - w)/2
        self.text_save_y = (1 - self.BOTTOM_H) * height + (self.BOTTOM_H * height - h)/2

    def init(self):
        self.display_surface = pg.display.set_mode((self.width, self.height))

    def update(self):
        self.display_surface.fill(self.BACKGROUND_COLOR)
        pg.draw.rect(self.display_surface, self.CANCEL_BTN_COLOR,
                        [self.MARGIN_W * self.width,
                         (1 - self.BOTTOM_H + (self.BOTTOM_H - self.BTN_H)/2) * self.height,
                         self.BTN_W * self.width,
                         self.BTN_H * self.height],
                        0, 10)
        pg.draw.rect(self.display_surface, self.SAVE_BTN_COLOR, 
                        [(1 - self.MARGIN_W - self.BTN_W) * self.width,
                         (1 - self.BOTTOM_H + (self.BOTTOM_H - self.BTN_H)/2) * self.height,
                         self.BTN_W * self.width,
                         self.BTN_H * self.height],
                        0, 10)
        pg.draw.line(self.display_surface, self.LINE_COLOR, (0, self.TOP_H*self.height), (self.width, self.TOP_H*self.height))
        pg.draw.line(self.display_surface, self.LINE_COLOR, (0, (1 - self.BOTTOM_H)*self.height), (self.width, (1 - self.BOTTOM_H)*self.height))
        self.display_surface.blit(self.text_title_surface, dest=(self.text_title_x, self.text_title_y))
        self.display_surface.blit(self.text_cancel_surface, dest=(self.text_cancel_x, self.text_cancel_y))
        self.display_surface.blit(self.text_save_surface, dest=(self.text_save_x, self.text_save_y))
        pg.display.flip()

 

이 코드를 Main App에서 실행시켜봅시다.

class MainApp:
    def __init__(self, width: int, height: int):
        self.width, self.height = width, height
        pg.init()
        # self.display = MainDisplay(width, height)
        self.display = SettingDisplay(width, height)
        self.system = MainSystem()
        self.setting_app = None
        self.tetris_app = None
        self._running = False

    def _init(self):
        self.display.init()
        self.system.init()
        self._running = True

    def _event(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self._running = False
            elif event.type == pg.KEYDOWN:
                print(event.key)

    def _quit(self):
        pg.quit()

    def execute(self):
        self._init()
        while self._running:
            self._event()
            self.display.update()
        self._quit()


def main():
    main_app = MainApp(640, 480)
    main_app.execute()


if __name__ == "__main__":
    main()

그림과 비슷하게 만들어 졌다.

 

이 안에 Setting 값을 이제 넣어야 합니다. 한번 만들어 볼까요??

 

 

 


Setting값 조절할 Window 만들기

Setting값을 조절할 창의 길이가 얼마정도인지 가늠이 안됩니다. 시인성을 생각하면 우선 480으로는 어려워 보인다는 것을 을 이전에 감으로 확인해 보았습니다.

이 창의 높이가 어떻게 될까..?

그래서 이번에는 비율이 아닌 pixel 단위로 계산 해보기로 합시다. 이전에 0.2h가 96이었던 점을 감안해 봅시다.

 

Key Mapping, System 단어가 작아졌다.

이렇게 하고 우선은 Surface를 만들어 봅시다. 원래의 H가 480pixel인 점을 감안하면 0.1h는 48pixel, 1.2h는 576pixel이 됩니다. 입력은 480pixel으로 받을테니 전체 스크린은 1.2배를 하고, 0.1h은 480pixel에서 그대로 계산하면 됩니다.

 

class SubSettingDisplay:
    BACKGROUND_COLOR = (255, 255, 255)
    TITLE_COLOR = (0, 0, 0)
    LABEL_COLOR = (127, 127, 127)
    VALUE_COLOR = (127, 127, 127)
    RECT_LINE = (192, 192, 192)
    SLIDER_LINE = (192, 192, 192)
    SLIDER_TOGGLE = (64, 64, 64)
    KEY_MAPPING = "Key Mapping"
    SYSTEM = "System"
    RIGHT = "Right"
    LEFT = "Left"
    CLOCKWISE_ROTATION = "Clockwise rotation"
    COUNTERCLOCKWISE_ROTATION = "Counterclockwise rotation"
    SOFT_DROP = "Soft drop"
    HARD_DROP = "Hard drop"
    HOLD = "Hold"
    SOUND_VOLUME = "Sound volume"
    PREVIEW_COUNT = "Preview count"
    GHOST_SYSTEM = "Ghost system"
    HOLD_SYSTEM = "Hold system"
    LOCK_DELAY = "Lock delay"
    GRAVITY = "Gravity"
    ARE = "ARE"
    DAS = "DAS"
    ARR = "ARR"
    SDF = "SDF"
    CONTENTS_H = 0.1
    KEY_MAPPING_LABEL_W = 0.3
    SYSTEM_LABEL_W = 0.2

    def __init__(self, width, height):
        self.width, self.height = width, height
        self.full_height = height * 1.2
        self.display_surface = None
        self.title_font = pg.font.SysFont("calibri", 28)
        self.contents_font = pg.font.SysFont("calibri", 16)
         
        ## text setting
        self.text_keymapping_surface = self.title_font.render(self.KEY_MAPPING, True, self.TITLE_COLOR)
        w, h = self.title_font.size(self.KEY_MAPPING)
        self.text_keymapping_x = width/4 - w/2
        self.text_keymapping_y = (self.CONTENTS_H * height - h)/2

        self.text_system_surface = self.title_font.render(self.SYSTEM, True, self.TITLE_COLOR)
        w, h = self.title_font.size(self.SYSTEM)
        self.text_system_x = width*3/4 - w/2
        self.text_system_y = (self.CONTENTS_H * height - h)/2

        self.text_right_surface = self.contents_font.render(self.RIGHT, True, self.LABEL_COLOR)
        w, h = self.contents_font.size(self.RIGHT)
        self.text_right_x = self.KEY_MAPPING_LABEL_W * width - w
        self.text_right_y = (self.CONTENTS_H * height - h)/2 + self.CONTENTS_H * height

        self.text_left_surface = self.contents_font.render(self.LEFT, True, self.LABEL_COLOR)
        w, h = self.contents_font.size(self.LEFT)
        self.text_left_x = self.KEY_MAPPING_LABEL_W * width - w
        self.text_left_y = (self.CONTENTS_H * height - h)/2 + self.CONTENTS_H * height * 2

        self.text_clockwise_surface = self.contents_font.render(self.CLOCKWISE_ROTATION, True, self.LABEL_COLOR)
        w, h = self.contents_font.size(self.CLOCKWISE_ROTATION)
        self.text_clockwise_x = self.KEY_MAPPING_LABEL_W * width - w
        self.text_clockwise_y = (self.CONTENTS_H * height - h)/2 + self.CONTENTS_H * height * 3

        self.text_counterclockwise_surface = self.contents_font.render(self.COUNTERCLOCKWISE_ROTATION, True, self.LABEL_COLOR)
        w, h = self.contents_font.size(self.COUNTERCLOCKWISE_ROTATION)
        self.text_counterclockwise_x = self.KEY_MAPPING_LABEL_W * width - w
        self.text_counterclockwise_y = (self.CONTENTS_H * height - h)/2 + self.CONTENTS_H * height * 4

        self.text_soft_drop_surface = self.contents_font.render(self.SOFT_DROP, True, self.LABEL_COLOR)
        w, h = self.contents_font.size(self.SOFT_DROP)
        self.text_soft_drop_x = self.KEY_MAPPING_LABEL_W * width - w
        self.text_soft_drop_y = (self.CONTENTS_H * height - h)/2 + self.CONTENTS_H * height * 5

        self.text_hard_drop_surface = self.contents_font.render(self.HARD_DROP, True, self.LABEL_COLOR)
        w, h = self.contents_font.size(self.HARD_DROP)
        self.text_hard_drop_x = self.KEY_MAPPING_LABEL_W * width - w
        self.text_hard_drop_y = (self.CONTENTS_H * height - h)/2 + self.CONTENTS_H * height * 6

        self.text_hold_surface = self.contents_font.render(self.HOLD, True, self.LABEL_COLOR)
        w, h = self.contents_font.size(self.HOLD)
        self.text_hold_x = self.KEY_MAPPING_LABEL_W * width - w
        self.text_hold_y = (self.CONTENTS_H * height - h)/2 + self.CONTENTS_H * height * 7        


    def init(self):
        self.display_surface = pg.display.set_mode((self.width, self.full_height))

    def update(self):
        self.display_surface.fill(self.BACKGROUND_COLOR)
        self.display_surface.blit(self.text_keymapping_surface,         dest=(self.text_keymapping_x, self.text_keymapping_y))
        self.display_surface.blit(self.text_system_surface,             dest=(self.text_system_x, self.text_system_y))
        self.display_surface.blit(self.text_right_surface,              dest=(self.text_right_x, self.text_right_y))
        self.display_surface.blit(self.text_left_surface,               dest=(self.text_left_x, self.text_left_y))
        self.display_surface.blit(self.text_clockwise_surface,          dest=(self.text_clockwise_x, self.text_clockwise_y))
        self.display_surface.blit(self.text_counterclockwise_surface,   dest=(self.text_counterclockwise_x, self.text_counterclockwise_y))
        self.display_surface.blit(self.text_soft_drop_surface,          dest=(self.text_soft_drop_x, self.text_soft_drop_y))
        self.display_surface.blit(self.text_hard_drop_surface,          dest=(self.text_hard_drop_x, self.text_hard_drop_y))
        self.display_surface.blit(self.text_hold_surface,               dest=(self.text_hold_x, self.text_hold_y))
        pg.display.flip()

 

우선 여기까지 작성하고 main app에 적용하면...

 

적용이 잘 된것을 볼 수 있다.

 

 

하지만 코드를 작성하다보니 너무 지치는데요...왜냐하면 Text를 하나 쓸 때마다 4줄씩 반복을 해야 하기 때문입니다.

 

        ## text setting
        self.text_keymapping_surface = self.title_font.render(self.KEY_MAPPING, True, self.TITLE_COLOR)
        w, h = self.title_font.size(self.KEY_MAPPING)
        self.text_keymapping_x = width/4 - w/2
        self.text_keymapping_y = (self.CONTENTS_H * height - h)/2

이 부분을 한줄 까지는 아니더라도 뭔가 방법이 없을까요?

 


함수로 묶어보기

함수는 다른때에 쓰는게 아닙니다. 바로 이렇게 반복적인 부분을 간편하게 작성할 수 있도록 하기 위해서 작성하는 것입니다.

4줄로 작성된 저 Text를 살펴보면

input은 font, text, color, x좌표, y좌표가 있네요. 그리고 x좌표로부터 right_align인지, center_align인지, left align인지 구분할 수 있습니다. 

즉, 함수는 이렇게 표현될 것입니다.

 

def get_text_info(text: str, 
                  font: pg.font.Font, 
                  color: Tuple[int, int, int], 
                  x_line: Union[int, float], 
                  y_line: Union[int, float], 
                  x_align:str="l",
                  y_align:str="c") -> Tuple[pg.Surface, float, float]:
    surface = font.render(text, True, color)
    w, h = font.size(text)

    x_offset, y_offset = 0, 0   ## align = "l"
    
    if x_align == "r":
        x_offset = w
    elif x_align == "c":
        x_offset = w/2

    if y_align == "r":
        y_offset = h
    elif y_align == "c":
        y_offset = h/2

    return surface, x_line - x_offset, y_line - y_offset

 

이 함수를 적용해서 다시 SubsettingDisplay를 만들어 보겠습니다.

class SubSettingDisplay:
    BACKGROUND_COLOR = (255, 255, 255)
    TITLE_COLOR = (0, 0, 0)
    LABEL_COLOR = (127, 127, 127)
    VALUE_COLOR = (127, 127, 127)
    RECT_LINE = (192, 192, 192)
    SLIDER_LINE = (192, 192, 192)
    SLIDER_TOGGLE = (64, 64, 64)
    KEY_MAPPING = "Key Mapping"
    SYSTEM = "System"
    RIGHT = "Right"
    LEFT = "Left"
    CLOCKWISE_ROTATION = "Clockwise rotation"
    COUNTERCLOCKWISE_ROTATION = "Counterclockwise rotation"
    SOFT_DROP = "Soft drop"
    HARD_DROP = "Hard drop"
    HOLD = "Hold"
    SOUND_VOLUME = "Sound volume"
    PREVIEW_COUNT = "Preview count"
    GHOST_SYSTEM = "Ghost system"
    HOLD_SYSTEM = "Hold system"
    LOCK_DELAY = "Lock delay"
    GRAVITY = "Gravity"
    ARE = "ARE"
    DAS = "DAS"
    ARR = "ARR"
    SDF = "SDF"
    CONTENTS_H = 0.1
    KEY_MAPPING_LABEL_W = 0.3
    SYSTEM_LABEL_W = 0.2

    def __init__(self, width, height):
        self.width, self.height = width, height
        self.full_height = height * 1.2
        self.display_surface = None
        self.title_font = pg.font.SysFont("calibri", 28)
        self.contents_font = pg.font.SysFont("calibri", 16)
         
        self.text_keymapping_surface, self.text_keymapping_x, self.text_keymapping_y = get_text_info(self.KEY_MAPPING, self.title_font, self.TITLE_COLOR, width * 0.25, self.CONTENTS_H * height * 0.5)
        self.text_system_surface, self.text_system_x, self.text_system_y = get_text_info(self.SYSTEM, self.title_font, self.TITLE_COLOR, width * 0.75, self.CONTENTS_H * height * 0.5)
        self.text_right_surface, self.text_right_x, self.text_right_y = get_text_info(self.RIGHT, self.contents_font, self.LABEL_COLOR, self.KEY_MAPPING_LABEL_W * width, self.CONTENTS_H * height * 1.5, "r", "c")
        self.text_left_surface, self.text_left_x, self.text_left_y = get_text_info(self.LEFT, self.contents_font, self.LABEL_COLOR, self.KEY_MAPPING_LABEL_W * width, self.CONTENTS_H * height * 2.5, "r", "c")
        self.text_clockwise_surface, self.text_clockwise_x, self.text_clockwise_y = get_text_info(self.CLOCKWISE_ROTATION, self.contents_font, self.LABEL_COLOR, self.KEY_MAPPING_LABEL_W * width, self.CONTENTS_H * height * 3.5, "r", "c")
        self.text_counterclockwise_surface, self.text_counterclockwise_x, self.text_counterclockwise_y = get_text_info(self.COUNTERCLOCKWISE_ROTATION, self.contents_font, self.LABEL_COLOR, self.KEY_MAPPING_LABEL_W * width, self.CONTENTS_H * height * 4.5, "r", "c")
        self.text_soft_drop_surface, self.text_soft_drop_x, self.text_soft_drop_y = get_text_info(self.SOFT_DROP, self.contents_font, self.LABEL_COLOR, self.KEY_MAPPING_LABEL_W * width, self.CONTENTS_H * height * 5.5, "r", "c")
        self.text_hard_drop_surface, self.text_hard_drop_x, self.text_hard_drop_y = get_text_info(self.HARD_DROP, self.contents_font, self.LABEL_COLOR, self.KEY_MAPPING_LABEL_W * width, self.CONTENTS_H * height * 6.5, "r", "c")
        self.text_hold_surface, self.text_hold_x, self.text_hold_y = get_text_info(self.HOLD, self.contents_font, self.LABEL_COLOR, self.KEY_MAPPING_LABEL_W * width, self.CONTENTS_H * height * 7.5, "r", "c")

    def init(self):
        self.display_surface = pg.display.set_mode((self.width, self.full_height))

    def update(self):
        self.display_surface.fill(self.BACKGROUND_COLOR)
        self.display_surface.blit(self.text_keymapping_surface,         dest=(self.text_keymapping_x, self.text_keymapping_y))
        self.display_surface.blit(self.text_system_surface,             dest=(self.text_system_x, self.text_system_y))
        self.display_surface.blit(self.text_right_surface,              dest=(self.text_right_x, self.text_right_y))
        self.display_surface.blit(self.text_left_surface,               dest=(self.text_left_x, self.text_left_y))
        self.display_surface.blit(self.text_clockwise_surface,          dest=(self.text_clockwise_x, self.text_clockwise_y))
        self.display_surface.blit(self.text_counterclockwise_surface,   dest=(self.text_counterclockwise_x, self.text_counterclockwise_y))
        self.display_surface.blit(self.text_soft_drop_surface,          dest=(self.text_soft_drop_x, self.text_soft_drop_y))
        self.display_surface.blit(self.text_hard_drop_surface,          dest=(self.text_hard_drop_x, self.text_hard_drop_y))
        self.display_surface.blit(self.text_hold_surface,               dest=(self.text_hold_x, self.text_hold_y))
        pg.display.flip()

 

코드가 옆으로 엄청 길어지긴 했지만 그래도 줄 자체는 줄어들었음을 알 수 있습니다.

PEP에 따르면 너무 오른쪽으로 긴 문장은 좀 자제해달라는 부분이 있습니다. (정확히는 79 charactor)

https://peps.python.org/pep-0008/#maximum-line-length

 

PEP 8 – Style Guide for Python Code | peps.python.org

PEP 8 – Style Guide for Python Code Author: Guido van Rossum , Barry Warsaw , Nick Coghlan Status: Active Type: Process Created: 05-Jul-2001 Post-History: 05-Jul-2001, 01-Aug-2013 Table of Contents This document gives coding conventions for the Python co

peps.python.org

 

그래서 코드를 아래와 같이 바꿉니다.

 

class SubSettingDisplay:
    BACKGROUND_COLOR = (255, 255, 255)
    TITLE_COLOR = (0, 0, 0)
    LABEL_COLOR = (127, 127, 127)
    VALUE_COLOR = (127, 127, 127)
    RECT_LINE = (192, 192, 192)
    SLIDER_LINE = (192, 192, 192)
    SLIDER_TOGGLE = (64, 64, 64)
    KEY_MAPPING = "Key Mapping"
    SYSTEM = "System"
    RIGHT = "Right"
    LEFT = "Left"
    CW_ROTATION = "Clockwise rotation"
    CCW_ROTATION = "Counterclockwise rotation"
    SOFT_DROP = "Soft drop"
    HARD_DROP = "Hard drop"
    HOLD = "Hold"
    SOUND_VOLUME = "Sound volume"
    PREVIEW_COUNT = "Preview count"
    GHOST_SYSTEM = "Ghost system"
    HOLD_SYSTEM = "Hold system"
    LOCK_DELAY = "Lock delay"
    GRAVITY = "Gravity"
    ARE = "ARE"
    DAS = "DAS"
    ARR = "ARR"
    SDF = "SDF"
    CONTENTS_H = 0.1
    KEY_MAPPING_LABEL_W = 0.3
    SYSTEM_LABEL_W = 0.2

    def __init__(self, width, height):
        self.width, self.height = width, height
        self.full_height = height * 1.2
        self.display_surface = None
        self.title_font = pg.font.SysFont("calibri", 28)
        self.contents_font = pg.font.SysFont("calibri", 16)
         
        self.text_keymapping_surface, self.text_keymapping_x, self.text_keymapping_y = get_text_info(
            self.KEY_MAPPING, 
            self.title_font, 
            self.TITLE_COLOR,
            width * 0.25, 
            self.CONTENTS_H * height * 0.5)
        self.text_system_surface, self.text_system_x, self.text_system_y = get_text_info(
            self.SYSTEM, 
            self.title_font, 
            self.TITLE_COLOR, width * 0.75, 
            self.CONTENTS_H * height * 0.5)
        self.text_right_surface, self.text_right_x, self.text_right_y = get_text_info(
            self.RIGHT, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 1.5, 
            "r", 
            "c")
        self.text_left_surface, self.text_left_x, self.text_left_y = get_text_info(
            self.LEFT, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 2.5, 
            "r", 
            "c")
        self.text_CW_surface, self.text_CW_x, self.text_CW_y = get_text_info(
            self.CW_ROTATION, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 3.5, 
            "r", 
            "c")
        self.text_CCW_surface, self.text_CCW_x, self.text_CCW_y = get_text_info(
            self.CCW_ROTATION, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 4.5, 
            "r",
            "c")
        self.text_soft_drop_surface, self.text_soft_drop_x, self.text_soft_drop_y = get_text_info(
            self.SOFT_DROP, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 5.5, 
            "r", 
            "c")
        self.text_hard_drop_surface, self.text_hard_drop_x, self.text_hard_drop_y = get_text_info(
            self.HARD_DROP, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 6.5, 
            "r", 
            "c")
        self.text_hold_surface, self.text_hold_x, self.text_hold_y = get_text_info(
            self.HOLD, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 7.5, 
            "r", 
            "c")

    def init(self):
        self.display_surface = pg.display.set_mode((self.width, self.full_height))

    def update(self):
        self.display_surface.fill(self.BACKGROUND_COLOR)
        self.display_surface.blit(self.text_keymapping_surface,         dest=(self.text_keymapping_x, self.text_keymapping_y))
        self.display_surface.blit(self.text_system_surface,             dest=(self.text_system_x, self.text_system_y))
        self.display_surface.blit(self.text_right_surface,              dest=(self.text_right_x, self.text_right_y))
        self.display_surface.blit(self.text_left_surface,               dest=(self.text_left_x, self.text_left_y))
        self.display_surface.blit(self.text_CW_surface,                 dest=(self.text_CW_x, self.text_CW_y))
        self.display_surface.blit(self.text_CCW_surface,                dest=(self.text_CCW_x, self.text_CCW_y))
        self.display_surface.blit(self.text_soft_drop_surface,          dest=(self.text_soft_drop_x, self.text_soft_drop_y))
        self.display_surface.blit(self.text_hard_drop_surface,          dest=(self.text_hard_drop_x, self.text_hard_drop_y))
        self.display_surface.blit(self.text_hold_surface,               dest=(self.text_hold_x, self.text_hold_y))
        pg.display.flip()

 

솔직히, 코드가 생긴게 이쁘다고는 말 못하겠습니다만...여기서 만족하고 넘어가도록 하겠습니다.

 

아직 오른편 System이 작성이 완료 안되었으니, 마무리 합시다.

class SubSettingDisplay:
    BACKGROUND_COLOR = (255, 255, 255)
    TITLE_COLOR = (0, 0, 0)
    LABEL_COLOR = (127, 127, 127)
    VALUE_COLOR = (127, 127, 127)
    RECT_LINE = (192, 192, 192)
    SLIDER_LINE = (192, 192, 192)
    SLIDER_TOGGLE = (64, 64, 64)
    KEY_MAPPING = "Key Mapping"
    SYSTEM = "System"
    RIGHT = "Right"
    LEFT = "Left"
    CW_ROTATION = "Clockwise rotation"
    CCW_ROTATION = "Counterclockwise rotation"
    SOFT_DROP = "Soft drop"
    HARD_DROP = "Hard drop"
    HOLD = "Hold"
    SOUND_VOLUME = "Sound volume"
    PREVIEW_COUNT = "Preview count"
    GHOST_SYSTEM = "Ghost system"
    HOLD_SYSTEM = "Hold system"
    LOCK_DELAY = "Lock delay"
    GRAVITY = "Gravity"
    ARE = "ARE"
    DAS = "DAS"
    ARR = "ARR"
    SDF = "SDF"
    CONTENTS_H = 0.1
    KEY_MAPPING_LABEL_W = 0.3
    SYSTEM_LABEL_W = 0.7

    def __init__(self, width, height):
        self.width, self.height = width, height
        self.full_height = height * 1.2
        self.display_surface = None
        self.title_font = pg.font.SysFont("calibri", 28)
        self.contents_font = pg.font.SysFont("calibri", 16)
         
        self.text_keymapping_surface, self.text_keymapping_x, self.text_keymapping_y = get_text_info(
            self.KEY_MAPPING, 
            self.title_font, 
            self.TITLE_COLOR,
            width * 0.25, 
            self.CONTENTS_H * height * 0.5)
        self.text_system_surface, self.text_system_x, self.text_system_y = get_text_info(
            self.SYSTEM, 
            self.title_font, 
            self.TITLE_COLOR, width * 0.75, 
            self.CONTENTS_H * height * 0.5)
        self.text_right_surface, self.text_right_x, self.text_right_y = get_text_info(
            self.RIGHT, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 1.5, 
            "r", 
            "c")
        self.text_left_surface, self.text_left_x, self.text_left_y = get_text_info(
            self.LEFT, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 2.5, 
            "r", 
            "c")
        self.text_CW_surface, self.text_CW_x, self.text_CW_y = get_text_info(
            self.CW_ROTATION, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 3.5, 
            "r", 
            "c")
        self.text_CCW_surface, self.text_CCW_x, self.text_CCW_y = get_text_info(
            self.CCW_ROTATION, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 4.5, 
            "r",
            "c")
        self.text_soft_drop_surface, self.text_soft_drop_x, self.text_soft_drop_y = get_text_info(
            self.SOFT_DROP, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 5.5, 
            "r", 
            "c")
        self.text_hard_drop_surface, self.text_hard_drop_x, self.text_hard_drop_y = get_text_info(
            self.HARD_DROP, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 6.5, 
            "r", 
            "c")
        self.text_hold_surface, self.text_hold_x, self.text_hold_y = get_text_info(
            self.HOLD, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.KEY_MAPPING_LABEL_W * width, 
            self.CONTENTS_H * height * 7.5, 
            "r", 
            "c")
        self.text_sound_volume_surface, self.text_sound_volume_x, self.text_sound_volume_y = get_text_info(
            self.SOUND_VOLUME, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 1.5, 
            "r", 
            "c")
        self.text_preview_count_surface, self.text_preview_count_volume_x, self.text_preview_count_volume_y = get_text_info(
            self.PREVIEW_COUNT, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 2.5, 
            "r", 
            "c")
        self.text_ghost_system_surface, self.text_ghost_system_x, self.text_ghost_system_y = get_text_info(
            self.GHOST_SYSTEM, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 3.5, 
            "r", 
            "c")
        self.text_hold_system_surface, self.text_hold_system_x, self.text_hold_system_y = get_text_info(
            self.HOLD_SYSTEM, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 4.5, 
            "r", 
            "c")
        self.text_lock_delay_surface, self.text_lock_delay_x, self.text_lock_delay_y = get_text_info(
            self.LOCK_DELAY, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 5.5, 
            "r", 
            "c")
        self.text_gravity_surface, self.text_gravity_x, self.text_gravity_y = get_text_info(
            self.GRAVITY, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 6.5, 
            "r", 
            "c")
        self.text_ARE_surface, self.text_ARE_x, self.text_ARE_y = get_text_info(
            self.ARE, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 7.5, 
            "r", 
            "c")
        self.text_DAS_surface, self.text_DAS_x, self.text_DAS_y = get_text_info(
            self.DAS, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 8.5, 
            "r", 
            "c")
        self.text_ARR_surface, self.text_ARR_x, self.text_ARR_y = get_text_info(
            self.ARR, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 9.5, 
            "r", 
            "c")
        self.text_SDF_surface, self.text_SDF_x, self.text_SDF_y = get_text_info(
            self.SDF, 
            self.contents_font, 
            self.LABEL_COLOR, 
            self.SYSTEM_LABEL_W * width, 
            self.CONTENTS_H * height * 10.5, 
            "r", 
            "c")

    def init(self):
        self.display_surface = pg.display.set_mode((self.width, self.full_height))

    def update(self):
        self.display_surface.fill(self.BACKGROUND_COLOR)
        self.display_surface.blit(self.text_keymapping_surface,        dest=(self.text_keymapping_x, self.text_keymapping_y))
        self.display_surface.blit(self.text_system_surface,            dest=(self.text_system_x, self.text_system_y))
        self.display_surface.blit(self.text_right_surface,             dest=(self.text_right_x, self.text_right_y))
        self.display_surface.blit(self.text_left_surface,              dest=(self.text_left_x, self.text_left_y))
        self.display_surface.blit(self.text_CW_surface,                dest=(self.text_CW_x, self.text_CW_y))
        self.display_surface.blit(self.text_CCW_surface,               dest=(self.text_CCW_x, self.text_CCW_y))
        self.display_surface.blit(self.text_soft_drop_surface,         dest=(self.text_soft_drop_x, self.text_soft_drop_y))
        self.display_surface.blit(self.text_hard_drop_surface,         dest=(self.text_hard_drop_x, self.text_hard_drop_y))
        self.display_surface.blit(self.text_sound_volume_surface,      dest=(self.text_sound_volume_x, self.text_sound_volume_y))
        self.display_surface.blit(self.text_preview_count_surface,     dest=(self.text_preview_count_volume_x, self.text_preview_count_volume_y))
        self.display_surface.blit(self.text_ghost_system_surface,      dest=(self.text_ghost_system_x, self.text_ghost_system_y))
        self.display_surface.blit(self.text_hold_system_surface,       dest=(self.text_hold_system_x, self.text_hold_system_y))
        self.display_surface.blit(self.text_lock_delay_surface,        dest=(self.text_lock_delay_x, self.text_lock_delay_y))
        self.display_surface.blit(self.text_gravity_surface,           dest=(self.text_gravity_x, self.text_gravity_y))
        self.display_surface.blit(self.text_ARE_surface,               dest=(self.text_ARE_x, self.text_ARE_y))
        self.display_surface.blit(self.text_DAS_surface,               dest=(self.text_DAS_x, self.text_DAS_y))
        self.display_surface.blit(self.text_ARR_surface,               dest=(self.text_ARR_x, self.text_ARR_y))
        self.display_surface.blit(self.text_SDF_surface,               dest=(self.text_SDF_x, self.text_SDF_y))
        pg.display.flip()

 

결과물이 잘 나왔다.

이제 각 label 옆에 rect와 slide bar, 그리고 checkbox를 달아주면 됩니다.

 

다음시간에 진행해보도록 하겠습니다

 

 


*reference

https://peps.python.org/pep-0008/#maximum-line-length