Exemple #1
0
 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
Exemple #2
0
    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)
Exemple #3
0
 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)
Exemple #4
0
 def __init__(self, world):
     LayeredDirty.__init__(self)
     
     self.world = world
     self.name = None #the name of the team
     self.suit = None #the pygame.image that shows the team
     self.controlpoint = None #the pygame.image of an controlpoint when this team controls it
     self.brain = None #the AgentBrain class that all agents of this team use to generate actions
     self.spawn_point = (0,0) #the spawning location of this team in the current map
     self.score = 0 #the score of the team in this game
     
     self.stats = collections.defaultdict(float) #saves all the statistics.
Exemple #5
0
 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()
Exemple #6
0
 def __init__(self,
              engine,
              *,
              background_color=(0, 0, 100),
              container_class=GameObjectCollection,
              set_up=None,
              **kwargs):
     super().__init__(engine)
     self.background_color = background_color
     self.background = None
     self.game_objects = container_class()
     self.render_group = LayeredDirty()
     if set_up is not None:
         set_up(self)
Exemple #7
0
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)
    def __init__(self, sequence:Sequence, offset:tuple, rect:pygame.Rect, skin:Skin):
        LayeredDirty.__init__(self)
        self.sequence = sequence
        self.sequence.addObserver(self)
        self.offset = offset
        self.rect = rect
        self.skin = skin
        self.blocks = []
        self.trackLines = []
        self.barLines = []
        self.lastTime = sequence.getTime()
        self.widthInBeats = sequence.timeSignature.getBeatsForBars(self.Width.DEF_WIDTH_IN_BARS)
        self.activeTrackCount = Sequence.MIN_TRACKS

        self._initializeGridSprites()
Exemple #9
0
    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
Exemple #10
0
    def __init__(self,
                 name='untitled',
                 par=3,
                 origin=Point(50, 50),
                 width=1080,
                 height=900,
                 ball=None,
                 **labeled_groups):
        self.score = -1
        self.name = name
        self.par = par
        self.origin = origin
        self.width = width
        self.height = height

        self.image = Surface((width, height))

        self.rect = pygame.Rect(*origin.as_2d_tuple(), width, height)

        self.groups = {'all': LayeredDirty()}

        for label, group in labeled_groups.items():
            self.groups[label] = group
            self.groups['all'].add(*group.sprites())

        self.ball = GolfBall(ball, 0, self.groups['all']) if ball else None
Exemple #11
0
 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])
Exemple #12
0
 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)
Exemple #13
0
    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
Exemple #14
0
    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
Exemple #15
0
    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()
Exemple #16
0
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
Exemple #17
0
    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)
Exemple #18
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
Exemple #19
0
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()
Exemple #20
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point


Hole = BaseHole(
    'Hole #3',
    par=3,
    origin=Point(50, 50, 0),
    ball=Point(253, 555, 0),
    noncollidibles=LayeredDirty(
        Text(Point(850, 183), 'Par 3', font.Font(None, 30), colors.WHITE)
    ),
    collidibles=LayeredDirty(
        Green([Point(180, 140, 0), Point(830, 140, 0), Point(830, 240, 0), Point(310, 240, 0), Point(310, 590, 0), Point(180, 590, 0)]),
        Rough([Point(310, 240, 0), Point(380, 240, 0), Point(380, 590, 0), Point(310, 590, 0)]),
        Sand([Point(380, 240, 0), Point(830, 240, 0), Point(830, 310, 0), Point(380, 310, 0)]),
        Pin(Point(780, 190, 0)),
        Money(Point(773, 265)),
        Wall(Point(180, 140, 0), Point(830, 140, 0), 5),
        Wall(Point(830, 140, 0), Point(830, 310, 0), 5),
        Wall(Point(830, 310, 0), Point(380, 310, 0), 5),
        Wall(Point(380, 310, 0), Point(380, 590, 0), 5),
        Wall(Point(380, 590, 0), Point(180, 590, 0), 5),
        Wall(Point(180, 590, 0), Point(180, 140, 0), 5)
    )
)
Exemple #21
0
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
Exemple #22
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point


