Example #1
0
def run():
    pygame.init()

    pygame.display.set_caption("Ballsurf")

    fps = 60
    default_millis = 1000 / fps
    fps_clock = pygame.time.Clock()

    width, height = 1280, 720
    screen: pygame.Surface = pygame.display.set_mode((width, height))

    game = Game()
    context = Context()

    # Game loop.
    while True:
        screen.fill((0, 0, 0))

        context.key_strokes = set()
        context.resize = False
        context.letter = ''

        # Get system events
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.VIDEORESIZE:
                width, height = event.dict['size']
                pygame.display.set_mode((width, height))
                context.resize = True
                CachedImage.clear_cache()

            if event.type == pygame.KEYDOWN:
                if event.key == 8:
                    context.key_strokes.add(Key.BACKSPACE)
                else:
                    context.letter = event.unicode

        # Key key strokes
        keys = pygame.key.get_pressed()
        if keys[K_SPACE]:
            context.key_strokes.add(Key.SPACE)
        if keys[K_RETURN]:
            context.key_strokes.add(Key.ENTER)
        if keys[K_DOWN]:
            context.key_strokes.add(Key.NEXT)
        if keys[K_UP]:
            context.key_strokes.add(Key.PREV)
        if keys[K_ESCAPE]:
            context.key_strokes.add(Key.ESCAPE)

        game.update(context)

        size = min(width, height)
        game.render(screen, size / Const.game_height)

        pygame.display.flip()
        context.time_factor = fps_clock.tick(fps) / default_millis
Example #2
0
    def __init__(self):
        self.__x = 0
        self.meters = Const.offset_meters
        self.image = CachedImage("res/img/noice.png")
        self.border = self.image.get_width() * Const.pixel_size
        self.random_line = [-1, 1]

        self.score = score.load_score()
Example #3
0
    def __init__(self, x=None):
        if x is None:
            self.x = 2 * Const.game_height
        else:
            self.x = x

        self.image = CachedImage(self.filename())
        self.diameter = self.image.get_width() * Const.pixel_size

        self.y = Const.game_height - self.diameter
        self.__vspeed = 0
        self.bounced = False
        self.hit_bottom = False

        self.id = uuid.uuid4()
Example #4
0
    def __init__(self, **kwargs):
        super(Direntry, self).__init__(**kwargs)

        with self.canvas:
            Color(0, 0, 0, 1)
            self.r = Rectangle()

        self.ci = CachedImage(pos_hint={'x': 0, 'y': 0.25},
                              size_hint=(1, 0.75),
                              fill=True)
        with self.ci.canvas.before:
            Color(0, 0, 0, 1)
            self.ci.r = Rectangle()
        self.add_widget(self.ci)

        self.l = Label(pos_hint={'x': 0.02, 'top': 0.24},
                           size_hint=(None, None))
        self.l.bind(texture_size=lambda *a: setattr(self.l, 'size', a[1]))
        self.add_widget(self.l)

        self.bind(pos=self.update_pos, size=self.update_size,
                  source=self.update_source,
                  orientation=self.update_orientation,
                  text=self.update_text)

        self.update_source(None, self.source)
        self.update_orientation(None, self.orientation)
        self.update_text(None, self.text)
Example #5
0
    def __init__(self,
                 filename: str,
                 top: float,
                 speed: float,
                 x: Optional[float] = None,
                 mirror: bool = True):
        if x is None:
            x = 2

        self.x = x * Const.game_height
        self.speed = speed

        self.image = CachedImage(filename, mirror and random.getrandbits(1))

        self.height = self.image.get_height() * Const.pixel_size
        self.width = self.image.get_width() * Const.pixel_size
        self.y = top
Example #6
0
class Background(Sprite, ABC):
    def __init__(self,
                 filename: str,
                 top: float,
                 speed: float,
                 x: Optional[float] = None,
                 mirror: bool = True):
        if x is None:
            x = 2

        self.x = x * Const.game_height
        self.speed = speed

        self.image = CachedImage(filename, mirror and random.getrandbits(1))

        self.height = self.image.get_height() * Const.pixel_size
        self.width = self.image.get_width() * Const.pixel_size
        self.y = top

    def update(self, context: Context, sprites: Sprites):
        self.x -= context.x_delta * self.speed

    def render(self, surface: pygame.Surface, size_factor: float):
        h = int(self.height * size_factor)
        w = int(self.width * size_factor)

        img = self.image.scale(w, h)

        l = int(self.x * size_factor)
        rect = pygame.Rect(0 if l >= 0 else abs(l), 0, w + min(0, l), h)

        surface.blit(img, (max(0, l), self.y * size_factor), rect)

    @property
    def box(self) -> GameRect:
        return GameRect(self.x, self.y, self.width, self.height)

    def can_delete(self) -> bool:
        return self.x <= -self.width
