Make a rect object scrollable

Viewed 107

I am drawing a chess move log onto a rect object - however after a certain point the text goes off of the bottom and gets cut off. I was wondering if its possible to make the rect surface scroll able so I can see the whole move log.

Here is the code for drawing the move log :

This is what I mean

As you can see after the 21st move - the log goes off the bottom of the move log area

def drawMoveLog(screen, gs, font): #draws move log
    moveLogArea = p.Rect(BOARD_WIDTH, 0, MOVE_LOG_PANEL_WIDTH, MOVE_LOG_PANEL_HEIGHT)
    p.draw.rect(screen , p.Color("gray"), moveLogArea)
    moveLog = gs.moveLog
    moveText = []
    for i in range(0, len(moveLog), 2): #go through move log 2 at a time
        moveString = "|| " + str(i//2 + 1) + ". " + str(moveLog[i]) + " "# to keep move 2 and 2 the same
        if i + 1 < len(moveLog): # before i continue want to make sure black moved
            moveString += str(moveLog[i + 1]) + " "
        moveText.append(moveString)

    movesPerRow = 1
    padding = 5
    lineSpacing = 4
    textY = padding
    #make 3 moves go in 1 line
    for i in range(0, len(moveText), movesPerRow):
        text = ""
        for j in range (movesPerRow):
            if i + j < len(moveText):
                text += moveText[i+j]
        textObject = font.render(text, True, p.Color('Black'))
        textLocation = moveLogArea.move(padding, textY)
        screen.blit(textObject, textLocation)
        textY += textObject.get_height() + lineSpacing

1 Answers

Create a function that renders the text in a transparent pygame.Surface high enough to contain the full text. To create a transparent Surface object you have to set the flag pygame.SRCALPHA:

def createMoveLog(gs, font): #draws move log
    moveLog = gs.moveLog
    moveText = []
    for i in range(0, len(moveLog), 2): #go through move log 2 at a time
        moveString = "|| " + str(i//2 + 1) + ". " + str(moveLog[i]) + " "# to keep move 2 and 2 the same
        if i + 1 < len(moveLog): # before i continue want to make sure black moved
            moveString += str(moveLog[i + 1]) + " "
        moveText.append(moveString)

    movesPerRow = 1
    padding = 5
    lineSpacing = 4
    no_of_lines = (len(moveText)+movesPerRow-1) // movesPerRow
    line_height = font.get_height() + lineSpacing 
    text_size = (MOVE_LOG_PANEL_WIDTH, no_of_lines * line_height + 2*padding)
    text_surface = p.Surface(text_size, p.SRCALPHA)

    textY = padding
    #make 3 moves go in 1 line
    for i in range(0, len(moveText), movesPerRow):
        text = ""
        for j in range (movesPerRow):
            if i + j < len(moveText):
                text += moveText[i+j]
        textObject = font.render(text, True, p.Color('Black'))
        text_surface.blit(textObject, (0, textY))
        textY += textObject.get_height() + lineSpacing

    return text_surface

Render the full text and use pygame.Surface.subsurface to create a new surface that references a rectangular area with the height MOVE_LOG_PANEL_HEIGHT.
The scroll argument is a value in the range [0.0, 1.0] and is used to scroll the text linearly. When the scrolling is 0.0, the top of the text is displayed, and when the scrolling is 1.0, the bottom of the text is displayed:

def drawMoveLog(screen, gs, font, scroll): #draws move log
    moveLogArea = p.Rect(BOARD_WIDTH, 0, MOVE_LOG_PANEL_WIDTH, MOVE_LOG_PANEL_HEIGHT)
    p.draw.rect(screen , p.Color("gray"), moveLogArea)

    text_surface = createMoveLog(gs, font)
    dy = text_surface.get_height() - MOVE_LOG_PANEL_HEIGHT
    if dy > 0:
        text_offset = int(dy * scroll) 
        test_rect = text_surface.get_rect()
        sub_rect = p.Rect(0, text_offset, MOVE_LOG_PANEL_WIDTH, MOVE_LOG_PANEL_HEIGHT)
        sub_text_surface = text_surface.subsurface(sub_rect)
        screen.blit(sub_text_surface, moveLogArea)

    else:
        screen.blit(text_surface, moveLogArea)

Compare the rendering of

moveLog = ["d3", "Nh6", "e3", "Rg8", "f3", "b6", "g3", "a5", "h3", "Ra6", "c3", "g6", "b3", "a4"]

with scroll = 0.0 and scroll = 1.0.

Related