コード例 #1
0
ファイル: menuview.py プロジェクト: gentimouton/smofac
 def _build_gui(self):
     """ Make a menu widget. """
     gui = LayeredDirty() # only reblit when dirty=1
     # TODO: prepare a rect
     menu_widget = MenuWidget(self._em, self.evtlabels)
     gui.add(menu_widget)
     return gui
コード例 #2
0
ファイル: field.py プロジェクト: zevlg/py-sealhunter
    def add(self, *args, **kwargs):
        """Add object O to field object list."""
        LayeredDirty.add(self, *args, **kwargs)

        # Append object in-place, even if ticking
        for o in args:
            if hasattr(o, "tick"):
                self.objects.append(o)
コード例 #3
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
コード例 #4
0
ファイル: gameview.py プロジェクト: gentimouton/smofac
    def _build_gui(self):
        """ Add a score widget on the right """

        gui = LayeredDirty()  # only reblit when dirty=1

        # score at top-right of the window
        rec = Rect(600 + 10, 0, 100, font_size * 1.5)
        evt_txt_dict = {RecipeMatchEvent: "current_score"}
        score_widget = TextLabelWidget(
            self._em, "0", events_attrs=evt_txt_dict, rect=rec, txtcolor=(0, 0, 0), bgcolor=(222, 222, 222)
        )
        gui.add(score_widget)

        # CPU at bottom-right of the window
        rec = Rect(600 + 10, 600 - font_size * 1.5, 100, font_size * 1.5)
        cpu_widget = CPUDisplayWidget(self._em, "0", rect=rec, txtcolor=(0, 0, 0), bgcolor=(222, 222, 222))
        gui.add(cpu_widget)

        # the recipe widget added when the game is built
        return gui
コード例 #5
0
ファイル: view.py プロジェクト: gentimouton/crowd-control
    def build_gui(self):
        """ Add widgets to the screen.
        Widgets on the left need only be reblitted when they get dirty.
        Widgets that overlay the world screen need to be reblitted every frame.
        """

        # start adding widgets
        leftgui = LayeredDirty() # only reblit when dirty=1
        overlaygui = LayeredUpdates() # reblit every frame
        w, h = self.win_size
        line_h = config_get_fontsize()
        gui_w = self.gui_offset
        
        # -- name label at top-left of the screen
        rec = pygame.Rect(0, 0, gui_w - 1, line_h - 1)
        evt_txt_dict = {MMyNameChangedEvent: 'newname', MGreetNameEvt:'newname'}
        txtcol = config_get_txtlabel_txtcolor()
        bgcol = config_get_txtlabel_bgcolor()
        namebox = TextLabelWidget(self._em, '', events_attrs=evt_txt_dict,
                                  rect=rec, txtcolor=txtcol, bgcolor=bgcol)
        leftgui.add(namebox)
        
        # -- list of connected players, until middle of the screen
        rec = pygame.Rect(0, line_h, gui_w - 1, line_h - 1)
        txt = 'Connected players:'
        txtcol = config_get_txtlabel_txtcolor()
        bgcol = config_get_txtlabel_bgcolor()
        whosonlinetitle = TextLabelWidget(self._em, txt, rect=rec,
                                          txtcolor=txtcol, bgcolor=bgcol)
        leftgui.add(whosonlinetitle)
        rec = pygame.Rect(0, 2 * line_h, gui_w - 1, h / 2 - 2 * line_h - 1)
        numlines = int(rec.height / line_h)
        txtcol = config_get_chatlog_txtcolor()
        bgcol = None #config_get_chatlog_bgcolor()
        whosonlinebox = PlayerListWidget(self._em, numlines, rect=rec,
                                         txtcolor=txtcol, bgcolor=bgcol)
        leftgui.add(whosonlinebox)
        
        # -- chat window overlay at bottom of the world screen
        chat_height = h / 4  
        numlines = int(chat_height / line_h)
        if numlines > 0: # text input field
            rec = pygame.Rect(gui_w + 1, h - line_h, w - gui_w - 1, line_h - 1) 
            chatbox = InputFieldWidget(self._em, rect=rec)
            overlaygui.add(chatbox)
        if numlines > 1: # text display line
            rec = pygame.Rect(gui_w + 1, h * 3 / 4,
                              w - gui_w - 1, h / 4 - line_h - 1)            
            txtcol = config_get_chatlog_txtcolor()
            # no bg color to disply on top of world screen
            chatwindow = ChatLogWidget(self._em, numlines=numlines, rect=rec,
                                       txtcolor=txtcol)
            overlaygui.add(chatwindow)
        
        self.left_gui_sprites = leftgui
        self.overlay_gui_sprites = overlaygui
