Saving high scores in pygame

。_饼干妹妹 提交于 2019-12-11 03:47:32

问题


I know this is a lot of code but I really need help making it so as long as a user keeps playing (not getting to a sys.quit) the high score saves and can be shown with the highscore func. Ive been working for hours and cant figure this part out. Please and sorry for so much code. Also open to any ways to make it run better or smoother.

import pygame, sys, random
from time import *
from pygame import *
from pygame.locals import *
scores=[]
name=[]
def playagain():
    print "Would you like to play again?"
    global playername
    choice=raw_input("Or do you want to see the current high scores: ")
    choice1=choice.lower()
    if choice=='yes' or choice=='y':
        playername=raw_input('Name:  ')
        main_loop(random.randint(3.0,6.0))
    elif choice=='high scores' or choice=='hs':
        highscores()
    elif choice=='no' or choice=='n' or choice=='goodbye' or choice=='bye' or choice=='exit' or choice=='quit':
        pygame.quit()
        sys.exit()       
def highscores():
    pygame.init()
    windowSurface = pygame.display.set_mode((500, 400), 0, 32)
    pygame.display.set_caption('Tic-toc!')
    WHITE = (255, 255, 255)
    BLUE = (0, 0, 255)
    RED=(255, 0, 0)
    GREEN=(0,255,0)
    basicFont = pygame.font.SysFont(None, 48)    
    global finaltime
    global scores
    global name
    global playername
    font = pygame.font.Font(None, 35)  # load the default font, size 50
    color = (255, 50, 0)
    if finaltime<=.01:
        finaltime=0.00
        scores.append(str(finaltime))
    else:
        scores.append(str(finaltime+.01))
    name.append(str(playername))            
    for i in range(len(scores)):
        score = scores[i]
        name= name[i]
        nameimage = font.render(name, True, color)
        namerect = nameimage.get_rect()
        namerect.left, namerect.y = 40, 100 + (i*(namerect.height + 20))
        windowSurface.blit(nameimage,namerect)
        scoreimage = font.render(score, True, color)
        scorerect = scoreimage.get_rect()
        scorerect.right, scorerect.y = 480, namerect.y
        windowSurface.blit(scoreimage, scorerect)
        for d in range(namerect.right + 25, scorerect.left-10, 25):
            pygame.draw.rect(scoreimage, color, pygame.Rect(d, scorerect.centery, 5, 5))
    pygame.display.update()
    sleep(7)
    pygame.quit()
    playagain()
def main_loop(timer):
    global playername
    playername=raw_input('Name:  ')
    global finaltime
    pygame.init()
    windowSurface = pygame.display.set_mode((500, 400), 0, 32)
    pygame.display.set_caption('Tic-toc!')
    WHITE = (255, 255, 255)
    BLUE = (0, 0, 255)
    RED=(255, 0, 0)
    GREEN=(0,255,0)
    basicFont = pygame.font.SysFont(None, 48)
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        timer-=.01
        if timer<=0.0099:
            timernew=0.00
            timer=0.00
            textnew=basicFont.render('0.00', True, WHITE, RED)
            textRectnew = textnew.get_rect()
            textRectnew.centerx = windowSurface.get_rect().centerx
            textRectnew.centery = windowSurface.get_rect().centery
            windowSurface.blit(textnew, textRect)
            pygame.display.update()
            break
        button1,button2,button3=pygame.mouse.get_pressed()
        text = basicFont.render(str(timer), True, WHITE, BLUE)
        textRect = text.get_rect()
        textRect.centerx = windowSurface.get_rect().centerx
        textRect.centery = windowSurface.get_rect().centery
        x,y=pygame.mouse.get_pos()
        if (x > textRect.left) and (x < textRect.right) and (y > textRect.top) and (y < textRect.bottom) and button1==1:
            text=basicFont.render(str(timer), True, WHITE, BLUE)
            finaltime=timer
            break
        sleep(.01)
        windowSurface.blit(text, textRect)
        pygame.display.update()
    pygame.quit()
    playagain()
    return
main_loop(random.randint(3.0,6.0))

回答1:


I did some simple modifications to your code. Have a look at the comments I added. This should give you a good starting point.

import pygame, sys, random

from time import *
from pygame import *
from pygame.locals import *

# define colors at top level of the script
WHITE = (255, 255, 255)
BLUE  = (0  ,   0, 255)
RED   = (255,   0,   0)
GREEN = (0  , 255,   0)

