11
\$\begingroup\$

I made a tower-defense game in Python with Pygame called "Bunny and Badgers". You're a bunny and must kill the badgers before they come into the castles. You can use W, A, S, D and the arrow keys to move around and press a mouse button to shoot. You can also use a joystick to control it. The game dures 1 minute and 30 seconds (or shorter if you're dead). When a badger came into a castle, the health will be increased.

The project is also on Github.

I mainly want to improve the speed. And I want to remove the hacky way of using settings.py (by using ConfigParser?). So, how can I improve my code?

Screenshot:

Screenshot

main.py

#!/usr/bin/env python2
import menu

# Launch menu
menu.launch()

menu.py

#!/usr/bin/env python2
# Import libraries
try:
    import pygame_sdl2
    pygame_sdl2.import_as_pygame()
    import pygame, sys, singleplayer, settings, jstest
    from pygame.locals import *
except:
    import pygame, sys, singleplayer, settings, jstest
    from pygame.locals import *

def launch():
    # Initialize pygame
    pygame.init()
    # Initialize the pygame font module
    pygame.font.init()
    
    # Set the width and height of the window
    width, height = int(pygame.display.Info().current_w), int(pygame.display.Info().current_h)
    # Create the window
    screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)
    # Set title
    pygame.display.set_caption("Bunny and Badgers")
    
    # Initialize the joystick module
    pygame.joystick.init()
    # Check if there are any joysticks
    joystick_count = pygame.joystick.get_count()
    # If there are any joysticks, initialize the first one, else quit the joystick module
    if joystick_count:
        joystick = pygame.joystick.Joystick(0)
        joystick.init()
        JS = True
    else:
        pygame.joystick.quit()
        JS = False
    
    # Set choice
    choice = 1
    Schoice = 1
    MorS = "main"
    # Set 1/12 height
    height12 = height/12
    
    # Load images
    # Load the background image
    grass = pygame.image.load("resources/images/grass.png")

    # Set display mode
    prevFS = settings.getFullscreen()
    if settings.getFullscreen() == True:
        screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN)
    elif settings.getFullscreen() == False:
        screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)

    
    # Keep looping through
    while True:
        # Set display mode if changed
        if prevFS != settings.getFullscreen():
            if settings.getFullscreen() == True:
                screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN)
                prevFS = settings.getFullscreen()
            elif settings.getFullscreen() == False:
                screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)
                prevFS = settings.getFullscreen()

        # Set joystick buttons, if there are any
        if JS:
            buttonUP = joystick.get_button(4)
            buttonDOWN = joystick.get_button(6)
            buttonX = joystick.get_button(14)
        # Clear the screen before drawing it again
        screen.fill(0)
        # Draw the background
        for x in range(width/grass.get_width()+1):
            for y in range(height/grass.get_height()+1):
                screen.blit(grass,(x*200,y*200))
    
        # Loop through the events
        for event in pygame.event.get():
            # Check if the event is the X button 
            if event.type == pygame.QUIT:
                # If it is quit the game
                pygame.quit()
                sys.exit()
            # Check if pressed on a text                
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mpos = pygame.mouse.get_pos()
                if MorS == "main":
                    if spRect.collidepoint(mpos):
                        singleplayer.play()
                    elif stRect.collidepoint(mpos):
                        MorS = "settings"
                    elif xtRect.collidepoint(mpos):
                        pygame.quit()
                        sys.exit()
                elif MorS == "settings":
                    if fsRect.collidepoint(mpos):
                        settings.changeFullscreen()
                    elif jsRect.collidepoint(mpos):
                        jstest.launch()
                    elif bcRect.collidepoint(mpos):
                        MorS = "main"
            # Check if a key is pressed
            elif event.type == pygame.KEYDOWN:
                # Check if arrow down is pressed
                if event.key == K_DOWN:
                    if MorS == "main":
                        if choice == 1:
                            choice = 2
                        elif choice == 2:
                            choice = 3
                        elif choice == 3:
                            choice = 1
                    elif MorS == "settings":
                        if Schoice == 1:
                            Schoice = 2
                        elif Schoice == 2:
                            Schoice = 3
                        elif Schoice == 3:
                            Schoice = 1
                # Check if arrow up is pressed
                elif event.key == K_UP:
                    if MorS == "main":
                        if choice == 1:
                            choice = 3
                        elif choice == 2:
                            choice = 1
                        elif choice == 3:
                            choice = 2
                    elif MorS == "settings":
                        if Schoice == 1:
                            Schoice = 3
                        elif Schoice == 2:
                            Schoice = 1
                        elif Schoice == 3:
                            Schoice = 2
                # Check if return is pressed
                elif event.key == K_RETURN:
                    if MorS == "main":
                        if choice == 1:
                            singleplayer.play()
                        elif choice == 2:
                            MorS = "settings"
                        elif choice == 3:
                            pygame.quit()
                            sys.exit()
                    elif MorS == "settings":
                        if Schoice == 1:
                            settings.changeFullscreen()
                        elif Schoice == 2:
                            jstest.launch()
                        elif Schoice == 3:
                            MorS = "main"
                # Quit by pressing escape
                elif event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                # Fullscreen by pressing F4
                elif event.key == K_F4:
                    settings.changeFullscreen()
            # Check if there are any joysticks
            if JS:
                # Check if UP is pressed
                if buttonUP:
                    if choice == 1:
                        choice = 3
                    elif choice == 2:
                        choice = 1
                    elif choice == 3:
                        choice = 2
                # Check if DOWN is pressed
                elif buttonDOWN:
                    if choice == 1:
                        choice = 2
                    elif choice == 2:
                        choice = 3
                    elif choice == 3:
                        choice = 1
                # Check if X is pressed
                elif buttonX:
                    if choice == 1:
                        singleplayer.play()
                    elif choice == 2:
                        MorS = "settings"
                    elif choice == 3:
                        pygame.quit()
                        sys.exit()
    
        # Set font
        font = pygame.font.Font("freesansbold.ttf", 24)
        bigfont = pygame.font.Font("freesansbold.ttf", 48)
    
        if MorS == "main":
            # Check for cursor
            if choice == 1:
                spText = "-- Single Player --"
                stText = "Settings"
                xtText = "Exit"
            elif choice == 2:
                spText = "Single Player"
                stText = "-- Settings --"
                xtText = "Exit"
            elif choice == 3:
                spText = "Single Player"
                stText = "Settings"
                xtText = "-- Exit --"
    
            # Render text
            # Render title text
            title = bigfont.render("Bunny and Badgers", True, (0,0,0))
            titleRect = title.get_rect()
            titleRect.centerx = screen.get_rect().centerx
            titleRect.centery = height12*2
            # Render single player text
            sp = font.render(spText, True, (0,0,0))
            spRect = sp.get_rect()
            spRect.centerx = screen.get_rect().centerx
            spRect.centery = height12*5
            # Render settings text
            st = font.render(stText, True, (0,0,0))
            stRect = st.get_rect()
            stRect.centerx = screen.get_rect().centerx
            stRect.centery = height12*6
            # Render exit text
            xt = font.render(xtText, True, (0,0,0))
            xtRect = xt.get_rect()
            xtRect.centerx = screen.get_rect().centerx
            xtRect.centery = height12*7
    
            # Draw text
            screen.blit(title, titleRect)
            screen.blit(sp, spRect)
            screen.blit(st, stRect)
            screen.blit(xt, xtRect)

        elif MorS == "settings":
            # Check for cursor
            if Schoice == 1:
                fsText = "-- Fullscreen: " + str(settings.getFullscreen()) + " --"
                jsText = "Test joystick"
                bcText = "Back"
            elif Schoice == 2:
                fsText = "Fullscreen: " + str(settings.getFullscreen())
                jsText = "-- Test joystick --"
                bcText = "Back"
            elif Schoice == 3:
                fsText = "Fullscreen: " + str(settings.getFullscreen())
                jsText = "Test joystick"
                bcText = "-- Back --"

            # Render text
            # Render title text
            title = bigfont.render("Bunny and Badgers", True, (0,0,0))
            titleRect = title.get_rect()
            titleRect.centerx = screen.get_rect().centerx
            titleRect.centery = height12*2
            # Render fullscreen text
            fs = font.render(fsText, True, (0,0,0))
            fsRect = fs.get_rect()
            fsRect.centerx = screen.get_rect().centerx
            fsRect.centery = height12*5
            # Render joystick text
            js = font.render(jsText, True, (0,0,0))
            jsRect = js.get_rect()
            jsRect.centerx = screen.get_rect().centerx
            jsRect.centery = height12*6
            # Render back text
            bc = font.render(bcText, True, (0,0,0))
            bcRect = bc.get_rect()
            bcRect.centerx = screen.get_rect().centerx
            bcRect.centery = height12*7

            # Draw text
            screen.blit(title, titleRect)
            screen.blit(fs, fsRect)
            screen.blit(js, jsRect)
            screen.blit(bc, bcRect)
    
        # Flip the display
        pygame.display.flip()