Example #7
0
    def got_dir(self, req, res, dt=0):
        if req:
            if res == rescache.get(req.url):
                return
            else:
                self.clear_widgets()
                rescache.set(req.url, res)

        sdir, direntries = get_direntries(res)

        files = [de for de in direntries if de[2] == FILE]

        jurl = self.server_url + urljoin('jpeg',
                                         quote(sdir.encode('utf-8')), '')
        url = self.server_url + urljoin(quote(sdir.encode('utf-8')), '')

        index = i = 0
        for (fn, orig_orientation, file_type) in files:
            fn = quote(fn.encode('utf-8'))
            if fn[-4:].lower() in (".jpg", "jpeg"):
                file_url = url + fn
            else:
                file_url = jurl + fn + '.jpg'

            orientation = orig_orientation
            if platform == 'android':
                orientation = {1: 8, 3: 6, 6: 6, 8: 8}[orig_orientation]

            image = CachedImage(source=file_url, orientation=orientation,
                                load=False, allow_scale=True)
            image.orig_orientation = orig_orientation
            image.bind(image_scale=self.on_image_scale)
            self.add_widget(image)

            if fn == self.filename:
                index = i
            i +=1

        self.index = index
Example #8
0
    def __init__(self):
        self.__vpos = 0.5
        self.__vspeed = -0.005
        self.__bounced = False
        self.__last_ball = None

        self.images = {
            t: CachedImage(f"res/img/man_{t.value}.png")
            for t in ImageType
        }

        self.__target_image = ImageType.LARGE
        self.__last_image_change = 0
        self.set_image(ImageType.LARGE)
