Example #1
0
    def make_gui_controls(self, grid):
        """Build the controls in the right side of the grid."""

        # the 'grid_row' variable is row to add into
        grid_row = 0

        # put level and position into grid at top right
        self.map_level = DisplayText(title='', label='Level:', tooltip=None)
        grid.addWidget(self.map_level, grid_row, 1, 1, 1)
        self.mouse_position = DisplayText(
            title='',
            label='Lon/Lat:',
            text_width=100,
            tooltip='Shows the mouse longitude and latitude on the map',
        )
        grid.addWidget(self.mouse_position, grid_row, 2, 1, 1)
        grid_row += 1

        # now add the two point control widgets to right part of grid
        self.map_point = PointPlacementControl('Map-relative Point')
        grid.addWidget(self.map_point, grid_row, 1, 1, 2)
        grid_row += 1

        self.view_point = PointPlacementControl('View-relative Point')
        grid.addWidget(self.view_point, grid_row, 1, 1, 2)
        grid_row += 1

        return grid_row
Example #2
0
 def __init__(self, screen, background, clock):
     self.screen = screen
     self.background = background
     self.clock = clock
     self.display_txt = DisplayText(self.background)
     self.title = TitleScreen(self.screen, self.background, self.clock)
     self.end = EndScreen(self.screen, self.background, self.clock,
                          self.display_txt)
    def __init__(self):
        super().__init__()

        self.dt_group = DisplayText(title='Group title longer', label='Label:',
                                    tooltip='A tooltip')
        self.dt_group.set_text("14")

        hbox = QHBoxLayout()
        hbox.setSpacing(5)
        hbox.setContentsMargins(1, 1, 1, 1)
        hbox.addWidget(self.dt_group)
        self.setLayout(hbox)

        self.setWindowTitle('DisplayText widget')
        self.show()
    def make_gui_level_mouse(self):
        """Build the control that shows the level and mouse position.

        Returns reference to containing layout.
        """

        hbox = QHBoxLayout()
        self.map_level = DisplayText(title='', label='Level:', tooltip=None)
        self.mouse_position = DisplayText(title='',
                                          label='Lon/Lat:',
                                          text_width=100,
                                          tooltip=None)
        hbox.addWidget(self.map_level)
        hbox.addWidget(self.mouse_position)

        return hbox
Example #5
0
 def __init__(self, screen, background, clock):
     self.screen = screen
     self.background = background
     self.clock = clock
     self.display_txt = DisplayText(self.background)
     self.title = TitleScreen(self.screen, self.background, self.clock)
     self.end = EndScreen(
         self.screen, self.background, self.clock, self.display_txt)
class DisplayTextExample(QWidget):
    """Application to demonstrate the pySlipQt 'DisplayText' widget."""

    def __init__(self):
        super().__init__()

        self.dt_group = DisplayText(title='Group title longer', label='Label:',
                                    tooltip='A tooltip')
        self.dt_group.set_text("14")

        hbox = QHBoxLayout()
        hbox.setSpacing(5)
        hbox.setContentsMargins(1, 1, 1, 1)
        hbox.addWidget(self.dt_group)
        self.setLayout(hbox)

        self.setWindowTitle('DisplayText widget')
        self.show()
