Python Forum
[pygame] Improvement with code
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[pygame] Improvement with code
#1
There are no problems with my code but I wanted someone to skim through it and tell me if there is anything I should improve. The multiple function from Utils is to return multiples of a number and isEven is to check if a number is even. The game is not close to being complete but I wanted to make sure to improve any areas before continuing. One more thing to keep in mind is that some of the functions and code may be incomplete, so don't worry about that. Thx in advance!
import pygame, random, os, sys, threading, time
from functools import partial
from pathlib import Path
from DestinationFunc import Screen_Display as SD, Button as BT, TextBox as TB
from Utils import multiple, isEven, Save, Load

pygame.init()

width = 800
height = 800
fps = 60

Screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()

#Loading pictures into dictionary
PD = {}
for picture in os.listdir(os.path.join(Path(__file__).parent, 'Destination Pics')):
    if picture != 'Thumbs.db':
        PD.update({picture.split('.')[0] : pygame.image.load(os.path.join(Path(__file__).parent, 'Destination Pics', picture)).convert()})

#References
picRef = {'WoodenBat' : (PD['WoodenBat'], PD['WoodenBatRight'], PD['WoodenBatDown'], PD['WoodenBatLeft']),
          'WoodenArmor' : (PD['WoodArmorUp'], PD['WoodArmorRight'], PD['WoodArmor'], PD['WoodArmorLeft']),
          'Player' : (PD['PlayerUp'], PD['PlayerRight'], PD['Player'], PD['PlayerLeft'])}

itemStats = {'WoodenBat' : 1, 'WoodenArmor' : 1}

#Map layout
#v = vacant, w = wall
maplayout = ['w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'v', 'w',
             'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w',
             ]

#Long Dict of maps
#Same key to def as stageSetup
#w = wall
#(object, (row, column))
MapDict = {1 : {1 : (('w', (7, 7)), ('w', (8, 8)), ('w', (7, 8)), ('w', (8, 7))), 2 : (), 3 : ()},
           2 : {1 : (), 2 : (), 3 : ()}
           }

UserData = {}
#UserData = {'Sheepposu' : {'password': 'Rachl032078', 'exp': 0, 'stage': None, 'floor': 0, 'player' : Player()}}

#Player class
class Player():
    def __init__(self, weapon, armor, damage, defense, agility, health, username, password):
        self.username = username
        self.password = password
        self.rect = pygame.Rect(700, 700, 50, 50)
        self.weapon = weapon
        self.armor = armor
        self.damage = damage
        self.defense = defense
        self.agility = agility
        self.health = health
        self.direction = 'up'
        self.movingList = []
        self.identifier = 'player'

    def draw(self):
        ref = {'up' : 0, 'right' : 1, 'down' : 2, 'left' : 3}
        Screen.blit(picRef['Player'][ref[self.direction]], (self.rect[0], self.rect[1]))
    

    def move(self):
        keyed = pygame.key.get_pressed()
        movingDict = {pygame.K_a : (0, '-', 'left'), pygame.K_d : (0, '+', 'right'),
                      pygame.K_w : (1, '-', 'up'), pygame.K_s : (1, '+', 'down'),
                      pygame.K_LEFT : (0, '-', 'left'), pygame.K_RIGHT : (0, '+', 'right'),
                      pygame.K_UP : (1, '-', 'up'), pygame.K_DOWN : (1, '+', 'down')
                      }
        adjacentMovesDict = {pygame.K_a : pygame.K_LEFT, pygame.K_d : pygame.K_RIGHT,
                             pygame.K_s : pygame.K_DOWN, pygame.K_w : pygame.K_UP,
                             pygame.K_LEFT : pygame.K_a, pygame.K_RIGHT : pygame.K_d,
                             pygame.K_UP : pygame.K_w, pygame.K_DOWN : pygame.K_s
                             }
        for key in movingDict:
            if keyed[key]:
                data = movingDict[key]
                self.rect[data[0]] = eval(str(self.rect[data[0]]) + data[1] + '1' + data[1] + str(round(self.agility / 2)))
                self.direction = data[2]
                if data[2] not in self.movingList:
                    self.movingList.append(data[2])
            elif not keyed[adjacentMovesDict[key]]:
                try:
                    self.movingList.remove(movingDict[key][2])
                except:
                    pass

    def forceMove(self, xChange, yChange):
        self.rect[0] += xChange
        self.rect[1] += yChange

    def teleport(self, x, y):
        self.rect[0] = x
        self.rect[1] = y

