示例#1
0
class LevelPlay(tools._State):
    def __init__(self):
        super(LevelPlay, self).__init__()

        tmx_data = load_pygame(MAP['map0'])

        map_data = pyscroll.data.TiledMapData(tmx_data)
        self.map_rect = pg.Rect(0, 0,
                                map_data.map_size[0] * map_data.tile_size[0],
                                map_data.map_size[1] * map_data.tile_size[1])
        self.map_layer = pyscroll.BufferedRenderer(map_data, SCREEN_SIZE)
        self.map_layer.zoom = 1
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)
        self.animations = pg.sprite.Group()
        self.labels = pg.sprite.Group()
        self.enemies = pg.sprite.Group()
        self.coins = pg.sprite.Group()
        self.pos_x = None
        self.pos_y = None
        self.pos_x_r = None
        self.pos_y_r = None
        self.upper_world = False

        self.time = 0
        self.timer = TIME
        self.coin_num = 0
        self.player_lives = 0
        self.hud = Hud()

        self.walls = list()
        for object in tmx_data.objects:
            if object.name == 'collide':
                self.walls.append(
                    pg.Rect(object.x, object.y, object.width, object.height))
            elif object.name == 'playerpos':
                self.pos_x = object.x
                self.pos_y = object.y
                self.player = Player(self.pos_x, self.pos_y, False, self.group)
            elif object.name == 'playerpos_r':
                self.pos_x_r = object.x
                self.pos_y_r = object.y
            elif object.name == 'enemy':
                Enemy(object.x, object.y, self.enemies)
            elif object.name == 'fish':
                Fish(object.x, object.y, self.enemies)
            elif object.name == 'fly':
                Fly(object.x, object.y, self.enemies)
            elif object.name == 'coin':
                Coin(object.x, object.y, self.coins)
            elif object.name == 'bat':
                Bat(object.x, object.y, self.enemies)
            elif object.name == 'enimy':
                Enimy(object.x, object.y, self.enemies)
            elif object.name == 'f1sh':
                F1sh(object.x, object.y, self.enemies)
            elif object.name == 'over_event':
                self.over_rect = pg.Rect(object.x, object.y, object.width,
                                         object.height)
            elif object.name == 'over_event_r':
                self.over_rect_r = pg.Rect(object.x, object.y, object.width,
                                           object.height)

        self.player.platform = self.walls

    def get_event(self, event):

        self.player.get_event(event)
        if event.type == pg.QUIT:
            self.quit = True
        elif event.type == pg.KEYDOWN:
            if event.key == pg.K_SPACE:
                self.map_layer.zoom = 0.5
        elif event.type == pg.KEYUP:
            if event.type == pg.K_ESCAPE:
                self.quit = True
            elif event.key == pg.K_SPACE:
                self.map_layer.zoom = 1
            else:
                pass

    def startup(self, persist):
        pg.mixer.init()

        song = MUSIC['bg']
        pg.mixer.music.load(song)
        pg.mixer.music.set_volume(0.1)
        pg.mixer.music.play()

        self.done = False
        self.persist = persist
        self.mask = self.persist['surface']
        self.transition = Transition(self.mask)
        self.player_lives = self.persist['lives']
        self.coin_num = self.persist['coins']

        if self.player.reverse == True:
            self.fog = pg.Surface(SCREEN_RECT.size, pg.SRCALPHA)
            self.fog_color = (0, 0, 0, 200)
            self.fog.fill(self.fog_color)

    def player_dead(self):
        sound = SFX['dead0']
        sound.play()

        self.player_lives -= 1
        if self.player_lives < 1:
            self.done = True
            self.next = 'LOSE'
        buffer = pg.display.get_surface()
        self.switch_screen = Transition(buffer)
        if self.player.reverse == False:
            self.player.rect.x, self.player.rect.y = self.pos_x, self.pos_y
        elif self.player.reverse == True:
            self.player.rect.x, self.player.rect.y = self.pos_x_r, self.pos_y_r

    def update(self, dt):
        self.offset_x, self.offset_y = self.group._map_layer.get_center_offset(
        )

        self.time += dt
        if self.time > self.timer:
            self.time -= self.timer
            self.player_dead()

        self.group.update(dt)
        self.enemies.update(dt)
        self.coins.update(dt)
        self.hud.update(self, dt)
        self.animations.update(dt)

        if self.player.rect.colliderect(self.over_rect_r):
            if self.player.reverse == True:
                self.done = True
                self.next = 'WIN'

        if self.player.rect.colliderect(self.over_rect):
            self.player.rect.x, self.player.rect.y = self.pos_x_r, self.pos_y_r
            if self.coin_num >= 30:
                self.player.kill()
                self.player = Player(self.pos_x_r, self.pos_y_r, True,
                                     self.group)
                self.player.platform = self.walls
                self.done = True
                self.next = 'UPPER'
            elif self.coin_num < 30:
                self.player.reverse = False
                self.done = True
                self.next = 'BOTUP'

        if pg.sprite.spritecollide(self.player, self.coins, True):
            self.coin_num += 1
            sound = SFX['coin']
            sound.play()
            self.labels.empty()
            self.animations.empty()
            coin_sprite = pg.sprite.Sprite(self.labels)
            coin_sprite.image = GFX['hud_coins']
            x = self.offset_x + self.player.rect.x
            y = self.offset_y + self.player.rect.y
            coin_sprite.rect = pg.Rect((x, y), coin_sprite.image.get_size())
            ani = Animation(x=50, y=10, duration=100, transition="out_bounce")
            ani.start(coin_sprite.rect)
            self.animations.add(ani)

        if not self.map_rect.contains(self.player.rect):
            self.player_dead()

        if pg.sprite.spritecollide(self.player, self.enemies, False):
            self.player_dead()

        self.labels.update(dt)

    def cleanup(self):
        pg.mixer.quit()
        self.persist = {}
        self.persist['coins'] = self.coin_num
        self.persist['lives'] = self.player_lives
        self.persist['surface'] = pg.display.get_surface()
        return self.persist

    def draw(self, surface):
        self.group.empty()
        if self.player.reverse == True:
            close = (enemy for enemy in self.enemies if get_distance(
                enemy.rect.center, self.player.rect.center) <= 100)
            close_enemies = pg.sprite.Group(close)
            self.group.add(self.player, self.coins, close_enemies)
        elif self.player.reverse == False:
            close = (enemy for enemy in self.enemies if get_distance(
                enemy.rect.center, self.player.rect.center) <= SCREEN_SIZE[0])
            close_enemies = pg.sprite.Group(close)
            self.group.add(self.player, self.coins, close_enemies)

        self.group.draw(surface)
        self.group.center(self.player.rect.center)

        if hasattr(self, 'fog') and self.map_layer.zoom == 1:
            self.fog.fill(self.fog_color)
            for i in range(200):
                pg.draw.circle(self.fog, pg.Color(0, 0, 0, 200 - i),
                               (self.player.rect.centerx + self.offset_x,
                                self.player.rect.centery + self.offset_y),
                               int(100 - i * 0.5))
            surface.blit(self.fog, (0, 0))
        elif hasattr(self, 'fog') and self.map_layer.zoom == 0.5:
            self.fog.fill(self.fog_color)
            surface.blit(self.fog, (0, 0))

        self.hud.draw(surface)
        self.transition.draw(surface)
        self.labels.draw(surface)

        if hasattr(self, 'switch_screen'):
            self.switch_screen.draw(surface)