# keep track of highscores
scores = []

def get_window_and_font():
    """Returns a tuple of a font and the surface of a newly created window"""
    pygame.init()
    pygame.display.set_caption('Tic-toc!')
    return pygame.font.SysFont(None, 48), pygame.display.set_mode((500, 400), 0, 32)

def playagain():
    """Returns if the player wants to play again"""
    print "Would you like to (p)lay again or (n)ot?"
    choice = raw_input("Or do you want to see the current (h)igh scores: ").lower()
    # use 'in' to check choices of fewer code
    if choice in ('yes', 'y', 'p', 'play', 'again'):
        return True
    elif choice in ('high scores', 'hs', 'h'):
        highscores()
        return True
    elif choice in ('no', 'n', 'goodbye', 'bye', 'exit', 'quit'):
        return False
    else:
        playagain()

def highscores():
    basicFont, windowSurface = get_window_and_font()

    # use enumerate to get the index of the sorted elements in our highscores
    # highscores are sorted by score, descending
    for i, (name, score) in enumerate(sorted(scores, key=lambda x: -x[1])):
        # use list comprehension to create a nice color effect in highscore :-)
        color = tuple([max(0, 255-i*x) for x in (15, 25, 40)])
        nameimage = basicFont.render(name, True, color)
        namerect = nameimage.get_rect()
        namerect.left, namerect.y = 40, 10 + (i*(namerect.height + 10))
        windowSurface.blit(nameimage,namerect)
        scoreimage = basicFont.render(str(score), True, color)
        scorerect = scoreimage.get_rect()
        scorerect.right, scorerect.y = 480, namerect.y
        windowSurface.blit(scoreimage, scorerect)
        for d in range(namerect.right + 25, scorerect.left-10, 25):
            pygame.draw.rect(scoreimage, color, pygame.Rect(d, scorerect.centery, 5, 5))

    pygame.display.update()
    # just check for MOUSEBUTTONUP and QUIT, using the filter argument of .get()
    while not any(pygame.event.get((MOUSEBUTTONUP, QUIT))):
        sleep(0.1)
    pygame.quit()

def play_game():
    """this function handles a round of the game and returns the playername and his score"""
    timer = random.randint(3.0,6.0)
    playername = raw_input('Name:  ')
    finaltime = 0
    basicFont, windowSurface = get_window_and_font()
    # keep running while no QUIT event is in the queue
    while not any(pygame.event.get(QUIT)):
        # clear the screen every tick
        windowSurface.fill((0,0,0))
        timer -= .01
        if timer <= 0.0099:
            textnew  = basicFont.render('0.00', True, WHITE, RED)
            textRectnew = textnew.get_rect()
            textRectnew.centerx = windowSurface.get_rect().centerx
            textRectnew.centery = windowSurface.get_rect().centery
            windowSurface.blit(textnew, textRect)
            pygame.display.update()
            break

        # we are only interested in button1, so discard the rest
        button1, _, _ = pygame.mouse.get_pressed()
        text = basicFont.render(str(timer), True, WHITE, BLUE)
        textRect = text.get_rect()
        textRect.centerx = windowSurface.get_rect().centerx
        textRect.centery = windowSurface.get_rect().centery

        # use collidepoint to check if mouse is above the rect
        # you could also use the MOUSEBUTTONUP event instead of mouse.get_pos()
        if button1 == 1 and textRect.collidepoint(pygame.mouse.get_pos()):
            text = basicFont.render(str(timer), True, WHITE, BLUE)
            finaltime = timer
            break

        sleep(.01)
        windowSurface.blit(text, textRect)
        pygame.display.update()

    pygame.quit()

    return playername, finaltime

def main():
    keep_playing = True
    while keep_playing:
        # play_game returns the playername and his score
        # store that in our highscore list
        scores.append((play_game()))
        # keep playing if the player wants to
        keep_playing = playagain()

# good habit to use the __name__ magic variable
if __name__ == '__main__':
    main()

You don't need global at all.

I think it is a little bit strange to close and reopen windows to switch between pygame and CLI, but I keeped that part of your code intact while moving the relevant code to its own function get_window_and_font.

You probably want to divide your game into different scenes later, like title screen, name entry screen, gameplay screen and highscore screen, but this beyond the scope of this answer.



来源:https://stackoverflow.com/questions/13984582/saving-high-scores-in-pygame

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!