#Enemy Class
class Enemy():
    def __init__(self, spawn, weapon, armor, damage, defense, agility, health, ID=''):
        self.rect = list(spawn)
        self.mapCoords = (spawn[0] / 80, spawn[1] / 80)
        self.weapon = weapon
        self.armor = aut
        if floor != 0:
            for tup in MapDict[self.floor][self.stage]:
                obj = tup[0]
                row = tup[1][0]
                column = tup[1][1] * 16
                area[row + column] = obj
        self.map = area
        self.obst = []
        bx = 0
        by = 0
        multiples = multiple(16, 16)
        for coord in self.map:
            if coord == 'w':
                x = bx * 50
                y = by * 50
                self.obst.append(Wall((x, y, 50, 50)))
            bx += 1
            if bx in multiples:
                bx = 0
                by += 1
        self.obst.append(Stair((50, 50, 50, 50), 'up'))
        if not tut:
            if self.stage != 1 or self.floor != 1:
                self.obst.append(Stair((700, 700, 50, 50), 'down'))
        self.map[17] = 'l'
        self.map[238] = 'l'

    def draw(self):
        Screen.fill(self.background)
        for obst in self.obst:
            obst.draw()

    def printMap(self):
        List = []
        count = 0
        for letter in self.map:
            count += 1
            List.append(letter)
            if count in multiple(16, 16):
                print(List)
                List = []

#Floor for first key, dictionary of stages for definition and list of enemies for stage definitions
GameLayout = {1 : {1 : Stage(1, 1, (20, 20, 225)), 2 : Stage(1, 2, (20, 225, 20)), 3 : Stage(1, 3, (225, 20, 20))},
              2 : {2 : Stage(2, 1, (20, 225, 20)), 2 : Stage(2, 2, (225, 20, 20)), 3 : Stage(2, 3, (20, 225, 20))}}

#Sign in function
def SignIn():
    #Intro
    sizeVar = 1
    OrganizationTup = (((205, 0, 0), 405, 295), ((215, 0, 0), 404, 296), ((225, 0, 0), 403, 297),
                       ((235, 0, 0), 402, 298), ((245, 0, 0), 401, 299), ((255, 0, 0), 400, 300))
    while sizeVar < 120:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        sizeVar += 1
        Screen.fill((0, 0, 255))
        for x in OrganizationTup:
            SD.message_display(Screen, 'Destination', sizeVar, x[0], x[1], x[2])
        pygame.display.update()
        clock.tick(fps)

    while True:
        #Login
        username = TB((200, 500, 400, 100), 'Type Username', 40, (0, 0, 255))
        password = TB((200, 650, 400, 100), 'Type Password', 40, (0, 0, 255))
        login = BT((650, 550, 100, 50), 'Log In', 30, (0, 0, 255))
        Signup = BT((650, 650, 100, 50), 'Sign Up', 30, (0, 0, 255))
        done = False
        signup = False
        while not done and not signup:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            username.start(Screen, (255, 0, 0), 18)
            password.start(Screen, (255, 0, 0), 18)
            done = login.start(Screen, (255, 0, 0), (200, 0, 0))
            signup = Signup.start(Screen, (255, 0, 0), (200, 0, 0))
            pygame.display.update()
            clock.tick(fps)

        #Verification
        UserName = username.text
        PassWord = password.text
        time.sleep(0.2)
        if signup:
            while True:
                Login = False
                done = False
                username = TB((200, 500, 400, 100), 'Type New Username', 40, (0, 0, 255))
                password = TB((200, 650, 400, 100), 'Type New Password', 40, (0, 0, 255))
                while not done and not Login:
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            pygame.quit()
                            sys.exit()
                    username.start(Screen, (255, 0, 0), 18)
                    password.start(Screen, (255, 0, 0), 18)
                    Login = login.start(Screen, (255, 0, 0), (200, 0, 0))
                    done = Signup.start(Screen, (255, 0, 0), (200, 0, 0))
                    pygame.display.update()
                    clock.tick(fps)
                UserName = username.text
                PassWord = password.text
                if Login:
                    return False
                else:
                    time.sleep(0.2)
                    if UserName != '':
                        valid = True
                        for user in UserData:
                            if user.lower() == UserName.lower():
                                valid = False
                        if not valid:
                            pygame.draw.rect(Screen, (0, 0, 255), (0, 350, 800, 50))
                            SD.message_display(Screen, 'Username already taken', 40, (255, 0, 0), 400, 450)
                            
                        elif PassWord != '':
                            pygame.draw.rect(Screen, (0, 0, 255), (0, 350, 800, 50))
                            SD.message_display(Screen, f'Successfully created account under {UserName}!', 40, (255, 0, 0), 400, 450)
                            NewPlayer = Player(item('WoodenBat'), item('WoodenArmor'), 1, 1, 1, 5, UserName, PassWord)
                            UserData.update({UserName : {'password' : PassWord, 'exp': 0, 'stage' : None, 'floor' : 0, 'player' : NewPlayer}})
                            Save(UserData)
                            return UserName

                        else:
                            pygame.draw.rect(Screen, (0, 0, 255), (0, 350, 800, 50))
                            SD.message_display(Screen, 'Invalid Password', 40, (255, 0, 0), 400, 450)
                            
                    else:
                        pygame.draw.rect(Screen, (0, 0, 255), (0, 350, 800, 50))
                        SD.message_display(Screen, 'Invalid Username', 40, (255, 0, 0), 400, 450)
                        time.sleep(0.2)
                        
                            
                        
        else:
            invalid = False
            valid = False
            for user in UserData:
                if UserName.lower() == user.lower():
                    invalid = False
                    valid = True
                    if PassWord == UserData[user]['password']:
                        return user
                    else:
                        pygame.draw.rect(Screen, (0, 0, 255), (0, 390, 800, 100))
                        SD.message_display(Screen, 'Invalid Password', 40, (255, 0, 0), 400, 450)
                        done = False
                else:
                    if not valid:
                        invalid = True
            if invalid:
                pygame.draw.rect(Screen, (0, 0, 255), (0, 390, 800, 100))
                SD.message_display(Screen, 'Invalid Username', 40, (255, 0, 0), 400, 450)
                done = False