Example #7
0
class TestPointPlacement(QMainWindow):
    def __init__(self, tile_dir=TileDirectory):
        super().__init__()

        self.tile_directory = tile_dir
        self.tile_source = Tiles.Tiles()

        # variables for layer IDs
        self.point_map_layer = None
        self.point_view_layer = None

        # build the GUI
        grid = QGridLayout()
        grid.setColumnStretch(0, 1)
        grid.setContentsMargins(2, 2, 2, 2)

        qwidget = QWidget(self)
        qwidget.setLayout(grid)
        self.setCentralWidget(qwidget)

        # build the 'controls' part of GUI
        num_rows = self.make_gui_controls(grid)

        self.pyslipqt = pySlipQt.PySlipQt(self,
                                          tile_src=self.tile_source,
                                          start_level=MinTileLevel)
        grid.addWidget(self.pyslipqt, 0, 0, num_rows + 1, 1)
        grid.setRowStretch(num_rows, 1)

        # set the size of the demo window, etc
        self.setGeometry(100, 100, DemoWidth, DemoHeight)
        self.setWindowTitle(DemoName)

        # tie events from controls to handlers
        self.map_point.remove.connect(self.remove_point_map)
        self.map_point.change.connect(self.change_point_map)

        self.view_point.remove.connect(self.remove_point_view)
        self.view_point.change.connect(self.change_point_view)

        self.pyslipqt.events.EVT_PYSLIPQT_LEVEL.connect(
            self.handle_level_change)
        self.pyslipqt.events.EVT_PYSLIPQT_POSITION.connect(
            self.handle_position_event)

        self.show()

        # set initial view position
        self.map_level.set_text('%d' % InitViewLevel)
        self.pyslipqt.GotoLevelAndPosition(InitViewLevel, InitViewPosition)

    def make_gui_controls(self, grid):
        """Build the controls in the right side of the grid."""

        # the 'grid_row' variable is row to add into
        grid_row = 0

        # put level and position into grid at top right
        self.map_level = DisplayText(title='', label='Level:', tooltip=None)
        grid.addWidget(self.map_level, grid_row, 1, 1, 1)
        self.mouse_position = DisplayText(
            title='',
            label='Lon/Lat:',
            text_width=100,
            tooltip='Shows the mouse longitude and latitude on the map',
        )
        grid.addWidget(self.mouse_position, grid_row, 2, 1, 1)
        grid_row += 1

        # now add the two point control widgets to right part of grid
        self.map_point = PointPlacementControl('Map-relative Point')
        grid.addWidget(self.map_point, grid_row, 1, 1, 2)
        grid_row += 1

        self.view_point = PointPlacementControl('View-relative Point')
        grid.addWidget(self.view_point, grid_row, 1, 1, 2)
        grid_row += 1

        return grid_row

    def final_setup(self):
        """Perform final setup.

        We do this in a OneShot() function for those operations that
        must not be done while the GUI is "fluid".
        """

        pass
#        self.pyslipqt.GotoLevelAndPosition(InitViewLevel, InitViewPosition)

######
# event handlers
######

##### map-relative point layer

    def change_point_map(self, placement, radius, colour, x, y, off_x, off_y):
        """Display updated point."""

        # remove any previous layer
        if self.point_map_layer:
            self.remove_point_map()

        # create the new layer
        point_data = [(x, y, {
            'placement': placement,
            'radius': radius,
            'colour': colour,
            'offset_x': off_x,
            'offset_y': off_y
        })]
        self.point_map_layer = self.pyslipqt.AddPointLayer(
            point_data, map_rel=True, visible=True, name='<point_layer>')

    def remove_point_map(self):
        """Delete the point map-relative layer."""

        if self.point_map_layer:
            self.pyslipqt.DeleteLayer(self.point_map_layer)
        self.point_map_layer = None

##### view-relative point layer

    def change_point_view(self, placement, radius, colour, x, y, off_x, off_y):
        """Display updated point."""

        if self.point_view_layer:
            self.remove_point_view()

        # create a new point layer
        point_data = [(x, y, {
            'placement': placement,
            'radius': radius,
            'colour': colour,
            'offset_x': off_x,
            'offset_y': off_y
        })]
        self.point_view_layer = self.pyslipqt.AddPointLayer(
            point_data, map_rel=False, visible=True, name='<point_layer>')

    def remove_point_view(self):
        """Delete the point view-relative layer."""

        if self.point_view_layer:
            self.pyslipqt.DeleteLayer(self.point_view_layer)
        self.point_view_layer = None

    ######
    # Exception handlers
    ######

    def handle_position_event(self, event):
        """Handle a pySlipQt POSITION event."""

        posn_str = ''
        if event.mposn:
            (lon, lat) = event.mposn
            posn_str = ('%.*f / %.*f' %
                        (LonLatPrecision, lon, LonLatPrecision, lat))

        self.mouse_position.set_text(posn_str)

    def handle_level_change(self, event):
        """Handle a pySlipQt LEVEL event."""

        self.map_level.set_text('%d' % event.level)