jstest.py

#!/usr/bin/env python2
# Import pygame
try:
    import pygame_sdl2
    pygame_sdl2.import_as_pygame()
    import pygame, menu, settings
    from pygame.locals import *
except:
   import pygame, menu, settings
   from pygame.locals import *

# Define some colors
BLACK    = (   0,   0,   0)
WHITE    = ( 255, 255, 255)

# This is a simple class that will help us print to the screen
# It has nothing to do with the joysticks, just outputing the
# information.
class TextPrint:
    def __init__(self):
        self.reset()
        self.font = pygame.font.Font(None, 20)

    def Print(self, screen, textString):
        textBitmap = self.font.render(textString, True, BLACK)
        screen.blit(textBitmap, [self.x, self.y])
        self.y += self.line_height
        
    def reset(self):
        self.x = 10
        self.y = 10
        self.line_height = 15
        
    def indent(self):
        self.x += 10
        
    def unindent(self):
        self.x -= 10

def launch():
    # Initialize pygame
    pygame.init()

    # Set the width and height of the window
    width, height = pygame.display.Info().current_w, pygame.display.Info().current_h

    # Create the window
    screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF) 

    # Set the window title
    pygame.display.set_caption("JoyStick Testing Module")

    #Loop until the user clicks the close button.
    done = False

    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()

    # Initialize the joysticks
    pygame.joystick.init()
    
    # Get ready to print
    textPrint = TextPrint()

    # Set display mode
    prevFS = settings.getFullscreen()
    if settings.getFullscreen() == True:
        screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN)
    elif settings.getFullscreen() == False:
        screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)

    # -------- Main Program Loop -----------
    while True:
        # Set display mode if changed
        if prevFS != settings.getFullscreen():
            if settings.getFullscreen() == True:
                screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN)
                prevFS = settings.getFullscreen()
            elif settings.getFullscreen() == False:
                screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)
                prevFS = settings.getFullscreen()


        # EVENT PROCESSING STEP
        for event in pygame.event.get(): # User did something
            # Check if the event is the X button 
            if event.type == pygame.QUIT:
                # If it is go back to the main menu
                menu.launch()
            # Check if a key is pressed
            elif event.type == pygame.KEYDOWN:
                # If pressed esc go back to the menu
                if event.key == K_ESCAPE:
                    menu.launch()
        
            # Possible joystick actions: JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION
            if event.type == pygame.JOYBUTTONDOWN:
                print("Joystick button pressed.")
            if event.type == pygame.JOYBUTTONUP:
                print("Joystick button released.")
            
 
        # DRAWING STEP
        # First, clear the screen to white. Don't put other drawing commands
        # above this, or they will be erased with this command.
        screen.fill(WHITE)
        textPrint.reset()

        # Get count of joysticks
        joystick_count = pygame.joystick.get_count()

        textPrint.Print(screen, "Number of joysticks: {}".format(joystick_count) )
        textPrint.indent()
    
        # For each joystick:
        for i in range(joystick_count):
            joystick = pygame.joystick.Joystick(i)
            joystick.init()

            textPrint.Print(screen, "Joystick {}".format(i) )
            textPrint.indent()
    
            # Get the name from the OS for the controller/joystick
            name = joystick.get_name()
            textPrint.Print(screen, "Joystick name: {}".format(name) )
        
            # Usually axis run in pairs, up/down for one, and left/right for
            # the other.
            axes = joystick.get_numaxes()
            textPrint.Print(screen, "Number of axes: {}".format(axes) )
            textPrint.indent()
        
            for i in range( axes ):
                axis = joystick.get_axis( i )
                textPrint.Print(screen, "Axis {} value: {:>6.3f}".format(i, axis) )
            textPrint.unindent()
            
            buttons = joystick.get_numbuttons()
            textPrint.Print(screen, "Number of buttons: {}".format(buttons) )
            textPrint.indent()

            for i in range( buttons ):
                button = joystick.get_button( i )
                textPrint.Print(screen, "Button {:>2} value: {}".format(i,button) )
            textPrint.unindent()
            
            # Hat switch. All or nothing for direction, not like joysticks.
            # Value comes back in an array.
            hats = joystick.get_numhats()
            textPrint.Print(screen, "Number of hats: {}".format(hats) )
            textPrint.indent()

            for i in range( hats ):
                hat = joystick.get_hat( i )
                textPrint.Print(screen, "Hat {} value: {}".format(i, str(hat)) )
            textPrint.unindent()
        
            textPrint.unindent()

    
        # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
    
        # Go ahead and update the screen with what we've drawn.
        pygame.display.flip()

        # Limit to 20 frames per second
        clock.tick(20)