示例#2
0
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)

    counter = 1
    counter2 = 1

    def __init__(self, state): 
        if state == False:
            self.fullscreen = False
            # true while running.
            self.running = False
            self.clock = pygame.time.Clock()
            # create all the directio variables
            self.direction = "still"
            self.EntityDirection = "still"
            self.EntityDirection1, self.EntityDirection2 = "still", "still"  
            self.fps = 1000

            self.bypass = False

            entityPos1, heroPos1 = False, False
                     
            # load data from pytmx
            tmx_data = load_pygame(self.filename)
            self.tmx_data = tmx_data

            mapPlay = load_pygame(get_map(stats['map']))
            # create new data source for pyscroll
            map_data = pyscroll.data.TiledMapData(mapPlay)
            # setup level geometry with simple pygame rects, loaded from pytmx.
            self.walls = list()
            for object in mapPlay.objects:
                self.walls.append(pygame.Rect(
                    object.x, object.y,
                    object.width, object.height))
            
            # create new renderer (camera)
            self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
            self.map_layer.zoom = 2

            self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)
            self.hero = Hero('Tiles/hero/character_still.png')
            self.entity = Entity('Tiles/hero/character_still.png')
            self.hero.position = stats['pos']
            self.entity.position = stats['pos']
            # add our hero to the group
            self.group.add(self.hero)
            #self.group.add(self.entity)
            
            self.entVel = (0, 0)

    def deep_thought(self): # The 'AI' function, needs work
        if self.counter2 % 75 == 0 or self.bypass == True:
            self.bypass = False
            if random.randint(0, 1) == 1:
                self.entity.velocity[0], self.entity.velocity[1] = 0, 0
            movement = random.choice(["self.entity.velocity[0] = -45; self.EntityDirection = 'left'; self.EntityDirection2 = 'left'",
                                      "self.entity.velocity[0] = 45; self.EntityDirection = 'right'; self.EntityDirection2 = 'right'",
                                      "self.entity.velocity[1] = -45; self.EntityDirection = 'up'; self.EntityDirection1 = 'up'",
                                      "self.entity.velocity[1] = 45; self.EntityDirection = 'down'; self.EntityDirection1 = 'down'"])
            exec(movement)
            
    def EntityAnimation(self, direction, number, character="hero"):
        self.entVel = self.entity.velocity
        
        self.counter += 1
        if self.EntityDirection1 == "still" and self.EntityDirection2 == "still":
            if self.EntityDirection == "left":
                self.entity = Entity('Tiles/' +character +'/walking_left/walking_left1.png')
            if self.EntityDirection == "right":
                self.entity = Entity('Tiles/' +character +'/walking_right/walking_right1.png')
            if self.EntityDirection == "up":
                self.entity = Entity('Tiles/' +character +'/walking_up/walking_up1.png')
            if self.EntityDirection == "down":
                self.entity = Entity('Tiles/' +character +'/walking_down/walking_down1.png')
        else:
            self.entity = Entity('Tiles/' +character +'/walking_' +direction +'/walking_' +direction +str(number) +'.png')
        self.entity.velocity = self.entVel

    def EntMoveBack(self):
        #self.deep_thought(self, True) # Comment this to disable the 'AI'
        pass

    def map_change(self, map, target=False): # Does what it says on the tin
            mapfile = get_map(map)
            tmx_data = load_pygame(mapfile)
            self.tmx_data = tmx_data
            map_data = pyscroll.data.TiledMapData(tmx_data)
            self.walls = list()
            for object in tmx_data.objects:
                self.walls.append(pygame.Rect(
                    object.x, object.y,
                    object.width, object.height))

            # creates new 'camera'
            self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
            self.map_layer.zoom = 2
            self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)

            #creates a new Hero to go on our new camera
            self.hero = Hero('Tiles/hero/character_still.png')
            try:
                self.hero.position = (target)
            except TypeError:
                self.hero.position = self.map_layer.map_rect.center
            self.map = stats['map'][:-4].lower()
            self.map = self.map.lstrip("m") # Fix that stupid bug that changes "maze1" to "ze1"
            self.map = self.map.lstrip("aps/")
            
    def switcher(self): # Bunch of IF statements to decide if we're at a door or not, then changes the map.
        if len(objectX) == len(objectY) == len(targetPosX) == len(targetPosY) == len(currentMap) == \
           len(targetMap) == len(animationDirection) == len(targetMapFile) == len(objectType):
            heroPos = [0, 0]
            heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1]
            for i in range(len(objectX)):
                if self.map == currentMap[i]:
                    if self.hero.position[0] - 15 <= int(objectX[i]) <= self.hero.position[0] + 15:
                        if self.hero.position[1] - 15 <= int(objectY[i]) <= self.hero.position[1] + 15:
                            if objectType[i] == "door":
                                used[i] = True
                                self.map_change(targetMapFile[i])
                                self.map = targetMap[i]
                                stats['map'] = targetMapFile[i]
                                heroPos = (int(targetPosX[i]), int(targetPosY[i]))
                                self.animation(animationDirection[i], 1)
                                self.hero.position = heroPos
                                return False
                            elif objectType[i] == "chest":
                                keyset, self.menu = "chest", "chest"                  
                                if used[i] == False:
                                    if chestContents[i] == None and used[i] == False:
                                        used[i] = True
                                        pickle.dump(used, open(os.path.join("data", "saves", "used.dat"), "wb"))
                                        chestContents[i] = self.genchests()
                                        pickle.dump(chestContents, open(os.path.join("data", "saves", "chestContents.dat"), "wb"))
                                self.chestNo = i                    
                            return False
                        
    def generate_surrounding_maps(self):
        heroPos = [0, 0]
        heroPos = self.hero.position
        if int(self.hero.position[0]) in range((self.tmx_data.width*32)-64,
                                                 (self.tmx_data.width*32)):
            target = (32, heroPos[1])
            self.grid[0] = self.grid[0]+1
            try:
                self.map_change(str(self.grid[0]+1) +", "+ str(self.grid[1]) +".tmx",
                                target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                self.animation("right", 1)
                target = (32, heroPos[1])
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[1]) in range((self.tmx_data.height*32)-64,
                                                 self.tmx_data.width*32):
            target = (heroPos[0], 32)
            self.grid[1] = self.grid[1]+1
            try:
                self.map_change(str(self.grid[0]) +", "+ str(self.grid[1]+1) +".tmx",
                                target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1]
                self.animation("up", 1)
                
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[0]) in range(0, 64):
            target = (self.tmx_data.width*32 - 32, heroPos[1])
            self.grid[0] = self.grid[0]-1
            try:
                self.map_change(str(self.grid[0]-1) +", "+ str(self.grid[1]) +".tmx",
                                target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1]
                self.animation("left", 1)
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[1]) in range(0, 64):
            target = (heroPos[0], self.tmx_data.height*32 - 32)
            self.grid[1] = self.grid[1]-1
            try:
                self.map_change(str(self.grid[0]) +", "+ str(self.grid[1]-1) +".tmx",
                                target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1]
                self.animation("down", 1)
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        else:
            pass

    def generate_new_map(self, octaves, freq, area, target, position):
        command = "{}/lib/generate/__init__.py".format(os.getcwd())
        if sys.platform.startswith('win32'):
            executeable = ("Python35\python.exe")
            
        elif sys.platform.startswith('linux'):
            executeable = ("python3.5")

        for y in range(self.grid[1] + eval("-"+ str(area)),self.grid[1] +  area):
            for x in range(self.grid[0] + eval("-"+ str(area)),self.grid[0] +  area):
                if os.path.isfile("data/maps/"+str(x)+", "+str(y)+".tmx"):
                    pass
                else:
                    p = subprocess.Popen([executeable, command, ("data/maps/"+
                                                    str(x)+", "+str(y)+".tmx"),
                                      str(octaves), str(freq), str(x), str(y)],
                                         close_fds=True)
        try:
            if p is not None:
                disp_width, disp_height = pygame.display.get_surface().get_size()
                #self.blit_inventory("speach", "Generating Map... Please Wait...")
                self.speach(disp_width, disp_height,
                            "Generating Map... Please Wait...") 
                pygame.display.update()
                p.wait()
                self.map_change((str(target[0])+", "+str(target[1])+".tmx"), position)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
        except UnboundLocalError:
            pass
                    
    def draw(self, surface):
        self.group.center(self.hero.rect.center)
        # draw the map and all sprites
        self.group.draw(surface)

    def speach(self, dispWidth, dispHeight, text):
