Beispiel #1
0
    def __init__(self, screen):
        super(PlatformingScene, self).__init__(screen)

        self.background_drawn = False
        self.headersize = 30

        self.camera = pygame.rect.Rect(0, 0, game_constants.w,
                                       game_constants.h)
        self.special_chars = SpecialChars()
        self.movelist = []
        self.time_elapsed = 0

        self.health = Health(5)
        self.score = Score(screen)
        self.player = Player(
            (screen.get_width() / 2, screen.get_height() / 2 - 30))
        self.playergroup = RenderUpdatesDraw(self.player)

        self.platforms = {}
        self.platforms[game_constants.h - 80] = [
            general.Box(-10000, game_constants.h - 80, 20000, 16)
        ]

        self.statics = RenderUpdatesDraw()
        self.statics.add(self.platforms.values()[0])
        self.screenstatics = RenderUpdatesDraw()
        self.actives = RenderUpdatesDraw()
        self.powerups = RenderUpdatesDraw()

        self.place_platforms()
        self.player.colliders = self.screenstatics

        self.header = pygame.Surface((screen.get_width(), self.headersize))
        self.header.fill(Color.BLACK)

        self.background = pygame.Surface(screen.get_size()).convert()

        gradiation = 128.0
        for i in xrange(int(gradiation)):
            color = (150 - (i * 150 / gradiation),
                     150 - (i * 150 / gradiation), 200)
            rect = (0, i * game_constants.h / gradiation, game_constants.w,
                    game_constants.h / gradiation + 1)
            self.background.fill(color, rect)

        # Move sprites into or out of 'screenstatics' group based on whether they're in camera
        self.screencheck()

        # fixme: rearchitect this
        self.challenging = False
Beispiel #2
0
    def __init__(self, screen):
        super(PlatformingScene, self).__init__(screen)

        self.background_drawn = False
        self.headersize = 30

        self.camera = pygame.rect.Rect(0, 0, game_constants.w, game_constants.h)
        self.special_chars = SpecialChars()
        self.movelist = []
        self.time_elapsed = 0

        self.health = Health(5)
        self.score = Score(screen)
        self.player = Player((screen.get_width() / 2, screen.get_height() / 2 - 30))
        self.playergroup = RenderUpdatesDraw(self.player)

        self.platforms = {}
        self.platforms[game_constants.h - 80] = [general.Box(-10000, game_constants.h - 80, 20000, 16)]

        self.statics = RenderUpdatesDraw()
        self.statics.add(self.platforms.values()[0])
        self.screenstatics = RenderUpdatesDraw()
        self.actives = RenderUpdatesDraw()
        self.powerups = RenderUpdatesDraw()

        self.place_platforms()
        self.player.colliders = self.screenstatics

        self.header = pygame.Surface((screen.get_width(), self.headersize))
        self.header.fill(Color.BLACK)

        self.background = pygame.Surface(screen.get_size()).convert()

        gradiation = 128.0
        for i in xrange(int(gradiation)):
            color = (150 - (i * 150 / gradiation), 150 - (i * 150 / gradiation), 200)
            rect = (0, i * game_constants.h / gradiation, game_constants.w, game_constants.h / gradiation + 1)
            self.background.fill(color, rect)

        # Move sprites into or out of 'screenstatics' group based on whether they're in camera
        self.screencheck()

        # fixme: rearchitect this
        self.challenging = False