def notification(text, textColor, bg):
    pygame.draw.rect(Screen, (0, 0, 255), (0, 0, 800, 75))
    SD.message_display(Screen, text, 25, textColor, 400, 50)
    pygame.display.update()
    time.sleep(5) #This function is used w/ threading so the sleep doesn't affect the GUI
    pygame.draw.rect(Screen, (0, 0, 255), (0, 0, 800, 75))
    pygame.display.update()
    
def LevelSetup(username, direction):
    if direction == 'up':
        if UserData[username]['stage'].stage == len(MapDict[UserData[username]['floor']]):
            UserData[username]['floor'] += 1
            UserData[username]['stage'] = GameLayout[UserData[username]['floor']][1]
        else:
            UserData[username]['stage'] = GameLayout[UserData[username]['floor']][UserData[username]['stage'].stage + 1]
    else:
        if UserData[username]['stage'].stage == 1:
            UserData[username]['floor'] -= 1
            UserData[username]['stage'] = GameLayout[UserData[username]['floor']][len(GameLayout[UserData[username]['floor']])]
        else:
            UserData[username]['stage'] = GameLayout[UserData[username]['floor']][UserData[username]['stage'].stage - 1]


def LevelRun(username):
    UD = UserData[username]
    stage = UD['stage']
    plr = UD['player']
    playing = True
    direction = None
    print('New Level')
    print(stage.stage)
    while playing:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
        stage.draw()
        for enemy in stage.enemies:
            enemy.draw()
            enemy.move(plr)
            collide(enemy, stage.obst)
        plr.draw()
        plr.move()
        playing, direction = collide(plr, stage.obst)
        pygame.display.update()
        clock.tick(fps)
    UserData[username]['player'] = plr
    LevelSetup(username, direction)
    return True