class AppFrame(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setGeometry(300, 300, DemoWidth, DemoHeight)
        self.setWindowTitle(DemoName)
        self.show()

        self.tile_source = tiles.Tiles()
        self.tile_directory = self.tile_source.tiles_dir

        # the data objects for map and view layers
        self.map_layer = None
        self.view_layer = None

        # build the GUI
        self.make_gui()

        self.show()

        # bind events to handlers
        self.pyslipqt.events.EVT_PYSLIPQT_POSITION.connect(
            self.handle_position_event)
        self.pyslipqt.events.EVT_PYSLIPQT_LEVEL.connect(
            self.handle_level_change)

        # finally, goto desired level and position
        self.pyslipqt.GotoLevelAndPosition(InitViewLevel, InitViewPosition)

#####
# Build the GUI
#####

    def make_gui(self):
        """Create application GUI."""

        # build the GUI
        grid = QGridLayout()

        qwidget = QWidget(self)
        qwidget.setLayout(grid)
        self.setCentralWidget(qwidget)

        # add controls to right of spacer
        rows = self.make_gui_controls(grid)
        #        grid.addLayout(controls)

        # put map view in left of horizontal box
        self.pyslipqt = pySlipQt.PySlipQt(self,
                                          start_level=InitViewLevel,
                                          tile_src=self.tile_source)
        grid.addWidget(self.pyslipqt, 0, 0, rows + 1, 1)

    def make_gui_controls(self, grid):
        """Build the 'controls' part of the GUI

        grid  reference to the grid layout to fill
        Returns reference to containing sizer object.
        """

        # row to put controls into
        row = 0

        # add the map level in use widget
        level_mouse = self.make_gui_level_mouse()
        grid.addLayout(level_mouse, row, 1)
        row += 1

        # buttons for each point of interest
        self.buttons = {}
        for (num, city) in enumerate(Cities):
            (lonlat, name) = city
            btn = QPushButton(name)
            grid.addWidget(btn, row, 1)
            btn.clicked.connect(self.handle_button)
            self.buttons[btn] = city
            row += 1

        return row

    def make_gui_level_mouse(self):
        """Build the control that shows the level and mouse position.

        Returns reference to containing layout.
        """

        hbox = QHBoxLayout()
        self.map_level = DisplayText(title='', label='Level:', tooltip=None)
        self.mouse_position = DisplayText(title='',
                                          label='Lon/Lat:',
                                          text_width=100,
                                          tooltip=None)
        hbox.addWidget(self.map_level)
        hbox.addWidget(self.mouse_position)

        return hbox

    ######
    # Exception handlers
    ######

    def handle_button(self, event):
        """Handle button event."""

        # get the button that was pressed
        sender_btn = self.sender()
        (posn, name) = self.buttons[sender_btn]
        log(f"Got button event, posn={posn}, name='{name}'")

        self.pyslipqt.GotoPosition(posn)

        if self.map_layer:
            # if there was a previous layer, delete it
            self.pyslipqt.DeleteLayer(self.map_layer)
        map_data = [posn]
        point_colour = '#0000ff40'
        self.map_layer = self.pyslipqt.AddPointLayer(map_data,
                                                     map_rel=True,
                                                     placement='cc',
                                                     color=point_colour,
                                                     radius=11,
                                                     visible=True,
                                                     name='map_layer')

        if self.view_layer:
            self.pyslipqt.DeleteLayer(self.view_layer)
        view_data = [(
            ((0, 0), (0, -10), (0, 0), (0, 10), (0, 0), (-10, 0), (0, 0), (10,
                                                                           0)),
            {
                'colour': '#ff0000ff'
            },
        )]
        #        poly_colour = '#ff0000ff'
        self.view_layer = self.pyslipqt.AddPolygonLayer(
            view_data,
            map_rel=False,
            placement='cc',
            #                                                        colour=poly_colour,
            closed=False,
            visible=True,
            width=2,
            name='view_layer')

    def handle_position_event(self, event):
        """Handle a pySlip POSITION event."""

        posn_str = ''
        if event.mposn:
            (lon, lat) = event.mposn
            posn_str = ('%.*f / %.*f' %
                        (LonLatPrecision, lon, LonLatPrecision, lat))

        self.mouse_position.set_text(posn_str)

    def handle_level_change(self, event):
        """Handle a pySlip LEVEL event."""

        self.map_level.set_text('%d' % event.level)
Example #9
0
class TestPolyPlacement(QMainWindow):
    def __init__(self, tile_dir=TileDirectory):
        super().__init__()

        self.tile_directory = tile_dir
        self.tile_source = Tiles.Tiles()

        # variables for layer IDs
        self.poly_map_layer = None
        self.poly_view_layer = None

        # build the GUI
        grid = QGridLayout()
        grid.setColumnStretch(0, 1)
        grid.setContentsMargins(2, 2, 2, 2)

        qwidget = QWidget(self)
        qwidget.setLayout(grid)
        self.setCentralWidget(qwidget)

        # build the 'controls' part of GUI
        num_rows = self.make_gui(grid)

        self.pyslipqt = pySlipQt.PySlipQt(self,
                                          tile_src=self.tile_source,
                                          start_level=MinTileLevel)
        grid.addWidget(self.pyslipqt, 0, 0, num_rows + 1, 1)
        grid.setRowStretch(num_rows, 1)

        # set the size of the demo window, etc
        self.setGeometry(100, 100, DemoWidth, DemoHeight)
        self.setWindowTitle(DemoName)

        # tie events from controls to handlers
        self.map_poly.remove.connect(self.remove_poly_map)
        self.map_poly.change.connect(self.change_poly_map)

        self.view_poly.remove.connect(self.remove_poly_view)
        self.view_poly.change.connect(self.change_poly_view)

        self.pyslipqt.events.EVT_PYSLIPQT_LEVEL.connect(
            self.handle_level_change)
        self.pyslipqt.events.EVT_PYSLIPQT_POSITION.connect(
            self.handle_position_event)

        self.map_level.set_text('0')

        self.show()

        # set initial view position
        self.map_level.set_text('%d' % InitViewLevel)
        self.pyslipqt.GotoLevelAndPosition(InitViewLevel, InitViewPosition)

#####
# Build the GUI
#####

    def make_gui(self, grid):
        """Create application GUI."""
        """Build the controls in the right side of the grid."""

        # the 'grid_row' variable is row to add into
        grid_row = 0

        # put level and position into grid at top right
        self.map_level = DisplayText(title='', label='Level:', tooltip=None)
        grid.addWidget(self.map_level, grid_row, 1, 1, 1)
        self.mouse_position = DisplayText(
            title='',
            label='Lon/Lat:',
            text_width=100,
            tooltip='Shows the mouse longitude and latitude on the map',
        )
        grid.addWidget(self.mouse_position, grid_row, 2, 1, 1)
        grid_row += 1

        # now add the two point control widgets to right part of grid
        self.map_poly = LayerControl('Map-relative Polygon')
        grid.addWidget(self.map_poly, grid_row, 1, 1, 2)
        grid_row += 1

        self.view_poly = LayerControl('View-relative Polygon')
        grid.addWidget(self.view_poly, grid_row, 1, 1, 2)
        grid_row += 1

        return grid_row

    ######
    # event handlers
    ######

##### map-relative polygon layer

    def change_poly_map(self, placement, line_width, line_colour, fill_colour,
                        closed, filled, x_off, y_off):
        """Display updated polygon."""

        print(
            f'change_poly_map: placement={placement}, line_width={line_width}, line_colour={line_colour}, fill_colour={fill_colour}, closed={closed}, filled={filled}, x_off={x_off}, y_off={y_off}'
        )

        if self.poly_map_layer:
            self.pyslipqt.DeleteLayer(self.poly_map_layer)

        poly_data = [(PolyPoints, {
            'placement': placement,
            'width': line_width,
            'colour': line_colour,
            'closed': closed,
            'filled': filled,
            'fillcolour': fill_colour,
            'offset_x': x_off,
            'offset_y': y_off
        })]
        self.poly_map_layer = self.pyslipqt.AddPolygonLayer(
            poly_data, map_rel=True, visible=True, name='<poly_map_layer>')

    def remove_poly_map(self):
        """Delete the polygon map-relative layer."""

        if self.poly_map_layer:
            self.pyslipqt.DeleteLayer(self.poly_map_layer)
        self.poly_map_layer = None

##### view-relative polygon layer

    def change_poly_view(self, placement, line_width, line_colour, fill_colour,
                         closed, filled, x_off, y_off):
        """Display updated view-relative polygon layer."""

        if self.poly_view_layer:
            self.pyslipqt.DeleteLayer(self.poly_view_layer)

        # create a new polygon layer
        poly_data = [(PolyViewPoints, {
            'placement': placement,
            'width': line_width,
            'colour': line_colour,
            'closed': closed,
            'filled': filled,
            'fillcolour': fill_colour,
            'offset_x': x_off,
            'offset_y': y_off
        })]
        self.poly_view_layer = self.pyslipqt.AddPolygonLayer(
            poly_data, map_rel=False, visible=True, name='<poly_view_layer>')

    def remove_poly_view(self):
        """Delete the polygon view-relative layer."""

        if self.poly_view_layer:
            self.pyslipqt.DeleteLayer(self.poly_view_layer)
        self.poly_view_layer = None

    def final_setup(self, level, position):
        """Perform final setup.

        level     zoom level required
        position  position to be in centre of view
        """

        self.pyslipqt.GotoLevelAndPosition(level, position)

    ######
    # Exception handlers
    ######

    def handle_position_event(self, event):
        """Handle a pySlipQt POSITION event."""

        posn_str = ''
        if event.mposn:
            (lon, lat) = event.mposn
            posn_str = ('%.*f / %.*f' %
                        (LonLatPrecision, lon, LonLatPrecision, lat))

        self.mouse_position.set_text(posn_str)

    def handle_level_change(self, event):
        """Handle a pySlipQt LEVEL event."""

        self.map_level.set_text('%d' % event.level)
Example #10
0
class SpaceCruise(object):
    def __init__(self, screen, background, clock):
        self.screen = screen
        self.background = background
        self.clock = clock
        self.display_txt = DisplayText(self.background)
        self.title = TitleScreen(self.screen, self.background, self.clock)
        self.end = EndScreen(self.screen, self.background, self.clock,
                             self.display_txt)

    def play_music(self, part):
        tracks = {
            'title': 'sounds/Hudsons Adventure Island - NES - Title Theme.mp3',
            'game': 'sounds/Lagoon - SNES - Phantom Hill.mp3',
            'end': 'sounds/Hudsons Adventure Island - NES - Title Theme.mp3'
        }
        pygame.mixer.music.load(tracks[part])
        pygame.mixer.music.play(-1)

    def stop_music(self):
        pygame.mixer.music.stop()

    def init_game(self):
        # Start music
        self.play_music('game')
        # Init entities
        self.ship = Spaceship(self.background)
        self.bullets = pygame.sprite.Group()
        self.stars = pygame.sprite.Group()
        for s in xrange(self.background.get_height() / 10):
            self.stars.add(Star(self.background, s * 10))
        self.enemies1 = pygame.sprite.Group()
        self.enemies1.add(EnemyOne(self.background))
        self.enemies2 = pygame.sprite.Group()
        self.enemies2.add(EnemyTwo(self.background))
        self.rocks = pygame.sprite.Group()
        self.explosions = pygame.sprite.Group()
        # Init some variables
        self.enemy_timer = 2000
        self.dead = False
        self.auslauf = 40
        self.move = 'center'
        self.running = True

    def preparing_end(self):
        self.clock.tick(30)
        self.auslauf -= 1
        self.explosions.update()
        self.background.fill((0, 0, 0))
        self.stars.add(Star(self.background))
        self.stars.update()
        self.enemies1.update()
        self.enemies2.update()
        self.rocks.update()
        if not self.auslauf:
            self.running = False
            self.run_end()

    def process_input(self):
        # Process keyboard input
        move_dict = {
            pygame.K_LEFT: 'left',
            pygame.K_RIGHT: 'right',
            pygame.K_UP: 'up',
            pygame.K_DOWN: 'down'
        }
        for event in pygame.event.get():
            key = pygame.key.get_pressed()
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key in move_dict:
                    self.move = move_dict[event.key]
                elif event.key == pygame.K_ESCAPE:
                    sys.exit()
                if event.key == pygame.K_SPACE:
                    self.bullets.add(Bullet(self.ship, self.background))
            elif event.type == pygame.KEYUP:
                if not any(key):
                    self.move = 'center'
                if sum(key) == 1:
                    if key[pygame.K_RIGHT]:
                        self.move = 'right'
                    elif key[pygame.K_LEFT]:
                        self.move = 'left'
                    elif key[pygame.K_UP]:
                        self.move = 'up'
                    elif key[pygame.K_DOWN]:
                        self.move = 'down'

    def update_all(self):
        self.background.fill((0, 0, 0))
        self.ship.update(self.move)
        self.bullets.update()
        self.stars.add(Star(self.background))
        self.stars.update()
        self.enemy_timer -= self.clock.get_time()
        if self.enemy_timer < 0:
            self.enemies1.add(EnemyOne(self.background))
            self.enemies2.add(EnemyTwo(self.background))
            self.rocks.add(Rock(self.background))
            self.enemy_timer = 2000
        self.enemies1.update()
        self.enemies2.update()
        self.rocks.update()

    def check_collisions(self):
        self.collisions = pygame.sprite.groupcollide(self.enemies1,
                                                     self.bullets, 1, 1)
        self.collisions.update(
            pygame.sprite.groupcollide(self.enemies2, self.bullets, 1, 1))
        for collision in self.collisions.keys():
            self.explosions.add(Explosion(self.background, collision.rect))
            self.display_txt.add_kill()
        collide = pygame.sprite.spritecollide(self.ship, self.rocks, False)
        collide2 = pygame.sprite.spritecollide(self.ship, self.enemies1, False)
        collide3 = pygame.sprite.spritecollide(self.ship, self.enemies2, False)
        if collide or collide2 or collide3:
            self.explosions.add(Explosion(self.background, self.ship.rect))
            self.ship.kill()
            self.dead = True
        self.explosions.update()

    def game_loop(self):
        """ The game loop. """
        # Init main loop
        self.init_game()
        # Loop
        while self.running:
            if self.dead:
                self.preparing_end()
            else:
                self.clock.tick(30)
                self.process_input()
                # Update entities
                self.update_all()
                # Check collisions
                self.check_collisions()
                self.display_txt.update()
            self.screen.blit(self.background, (0, 0))
            pygame.display.flip()

    def run_title(self):
        self.play_music('title')
        result = self.title.title_loop()
        if result == 'start':
            self.stop_music()
            self.game_loop()
        elif result == 'quit':
            sys.exit()

    def run_end(self):
        self.play_music('end')
        result = self.end.end_loop()
        if result == 'restart':
            self.stop_music()
            self.display_txt.reset()
            self.game_loop()
        elif result == 'quit':
            sys.exit()
Example #11
0
class SpaceCruise(object):

    def __init__(self, screen, background, clock):
        self.screen = screen
        self.background = background
        self.clock = clock
        self.display_txt = DisplayText(self.background)
        self.title = TitleScreen(self.screen, self.background, self.clock)
        self.end = EndScreen(
            self.screen, self.background, self.clock, self.display_txt)

    def play_music(self, part):
        tracks = {
            'title': 'sounds/Hudsons Adventure Island - NES - Title Theme.mp3',
            'game': 'sounds/Lagoon - SNES - Phantom Hill.mp3',
            'end': 'sounds/Hudsons Adventure Island - NES - Title Theme.mp3'}
        pygame.mixer.music.load(tracks[part])
        pygame.mixer.music.play(-1)

    def stop_music(self):
        pygame.mixer.music.stop()

    def init_game(self):
        # Start music
        self.play_music('game')
        # Init entities
        self.ship = Spaceship(self.background)
        self.bullets = pygame.sprite.Group()
        self.stars = pygame.sprite.Group()
        for s in xrange(self.background.get_height() / 10):
            self.stars.add(Star(self.background, s * 10))
        self.enemies1 = pygame.sprite.Group()
        self.enemies1.add(EnemyOne(self.background))
        self.enemies2 = pygame.sprite.Group()
        self.enemies2.add(EnemyTwo(self.background))
        self.rocks = pygame.sprite.Group()
        self.explosions = pygame.sprite.Group()
        # Init some variables
        self.enemy_timer = 2000
        self.dead = False
        self.auslauf = 40
        self.move = 'center'
        self.running = True

    def preparing_end(self):
        self.clock.tick(30)
        self.auslauf -= 1
        self.explosions.update()
        self.background.fill((0, 0, 0))
        self.stars.add(Star(self.background))
        self.stars.update()
        self.enemies1.update()
        self.enemies2.update()
        self.rocks.update()
        if not self.auslauf:
            self.running = False
            self.run_end()

    def process_input(self):
        # Process keyboard input
        move_dict = {pygame.K_LEFT: 'left', pygame.K_RIGHT: 'right',
                     pygame.K_UP: 'up', pygame.K_DOWN: 'down'}
        for event in pygame.event.get():
            key = pygame.key.get_pressed()
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key in move_dict:
                    self.move = move_dict[event.key]
                elif event.key == pygame.K_ESCAPE:
                    sys.exit()
                if event.key == pygame.K_SPACE:
                    self.bullets.add(Bullet(self.ship, self.background))
            elif event.type == pygame.KEYUP:
                if not any(key):
                    self.move = 'center'
                if sum(key) == 1:
                    if key[pygame.K_RIGHT]:
                        self.move = 'right'
                    elif key[pygame.K_LEFT]:
                        self.move = 'left'
                    elif key[pygame.K_UP]:
                        self.move = 'up'
                    elif key[pygame.K_DOWN]:
                        self.move = 'down'

    def update_all(self):
        self.background.fill((0, 0, 0))
        self.ship.update(self.move)
        self.bullets.update()
        self.stars.add(Star(self.background))
        self.stars.update()
        self.enemy_timer -= self.clock.get_time()
        if self.enemy_timer < 0:
            self.enemies1.add(EnemyOne(self.background))
            self.enemies2.add(EnemyTwo(self.background))
            self.rocks.add(Rock(self.background))
            self.enemy_timer = 2000
        self.enemies1.update()
        self.enemies2.update()
        self.rocks.update()

    def check_collisions(self):
        self.collisions = pygame.sprite.groupcollide(
            self.enemies1, self.bullets, 1, 1)
        self.collisions.update(pygame.sprite.groupcollide(
            self.enemies2, self.bullets, 1, 1))
        for collision in self.collisions.keys():
            self.explosions.add(
                Explosion(self.background, collision.rect))
            self.display_txt.add_kill()
        collide = pygame.sprite.spritecollide(
            self.ship, self.rocks, False)
        collide2 = pygame.sprite.spritecollide(
            self.ship, self.enemies1, False)
        collide3 = pygame.sprite.spritecollide(
            self.ship, self.enemies2, False)
        if collide or collide2 or collide3:
            self.explosions.add(
                Explosion(self.background, self.ship.rect))
            self.ship.kill()
            self.dead = True
        self.explosions.update()

    def game_loop(self):
        """ The game loop. """
        # Init main loop
        self.init_game()
        # Loop
        while self.running:
            if self.dead:
                self.preparing_end()
            else:
                self.clock.tick(30)
                self.process_input()
                # Update entities
                self.update_all()
                # Check collisions
                self.check_collisions()
                self.display_txt.update()
            self.screen.blit(self.background, (0, 0))
            pygame.display.flip()

    def run_title(self):
        self.play_music('title')
        result = self.title.title_loop()
        if result == 'start':
            self.stop_music()
            self.game_loop()
        elif result == 'quit':
            sys.exit()

    def run_end(self):
        self.play_music('end')
        result = self.end.end_loop()
        if result == 'restart':
            self.stop_music()
            self.display_txt.reset()
            self.game_loop()
        elif result == 'quit':
            sys.exit()