singleplayer.py

#!/usr/bin/env python2
# Import libraries
try:
    import pygame_sdl2
    pygame_sdl2.import_as_pygame()
    import pygame, sys, singleplayer, settings, jstest
    from pygame.locals import *
except:
    import pygame, sys, singleplayer, settings, jstest
    from pygame.locals import *

def launch():
    # Initialize pygame
    pygame.init()
    # Initialize the pygame font module
    pygame.font.init()
    
    # Set the width and height of the window
    width, height = int(pygame.display.Info().current_w), int(pygame.display.Info().current_h)
    # Create the window
    screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)
    # Set title
    pygame.display.set_caption("Bunny and Badgers")
    
    # Initialize the joystick module
    pygame.joystick.init()
    # Check if there are any joysticks
    joystick_count = pygame.joystick.get_count()
    # If there are any joysticks, initialize the first one, else quit the joystick module
    if joystick_count:
        joystick = pygame.joystick.Joystick(0)
        joystick.init()
        JS = True
    else:
        pygame.joystick.quit()
        JS = False
    
    # Set choice
    choice = 1
    Schoice = 1
    MorS = "main"
    # Set 1/12 height
    height12 = height/12
    
    # Load images
    # Load the background image
    grass = pygame.image.load("resources/images/grass.png")

    # Set display mode
    prevFS = settings.getFullscreen()
    if settings.getFullscreen() == True:
        screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN)
    elif settings.getFullscreen() == False:
        screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)

    
    # Keep looping through
    while True:
        # Set display mode if changed
        if prevFS != settings.getFullscreen():
            if settings.getFullscreen() == True:
                screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN)
                prevFS = settings.getFullscreen()
            elif settings.getFullscreen() == False:
                screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)
                prevFS = settings.getFullscreen()

        # Set joystick buttons, if there are any
        if JS:
            buttonUP = joystick.get_button(4)
            buttonDOWN = joystick.get_button(6)
            buttonX = joystick.get_button(14)
        # Clear the screen before drawing it again
        screen.fill(0)
        # Draw the background
        for x in range(width/grass.get_width()+1):
            for y in range(height/grass.get_height()+1):
                screen.blit(grass,(x*200,y*200))
    
        # Loop through the events
        for event in pygame.event.get():
            # Check if the event is the X button 
            if event.type == pygame.QUIT:
                # If it is quit the game
                pygame.quit()
                sys.exit()
            # Check if pressed on a text                
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mpos = pygame.mouse.get_pos()
                if MorS == "main":
                    if spRect.collidepoint(mpos):
                        singleplayer.play()
                    elif stRect.collidepoint(mpos):
                        MorS = "settings"
                    elif xtRect.collidepoint(mpos):
                        pygame.quit()
                        sys.exit()
                elif MorS == "settings":
                    if fsRect.collidepoint(mpos):
                        settings.changeFullscreen()
                    elif jsRect.collidepoint(mpos):
                        jstest.launch()
                    elif bcRect.collidepoint(mpos):
                        MorS = "main"
            # Check if a key is pressed
            elif event.type == pygame.KEYDOWN:
                # Check if arrow down is pressed
                if event.key == K_DOWN:
                    if MorS == "main":
                        if choice == 1:
                            choice = 2
                        elif choice == 2:
                            choice = 3
                        elif choice == 3:
                            choice = 1
                    elif MorS == "settings":
                        if Schoice == 1:
                            Schoice = 2
                        elif Schoice == 2:
                            Schoice = 3
                        elif Schoice == 3:
                            Schoice = 1
                # Check if arrow up is pressed
                elif event.key == K_UP:
                    if MorS == "main":
                        if choice == 1:
                            choice = 3
                        elif choice == 2:
                            choice = 1
                        elif choice == 3:
                            choice = 2
                    elif MorS == "settings":
                        if Schoice == 1:
                            Schoice = 3
                        elif Schoice == 2:
                            Schoice = 1
                        elif Schoice == 3:
                            Schoice = 2
                # Check if return is pressed
                elif event.key == K_RETURN:
                    if MorS == "main":
                        if choice == 1:
                            singleplayer.play()
                        elif choice == 2:
                            MorS = "settings"
                        elif choice == 3:
                            pygame.quit()
                            sys.exit()
                    elif MorS == "settings":
                        if Schoice == 1:
                            settings.changeFullscreen()
                        elif Schoice == 2:
                            jstest.launch()
                        elif Schoice == 3:
                            MorS = "main"
                # Quit by pressing escape
                elif event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                # Fullscreen by pressing F4
                elif event.key == K_F4:
                    settings.changeFullscreen()
            # Check if there are any joysticks
            if JS:
                # Check if UP is pressed
                if buttonUP:
                    if choice == 1:
                        choice = 3
                    elif choice == 2:
                        choice = 1
                    elif choice == 3:
                        choice = 2
                # Check if DOWN is pressed
                elif buttonDOWN:
                    if choice == 1:
                        choice = 2
                    elif choice == 2:
                        choice = 3
                    elif choice == 3:
                        choice = 1
                # Check if X is pressed
                elif buttonX:
                    if choice == 1:
                        singleplayer.play()
                    elif choice == 2:
                        MorS = "settings"
                    elif choice == 3:
                        pygame.quit()
                        sys.exit()
    
        # Set font
        font = pygame.font.Font("freesansbold.ttf", 24)
        bigfont = pygame.font.Font("freesansbold.ttf", 48)
    
        if MorS == "main":
            # Check for cursor
            if choice == 1:
                spText = "-- Single Player --"
                stText = "Settings"
                xtText = "Exit"
            elif choice == 2:
                spText = "Single Player"
                stText = "-- Settings --"
                xtText = "Exit"
            elif choice == 3:
                spText = "Single Player"
                stText = "Settings"
                xtText = "-- Exit --"
    
            # Render text
            # Render title text
            title = bigfont.render("Bunny and Badgers", True, (0,0,0))
            titleRect = title.get_rect()
            titleRect.centerx = screen.get_rect().centerx
            titleRect.centery = height12*2
            # Render single player text
            sp = font.render(spText, True, (0,0,0))
            spRect = sp.get_rect()
            spRect.centerx = screen.get_rect().centerx
            spRect.centery = height12*5
            # Render settings text
            st = font.render(stText, True, (0,0,0))
            stRect = st.get_rect()
            stRect.centerx = screen.get_rect().centerx
            stRect.centery = height12*6
            # Render exit text
            xt = font.render(xtText, True, (0,0,0))
            xtRect = xt.get_rect()
            xtRect.centerx = screen.get_rect().centerx
            xtRect.centery = height12*7
    
            # Draw text
            screen.blit(title, titleRect)
            screen.blit(sp, spRect)
            screen.blit(st, stRect)
            screen.blit(xt, xtRect)

        elif MorS == "settings":
            # Check for cursor
            if Schoice == 1:
                fsText = "-- Fullscreen: " + str(settings.getFullscreen()) + " --"
                jsText = "Test joystick"
                bcText = "Back"
            elif Schoice == 2:
                fsText = "Fullscreen: " + str(settings.getFullscreen())
                jsText = "-- Test joystick --"
                bcText = "Back"
            elif Schoice == 3:
                fsText = "Fullscreen: " + str(settings.getFullscreen())
                jsText = "Test joystick"
                bcText = "-- Back --"

            # Render text
            # Render title text
            title = bigfont.render("Bunny and Badgers", True, (0,0,0))
            titleRect = title.get_rect()
            titleRect.centerx = screen.get_rect().centerx
            titleRect.centery = height12*2
            # Render fullscreen text
            fs = font.render(fsText, True, (0,0,0))
            fsRect = fs.get_rect()
            fsRect.centerx = screen.get_rect().centerx
            fsRect.centery = height12*5
            # Render joystick text
            js = font.render(jsText, True, (0,0,0))
            jsRect = js.get_rect()
            jsRect.centerx = screen.get_rect().centerx
            jsRect.centery = height12*6
            # Render back text
            bc = font.render(bcText, True, (0,0,0))
            bcRect = bc.get_rect()
            bcRect.centerx = screen.get_rect().centerx
            bcRect.centery = height12*7

            # Draw text
            screen.blit(title, titleRect)
            screen.blit(fs, fsRect)
            screen.blit(js, jsRect)
            screen.blit(bc, bcRect)
    
        # Flip the display
        pygame.display.flip()

