def __init__(self, scene, location: Tuple[int, int]):
        """
        Construct a new NPC.

        :param location: The top-left coordinate of the object on the screen.
        """

        # Crash proof scaling
        while True:
            try:
                avatar_num = random.randint(0, Avatars.max_number)

                # Prevent duplicate avatars
                if avatar_num in self.avatars_in_use:
                    continue
                else:
                    self.avatars_in_use.append(avatar_num)

                avatar_image: Surface = pygame.image.load(
                    str(Paths.avatars / f"{avatar_num}.png"))
                headless_image: Surface = pygame.image.load(
                    str(Paths.headless / f"headless{avatar_num % 5}.png"))
                avatar_image = pygame.transform.smoothscale(
                    avatar_image, Avatars.size)
            except ValueError:
                print(f"ERROR: Avatar {avatar_num} is not 24 or 32bit")
            else:
                break

        # Turn around after x frames
        self.frames_until_turn = random.randint(100, 500)
        self.frames_until_walk = random.randint(10, 150)

        size = (headless_image.get_width() + 20, avatar_image.get_height() +
                headless_image.get_height() - Avatars.offset_y)

        surface = Surface(size)
        surface.fill(Colors.black)
        surface.set_colorkey(Colors.black)
        surface.blits(((headless_image,
                        (0, avatar_image.get_height() - Avatars.offset_y)),
                       (avatar_image, (Avatars.offset_x, 0))))

        super().__init__(scene, location, surface)
Example #2
0
class HighScore(GameObject):
    def get_scores(self):
        with open(HIGHSCORES_BASEPATH, 'r') as scores_json:
            json_scores = json.loads(scores_json.read())
        return json_scores

    def set_cursor_positions(self, cursor: Cursor):
        # Cursor positions
        cursor.add_position(
            self.back.rect.left - cursor.rect.width,
            self.back.rect.centery - int(cursor.rect.height / 2),
        )

    def update_scores(self):
        # Create TExt objects for the scores
        font_file = 'BalooChettan2-SemiBold.ttf'
        self.scores = []
        self.score_pos = []
        for i, score in enumerate(self.get_scores()):
            self.scores.append(
                TextObject(
                    str(score),
                    font_file,
                    antialias=True,
                    font_color=colors.white,
                    font_size=32,
                ), )
            self.score_pos.append(
                TextObject(
                    f'{str(i + 1)}.',
                    font_file,
                    antialias=True,
                    font_color=colors.white,
                    font_size=32,
                ))

        # Set position of the scores
        max_width = 0
        separation = 150
        for score in self.scores:
            if score.rect.width > max_width:
                max_width = score.rect.width
        for i, score in enumerate(self.scores):
            score.rect.move_ip(
                ((self.screen_w / 2) + separation + max_width -
                 score.rect.width),
                self.screen_h * .3 + self.screen_h * .05 * i,
            )
            self.score_pos[i].rect.move_ip(
                ((self.screen_w / 2) - separation -
                 self.score_pos[i].rect.width),
                score.rect.top,
            )

        # Draw base image
        self.image = Surface((self.screen_w, self.screen_h))
        self.image.set_colorkey((0, 0, 0))
        self.image.blits((
            *[s.get_draw() for s in self.score_pos],
            *[s.get_draw() for s in self.scores],
            self.back.get_draw(),
            self.title_text.get_draw(),
        ))

        # Base rect
        self.rect = self.image.get_rect()

        # Update draw
        self.dirty = 1

    def start(self):
        # Text creation
        font_file = 'BalooChettan2-SemiBold.ttf'
        self.title_text = TextObject(
            'High Scores',
            font_file,
            antialias=True,
            font_color=colors.white,
            font_size=64,
        )
        self.back = TextObject(
            'Back',
            font_file,
            antialias=True,
            font_color=colors.white,
            font_size=32,
        )

        # Text position
        self.title_text.set_pos(
            (self.screen_w - self.title_text.rect.width) / 2,
            int(self.screen_h * .1))

        self.back.set_pos((self.screen_w - self.back.rect.width) / 2,
                          self.screen_h * .75)