Beispiel #3
0
class PlatformingScene(BaseScene):
    """ Class for the main playable game environment. """
    def __init__(self, screen):
        super(PlatformingScene, self).__init__(screen)

        self.background_drawn = False
        self.headersize = 30

        self.camera = pygame.rect.Rect(0, 0, game_constants.w,
                                       game_constants.h)
        self.special_chars = SpecialChars()
        self.movelist = []
        self.time_elapsed = 0

        self.health = Health(5)
        self.score = Score(screen)
        self.player = Player(
            (screen.get_width() / 2, screen.get_height() / 2 - 30))
        self.playergroup = RenderUpdatesDraw(self.player)

        self.platforms = {}
        self.platforms[game_constants.h - 80] = [
            general.Box(-10000, game_constants.h - 80, 20000, 16)
        ]

        self.statics = RenderUpdatesDraw()
        self.statics.add(self.platforms.values()[0])
        self.screenstatics = RenderUpdatesDraw()
        self.actives = RenderUpdatesDraw()
        self.powerups = RenderUpdatesDraw()

        self.place_platforms()
        self.player.colliders = self.screenstatics

        self.header = pygame.Surface((screen.get_width(), self.headersize))
        self.header.fill(Color.BLACK)

        self.background = pygame.Surface(screen.get_size()).convert()

        gradiation = 128.0
        for i in xrange(int(gradiation)):
            color = (150 - (i * 150 / gradiation),
                     150 - (i * 150 / gradiation), 200)
            rect = (0, i * game_constants.h / gradiation, game_constants.w,
                    game_constants.h / gradiation + 1)
            self.background.fill(color, rect)

        # Move sprites into or out of 'screenstatics' group based on whether they're in camera
        self.screencheck()

        # fixme: rearchitect this
        self.challenging = False

    def lazy_redraw(self):
        return False

    def fill_level(self, height):
        platform_level = self.platforms.setdefault(height, [])

        max_right = self.camera.right + game_constants.w
        min_left = self.camera.left - game_constants.w

        # cull platforms that have gone too far -- TODO this doesn't work yet
        bad_platforms = [
            p for p in platform_level
            if p.rect.left > max_right or p.rect.right < min_left
        ]
        [platform_level.remove(p) for p in bad_platforms]
        [self.statics.remove(p) for p in bad_platforms]

        # add on platforms until the limit is reached
        if not len(platform_level):
            leftmost = random.randint(-game_constants.w, game_constants.w)
            rightmost = leftmost = random.randint(-game_constants.w,
                                                  game_constants.w)
        else:
            leftmost = min([p.rect.left for p in platform_level])
            rightmost = max([p.rect.right for p in platform_level])

        while rightmost < max_right:
            new_start = rightmost + random.randint(150, 300)
            new_width = random.randint(200, 1000)
            new_width = new_width - new_width % 16  # Cut off to the nearest multiple of 16
            new_p = Platform(new_start, height, new_width, 16)
            platform_level.append(new_p)
            self.statics.add(new_p)
            rightmost = new_start + new_width
        while leftmost > min_left:
            new_start = leftmost - random.randint(150, 300)
            new_width = random.randint(200, 1000)
            new_width = new_width - new_width % 16  # Cut off to the nearest multiple of 16
            new_p = Platform(new_start - new_width, height, new_width, 16)
            platform_level.append(new_p)
            self.statics.add(new_p)
            leftmost = new_start - new_width

    def place_platforms(self):
        # Generate platforms based on camera position: Make sure there are always platforms extending at least as far as +-4*game_constants.w, +-4*game_constants.h from the player
        max_height = self.camera.top - 2 * game_constants.h
        lowest = max(self.platforms.keys())
        highest = min(self.platforms.keys())

        for h in range(highest, lowest, 80):
            self.fill_level(h)

        while highest > max_height:
            highest -= 80
            self.fill_level(highest)

    def draw_background(self):
        self.screen.blit(self.background, (0, 0))
        self.screen.blit(self.header, (0, 0))
        pygame.display.update()
        self.background_drawn = True

    def draw_header(self):
        dirty = []
        self.screen.set_clip(0, 0, game_constants.w,
                             self.headersize)  # Only draw in header area
        self.score.clear(self.screen, self.header)
        self.health.clear(self.screen, self.header)
        dirty += self.score.draw(self.screen, self.time_elapsed)
        dirty += self.health.draw(self.screen)
        return dirty

    def draw(self):
        if not self.background_drawn:
            self.draw_background()

        self.camshift()

        header_dirty = self.draw_header()

        dirty = []

        # Don't draw over header
        self.screen.set_clip(0, self.headersize, game_constants.w,
                             game_constants.h)

        rect_sources = [
            self.screenstatics,
            self.powerups,
            self.actives,
            self.playergroup,
            self.player.bullets,
        ]

        for rect_source in rect_sources:
            rect_source.clear(self.screen, self.background)

        for rect_source in rect_sources:
            dirty += rect_source.draw(self.screen, self.camera)

        # hack: repaint selected_opponent to make sure it's visible
        if self.player.selected_opponent:
            dirty += [
                self.player.selected_opponent.draw(self.screen, self.camera)
            ]

        # Constrain all dirty rectangles in main game area to main game area.
        dirty = [
            dirty_rect.clip(self.screen.get_clip()) for dirty_rect in dirty
        ]

        return header_dirty + dirty

    def camshift(self):
        newpos = self.player.rect
        bounds = self.camera.inflate(-game_constants.w + 50,
                                     -game_constants.h + 100)
        # Move the screen if we're near the edge
        if newpos.right > bounds.right:
            self.camera = self.camera.move(newpos.right - bounds.right, 0)
        elif newpos.left < bounds.left:
            self.camera = self.camera.move(newpos.left - bounds.left, 0)
        if newpos.bottom > bounds.bottom:
            self.camera = self.camera.move(0, newpos.bottom - bounds.bottom)
        elif newpos.top < bounds.top:
            self.camera = self.camera.move(0, newpos.top - bounds.top)
        self.screencheck()

    def screencheck(self):
        """Classify objects by whether they are on the screen"""

        for platform_level in self.platforms.values():
            for platform in platform_level:
                if platform not in self.screenstatics:
                    # This platform wasn't on the screen: is it now?
                    if platform.rect.colliderect(self.camera):
                        self.screenstatics.add(platform)
                        # If it's a platform (has the attribute'word') give it an
                        #   identifying word while it's onscreen
                        if hasattr(platform, 'word'):
                            platform.word = Word(self.special_chars.new(),
                                                 platform.font)
                else:
                    # This platform is on the screen: is it gone now?
                    if not platform.rect.colliderect(self.camera):
                        self.screenstatics.remove(platform)
                        # If it's a platform (has the attribute'word')
                        #  and it's out of camera, free up its symbol for later use
                        if hasattr(platform, 'word'):
                            self.special_chars.release(platform.word.string)
                            platform.word = None
        for sprite in self.powerups.sprites():
            if not sprite.rect.colliderect(
                    self.camera.inflate(game_constants.w, 0)):
                sprite.kill()
        for sprite in self.actives.sprites(
        ):  # need a list because we're going to delete from it
            # Opponents are allowed to be a full screen width outside of camera, but no further
            if not sprite.rect.colliderect(
                    self.camera.inflate(game_constants.w, 0)):
                if sprite == self.player.selected_opponent:
                    self.player.selected_opponent = None
                sprite.kill()

    def is_reachable(self, platform):
        player_rect = self.player.rect
        """ Is it possible for the player to jump to this platform in the concievable future? """
        # Test 1: the platform must be within jumping height
        if player_rect.bottom - game_constants.maxjump_height < platform.rect.top < player_rect.bottom:
            # Test 2: the player cannot be under the platform
            if (player_rect.right < platform.rect.left):
                # Test 3: the path from the player position to the optimal jump position must be contiguous
                jumpdist = platform.rect.left - player_rect.right
                if jumpdist < game_constants.maxjump_width:  # Maximum distance that can be jumped
                    return True
                else:
                    start = (player_rect.right, player_rect.bottom)
                    size = (jumpdist - game_constants.maxjump_width, 1)
                    testrect = pygame.rect.Rect(start, size)
                    for collider in self.screenstatics:
                        if collider.rect.contains(testrect):
                            return True
            elif (player_rect.left > platform.rect.right):
                # Test 3: the path from the player position to the optimal jump position must be contiguous
                jumpdist = player_rect.left - platform.rect.right
                if jumpdist < game_constants.maxjump_width:  # Maximum distance that can be jumped
                    return True
                else:
                    start = (platform.rect.right +
                             game_constants.maxjump_width, player_rect.bottom)
                    size = (jumpdist - game_constants.maxjump_width, 1)
                    testrect = pygame.rect.Rect(start, size)
                    for collider in self.screenstatics:
                        if collider.rect.contains(testrect):
                            return True

    def tick(self, elapsed):
        self.place_platforms()

        self.time_elapsed += elapsed

        for direction in self.movelist:
            self.player.direct(direction)

        for active_obj in self.actives:
            active_obj.tick(self.player.rect.center)

        for powerup in self.powerups:
            powerup.tick()

        for screenstatic in self.screenstatics:  # Objects on the screen
            # Only platforms have a 'word' attribute
            if hasattr(screenstatic, 'word'):
                # Will it be possible to get to this object without having to walk on air
                screenstatic.reachable = self.is_reachable(screenstatic)
        self.player.tick()

        if (self.health.value() <= 0):
            self.switch_to = GameOverScene(self.screen)

    def type_special(self, key):  # Typing a special character
        for platform_level in self.platforms.values():
            for platform in platform_level:
                if hasattr(platform, 'word'):  # HACK to ignore bottom platform
                    if platform.reachable and self.camera.colliderect(
                            platform.rect):
                        if key == platform.contents():
                            return platform