Hole = BaseHole(
    'Hole #11',
    par=3,
    origin=Point(75, 50, 0),
    ball=Point(180, 680, 0),
    noncollidibles=LayeredDirty(
        Text(Point(900, 75), 'Par 3', font.Font(None, 30), colors.WHITE),
    ),
    collidibles=LayeredDirty(
        Green([Point(130, 620, 0), Point(230, 620, 0), Point(230, 730, 0), Point(130, 730, 0)]),
        Rough([Point(230, 730, 0), Point(230, 680, 0), Point(350, 680, 0), Point(350, 730, 0)]),
        Slope([Point(230, 620, 0), Point(230, 540, 0), Point(350, 540, 0), Point(350, 620, 0)], Color(200, 0, 0, 255), Vector2(0.15, 0.4)),
        Green([Point(230, 620, 0), Point(230, 680, 0), Point(350, 680, 0), Point(350, 620, 0)]),
        Rough([Point(350, 460, 0), Point(470, 460, 0), Point(470, 730, 0), Point(350, 730, 0)]),
        Green([Point(470, 620, 0), Point(710, 620, 0), Point(710, 680, 0), Point(590, 680, 0), Point(590, 730, 0), Point(470, 730, 0)]),
        Green([Point(650, 620, 0), Point(650, 310, 0), Point(790, 310, 0), Point(790, 620, 0)]),
        Sand([Point(790, 620, 0), Point(790, 560, 0), Point(880, 560, 0), Point(880, 620, 0)]),
        Water([Point(790, 560, 0), Point(790, 450, 0), Point(880, 450, 0), Point(880, 560, 0)]),
        Sand([Point(790, 450, 0), Point(790, 310, 0), Point(880, 310, 0), Point(880, 450, 0)]),
        Slope([Point(470, 510, 0), Point(470, 390, 0), Point(650, 390, 0), Point(650, 510, 0)], Color(200, 0, 0, 255), Vector2(-0.2, -0.15)),
        Green([Point(470, 460, 0), Point(130, 460, 0), Point(130, 310, 0), Point(470, 310, 0)]),
        Rough([Point(470, 390, 0), Point(470, 190, 0), Point(560, 190, 0), Point(560, 390, 0)]),
Exemple #23
0
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)
Exemple #24
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point

Hole = BaseHole(
    'Hole #13',
    par=3,
    origin=Point(100, 0, 0),
    ball=Point(495, 315, 0),
    noncollidibles=LayeredDirty(
        Text(Point(775, 605), 'Par 3', font.Font(None, 30), colors.WHITE), ),
    collidibles=LayeredDirty(
        Green([
            Point(440, 260, 0),
            Point(540, 260, 0),
            Point(540, 360, 0),
            Point(440, 360, 0)
        ]),
        Slope([
            Point(440, 360, 0),
            Point(510, 360, 0),
            Point(510, 410, 0),
            Point(470, 410, 0),
            Point(470, 460, 0),
            Point(440, 460, 0)
        ], Color(200, 0, 0, 255), Vector2(0.5, 0.5)),
        Slope([
Exemple #25
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point


Hole = BaseHole(
    'Hole #4',
    par=4,
    origin=Point(50, 100, 0),
    ball=Point(312, 580, 0),
    noncollidibles=LayeredDirty(
        Text(Point(900, 268), 'Par 4', font.Font(None, 30), colors.WHITE),
    ),
    collidibles=LayeredDirty(
        Green([Point(250, 600, 0), Point(250, 150, 0), Point(370, 150, 0), Point(370, 250, 0), Point(770, 250, 0), Point(770, 150, 0), Point(870, 150, 0), Point(870, 400, 0), Point(770, 400, 0), Point(770, 300, 0), Point(370, 300, 0), Point(370, 600, 0)]),
        Slope([Point(250, 150, 0), Point(250, 90, 0), Point(370, 90, 0), Point(370, 150, 0)], Color(100, 0, 0, 255), Vector2(0.0, -0.7)),
        Sand([Point(250, 90, 0), Point(250, 50, 0), Point(370, 50, 0), Point(370, 90, 0)]),
        Slope([Point(410, 250, 0), Point(410, 200, 0), Point(770, 200, 0), Point(770, 250, 0)], Color(100, 0, 0, 255), Vector2(-0.33, -0.6)),
        Slope([Point(410, 300, 0), Point(410, 360, 0), Point(770, 360, 0), Point(770, 300, 0)], Color(100, 0, 0, 255), Vector2(-0.33, 0.6)),
        Rough([Point(410, 200, 0), Point(410, 150, 0), Point(770, 150, 0), Point(770, 200, 0)]),
        Rough([Point(770, 400, 0), Point(410, 400, 0), Point(410, 360, 0), Point(770, 360, 0)]),
        Pin(Point(840, 275, 0)),
        Money(Point(305, 200)),
        Wall(Point(250, 50, 0), Point(370, 50, 0), 5),
        Wall(Point(370, 50, 0), Point(370, 250, 0), 5),
        Wall(Point(370, 250, 0), Point(410, 250, 0), 5),
        Wall(Point(410, 250, 0), Point(410, 150, 0), 5),
Exemple #26
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point

Hole = BaseHole('Hole #12',
                par=5,
                origin=Point(80, 30, 0),
                ball=Point(440, 125, 0),
                noncollidibles=LayeredDirty(
                    Text(Point(530, 15), 'Par 5', font.Font(None, 30),
                         colors.WHITE), ),
                collidibles=LayeredDirty(
                    Green([
                        Point(50, 50, 0),
                        Point(500, 50, 0),
                        Point(500, 200, 0),
                        Point(100, 200, 0),
                        Point(100, 450, 0),
                        Point(50, 450, 0)
                    ]),
                    Slope([
                        Point(100, 200, 0),
                        Point(200, 200, 0),
                        Point(200, 450, 0),
                        Point(100, 450, 0)
                    ], Color(200, 0, 0, 255), Vector2(0.3, 0.0)),
                    Sand([
Exemple #27
0
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)
Exemple #28
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point

Hole = BaseHole('Hole #10',
                par=2,
                origin=Point(50, 75, 0),
                ball=Point(485, 690, 0),
                noncollidibles=LayeredDirty(
                    Text(Point(810, 340), 'Par 2', font.Font(None, 30),
                         colors.WHITE), ),
                collidibles=LayeredDirty(
                    Rough([
                        Point(300, 430, 0),
                        Point(340, 430, 0),
                        Point(340, 470, 0),
                        Point(300, 470, 0)
                    ]),
                    Rough([
                        Point(630, 430, 0),
                        Point(670, 430, 0),
                        Point(670, 470, 0),
                        Point(630, 470, 0)
                    ]),
                    Slope([
                        Point(300, 430, 0),
                        Point(260, 390, 0),
Exemple #29
0
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)
Exemple #30
0
 def init(cls):
     cls.contents = LayeredDirty()
     cls.clock = time.Clock()
Exemple #31
0
    def applyColour(self, colour):
        """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)
Exemple #32
0
def addGroup():
   newGroup = LayeredDirty()
   groupList.append(newGroup)
Exemple #33
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)
Exemple #34
0
 def __init__(self, *args, **kwargs):
     kwargs.setdefault("_time_threshold", 9e9)
     LayeredDirty.__init__(self, *args, **kwargs)
Exemple #35
0
 def __init__(self, *args, **kwargs):
     kwargs.setdefault("_time_threshold", 9e9)
     LayeredDirty.__init__(self, *args, **kwargs)
Exemple #36
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()
        # 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
Exemple #37
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point

Hole = BaseHole(
    'Hole #7',
    par=4,
    origin=Point(50, 50, 0),
    ball=Point(255, 630, 0),
    noncollidibles=LayeredDirty(
        Text(Point(805, 70), 'Par 4', font.Font(None, 30), colors.WHITE)),
    collidibles=LayeredDirty(
        Green([
            Point(50, 500, 0),
            Point(450, 500, 0),
            Point(450, 700, 0),
            Point(50, 700, 0)
        ]),
        Slope([
            Point(200, 500, 0),
            Point(300, 500, 0),
            Point(300, 325, 0),
            Point(200, 325, 0)
        ], Color(125, 0, 0, 255), Vector2(0.0, -0.1)),
        Rough([
            Point(200, 325, 0),
            Point(200, 200, 0),
Exemple #38
0
import pygame, sys, os, time
from pygame.locals import *
from pygame import font
from pygame.sprite import DirtySprite, LayeredDirty
pygame.init()
global allFont
allFont = font.SysFont("monospace",11)
# set up the window
global MAINWINDOW
MAINWINDOW = pygame.display.set_mode((1200, 1000), 0, 32)
pygame.display.set_caption('Character Generator')
global fullWindowGroup
fullWindowGroup = LayeredDirty()
global groupList
groupList = []
groupList.append(fullWindowGroup)
def drawSquare(xposition,yposition,length,color):
   pygame.draw.rect(MAINWINDOW, color, (xposition,yposition,length,length))
def drawRect(rect,color):
   r = pygame.draw.rect(MAINWINDOW, color, rect)
   return r
#groups
def addGroup():
   newGroup = LayeredDirty()
   groupList.append(newGroup)
def drawGroup(group):
   dirty = group.draw(MAINWINDOW)
   pygame.display.update(dirty)
def drawAllGroups():
   for g in groupList:
      drawGroup(g)
Exemple #39
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point

Hole = BaseHole(
    'Hole #6',
    par=3,
    origin=Point(150, 100, 0),
    ball=Point(200, 630, 0),
    noncollidibles=LayeredDirty(
        Text(Point(88, 92), 'Par 3', font.Font(None, 30), colors.WHITE)),
    collidibles=LayeredDirty(
        Water([
            Point(150, 150, 0),
            Point(150, 550, 0),
            Point(550, 550, 0),
            Point(550, 150, 0)
        ]),
        Green([
            Point(150, 550, 0),
            Point(550, 550, 0),
            Point(550, 700, 0),
            Point(150, 700, 0)
        ]),
        Green([
            Point(150, 150, 0),
            Point(150, 50, 0),
Exemple #40
0
 def init(cls):
     cls.objects = LayeredDirty()
     cls.selected_objects = []
Exemple #41
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point


Hole = BaseHole(
    'Hole #8',
    par=2,
    origin=Point(50, 50, 0),
    ball=Point(145, 520, 0),
    noncollidibles=LayeredDirty(
        Text(Point(708, 20), 'Par 2', font.Font(None, 30), colors.WHITE),
        Text(Point(925, 310), 'Is this lava?', font.Font(None, 24), colors.WHITE)
    ),
    collidibles=LayeredDirty(
        Green([Point(50, 50, 0), Point(50, 580, 0), Point(250, 580, 0), Point(250, 200, 0), Point(650, 200, 0), Point(650, 50, 0)]),
        Rough([Point(650, 50, 0), Point(800, 50, 0), Point(800, 200, 0), Point(650, 200, 0)]),
        Lava([Point(250, 580, 0), Point(250, 200, 0), Point(800, 200, 0), Point(800, 50, 0), Point(900, 50, 0), Point(900, 580, 0)]),
        Pin(Point(730, 125, 0)),
        Money(Point(225, 175)),
        Wall(Point(50, 50, 0), Point(900, 50, 0), 5),
        Wall(Point(900, 50, 0), Point(900, 580, 0), 5),
        Wall(Point(900, 580, 0), Point(50, 580, 0), 5),
        Wall(Point(50, 580, 0), Point(50, 50, 0), 5)
    )
)
Exemple #42
0
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
Exemple #43
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point

Hole = BaseHole('Hole #5',
                par=4,
                origin=Point(50, 100, 0),
                ball=Point(490, 550, 0),
                noncollidibles=LayeredDirty(
                    Text(Point(670, 138), 'Par 4', font.Font(None, 30),
                         colors.WHITE), ),
                collidibles=LayeredDirty(
                    Green([
                        Point(440, 100, 0),
                        Point(540, 100, 0),
                        Point(540, 200, 0),
                        Point(440, 200, 0)
                    ]),
                    Slope([
                        Point(440, 100, 0),
                        Point(380, 50, 0),
                        Point(600, 50, 0),
                        Point(540, 100, 0)
                    ], Color(100, 0, 0, 255), Vector2(0.0, -0.4)),
                    Slope([
                        Point(600, 50, 0),
                        Point(540, 100, 0),
Exemple #44
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point

Hole = BaseHole('Hole #1',
                par=1,
                origin=Point(50, 50, 0),
                ball=Point(535, 545, 0),
                noncollidibles=LayeredDirty(
                    Text(Point(515, 160), 'Par 1', font.Font(None, 30),
                         colors.WHITE), ),
                collidibles=LayeredDirty(
                    Green([
                        Point(360, 190, 0),
                        Point(700, 190, 0),
                        Point(700, 600, 0),
                        Point(360, 600, 0)
                    ]), Pin(Point(535, 260, 0)), Money(Point(529, 215)),
                    Wall(Point(360, 190, 0), Point(700, 190, 0), 5),
                    Wall(Point(700, 190, 0), Point(700, 600, 0), 5),
                    Wall(Point(700, 600, 0), Point(360, 600, 0), 5),
                    Wall(Point(360, 600, 0), Point(360, 190, 0), 5)))
Exemple #45
0
    def applyColour(self, colour):
        """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)
Exemple #46
0
from pygame import Color, font
from pygame.math import Vector2
from pygame.sprite import LayeredDirty

from src.models import Hole as BaseHole
from src.sprites import *
from src.utils import colors, Point


Hole = BaseHole(
    'Hole #9',
    par=3,
    origin=Point(150, 50, 0),
    ball=Point(505, 450, 0),
    noncollidibles=LayeredDirty(
        Text(Point(590, 143), 'Par 3', font.Font(None, 30), colors.WHITE),
    ),
    collidibles=LayeredDirty(
        Green([Point(450, 100, 0), Point(560, 100, 0), Point(560, 200, 0), Point(450, 200, 0)]),
        Lava([Point(450, 200, 0), Point(440, 200, 0), Point(440, 90, 0), Point(450, 90, 0)]),
        Lava([Point(450, 100, 0), Point(450, 90, 0), Point(570, 90, 0), Point(570, 100, 0)]),
        Lava([Point(560, 100, 0), Point(560, 210, 0), Point(570, 210, 0), Point(570, 100, 0)]),
        Lava([Point(560, 210, 0), Point(440, 210, 0), Point(440, 200, 0), Point(560, 200, 0)]),
        Green([Point(440, 210, 0), Point(440, 510, 0), Point(570, 510, 0), Point(570, 210, 0)]),
        Slope([Point(570, 510, 0), Point(570, 360, 0), Point(620, 360, 0), Point(620, 510, 0)], Color(200, 0, 0, 255), Vector2(0.33, 0.0)),
        Green([Point(620, 360, 0), Point(750, 510, 0), Point(620, 510, 0)]),
        Slope([Point(620, 510, 0), Point(620, 560, 0), Point(750, 560, 0), Point(750, 510, 0)], Color(200, 0, 0, 255), Vector2(0.0, 0.4)),
        Green([Point(620, 560, 0), Point(620, 700, 0), Point(750, 560, 0)]),
        Slope([Point(620, 560, 0), Point(570, 560, 0), Point(570, 700, 0), Point(620, 700, 0)], Color(200, 0, 0, 255), Vector2(-0.5, 0.0)),
        Green([Point(340, 560, 0), Point(340, 620, 0), Point(570, 620, 0), Point(570, 560, 0)]),
        Rough([Point(570, 700, 0), Point(570, 620, 0), Point(340, 620, 0), Point(340, 700, 0)]),
Exemple #47
0
    def __init__(self, console=None):
        self.console = console
        self.players = []               # players on the field
        self.objects = []               # objects on the field
        self.deleted = []               # object to delete

        LayeredDirty.__init__(self, _update=True, _time_threshold=1000.0/FPS)
        self.game_over = False
        self.screen = pygame.display.get_surface()

        self.lockfps = FPS
        self.clock = pygame.time.Clock()

        self.bg = load_texture("Misc/backdrop.png")
        self.ice = load_texture("Misc/ice.png", True)
        self.ice_mask = pygame.mask.from_surface(self.ice)
        self.ice_rects = [pygame.Rect(FLIMIT_WIDTH[0], FLIMIT_HEIGHT[0],
                                      FLIMIT_WIDTH[1]-FLIMIT_WIDTH[0],
                                      FLIMIT_HEIGHT[1]-FLIMIT_HEIGHT[0]),
                          self.ice_mask.get_bounding_rects()[0]]
        self.ice_gap_rect = pygame.Rect(270, 0, 66, 175)

        if 'field' in option('debug'):
            debug("FIELD: ice rects: %s"%self.ice_rects)

        self.start = pygame.Surface((640,480))
        self.start.blit(self.bg, (0, 0))
        self.start.blit(self.ice, (0, ICE_YOFFSET))

        self.field = self.start.copy()
        self.ticks = 0                  # total ticks field played

        self.screen.blit(self.field, (0,0))
        # System font, for messages and FPS
        self.sfont = load_font("default.ttf", 14)

        # FPS drawer if needed
        if "fps" in option("show"):
            self.fps = pygame.sprite.GroupSingle()
            self.fps.add(pygame.sprite.DirtySprite())
#            self.fpsprite = pygame.sprite.DirtySprite()
            self.update_fpsprite()
            # show FPS rate on top of everything
            self.add(self.fps, layer=TOP_LAYER)

        # Messages
        self.messages = []
        self.show_messages = []

        self.msgs = pygame.sprite.DirtySprite()
        self.msgs.visible = 0
        self.msgs_offset = 0
        self.msgs_linesize = self.sfont.get_linesize()
        _ssh = self.msgs_linesize * option("max-messages")
        sprite_image(self.msgs, pygame.Surface((640, _ssh)))
        sprite_move(self.msgs, 0, 71)
        self.add(self.msgs, layer=0)

        # Sprite for level's progress
        self.lp_font = load_font('trebuc.ttf', 14)
        self.lp_font.set_bold(True)

        self.level_prgrs = pygame.sprite.DirtySprite()
        sprite_image(self.level_prgrs, pygame.Surface((640, 20)))
        sprite_move(self.level_prgrs, 0, 0)
        self.level_prgrs.image.blit(self.bg, (0,0), self.level_prgrs.rect)
        self.add(self.level_prgrs, layer=TOP_LAYER)
Exemple #48
0
    def remove(self, *args):
        """Remove object O from field's object list."""
        LayeredDirty.remove(self, *args)

        # Mark as deleted, so object will be deleted on next tick
        self.deleted.extend(args)
Exemple #49
0
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