settings.py

#!/usr/bin/env python2
# Import libraries
from os import remove as remove
from os import system as execute
from os import name as system

def getFullscreen():
    # Open file
    f = open("settings.txt", "r+")
    fl = list(f)

    # Check if fullscreen is True or False
    if fl[0] == "fullscreen=True\n":
        return True
    elif fl[0] == "fullscreen=False\n":
        return False

    # Close the file
    f.close()

def changeFullscreen():
    # Open file
    f = open("settings.txt", "r+")
    fl = list(f)

    # Check if fullscreen is True or False
    if fl[0] == "fullscreen=True\n":
        fs = True
    elif fl[0] == "fullscreen=False\n":
        fs = False

    # Close the file
    f.close()

    # Remove the file
    remove("settings.txt")

    # Make a new file
    if system == "nt":
        execute("type NUL > settings.txt")
    elif system == "posix":
        execute("touch settings.txt")
    nf = open("settings.txt", "r+")

    # Change fullscreen
    if fs:
        nf.write("fullscreen=False\n")
    elif not fs:
        nf.write("fullscreen=True\n")

    # Close the new file
    nf.close()
\$\endgroup\$
6
  • 6
    \$\begingroup\$ You have provided a whole lot of code here but not much explanation about what the "Bunny and Badgers" game is. I suggest adding some more description about the game and maybe a screenshot of how it looks. \$\endgroup\$ Sep 6 '15 at 10:18
  • 1
    \$\begingroup\$ @SimonForsberg It's a tower defense game and I added a screenshot. \$\endgroup\$
    – wb9688
    Sep 6 '15 at 10:30
  • \$\begingroup\$ For future reference write the description so that people glancing over your program can immediately know exactly what each and every part of the program does without having to decode anything. A bit of advice here would be to not only post the code for every part of the program but also a description of what the code does and how you hope it could be improved. \$\endgroup\$
    – Zenohm
    Sep 6 '15 at 17:46
  • \$\begingroup\$ You use a lot of abbreviations in your code, which is fine except that some of them are not all that clear. Take MorS for example (or even Schoice), while it may be very clear to you that you meant main_or_settings it won't be immediately clear to someone else reading the code. If you're going to name things using abbreviations make sure that their meanings are completely clear. Don't sacrifice clarity for convenience, it'll bite you in the long run. \$\endgroup\$
    – Zenohm
    Sep 6 '15 at 18:27
  • \$\begingroup\$ @wb9688 One question. Did you make the description you have on here before or after you made it in the readme? \$\endgroup\$
    – Zenohm
    Sep 6 '15 at 19:33
