コード例 #1
0
ファイル: scene.py プロジェクト: derrida/shmuppy
class Scene(object):

    def __init__(self, screen):
        """Create the scene's objects."""

        self.screen = screen
        self.running = True

        # Groups for sprites
        self.players = Group()
        self.enemies = Group()
        self.chars = Group()
        self.weapons = Group()
        self.projs = Group()
        self.all = LayeredDirty()

        # Room
        self.room = Room(self)
        self.all.add(self.room)

        # Weapons
        self.weapon_list = [ LaserGun(self), Bow(self) ]
        for weapon in self.weapon_list:
            self.weapons.add(weapon)

        # Players
        self.player = Player(self)
        self.players.add(self.player)
        self.all.add(self.players)

        # Enemies
        enemy_list = [ Human, Glork ]
        for enemy in range(0, randint(50,100)):
            self.enemies.add(choice(enemy_list)(self))
        self.all.add(self.enemies)

        # Characters
        self.chars.add([self.players, self.enemies])

        # Layers
        self.all = LayeredDirty([
            self.room,
            self.enemies,
            self.players,
            self.weapons,
            self.projs ])

    def draw(self):
        """Draw all of the objects to the screen."""

        # Update all scene layers to the screen.
        self.all.update()
        self.dirty_rects = self.all.draw(self.screen)
        display.update(self.dirty_rects)
コード例 #2
0
ファイル: scenes.py プロジェクト: pathunstrom/santadrop
class Game(BaseScene):

    def __init__(self, engine):
        super().__init__(engine, background_color=(10, 21, 41))
        self.render_group = LayeredDirty()
        self.spawn_objects = [InfiniteObjectManager(self, Chimney, self.groups[config.KEY_CHIMNEY])]
        self.spawner = Spawner()
        self.spawn_objects.append(self.spawner)
        santa = Santa(self,
                      Vector(*self.engine.display.get_rect().center),
                      self.groups[config.KEY_GIFTS],
                      self.groups[config.KEY_SANTA])
        self.controller = Controller(actor=santa)
        channel = resources.sounds["santaclauseiscoming"].play(-1)
        channel.set_volume(0.1)
        self.score = 0
        self.missed_chimneys = 0
        Score(self, lambda: self.score, self.groups[config.KEY_UI])

    def render(self):
        window = display.get_surface()
        for group in self.groups.values():
            self.render_group.add(group.sprites())
        for sprite in self.render_group.sprites():
            self.render_group.change_layer(sprite, sprite.layer)
            sprite.pre_draw()
        return self.render_group.draw(window, self.background)

    def simulate(self, time_delta: float):
        self.controller.respond()
        super().simulate(time_delta)
        for spawn_object in self.spawn_objects:
            spawn_object.resolve(time_delta)
        collisions = groupcollide(self.groups[config.KEY_CHIMNEY], self.groups[config.KEY_GIFTS], False, False)
        successes = 0
        for chimney, gifts in collisions.items():
            for gift in gifts:
                if chimney.rect.left < gift.position.x < chimney.rect.right:
                    successes += 1
                    gift.kill()
                chimney.delivered = True
        if successes:
            self.score += config.POINTS_GIFT_DELIVERED * successes
            logging.debug(f"{successes} Successes!")
        if self.missed_chimneys >= config.LIMIT_CHIMNEYS_MISSED:
            self.running = False
コード例 #3
0
ファイル: scene.py プロジェクト: Raksoiv/space-escape
class Scene:
    '''
    Describe a Scene in a game.

    This is a base class for every scene in the game, has a main_loop
    that can be called from the main process and the functions start and
    update to controll the first and sucesives ticks respectively.
    '''
    def __init__(self, screen: Surface):
        '''
        Constructor of the class, takes the screen to gain control over
        the render of the game objects
        '''
        # Get display info
        info = Info()
        # Get Clock to ensure frame rating
        self.clock = Clock()
        # The default return value of the Scene
        self.return_value = -1
        # Set the continue condition
        self.running = True
        # Get the relevant information from info
        self.screen_h, self.screen_w = info.current_h, info.current_w
        # Set the screen of the Scene
        self.screen: Surface = screen

        # Main Sprite groups
        self.event_group = Group()
        self.update_group = Group()
        self.render_group = LayeredDirty()

    def start(self):
        '''
        This function will is the first function called when the scene starts
        running, here you can configure the position and starting behaviour of
        your scene
        '''
        pass

    def update(self):
        '''
        This function will be called every tick of the game and needs
        to be overrided in every scene to fill the desired behaviour
        '''
        pass

    def clear(self):
        '''
        This function will be called on the end of the scene to clean any
        configuration or variables to the next scene.

        It will raise NotImplementedError if it's not implemented, at least
        needs a pass function if no work is needed
        '''
        raise NotImplementedError

    def exit(self, return_value):
        '''
        This function will end the scene and return the value to the parent
        '''
        self.running = False
        self.return_value = return_value
        self.event_group.empty()
        self.update_group.empty()
        self.render_group.empty()
        self.clear()

    def main_loop(self):
        '''
        This is the main loop of the scene, don't overrive if not necesary.
        Here you will find the main workflow for an scene
        '''
        # Ensures the starts conditions
        self.running = True
        self.return_value = -1

        # Calls the start function, to configurate the scene
        self.start()

        # Main loop of the scene
        while self.running:
            # Event catch
            # Set the event queue of the objet itself
            self.events = []
            for e in event.get():
                self.events.append(e)
                for s in self.event_group.sprites():
                    s.add_event(e)
                if e.type == QUIT:
                    self.exit(-1)

            # Group update
            self.update_group.update(self.clock.get_time())

            # Calls the update function for every tick of the game
            self.update()

            # Render group
            self.render_group.draw(self.screen)

            display.flip()

            # Ensure frame rate
            if DEBUG:
                print(self.clock.get_fps())
            self.clock.tick(60)

        return self.return_value