##        text = "Laudem bonorum salutandi pri te, tollit melius delicata mel cu,\
##                eu mea ullum legimus. Probo debitis te vel. Labores vulputate \
##                argumentum sea id. Cibo vitae vocent eos no, ne odio molestiae\
##                duo."
        screen.blit(pygame.transform.scale(load_image(os.path.join(
            "images", "gui", "speach.png")), (dispWidth, 150)), (0, dispHeight-150))
        text = textwrap.wrap(text, width=95)
        for i, line in enumerate(text): 
            text_blit = pixel_font.render(line, False, pygame.Color('white'))
            screen.blit(text_blit, (60, dispHeight-110 + 25*i))

    def map_generate(self, output, octaves, freq, x, y):
        command = "{}/lib/generate/__init__.py".format(os.getcwd())
        
        if sys.platform.startswith('win32'):
            executeable = ("Python35\python.exe")
            
        elif sys.platform.startswith('linux'):
            executeable = ("python3.5")
            
        subprocess.Popen([executeable, command, output, str(octaves), str(freq),
                          str(x), str(y)],close_fds=True) 

    def handle_input(self, keyset):
        """ Handle pygame input events
        """
        
        poll = pygame.event.poll
        
        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                pygame.quit()
                break

            elif event.type == KEYDOWN:
                

                if keyset == "game":
                    if event.key == K_EQUALS:
                        self.map_layer.zoom += .25

                    elif event.key == K_MINUS:
                        value = self.map_layer.zoom - .25
                        if value > 0:
                            self.map_layer.zoom = value
                        else:
                            self.map_layer.zoom = 0.1

                    elif event.key == K_KP0:
                        try:
                            if self.switcher() == True:
                                self.generate_surrounding_maps()
                        except FileNotFoundError:
                            print("Exception Caught")
                        pass

                    elif event.key == K_e:
                        self.menu = "inventory"
                        pass

                    if event.key == K_ESCAPE:
                        for i in attack_stats_types:
                            stats[i] = attack_stats[i]
                        pickle.dump(stats, open(os.path.join("data", "saves", "save.dat"), "wb"))
                        pickle.dump(inventory, open(os.path.join("data", "saves", "inventory.dat"), "wb"))
                        self.running = False
                        pygame.quit()
                        print(" ")
                        sleep(0.5)
                        print("Shutdown... Complete")
                        sys.exit()
                        break

                if keyset != "game":
                    if event.key == K_ESCAPE:
                        self.menu = "game"
                        pass

                if keyset == "inventory":
                    if event.key == K_r:
                        self.genchests()

                if keyset == "chest":
                    if event.key == K_r:
                        chestContents[self.chestNo] = self.genchests()

                    if event.key == K_t:
                        if taken[self.chestNo] != True:
                            self.takeChest()
                            taken[self.chestNo] = True
                            pickle.dump(taken, open(os.path.join("data", "saves", "taken.dat"), "wb"))

                if keyset == "attack":
                    pass

                #Basically just debug keys
                if event.key == K_KP1:
                    self.menu = "game"
                    pass

                elif event.key == K_KP2:
                    self.map_change(FOREST)
                    self.map = "forest"

                elif event.key == K_KP3:
                    self.generate_new_map(4, 16, 3)
                    pass

                elif event.key == K_KP4:
                    self.map_generate(str(self.grid[0]) +", "+ str(self.grid[1]) +".tmx", 4, 16.0, self.grid[0], self.grid[1])  
                    pass

                elif event.key == K_KP5:
                    self.enemy_stats = self.gen_enemy(attack_stats, enemy_stats)
                    self.menu = "attack"
                    pass

                elif event.key == K_KP6:
                    print("X :" +str(int(self.hero.position[0])) +
                          ", Y: " +str(int(self.hero.position[1])) +
                          ", Map: "+ self.map)
                    pass

                elif event.key == K_KP7:
                    print(str(pygame.mouse.get_pos()))
                    pass
                
                elif event.key == K_KP8:
                    sleep(0.5)

                elif event.key == K_KP9:
                    editor = db_interface.Editor()
                    conn = sqlite3.connect('data/saves/data.db')
                    c = conn.cursor()

                    for var in vars:
                        exec("del "+var+"[:]")
                        for data in c.execute("SELECT {} FROM csv".format(var)):
                            data = str(data[0])
                            exec("{}.append(\"{}\")".format(var, data))
                            pass

                elif event.key == K_F11:
                    for m in screeninfo.get_monitors():
                        displ = str(m)
                        w, h, mx, c = displ.split(", ")
                        
                    if self.fullscreen:
                        self.fullscreen = False
                        screen = init_screen(1024, 700, pygame.HWSURFACE | pygame.FULLSCREEN )
                    else:
                        self.fullscreen = True
                        screen = init_screen(w, h, pygame.HWSURFACE | pygame.RESIZABLE )

                    pygame.display.toggle_fullscreen()

            elif event.type == VIDEORESIZE:
                self.map_layer.set_size((event.w, event.h))
                dispHeight = event.h
                dispWidth = event.w
                

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        if keyset == "game":
            pressed = pygame.key.get_pressed()
            if pressed[K_UP]:
                self.hero.velocity[1] = -HERO_MOVE_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_DOWN]:
                self.hero.velocity[1] = HERO_MOVE_SPEED
                self.direction = "down"
                self.direction2 = "down"
            elif pressed[K_w]:
                self.hero.velocity[1] = -HERO_SPRINT_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_s]:
                self.hero.velocity[1] = HERO_SPRINT_SPEED
                self.direction = "down"
                self.direction2 = "down"
            else:
                self.hero.velocity[1] = 0
                self.direction2 = "still"
            if pressed[K_LEFT]:
                self.hero.velocity[0] = -HERO_MOVE_SPEED
                self.direction = "left"
                self.direction1 = "left"
            elif pressed[K_RIGHT]:
                self.hero.velocity[0] = HERO_MOVE_SPEED
                self.direction = "right"
                self.direction1 = "right"
            elif pressed[K_a]:
                self.hero.velocity[0] = -HERO_SPRINT_SPEED
                self.direction = "left"
                self.direction1 = "left"
            elif pressed[K_d]:
                self.hero.velocity[0] = HERO_SPRINT_SPEED
                self.direction = "right"
                self.direction1 = "right"
            else:
                self.hero.velocity[0] = 0
                self.direction1 = "still"

            if self.direction1 == "still" and self.direction2 == "still":
                self.direction = "still"

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def animation(self, direction, number):
        if self.direction1 == "still" and self.direction2 == "still":
            if self.direction == "left":
                self.hero = Hero('Tiles/hero/walking_left/walking_left1.png')
            if self.direction == "right":
                self.hero = Hero('Tiles/hero/walking_right/walking_right1.png')
            if self.direction == "up":
                self.hero = Hero('Tileshero/walking_up/walking_up1.png')
            if self.direction == "down":
                self.hero = Hero('Tiles/hero/walking_down/walking_down1.png')

        else:
            self.hero = Hero('Tiles/hero/walking_' +direction +'/walking_' +direction +str(number) +'.png')      

    def genchests(self):

        wr = WeightedRandomizer(itemsProbability)
        
        self.taken = False
        chest.clear()
        numItems = random.randint(1, random.randint(2, 4))
        if random.randint(0, 3) < 1:
            numItems += 1
        elif random.randint(0, 9) < 2:
            numItems += 2
        elif random.randint(0, 18) < 2:
            numItems += 5
        for i in range(0, numItems):
            item = wr.random()
            while item in chest: 
                item = wr.random()
            chest.append(item)

        return chest

    def gen_enemy(self, player_stats, enemy_stat):
        stats = attack_stats_types
        stat = player_stats
        for i in range(len(player_stats)):
            j = stats[i]
            try:
                enemy_stat[stats[i]] = int((stat[j]-(stat[j]*0.2)) + random.randint(0, int(stat[j]*0.4)))
            except TypeError:
                enemy_stat[j] = choice(attack_types)
        return enemy_stat
        pass

    def player_attack():
        type = None
        while type not in attack_types:
            type = input("[ QUESTION ] Enter attack type. ")
            if type not in attack_types:
                print("[ ERROR    ] Attack type {} not found. Must be {}".format(type, attack_types))
            else:
                break
        return type
        pass

    def attack(self, attacker_stats, defender_stats, player_attack_type):
        fraction = attacker_stats['strength'] / defender_stats['blocking']
        print("[ INFO     ] Defender attack type: {}".format(defender_stats['attack']))
        if player_attack_type != defender_stats['attack']:
            if fraction > (0.8 + (randint(0, 40)/100)):
                attacker_stats['health'] -= int(fraction*10)
                pass # Attacker Win
            else:
                defender_stats['health'] -= int(fraction*10)
                pass # Attacker Loss
        elif player_attack_type == attacker_stats['attack']: # Better odds here
            if fraction > (0.9 + (randint(0, 40)/100)):
                attacker_stats['health'] -= int(fraction*10)
                pass # Attacker Win
            else:
                defender_stats['health'] -= int(fraction*10)
                pass # Attacker Loss
        else:
            if fraction > (0.70 + (randint(0, 40)/100)): # Odds are worse here
                attacker_stats['health'] -= int(fraction*10)
                pass # Attacker Win
            else:
                defender_stats['health'] -= int(fraction*10)
                pass # Attacker Loss
        print("[ INFO     ] Attacker: {}  Defender: {}".format(attacker_stats['health'], defender_stats['health']))
        print("[ INFO     ] Health to be lost: {}".format(int(fraction*10)))
        return attacker_stats, defender_stats
        
    def blit_inventory(self, screenMode, speach=None):
        if screenMode != "game":
            xCounter, counter, OverCounter = 0, 0, 0
            dispWidth, dispHeight = pygame.display.get_surface().get_size()
            guiX = (dispWidth / 2) - 175
            guiY = (dispHeight / 2) - 165
            screen.blit(load_image(os.path.join("images", "gui", "transparent.png")),( 0, 0))
            screen.blit(load_image(os.path.join("images", "gui", screenMode +".png")),(guiX, guiY))
        if screenMode == "inventory" or screenMode == "chest":
            dt = (clock.tick() / 500)
            clock.tick(self.fps)

            if len(inventory) > 0:
                for i in range(0, len(inventory)):
                    OverCounter += 1
                    if xCounter >= 9:
                        counter += 1
                        xCounter = 0
                    screen.blit(load_image(os.path.join("images", "items",\
                    str(items[inventory[i]])+".png")), (guiX + 16 + 36*xCounter, guiY + 168 + 36*counter))
                    xCounter += 1
        if screenMode == "chest" and chestContents[self.chestNo] != None:
            itemNo = 0
            for i in range(0, len(chestContents[self.chestNo])):
                screen.blit(load_image(os.path.join("images", "items",\
                            items[str(chestContents[self.chestNo][i])]\
                            +".png")), (guiX + 123 + 36*itemNo,\
                            guiY + 34 + int(35 * (i/3)) - int(35 * (i/3)) % 35))

                if itemNo < 2:
                    itemNo += 1
                else:
                    itemNo = 0

        if screenMode == "speach":
            self.speach(dispWidth, dispHeight, speach)
        if screenMode == "attack":
            picture = load_image(os.path.join("Tiles", "hero", "walking_down", "walking_down1.png"))
            picture = pygame.transform.scale(picture, (100, 100))
            rect = picture.get_rect()
            rect = rect.move((guiX + 50, guiY + 28))
            screen.blit(picture, rect)
            text = font.render("Player : Enemy", True, pygame.Color('black'))
            screen.blit(text, (guiX + 172, guiY + 45))
            text = "Health: "+str(attack_stats['health'])+"    Skill: "+str(attack_stats['skill'])+"    Attack: "+str(attack_stats['attack'])
            text_render = pixel_font.render(text, False, pygame.Color('gray27'))
            screen.blit(text_render, (guiX+20, guiY+290))
            for i, attack in enumerate(attack_types):
                text = load_font(30, "data/PixelFont.ttf").render(attack, False, pygame.Color('black'))
                screen.blit(text, (guiX+172, guiY+25+28*(i+2)))
            #
            if pygame.mouse.get_pressed()[0] == 1:
                #print(pygame.mouse.get_pos())
                mouse_pos = pygame.mouse.get_pos()
                if guiX+160 < mouse_pos[0] and guiX+330 > mouse_pos[0]: 
                    for i, attack in enumerate(attack_types):
                        if guiY+25+28*(i+2) < mouse_pos[1] and (guiY+25+28*(i+2))+28 > mouse_pos[1]:
                            print(attack)
                            self.attack(attack_stats, enemy_stats, attack)
                        else:
                            pass

            pass
                
    def takeChest(self):
        if len(inventory) < 27:  
            if chestContents[self.chestNo] != None:
                for i in range(0, (len(chestContents[self.chestNo]))):
                    #print(i)
                    inventory.append(chestContents[self.chestNo][i])
                chestContents[self.chestNo][:] = []
            pickle.dump(chestContents, open(os.path.join("data", "saves", "chestContents.dat"), "wb"))
            
                
    def run(self):
        screenMode = pygame.RESIZABLE

        oldPlay = stats['playTime']
        clock = pygame.time.Clock()
        self.running = True

        self.grid = [0, 0]

        debug = True
        dispWidth, dispHeight = 1024, 768
        self.menu = "game"
        game_time = pygame.time.get_ticks()
        playTime = font.render("Timer: ", False, pygame.Color('white'))        
        minutes = 0

        self.map = stats['map'][:-4].lower()
        self.map = self.map.lstrip("m") # Fix that stupid bug that changes "maze1" to "ze1"
        self.map = self.map.lstrip("aps/")
        
        try:
            while self.running:
                dt = (clock.tick() / 500)
                clock.tick(self.fps)

                if self.menu == "game":
                    #self.deep_thought()
                    if self.counter2 % 7 == 0:
                        heroPos = self.hero.position
                        self.animation(self.direction, self.counter)
                        self.hero.position = heroPos
                        #entityPos = self.entity.position
                        #self.EntityAnimation(self.EntityDirection, self.counter, "princess")
                        #self.entity.position = entityPos
                        
                        self.counter += 1
                        guiX = (dispWidth / 2) - 175
                        guiY = (dispHeight / 2) - 165
                        
                        self.group.remove(self.hero)
                        #self.group.remove(self.entity)
                        self.group.empty()
                        self.group.add(self.hero)
                        #self.group.add(self.entity)

                self.counter2 += 1
                if self.counter > 8:
                    self.counter = 1

                stats['pos'] = self.hero.position
                currentTime = systime()
                seconds = currentTime - gameStart + oldPlay
                dispWidth, dispHeight = pygame.display.get_surface().get_size()
                stats['playTime'] = seconds

                

                if debug == True and self.counter2 % 1 == 0:
                    location = font.render("Position: " + str(round(round(self.hero.position[0], -1) / 10)) + ", " + str(round(round(self.hero.position[1], -1) / 10)), False, pygame.Color('white'))
                    mapdebug = font.render("Map Name: " + str(self.map), False, pygame.Color('white'))
                    minutes = seconds // 60
                    secondsDisp = seconds % 60
                    if minutes < 1:
                        minutes = 0
                    if secondsDisp == 60:
                        secondsDisp = 0
                        minutes += 1
                    fps = font.render("FPS:" + str(int(clock.get_fps())), False, pygame.Color('white'))
                    screen.blit(fps, (50, 50))
                    screen.blit(playTime, (50,100))
                    screen.blit(location, (50,75))
                    screen.blit(mapdebug, (50, 125))

                    playTime = font.render("Timer: " + str(floor(minutes)) + " : " + str(round(secondsDisp)), True, pygame.Color('white'))
                    screen.blit(playTime, (50,100))    


                self.blit_inventory(str(self.menu))
                      
                pygame.display.update()
                #pygame,display.flip()
                self.handle_input(self.menu)
                self.update(dt)
                self.draw(screen)

        except KeyboardInterrupt:
            self.running = False
            pygame.quit()