Example #3
0
class TextShootObject(TextObject):
    def __init__(self,
                 scene,
                 location: Tuple[int, int],
                 parent: GraphicalObject = None,
                 short: bool = False):

        if not short and random.randint(0, 4) == 2:
            self.word = random.choice(Words.long).upper()
        else:
            self.word = random.choice(Words.single).upper()

        self.typed = 0

        super().__init__(scene,
                         location,
                         self.word,
                         font_path=FONT_PATH,
                         font_size=FONT_SIZE,
                         font_color=Colors.white)

        self.parent = parent
        self.half_width = self.surface.get_width() / 2

    def key_input(self, key):
        key_name = pygame.key.name(key)

        if key_name == "space":
            key_name = " "

        if self.word[self.typed].lower() == key_name:
            if self.typed == len(self.word) - 1:
                return TextShootState.WORD_END
            self.typed += 1
            return TextShootState.SUCCESS
        return TextShootState.WRONG_KEY

    def draw(self):
        if not self.typed:
            self.surface = FONT.render(self.word, True, Colors.white,
                                       Colors.blurple)
        elif self.typed >= len(self.word):
            self.surface = FONT.render(self.word, True, Colors.red,
                                       Colors.blurple)
        else:
            typed_text = self.word[:self.typed].replace(" ", "_")
            untyped_text = self.word[self.typed:]

            typed_surface: Surface = FONT.render(typed_text, True, Colors.red,
                                                 Colors.blurple)
            untyped_surface: Surface = FONT.render(untyped_text, True,
                                                   Colors.white,
                                                   Colors.blurple)

            self.surface = Surface(
                (typed_surface.get_width() + untyped_surface.get_width(),
                 max(typed_surface.get_height(),
                     untyped_surface.get_height())))

            self.surface.blits(
                ((typed_surface, (0, 0)), (untyped_surface,
                                           (typed_surface.get_width(), 0))))

        surface = Surface(
            (self.surface.get_width() + 20, self.surface.get_height()))

        surface.set_colorkey((0, 0, 0))

        pygame.draw.ellipse(surface, Colors.blurple,
                            Rect(0, 0, 20, surface.get_height()))
        pygame.draw.ellipse(
            surface, Colors.blurple,
            Rect(surface.get_width() - 20, 0, 20, surface.get_height()))

        surface.blit(self.surface, (10, 0))
        self.surface = surface

        if self.parent:
            self.location = (self.parent.location[0] - self.half_width +
                             self.parent.surface.get_width() / 2,
                             self.parent.location[1] - 40)

        # Out of bounds on left side
        if self.location[0] <= 0 and self.parent.y_direction < 0:
            self.parent.y_direction = abs(self.parent.y_direction)
            self.parent.move_absolute((self.half_width + self.parent.size[0],
                                       self.parent.location[1]))

        # Out of bounds on right side
        elif self.location[0] + self.surface.get_width() >= screen.get_width(
        ) and self.parent.y_direction > 0:
            self.parent.y_direction = -abs(self.parent.y_direction)
            new_x = Window.width - (self.half_width + self.parent.size[0])
            self.parent.move_absolute((new_x, self.parent.location[1]))

        super(TextObject, self).draw()

        if self.parent:
            self.parent.draw()
Example #4
0
class Credits(GameObject):
    font_file = 'BalooChettan2-SemiBold.ttf'

    def set_cursor_positions(self, cursor: Cursor):
        # Cursor positions
        cursor.add_position(
            self.back.rect.left - cursor.rect.width,
            self.back.rect.centery - int(cursor.rect.height / 2),
        )

    def start(self):
        # Text creation
        self.title_text = TextObject(
            'Credits',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=64,
        )

        font_size = 24
        # Game Developer
        self.gd_title = TextObject(
            'Game Developer:',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=font_size,
        )
        self.gd_content = TextObject(
            'Oscar Rencoret github.com/Raksoiv',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=font_size,
        )

        # Assets
        self.a_title = TextObject(
            'Art Pack:',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=font_size,
        )
        self.a_content = TextObject(
            '« Space Shooter Redux » from Kenney.nl',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=font_size,
        )

        # Music
        self.s_title = TextObject(
            'Music:',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=font_size,
        )
        self.s1_content = TextObject(
            '« Deep Blue » from Bensound.com',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=font_size,
        )
        self.s2_content = TextObject(
            '« Extreme Action » from Bensound.com',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=font_size,
        )

        # Back
        self.back = TextObject(
            'Back',
            self.font_file,
            antialias=True,
            font_color=colors.white,
            font_size=font_size,
        )

        # Set the positions of the text
        self.title_text.set_pos(
            (self.screen_w - self.title_text.rect.width) / 2,
            int(self.screen_h * .1))

        title_x = int(self.screen_w * .4) - 10
        content_x = int(self.screen_w * .4) + 10

        gd_top = self.screen_h * .3
        self.gd_title.set_pos(0, gd_top)
        # self.gd_title.rect.left = 100
        self.gd_title.rect.right = title_x
        self.gd_content.set_pos(0, gd_top)
        # self.gd_content.rect.right = self.screen_w - 100
        self.gd_content.rect.left = content_x

        a_top = gd_top + 2 * font_size
        self.a_title.set_pos(0, a_top)
        # self.a_title.rect.left = 100
        self.a_title.rect.right = title_x
        self.a_content.set_pos(0, a_top)
        # self.a_content.rect.right = self.screen_w - 100
        self.a_content.rect.left = content_x

        s1_top = a_top + 2 * font_size
        s2_top = s1_top + font_size
        self.s_title.set_pos(0, s1_top)
        # self.s_title.rect.left = 100
        self.s_title.rect.right = title_x
        self.s1_content.set_pos(0, s1_top)
        # self.s1_content.rect.right = self.screen_w - 100
        self.s1_content.rect.left = content_x
        self.s2_content.set_pos(0, s2_top)
        # self.s2_content.rect.right = self.screen_w - 100
        self.s2_content.rect.left = content_x

        self.back.set_pos((self.screen_w - self.back.rect.width) / 2,
                          self.screen_h * .75)

        # Set the base image
        self.image = Surface((self.screen_w, self.screen_h))
        self.image.set_colorkey((0, 0, 0))
        self.image.blits((
            self.title_text.get_draw(),
            self.gd_title.get_draw(),
            self.gd_content.get_draw(),
            self.a_title.get_draw(),
            self.a_content.get_draw(),
            self.s_title.get_draw(),
            self.s1_content.get_draw(),
            self.s2_content.get_draw(),
            self.back.get_draw(),
        ))

        self.rect = self.image.get_rect()

        # Update draw
        self.dirty = 1
Example #5
0
 def render(self, screen: Surface) -> None:
     screen.blits((
         (text, text_rect)
         for text, text_rect, text_ts in self._on_screen
     ))