Beispiel #4
0
class PlatformingScene(BaseScene):
    """ Class for the main playable game environment. """
    def __init__(self, screen):
        super(PlatformingScene, self).__init__(screen)

        self.background_drawn = False
        self.headersize = 30

        self.camera = pygame.rect.Rect(0, 0, game_constants.w, game_constants.h)
        self.special_chars = SpecialChars()
        self.movelist = []
        self.time_elapsed = 0

        self.health = Health(5)
        self.score = Score(screen)
        self.player = Player((screen.get_width() / 2, screen.get_height() / 2 - 30))
        self.playergroup = RenderUpdatesDraw(self.player)

        self.platforms = {}
        self.platforms[game_constants.h - 80] = [general.Box(-10000, game_constants.h - 80, 20000, 16)]

        self.statics = RenderUpdatesDraw()
        self.statics.add(self.platforms.values()[0])
        self.screenstatics = RenderUpdatesDraw()
        self.actives = RenderUpdatesDraw()
        self.powerups = RenderUpdatesDraw()

        self.place_platforms()
        self.player.colliders = self.screenstatics

        self.header = pygame.Surface((screen.get_width(), self.headersize))
        self.header.fill(Color.BLACK)

        self.background = pygame.Surface(screen.get_size()).convert()

        gradiation = 128.0
        for i in xrange(int(gradiation)):
            color = (150 - (i * 150 / gradiation), 150 - (i * 150 / gradiation), 200)
            rect = (0, i * game_constants.h / gradiation, game_constants.w, game_constants.h / gradiation + 1)
            self.background.fill(color, rect)

        # Move sprites into or out of 'screenstatics' group based on whether they're in camera
        self.screencheck()

        # fixme: rearchitect this
        self.challenging = False

    def lazy_redraw(self):
        return False

    def fill_level(self, height):
        platform_level = self.platforms.setdefault(height, [])

        max_right = self.camera.right + game_constants.w
        min_left = self.camera.left - game_constants.w

        # cull platforms that have gone too far -- TODO this doesn't work yet
        bad_platforms = [p for p in platform_level if p.rect.left > max_right or p.rect.right < min_left]
        [platform_level.remove(p) for p in bad_platforms]
        [self.statics.remove(p) for p in bad_platforms]

        # add on platforms until the limit is reached
        if not len(platform_level):
            leftmost = random.randint(-game_constants.w, game_constants.w)
            rightmost = leftmost = random.randint(-game_constants.w, game_constants.w)
        else:
            leftmost = min([p.rect.left for p in platform_level])
            rightmost = max([p.rect.right for p in platform_level])

        while rightmost < max_right:
            new_start = rightmost + random.randint(150, 300)
            new_width = random.randint(200, 1000)
            new_width = new_width - new_width % 16 # Cut off to the nearest multiple of 16
            new_p = Platform(new_start, height, new_width, 16)
            platform_level.append(new_p)
            self.statics.add(new_p)
            rightmost = new_start + new_width
        while leftmost > min_left:
            new_start = leftmost - random.randint(150, 300)
            new_width = random.randint(200, 1000)
            new_width = new_width - new_width % 16 # Cut off to the nearest multiple of 16
            new_p = Platform(new_start - new_width, height, new_width, 16)
            platform_level.append(new_p)
            self.statics.add(new_p)
            leftmost = new_start - new_width

    def place_platforms(self):
        # Generate platforms based on camera position: Make sure there are always platforms extending at least as far as +-4*game_constants.w, +-4*game_constants.h from the player
        max_height = self.camera.top - 2 * game_constants.h
        lowest = max(self.platforms.keys())
        highest = min(self.platforms.keys())

        for h in range(highest, lowest, 80):
            self.fill_level(h)

        while highest > max_height:
            highest -= 80
            self.fill_level(highest)

    def draw_background(self):
        self.screen.blit(self.background, (0, 0))
        self.screen.blit(self.header, (0, 0))
        pygame.display.update()
        self.background_drawn = True

    def draw_header(self):
        dirty = []
        self.screen.set_clip(0, 0, game_constants.w, self.headersize) # Only draw in header area
        self.score.clear(self.screen, self.header)
        self.health.clear(self.screen, self.header)
        dirty += self.score.draw(self.screen, self.time_elapsed)
        dirty += self.health.draw(self.screen)
        return dirty

    def draw(self):
        if not self.background_drawn:
            self.draw_background()

        self.camshift()

        header_dirty = self.draw_header()

        dirty = []

        # Don't draw over header
        self.screen.set_clip(0, self.headersize, game_constants.w, game_constants.h)

        rect_sources = [
            self.screenstatics,
            self.powerups,
            self.actives,
            self.playergroup,
            self.player.bullets,
        ]

        for rect_source in rect_sources:
            rect_source.clear(self.screen, self.background)

        for rect_source in rect_sources:
            dirty += rect_source.draw(self.screen, self.camera)

        # hack: repaint selected_opponent to make sure it's visible
        if self.player.selected_opponent:
            dirty += [self.player.selected_opponent.draw(self.screen, self.camera)]

        # Constrain all dirty rectangles in main game area to main game area.
        dirty = [dirty_rect.clip(self.screen.get_clip()) for dirty_rect in dirty]

        return header_dirty + dirty

    def camshift(self):
        newpos = self.player.rect
        bounds = self.camera.inflate(-game_constants.w + 50, -game_constants.h + 100)
        # Move the screen if we're near the edge
        if newpos.right > bounds.right:
            self.camera = self.camera.move(newpos.right - bounds.right, 0)
        elif newpos.left < bounds.left:
            self.camera = self.camera.move(newpos.left - bounds.left, 0)
        if newpos.bottom > bounds.bottom:
            self.camera = self.camera.move(0, newpos.bottom - bounds.bottom)
        elif newpos.top < bounds.top:
            self.camera = self.camera.move(0, newpos.top - bounds.top)
        self.screencheck()

    def screencheck(self):
        """Classify objects by whether they are on the screen"""

        for platform_level in self.platforms.values():
            for platform in platform_level:
                if platform not in self.screenstatics:
                    # This platform wasn't on the screen: is it now?
                    if platform.rect.colliderect(self.camera):
                        self.screenstatics.add(platform)
                        # If it's a platform (has the attribute'word') give it an
                        #   identifying word while it's onscreen
                        if hasattr(platform, 'word'):
                            platform.word = Word(self.special_chars.new(), platform.font)
                else:
                    # This platform is on the screen: is it gone now?
                    if not platform.rect.colliderect(self.camera):
                        self.screenstatics.remove(platform)
                        # If it's a platform (has the attribute'word')
                        #  and it's out of camera, free up its symbol for later use
                        if hasattr(platform, 'word'):
                            self.special_chars.release(platform.word.string)
                            platform.word = None
        for sprite in self.powerups.sprites():
            if not sprite.rect.colliderect(self.camera.inflate(game_constants.w, 0)):
                sprite.kill()
        for sprite in self.actives.sprites(): # need a list because we're going to delete from it
            # Opponents are allowed to be a full screen width outside of camera, but no further
            if not sprite.rect.colliderect(self.camera.inflate(game_constants.w, 0)):
                if sprite == self.player.selected_opponent:
                    self.player.selected_opponent = None
                sprite.kill()

    def is_reachable(self, platform):
        player_rect = self.player.rect
        """ Is it possible for the player to jump to this platform in the concievable future? """
        # Test 1: the platform must be within jumping height
        if player_rect.bottom - game_constants.maxjump_height < platform.rect.top < player_rect.bottom:
            # Test 2: the player cannot be under the platform
            if (player_rect.right < platform.rect.left):
                # Test 3: the path from the player position to the optimal jump position must be contiguous
                jumpdist = platform.rect.left - player_rect.right
                if jumpdist < game_constants.maxjump_width: # Maximum distance that can be jumped
                    return True
                else:
                    start = (player_rect.right, player_rect.bottom)
                    size = (jumpdist - game_constants.maxjump_width, 1)
                    testrect = pygame.rect.Rect(start, size)
                    for collider in self.screenstatics:
                        if collider.rect.contains(testrect):
                            return True
            elif (player_rect.left > platform.rect.right):
                # Test 3: the path from the player position to the optimal jump position must be contiguous
                jumpdist = player_rect.left - platform.rect.right
                if jumpdist < game_constants.maxjump_width: # Maximum distance that can be jumped
                    return True
                else:
                    start = (platform.rect.right + game_constants.maxjump_width, player_rect.bottom)
                    size = (jumpdist - game_constants.maxjump_width, 1)
                    testrect = pygame.rect.Rect(start, size)
                    for collider in self.screenstatics:
                        if collider.rect.contains(testrect):
                            return True

    def tick(self, elapsed):
        self.place_platforms()

        self.time_elapsed += elapsed

        for direction in self.movelist:
            self.player.direct(direction)

        for active_obj in self.actives:
            active_obj.tick(self.player.rect.center)

        for powerup in self.powerups:
            powerup.tick()

        for screenstatic in self.screenstatics: # Objects on the screen
            # Only platforms have a 'word' attribute
            if hasattr(screenstatic, 'word'):
                # Will it be possible to get to this object without having to walk on air
                screenstatic.reachable = self.is_reachable(screenstatic)
        self.player.tick()

        if (self.health.value() <= 0):
            self.switch_to = GameOverScene(self.screen)

    def type_special(self, key): # Typing a special character
        for platform_level in self.platforms.values():
            for platform in platform_level:
                if hasattr(platform, 'word'): # HACK to ignore bottom platform
                    if platform.reachable and self.camera.colliderect(platform.rect):
                        if key == platform.contents():
                            return platform