def collide(plr, obstacle):
    for obst in obstacle:
        if obst.rect.colliderect(plr.rect):
            if obst.type == 'Stairup' and plr.identifier != 'enemy':
                print('Up')
                plr.forceMove(700 - plr.rect[0], 650 - plr.rect[1] - 25)
                return False, 'up'
            elif obst.type == 'Stairdown' and plr.identifier != 'enemy':
                print('Down')
                plr.teleport(50, 125)
                return False, 'down'
            if 'right' in plr.movingList or 'left' in plr.movingList:
                if isEven(plr.rect[0] - obst.rect[0]):
                    xChange = 1 + round(plr.agility / 2)
                else:
                    xChange = (1 + round(plr.agility / 2)) * -1
                plr.forceMove(xChange, 0)
            if 'up' in plr.movingList or 'down' in plr.movingList:
                if isEven(plr.rect[1] - obst.rect[1]):
                    yChange = 1 + round(plr.agility / 2)
                else:
                    yChange = (1 + round(plr.agility / 2)) * -1
                plr.forceMove(0, yChange)
    return True, None

def BackRange(last, first):
    count = last + 1
    output = []
    for x in range(0, last - first):
        count -= 1
        output.append(count)
    return output

def LevelCheck(exp):
    levelRef = {1 : 0, 2 : 100, 3 : 225, 4 : 540, 5 : 915, 6 : 1420, 7 : 1975, 8 : 2640, 9 : 3980, 10 : 5035}
    count = len(levelRef) - 1
    for x in BackRange(len(levelRef) - 1, -1):
        if exp >= levelRef[x]:
            return x

def tutorial(username):
    stage = Stage(0, 0, (30, 240, 30), True)
    plr = UserData[username]['player']
    playing = True
    direction = None
    while playing:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
        stage.draw()
        for enemy in stage.enemies:
            enemy.draw()
            enemy.move(plr)
            collide(enemy, stage.obst)
        plr.draw()
        plr.move()
        playing, direction = collide(plr, stage.obst)
        pygame.display.update()
        clock.tick(fps)
    UserData[username]['stage'] = GameLayout[1][1]
    UserData[username]['floor'] = 1
    return True


def main(start=False):
    if start:
        username = False
        while not username:
            username = SignIn()
    UD = UserData[username]
    if UD['stage'] == None:
        if not tutorial(username):
            return False
    while True:
        if not LevelRun(username):
            return
        if UserData[username]['floor'] == len(stageSetup) and UserData[username]['stage'].stage == len(stageSetup[len(stageSetup)]):
            EndGame('Yay!')
            break

def EndGame(death=True):
    if death is None:
        #Died!
        pass

    else:
        #Beat Game!
        pass

    wait = time.time()
    while time.time() - wait < 5:
        pygame.display.update()

if __name__ == '__main__':
    main(True)
    pygame.quit()
    sys.exit()rmor
        self.damage = damage
        self.defense = defense
        self.agility = agility
        self.health = health
        self.direction = 'down'
        self.name = 'Enemy' + str(ID)
        self.identifier = 'enemy'
        self.debounce = False
        self.movingList = []

    def draw(self):
        DirectionToPic = {'up' : self.name + 'Down', 'right' : self.name + 'Left', 'down' : self.name, 'left' : self.name + 'Right'}
        Screen.blit(PD[DirectionToPic[self.direction]], (self.rect[0], self.rect[1]))

    def move(self, plr):
        self.movingList = []
        x = 0
        y = 0
        if self.debounce:
            if self.rect[0] - plr.rect[0] != 0:
                if isEven(self.rect[0] - plr.rect[0]):
                    x = -1
                    self.direction = 'right'
                else:
                    x = 1
                    self.direction = 'left'
                self.movingList.append(self.direction)
            if self.rect[1] - plr.rect[1] != 0:
                if isEven(self.rect[1] - plr.rect[1]):
                    y = -1
                    self.direction = 'down'
                else:
                    y = 1
                    self.direction = 'up'
                self.movingList.append(self.direction)
            self.rect[0] += x + round(self.agility / 2)
            self.rect[1] += y + round(self.agility / 2)
            self.debounce = False
        else:
            self.debounce = True

    def forceMove(self, xChange, yChange):
        self.rect[0] += xChange
        self.rect[1] += yChange

class item():
    def __init__(self, weapon):
        self.weapon = weapon

#Floor for first key, dictionary of stages for definition and list of enemies for stage definitions
stageSetup = {1 : {1 : [Enemy((325, 50, 50, 50), picRef['WoodenBat'], picRef['WoodenArmor'], 1, 0, 0, 1)],
                   2 : [],
                   3 : []},
              2 : {1 : [],
                   2 : [],
                   3 : []},
              3 : {1 : [],
                   2 : [],
                   3 : []}}