2
\$\begingroup\$

I may have missed some bits and pieces, but the idea here is to give you a starting point so you can look at your own code and decide what is good, and what needs to be changed

menu.py

 if settings.getFullscreen() == True:
    screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN)
elif settings.getFullscreen() == False:
    screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)

This is equivalent to

if settings.getFullScreen():
else:

Here there is really similar code

if prevFS != settings.getFullscreen():
    if settings.getFullscreen() == True:
        screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN)
        prevFS = settings.getFullscreen()
    elif settings.getFullscreen() == False:
        screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)
        prevFS = settings.getFullscreen()

I would suggest making a function to actually change to and from fullscreen, so you don't have to worry about changing anywhere near as much code later.


if JS:
    buttonUP = joystick.get_button(4)
    buttonDOWN = joystick.get_button(6)
    buttonX = joystick.get_button(14)

Does this need to be done every single iteration through the loop?


if event.type == pygame.QUIT:
    # If it is quit the game
    pygame.quit()
    sys.exit()

This is another good place for a function


if choice == 1:
    choice = 2
elif choice == 2:
    choice = 3
elif choice == 3:
    choice = 1

I recommend the % operator, it will save you a lot of lines, and make it more obvious that this is a cyclic menu

choice == (previous_choice + 1) % number_of_choices