示例#3
0
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)
    

    def __init__(self, state): 
        if state == False:
            screenMode = pygame.RESIZABLE
            # true while running.
            self.running = False
            self.clock = pygame.time.Clock()
            self.direction = "still"
            self.fps = 180

            self.counter = 1
            self.counter2 = 1

            heroPos1 = False

            # load data from pytmx
            tmx_data = load_pygame(self.filename)

            mapPlay = load_pygame(get_map(stats['map']))
            # create new data source for pyscroll
            map_data = pyscroll.data.TiledMapData(mapPlay)
            # setup level geometry with simple pygame rects, loaded from pytmx.
            self.walls = list()
            for object in mapPlay.objects:
                self.walls.append(pygame.Rect(
                    object.x, object.y,
                    object.width, object.height))
            
            # create new renderer (camera)
            self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
            self.map_layer.zoom = 2
            self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)
            self.hero = Hero('Tiles/character/character_still.png')
            self.hero.position = stats['pos']
            # add our hero to the group
            self.group.add(self.hero)

    def map_change(self, map):
            mapfile = get_map(map)
            tmx_data = load_pygame(mapfile)
            print(tmx_data)
            map_data = pyscroll.data.TiledMapData(tmx_data)
            self.walls = list()
            for object in tmx_data.objects:
                self.walls.append(pygame.Rect(
                    object.x, object.y,
                    object.width, object.height))


            self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
            self.map_layer.zoom = 2
            self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)

            self.hero = Hero('Tiles/character/character_still.png')
            self.hero.position = self.map_layer.map_rect.center


            
    def switcher(self):
        if len(doorX) == len(doorY) == len(targetPosX) == len(targetPosY) == len(currentMap) == len(targetMap) == len(animationDirection) == len(targetMapFile):
            for i in range(len(doorX)):
                if self.map == currentMap[i]:
                    if self.hero.position[0] - 15 <= doorX[i] <= self.hero.position[0] + 15:
                        print("OK!")
                        if self.hero.position[1] - 15 <= doorY[i] <= self.hero.position[1] + 15:
                            self.map_change(targetMapFile[i])
                            self.map = targetMap[i]
                            stats['map'] = targetMapFile[i]
                            heroPos = (targetPosX[i], targetPosY[i])
                            self.animation(animationDirection[i], 1)
                            self.hero.position = heroPos
                            print("Yeah!")
                            break
                    else:
                        print("Nope!")
                        print(str(doorX[i]) +" " +str(self.hero.position[0]))
                        print(str(doorY[i]) +" " +str(self.hero.position[1]))
                        
                else:
                    #print("Never!")
                    pass
        else:
            print("Error: Invalid number of door entries.")