#Obstacles
class Wall():
    def __init__(self, rect):
        self.rect = pygame.Rect(rect)
        self.type = 'Wall'
        
    def draw(self):
        Screen.blit(PD['Wall'], (self.rect[0], self.rect[1]))

class SavePoint():
    def __init__(self, rect):
        self.rect = pygame.Rect(rect)
        self.type = 'SavePoint'

    def draw(self):
        Screen.blit(PD['SavePoint'], (self.rect[0], self.rect[1]))

class Stair():
    def __init__(self, rect, direction):
        self.rect = pygame.Rect(rect)
        self.direction = direction
        self.type = 'Stair' + direction

    def draw(self):
        if self.direction == 'up':
            Screen.blit(PD['StairsUp'], (self.rect[0], self.rect[1]))
        else:
            Screen.blit(PD['StairsDown'], (self.rect[0], self.rect[1]))

#Creating a class of stage allows me to save it and it's attributes when the player leaves
class Stage():
    def __init__(self, floor, stage, background, tut=False):
        if not tut:
            self.enemies = stageSetup[floor][stage]
        else:
            self.enemies = [Enemy((325, 50, 50, 50), 'WoodenBat', 'WoodenArmor', 1, 1, 1, 1)]
        self.background = background
        self.floor = floor
        self.stage = stage
        area = maplayout
        if floor != 0:
            for tup in MapDict[self.floor][self.stage]:
                obj = tup[0]
                row = tup[1][0]
                column = tup[1][1] * 16
                area[row + column] = obj
        self.map = area
        self.obst = []
        bx = 0
        by = 0
        multiples = multiple(16, 16)
        for coord in self.map:
            if coord == 'w':
                x = bx * 50
                y = by * 50
                self.obst.append(Wall((x, y, 50, 50)))
            bx += 1
            if bx in multiples:
                bx = 0
                by += 1
        self.obst.append(Stair((50, 50, 50, 50), 'up'))
        if not tut:
            if self.stage != 1 or self.floor != 1:
                self.obst.append(Stair((700, 700, 50, 50), 'down'))
        self.map[17] = 'l'
        self.map[238] = 'l'

    def draw(self):
        Screen.fill(self.background)
        for obst in self.obst:
            obst.draw()

    def printMap(self):
        List = []
        count = 0
        for letter in self.map:
            count += 1
            List.append(letter)
            if count in multiple(16, 16):
                print(List)
                List = []

#Floor for first key, dictionary of stages for definition and list of enemies for stage definitions
GameLayout = {1 : {1 : Stage(1, 1, (20, 20, 225)), 2 : Stage(1, 2, (20, 225, 20)), 3 : Stage(1, 3, (225, 20, 20))},
              2 : {2 : Stage(2, 1, (20, 225, 20)), 2 : Stage(2, 2, (225, 20, 20)), 3 : Stage(2, 3, (20, 225, 20))}}