if choice == 1:
            spText = "-- Single Player --"
            stText = "Settings"
            xtText = "Exit"
        elif choice == 2:
            spText = "Single Player"
            stText = "-- Settings --"
            xtText = "Exit"
        elif choice == 3:
            spText = "Single Player"
            stText = "Settings"
            xtText = "-- Exit --"

Rather than a number of variables, a list would be a good way of storing this data. You can then just add "--" around which ever item you need to. Text = ["Single Player", "Settings", "Exit"]

Text[choice] ="--" + Text[choice] + "--"

or something to that effect


        sp = font.render(spText, True, (0,0,0))
        spRect = sp.get_rect()
        spRect.centerx = screen.get_rect().centerx
        spRect.centery = height12*5
        # Render settings text
        st = font.render(stText, True, (0,0,0))
        stRect = st.get_rect()
        stRect.centerx = screen.get_rect().centerx
        stRect.centery = height12*6
        # Render exit text
        xt = font.render(xtText, True, (0,0,0))
        xtRect = xt.get_rect()
        xtRect.centerx = screen.get_rect().centerx
        xtRect.centery = height12*7

You can make this more modular, and just iterate over the list

for i in xrange(Text):
    renderName(Text[i], i+5) //menu_name and height

singleplayer.py

A lot of this code looks identical to menu.py, I'm not sure it is needed