##        elif self.map == "maze1":
##        #HOUSE2
##            if self.hero.position[0] >= -20 and self.hero.position[0] <= 20 and self.hero.position[1] <= 20 and self.hero.position[1] >= -15:
##                self.map_change(HOUSE1)
##                stats['map'] = HOUSE1
##                self.map = "house1"
##                heroPos = 206, 48
##                self.animation("down", 1)
##                self.hero.position = heroPos
##                self.group.remove(self)
##                self.group.empty()
##                self.group.add(self.hero)

    def draw(self, surface):
        self.group.center(self.hero.rect.center)
        # draw the map and all sprites
        self.group.draw(surface)

    def handle_input(self, keyset):
        """ Handle pygame input events
        """
        poll = pygame.event.poll
        
        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                pygame.quit()
                break

            elif event.type == KEYDOWN:
                

                if keyset == "game":
                    if event.key == K_EQUALS:
                        self.map_layer.zoom += .25

                    elif event.key == K_MINUS:
                        value = self.map_layer.zoom - .25
                        if value > 0:
                            self.map_layer.zoom = value

                    elif event.key == K_KP0:
                        self.switcher()
                        pass

                    elif event.key == K_e:
                        self.menu = "inventory"
                        print("Inventory")
                        pass

                    if event.key == K_ESCAPE:
                        pickle.dump(stats, open(os.path.join("data", "saves", "save.dat"), "wb"))
                        pickle.dump(inventory, open(os.path.join("data", "saves", "inventory.dat"), "wb"))
                        self.running = False
                        pygame.quit()
                        print(" ")
                        sleep(0.5)
                        print("Shutdown... Complete")
                        sys.exit()
                        break

                if keyset == "inventory":
                    if event.key == K_ESCAPE:
                        self.menu = "game"
                        print("Game")
                        pass

                    if event.key == K_r:
                        self.genchests()
                    

                elif event.key == K_KP1:
                    self.menu = "game"
                    print("Game")
                    pass

                elif event.key == K_KP2:
                    self.map_change(FOREST)
                    self.map = "forest"

                elif event.key == K_KP3:
                    self.menu = "inventory"
                    print("Inventory")
                    pass

                elif event.key == K_KP4:
                    pass

                elif event.key == K_KP5:
                    pass

                elif event.key == K_KP6:
                    print("X :" +str(self.hero.position[0]) +", Y: " +str(self.hero.position[1]))
                    pass

                elif event.key == K_KP7:
                    print(str(pygame.mouse.get_pos()))
                    pass
                
                elif event.key == K_KP8:
                    sleep(0.5)

                elif event.key == K_KP9:
                    self.genchests()
                    pass

                elif event.key == K_F11:
                    pygame.display.toggle_fullscreen()

            elif event.type == VIDEORESIZE:
                self.map_layer.set_size((event.w, event.h))
                dispHeight = event.h
                dispWidth = event.w
                

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        if keyset == "game":
            pressed = pygame.key.get_pressed()
            if pressed[K_UP]:
                self.hero.velocity[1] = -HERO_MOVE_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_DOWN]:
                self.hero.velocity[1] = HERO_MOVE_SPEED
                self.direction = "down"
                self.direction2 = "down"
            elif pressed[K_w]:
                self.hero.velocity[1] = -HERO_SPRINT_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_s]:
                self.hero.velocity[1] = HERO_SPRINT_SPEED
                self.direction = "down"
                self.direction2 = "down"
            else:
                self.hero.velocity[1] = 0
                self.direction2 = "still"
            if pressed[K_LEFT]:
                self.hero.velocity[0] = -HERO_MOVE_SPEED
                self.direction = "left"
                self.direction2 = "left"
            elif pressed[K_RIGHT]:
                self.hero.velocity[0] = HERO_MOVE_SPEED
                self.direction = "right"
                self.direction2 = "right"
            elif pressed[K_a]:
                self.hero.velocity[0] = -HERO_SPRINT_SPEED
                self.direction = "left"
                self.direction2 = "left"
            elif pressed[K_d]:
                self.hero.velocity[0] = HERO_SPRINT_SPEED
                self.direction = "right"
                self.direction2 = "right"
            else:
                self.hero.velocity[0] = 0
                self.direction1 = "still"

            if self.direction1 == "still" and self.direction2 == "still":
                self.direction = "still"

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def animation(self, direction, number):
        self.counter += 1
        if self.direction1 == "still" and self.direction2 == "still":
            if self.direction == "left":
                self.hero = Hero('Tiles/character/walking_left/walking_left1.png')
            if self.direction == "right":
                self.hero = Hero('Tiles/character/walking_right/walking_right1.png')
            if self.direction == "up":
                self.hero = Hero('Tiles/character/walking_up/walking_up1.png')
            if self.direction == "down":
                self.hero = Hero('Tiles/character/walking_down/walking_down1.png')

        else:
            self.hero = Hero('Tiles/character/walking_' +direction +'/walking_' +direction +str(number) +'.png')

                
            self.group.remove(self)
            self.group.empty()
            self.group.add(self.hero)
        


    def genchests(self):
        itm1, itm2, itm3, itm4, itm5, itm6 = "0", "0", "0", "0", "0", "0"
        numberItems = random.randint(1, 6)
        for i in range(0, numberItems):
            item = random.randint(1, 5)
            if i == 1:
                itm1 = item
            if i == 2:
                itm2 = item
            if i == 3:
                itm3 = item
            if i == 4:
                itm4 = item
            if i == 5:
                itm5 = item
            if i == 6:
                itm6 = item
        print("Found Chest With "+str(numberItems) +" Items: " +str(itm1) +" " +str(itm2) +" " +str(itm3) +" " +str(itm4) +" " +str(itm5) +" " +str(itm6) +" ")
        if 1 in(itm1, itm2, itm3, itm4, itm5, itm6):
            inventory['sword'] = True
        else:
            inventory['sword'] = False

        if 2 in(itm1, itm2, itm3, itm4, itm5, itm6):
            inventory['axe'] = True
        else:
            inventory['axe'] = False

        if 3 in(itm1, itm2, itm3, itm4, itm5, itm6):
            inventory['shovel'] = True
        else:
            inventory['shovel'] = False

        if 4 in(itm1, itm2, itm3, itm4, itm5, itm6):
            inventory['bow'] = True
        else:
            inventory['bow'] = False
            
            
    def run(self):
        screenMode = pygame.RESIZABLE
        self.map = stats['map'][:-4].lower()
        self.map = self.map.lstrip("maps/")
        oldPlay = stats['playTime']
        clock = pygame.time.Clock()
        self.running = True
        debug = True
        dispWidth, dispHeight = 1024, 768
        self.menu = "game"
        game_time = pygame.time.get_ticks()
        playTime = font.render("Timer: ", False, pygame.Color('white'))        
        minutes = 0
        try:
            while self.running:                  
                dt = (clock.tick() / 500)
                clock.tick(self.fps)
                if self.counter2 == 5:
                    heroPos = self.hero.position
                    self.animation(self.direction, self.counter)
                    self.counter += 1
                    self.counter2 = 0
                    guiX = (dispWidth / 2) - 175
                    guiY = (dispHeight / 2) - 165
                    self.hero.position = heroPos
                self.counter2 += 1
                if self.counter > 9:
                    self.counter = 1
                stats['pos'] = self.hero.position
                currentTime = systime()
                seconds = currentTime - gameStart + oldPlay
                dispWidth, dispHeight = pygame.display.get_surface().get_size()
                stats['playTime'] = seconds
                self.group.remove(self)
                self.group.add(self.hero)


                    
                if debug == True:
                    location = font.render("Position: " + str(round(round(self.hero.position[0], -1) / 10)) + ", " + str(round(round(self.hero.position[1], -1) / 10)), False, pygame.Color('white'))
                    fps = font.render("FPS:" + str(int(clock.get_fps())), False, pygame.Color('white'))
                    mapdebug = font.render("Map Name: " + str(self.map), False, pygame.Color('white'))
                    minutes = seconds // 60
                    secondsDisp = seconds % 60
                    if minutes < 1:
                        minutes = 0
                    if secondsDisp == 60:
                        secondsDisp = 0
                        minutes += 1
                    playTime = font.render("Timer: " + str(floor(minutes)) + " : " + str(round(secondsDisp)), True, pygame.Color('white'))
                    screen.blit(playTime, (50,100))
                    screen.blit(fps, (50, 50))
                    screen.blit(location, (50,75))
                    screen.blit(mapdebug, (50, 125))
                    

                if self.menu == "inventory":
                    screen.blit(load_image(os.path.join("Images", "transparent.png")),( 0, 0))
                    screen.blit(load_image(os.path.join("Images", "inventory.png")),(guiX, guiY))
                    if inventory["sword"] == True:
                        screen.blit(load_image(os.path.join("Images", "sword.png")),( guiX + 16, guiY + 168))
                    if inventory["axe"] == True:
                        screen.blit(load_image(os.path.join("Images", "axe.png")),( guiX + 52, guiY + 168))
                    if inventory["bow"] == True:
                        screen.blit(load_image(os.path.join("Images", "bow.png")),( guiX + 88, guiY + 168))
                    if inventory["shovel"] == True:
                        screen.blit(load_image(os.path.join("Images", "shovel.png")),( guiX + 124, guiY + 168))
                    
                pygame.display.update()
                self.handle_input(self.menu)
                self.update(dt)
                self.draw(screen)

        except KeyboardInterrupt:
            self.running = False
            pygame.quit()