コード例 #4
0
ファイル: cat3.py プロジェクト: zai1208/stuntcat
class CatUniScene(Scene):
    def __init__(self, *args, **kwargs):
        Scene.__init__(self, *args, **kwargs)
        (width, height) = (1920//2, 1080//2)
        self.width, self.height = width, height

        # Loading screen should always be a fallback active scene
        self.active = False
        self.first_render = True

        self.myfont = pygame.font.SysFont("monospace", 20)

        self.background = gfx('background.png').convert()
        # self.cat_unicycle = gfx('cat_unicycle.png').convert_alpha()
        # self.fish = gfx('fish.png').convert_alpha()
        # self.foot = gfx('foot.png').convert_alpha()
        # self.foot_part = gfx('foot_part.png').convert_alpha()
        # self.shark = gfx('shark.png').convert_alpha()

        sfx('cat_jump.ogg')
        sfx('eatfish.ogg')

        #cat variables
        self.cat_wire_height = height - 100
        self.cat_location = [width / 2, height - 100]
        self.cat_speed = [0, 0]
        self.cat_speed_max = 8
        self.cat_fall_speed_max = 16
        self.cat_angle = 0
        self.cat_angular_vel = 0
        self.cat_head_location = [
            int(self.cat_location[0] + 100 * math.cos(self.cat_angle - math.pi / 2)),
            int(self.cat_location[1] + 100 * math.sin(self.cat_angle - math.pi / 2)),
        ]

        self.left_pressed = False
        self.right_pressed = False
        self.score = 0


        #timing
        self.dt_scaled = 0
        self.total_time = 0


        #elephant and shark classes
        self.elephant = Elephant(self)
        self.shark_active = False #is the shark enabled yet
        self.elephant_active = False
        self.cat = Cat(self)
        self.score_text = Score(self)

        self.deadzones = []

        # self.deadzones = [
        #     DeadZone(
        #         [
        #             [0, height - 100],
        #             [0.1 * width, height - 100],
        #             [0.1 * width, height],
        #             [0, height],
        #         ],
        #     ),
        #     DeadZone(
        #         [
        #             [0.9 * width, height - 100],
        #             [width, height - 100],
        #             [width, height],
        #             [0.9 * width, height],
        #         ],
        #     ),
        # ]

        self.init_sprites()

        # lists of things to catch by [posx, posy, velx, vely]
        # self.fish = [[0, height / 2, 10, -5]]
        self.fish = LayeredDirtyAppend()
        self.fish.extend([Fish(self.allsprites, 0, height / 2, 10, -5)])

        self.not_fish = LayeredDirtyAppend()

        #difficulty varibles
        self.number_of_not_fish = 0



    def init_sprites(self):
        """temp, this will go in the init.
        """
        sprite_list = [
            self.elephant,
            self.cat,
            self.score_text
        ]
        sprite_list += self.deadzones
        self.allsprites = LayeredDirty(
            sprite_list,
            _time_threshold=1000/10.0
        )
        scene = self
        self.shark = Shark(self.allsprites, scene, self.width, self.height)
        self.allsprites.add(self.shark)
        self.allsprites.clear(self.screen, self.background)


    #what to do when you die, reset the level
    def reset_on_death(self):
        self.cat_location = [self.width / 2, self.height - 100]
        self.cat_speed = [0, 0]
        self.cat_angle = 0
        self.cat_angular_vel = 0
        self.score = 0
        self.total_time = 0

        self.elephant.last_animation = 0
        self.elephant.state = 0
        self.elephant.just_happened = None
        self.elephant.dirty = 1
        self.elephant_active = False

        self.shark.last_animation = 0
        self.shark.state = 0
        self.shark_active = False
        self.shark.just_happened = None
        self.shark.dirty = 1

        if hasattr(self.shark, 'lazer'):
            self.shark.lazer.kill()


    #periodically increase the difficulty
    def increase_difficulty(self):
        self.number_of_not_fish = 0
        if self.score > 3:
            self.number_of_not_fish = 1
        if self.score > 9:
            self.number_of_not_fish = 1
        if self.score > 15:
            self.number_of_not_fish = 2
        if self.score > 19:
            self.number_of_not_fish = 1
        if self.score > 25:
            self.number_of_not_fish = 2
        if self.score > 35:
            self.number_of_not_fish = 3
        if self.score >= 50:
            self.number_of_not_fish = int((self.score - 20)/10)

        #TODO: to make it easier to test.
        # if self.score >= 15:
        #     self.shark_active = True
        if self.score >= 10:
            self.shark_active = True

        #TODO: to make it easier to test.
        if self.score >= 20:
            self.elephant_active = True

    def render_sprites(self):
        rects = []
        self.allsprites.update()
        rects.extend(self.allsprites.draw(self.screen))
        return rects

    def render(self):
        rects = []
        if self.first_render:
            self.first_render = False
            rects.append(self.screen.get_rect())
        rects.extend(self.render_sprites())
        return rects

        # we draw the sprites, and then the lines over the top.
        self.render_sprites()

        screen = self.screen
        width, height = self.width, self.height

        if 0:
            background_colour = (0, 0, 0)
            screen.fill(background_colour)
            screen.blit(self.background, (0, 0))

        self.elephant.render(screen, width, height)
        self.shark.render(screen, width, height)

        # draw cat
        pygame.draw.line(
            screen, [0, 0, 255], self.cat_location, self.cat_head_location, 20
        )
        pygame.draw.circle(screen, [0, 0, 255], self.cat_head_location, 50, 1)
        pygame.draw.circle(screen, [0, 255, 0], self.cat_head_location, 100, 1)

        # draw dead zones
        pygame.draw.polygon(
            screen,
            [255, 0, 0],
            [
                [0, height - 100],
                [0.1 * width, height - 100],
                [0.1 * width, height],
                [0, height],
            ],
        )
        pygame.draw.polygon(
            screen,
            [255, 0, 0],
            [
                [0.9 * width, height - 100],
                [width, height - 100],
                [width, height],
                [0.9 * width, height],
            ],
        )

        # draw fish and not fish
        for f in self.fish:
            pygame.draw.circle(screen, [0, 255, 0], [int(f.pos[0]), int(f.pos[1])], 10)
        for f in self.not_fish:
            pygame.draw.circle(screen, [255, 0, 0], [int(f.pos[0]), int(f.pos[1])], 10)

        # draw score
        textsurface = self.myfont.render(str(self.score), True, [0, 0, 0]
        )
        screen.blit(textsurface, (200, 300))
        return [screen.get_rect()]

    def tick(self, dt):
        self.increase_difficulty()

        self.total_time += dt #keep track of the total number of ms passed during the game
        dt_scaled = dt/17
        self.dt_scaled = dt_scaled
        width, height = self.width, self.height

        ##cat physics
        self.cat_angular_vel *= 0.9**dt_scaled #max(0.9/(max(0.1,dt_scaled)),0.999)

        # add gravity
        self.cat_speed[1] = min(self.cat_speed[1] + (1 * dt_scaled), self.cat_fall_speed_max)

        # accelerate the cat left or right
        if self.right_pressed:
            self.cat_speed[0] = min(
                self.cat_speed[0] + 0.3 * dt_scaled, self.cat_speed_max
            )
            self.cat_angle -= 0.003 * dt_scaled

        if self.left_pressed:
            self.cat_speed[0] = max(
                self.cat_speed[0] - 0.3 * dt_scaled, -self.cat_speed_max
            )
            self.cat_angle += 0.003 * dt_scaled

        # make the cat fall
        angle_sign = 1 if self.cat_angle > 0 else -1
        self.cat_angular_vel += 0.0002 * angle_sign * dt_scaled
        self.cat_angle += self.cat_angular_vel * dt_scaled
        if (self.cat_angle > math.pi / 2 or self.cat_angle < -math.pi / 2) and self.cat_location[1] > height - 160:
            self.reset_on_death()

        # move cat
        self.cat_location[0] += self.cat_speed[0] * dt_scaled
        self.cat_location[1] += self.cat_speed[1] * dt_scaled
        if self.cat_location[1] > self.cat_wire_height and self.cat_location[0] > 0.25 * width:
            self.cat_location[1] = self.cat_wire_height
            self.cat_speed[1] = 0
        if self.cat_location[1] > height:
            self.reset_on_death()
        if self.cat_location[0] > width:
            self.cat_location[0] = width
            if self.cat_angle > 0:
                self.cat_angle *= 0.7
        self.cat_head_location = [
            int(self.cat_location[0] + 100 * math.cos(self.cat_angle - math.pi / 2)),
            int(self.cat_location[1] + 100 * math.sin(self.cat_angle - math.pi / 2)),
        ]

        # check for out of bounds
        if self.cat_location[0] > 0.98 * width and self.cat_location[1] > self.cat_wire_height - 30:
            #bump the cat back in
            self.cat_angular_vel -= 0.01*dt_scaled
            self.cat_speed[0] = -5
            self.cat_speed[1] = -20
            #self.reset_on_death()
        if self.cat_location[0] < 0.25 * width and self.cat_location[1] > self.cat_wire_height - 30:
            pass

        #check for collision with the elephant stomp
        if self.elephant_active:
            self.elephant.animate(self.total_time)
            self.elephant.collide(self, width, height, self.cat_head_location)
        if self.shark_active:
            self.shark.animate(self.total_time)
            self.shark.collide(self, width, height, self.cat_location)

        ##object physics

        # move fish and not fish
        for f in reversed(self.fish.sprites()):
            f.pos[0] += f.velocity[0] * dt_scaled  # speed of the throw
            f.velocity[1] += 0.2 * dt_scaled  # gravity
            f.pos[1] += f.velocity[1] * dt_scaled # y velocity
            # check out of bounds
            if f.pos[1] > height:
                self.fish.remove(f)
                f.kill()
        for f in reversed(self.not_fish.sprites()):
            f.pos[0] += f.velocity[0] * dt_scaled # speed of the throw
            f.velocity[1] += 0.2 * dt_scaled  # gravity
            f.pos[1] += f.velocity[1] * dt_scaled  # y velocity
            # check out of bounds
            if f.pos[1] > height:
                self.not_fish.remove(f)
                f.kill()

        # check collision with the cat
        for f in reversed(self.fish.sprites()):
            if distance([f.rect[0], f.rect[1]], self.cat_head_location) < 100:
                self.score += 1
                self.fish.remove(f)
                sfx('eatfish.ogg', play=1)
                f.kill()
        for f in reversed(self.not_fish.sprites()):
            if distance([f.rect[0], f.rect[1]], self.cat_head_location) < 50:
                self.not_fish.remove(f)
                f.kill()
                self.angle_to_not_fish = (
                    math.atan2(
                        self.cat_head_location[1] - f.rect[1],
                        self.cat_head_location[0] - f.rect[0],
                    )
                    - math.pi / 2
                )
                side = 1 if self.angle_to_not_fish < 0 else -1
                self.cat_angular_vel += side * random.uniform(0.08, 0.15)

        # refresh lists
        while len(self.fish) < 1:
            # choose a side of the screen
            if random.choice([0, 1]) == 0:
                self.fish.append(
                    Fish(self.allsprites,
                        0,
                        height/2,#random.randint(0, height / 2),
                        random.randint(3, 7),
                        -random.randint(5, 12),
                    )
                )
            else:
                self.fish.append(
                    Fish(self.allsprites,
                        width,
                        height/2,#random.randint(0, height / 2),
                        -random.randint(3, 7),
                        -random.randint(5, 12),
                    )
                )
        while len(self.not_fish) < self.number_of_not_fish:
            # choose a side of the screen
            if random.choice([0, 1]) == 0:
                self.not_fish.append(
                    NotFish(self.allsprites,
                        0,
                        height/2,#random.randint(0, height / 2),
                        random.randint(3, 7),
                        -random.randint(5, 12),
                    )
                )
            else:
                self.not_fish.append(
                    NotFish(self.allsprites,
                        width,
                        height/2,#random.randint(0, height / 2),
                        -random.randint(3, 7),
                        -random.randint(5, 12),
                    )
                )

    def event(self, event):
        width, height = self.width, self.height
        if event.type == KEYDOWN:
            if event.key == K_RIGHT:
                self.right_pressed = True
                # cat_speed[0] = min(cat_speed[0] + 2, cat_speed_max)
                # cat_angle -= random.uniform(0.02*math.pi, 0.05*math.pi)
            elif event.key == K_LEFT:
                self.left_pressed = True
                # cat_speed[0] = min(cat_speed[0] - 2, cat_speed_max)
                # cat_angle += random.uniform(0.02*math.pi, 0.05*math.pi)
            elif event.key == K_a:
                self.cat_angular_vel -= random.uniform(0.01 * math.pi, 0.03 * math.pi)
            elif event.key == K_d:
                self.cat_angular_vel += random.uniform(0.01 * math.pi, 0.03 * math.pi)
            elif event.key == K_UP:
                if self.cat_location[1] > self.cat_wire_height - 1:
                    self.cat_speed[1] -= 25
                    sfx('cat_jump.ogg', play=1)

        elif event.type == KEYUP:
            if event.key == K_UP:
                if self.cat_speed[1] < 0:
                    self.cat_speed[1] = 0
            elif event.key == K_RIGHT:
                self.right_pressed = False
            elif event.key == K_LEFT:
                self.left_pressed = False
コード例 #5
0
ファイル: scenes.py プロジェクト: pingf/pursuedpybear
class BaseScene(Scene):
    def __init__(self,
                 engine,
                 *,
                 background_color=(0, 0, 55),
                 container_class=GameObjectCollection,
                 **kwargs):
        super().__init__(engine)
        self.background_color = background_color
        self.background = engine.display.copy()
        self.background.fill(self.background_color)
        self.game_objects = container_class()
        self.render_group = LayeredDirty()

    def __contains__(self, item: Hashable) -> bool:
        return item in self.game_objects

    def render(self):
        window = self.engine.display
        self.render_group.add(s for s in self.game_objects)
        return self.render_group.draw(window, self.background)

    def simulate(self, time_delta: float):
        for game_object in self.game_objects:
            game_object.update(time_delta)

    def change(self):
        """
        Default case, override in subclass as necessary.
        """
        return self.running, {"scene_class": self.next}

    def add(self, game_object: Hashable, tags: Iterable = ()) -> None:
        """
        Add a game_object to the scene.

        game_object: Any GameObject object. The item to be added.
        tags: An iterable of Hashable objects. Values that can be used to
              retrieve a group containing the game_object.

        Examples:
            scene.add(MyGameObject())

            scene.add(MyGameObject(), tags=("red", "blue")
        """
        self.game_objects.add(game_object, tags)

    def get(self,
            *,
            kind: Type = None,
            tag: Hashable = None,
            **kwargs) -> Iterator:
        """
        Get an iterator of GameObjects by kind or tag.

        kind: Any type. Pass to get a subset of contained GameObjects with the
              given type.
        tag: Any Hashable object. Pass to get a subset of contained GameObjects
             with the given tag.

        Pass both kind and tag to get objects that are both that type and that
        tag.

        Examples:
            scene.get(type=MyGameObject)

            scene.get(tag="red")

            scene.get(type=MyGameObject, tag="red")
        """
        return self.game_objects.get(kind=kind, tag=tag, **kwargs)

    def remove(self, game_object: Hashable) -> None:
        """
        Remove the given object from the scene.

        game_object: A game object.

        Example:
            scene.remove(my_game_object)
        """
        self.game_objects.remove(game_object)
コード例 #6
0
                pixel = self.image.get_at((x, y)).r
                if (pixel > 50):
                    self.image.set_at((x, y), colour)


# create sprites
bg = PpuiImage("assets/lcars_screen_1.png")
button = PpuiImage("assets/button.png")
button.applyColour((255, 204, 153))

# add sprites to layer
sprites = LayeredDirty()
sprites.add(bg)
sprites.add(button)

# event loop
while pygame.display.get_init():
    sprites.draw(screenSurface)
    pygame.display.update()

    for event in pygame.event.get():
        if event.type == KEYUP:
            pygame.quit()
            break

        if (event.type == MOUSEMOTION):
            # move button around as mouse moves (or touch-drag)
            button.rect.left = event.pos[0]
            button.rect.top = event.pos[1]
            button.dirty = 1
コード例 #7
0
class CatUniScene(Scene):
    def __init__(self, *args, **kwargs):
        Scene.__init__(self, *args, **kwargs)
        (width, height) = (1920 // 2, 1080 // 2)
        self.width, self.height = width, height

        # Loading screen should always be a fallback active scene
        self.active = False
        self.first_render = True

        self.myfont = pygame.font.SysFont("monospace", 20)

        self.background = gfx('background.png', convert=True)
        # self.cat_unicycle = gfx('cat_unicycle.png').convert_alpha()
        # self.fish = gfx('fish.png').convert_alpha()
        # self.foot = gfx('foot.png').convert_alpha()
        # self.foot_part = gfx('foot_part.png').convert_alpha()
        # self.shark = gfx('shark.png').convert_alpha()

        sfx('cat_jump.ogg')
        sfx('eatfish.ogg')
        sfx('splash.ogg')
        sfx('cat_crash.ogg')

        self.meow_names = [
            'cat_meow01.ogg', 'cat_meow02.ogg', 'cat_meow03.ogg'
        ]
        self.last_meow = None

        self.touching_ground = True
        self.jumping = False
        self.jumping_time = 0
        self.jump_key = None

        for meow_name in self.meow_names:
            sfx(meow_name)

        self.boing_names = ['boing1.ogg', 'boing2.ogg', 'boing3.ogg']
        for boing_name in self.boing_names:
            sfx(boing_name)

        #cat variables
        self.cat_wire_height = height - 100
        self.cat_location = [width / 2, height - 100]
        self.cat_speed = [0, 0]
        self.cat_speed_max = 8
        self.cat_fall_speed_max = 16
        self.cat_roll_speed = .01
        self.cat_angle = 0
        self.cat_angular_vel = 0
        self.cat_head_location = [
            int(self.cat_location[0] +
                100 * math.cos(self.cat_angle - math.pi / 2)),
            int(self.cat_location[1] +
                100 * math.sin(self.cat_angle - math.pi / 2)),
        ]

        self.people_mad = False
        self.people_mad_duration = 3000  #ms
        self.people_mad_current_time = 0
        self.next_notfish = 0
        self.notfish_time = 0

        self.last_joy_right_tilt = 0
        self.last_joy_left_tilt = 0

        self.left_pressed = False
        self.right_pressed = False

        self.score = 0

        #timing
        self.dt_scaled = 0
        self.total_time = 0

        #elephant and shark classes
        self.elephant = Elephant(self)
        self.shark_active = False  #is the shark enabled yet
        self.elephant_active = False
        self.cat = Cat(self)
        self.score_text = Score(self)

        self.deadzones = []

        # self.deadzones = [
        #     DeadZone(
        #         [
        #             [0, height - 100],
        #             [0.1 * width, height - 100],
        #             [0.1 * width, height],
        #             [0, height],
        #         ],
        #     ),
        #     DeadZone(
        #         [
        #             [0.9 * width, height - 100],
        #             [width, height - 100],
        #             [width, height],
        #             [0.9 * width, height],
        #         ],
        #     ),
        # ]

        self.init_sprites()

        # lists of things to catch by [posx, posy, velx, vely]
        # self.fish = [[0, height / 2, 10, -5]]
        self.fish = LayeredDirtyAppend()
        self.fish.extend([Fish(self.allsprites, 0, height / 2, 10, -5)])

        self.not_fish = LayeredDirtyAppend()

        self.unicycle_sound = sfx('unicycle.ogg',
                                  play=True,
                                  loops=-1,
                                  fadein=500)

        self.reset_meow()

        #difficulty varibles
        self.number_of_not_fish = 0

    def reset_meow(self):
        self.next_meow = random.uniform(5000, 10000)

    def meow(self):
        # Play a meow sound, but not the same one twice in a row
        meow_names = self.meow_names[:]
        if self.last_meow in self.meow_names:
            meow_names.remove(self.last_meow)
        self.last_meow = random.choice(meow_names)
        sfx(self.last_meow, play=1)
        self.reset_meow()

    def init_sprites(self):
        """temp, this will go in the init.
        """
        sprite_list = [self.elephant, self.cat, self.score_text]
        sprite_list += self.deadzones
        self.allsprites = LayeredDirty(sprite_list,
                                       _time_threshold=1000 / 10.0)
        scene = self
        self.shark = Shark(self.allsprites, scene, self.width, self.height)
        self.allsprites.add(self.shark)
        self.allsprites.clear(self.screen, self.background)

    #what to do when you die, reset the level
    def reset_on_death(self):
        self.cat_location = [self.width / 2, self.height - 100]
        self.cat_speed = [0, 0]
        self.cat_angle = 0
        self.cat_angular_vel = 0
        self.score = 0
        self.total_time = 0

        self.elephant.last_animation = 0
        self.elephant.state = 0
        self.elephant.just_happened = None
        self.elephant.dirty = 1
        self.elephant_active = False
        self.elephant.animate(self.total_time)

        #make the shark leave
        self.shark_active = False
        self.shark.last_animation = 0
        self.shark.dirty = True

        if self.shark.get_state() in ('aiming', 'fire laser'):
            self.shark.just_happenend = None
            self.shark.set_state('leaving')
            self.shark.applaud = False
        else:
            self.shark.just_happenend = None
            self.shark.set_state('offscreen')
            self.shark.animate(self.total_time)

        sfx('shark_appear.ogg', fadeout=1000)

        if self.shark.lazer:
            self.shark.lazer.kill()

    #periodically increase the difficulty
    def increase_difficulty(self):
        self.number_of_not_fish = 0
        if self.score > 3:
            self.number_of_not_fish = 1
        if self.score > 9:
            self.number_of_not_fish = 1
        if self.score > 15:
            self.number_of_not_fish = 2
        if self.score > 19:
            self.number_of_not_fish = 1
        if self.score > 25:
            self.number_of_not_fish = 2
        if self.score > 35:
            self.number_of_not_fish = 3
        if self.score >= 50:
            self.number_of_not_fish = int((self.score - 20) / 10)

        #TODO: to make it easier to test.
        # if self.score >= 15:
        #     self.shark_active = True
        if self.score >= 10:
            self.shark_active = True

        #TODO: to make it easier to test.

        # Elephant doesn't work yet, so let's not use it
#        if self.score >= 20:
#            self.elephant_active = True

    def annoy_crowd(self):
        self.people_mad = True
        self.people_mad_current_time = 0

    def render_sprites(self):
        rects = []
        self.allsprites.update()
        rects.extend(self.allsprites.draw(self.screen))
        return rects

    def render(self):
        rects = []
        if self.first_render:
            self.first_render = False
            rects.append(self.screen.get_rect())
        rects.extend(self.render_sprites())
        return rects

    def tick(self, dt):
        self.increase_difficulty()

        self.cat.animate(dt)

        self.total_time += dt  #keep track of the total number of ms passed during the game
        dt_scaled = dt / 17
        self.dt_scaled = dt_scaled
        width, height = self.width, self.height

        ##cat physics
        self.cat_angular_vel *= 0.9**dt_scaled  #max(0.9/(max(0.1,dt_scaled)),0.999)

        #make the cat slide in the direction it's rotated
        self.cat_speed[0] += math.sin(
            self.cat_angle) * (dt_scaled * self.cat_roll_speed)

        # add gravity
        self.cat_speed[1] = min(self.cat_speed[1] + (1 * dt_scaled),
                                self.cat_fall_speed_max)

        self.unicycle_sound.set_volume(
            abs(self.cat_speed[0] / self.cat_speed_max))

        # accelerate the cat left or right
        if self.right_pressed:
            self.cat_speed[0] = min(self.cat_speed[0] + 0.3 * dt_scaled,
                                    self.cat_speed_max)
            self.cat_angle -= 0.003 * dt_scaled

        if self.left_pressed:
            self.cat_speed[0] = max(self.cat_speed[0] - 0.3 * dt_scaled,
                                    -self.cat_speed_max)
            self.cat_angle += 0.003 * dt_scaled

        # make the cat fall
        angle_sign = 1 if self.cat_angle > 0 else -1
        self.cat_angular_vel += 0.0002 * angle_sign * dt_scaled
        self.cat_angle += self.cat_angular_vel * dt_scaled
        if (self.cat_angle > math.pi / 2 or self.cat_angle < -math.pi / 2
            ) and self.cat_location[1] > height - 160:
            sfx('cat_crash.ogg', play=1)
            self.reset_on_death()

        # move cat
        self.cat_location[0] += self.cat_speed[0] * dt_scaled
        self.cat_location[1] += self.cat_speed[1] * dt_scaled
        if self.cat_location[1] > self.cat_wire_height and self.cat_location[
                0] > 0.25 * width:
            self.touching_ground = True
            self.cat_location[1] = self.cat_wire_height
            self.cat_speed[1] = 0
        else:
            self.touching_ground = False

        if self.cat_location[1] > height:
            sfx('splash.ogg', play=1)
            self.meow()
            self.reset_on_death()
        if self.cat_location[0] > width:
            self.cat_location[0] = width
            if self.cat_angle > 0:
                self.cat_angle *= 0.7
        self.cat_head_location = [
            int(self.cat_location[0] +
                100 * math.cos(self.cat_angle - math.pi / 2)),
            int(self.cat_location[1] +
                100 * math.sin(self.cat_angle - math.pi / 2)),
        ]

        # check for out of bounds
        if self.cat_location[0] > 0.98 * width and self.cat_location[
                1] > self.cat_wire_height - 30:
            #bump the cat back in
            self.meow()
            sfx(random.choice(self.boing_names), play=True)
            self.cat_angular_vel -= 0.01 * dt_scaled
            self.cat_speed[0] = -5
            self.cat_speed[1] = -20
            #self.reset_on_death()
        if self.cat_location[0] < 0.25 * width and self.cat_location[
                1] > self.cat_wire_height - 30:
            pass

        #check for collision with the elephant stomp
        if self.elephant_active:
            self.elephant.animate(self.total_time)
            self.elephant.collide(self, width, height, self.cat_head_location)
        if self.shark_active or self.shark.states[
                self.shark.state] == 'leaving':
            self.shark.animate(self.total_time)
            self.shark.collide(self, width, height, self.cat_location)

        #jumping physics
        if self.jumping:
            self.cat_speed[1] -= dt * (
                (CAT_MAX_JUMPING_TIME - self.jumping_time) /
                CAT_MAX_JUMPING_TIME) * CAT_JUMP_SPEED
            self.jumping_time += dt
            if self.jumping_time >= CAT_MAX_JUMPING_TIME:
                self.jumping = False

        ##meow timing
        if self.next_meow <= 0:
            self.meow()
        self.next_meow -= dt

        ##angry people (increased throwing of not-fish)
        if self.people_mad:
            self.people_mad_current_time += dt
            self.notfish_time += dt
            if self.notfish_time >= self.next_notfish:
                self.next_notfish = random.randint(100, 400)
                self.notfish_time = 0
                self.SpawnNotFish()
            if self.people_mad_current_time >= self.people_mad_duration:
                self.people_mad = False

        ##object physics

        # move fish and not fish
        for f in reversed(self.fish.sprites()):
            f.pos[0] += f.velocity[0] * dt_scaled  # speed of the throw
            f.velocity[1] += 0.2 * dt_scaled  # gravity
            f.pos[1] += f.velocity[1] * dt_scaled  # y velocity
            # check out of bounds
            if f.pos[1] > height:
                self.fish.remove(f)
                f.kill()
        for f in reversed(self.not_fish.sprites()):
            f.pos[0] += f.velocity[0] * dt_scaled  # speed of the throw
            f.velocity[1] += 0.2 * dt_scaled  # gravity
            f.pos[1] += f.velocity[1] * dt_scaled  # y velocity
            # check out of bounds
            if f.pos[1] > height:
                self.not_fish.remove(f)
                f.kill()

        # check collision with the cat
        for f in reversed(self.fish.sprites()):
            if distance([f.rect[0], f.rect[1]], self.cat_head_location) < 100:
                self.score += 1
                self.fish.remove(f)
                sfx('eatfish.ogg', play=1)
                f.kill()
        for f in reversed(self.not_fish.sprites()):
            if distance([f.rect[0], f.rect[1]], self.cat_head_location) < 50:
                self.not_fish.remove(f)
                f.kill()
                self.angle_to_not_fish = (math.atan2(
                    self.cat_head_location[1] - f.rect[1],
                    self.cat_head_location[0] - f.rect[0],
                ) - math.pi / 2)
                side = 1 if self.angle_to_not_fish < 0 else -1
                self.cat_angular_vel += side * random.uniform(0.08, 0.15)
                sfx(random.choice(self.boing_names), play=True)

        # refresh lists
        while len(self.fish) < 1 and not self.people_mad:
            # choose a side of the screen
            if random.choice([0, 1]) == 0:
                self.fish.append(
                    Fish(
                        self.allsprites,
                        0,
                        height / 2,  #random.randint(0, height / 2),
                        random.randint(3, 7),
                        -random.randint(5, 12),
                    ))
            else:
                self.fish.append(
                    Fish(
                        self.allsprites,
                        width,
                        height / 2,  #random.randint(0, height / 2),
                        -random.randint(3, 7),
                        -random.randint(5, 12),
                    ))
        while len(self.not_fish) < self.number_of_not_fish:
            self.SpawnNotFish()

    def SpawnNotFish(self):
        # choose a side of the screen
        velocity_multiplier = 1
        x_pos = 0
        if random.randint(0, 1):
            velocity_multiplier *= -1
            x_pos = self.width
        self.not_fish.append(
            NotFish(
                self.allsprites,
                x_pos,
                self.height / 2,
                random.randint(3, 7) * velocity_multiplier,
                -random.randint(5, 12),
            ))

    def start_jump(self, key):
        self.jump_key = key
        if self.touching_ground and not self.jumping:
            self.jumping = True
            self.jumping_time = 0
            self.cat_speed[1] -= 12.5
            sfx('cat_jump.ogg', play=1)

    def stop_jump(self):
        self.jumping = False
        sfx('cat_jump.ogg', fadeout=50)

    def tilt_left(self):
        self.cat_angular_vel -= random.uniform(0.01 * math.pi, 0.03 * math.pi)

    def tilt_right(self):
        self.cat_angular_vel += random.uniform(0.01 * math.pi, 0.03 * math.pi)

    def event(self, event):
        if event.type == KEYDOWN:
            if event.key == K_RIGHT:
                self.right_pressed = True
            elif event.key == K_LEFT:
                self.left_pressed = True
            elif event.key == K_a:
                self.tilt_left()
            elif event.key == K_d:
                self.tilt_right()
            elif event.key in (K_UP, K_SPACE):
                self.start_jump(event.key)
        elif event.type == KEYUP:
            if event.key == self.jump_key:
                self.stop_jump()
            elif event.key == K_RIGHT:
                self.right_pressed = False
            elif event.key == K_LEFT:
                self.left_pressed = False

        if event.type == JOYBUTTONDOWN:
            if event.button in JOY_JUMP_BUTTONS:
                self.start_jump("JOY" + str(event.button))
            if event.button in JOY_LEFT_BUTTONS:
                self.tilt_left()
            if event.button in JOY_RIGHT_BUTTONS:
                self.tilt_right()

        if event.type == JOYBUTTONUP:
            if "JOY" + str(event.button) == self.jump_key:
                self.stop_jump()

        if event.type == JOYAXISMOTION:
            if event.axis == 0:
                if event.value >= JOY_SENSE:
                    self.right_pressed = True
                    self.left_pressed = False
                elif event.value <= -JOY_SENSE:
                    self.right_pressed = False
                    self.left_pressed = True
                else:
                    self.right_pressed = False
                    self.left_pressed = False
            if event.axis == JOY_TILT_RIGHT_AXIS:
                if self.last_joy_right_tilt < JOY_SENSE and event.value >= JOY_SENSE:
                    self.tilt_right()
                self.last_joy_right_tilt = event.value
            if event.axis == JOY_TILT_LEFT_AXIS:
                if self.last_joy_left_tilt < JOY_SENSE and event.value >= JOY_SENSE:
                    self.tilt_left()
                self.last_joy_left_tilt = event.value
コード例 #8
0
ファイル: screen.py プロジェクト: otfrom/axengine2
class Screen(object):
    def __init__(self, name):
        State.name = name
        State.screen = self
        State.controls = State.screens[State.name]['controls']
        State.groups = {}
        self.layers = LayeredDirty()
        self.add_all()
        State.save(State.name)

    def add_all(self):
        """Add all the objects specified in the screen's configuration
            resource to their proper sprite groups for rendering."""

        for obj in State.screens[State.name]['objects']:
            self.add_object(obj)

    def add_object(self, name, amount=1, pos=None):
        """Add one or many of a single game object resource to the screen.

        name:   the name of the game object.
        amount: the amount of instances to add.
        pos:    if value is 'random', every object will start in a random
                location.
                if value is a (x,y) tuple, every object will start at that
                screen location."""

        obj = State.objects[name]
        new_pos = None
        for i in range(0, amount):
            if pos == 'random':
                scr = State.window.get_size()
                spr = obj['size']
                new_pos = (randint(0, scr[0]/spr[0]), randint(0, scr[1]/spr[1]))
            elif type(pos) == type(tuple()):
                new_pos = pos
            if new_pos:
                obj['pos'] = new_pos
            group = obj['group']
            if group not in State.groups:
                State.groups[group] = Group()
            sprite = eval(group.capitalize())(obj)
            State.groups[group].add(sprite)
        if obj['cursor']:
            State.cursor = sprite
        self.layers.add(State.groups[group])

    def draw(self):
        """Run the update method of every sprite, keeping track of which ones
            are dirty and need updating, and then finally updating only the
            dirty areas."""

        self.layers.update()
        State.dirty = self.layers.draw(State.window)
        display.update(State.dirty)

    def switch(self, name):
        """Switch to a new screen by saving the current state, and then
            restoring the specified state."""

        State.save(State.name)
        State.prev_name = State.name
        State.restore(name)

    def restore(self):
        """Called when a screen is restored from a saved state."""

        State.pressed = []
        for group in State.groups:
            for sprite in State.groups[group]:
                sprite.dirty = 1
                sprite.stopped = True
コード例 #9
0
ファイル: MapView.py プロジェクト: CheapSeth/Port-Tales
class MapView:
    def __init__(self, action_handler, index):
        # Init clock
        self.clock = pyg.time.Clock()

        # Set handler
        self.action_handler = action_handler

        # Init groupsView
        self.all_sprites = LayeredDirty()
        Fps.containers += (self.all_sprites,)

        # Create window
        self.screen, self.background = reset_screen()
        if DISPLAY_FPS:
            Fps(self.clock)

        # Blit level
        image, rect = get_stage_image(index)
        self.background.blit(image, rect)

        # Tile handling
        from TileView import TileView
        TileView.layer_container = self.all_sprites

        # Initialize attributes
        self.exit = False
        self.done = False
        self.countdown = None

    def win(self):
        self.done = True
        self.win = True
        self.countdown = countdown(GoalView.len_animation)

    def lose(self, nb_tiles):
        self.done = True
        self.win = False
        value = MinimizingPlayerView.len_animation
        value += TeleportingPlayerView.len_animation * (nb_tiles-2)
        value += FallingPlayerView.len_animation
        value *= 2
        self.countdown = countdown(value)


    def reactor_loop(self):
        # Infinite loop
        while True:
            # Get input
            for ev in pyg.event.get():
                # Quit
                if (ev.type == pyg.KEYDOWN and ev.key == pyg.K_ESCAPE)\
                   or ev.type == pyg.QUIT:
                    safe_exit()
                # Reset
                if ev.type == pyg.JOYBUTTONDOWN and \
                   ev.button in RESET_BUTTONS:
                    win_reset = False, True
                    return win_reset

            # Handle countdown
            if self.done and next(self.countdown):
                self.all_sprites.empty()
                win_reset = self.win, False
                return win_reset

            # Read input
            if not self.done:
                self.action_handler.read_inputs()

            # Clear sprites from screen
            self.all_sprites.clear(self.screen, self.background)

            # Update sprites
            self.all_sprites.update()

            # Draw sprites on screen
            dirty = self.all_sprites.draw(self.screen)

            # Update display
            pyg.display.flip()

            # Frame rate control
            self.clock.tick(FPS)
コード例 #10
0
class CatUniScene(Scene):  # pylint:disable=too-many-instance-attributes
    """Cat unicycle scene."""
    def __init__(self, *args, **kwargs):
        Scene.__init__(self, *args, **kwargs)

        (width, height) = (1920 // 2, 1080 // 2)
        self.width, self.height = width, height

        # Loading screen should always be a fallback active scene
        self.active = False
        self.first_render = True

        self.myfont = pygame.font.SysFont("monospace", 20)

        self.background = gfx("background.png", convert=True)
        # self.cat_unicycle = gfx('cat_unicycle.png').convert_alpha()
        # self.fish = gfx('fish.png').convert_alpha()
        # self.foot = gfx('foot.png').convert_alpha()
        # self.foot_part = gfx('foot_part.png').convert_alpha()
        # self.shark = gfx('shark.png').convert_alpha()

        sfx("cat_jump.ogg")
        sfx("eatfish.ogg")
        sfx("splash.ogg")
        sfx("cat_crash.ogg")

        self.meow_names = [
            "cat_meow01.ogg", "cat_meow02.ogg", "cat_meow03.ogg"
        ]
        self.last_meow = None

        self.touching_ground = True
        self.jumping = False
        self.jumping_time = 0
        self.jump_key = None

        for meow_name in self.meow_names:
            sfx(meow_name)

        self.boing_names = ["boing1.ogg", "boing2.ogg", "boing3.ogg"]
        for boing_name in self.boing_names:
            sfx(boing_name)

        self.people_mad = False
        self.people_mad_duration = 3000  # ms
        self.people_mad_current_time = 0
        self.next_notfish = 0
        self.notfish_time = 0

        self.last_joy_right_tilt = 0
        self.last_joy_left_tilt = 0

        self.left_pressed = False
        self.right_pressed = False
        self.player_data = PlayerData(width, height)

        # timing
        self.dt_scaled = 0
        self.total_time = 0

        # elephant and shark classes
        self.elephant = Elephant(self)
        self.shark_active = False  # is the shark enabled yet
        self.elephant_active = False
        self.cat = Cat(self)
        self.score_text = Score(self)

        self.allsprites = None  # type: Optional[LayeredDirty]
        self.shark = None  # type: Optional[Shark]
        self.init_sprites()

        # lists of things to catch by [posx, posy, velx, vely]
        # self.fish = [[0, height / 2, 10, -5]]
        self.fish = LayeredDirtyAppend()
        self.fish.extend([Fish(self.allsprites, (0, height / 2), (10, -5))])

        self.not_fish = LayeredDirtyAppend()

        self.unicycle_sound = sfx("unicycle.ogg",
                                  play=True,
                                  loops=-1,
                                  fadein=500)

        self._reset_meow()

        # difficulty varibles
        self.number_of_not_fish = 0

    def _reset_meow(self):
        self.next_meow = random.uniform(5000, 10000)

    def _meow(self):
        # Play a meow sound, but not the same one twice in a row
        meow_names = self.meow_names[:]
        if self.last_meow in self.meow_names:
            meow_names.remove(self.last_meow)
        self.last_meow = random.choice(meow_names)
        sfx(self.last_meow, play=1)
        self._reset_meow()

    def init_sprites(self):
        """temp, this will go in the init."""
        sprite_list = [self.elephant, self.cat, self.score_text]
        self.allsprites = LayeredDirty(sprite_list,
                                       _time_threshold=1000 / 10.0)
        scene = self
        self.shark = Shark(self.allsprites, scene, self.width, self.height)
        self.allsprites.add(self.shark)
        self.allsprites.clear(self.screen, self.background)

    def reset_on_death(self):
        """Reset on death.

        What to do when you die, reset the level.
        """
        self.player_data.reset()
        self.total_time = 0

        self.elephant.last_animation = 0
        self.elephant.state = 0
        self.elephant.just_happened = None
        self.elephant.dirty = 1
        self.elephant_active = False
        self.elephant.animate(self.total_time)

        # make the shark leave
        self.shark_active = False
        self.shark.last_animation = 0
        self.shark.dirty = True

        if self.shark.get_state() in ("aiming", "fire laser"):
            self.shark.just_happened = None
            self.shark.set_state("leaving")
            self.shark.applaud = False
        else:
            self.shark.just_happened = None
            self.shark.set_state("offscreen")
            self.shark.animate(self.total_time)

        sfx("shark_appear.ogg", fadeout=1000)

        if self.shark.lazer:
            self.shark.lazer.kill()

    def increase_difficulty(self):
        """ Periodically increase the difficulty."""
        self.number_of_not_fish = 0
        if self.player_data.score > 3:
            self.number_of_not_fish = 1
        if self.player_data.score > 9:
            self.number_of_not_fish = 1
        if self.player_data.score > 15:
            self.number_of_not_fish = 2
        if self.player_data.score > 19:
            self.number_of_not_fish = 1
        if self.player_data.score > 25:
            self.number_of_not_fish = 2
        if self.player_data.score > 35:
            self.number_of_not_fish = 3
        if self.player_data.score >= 50:
            self.number_of_not_fish = int((self.player_data.score - 20) / 10)

        if self.player_data.score >= 10:
            self.shark_active = True

        # Elephant doesn't work yet, so let's not use it

    #        if self.player_data.score >= 20:
    #            self.elephant_active = True

    def annoy_crowd(self):
        """ Annoy the crowd."""
        self.people_mad = True
        self.people_mad_current_time = 0

    def render_sprites(self):
        """ Render the sprites."""
        rects = []
        self.allsprites.update(time_delta=self.dt_scaled,
                               height=self.height,
                               player_data=self.player_data)
        rects.extend(self.allsprites.draw(self.screen))
        return rects

    def render(self):
        rects = []
        if self.first_render:
            self.first_render = False
            rects.append(self.screen.get_rect())
        rects.extend(self.render_sprites())
        return rects

    def tick(self, time_delta):
        self.increase_difficulty()

        self.cat.animate(time_delta)

        self.total_time += (
            time_delta  # keep track of the total number of ms passed during the game
        )
        dt_scaled = time_delta / 17
        self.dt_scaled = dt_scaled
        width, height = self.width, self.height

        ##cat physics
        self.player_data.cat_angular_vel *= (
            0.9**dt_scaled)  # max(0.9/(max(0.1,dt_scaled)),0.999)

        # make the cat slide in the direction it's rotated
        self.player_data.cat_speed[0] += math.sin(
            self.player_data.cat_angle) * (dt_scaled *
                                           self.player_data.cat_roll_speed)

        # add gravity
        self.player_data.cat_speed[1] = min(
            self.player_data.cat_speed[1] + (1 * dt_scaled),
            self.player_data.cat_fall_speed_max,
        )

        self.unicycle_sound.set_volume(
            abs(self.player_data.cat_speed[0] /
                self.player_data.cat_speed_max))

        self._move_cat()
        self._cat_out_of_bounds()

        # check for collision with the elephant stomp
        if self.elephant_active:
            self.elephant.animate(self.total_time)
            self.elephant.collide(width)
        if self.shark_active or self.shark.states[
                self.shark.state] == "leaving":
            self.shark.animate(self.total_time)
            self.shark.collide(self, width, height,
                               self.player_data.cat_location)

        self._cat_jumping(time_delta)
        self._cats_meow(time_delta)
        self._angry_people(time_delta)
        self._collide_flying_objects()
        self._spawn_flying_objects()

    def _move_cat(self):
        """Move, accelerate, and tilt the cat."""

        # accelerate the cat left or right
        if self.right_pressed:
            self.player_data.cat_speed[0] = min(
                self.player_data.cat_speed[0] + 0.3 * self.dt_scaled,
                self.player_data.cat_speed_max,
            )
            self.player_data.cat_angle -= 0.003 * self.dt_scaled

        if self.left_pressed:
            self.player_data.cat_speed[0] = max(
                self.player_data.cat_speed[0] - 0.3 * self.dt_scaled,
                -self.player_data.cat_speed_max,
            )
            self.player_data.cat_angle += 0.003 * self.dt_scaled

        # make the cat fall
        angle_sign = 1 if self.player_data.cat_angle > 0 else -1
        self.player_data.cat_angular_vel += 0.0002 * angle_sign * self.dt_scaled
        self.player_data.cat_angle += self.player_data.cat_angular_vel * self.dt_scaled
        if (self.player_data.cat_angle > math.pi / 2
                or self.player_data.cat_angle < -math.pi / 2
            ) and self.player_data.cat_location[1] > self.height - 160:
            sfx("cat_crash.ogg", play=1)
            self.reset_on_death()

        # move cat
        self.player_data.cat_location[0] += (self.player_data.cat_speed[0] *
                                             self.dt_scaled)
        self.player_data.cat_location[1] += (self.player_data.cat_speed[1] *
                                             self.dt_scaled)
        if (self.player_data.cat_location[1] > self.player_data.cat_wire_height
                and self.player_data.cat_location[0] > 0.25 * self.width):
            self.touching_ground = True
            self.player_data.cat_location[1] = self.player_data.cat_wire_height
            self.player_data.cat_speed[1] = 0
        else:
            self.touching_ground = False

    def _cat_out_of_bounds(self):
        """check for out of bounds"""

        # in the pool
        if self.player_data.cat_location[1] > self.height:
            sfx("splash.ogg", play=1)
            self._meow()
            self.reset_on_death()

        # to the right of screen.
        if self.player_data.cat_location[0] > self.width:
            self.player_data.cat_location[0] = self.width
            if self.player_data.cat_angle > 0:
                self.player_data.cat_angle *= 0.7

        self.player_data.cat_head_location = [
            int(self.player_data.cat_location[0] +
                100 * math.cos(self.player_data.cat_angle - math.pi / 2)),
            int(self.player_data.cat_location[1] +
                100 * math.sin(self.player_data.cat_angle - math.pi / 2)),
        ]

        if (self.player_data.cat_location[0] > 0.98 * self.width
                and self.player_data.cat_location[1] >
                self.player_data.cat_wire_height - 30):
            # bump the cat back in
            self._meow()
            sfx(random.choice(self.boing_names), play=True)
            self.player_data.cat_angular_vel -= 0.01 * self.dt_scaled
            self.player_data.cat_speed[0] = -5
            self.player_data.cat_speed[1] = -20
            # self.reset_on_death()
        if (self.player_data.cat_location[0] < 0.25 * self.width
                and self.player_data.cat_location[1] >
                self.player_data.cat_wire_height - 30):
            pass

    def _cat_jumping(self, time_delta):
        """jumping physics"""
        if self.jumping:
            self.player_data.cat_speed[1] -= (
                time_delta * ((CAT_MAX_JUMPING_TIME - self.jumping_time) /
                              CAT_MAX_JUMPING_TIME) * CAT_JUMP_SPEED)
            self.jumping_time += time_delta
            if self.jumping_time >= CAT_MAX_JUMPING_TIME:
                self.jumping = False

    def _cats_meow(self, time_delta):
        """meow timing"""
        if self.next_meow <= 0:
            self._meow()
        self.next_meow -= time_delta

    def _angry_people(self, time_delta):
        """angry people (increased throwing of not-fish)"""

        if self.people_mad:
            self.people_mad_current_time += time_delta
            self.notfish_time += time_delta
            if self.notfish_time >= self.next_notfish:
                self.next_notfish = random.randint(100, 400)
                self.notfish_time = 0
                self._spawn_not_fish()
            if self.people_mad_current_time >= self.people_mad_duration:
                self.people_mad = False

    def _collide_flying_objects(self):
        """object physics"""
        height = self.height
        dt_scaled = self.dt_scaled

        # move fish and not fish
        for fish in reversed(self.fish.sprites()):
            fish.pos[0] += fish.velocity[0] * dt_scaled  # speed of the throw
            fish.velocity[1] += 0.2 * dt_scaled  # gravity
            fish.pos[1] += fish.velocity[1] * dt_scaled  # y velocity
            # check out of bounds
            if fish.pos[1] > height:
                self.fish.remove(fish)
                fish.kill()
        for fish in reversed(self.not_fish.sprites()):
            fish.pos[0] += fish.velocity[0] * dt_scaled  # speed of the throw
            fish.velocity[1] += 0.2 * dt_scaled  # gravity
            fish.pos[1] += fish.velocity[1] * dt_scaled  # y velocity
            # check out of bounds
            if fish.pos[1] > height:
                self.not_fish.remove(fish)
                fish.kill()

        # check collision with the cat
        for fish in reversed(self.fish.sprites()):
            if (distance([fish.rect[0], fish.rect[1]],
                         self.player_data.cat_head_location) < 100):
                self.player_data.increment_score()
                self.fish.remove(fish)
                sfx("eatfish.ogg", play=1)
                fish.kill()
        for fish in reversed(self.not_fish.sprites()):
            if (distance([fish.rect[0], fish.rect[1]],
                         self.player_data.cat_head_location) < 50):
                self.not_fish.remove(fish)
                fish.kill()
                self.player_data.angle_to_not_fish = (math.atan2(
                    self.player_data.cat_head_location[1] - fish.rect[1],
                    self.player_data.cat_head_location[0] - fish.rect[0],
                ) - math.pi / 2)
                side = 1 if self.player_data.angle_to_not_fish < 0 else -1
                self.player_data.cat_angular_vel += side * random.uniform(
                    0.08, 0.15)
                sfx(random.choice(self.boing_names), play=True)

    def _spawn_flying_objects(self):
        """Throws random objects at the cat."""
        width, height = self.width, self.height

        # refresh lists
        while len(self.fish) < 1 and not self.people_mad:
            # choose a side of the screen
            if random.choice([0, 1]) == 0:
                self.fish.append(
                    Fish(
                        self.allsprites,
                        (0, height / 2),  # random.randint(0, height / 2),
                        (random.randint(3, 7), -random.randint(5, 12)),
                    ))
            else:
                self.fish.append(
                    Fish(
                        self.allsprites,
                        (width, height / 2),  # random.randint(0, height / 2),
                        (-random.randint(3, 7), -random.randint(5, 12)),
                    ))
        while len(self.not_fish) < self.number_of_not_fish:
            self._spawn_not_fish()

    def _spawn_not_fish(self):
        """Choose a side of the screen."""

        velocity_multiplier = 1
        x_pos = 0
        if random.randint(0, 1):
            velocity_multiplier *= -1
            x_pos = self.width
        self.not_fish.append(
            NotFish(
                self.allsprites,
                (x_pos, self.height / 2),
                (random.randint(3, 7) * velocity_multiplier,
                 -random.randint(5, 12)),
            ))

    def _start_jump(self, key):
        self.jump_key = key
        if self.touching_ground and not self.jumping:
            self.jumping = True
            self.jumping_time = 0
            self.player_data.cat_speed[1] -= 12.5
            sfx("cat_jump.ogg", play=1)

    def _stop_jump(self):
        self.jumping = False
        sfx("cat_jump.ogg", fadeout=50)

    def _tilt_left(self):
        self.player_data.cat_angular_vel -= random.uniform(
            0.01 * math.pi, 0.03 * math.pi)

    def _tilt_right(self):
        self.player_data.cat_angular_vel += random.uniform(
            0.01 * math.pi, 0.03 * math.pi)

    def _event_keydown(self, event):
        if event.key == pygame.K_RIGHT:
            self.right_pressed = True
        elif event.key == pygame.K_LEFT:
            self.left_pressed = True
        elif event.key == pygame.K_a:
            self._tilt_left()
        elif event.key == pygame.K_d:
            self._tilt_right()
        elif event.key in (pygame.K_UP, pygame.K_SPACE):
            self._start_jump(event.key)

    def _event_keyup(self, event):
        if event.key == self.jump_key:
            self._stop_jump()
        elif event.key == pygame.K_RIGHT:
            self.right_pressed = False
        elif event.key == pygame.K_LEFT:
            self.left_pressed = False

    def _event_joybuttondown(self, event):
        if event.button in JOY_JUMP_BUTTONS:
            self._start_jump("JOY" + str(event.button))
        if event.button in JOY_LEFT_BUTTONS:
            self._tilt_left()
        if event.button in JOY_RIGHT_BUTTONS:
            self._tilt_right()

    def _event_joybuttonup(self, event):
        if "JOY" + str(event.button) == self.jump_key:
            self._stop_jump()

    def _event_joyaxismotion(self, event):
        if event.axis == 0:
            if event.value >= JOY_SENSE:
                self.right_pressed = True
                self.left_pressed = False
            elif event.value <= -JOY_SENSE:
                self.right_pressed = False
                self.left_pressed = True
            else:
                self.right_pressed = False
                self.left_pressed = False
        if event.axis == JOY_TILT_RIGHT_AXIS:
            # if self.last_joy_right_tilt < JOY_SENSE and event.value >= JOY_SENSE:
            if self.last_joy_right_tilt < JOY_SENSE < event.value:
                self._tilt_right()
            self.last_joy_right_tilt = event.value
        if event.axis == JOY_TILT_LEFT_AXIS:
            # if self.last_joy_left_tilt < JOY_SENSE and event.value >= JOY_SENSE:
            if self.last_joy_left_tilt < JOY_SENSE < event.value:
                self._tilt_left()
            self.last_joy_left_tilt = event.value

    def event(self, event):
        if event.type == pygame.KEYDOWN:
            self._event_keydown(event)
        elif event.type == pygame.KEYUP:
            self._event_keyup(event)
        elif event.type == pygame.JOYBUTTONDOWN:
            self._event_joybuttondown(event)
        elif event.type == pygame.JOYBUTTONUP:
            self._event_joybuttonup(event)
        elif event.type == pygame.JOYAXISMOTION:
            self._event_joyaxismotion(event)
コード例 #11
0
ファイル: MapView.py プロジェクト: bashkirtsevich/Port-Tales
class MapView:
    def __init__(self, action_handler, index):
        # Init clock
        self.clock = pyg.time.Clock()

        # Set handler
        self.action_handler = action_handler

        # Init groupsView
        self.all_sprites = LayeredDirty(_use_updates = True,
                                        _time_threshold = 1000)
        Fps.containers += (self.all_sprites,)

        # Create window
        self.screen, self.background = reset_screen()
        if DISPLAY_FPS:
            Fps(self.clock)

        # Blit level
        image, rect = get_stage_image(index)
        self.background.blit(image, rect)
        self.screen.blit(self.background, self.background.get_rect())

        # Tile handling
        from TileView import TileView
        TileView.layer_container = self.all_sprites

        # Initialize attributes
        self.exit = False
        self.done = False
        self.countdown = None

    def win(self):
        self.done = True
        self.win = True
        self.countdown = countdown(GoalView.len_animation)

    def lose(self, nb_tiles):
        self.done = True
        self.win = False
        value = MinimizingPlayerView.len_animation
        value += TeleportingPlayerView.len_animation * (nb_tiles-2)
        value += FallingPlayerView.len_animation
        value *= 2
        self.countdown = countdown(value)


    def reactor_loop(self):
        # Infinite loop
        while True:
            # Get input
            for ev in pyg.event.get():
                # Quit
                if (ev.type == pyg.KEYDOWN and ev.key == pyg.K_ESCAPE)\
                   or ev.type == pyg.QUIT:
                    safe_exit()
                # Fullscreen
                if ev.type == pyg.KEYDOWN and ev.key == pyg.K_f:
                    # Toggle fullscreen
                    Constants.FULLSCREEN ^= True
                    # Reset screen
                    self.screen, _ = reset_screen()
                    args = self.background, self.background.get_rect()
                    self.screen.blit(*args)
                    # Repaint all
                    self.all_sprites._use_update = False
                # Mute
                if ev.type == pyg.KEYDOWN and ev.key == pyg.K_SEMICOLON:
                    volume = 0 if pyg.mixer.music.get_volume() else VOLUME
                    pyg.mixer.music.set_volume(float(volume)/100)
                # Reset
                if (ev.type == pyg.KEYDOWN and ev.key == pyg.K_r) or\
                (ev.type == pyg.JOYBUTTONDOWN and ev.button in RESET_BUTTONS):
                    win_reset = False, True
                    return win_reset

            # Handle countdown
            if self.done and next(self.countdown):
                self.all_sprites.empty()
                win_reset = self.win, False
                return win_reset

            # Read input
            if not self.done:
                self.action_handler.read_inputs()

            # Clear sprites from screen
            self.all_sprites.clear(self.screen, self.background)

            # Update sprites
            self.all_sprites.update()

            # Draw sprites on screen
            dirty = self.all_sprites.draw(self.screen)

            # Update display
            pyg.display.update(dirty)

            # Frame rate control
            self.clock.tick(FPS)
コード例 #12
0
ファイル: demo.py プロジェクト: tobykurien/rpi_lcars
                pixel = self.image.get_at((x, y)).r
                if pixel > 50:
                    self.image.set_at((x, y), colour)


# create sprites
bg = PpuiImage("assets/lcars_screen_1.png")
button = PpuiImage("assets/button.png")
button.applyColour((255, 204, 153))

# add sprites to layer
sprites = LayeredDirty()
sprites.add(bg)
sprites.add(button)

# event loop
while pygame.display.get_init():
    sprites.draw(screenSurface)
    pygame.display.update()

    for event in pygame.event.get():
        if event.type == KEYUP:
            pygame.quit()
            break

        if event.type == MOUSEMOTION:
            # move button around as mouse moves (or touch-drag)
            button.rect.left = event.pos[0]
            button.rect.top = event.pos[1]
            button.dirty = 1
コード例 #13
0
ファイル: screen.py プロジェクト: pombredanne/axengine2
class Screen(object):
    def __init__(self, name):
        State.name = name
        State.screen = self
        State.controls = State.screens[State.name]['controls']
        State.groups = util.GroupCache()
        self.layers = LayeredDirty()
        self.add_all()
        State.save(State.name)

    def new_game(self):
        self.switch('world')

    def quit(self):
        if State.name == 'title': State.running = False
        else: self.switch(State.prev_name)

    def menu_up(self):
        pass

    def menu_down(self):
        pass

    def add_all(self):
        """Add all the objects specified in the screen's configuration
            resource to their proper sprite groups for rendering."""

        for obj in State.screens[State.name]['objects']:
            self.add_object(obj)

    def add_object(self, name, group=None, pos=None):
        """Add a game object resource to the screen.

        name:   the name of the game object.
        pos:    object will be placed on this tile."""

        # Get object data from given name
        data = State.objects[name]

        # If group is not set, use object's default group.
        if not group: group = data['group']

        # Creates a game object from the name of its group, and adds it to
        # the group.
        sprite = eval(group.capitalize())(data)
        State.groups[group].add(sprite)

        # Set the object's starting tile.
        if pos: data['pos'] = sprite.set_pos(data, pos)

        # If an object is a player, tell the state so it can be controlled.
        # TODO: Make State.player a list of sprites.
        if sprite in State.groups['player']:
            State.player = sprite

        # Add the sprite groups to the rendering queue.
        self.layers.add(State.groups[group])

        return sprite

    def draw(self):
        """Run the update method of every sprite, keeping track of which ones
            are dirty and need updating, and then finally updating only the
            dirty areas."""

        self.layers.update()
        State.dirty = self.layers.draw(State.window)
        display.update(State.dirty)

    def switch(self, name):
        """Switch to a new screen by saving the current state, and then
            restoring the specified state."""

        State.save(State.name)
        State.prev_name = State.name
        State.restore(name)

    def restore(self):
        """Called when a screen is restored from a saved state."""

        State.pressed = []
        for group in State.groups:
            for sprite in State.groups[group]:
                sprite.dirty = 1
                sprite.stopped = True