Example #1
0
class Game:
    '''
    Class to define an individual game
    Each game is represented as an object
    '''
    def __init__(self, level, time, lives):
        '''
        Initializes game, includes:
        1. Setup map+screen, player 1, position player on map
        2. Set numeric codes for class instances
        3. Starts the game timer
        4. Initializes any other variables needed for each game
        '''

        self.screen = Screen(36, 96, level, self)

        self.player = Mario(self, lives)

        # 0: Back, 1: Cloud (Back) ...  5. Mario, 6. Brick, 7. PowerUp

        self.codes = [Backg(), Cloud(), None, None, None, self.player, Brick()]
        for temp in range(1000):
            self.codes.append(None)
            temp += 1
            temp -= 1

        self.screen.position(self.player)

        self.stime = timer()
        self.etime = self.stime + time

        # self.count - self.count_l indicates number of
        # enemies onscreen within any cycle
        self.count = 20
        self.count_l = 20

        self.level = level

        self.points = 0

    def change_state(self, keypress):
        '''
        Calculates and applies changes within each cycle
        '''

        # To check if life is lost within cycle
        clife = self.player.lives

        # Apply mario movement
        self.player.move(keypress)

        # Update background (right/left)
        if self.player.get_loc()[1] > self.screen.offset + configs.OFFSTRAIGHT:
            self.screen.offset += 1

        # Generate any enemies
        if self.level != 0:
            self.generate_enemy()

        # Apply gravity and movement
        # > On powerup
        if self.codes[7] is not None:
            self.codes[7].vertical()
            if (self.get_time() // 1) % 2 == 0:
                self.codes[7].move(1)

        # > On enemy
        for enemy in range(self.count_l, self.count):
            if self.codes[enemy] is not None:
                self.codes[enemy].vertical()
                self.codes[enemy].move()

        # > On boss
        if self.codes[999] is not None:
            self.codes[999].move()
            if self.player.j > configs.LEV_J // 2:
                self.codes[999].vertical()

        # > On player
        self.player.vertical()

        # Check interactions
        # > Checks which enemy is alive and updates accordingly
        for enemy in range(self.count_l, self.count):
            enj = self.codes[enemy]
            if enj is not None:
                if enj.lives <= 0:
                    self.erase(enemy, 1, enj.i, enj.j)
                    self.count_l += 1

        # > Checks if player is alive and updates accordingly
        if self.player.lives < clife:
            return -1

        # Crossed game level
        if self.player.j >= 400:
            return 1

        return 0

    def generate_enemy(self):
        '''
        Creates an enemy
        '''

        if random() < configs.PROB_ENEMY:
            copy_j = self.screen.offset + configs.DIM_J - randrange(10)
            copy_i = 1
            mush = Enemy(self, self.count, copy_i, copy_j)
            self.screen.position(mush)
            self.codes[self.count] = mush
            self.count += 1

        if self.level == 2 and self.player.j == 50:
            boss = Boss(self, 999, 8, 50)
            self.screen.position(boss)
            self.codes[999] = boss

    def erase(self, objn, direct, copy_i, copy_j):
        '''
        Recursively erases all elements of type objn in direct contact
        '''

        if direct == 1:
            i = copy_i
            j = copy_j + 1
        elif direct == 2:
            i = copy_i
            j = copy_j - 1
        elif direct == 3:
            i = copy_i - 1
            j = copy_j
        elif direct == 4:
            i = copy_i + 1
            j = copy_j

        if i >= 36 or i <= -1:
            return

        if self.screen.gmap[i, j] == objn:
            self.screen.add(Backg(), i, i + 1, j, j + 1)
            for k in range(1, 5):
                self.erase(objn, k, i, j)

    def delete(self):
        '''
        compatibility
        '''
        pass

    def repaint(self):
        '''
        Repaints the board
        '''
        clear()
        self.screen.render()
        self.headline()

    def headline(self):
        '''
        Part of the render, gives status
        '''
        print('Level: ' + str(self.level) + '\t\u23f1 : ' +
              str(self.get_t_remain() // 1) + '\t\u2661 : ' +
              str(self.player.lives))
        print('POINTS: ' + str(self.points))

    @classmethod
    def level_screen(cls, level, lives, points):
        '''
        Printed in between levels
        '''
        clear()
        print("Level: " + str(level))
        print("Lives left: " + str(lives))
        print("Total Points: " + str(points))
        print("Press any key to continue")

    def get_t_remain(self):
        '''
        returns the time remaining for a game
        '''
        return self.etime - timer()

    def get_t_past(self):
        '''
        returns the time elapsed in a game
        '''
        return timer() - self.stime

    @classmethod
    def get_time(cls):
        '''
        returns the current time
        '''
        return timer()