コード例 #6
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)
コード例 #7
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
コード例 #8
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)
コード例 #9
0
        """Very simple colour substitution"""
        for x in range(0, self.rect.width):
            for y in range(0, self.rect.height):
                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]
コード例 #10
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
コード例 #11
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
コード例 #12
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)
コード例 #13
0
ファイル: gameview.py プロジェクト: gentimouton/smofac
class GameView:
    def __init__(self, em, ev):
        """ Score and recipe widgets on the right, game board on the left.
        em is the mode's event manager,
        ev is an event containing data from the previous mode (e.g. menu 
        or level transition). ev contains the level number.  
        """

        pygame.display.init()  # OK to init multiple times
        pygame.font.init()

        self._em = em

        window = pygame.display.set_mode(resolution)
        self.window = window
        pygame.display.set_caption("Smoothie Factory - In Play")

        # blit the bg screen: all black
        bg = Surface(window.get_size())
        bg.fill((0, 0, 0))
        bg = bg.convert()
        self.window_bg = bg
        self.window.blit(bg, (0, 0))

        # fruit sprites
        self.fruit_to_spr = {}  # map a fruit to its sprite
        self.fruit_sprites = LayeredDirty()  # only reblit when dirty=1
        self.interp_steps = 0  # 2 interpolation steps between 2 model updates

        # build GUI
        self.gui = self._build_gui()  # return a sprite group

        em.subscribe(BoardBuiltEvent, self.on_board_built)
        em.subscribe(GameBuiltEvent, self.on_game_built)
        em.subscribe(FruitKilledEvent, self.on_fruit_killed)
        em.subscribe(FruitPlacedEvent, self.on_fruit_spawned)
        em.subscribe(FruitSpeedEvent, self.on_speed_change)
        em.subscribe(QuitEvent, self.on_quit)

    def _build_gui(self):
        """ Add a score widget on the right """

        gui = LayeredDirty()  # only reblit when dirty=1

        # score at top-right of the window
        rec = Rect(600 + 10, 0, 100, font_size * 1.5)
        evt_txt_dict = {RecipeMatchEvent: "current_score"}
        score_widget = TextLabelWidget(
            self._em, "0", events_attrs=evt_txt_dict, rect=rec, txtcolor=(0, 0, 0), bgcolor=(222, 222, 222)
        )
        gui.add(score_widget)

        # CPU at bottom-right of the window
        rec = Rect(600 + 10, 600 - font_size * 1.5, 100, font_size * 1.5)
        cpu_widget = CPUDisplayWidget(self._em, "0", rect=rec, txtcolor=(0, 0, 0), bgcolor=(222, 222, 222))
        gui.add(cpu_widget)

        # the recipe widget added when the game is built
        return gui

    def on_game_built(self, ev):
        """ Build the recipe GUI, and set the spr movement timer. """

        # recipe widget
        evt_recipe_dict = {RecipeMatchEvent: "recipe"}
        rec = Rect(600, font_size * 1.5, 150, 400)
        # ev.recipes maps tuples of fruit type to score
        rwid = RecipesWidget(
            self._em, ev.recipes, evt_recipe_dict, rect=rec, txtcolor=(222, 222, 222), bgcolor=(0, 0, 0)
        )
        self.gui.add(rwid)

        # spr movement timer
        model_mvt_timer = 1000 / ev.fruit_speed
        self.base_spr_timer = model_mvt_timer / steps_per_cell
        self.spr_timer = self.base_spr_timer

        self._em.subscribe(VTickEvent, self.on_tick)

    def on_board_built(self, ev):
        """ Build the board background. """

        width, height = ev.width, ev.height
        board = ev.board  # to obtain cells from coords

        win_height = self.window.get_height()
        bg = Surface((win_height, win_height))
        bg = bg.convert()
        bg.fill(bg_color)

        for left in range(width):
            for top in range(height):
                cell = board.get_cell(left, top)
                bg.blit(cell.image, cell.rect)
        # blit the board bg onto the window's bg
        self.window_bg.blit(bg, (0, 0))

        self._em.subscribe(BoardUpdatedEvent, self.on_board_update)

    def on_fruit_spawned(self, ev):
        """ When a fruit appears, add it to the sprite group """
        fruit = ev.fruit
        fruit_spr = FruitSpr(fruit, self.interp_steps)
        self.fruit_to_spr[fruit] = fruit_spr
        self.fruit_sprites.add(fruit_spr)

    def on_fruit_killed(self, ev):
        """ When a fruit is killed, remove the spr """
        fruit = ev.fruit
        fruit_spr = self.fruit_to_spr[fruit]
        fruit_spr.kill()  # remove fruit_spr from self.fruit_sprites
        del self.fruit_to_spr[fruit]

    def on_board_update(self, ev):
        """ Store the new fruits' positions. 
        The actual display happens at clock tick. 
        """
        # prepare spr interpolation timer and step counter
        self.spr_timer = self.base_spr_timer
        self.interp_steps = 0  # restart interpolating fruit positions
        for fruit_spr in self.fruit_sprites:
            fruit_spr.resync(self.interp_steps)

    def on_tick(self, ev):
        """ Blit the active board elements and the GUI on the screen. """

        if not pygame.display.get_init():  # if the display is ON
            return

        # spr positions
        duration = ev.loopduration
        self.spr_timer -= duration
        if self.spr_timer <= 0:
            self.spr_timer = self.base_spr_timer
            self.interp_steps += 1
            # interpolate 3 positions,
            # but the last one is done when board is updated (so only 2)
            if self.interp_steps < steps_per_cell:
                for fruit in self.fruit_sprites:
                    fruit.resync(self.interp_steps)

        # display
        gui = self.gui
        fruits = self.fruit_sprites
        screen = self.window
        bg = self.window_bg
        # clear the window from all the sprites, replacing them with the bg
        gui.clear(screen, bg)
        fruits.clear(screen, bg)
        gui.update(duration)  # call update() on each sprite of the group
        fruits.update(duration)  # reset the dirty flag to 0
        # collect the display areas that need to be redrawn
        dirty_gui = gui.draw(screen)
        dirty_fruits = fruits.draw(screen)
        dirty_rects = dirty_gui + dirty_fruits
        pygame.display.update(dirty_rects)  # redisplay those areas only

        # flip the screen
        pygame.display.flip()

    def on_speed_change(self, ev):
        """ When the fruit speed changes, update the speed of fruit sprites. """
        model_mvt_timer = 1000 / ev.speed
        self.base_spr_timer = model_mvt_timer / steps_per_cell

    def on_quit(self, ev):
        """ Shut down the display """
        pygame.display.quit()
コード例 #14
0
ファイル: demo.py プロジェクト: tobykurien/rpi_lcars
        """Very simple colour substitution"""
        for x in range(0, self.rect.width):
            for y in range(0, self.rect.height):
                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]
コード例 #15
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