Example #9
0
class Tartan(Sprite):

    def __init__(self):
        self.__x = 0
        self.meters = Const.offset_meters
        self.image = CachedImage("res/img/noice.png")
        self.border = self.image.get_width() * Const.pixel_size
        self.random_line = [-1, 1]

        self.score = score.load_score()

    def update(self, context: Context, sprites: Sprites):
        self.__x -= context.x_delta
        self.meters = context.meters
        while self.__x < -self.border:
            self.__x += self.border

        self.random_line[0] -= context.x_delta
        if self.random_line[0] < 0 and random.random() < 0.05:
            self.random_line[0] = 3 * Const.game_height
            self.random_line[1] = random.randint(1, 2)

    def render(self, surface: pygame.Surface, size_factor: float):
        area = Const.tartan_area(surface)
        surface.fill((156, 67, 47), area)

        size = int(self.image.get_width() * Const.pixel_size * size_factor)
        img = self.image.scale(size, size)

        for i in range(0, surface.get_width() // size + 2):
            surface.blit(img, (i * size + self.__x * size_factor, area.top))

        t = int((Const.tartan_top + Const.pixel_size) * size_factor)
        h = int(Const.tartan_height * 0.38 * size_factor)
        lines = [
            t,
            t + h,
            t + 2 * h
        ]

        for y in lines:
            for x in range(0, 3 * Const.game_height):
                surface.fill((255, 200, 200),
                             pygame.Rect(
                                 int((x + self.__x) * size_factor),
                                 y,
                                 int(size_factor * 1),
                                 int(size_factor * Const.pixel_size)
                             ))

        m = 50
        next_meter_in = m - (self.meters - Const.player_position) % m
        next_meter_str = str(int(((self.meters - Const.player_position) // m + 1) * m))
        surface.fill((255, 200, 200),
                     pygame.Rect(
                         int(next_meter_in * size_factor),
                         lines[0],
                         int(size_factor * Const.pixel_size),
                         h
                     ))
        font = pygame.font.Font("res/arcade.ttf", h)
        img = font.render(next_meter_str, True, (255, 200, 200))
        surface.blit(img, (int((next_meter_in - 2 * Const.pixel_size) * size_factor) - img.get_width(),
                           int(lines[0] + h / 2 - img.get_height() * 0.45)))

        surface.fill((255, 200, 200),
                     pygame.Rect(
                         int(self.random_line[0] * size_factor),
                         lines[self.random_line[1]],
                         int(size_factor * Const.pixel_size),
                         h
                     ))

        PADDING = Const.pixel_size * 2
        for i, (name, s) in reversed(list(enumerate(self.score))):
            left = s - (self.meters - Const.player_position)
            if -Const.game_height < left < Const.game_height * 3:
                text = f"{i + 1}   {name}".rstrip()
                img = font.render(text, True, (255, 255, 255))

                pixel = int(Const.pixel_size * size_factor)
                surface.fill((133, 94, 66),
                             pygame.Rect(
                                 int(left * size_factor) - pixel,
                                 int(Const.tartan_top * size_factor - h),
                                 int(size_factor * Const.pixel_size) + 2 * pixel,
                                 h
                             ))

                l = int((left - PADDING) * size_factor - img.get_width() // 2)
                surface.fill((106, 75, 53),
                             pygame.Rect(
                                 max(0, l - pixel),
                                 int(Const.tartan_top * size_factor - h * 1.5) - pixel,
                                 img.get_width() + PADDING * 2 * size_factor + min(0, l) + 2 * pixel,
                                 img.get_height() + 2 * pixel
                             ))

                surface.fill((133, 94, 66),
                             pygame.Rect(
                                 max(0, l),
                                 int(Const.tartan_top * size_factor - h * 1.5),
                                 img.get_width() + PADDING * 2 * size_factor + min(0, l),
                                 img.get_height()
                             ))

                surface.blit(img, (
                    int(left * size_factor - img.get_width() // 2),
                    int(Const.tartan_top * size_factor - h * 1.5)
                ))

    def box(self) -> GameRect:
        return GameRect(0, 0, 1, 1)

    def type(self) -> Type:
        return Type.TARTAN
Example #10
0
class Ball(Sprite, ABC):

    def __init__(self, x=None):
        if x is None:
            self.x = 2 * Const.game_height
        else:
            self.x = x

        self.image = CachedImage(self.filename())
        self.diameter = self.image.get_width() * Const.pixel_size

        self.y = Const.game_height - self.diameter
        self.__vspeed = 0
        self.bounced = False
        self.hit_bottom = False

        self.id = uuid.uuid4()

    def update(self, context: Context, sprites: Sprites):
        self.x -= context.x_delta
        if self.bounced:
            self.move_by_gravity(context)

    def render(self, surface: pygame.Surface, size_factor: float):
        rect = self.box.to_pygame(size_factor, False)
        if rect.width <= 0 or rect.height <= 0:
            return

        img = self.image.scale(rect.width, rect.height)
        surface.blit(img, (rect.left, rect.top))

    def bounce(self, velocity: float):
        self.bounced = True
        self.__vspeed = -velocity / 2

    def move_by_gravity(self, context: Context):

        # time in s
        t = context.time_factor / Const.fps
        # gravity in m/(s**2)
        a = context.gravity
        self.y = 1 / 2 * a * (t ** 2) + \
                 self.__vspeed * t + \
                 self.y
        self.__vspeed = a * t + self.__vspeed
        if self.y + self.diameter >= Const.game_height + self.diameter * 0.3 and not self.hit_bottom:
            self.__vspeed = -self.__vspeed * self.bounciness()
            self.hit_bottom = True
        elif self.y + self.diameter < Const.game_height + self.diameter * 0.3 and self.hit_bottom:
            self.hit_bottom = False

    @property
    def box(self) -> GameRect:
        offset = max(0, (self.y + self.diameter) - Const.game_height)
        y_delta = 0
        if offset > self.diameter * 0.3:
            y_delta = offset - self.diameter * 0.3
            offset = self.diameter * 0.3

        return GameRect(self.x, self.y - y_delta, self.diameter, self.diameter - offset)

    def type(self) -> Type:
        return Type.BALL

    def can_delete(self) -> bool:
        return self.x <= -1

    @abstractmethod
    def filename(self) -> str:
        pass

    @abstractmethod
    def bounciness(self) -> float:
        """
        :return: by how much the velocity of the player is multiplied when he hits the ball
        """
        pass

    @abstractmethod
    def immediate_speed_increase(self) -> float:
        pass

    @abstractmethod
    def desired_speed_increase(self) -> float:
        pass