示例#4
0
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)

    counter = 1
    counter2 = 1

    def __init__(self, state):
        if state == False:
            self.fullscreen = False
            # true while running.
            self.running = False
            self.clock = pygame.time.Clock()
            # create all the directio variables
            self.direction = "still"
            self.EntityDirection = "still"
            self.EntityDirection1, self.EntityDirection2 = "still", "still"
            self.fps = 1000

            self.bypass = False

            entityPos1, heroPos1 = False, False

            # load data from pytmx
            tmx_data = load_pygame(self.filename)
            self.tmx_data = tmx_data

            mapPlay = load_pygame(get_map(stats['map']))
            # create new data source for pyscroll
            map_data = pyscroll.data.TiledMapData(mapPlay)
            # setup level geometry with simple pygame rects, loaded from pytmx.
            self.walls = list()
            for object in mapPlay.objects:
                self.walls.append(
                    pygame.Rect(object.x, object.y, object.width,
                                object.height))

            # create new renderer (camera)
            self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                       screen.get_size())
            self.map_layer.zoom = 2

            self.group = PyscrollGroup(map_layer=self.map_layer,
                                       default_layer=4)
            self.hero = Hero('Tiles/hero/character_still.png')
            self.entity = Entity('Tiles/hero/character_still.png')
            self.hero.position = stats['pos']
            self.entity.position = stats['pos']
            # add our hero to the group
            self.group.add(self.hero)
            #self.group.add(self.entity)

            self.entVel = (0, 0)

    def deep_thought(self):  # The 'AI' function, needs work
        if self.counter2 % 75 == 0 or self.bypass == True:
            self.bypass = False
            if random.randint(0, 1) == 1:
                self.entity.velocity[0], self.entity.velocity[1] = 0, 0
            movement = random.choice([
                "self.entity.velocity[0] = -45; self.EntityDirection = 'left'; self.EntityDirection2 = 'left'",
                "self.entity.velocity[0] = 45; self.EntityDirection = 'right'; self.EntityDirection2 = 'right'",
                "self.entity.velocity[1] = -45; self.EntityDirection = 'up'; self.EntityDirection1 = 'up'",
                "self.entity.velocity[1] = 45; self.EntityDirection = 'down'; self.EntityDirection1 = 'down'"
            ])
            exec(movement)

    def EntityAnimation(self, direction, number, character="hero"):
        self.entVel = self.entity.velocity

        self.counter += 1
        if self.EntityDirection1 == "still" and self.EntityDirection2 == "still":
            if self.EntityDirection == "left":
                self.entity = Entity('Tiles/' + character +
                                     '/walking_left/walking_left1.png')
            if self.EntityDirection == "right":
                self.entity = Entity('Tiles/' + character +
                                     '/walking_right/walking_right1.png')
            if self.EntityDirection == "up":
                self.entity = Entity('Tiles/' + character +
                                     '/walking_up/walking_up1.png')
            if self.EntityDirection == "down":
                self.entity = Entity('Tiles/' + character +
                                     '/walking_down/walking_down1.png')
        else:
            self.entity = Entity('Tiles/' + character + '/walking_' +
                                 direction + '/walking_' + direction +
                                 str(number) + '.png')
        self.entity.velocity = self.entVel

    def EntMoveBack(self):
        #self.deep_thought(self, True) # Comment this to disable the 'AI'
        pass

    def map_change(self, map, target=False):  # Does what it says on the tin
        mapfile = get_map(map)
        tmx_data = load_pygame(mapfile)
        self.tmx_data = tmx_data
        map_data = pyscroll.data.TiledMapData(tmx_data)
        self.walls = list()
        for object in tmx_data.objects:
            self.walls.append(
                pygame.Rect(object.x, object.y, object.width, object.height))

        # creates new 'camera'
        self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
        self.map_layer.zoom = 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)

        #creates a new Hero to go on our new camera
        self.hero = Hero('Tiles/hero/character_still.png')
        try:
            self.hero.position = (target)
        except TypeError:
            self.hero.position = self.map_layer.map_rect.center
        self.map = stats['map'][:-4].lower()
        self.map = self.map.lstrip(
            "m")  # Fix that stupid bug that changes "maze1" to "ze1"
        self.map = self.map.lstrip("aps/")

    def switcher(
        self
    ):  # Bunch of IF statements to decide if we're at a door or not, then changes the map.
        if len(objectX) == len(objectY) == len(targetPosX) == len(targetPosY) == len(currentMap) == \
           len(targetMap) == len(animationDirection) == len(targetMapFile) == len(objectType):
            heroPos = [0, 0]
            heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[
                1]
            for i in range(len(objectX)):
                if self.map == currentMap[i]:
                    if self.hero.position[0] - 15 <= int(
                            objectX[i]) <= self.hero.position[0] + 15:
                        if self.hero.position[1] - 15 <= int(
                                objectY[i]) <= self.hero.position[1] + 15:
                            if objectType[i] == "door":
                                used[i] = True
                                self.map_change(targetMapFile[i])
                                self.map = targetMap[i]
                                stats['map'] = targetMapFile[i]
                                heroPos = (int(targetPosX[i]),
                                           int(targetPosY[i]))
                                self.animation(animationDirection[i], 1)
                                self.hero.position = heroPos
                                return False
                            elif objectType[i] == "chest":
                                keyset, self.menu = "chest", "chest"
                                if used[i] == False:
                                    if chestContents[i] == None and used[
                                            i] == False:
                                        used[i] = True
                                        pickle.dump(
                                            used,
                                            open(
                                                os.path.join(
                                                    "data", "saves",
                                                    "used.dat"), "wb"))
                                        chestContents[i] = self.genchests()
                                        pickle.dump(
                                            chestContents,
                                            open(
                                                os.path.join(
                                                    "data", "saves",
                                                    "chestContents.dat"),
                                                "wb"))
                                self.chestNo = i
                            return False

    def generate_surrounding_maps(self):
        heroPos = [0, 0]
        heroPos = self.hero.position
        if int(self.hero.position[0]) in range((self.tmx_data.width * 32) - 64,
                                               (self.tmx_data.width * 32)):
            target = (32, heroPos[1])
            self.grid[0] = self.grid[0] + 1
            try:
                self.map_change(
                    str(self.grid[0] + 1) + ", " + str(self.grid[1]) + ".tmx",
                    target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                self.animation("right", 1)
                target = (32, heroPos[1])
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[1]) in range(
            (self.tmx_data.height * 32) - 64, self.tmx_data.width * 32):
            target = (heroPos[0], 32)
            self.grid[1] = self.grid[1] + 1
            try:
                self.map_change(
                    str(self.grid[0]) + ", " + str(self.grid[1] + 1) + ".tmx",
                    target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[
                    0], self.hero.position[1]
                self.animation("up", 1)

            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[0]) in range(0, 64):
            target = (self.tmx_data.width * 32 - 32, heroPos[1])
            self.grid[0] = self.grid[0] - 1
            try:
                self.map_change(
                    str(self.grid[0] - 1) + ", " + str(self.grid[1]) + ".tmx",
                    target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[
                    0], self.hero.position[1]
                self.animation("left", 1)
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[1]) in range(0, 64):
            target = (heroPos[0], self.tmx_data.height * 32 - 32)
            self.grid[1] = self.grid[1] - 1
            try:
                self.map_change(
                    str(self.grid[0]) + ", " + str(self.grid[1] - 1) + ".tmx",
                    target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[
                    0], self.hero.position[1]
                self.animation("down", 1)
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        else:
            pass

    def generate_new_map(self, octaves, freq, area, target, position):
        command = "{}/lib/generate/__init__.py".format(os.getcwd())
        if sys.platform.startswith('win32'):
            executeable = ("Python35\python.exe")

        elif sys.platform.startswith('linux'):
            executeable = ("python3.5")

        for y in range(self.grid[1] + eval("-" + str(area)),
                       self.grid[1] + area):
            for x in range(self.grid[0] + eval("-" + str(area)),
                           self.grid[0] + area):
                if os.path.isfile("data/maps/" + str(x) + ", " + str(y) +
                                  ".tmx"):
                    pass
                else:
                    p = subprocess.Popen([
                        executeable, command,
                        ("data/maps/" + str(x) + ", " + str(y) + ".tmx"),
                        str(octaves),
                        str(freq),
                        str(x),
                        str(y)
                    ],
                                         close_fds=True)
        try:
            if p is not None:
                disp_width, disp_height = pygame.display.get_surface(
                ).get_size()
                #self.blit_inventory("speach", "Generating Map... Please Wait...")
                self.speach(disp_width, disp_height,
                            "Generating Map... Please Wait...")
                pygame.display.update()
                p.wait()
                self.map_change(
                    (str(target[0]) + ", " + str(target[1]) + ".tmx"),
                    position)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
        except UnboundLocalError:
            pass

    def draw(self, surface):
        self.group.center(self.hero.rect.center)
        # draw the map and all sprites
        self.group.draw(surface)

    def speach(self, dispWidth, dispHeight, text):
        ##        text = "Laudem bonorum salutandi pri te, tollit melius delicata mel cu,\
        ##                eu mea ullum legimus. Probo debitis te vel. Labores vulputate \
        ##                argumentum sea id. Cibo vitae vocent eos no, ne odio molestiae\
        ##                duo."
        screen.blit(
            pygame.transform.scale(
                load_image(os.path.join("images", "gui", "speach.png")),
                (dispWidth, 150)), (0, dispHeight - 150))
        text = textwrap.wrap(text, width=95)
        for i, line in enumerate(text):
            text_blit = pixel_font.render(line, False, pygame.Color('white'))
            screen.blit(text_blit, (60, dispHeight - 110 + 25 * i))

    def map_generate(self, output, octaves, freq, x, y):
        command = "{}/lib/generate/__init__.py".format(os.getcwd())

        if sys.platform.startswith('win32'):
            executeable = ("Python35\python.exe")

        elif sys.platform.startswith('linux'):
            executeable = ("python3.5")

        subprocess.Popen([
            executeable, command, output,
            str(octaves),
            str(freq),
            str(x),
            str(y)
        ],
                         close_fds=True)

    def handle_input(self, keyset):
        """ Handle pygame input events
        """

        poll = pygame.event.poll

        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                pygame.quit()
                break

            elif event.type == KEYDOWN:

                if keyset == "game":
                    if event.key == K_EQUALS:
                        self.map_layer.zoom += .25

                    elif event.key == K_MINUS:
                        value = self.map_layer.zoom - .25
                        if value > 0:
                            self.map_layer.zoom = value
                        else:
                            self.map_layer.zoom = 0.1

                    elif event.key == K_KP0:
                        try:
                            if self.switcher() == True:
                                self.generate_surrounding_maps()
                        except FileNotFoundError:
                            print("Exception Caught")
                        pass

                    elif event.key == K_e:
                        self.menu = "inventory"
                        pass

                    if event.key == K_ESCAPE:
                        for i in attack_stats_types:
                            stats[i] = attack_stats[i]
                        pickle.dump(
                            stats,
                            open(os.path.join("data", "saves", "save.dat"),
                                 "wb"))
                        pickle.dump(
                            inventory,
                            open(
                                os.path.join("data", "saves", "inventory.dat"),
                                "wb"))
                        self.running = False
                        pygame.quit()
                        print(" ")
                        sleep(0.5)
                        print("Shutdown... Complete")
                        sys.exit()
                        break

                if keyset != "game":
                    if event.key == K_ESCAPE:
                        self.menu = "game"
                        pass

                if keyset == "inventory":
                    if event.key == K_r:
                        self.genchests()

                if keyset == "chest":
                    if event.key == K_r:
                        chestContents[self.chestNo] = self.genchests()

                    if event.key == K_t:
                        if taken[self.chestNo] != True:
                            self.takeChest()
                            taken[self.chestNo] = True
                            pickle.dump(
                                taken,
                                open(
                                    os.path.join("data", "saves", "taken.dat"),
                                    "wb"))

                if keyset == "attack":
                    pass

                #Basically just debug keys
                if event.key == K_KP1:
                    self.menu = "game"
                    pass

                elif event.key == K_KP2:
                    self.map_change(FOREST)
                    self.map = "forest"

                elif event.key == K_KP3:
                    self.generate_new_map(4, 16, 3)
                    pass

                elif event.key == K_KP4:
                    self.map_generate(
                        str(self.grid[0]) + ", " + str(self.grid[1]) + ".tmx",
                        4, 16.0, self.grid[0], self.grid[1])
                    pass

                elif event.key == K_KP5:
                    self.enemy_stats = self.gen_enemy(attack_stats,
                                                      enemy_stats)
                    self.menu = "attack"
                    pass

                elif event.key == K_KP6:
                    print("X :" + str(int(self.hero.position[0])) + ", Y: " +
                          str(int(self.hero.position[1])) + ", Map: " +
                          self.map)
                    pass

                elif event.key == K_KP7:
                    print(str(pygame.mouse.get_pos()))
                    pass

                elif event.key == K_KP8:
                    sleep(0.5)

                elif event.key == K_KP9:
                    editor = db_interface.Editor()
                    conn = sqlite3.connect('data/saves/data.db')
                    c = conn.cursor()

                    for var in vars:
                        exec("del " + var + "[:]")
                        for data in c.execute(
                                "SELECT {} FROM csv".format(var)):
                            data = str(data[0])
                            exec("{}.append(\"{}\")".format(var, data))
                            pass

                elif event.key == K_F11:
                    for m in screeninfo.get_monitors():
                        displ = str(m)
                        w, h, mx, c = displ.split(", ")

                    if self.fullscreen:
                        self.fullscreen = False
                        screen = init_screen(
                            1024, 700, pygame.HWSURFACE | pygame.FULLSCREEN)
                    else:
                        self.fullscreen = True
                        screen = init_screen(
                            w, h, pygame.HWSURFACE | pygame.RESIZABLE)

                    pygame.display.toggle_fullscreen()

            elif event.type == VIDEORESIZE:
                self.map_layer.set_size((event.w, event.h))
                dispHeight = event.h
                dispWidth = event.w

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        if keyset == "game":
            pressed = pygame.key.get_pressed()
            if pressed[K_UP]:
                self.hero.velocity[1] = -HERO_MOVE_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_DOWN]:
                self.hero.velocity[1] = HERO_MOVE_SPEED
                self.direction = "down"
                self.direction2 = "down"
            elif pressed[K_w]:
                self.hero.velocity[1] = -HERO_SPRINT_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_s]:
                self.hero.velocity[1] = HERO_SPRINT_SPEED
                self.direction = "down"
                self.direction2 = "down"
            else:
                self.hero.velocity[1] = 0
                self.direction2 = "still"
            if pressed[K_LEFT]:
                self.hero.velocity[0] = -HERO_MOVE_SPEED
                self.direction = "left"
                self.direction1 = "left"
            elif pressed[K_RIGHT]:
                self.hero.velocity[0] = HERO_MOVE_SPEED
                self.direction = "right"
                self.direction1 = "right"
            elif pressed[K_a]:
                self.hero.velocity[0] = -HERO_SPRINT_SPEED
                self.direction = "left"
                self.direction1 = "left"
            elif pressed[K_d]:
                self.hero.velocity[0] = HERO_SPRINT_SPEED
                self.direction = "right"
                self.direction1 = "right"
            else:
                self.hero.velocity[0] = 0
                self.direction1 = "still"

            if self.direction1 == "still" and self.direction2 == "still":
                self.direction = "still"

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def animation(self, direction, number):
        if self.direction1 == "still" and self.direction2 == "still":
            if self.direction == "left":
                self.hero = Hero('Tiles/hero/walking_left/walking_left1.png')
            if self.direction == "right":
                self.hero = Hero('Tiles/hero/walking_right/walking_right1.png')
            if self.direction == "up":
                self.hero = Hero('Tileshero/walking_up/walking_up1.png')
            if self.direction == "down":
                self.hero = Hero('Tiles/hero/walking_down/walking_down1.png')

        else:
            self.hero = Hero('Tiles/hero/walking_' + direction + '/walking_' +
                             direction + str(number) + '.png')

    def genchests(self):

        wr = WeightedRandomizer(itemsProbability)

        self.taken = False
        chest.clear()
        numItems = random.randint(1, random.randint(2, 4))
        if random.randint(0, 3) < 1:
            numItems += 1
        elif random.randint(0, 9) < 2:
            numItems += 2
        elif random.randint(0, 18) < 2:
            numItems += 5
        for i in range(0, numItems):
            item = wr.random()
            while item in chest:
                item = wr.random()
            chest.append(item)

        return chest

    def gen_enemy(self, player_stats, enemy_stat):
        stats = attack_stats_types
        stat = player_stats
        for i in range(len(player_stats)):
            j = stats[i]
            try:
                enemy_stat[
                    stats[i]] = int((stat[j] - (stat[j] * 0.2)) +
                                    random.randint(0, int(stat[j] * 0.4)))
            except TypeError:
                enemy_stat[j] = choice(attack_types)
        return enemy_stat
        pass

    def player_attack():
        type = None
        while type not in attack_types:
            type = input("[ QUESTION ] Enter attack type. ")
            if type not in attack_types:
                print(
                    "[ ERROR    ] Attack type {} not found. Must be {}".format(
                        type, attack_types))
            else:
                break
        return type
        pass

    def attack(self, attacker_stats, defender_stats, player_attack_type):
        fraction = attacker_stats['strength'] / defender_stats['blocking']
        print("[ INFO     ] Defender attack type: {}".format(
            defender_stats['attack']))
        if player_attack_type != defender_stats['attack']:
            if fraction > (0.8 + (randint(0, 40) / 100)):
                attacker_stats['health'] -= int(fraction * 10)
                pass  # Attacker Win
            else:
                defender_stats['health'] -= int(fraction * 10)
                pass  # Attacker Loss
        elif player_attack_type == attacker_stats[
                'attack']:  # Better odds here
            if fraction > (0.9 + (randint(0, 40) / 100)):
                attacker_stats['health'] -= int(fraction * 10)
                pass  # Attacker Win
            else:
                defender_stats['health'] -= int(fraction * 10)
                pass  # Attacker Loss
        else:
            if fraction > (0.70 +
                           (randint(0, 40) / 100)):  # Odds are worse here
                attacker_stats['health'] -= int(fraction * 10)
                pass  # Attacker Win
            else:
                defender_stats['health'] -= int(fraction * 10)
                pass  # Attacker Loss
        print("[ INFO     ] Attacker: {}  Defender: {}".format(
            attacker_stats['health'], defender_stats['health']))
        print("[ INFO     ] Health to be lost: {}".format(int(fraction * 10)))
        return attacker_stats, defender_stats

    def blit_inventory(self, screenMode, speach=None):
        if screenMode != "game":
            xCounter, counter, OverCounter = 0, 0, 0
            dispWidth, dispHeight = pygame.display.get_surface().get_size()
            guiX = (dispWidth / 2) - 175
            guiY = (dispHeight / 2) - 165
            screen.blit(
                load_image(os.path.join("images", "gui", "transparent.png")),
                (0, 0))
            screen.blit(
                load_image(os.path.join("images", "gui", screenMode + ".png")),
                (guiX, guiY))
        if screenMode == "inventory" or screenMode == "chest":
            dt = (clock.tick() / 500)
            clock.tick(self.fps)

            if len(inventory) > 0:
                for i in range(0, len(inventory)):
                    OverCounter += 1
                    if xCounter >= 9:
                        counter += 1
                        xCounter = 0
                    screen.blit(load_image(os.path.join("images", "items",\
                    str(items[inventory[i]])+".png")), (guiX + 16 + 36*xCounter, guiY + 168 + 36*counter))
                    xCounter += 1
        if screenMode == "chest" and chestContents[self.chestNo] != None:
            itemNo = 0
            for i in range(0, len(chestContents[self.chestNo])):
                screen.blit(load_image(os.path.join("images", "items",\
                            items[str(chestContents[self.chestNo][i])]\
                            +".png")), (guiX + 123 + 36*itemNo,\
                            guiY + 34 + int(35 * (i/3)) - int(35 * (i/3)) % 35))

                if itemNo < 2:
                    itemNo += 1
                else:
                    itemNo = 0

        if screenMode == "speach":
            self.speach(dispWidth, dispHeight, speach)
        if screenMode == "attack":
            picture = load_image(
                os.path.join("Tiles", "hero", "walking_down",
                             "walking_down1.png"))
            picture = pygame.transform.scale(picture, (100, 100))
            rect = picture.get_rect()
            rect = rect.move((guiX + 50, guiY + 28))
            screen.blit(picture, rect)
            text = font.render("Player : Enemy", True, pygame.Color('black'))
            screen.blit(text, (guiX + 172, guiY + 45))
            text = "Health: " + str(
                attack_stats['health']) + "    Skill: " + str(
                    attack_stats['skill']) + "    Attack: " + str(
                        attack_stats['attack'])
            text_render = pixel_font.render(text, False,
                                            pygame.Color('gray27'))
            screen.blit(text_render, (guiX + 20, guiY + 290))
            for i, attack in enumerate(attack_types):
                text = load_font(30, "data/PixelFont.ttf").render(
                    attack, False, pygame.Color('black'))
                screen.blit(text, (guiX + 172, guiY + 25 + 28 * (i + 2)))
            #
            if pygame.mouse.get_pressed()[0] == 1:
                #print(pygame.mouse.get_pos())
                mouse_pos = pygame.mouse.get_pos()
                if guiX + 160 < mouse_pos[0] and guiX + 330 > mouse_pos[0]:
                    for i, attack in enumerate(attack_types):
                        if guiY + 25 + 28 * (i + 2) < mouse_pos[1] and (
                                guiY + 25 + 28 * (i + 2)) + 28 > mouse_pos[1]:
                            print(attack)
                            self.attack(attack_stats, enemy_stats, attack)
                        else:
                            pass

            pass

    def takeChest(self):
        if len(inventory) < 27:
            if chestContents[self.chestNo] != None:
                for i in range(0, (len(chestContents[self.chestNo]))):
                    #print(i)
                    inventory.append(chestContents[self.chestNo][i])
                chestContents[self.chestNo][:] = []
            pickle.dump(
                chestContents,
                open(os.path.join("data", "saves", "chestContents.dat"), "wb"))

    def run(self):
        screenMode = pygame.RESIZABLE

        oldPlay = stats['playTime']
        clock = pygame.time.Clock()
        self.running = True

        self.grid = [0, 0]

        debug = True
        dispWidth, dispHeight = 1024, 768
        self.menu = "game"
        game_time = pygame.time.get_ticks()
        playTime = font.render("Timer: ", False, pygame.Color('white'))
        minutes = 0

        self.map = stats['map'][:-4].lower()
        self.map = self.map.lstrip(
            "m")  # Fix that stupid bug that changes "maze1" to "ze1"
        self.map = self.map.lstrip("aps/")

        try:
            while self.running:
                dt = (clock.tick() / 500)
                clock.tick(self.fps)

                if self.menu == "game":
                    #self.deep_thought()
                    if self.counter2 % 7 == 0:
                        heroPos = self.hero.position
                        self.animation(self.direction, self.counter)
                        self.hero.position = heroPos
                        #entityPos = self.entity.position
                        #self.EntityAnimation(self.EntityDirection, self.counter, "princess")
                        #self.entity.position = entityPos

                        self.counter += 1
                        guiX = (dispWidth / 2) - 175
                        guiY = (dispHeight / 2) - 165

                        self.group.remove(self.hero)
                        #self.group.remove(self.entity)
                        self.group.empty()
                        self.group.add(self.hero)
                        #self.group.add(self.entity)

                self.counter2 += 1
                if self.counter > 8:
                    self.counter = 1

                stats['pos'] = self.hero.position
                currentTime = systime()
                seconds = currentTime - gameStart + oldPlay
                dispWidth, dispHeight = pygame.display.get_surface().get_size()
                stats['playTime'] = seconds

                if debug == True and self.counter2 % 1 == 0:
                    location = font.render(
                        "Position: " +
                        str(round(round(self.hero.position[0], -1) / 10)) +
                        ", " +
                        str(round(round(self.hero.position[1], -1) / 10)),
                        False, pygame.Color('white'))
                    mapdebug = font.render("Map Name: " + str(self.map), False,
                                           pygame.Color('white'))
                    minutes = seconds // 60
                    secondsDisp = seconds % 60
                    if minutes < 1:
                        minutes = 0
                    if secondsDisp == 60:
                        secondsDisp = 0
                        minutes += 1
                    fps = font.render("FPS:" + str(int(clock.get_fps())),
                                      False, pygame.Color('white'))
                    screen.blit(fps, (50, 50))
                    screen.blit(playTime, (50, 100))
                    screen.blit(location, (50, 75))
                    screen.blit(mapdebug, (50, 125))

                    playTime = font.render(
                        "Timer: " + str(floor(minutes)) + " : " +
                        str(round(secondsDisp)), True, pygame.Color('white'))
                    screen.blit(playTime, (50, 100))

                self.blit_inventory(str(self.menu))

                pygame.display.update()
                #pygame,display.flip()
                self.handle_input(self.menu)
                self.update(dt)
                self.draw(screen)

        except KeyboardInterrupt:
            self.running = False
            pygame.quit()