-2

So I have created my first game and I want to track the high score with shelve. My logic is that I have a global variable called highscore. At the beginning of the game in game_menu() it is assigned the value that is in the highscore file. The logic is that if the current score (dodged) is greater than highscore, then the highscore file gets assigned the value of dodged and that is displayed in the game menu. This does work for the most part, but even if the dodged variable is smaller than highscore, it still gets assigned to the file. It's like the game is not seeing the If statement. Below is the important part of code of the game.

d = shelve.open("highscore.txt")
highscore = d["highscore"]
d.close()

best_score(highscore)

Above, we have assign to the global variable the value inside the file and display via best_score

if dodged > highscore:
    d = shelve.open("highscore.txt")
    d["highscore"] = dodged
    d.close

This is where I think the problem is. It clearly says if dodged is bigger, but even if it's equal or smaller the file gets replaced with the dodged variable. I even tried putting in ifesle, but nothing works.

Below is full code of game as requested

import pygame
import time
import random
import shelve

pygame.init()

display_width = 800
display_height = 600

black = (0,0,0)
red = (255,0,0)
dark_red = (200,0,0)
green = (0,255,0)
dark_green = (0,200,0)

awing_width = 95

gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("Lonely ship")
clock = pygame.time.Clock()

background = pygame.image.load("space.jpg")

awingImg = pygame.image.load("A-wing.png")
awingImg = pygame.transform.scale(awingImg, (95,119))

asteroidImg  = pygame.image.load("AsteroidPNG.png")
asteroidImg = pygame.transform.scale(asteroidImg, (100,100))

def score(score):
    scoreFont = pygame.font.Font("freesansbold.ttf", 30)
    text = scoreFont.render("Dodged: "+str(score), True, red)
    gameDisplay.blit(text, (10,10))

def best_score(best_score):
    scoreFont = pygame.font.Font("freesansbold.ttf", 30)
    text = scoreFont.render("Highscore: "+str(best_score), True, red)
    gameDisplay.blit(text, (10,10))

def asteroid(asteroidx, asteroidy, asteroidw, asteroidh):
    gameDisplay.blit(asteroidImg, (asteroidx, asteroidy, asteroidw, asteroidh))

def awing(x,y):
    gameDisplay.blit(awingImg, (x,y))

def text_objects(text, font):
    textSurface = font.render(text, True, red)
    return textSurface, textSurface.get_rect()

def button_text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()

def message_display(text):
    largeText = pygame.font.Font("freesansbold.ttf", 50)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((display_width/2), (display_height/2))
    gameDisplay.blit(TextSurf, TextRect)
    pygame.display.update()
    time.sleep(2)
    pygame.event.clear()
    game_menu()

def outOfBounds():
    message_display("You flew out of bounds!")

def crash():
    message_display("You crashed!")

def win():
    message_display("YOU WIN!!!")

def button(message,x,y,w,h,dc,bc,action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    if x+w > mouse[0] > x and y+h > mouse [1] > y:
        pygame.draw.rect(gameDisplay, bc, (x,y,w,h))
        if click[0] == 1 and action != None:
            if action == "play":
                game_loop()
            elif action == "quit":
                pygame.quit()
                quit()
    else:     
        pygame.draw.rect(gameDisplay, dc, (x,y,w,h))

    smallText = pygame.font.Font("freesansbold.ttf", 20)
    textSurf, textRect = button_text_objects(message, smallText)
    textRect.center = ( (x+(w/2)), (y+(h/2)) )
    gameDisplay.blit(textSurf, textRect)

global highscore

def game_menu():

    intro = True

    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()


        gameDisplay.blit(background, (0,0))


        d = shelve.open("highscore.txt")
        highscore = d["highscore"]
        d.close()

        best_score(highscore)

        largeText = pygame.font.Font("freesansbold.ttf", 50)
        TextSurf, TextRect = text_objects("Lonely Ship", largeText)
        TextRect.center = ((display_width/2), (display_height/2))
        gameDisplay.blit(TextSurf, TextRect)

        button("Play", 200, 400, 100, 50, dark_green,green, "play")
        button("Quit", 500, 400, 100, 50, dark_red,red, "quit")


        pygame.display.update()
        clock.tick(15)

def game_loop():
    x = (display_width * 0.425)
    y = (display_height * 0.75)

    x_change = 0

    asteroid_startx = random.randrange(0, display_width)
    asteroid_starty = -600
    asteroid_speed = 5
    asteroid_width = 100
    asteroid_height = 100

    dodged = 0
    gameExit = False

    while not gameExit:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x_change += -10
                elif event.key == pygame.K_RIGHT:
                    x_change += 10

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:   
                    x_change += 10
                elif event.key == pygame.K_RIGHT:
                    x_change += -10

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    game_menu()

        x += x_change


        gameDisplay.blit(background, (0,0))

        asteroid(asteroid_startx, asteroid_starty, asteroid_width, asteroid_height)
        asteroid_starty += asteroid_speed
        awing(x,y)
        score(dodged)

        if x > display_width - awing_width or x < 0:
            outOfBounds()

        if asteroid_starty > display_height:
           asteroid_starty = 0 - asteroid_height
           asteroid_startx = random.randrange(0, display_width)
           dodged += 1
           asteroid_speed += 0.5

        if dodged > highscore:
           d = shelve.open("highscore.txt")
           d["highscore"] = dodged
           d.close



        if y < asteroid_starty + asteroid_height:
            print("y crossover")

            if x > asteroid_startx and x < asteroid_startx + asteroid_width or x + awing_width > asteroid_startx and x + awing_width < asteroid_startx + asteroid_width:
                print("x crossover")
                crash()

            if dodged >= 50:
               d = shelve.open("highscore.txt")
               d["highscore"] = 0
               d.close
               win()

        pygame.display.update()
        clock.tick(60)

game_menu()
game_loop()
pygame.quit()
quit()
Sawbonz
  • 7
  • 3
  • 2
    Please [edit] the question to show what the format of your `highscore.txt` file looks like. – Martin Evans Mar 06 '18 at 10:04
  • It is impossible to say what is going on with just few lines of code. please at least post the whole game_menu function block (or where the problem is happening) – roschach Mar 06 '18 at 10:06
  • where did you get the `dodged` variable from??? edit your question and write a correct code... is you highscore a string or a int to compare... I do not understand ?? – Jai Mar 06 '18 at 10:08
  • is the `d.close` the actual code or a copy-paste error ? – polku Mar 06 '18 at 10:10
  • Ok I see I defined highscore twice once as a global variable and once in the gameloop. That is probably why, now that i removed the highscore in gameloop it says that it has not been defined even thought it is as a global variable – Sawbonz Mar 06 '18 at 11:33

1 Answers1

1

I think what happens is you're comparing number to string. The number is always smaller as described here, if you're using python 2.x. If you're using 3.x, then this would raise an error.

0 > '0' // false

Thus what you need to do is cast the highscore to int:

highscore = int(d["highscore"])

Or, the other way around - dodged being a string, because in the case where highscore is a string, you'll never go inside the if.

Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100