settings.py

def changeFullscreen():
    # Open file
    f = open("settings.txt", "r+")
    fl = list(f)

    # Check if fullscreen is True or False
    if fl[0] == "fullscreen=True\n":
        fs = True
    elif fl[0] == "fullscreen=False\n":
        fs = False

    # Close the file
    f.close()

You could remove all this, and just call the function you already have implemented

def changeFullscreen():
    fs = getFullScreen()
\$\endgroup\$
2
  • \$\begingroup\$ The joystick code needs to be executed every loop because it returns the current state of the button \$\endgroup\$
    – wb9688
    Sep 10 '15 at 18:57
  • \$\begingroup\$ @wb9688 Imagine if the game was running, and suddenly it became really really slow. You have a memory leak, or you are doing something really intensive. If someone were to press a button, as in down and up while that was happening, you would actually miss that input. Since there is no buffer or interrupt on button press, if the game lags you lose input. This wouldn't be a problem if you can guarantee that you can make it through an iteration in less time than it takes for a button to be pressed, every single time. Can you? \$\endgroup\$
    – spyr03
    Sep 10 '15 at 19:22
2
\$\begingroup\$

This not a full review.

Your functions are too long for my taste. I try to keep my functions to at most 10-15 lines. Breaking your code in smaller functions is some type of documentation which improves readability.

You have a lot of

                    if choice == 1:
                        choice = 2
                    elif choice == 2:
                        choice = 3
                    elif choice == 3:
                        choice = 1

with all other types of conditions mixed in. It makes for a very hard read. There are probably ways you can "fix" that, which will probably involve using more and shorter functions.

if settings.getFullscreen() == True:
elif settings.getFullscreen() == False:

is just

if settings.getFullscreen():
else:
\$\endgroup\$
1
\$\begingroup\$

Use convert_alpha() on your images to improve the speed. Like this:

player = pygame.image.load("resources/images/dude.png").convert_alpha()

And set the max fps to 30 with a clock object:

# By init
clock = pygame.time.Clock()
# In the main loop
clock.tick(30)
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Why? What is improved? \$\endgroup\$
    – Caridorc
    Sep 6 '15 at 18:51
  • \$\begingroup\$ @Caridorc mainly the speed \$\endgroup\$
    – wb9688
    Sep 7 '15 at 12:50
  • 2
    \$\begingroup\$ Valid point, but you should add that to your answer \$\endgroup\$
    – Caridorc
    Sep 7 '15 at 13:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.