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
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
.