#Sign in function
def SignIn():
    #Intro
    sizeVar = 1
    OrganizationTup = (((205, 0, 0), 405, 295), ((215, 0, 0), 404, 296), ((225, 0, 0), 403, 297),
                       ((235, 0, 0), 402, 298), ((245, 0, 0), 401, 299), ((255, 0, 0), 400, 300))
    while sizeVar < 120:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        sizeVar += 1
        Screen.fill((0, 0, 255))
        for x in OrganizationTup:
            SD.message_display(Screen, 'Destination', sizeVar, x[0], x[1], x[2])
        pygame.display.update()
        clock.tick(fps)

    while True:
        #Login
        username = TB((200, 500, 400, 100), 'Type Username', 40, (0, 0, 255))
        password = TB((200, 650, 400, 100), 'Type Password', 40, (0, 0, 255))
        login = BT((650, 550, 100, 50), 'Log In', 30, (0, 0, 255))
        Signup = BT((650, 650, 100, 50), 'Sign Up', 30, (0, 0, 255))
        done = False
        signup = False
        while not done and not signup:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            username.start(Screen, (255, 0, 0), 18)
            password.start(Screen, (255, 0, 0), 18)
            done = login.start(Screen, (255, 0, 0), (200, 0, 0))
            signup = Signup.start(Screen, (255, 0, 0), (200, 0, 0))
            pygame.display.update()
            clock.tick(fps)

        #Verification
        UserName = username.text
        PassWord = password.text
        time.sleep(0.2)
        if signup:
            while True:
                Login = False
                done = False
                username = TB((200, 500, 400, 100), 'Type New Username', 40, (0, 0, 255))
                password = TB((200, 650, 400, 100), 'Type New Password', 40, (0, 0, 255))
                while not done and not Login:
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            pygame.quit()
                            sys.exit()
                    username.start(Screen, (255, 0, 0), 18)
                    password.start(Screen, (255, 0, 0), 18)
                    Login = login.start(Screen, (255, 0, 0), (200, 0, 0))
                    done = Signup.start(Screen, (255, 0, 0), (200, 0, 0))
                    pygame.display.update()
                    clock.tick(fps)
                UserName = username.text
                PassWord = password.text
                if Login:
                    return False
                else:
                    time.sleep(0.2)
                    if UserName != '':
                        valid = True
                        for user in UserData:
                            if user.lower() == UserName.lower():
                                valid = False
                        if not valid:
                            pygame.draw.rect(Screen, (0, 0, 255), (0, 350, 800, 50))
                            SD.message_display(Screen, 'Username already taken', 40, (255, 0, 0), 400, 450)
                            
                        elif PassWord != '':
                            pygame.draw.rect(Screen, (0, 0, 255), (0, 350, 800, 50))
                            SD.message_display(Screen, f'Successfully created account under {UserName}!', 40, (255, 0, 0), 400, 450)
                            NewPlayer = Player(item('WoodenBat'), item('WoodenArmor'), 1, 1, 1, 5, UserName, PassWord)
                            UserData.update({UserName : {'password' : PassWord, 'exp': 0, 'stage' : None, 'floor' : 0, 'player' : NewPlayer}})
                            Save(UserData)
                            return UserName

                        else:
                            pygame.draw.rect(Screen, (0, 0, 255), (0, 350, 800, 50))
                            SD.message_display(Screen, 'Invalid Password', 40, (255, 0, 0), 400, 450)
                            
                    else:
                        pygame.draw.rect(Screen, (0, 0, 255), (0, 350, 800, 50))
                        SD.message_display(Screen, 'Invalid Username', 40, (255, 0, 0), 400, 450)
                        time.sleep(0.2)
                        
                            
                        
        else:
            invalid = False
            valid = False
            for user in UserData:
                if UserName.lower() == user.lower():
                    invalid = False
                    valid = True
                    if PassWord == UserData[user]['password']:
                        return user
                    else:
                        pygame.draw.rect(Screen, (0, 0, 255), (0, 390, 800, 100))
                        SD.message_display(Screen, 'Invalid Password', 40, (255, 0, 0), 400, 450)
                        done = False
                else:
                    if not valid:
                        invalid = True
            if invalid:
                pygame.draw.rect(Screen, (0, 0, 255), (0, 390, 800, 100))
                SD.message_display(Screen, 'Invalid Username', 40, (255, 0, 0), 400, 450)
                done = False

def notification(text, textColor, bg):
    pygame.draw.rect(Screen, (0, 0, 255), (0, 0, 800, 75))
    SD.message_display(Screen, text, 25, textColor, 400, 50)
    pygame.display.update()
    time.sleep(5) #This function is used w/ threading so the sleep doesn't affect the GUI
    pygame.draw.rect(Screen, (0, 0, 255), (0, 0, 800, 75))
    pygame.display.update()
    
def LevelSetup(username, direction):
    if direction == 'up':
        if UserData[username]['stage'].stage == len(MapDict[UserData[username]['floor']]):
            UserData[username]['floor'] += 1
            UserData[username]['stage'] = GameLayout[UserData[username]['floor']][1]
        else:
            UserData[username]['stage'] = GameLayout[UserData[username]['floor']][UserData[username]['stage'].stage + 1]
    else:
        if UserData[username]['stage'].stage == 1:
            UserData[username]['floor'] -= 1
            UserData[username]['stage'] = GameLayout[UserData[username]['floor']][len(GameLayout[UserData[username]['floor']])]
        else:
            UserData[username]['stage'] = GameLayout[UserData[username]['floor']][UserData[username]['stage'].stage - 1]


def LevelRun(username):
    UD = UserData[username]
    stage = UD['stage']
    plr = UD['player']
    playing = True
    direction = None
    print('New Level')
    print(stage.stage)
    while playing:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
        stage.draw()
        for enemy in stage.enemies:
            enemy.draw()
            enemy.move(plr)
            collide(enemy, stage.obst)
        plr.draw()
        plr.move()
        playing, direction = collide(plr, stage.obst)
        pygame.display.update()
        clock.tick(fps)
    UserData[username]['player'] = plr
    LevelSetup(username, direction)
    return True

def collide(plr, obstacle):
    for obst in obstacle:
        if obst.rect.colliderect(plr.rect):
            if obst.type == 'Stairup' and plr.identifier != 'enemy':
                print('Up')
                plr.forceMove(700 - plr.rect[0], 650 - plr.rect[1] - 25)
                return False, 'up'
            elif obst.type == 'Stairdown' and plr.identifier != 'enemy':
                print('Down')
                plr.teleport(50, 125)
                return False, 'down'
            if 'right' in plr.movingList or 'left' in plr.movingList:
                if isEven(plr.rect[0] - obst.rect[0]):
                    xChange = 1 + round(plr.agility / 2)
                else:
                    xChange = (1 + round(plr.agility / 2)) * -1
                plr.forceMove(xChange, 0)
            if 'up' in plr.movingList or 'down' in plr.movingList:
                if isEven(plr.rect[1] - obst.rect[1]):
                    yChange = 1 + round(plr.agility / 2)
                else:
                    yChange = (1 + round(plr.agility / 2)) * -1
                plr.forceMove(0, yChange)
    return True, None

def BackRange(last, first):
    count = last + 1
    output = []
    for x in range(0, last - first):
        count -= 1
        output.append(count)
    return output

def LevelCheck(exp):
    levelRef = {1 : 0, 2 : 100, 3 : 225, 4 : 540, 5 : 915, 6 : 1420, 7 : 1975, 8 : 2640, 9 : 3980, 10 : 5035}
    count = len(levelRef) - 1
    for x in BackRange(len(levelRef) - 1, -1):
        if exp >= levelRef[x]:
            return x

def tutorial(username):
    stage = Stage(0, 0, (30, 240, 30), True)
    plr = UserData[username]['player']
    playing = True
    direction = None
    while playing:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
        stage.draw()
        for enemy in stage.enemies:
            enemy.draw()
            enemy.move(plr)
            collide(enemy, stage.obst)
        plr.draw()
        plr.move()
        playing, direction = collide(plr, stage.obst)
        pygame.display.update()
        clock.tick(fps)
    UserData[username]['stage'] = GameLayout[1][1]
    UserData[username]['floor'] = 1
    return True


def main(start=False):
    if start:
        username = False
        while not username:
            username = SignIn()
    UD = UserData[username]
    if UD['stage'] == None:
        if not tutorial(username):
            return False
    while True:
        if not LevelRun(username):
            return
        if UserData[username]['floor'] == len(stageSetup) and UserData[username]['stage'].stage == len(stageSetup[len(stageSetup)]):
            EndGame('Yay!')
            break

def EndGame(death=True):
    if death is True:
        #Died!
        pass

    else:
        #Beat Game!
        pass

    wait = time.time()
    while time.time() - wait < 5:
        pygame.display.update()

if __name__ == '__main__':
    main(True)
    pygame.quit()
    sys.exit()
Reply
#2
I am very anti-nested-while loop in games. I find it to be ugly and hard to maintain. I find creating some form of state machine creates order from this kind of chaos. I'll save you my speech because i could of sworn i gave it to you before about this very thing.
Recommended Tutorials:
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  question about my pygame code for space shooter Than999 4 2,512 Feb-07-2022, 03:55 AM
Last Post: metulburr
  question about my Pygame code Than999 2 1,682 Feb-06-2022, 10:03 PM
Last Post: Than999
  [PyGame] Problems with jump code in pygame Joningstone 4 5,365 Aug-23-2021, 08:23 PM
Last Post: deanhystad
  Distributing Python/Pygame code with CX_Freeze jfng75 2 2,814 Jan-11-2021, 10:23 PM
Last Post: snippsat
  My Pygame Code always says "(Not responding") noodlespinbot 3 8,106 Feb-29-2020, 10:50 PM
Last Post: Windspar
  Python Pygame code help Trajme 1 4,025 Dec-07-2017, 04:55 PM
Last Post: nilamo
  Appropriately delay this PyGame code kleynah22 2 4,390 Nov-09-2017, 02:00 PM
Last Post: Windspar

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020