Ejemplo n.º 1
0
def hit_detection(G=G):
    #platform hit detection
    plats = [Rect((x, y), (w, h)) for x, y, w, h, idx in G[LVL][PLATS]]
    off, box = hitbox_data[G[STATE]]
    hitbox = Rect((G[X]+off[0], G[Y]+off[1]), box)
    if G[X_VEL]:
        xflag = abs(G[X_VEL]) > 0
        while hitbox.move(G[X_VEL], 0).collidelist(plats) != -1:
            G[X_VEL] += 1 if G[X_VEL] < 0 else -1
        if xflag and not G[X_VEL]:
            if G[STATE] in ["DIVE", "DIVELANDJUMP"]:
                G[STATE] = "BONK"
                G[FRAME] = 0

    if G[Y_VEL]:
        yflag = G[Y_VEL] > 0
        while hitbox.move(0, G[Y_VEL]).collidelist(plats) != -1:
            G[Y_VEL] += 1 if G[Y_VEL] < 0 else -1
        if yflag and not G[Y_VEL]:
            # i dont love changing the state here but it seems fine
            if G[STATE] in ["FALLING", "AIR", "DIVELANDJUMP"]:
                G[STATE] = "LAND"
                G[FRAME] = 0
            if G[STATE] in ["DIVE", "BONK"]:
                G[STATE] = G[STATE] + "LAND"
                G[FRAME] = 0

    if G[X_VEL] and G[Y_VEL]:
        while hitbox.move(G[X_VEL], G[Y_VEL]).collidelist(plats) != -1:
            G[X_VEL] += 1 if G[X_VEL] < 0 else -1
            G[Y_VEL] += 1 if G[Y_VEL] < 0 else -1
Ejemplo n.º 2
0
class Baffle(pygame.sprite.Sprite):
    def __init__(self, screecSize):
        super().__init__()
        self.xlim = screecSize[0]
        self.ylim = screecSize[1]
        self.image = pygame.image.load(r'./Image/Baffle.png').convert_alpha()
        self.image = transform.scale(self.image, (100, 15))
        self.rect = Rect(self.xlim // 2 - 50, self.ylim - 15 - 5, 100, 15)
        self.speed = 200

    def update(self, dt):
        keys = pygame.key.get_pressed()
        dx = dt * self.speed
        if keys[pygame.K_RIGHT]:
            self.moveRight(dx)
        if keys[pygame.K_LEFT]:
            self.moveLeft(dx)

    def moveRight(self, dx):
        toRight = self.xlim - self.rect.right
        if toRight <= 0:
            return
        elif toRight < dx:
            self.rect = self.rect.move(toRight, 0)
        else:
            self.rect = self.rect.move(dx, 0)

    def moveLeft(self, dx):
        toLeft = self.rect.left
        if toLeft <= 0:
            return
        elif toLeft < dx:
            self.rect = self.rect.move(-toLeft, 0)
        else:
            self.rect = self.rect.move(-dx, 0)
Ejemplo n.º 3
0
class GameObject:
    def __init__(self, x, y, w, h, speed=(0, 0)):
        self._rect = Rect(x, y, w, h)
        self._speed = (round(speed[0] * c.speed_scale),
                       round(speed[1] * c.speed_scale))

    @property
    def rect(self):
        return self._rect

    @property
    def speed(self):
        return self._speed

    def draw(self, surface):
        pass

    def move(self, dx, dy):
        self._rect = self._rect.move(dx, dy)

    def update(self):
        """"""
        if self._speed == [0, 0]:
            return

        self.move(*self._speed)
Ejemplo n.º 4
0
class Asteroid(Sprite):
    def __init__(self, img_name, width, height, game):
        super().__init__()
        self.image = pygame.image.load(img_name).convert_alpha()
        self.rect = Rect(randrange(game.width - width), -100, width, height)
        self.y_speed = randrange(15, 25)
        self.game = game

    def update(self, *args):
        x_move = 0
        y_move = self.y_speed

        self.rect = self.rect.move(x_move, y_move)
        if self.rect.top > self.game.height:
            super().kill()

    def kill(self):
        self.game.elements['exploding_asteroids'].add(AnimatedAsteroid(join('gfx', 'asteroid_exploded.png'),
                                                                       self.rect,
                                                                       4,
                                                                       self.game))
        if self.game.newPU:
            self.game.elements['power-ups'].add(PowerUp(join('gfx', 'PowerUp.png'), self.rect, self.game))
            self.game.newPU = False
        super().kill()
Ejemplo n.º 5
0
    def draw_control(self):
        top_left_rect = Rect(
            0, 0,
            self.dimensions.width - self.padding, self.dimensions.height - self.padding
        )
        bottom_right_rect = Rect(
            self.padding, self.padding,
            self.dimensions.width - self.padding, self.dimensions.height - self.padding
        )

        label = self.font.render(self.text, 1, color(255, 255, 255, 255))
        font_rect = Rect(
            (self.dimensions.width / 2) - (label.get_width() / 2),
            (self.dimensions.height / 2) - (label.get_height() / 2),
            self.dimensions.width,
            self.dimensions.height
        )

        if self.mouse_entered and self.left_down:
            font_rect = font_rect.move(self.padding / 2, self.padding / 2)
            self.surface.fill(color(0, 0, 200, 255), rect=bottom_right_rect)
            self.surface.fill(color(0, 0, 75, 255), rect=top_left_rect)
            self.surface.fill(color(0, 0, 250, 255),
                              rect=Rect(self.padding, self.padding, self.dimensions.width - self.padding * 2,
                                        self.dimensions.height - self.padding * 2))
        else:
            self.surface.fill(color(0, 0, 75, 255), rect=bottom_right_rect)
            self.surface.fill(color(0, 0, 200, 255), rect=top_left_rect)
            self.surface.fill(color(0, 0, 250, 255), rect=Rect(self.padding, self.padding, self.dimensions.width - self.padding * 2, self.dimensions.height - self.padding * 2))

        self.surface.blit(label, font_rect)
Ejemplo n.º 6
0
class GameObject:
    def __init__(self, x, y, w, h, speed=[0, 0]):
        self.bounds = Rect(x, y, w, h)
        self.speed = speed.copy()
        self.old_pos = None
        self.old_speed = None

    @property
    def left(self):
        return self.bounds.left

    @property
    def right(self):
        return self.bounds.right

    @property
    def top(self):
        return self.bounds.top

    @property
    def bottom(self):
        return self.bounds.bottom

    @property
    def width(self):
        return self.bounds.width

    @property
    def height(self):
        return self.bounds.height

    @property
    def center(self):
        return self.bounds.center

    @property
    def centerx(self):
        return self.bounds.centerx

    @property
    def centery(self):
        return self.bounds.centery

    def draw(self, surface):
        pass

    def move(self, dx: object, dy: object) -> object:
        self.bounds = self.bounds.move(dx, dy)

    def update(self):
        """"""
        self.old_pos = self.bounds.copy()
        self.old_speed = self.speed.copy()

        if self.speed == [0, 0]:
            return

        self.move(*self.speed)
Ejemplo n.º 7
0
class LaserSprite(Sprite):
    def __init__(self, img_name, rect, game):
        self.image = pygame.image.load(img_name).convert_alpha()
        self.rect = Rect(rect.centerx, rect.y, 2, 9)
        super(LaserSprite, self).__init__()

    def update(self, *args):
        super(LaserSprite, self).update()
        self.rect = self.rect.move(0, -20)
Ejemplo n.º 8
0
 def animate(self):
     s = pygame.Surface(self.size)
     height = self.size[1]
     self.offset += 0.1
     for step in self.steps:
         src = Rect(step, 0, 2, height)
         dst = src.move(0, math.cos(self.offset + step * .02) * self.amount)
         s.blit(self.base, dst, src)
     return s
Ejemplo n.º 9
0
class LaserSprite(Sprite):
    def __init__(self, img_name, rect):
        self.image = pygame.image.load(img_name).convert_alpha()
        self.rect = Rect(rect.centerx, rect.y, 2, 9)
        super().__init__()

    def update(self):
        self.rect = self.rect.move(0, -10)
        if self.rect.bottom < 0:
            self.kill()
Ejemplo n.º 10
0
class GameObject:
    def __init__(self, x, y, w, h, speed=(0, 0)):
        self.bounds = Rect(x, y, w, h)
        self.speed = speed

    @property
    def left(self):
        return self.bounds.left

    @property
    def right(self):
        return self.bounds.right

    @property
    def top(self):
        return self.bounds.top

    @property
    def bottom(self):
        return self.bounds.bottom

    @property
    def width(self):
        return self.bounds.width

    @property
    def height(self):
        return self.bounds.height

    @property
    def center(self):
        return self.bounds.center

    @property
    def centerx(self):
        return self.bounds.centerx

    @property
    def centery(self):
        return self.bounds.centery

    def draw(self, surface):
        pass

    def move(self, dx, dy):
        # dx = ...
        # dy = ...
        self.bounds = self.bounds.move(dx, dy)

    def update(self):
        if self.speed == [0, 0]:
            return

        self.move(*self.speed)
Ejemplo n.º 11
0
class Camera(pygame.sprite.Group):
    """Camera class. Follow the player on the screen"""
    # Position of the camera is the top left corner
    def __init__(self, nmbrOfTilesOnScreen, tileSize, screenSize):
        """Basic camera information"""
        pygame.sprite.Group.__init__(self)
        self.tileSize = tileSize
        self.nmbrOfTilesOnScreen = nmbrOfTilesOnScreen
        self.screenRect = Rect(0, 0, screenSize.x, screenSize.y)
        self.tileRect = Rect(0, 0, nmbrOfTilesOnScreen.x, nmbrOfTilesOnScreen.y)
        self.levelSize = Vector(0, 0)

    def setPosition(self, x, y):
        """Set the position of the camera"""
        x = x - self.tileRect.x - self.tileRect.width / 2
        y = y - self.tileRect.y - self.tileRect.height / 2

        self.tileRect = self.tileRect.move(x, y)

    def setVisibleSprites(self, level):
        """Get the tiles that fall inside the screen and show them"""
        tiles = level.getTilesInRect(self.tileRect, self.tileRect)
        self.levelSize = Vector(level.width, level.height)
        self.empty()
        self.add(tiles)

    def MoveCameraToPlayerLocation(self, player):
        """Move the camera so that it is centered on the player but doesn't go past the side"""
        self.screenRect.x = max(player.x - self.screenRect.width / 2, 0)
        self.screenRect.x = min(max(0, (self.levelSize.x * self.tileSize.x - self.screenRect.width)), self.screenRect.x)
        self.screenRect.y = max(player.y - self.screenRect.height / 2, 0)
        self.screenRect.y = min(max(0, (self.levelSize.y * self.tileSize.y - self.screenRect.height)), self.screenRect.y)

    def draw(self, surface, player, npcList):
        """Draw the player, creatures and tiles with the camera movement"""
        self.MoveCameraToPlayerLocation(player.rect)
        sprites = self.sprites()
        surface_blit = surface.blit
        # Move every sprite so as to be well placed with the camera
        for spr in sprites:
            rect = Rect(spr.rect.x - self.screenRect.x, spr.rect.y - self.screenRect.y, 0, 0)
            self.spritedict[spr] = surface_blit(spr.image, rect)

        for npc in npcList:
            rect = Rect(npc.rect.x - self.screenRect.x, npc.rect.y - self.screenRect.y, 0, 0)
            surface_blit(npc.image, rect)

        rect = Rect(player.rect)
        rect.x -= self.screenRect.x
        rect.y -= self.screenRect.y
        player.net.draw(surface_blit, self.screenRect)
        surface_blit(player.image, rect)

        self.lostsprites = []
Ejemplo n.º 12
0
class GameObject:
    def __init__(self, x, y, w, h, speed=(0, 0)):
        self.bounds = Rect(x, y, w, h)
        self.speed = speed
        #@property - объект вычисляемого свойства только для чтения
        #по факту я определяю сам объект (его границы) и возможность перемещения
        @property
        def left(self):
            return self.bounds.left

        @property
        def right(self):
            return self.bounds.right

        @property
        def top(self):
            return self.bounds.top

        @property
        def bottom(self):
            return self.bounds.bottom

        @property
        def width(self):
            return self.bounds.width

        @property
        def height(self):
            return self.bounds.height

        @property
        def center(self):
            return self.bounds.center

        @property
        def centerx(self):
            return self.bounds.centerx

        @property
        def centery(self):
            return self.bounds.centery

        def draw(self, surface):
            pass

        def move(self, dx, dy):
            self.bounds = self.bounds.move(dx, dy)

        def update(self):
            if self.speed == [0, 0]:
                return

            self.move(*self.speed)
Ejemplo n.º 13
0
class GameObject:
    def __init__(self, x: int, y: int, width: int, height: int, speed=(0, 0)):
        self.bounds = Rect(x, y, width, height)
        self.speed = speed

    @property
    def left(self):
        return self.bounds.left

    @property
    def right(self):
        return self.bounds.right

    @property
    def width(self):
        return self.bounds.width

    @property
    def height(self):
        return self.bounds.height

    @property
    def top(self):
        return self.bounds.top

    @property
    def bottom(self):
        return self.bounds.bottom

    @property
    def center(self):
        return self.bounds.center

    @property
    def centerx(self):
        return self.bounds.centerx

    @property
    def centery(self):
        return self.bounds.centery

    def draw(self, surface) -> None:
        pass

    def move(self, dx, dy) -> None:
        self.bounds = self.bounds.move(dx, dy)

    def update(self) -> None:
        if self.speed == [0, 0]:
            return

        self.move(*self.speed)
Ejemplo n.º 14
0
class Ship(Sprite):
    def __init__(self, img_name, width, height, game):
        super().__init__()

        self.image = pygame.image.load(img_name).convert_alpha()
        self.rect = Rect(454, 516, width, height)
        self.exploded = False
        self.game = game
        self.cannon_cooldown = 15
        self.poweruptime = 0

    def update(self):
        if not self.exploded:
            if self.game.ship_collides:
                self.exploded = True
                return

            x_move = 0
            y_move = 0
            if self.game.input.up and not self.rect.top <= 0:
                y_move -= 20
            elif self.game.input.down and not self.rect.bottom >= self.game.height:
                y_move += 20
            if self.game.input.left and not self.rect.left <= 0:
                x_move -= 20
            if self.game.input.right and not self.rect.right >= self.game.width:
                x_move += 20
            if self.game.input.fire:
                if self.poweruptime > 0:
                    self.game.laser_sound.play()
                    self.game.elements['lasers'].add(LaserSprite(join('gfx', 'laser.png'), self.rect))
                    self.poweruptime -= 1
                if not self.game.ship_catches:
                    if not self.cannon_cooldown:
                        self.game.laser_sound.play()
                        self.game.elements['lasers'].add(
                            LaserSprite(join('gfx', 'laser.png'), self.rect))
                        self.cannon_cooldown = 6
                else:
                    self.game.ship_catches.pop()
                    self.poweruptime += 75
            self.rect = self.rect.move(x_move, y_move)
            self.cannon_cooldown = self.cannon_cooldown - 1 if self.cannon_cooldown else 0
        else:
            self.groups()[-1].add(AnimatedShip(join('gfx', 'ship_exploded.png'),
                                               self.rect,
                                               3,
                                               self.game))
Ejemplo n.º 15
0
class GameObject:
    def __init__(self, x, y, w, h, speed=(0, 0)):
        self.bounds = Rect(x, y, w, h)
        self.speed = speed

    @property
    def center(self):
        return self.bounds.center

    def move(self, dx, dy):
        self.bounds = self.bounds.move(dx, dy)

    def update(self):
        if self.speed == (0, 0):
            return
        self.move(*self.speed)
Ejemplo n.º 16
0
class GameObject:
    def __init__(self, x, y, w, h):
        self.bound = Rect(x, y, w, h)

    @property
    def left(self):
        return self.bound.left

    @property
    def right(self):
        return self.bound.right

    @property
    def top(self):
        return self.bound.top

    @property
    def bottom(self):
        return self.bound.bottom

    @property
    def width(self):
        return self.bound.width

    @property
    def height(self):
        return self.bound.height

    @property
    def center(self):
        return self.bound.center

    @property
    def centerx(self):
        return self.bound.centerx

    @property
    def centery(self):
        return self.bound.centery

    def move(self, dx, dy):
        self.bound = self.bound.move(dx, dy)

    def draw(self, surface):
        pass
Ejemplo n.º 17
0
class GameObject:
    def __init__(self, x, y, w, h, speed=(0, 0)):
        self.x = x
        self.y = y
        self.bounds = Rect(x, y, w, h)
        self.speed = speed

    def draw(self, surface):  #отрисовать
        pass

    def move(self, dx, dy):  #
        self.bounds = self.bounds.move(dx, dy)

    def update(self):  #обновить координаты
        if self.speed == [0, 0]:
            return

        self.move(*self.speed)
Ejemplo n.º 18
0
class PowerUp(Sprite):
    def __init__(self, img_name, rect, game):
        self.game = game
        self.image = pygame.image.load(img_name).convert_alpha()
        self.rect = Rect(rect.centerx, rect.y, 40, 40)
        self.x = choice([-5, 5])
        self.y = choice([-5, 5])
        super().__init__()

    def update(self):
        if self.rect.top <= 0:
            self.y = 5
        if self.rect.bottom >= self.game.height:
            self.y = -5
        if self.rect.left <= 0:
            self.x = 5
        if self.rect.right >= self.game.width:
            self.x = -5
        self.rect = self.rect.move(self.x, self.y)
Ejemplo n.º 19
0
class Feature:
    def __init__(self, x, y, w, h, image):
        self.init_x = x
        self.init_y = y
        self.i_x = 0
        self.i_y = 0
        self.p = 0
        self.init_bounds = Rect(x, y, w, h)
        self.bounds = Rect(x, y, w, h)
        self.image = image
        self.percents = 30
        self.percents2 = 30

    def draw(self, surface):
        surface.blit(self.image, self.bounds)

    def move(self, x, y, speed=None):
        # print("start x =", x)
        # print("start y =", y)
        new_x = x  #+ self.bounds.w * (100 - self.percents) / 100 / 2
        new_y = y  #+ self.bounds.h * (100 - self.percents) / 100 / 2
        # print("end x =", new_x)
        # print("end y =", new_y)
        self.bounds = self.bounds.move(
            new_x, new_y)  #двигает прямоуголник в новые координаты

    def scale(self, percents, image):

        self.image = image
        self.image = pygame.transform.scale(
            self.image, (int(self.init_bounds.w * 0.01 * percents),
                         int(self.init_bounds.h * 0.01 * percents)))

        self.percents = percents
        pygame.time.wait(10)

        self.bounds.x += self.bounds.w * (100 - self.percents) / 100 / 2
        self.bounds.y += self.bounds.h * (100 - self.percents) / 100 / 2

        self.bounds.x += self.bounds.w * (self.percents2 - percents) / 100 / 2
        self.bounds.y += self.bounds.h * (self.percents2 - percents) / 100 / 2
        self.percents2 = percents
Ejemplo n.º 20
0
class Asteroid(Sprite):
    def __init__(self, img_name, width, height, game):
        super(Asteroid, self).__init__()

        self.image = pygame.image.load(img_name).convert_alpha()
        self.rect = Rect(randrange(956 - width), -100, width, height)
        self.y_speed = randrange(10, 30)
        self.game = game

    def update(self, *args):
        x_move = 0
        y_move = self.y_speed

        self.rect = self.rect.move(x_move, y_move)

    def kill(self):
        self.game.elements['exploding_asteroids'].add(
            AnimatedAsteroid(join('gfx', 'asteroid_exploded.png'), self.rect,
                             4, self.game))
        super(Asteroid, self).kill()
Ejemplo n.º 21
0
class Ship(Sprite):
    def __init__(self, img_name, width, height, game):
        super(Ship, self).__init__()

        self.image = pygame.image.load(img_name).convert_alpha()
        self.rect = Rect(454, 516, width, height)
        self.exploded = False
        self.game = game
        self.cannon_cooldown = 10

    def update(self):
        if not self.exploded:
            if self.game.ship_collides:
                self.exploded = True
                return

            x_move = 0
            y_move = 0
            if self.game.input.up_pressed:
                y_move -= 20
            elif self.game.input.down_pressed:
                y_move += 20
            if self.game.input.left_pressed:
                x_move -= 20
            if self.game.input.right_pressed:
                x_move += 20
            if self.game.input.space_pressed:
                if not self.cannon_cooldown:
                    self.game.laser_sound.play()
                    self.game.elements['lasers'].add(
                        LaserSprite(join('gfx', 'laser.png'), self.rect,
                                    self.game))
                    self.cannon_cooldown = 6
            self.rect = self.rect.move(x_move, y_move)
            self.cannon_cooldown = self.cannon_cooldown - 1 if self.cannon_cooldown else 0
        else:
            self.groups()[-1].add(
                AnimatedShip(join('gfx', 'ship_exploded.png'), self.rect, 3,
                             self.game))
Ejemplo n.º 22
0
    def draw(self, screen):
        super().draw(screen)
        mark_rect = Rect(self.absolute_bounds.x, self.absolute_bounds.y, self.mark_size, self.mark_size)
        for unit in self.game.sprites:
            shape = unit.cls_dict.get('mark_shape', 'quad')

            pos = self.worldpos_to_minimap(unit.pos.x, unit.pos.y)
            mark_rect.centerx = self.absolute_bounds.x + pos[0]
            mark_rect.centery = self.absolute_bounds.y + pos[1]

            if shape == 'circle':
                pygame.draw.ellipse(screen, self.mark_color, mark_rect)
                pygame.draw.ellipse(screen, unit.team_color, mark_rect, 2)
            if shape == 'quad':
                pygame.draw.rect(screen, self.mark_color, mark_rect)
                pygame.draw.rect(screen, unit.team_color, mark_rect, 3)

        camera_rect = Rect(
            (self.game.world_size - self.game.camera.offset_x) * self.world_ratio_width,
            (self.game.world_size - self.game.camera.offset_y) * self.world_ratio_height,
            config['screen']['size'][0] * self.world_ratio_width,
            config['screen']['size'][1] * self.world_ratio_height
        )
        pygame.draw.rect(screen, Color('yellow'), camera_rect.move(self.absolute_bounds.x, self.absolute_bounds.y), 1)
Ejemplo n.º 23
0
Archivo: dmc.py Proyecto: runkov/dmc
class GameEntity:
    def __init__(self, x, y, speed=(0, 0), fps=DEFAULT_FPS):
        self.fps = fps
        self.speed = speed
        self.bounds = Rect(x, y, 50, 50)
        self.bounds.center = (x, y)
        self.direction = TO_THE_RIGHT
        self.image = load_image('monster01.png', -1)
        self.image_dx = (self.bounds.w - self.image.get_width()) // 2
        self.image_dy = (self.bounds.h // 2 - self.image.get_height())

    def draw(self, surface, camera):
        surface.blit(self.image, (self.bounds.x + self.image_dx - camera.x,
                                  self.bounds.y + self.image_dy - camera.y))

    def get_rect_image(self):
        return self.image.get_rect().move(
            (self.bounds.x + self.image_dx, self.bounds.y + self.image_dy))

    def update(self, target):
        # dx = 0
        # dy = 0
        line_speed = PLAYER_SPEED // 4 // self.fps
        if self.bounds.centerx - target.x > 0:
            dx = -line_speed
        else:
            dx = line_speed
        if self.bounds.centery - target.y > 0:
            dy = -line_speed
        else:
            dy = line_speed
        self.speed = (dx, dy)
        self.move(*self.speed)

    def move(self, dx, dy):
        self.bounds = self.bounds.move(int(dx), int(dy))
Ejemplo n.º 24
0
class Widget(Sprite):
    """Use Widget class for better movement tracking

       Widget class inherits from Sprite class.
       Test cases for class Widget

       >>> from widget import *
       >>> import pygame
       >>> s = pygame.surface.Surface((30,30))
       >>> w = Widget(s, (0,0,30,30), (0,0))
       >>> w.rect
       <rect(0, 0, 30, 30)>
       >>> w.update()
       >>> w.rect
       <rect(0, 0, 30, 30)>
       >>> w.getMovement()
       [0, 0]

       >>> w.setX(1)
       >>> w.getX()
       1

       >>> w.setY(4)
       >>> w.getY()
       4

       >>> w.setMovement((3,5))
       >>> w.getMovement()
       (3, 5)

       >>> w.getName()
       (0, 0)

       >>> w.setPosition((5,7))
       >>> w.getPosition()
       (5, 7)
    """
    def __init__(self, image, rect, name=''):
        """Instantiate a widget with a given surface,
           rectangle, and (x,y) movement pair.
        """
        Sprite.__init__(self)
        self.movement = [0, 0]
        self.rect = Rect(rect)
        self.lastRect = self.rect
        self.image = image
        self.name = name
        self.frames = []
        self.frameIndex = 0
        self.frameRate = 1
        self.timeDelay = WIDGETFRAMES
        self.lastUpdate = 0
        self.world = None
        self.undone = False
        self.id = self.rect.top + self.rect.left +\
                  self.rect.width + self.rect.height

    def attachToWorld(self, world):
        self.world = world
        self.id = self.world.curWidgetID
        self.world.curWidgetID += 1

    def startAnimation(self, frames, startIndex, frameRate):
        self.frames = frames
        self.frameIndex = startIndex
        self.frameRate = frameRate
        self.image = self.frames[startIndex]
        self.lastUpdate = self.timeDelay

    def __str__(self):
        return str(self.rect.left) + str(self.rect.top) + str(self.id)

    def setMovement(self, vector):
        """Set movement with a pair"""
        if (self.movement != [0, 0] and vector == [0, 0]):
            self.world.dirtyGroup.add(self)
        self.movement = vector

    def getMovement(self):
        """Return movement as a pair"""
        return self.movement

    def setStop(self):
        """Set movement to 0"""
        self.setMovement([0, 0])

    def setY(self, y):
        """Set y-component of movement"""
        self.movement[1] = y

    def setX(self, x):
        """Set x-component of movement"""
        self.movement[0] = x

    def getX(self):
        """Get x-component of movement"""
        return self.movement[0]

    def getY(self):
        """Set y-component of movement"""
        return self.movement[1]

    def setPosition(self, pair):
        """Set x and y coords of Widget"""
        self.rect.topleft = pair

    def getPosition(self):
        """Get x and y coords of Widget"""
        return self.rect.topleft

    def update(self):
        """Move sprite according to its movement vector"""
        # Widget needs to be animated
        if (len(self.frames) > 0):
            if self.lastUpdate <= 0:
                self.frameIndex = (self.frameIndex + 1) % (len(self.frames))
                self.image = self.frames[self.frameIndex]
                self.lastUpdate = self.timeDelay
                self.world.dirtyGroup.add(self)
            else:
                self.lastUpdate -= 1

        elif (self.getMovement != [0, 0]):
            self.lastRect = Rect(self.rect)
            self.rect.move_ip(self.movement)
            self.world.dirtyGroup.add(self)

    def undoUpdate(self):
        """Widget returns to state prior to last update()"""
        self.rect = self.lastRect

    def getShadow(self):
        shadow = Sprite()
        shadow.rect = self.lastRect.move(0, 0)
        return shadow

    def getName(self):
        """Get name of Widget"""
        return self.name
Ejemplo n.º 25
0
pygame.init()
screen = pygame.display.set_mode(size)
color = (255, 255, 255)
screen.fill(color)
pygame.display.update()

dino = pygame.image.load("images/d1.png")

dino_rect = Rect(50, 100, 0, 0)

pygame.display.update()
done = 0
dino_rect = Rect(50, 100, 0, 0)

clock = Clock()  # 设置时钟
while not done:
    clock.tick(10)
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            done = 1
            break
    if dino_rect.left >= size[0] - dino.get_width():
        print("撞墙了")
    else:
        dino_rect = dino_rect.move([10, 0])  # 每次往前移动10
        screen.fill(color)  # 一定要重新填充背景色,否则移动时会留下上次的影子
        screen.blit(dino, dino_rect)
        pygame.display.update()

pygame.quit()
Ejemplo n.º 26
0
class Graphic(Component):
    """A 2D image that can draw itself onto a Surface or another
    Graphic.

    It maintains a position relative to the associated Entity's
    on-screen position and will be drawn there accordingly.
    (For example, if the Entity's position is (30, 30) and this
    Graphic's position is (2, 3), it will be drawn to (32, 33)
    on-screen.)

    Several effects can also be applied to it, such as flipping the
    image and adding or reducing transparency.

    Attributes:
        _image (Surface): Contains the Graphic's actual pixel data.
        _rect (Rect): Contains the Graphic's x and y-offsets relative
            to its associated Entity, as well as its width and height.
    """
    def __init__(self, source, x=0, y=0):
        """Declare and initialize instance variables.

        Args:
            source (Surface): Contains the 2D image associated with this
                Graphic.
            x (int): The x-offset of the Graphic's top-left corner
                relative to its associated Entity.
                The default value is 0.
            y (int): The y-offset of the Graphic's top-left corner
                relative to its associated Entity.
                The default value is 0.
        """
        super(Graphic, self).__init__()
        self._image = convert_to_colorkey_alpha(source)
        self._rect = Rect(x, y, source.get_width(), source.get_height())

    def offset(self, dx=0, dy=0):
        """Move the Graphic away from its original position relative to
        the associated Entity by a set horizontal and/or vertical
        distance.

        It is safe to pass floats as arguments to this method; they will
        automatically be rounded to the nearest whole number.

        Args:
            dx (int): The horizontal distance to travel. A positive
                value will move the Graphic to the right, while a
                negative value will move it to the left.
                Defaults to 0.
            dy (int): The vertical distance to travel. A positive value
                will move the Graphic down, while a negative value will
                move it up.
                Defaults to 0.
        """
        self._rect.move_ip(int(round(dx)), int(round(dy)))

    def set_position(self, new_x=None, new_y=None):
        """Re-position the Graphic onto an exact location relative to
        its associated Entity.

        It is safe to pass floats as arguments to this method; they will
        automatically be rounded to the nearest whole number.

        Args:
            new_x (int): The x-coordinate of the top-left corner for the
                Graphic's new position.
                This parameter is optional; you can omit it from the
                function call if you want to retain the Graphic's
                x-position.
            new_y (int): The y-coordinate of the top-left corner for the
                Graphic's new position.
                This parameter is optional; you can omit it from the
                function call if you want to retain the Graphic's
                y-position.
        """
        if new_x is not None:
            self._rect.x = int(round(new_x))
        if new_y is not None:
            self._rect.y = int(round(new_y))

    def get_width(self):
        return self._rect.width

    def get_height(self):
        return self._rect.height

    def center(self, axis, container_rect):
        """Move the associated Entity so that this Graphic is centered
        horizontally and/or vertically within an area of the screen.

        Args:
            axis (Axis): A literal from the Axis enum for specifying
                whether the image should be centered on the horizontal
                or vertical plane.
                To center the image on both planes, you can combine both
                values using the | (bitwise or) operator.
            container_rect (Rect): A Rect containing the position and
                dimensions of the area that this Graphic will be
                centered relative to.
        """
        if (axis & Axis.horizontal) == Axis.horizontal:
            centered_x = (container_rect.width - self.get_width()) / 2
            centered_x += container_rect.x
            self.entity.set_position(new_x=centered_x - self._rect.x)

        if (axis & Axis.vertical) == Axis.vertical:
            centered_y = (container_rect.height - self.get_height()) / 2
            centered_y += container_rect.y
            self.entity.set_position(new_y=centered_y - self._rect.y)

    def is_contained(self, container_rect):
        """Return a Boolean indicating whether this Graphic is
        completely contained within an area of the screen.
        (i.e. No pixels exceed the area's boundaries.)

        Args:
            container_rect (Rect): Contains the position and dimensions
                of the area this Graphic will be compared to.
        """
        if container_rect.contains(self.draw_rect()):
            return True
        else:
            return False

    def is_outside(self, container_rect):
        """Return a Boolean indicating whether this Graphic is
        completely outside of an area of the screen.
        (i.e. All pixels exceed the area's boundaries.)

        Args:
            container_rect (Rect): Contains the position and dimensions
                of the area this Graphic will be compared to.
        """
        if not container_rect.colliderect(self.draw_rect()):
            return True
        else:
            return False

    def draw_rect(self):
        """Return a Rect containing the actual position the Graphic
        will be drawn to, with the Entity's position taken into account.
        """
        return self._rect.move(self.entity.x, self.entity.y)

    def flip(self, axis):
        """Flip the image horizontally and/or vertically.

        Args:
            axis (Axis): A literal from the Axis enum for specifying
                whether to apply a horizontal or vertical flip.
                To flip the image both ways, you can combine both values
                using the | (bitwise or) operator.
        """
        if (axis & Axis.horizontal) == Axis.horizontal:
            self._image = pygame.transform.flip(self._image, True, False)
        if (axis & Axis.vertical) == Axis.vertical:
            self._image = pygame.transform.flip(self._image, False, True)

    def magnify(self, zoom):
        """Enlarge or shrink the image using an equal scale for the
        width and height.

        Args:
            zoom (float): The amount used to multiply the image's
                dimensions. For example, passing a value of 2 when the
                image's dimensions are 24x24 will enlarge the image to
                48x48. Passing 0.5 will shrink it to 12x12.
        """
        magnified_image = pygame.transform.scale(
            self._image, (int(round(self.get_width() * zoom)),
                          int(round(self.get_height() * zoom))))
        self._image = magnified_image
        self._update_rect_dimensions()

    def resize(self, new_width, new_height):
        """Stretch and/or shrink the image to fit new dimensions.

        Args:
            new_width (int): The width that the image will shrink or
                stretch to fit.
            new_height (int): The height that the image will shrink or
                stretch to fit.
        """
        resized_image = pygame.transform.scale(
            self._image, (int(round(new_width)), int(round(new_height))))
        self._image = resized_image
        self._update_rect_dimensions()

    def _update_rect_dimensions(self):
        """Update the width and height of _rect with the current
        dimensions of _image.
        """
        self._rect.width = self._image.get_width()
        self._rect.height = self._image.get_height()

    def opacify(self, amount):
        """Increase or decrease the image's transparency.

        Note that Graphic images always start with an opacity of 255,
        which is fully opaque.

        Args:
            amount (int): How much to add to the image's opacity value.
                Positive values will make the image more opaque, while
                negative values will make it more transparent.
                To make the image fully opaque, pass 255 or more. To
                make the image fully transparent, pass -255 or less.
        """
        self._image.set_alpha(self._image.get_alpha() + amount)

    def is_opaque(self):
        """Return a Boolean indicating whether the image is fully
        opaque.
        """
        if self._image.get_alpha() >= 255:
            return True
        else:
            return False

    def is_transparent(self):
        """Return a Boolean indicating whether the image is fully
        transparent.
        """
        if self._image.get_alpha() <= 0:
            return True
        else:
            return False

    def blit(self, source, position, rect=None, special_flags=0):
        """Draw a Surface on top of this Graphic.

        Args:
            source (Surface): The image that will be drawn onto this
                Graphic.
            position (tuple of int, int): Contains the x and y-positions
                of the source image relative to this Graphic.
            area (Rect): An optional parameter specifying the region of
                the source image that will be used.
                Leave this parameter blank to draw the entire source
                image.
            special_flags (int): A combination of various PyGame flags
                for blitting effects. See the PyGame documentation on
                Surface.blit() for more information.
                This is an optional parameter; leave it blank to use no
                flags when blitting.

        Returns:
            A Rect containing the region of this Graphic that was drawn
            onto.
        """
        x = position[0]
        y = position[1]
        return self._image.blit(source, (x, y), rect, special_flags)

    def draw(self, destination):
        """Draw this Graphic's image onto a destination Surface.

        Args:
            destination (Surface): Will have this Graphic drawn on it.

        Returns:
            A Rect containing the region of the destination that was
            drawn onto.
        """
        return destination.blit(self._image, self.draw_rect())
Ejemplo n.º 27
0
class Unit(object):
    notable_attributes = {"Firepower", "Durability", "Velocity", "Rapidity"}
    walking_animations = 0
    attacking_animations = 0
    orientation_indices = (0, 0, 0, 0, 0, 0, 0, 0)
    cost = 0xA00
    pace = 50
    obstruance = grid.obstruance("unit")
    exclusion = grid.obstruance("notland")
    footprint = (10, 8)
    area_of_awareness = (50, 40)
    area_of_attack = (10, 8)
    is_flat = False
    aliment = None
    vital = False
    destination = None
    human = False

    def __init__(self, location):
        self.damage = 0
        self.rect = Rect(0, 0, *self.footprint)
        self.rect.center = Rect(location).center
        self.animation_frame = 1
        self.orient(6)
        self.image = self.obtain_frame()
        self.attacking = False
        self.walking = False
        self.finished = False
        self.temporal_accumulator = random.randint(0, 20)
        self.directions = Rect(0, 0, self.velocity, round(self.velocity * 0.8))
        self.directions.center = (0, 0)
        self.reload_time = 0
        self.flash = False
        self.killed_by = None

    def __getstate__(self):
        state = self.__dict__.copy()
        state["image"] = None
        return state

    def __setstate__(self, state):
        self.__dict__.update(state)
        self.image = self.obtain_frame()

    def step_position(self):
        """ where will it be on the next step? """
        if self.walking:
            vector = octoclock_direction(self.orientation, self.directions)
            next_position = self.rect.move(vector)
        else:
            next_position = self.rect
        return next_position

    def orient(self, orientation):
        self.orientation = orientation
        self.attend_to_surroundings()

    def navigate(self, next_position):
        if grid.rect_in_bounds(next_position):
            self.move(next_position)

    def move(self, location):
        self.rect = location
        self.attend_to_surroundings()

    def attend_to_surroundings(self):
        """ arrange the areas of awareness and attack
        depending on the orientation as a number on
        the octoclock.
           0
         7   1
        6     2
         5   3
           4
        """
        centre_of_attention = octoclock_direction(self.orientation, self.rect)
        self.rect_of_awareness = Rect(0, 0, *self.area_of_awareness)
        self.rect_of_awareness.center = centre_of_attention
        self.rect_of_attack = Rect(0, 0, *self.area_of_attack)
        self.attend_to_attack_area(centre_of_attention)

    def attend_to_attack_area(self, centre):
        """ Our modern military units have ranged attacks """
        place_opposite(self.rect_of_attack, self.orientation, centre)

    def obtain_frame(self):
        """ obtain that portion of the animated chromograph
        that shows the unit as standing, walking or attacking
        in its current orientation """
        frames_tall = max(self.orientation_indices) + 1
        frames_wide = self.walking_animations + self.attacking_animations + 1
        anim_row = self.orientation_indices[self.orientation]
        anim_col = self.animation_frame
        return chromographs.obtain_frame(self.animated_chromograph_name, anim_col, anim_row, frames_wide, frames_tall)

    def attack(self, audible=True):
        """ Assume a ferocius aspect """
        if self.attacking or not self.attacking_animations:
            return
        if self.reload_time > time():
            return
        self.temporal_accumulator = 0
        self.attacking = True
        self.reload_time = time() + 5.0 / self.rapidity
        self.animation_frame = self.walking_animations + 1
        self.image = self.obtain_frame()
        if audible:
            phonographs.play(self.attack_phonograph)
        return True

    def animate(self, ms):
        """ Create the illusion of movement """
        self.temporal_accumulator += ms
        if self.temporal_accumulator < self.pace:
            return False  # nothing to be done
        self.temporal_accumulator = 0
        frame = self.animation_frame
        if self.destroyed():
            frame = 0
        elif self.attacking:
            frame += 1
            if frame > self.walking_animations + self.attacking_animations:
                frame = 1
                self.attacking = False
        elif self.walking:
            frame += 1
            if frame > self.walking_animations:
                frame = 1
        self.animation_frame = frame
        self.image = self.obtain_frame()
        return True  # something was changed

    def harm(self, quanta_of_destruction, cause=None):
        """ Deal damage to the unit, possibly rendering it inactive """
        self.damage += quanta_of_destruction
        self.flash = True
        if self.damage >= self.durability:
            self.obstruance = 0
            self.animation_frame = 0
            self.walking = False
            self.attacking = False
            self.image = self.obtain_frame()
            self.killed_by = cause

    def destroyed(self):
        return self.damage >= self.durability

    def things_perceived(self, things):
        """ things that are perceived """
        indices = self.rect_of_awareness.collidelistall(things)
        return [things[i] for i in indices]

    def things_in_range(self, things):
        indices = self.rect_of_attack.collidelistall(things)

    def find_obstacles(self, location, knowledge):
        """ find things that obstruct a rectangle such that this
        unit may not occupy the same space if it were there.
        """
        indices = location.collidelistall(knowledge)
        return [
            knowledge[i] for i in indices if knowledge[i] is not self and (knowledge[i].obstruance & self.exclusion)
        ]

    def find_nearest(self, things):
        """ nearest thing sorted by distance from centre """

        def dist(thing):
            rx, ry = thing.rect.center
            mx, my = self.rect.center
            return (rx - mx) ** 2 + (ry - my) ** 2

        return sorted(things, key=dist)

    def orientation_towards(self, position):
        """ octaclock direction from self centre to position """
        cx, cy = self.rect.center
        px, py = position[:2]
        dx = px - cx
        dy = py - cy
        steep = (dx == 0) or abs(dy / dx) > 3
        shallow = (dy == 0) or abs(dx / dy) > 3
        if steep:
            return 0 if dy < 0 else 4
        if shallow:
            return 2 if dx > 0 else 6
        if dy < 0:
            return 1 if dx > 0 else 7
        return 3 if dx > 0 else 5
Ejemplo n.º 28
0
class Enemy(object):
	""" The enemy class.

	An instance of this class represents an enemy in the game.

	Attributes:
		_pos: The current position of the enemy.
		_direction: The current direction of the enemy. This could be LEFT or RIGHT.
		_collision_rect: The rectangle to check for collisions.
		_head_rect: The rectangle to check for deadly collisions.
		_walking_line: The rectangle to determine if the enemy is standing on the ground.
		_left_rect: The rectangle to determine if the enemy has reached the left end of a platform.
		_right_rect: The rectangle to determine if the enemy has reached the right end of a platform.
		_dy: The vertical speed of the enemy.
		_pic: The picture to display the enemy.
		_death_animation: The death animation of this enemy.
		_hit_sound: The sound when the character takes damage from this enemy.
		_death_sound: The sound when this enemy dies.
	"""

	# The horizontal speed.
	SPEED = 1
	# Value for the _direction attribute.
	LEFT, RIGHT = range(2)
	# Maximal falling speed.
	MAX_FALLING = 2
	# Vertical acceleration.
	V_FALLING = 0.1

	def __init__(self, pos=None, direction=LEFT, pic=None, death_animation=None):
		if pos is None:
			pos = [0, 0]
		if pic is None or death_animation is None:
			animation_manager = AnimationManager.MANAGER
			animation = animation_manager.get_animation("animations")
			if pic is None:
				pic = Animated(PictureManager.MANAGER, animation[0], animation[1]["Monster"])
			if death_animation is None:
				death_animation = (PictureManager.MANAGER, animation[0], animation[1]["MonsterExplode"])
		self._pos = pos
		self._direction = direction
		self._collision_rect = Rect(pos, (31, 31))
		self._head_rect = Rect((pos[0], pos[1] - 4), (31, 4))
		self._walking_line = Rect((pos[0], pos[1] + 31), (31, 1))
		self._left_rect = Rect((pos[0] - 1, pos[1] + 31), (1, 1))
		self._right_rect = Rect((pos[0] + 30, pos[1] + 31), (1, 1))
		self._dy = 0
		self._pic = pic
		self._death_animation = death_animation

		self._hit_sound = SoundManager.MANAGER.get_sound("hit.wav")
		self._death_sound = SoundManager.MANAGER.get_sound("hit2.wav")

	def draw(self, surface, tick, camera, size):
		""" Draws the enemy.

		This method draws the enemy on the given surface.

		Args:
			surface: The surface to draw on.
			tick: the current tick of the game.
			camera: The position of the camera.
			size: The size of the window. This argument is not used at the moment.
		"""
		self._pic.draw(surface, self._collision_rect.x - camera[0], self._collision_rect.y - camera[1], tick, False)

	def tick(self, platforms):
		""" Method for handling the game ticks.

		This method should be called every tick to calculate the enemy changes.

		Args:
			platforms: The platforms of the level.
		"""
		if self._direction == Enemy.LEFT:
			dx = -Enemy.SPEED
		else:
			dx = Enemy.SPEED
		if self._dy < Enemy.MAX_FALLING:
			self._dy += Enemy.V_FALLING
		colliding = None
		for platform in platforms:
			if platform.collides(self._walking_line):
				colliding = platform
				break
		if colliding is not None:
			self._dy = 0
			if not colliding.collides(self._left_rect):
				self._direction = Enemy.RIGHT
			elif not colliding.collides(self._right_rect):
				self._direction = Enemy.LEFT
		self._collision_rect = self._collision_rect.move(dx, self._dy)
		self._head_rect = self._head_rect.move(dx, self._dy)
		self._walking_line = self._walking_line.move(dx, self._dy)
		self._left_rect = self._left_rect.move(dx, self._dy)
		self._right_rect = self._right_rect.move(dx, self._dy)

	def collide(self, character):
		""" Checks for collision.

		This method checks for a collision with the character.
		If the character collides on the side he gets damage.
		If the character collides on the top the enemy dies and the character gets points.

		Args:
			character: The character to check with.

		Returns:
			The death animation if the enemy dies. None otherwise.
		"""
		if character.is_colliding(self._collision_rect):
			character.change_lives(-1)
			self._hit_sound.play()
		elif character.is_colliding(self._head_rect):
			character.change_points(10)
			character.jump()
			self._death_sound.play()
			return Animation(self._death_animation[0], self._death_animation[1], self._death_animation[2],
							 (self._collision_rect.x - 14, self._collision_rect.y - 14))
		return None
Ejemplo n.º 29
0
class GameObject:
    def __init__(self, x, y, w, h, speed=(0, 0)):
        #left, top, width, height
        self.bounds = Rect(x, y, w, h)
        self.speed = speed

    @property
    def left(self):
        return self.bounds.left

    @property
    def right(self):
        return self.bounds.right

    @property
    def top(self):
        return self.bounds.top

    @property
    def bottom(self):
        return self.bounds.bottom

    @property
    def width(self):
        return self.bounds.width

    @property
    def height(self):
        return self.bounds.height

    @property
    def center(self):
        return self.bounds.center

    @property
    def centerx(self):
        return self.bounds.centerx

    @property
    def centery(self):
        return self.bounds.centery

    def _left_egde(self):
        """
        충돌 검사를 위한 오브젝트의 왼쪽 면
        """
        return Rect(self.left, self.top, 1, self.height)

    def _right_egde(self):
        """
        충돌 검사를 위한 오브젝트의 오른쪽 면
        """
        return Rect(self.right, self.top, 1, self.height)

    def _top_egde(self):
        """
        충돌 검사를 위한 오브젝트의 위쪽 면
        """
        return Rect(self.left, self.top, self.width, 1)

    def _bottom_egde(self):
        """
        충돌 검사를 위한 오브젝트의 아랫쪽 면
        """
        return Rect(self.left, self.bottom, self.width, 1)

    @property
    def edges(self):
        return dict(left=self._left_egde(),
                    right=self._right_egde(),
                    top=self._top_egde(),
                    bottom=self._bottom_egde())

    def draw(self, surface):
        """
        자식 클래스에서 처리하도록 비워둠
        """
        pass

    def move(self, dx, dy):
        self.bounds = self.bounds.move(dx, dy)

    def update(self):
        if self.speed == [0, 0]:
            return

        #*연산자는 리스트를 튜플 형태로 전달
        #**연산자는 딕셔너리 형태로 전달
        self.move(*self.speed)
Ejemplo n.º 30
0
class Camera(pygame.sprite.Group):
    """Camera class. Follow the player on the screen"""

    # Position of the camera is the top left corner
    def __init__(self, nmbrOfTilesOnScreen, tileSize, screenSize):
        """Basic camera information"""
        pygame.sprite.Group.__init__(self)
        self.tileSize = tileSize
        self.nmbrOfTilesOnScreen = nmbrOfTilesOnScreen
        self.screenRect = Rect(0, 0, screenSize.x, screenSize.y)
        self.tileRect = Rect(0, 0, nmbrOfTilesOnScreen.x, nmbrOfTilesOnScreen.y)
        self.levelSize = Vector2(0, 0)
        self.fontRendererBig = pygame.font.Font(os.path.join("fonts", 'Millennium-Regular_0.ttf'), 18)
        self.fontRendererMedium = pygame.font.Font(os.path.join("fonts", 'Millennium-Regular_0.ttf'), 12)
        self.fontRendererSmall = pygame.font.Font(os.path.join("fonts", 'Millennium-Regular_0.ttf'), 8)


    def setPosition(self, x, y):
        """Set the position of the camera"""
        x = x - self.tileRect.x - self.tileRect.width / 2
        y = y - self.tileRect.y - self.tileRect.height / 2

        self.tileRect = self.tileRect.move(x, y)

    def setVisibleSprites(self, level):
        """Get the tiles that fall inside the screen and show them"""
        tiles = level.getTilesInRect(self.tileRect, self.tileRect)
        self.levelSize = Vector2(level.width, level.height)
        self.empty()
        self.add(tiles)

    def MoveCameraToPlayerLocation(self, player):
        """Move the camera so that it is centered on the player but doesn't go past the side"""
        self.screenRect.x = max(player.x - self.screenRect.width / 2, 0)
        self.screenRect.x = min(max(0, (self.levelSize.x * self.tileSize.x - self.screenRect.width)), self.screenRect.x)
        self.screenRect.y = max(player.y - self.screenRect.height / 2, 0)
        self.screenRect.y = min(max(0, (self.levelSize.y * self.tileSize.y - self.screenRect.height)),
                                self.screenRect.y)

    def drawScreen(self, surface, level: Map, player, npcList):
        """Draw the player, creatures and tiles with the camera movement"""
        if player is not None:
            self.MoveCameraToPlayerLocation(player.rect)

        if level is not None:
            self.setVisibleSprites(level)

        sprites = self.sprites()
        surface_blit = surface.blit
        rect = Rect(0, 0, 0, 0)
        # Move every sprite so as to be well placed with the camera
        self.drawMap(surface_blit, sprites)
        self.drawSprites(surface_blit, npcList, surface)

        if player is not None:
            rect = Rect(player.rect)
            rect.x -= self.screenRect.x
            rect.y -= self.screenRect.y
            player.drawAt(rect, surface, self.fontRendererMedium)
            # pointList = []
            # for i in range(len(player.path) - 1, 0, -1):
            #     pointList.append([player.path[i].rect.x + self.tileSize.x / 2, player.path[i].rect.y + self.tileSize.y / 2])
            # if len(pointList) > 1:
            #     pygame.draw.lines(surface, (100,100,100), False, pointList, 5)

        # Draw debug info to screen
        rect.x = 0
        rect.y = 13
        # surface_blit(self.fontRendererMedium.render("Nmbr Of tasks: " + str(len(npcList[0].taskList.listOfTasks)), False, (0, 0, 0)), rect)

        self.lostsprites = []

    def drawSprites(self, surface_blit, AI, screen):
        if AI is not None:
            for npc in AI:
                rect = Rect(npc.rect.x - self.screenRect.x, npc.rect.y - self.screenRect.y, 0, 0)
                surface_blit(npc.image, rect)
                surface_blit(self.fontRendererMedium.render("C:" + str(npc.converted), False, (0, 0, 0)), rect)
                # # rect.y += self.fontRendererMedium.size("P")[1]
                # # surface_blit(self.fontRendererMedium.render(str(npc.needs.thirst), False, (0, 0, 0)), rect)
                # rect.y += self.fontRendererSmall.size("P")[1]
                # surface_blit(self.fontRendererSmall.render("S:" + str(npc.needs.sleep), False, (0, 0, 0)), rect)
                # # rect.y += self.fontRendererMedium.size("P")[1]
                # # surface_blit(self.fontRendererMedium.render(str(npc.needs.boredom), False, (0, 0, 0)), rect)
                rect.y += self.fontRendererSmall.size("P")[1]
                surface_blit(self.fontRendererBig.render(str(npc.currentState), False, (0, 0, 0)), rect)
                pointList = []
                if npc.target is not None:
                    pointList.append(npc.target+self.tileSize/2)
                for i in range(len(npc.path)-1, 0, -1):
                    pointList.append([npc.path[i].rect.x+self.tileSize.x/2, npc.path[i].rect.y+self.tileSize.y/2])
                # if npc.roamNode is not None:
                #     pygame.draw.rect(screen, (0, 0, 0), Rect(npc.roamNode.pos.x+10,npc.roamNode.pos.y+10, 30, 30), 5)
                #     pointList.append(npc.roamNode.pos+self.tileSize/2)
                if len(pointList) > 1:
                    pygame.draw.lines(screen, (0,0,0), False, pointList, 5)
                # if npc.roamNode is not None:
                #     pygame.draw.rect(screen, (0, 0, 0), Rect(npc.roamNode.pos.x+10,npc.roamNode.pos.y+10, 30, 30), 5)

    def drawMap(self, surface_blit, tiles):
        for spr in tiles:
            rect = Rect(spr.rect.x - self.screenRect.x, spr.rect.y - self.screenRect.y, 0, 0)
            self.spritedict[spr] = surface_blit(spr.image, rect)
            surface_blit(self.fontRendererSmall.render(str(spr.f), False, (0, 0, 0)), rect)
            for action in spr.userActions:
                rect.move_ip(0, 10)
                surface_blit(self.fontRendererSmall.render(str(action), False, (0, 0, 0)), rect)


    def drawDebug(self, surface, debugInfo):
        rect = Rect(0, 0, 10, 10)
        for arg in debugInfo:
            rect.y += self.fontRendererMedium.size("P")[1]
            surface.blit(self.fontRendererMedium.render(str(arg), False, (0, 0, 0)), rect)
Ejemplo n.º 31
0
Archivo: dmc.py Proyecto: runkov/dmc
class Player:
    def __init__(self, x, y, speed=(0, 0), fps=DEFAULT_FPS):
        self.fps = fps
        self.bounds = Rect(x, y, 50, 50)
        self.bounds.center = (x, y)
        self.speed = speed  # (dx, dy)
        self._last_speed = speed
        self.direction = TO_THE_RIGHT
        self.image = load_image('hero01.jpeg', -1)
        self.frames = {
            TO_THE_RIGHT:
            load_frames('sprite-sheet-walking-girl.png', 6, 5),
            TO_THE_LEFT:
            load_frames('sprite-sheet-walking-girl.png', 6, 5, reverse=True)
        }
        self.animation_speed = 8
        self.animation_tick = 0
        self.animation_current_frame = 0
        self.image_dx = (self.bounds.w -
                         self.frames[TO_THE_LEFT][0].get_width()) // 2
        self.image_dy = (self.bounds.h // 2 -
                         self.frames[TO_THE_LEFT][0].get_height())

    @property
    def x(self):
        return self.bounds.centerx

    @property
    def y(self):
        return self.bounds.centery

    @property
    def is_run(self):
        if self.speed == (0, 0):
            return False
        else:
            return True

    def set_fps(self, new_fps):
        self.fps = new_fps

    def handle_events(self, keys):
        dx = 0
        dy = 0
        if keys[pygame.K_a]:
            dx = -PLAYER_SPEED / self.fps
        if keys[pygame.K_d]:
            dx = PLAYER_SPEED / self.fps
        if keys[pygame.K_w]:
            dy = -PLAYER_SPEED / self.fps
        if keys[pygame.K_s]:
            dy = PLAYER_SPEED / self.fps
        self._last_speed = self.speed
        self.speed = (dx, dy)
        if self.speed[0] > 0:
            self.direction = TO_THE_RIGHT
        elif self.speed[0] < 0:
            self.direction = TO_THE_LEFT

    def move(self, dx, dy):
        self.bounds = self.bounds.move(int(dx), int(dy))

    def update(self):
        if self.speed != (0, 0):
            self.move(*self.speed)
        #  определяем спрайт для анимации персонажа
        if self.animation_tick == 0:
            self.animation_current_frame = (self.animation_current_frame +
                                            1) % 5
            if self.is_run:
                self.image = self.frames[self.direction][
                    self.animation_current_frame]
            else:
                self.image = self.frames[self.direction][12]
        self.animation_tick = (self.animation_tick +
                               1) % (60 // self.animation_speed)

    def draw(self, surface, camera):
        surface.blit(self.image, (self.bounds.x + self.image_dx - camera.x,
                                  self.bounds.y + self.image_dy - camera.y))
Ejemplo n.º 32
0
class Widget(Sprite):
    """Use Widget class for better movement tracking

       Widget class inherits from Sprite class.
       Test cases for class Widget

       >>> from widget import *
       >>> import pygame
       >>> s = pygame.surface.Surface((30,30))
       >>> w = Widget(s, (0,0,30,30), (0,0))
       >>> w.rect
       <rect(0, 0, 30, 30)>
       >>> w.update()
       >>> w.rect
       <rect(0, 0, 30, 30)>
       >>> w.getMovement()
       [0, 0]

       >>> w.setX(1)
       >>> w.getX()
       1

       >>> w.setY(4)
       >>> w.getY()
       4

       >>> w.setMovement((3,5))
       >>> w.getMovement()
       (3, 5)

       >>> w.getName()
       (0, 0)

       >>> w.setPosition((5,7))
       >>> w.getPosition()
       (5, 7)
    """

    def __init__(self, image, rect, name=''):
        """Instantiate a widget with a given surface,
           rectangle, and (x,y) movement pair.
        """
        Sprite.__init__(self)
        self.movement = [0, 0]
        self.rect = Rect(rect)
        self.lastRect = self.rect
        self.image = image
        self.name = name
        self.frames = []
        self.frameIndex = 0
        self.frameRate = 1
        self.timeDelay = WIDGETFRAMES
        self.lastUpdate = 0
        self.world = None
        self.undone = False
        self.id = self.rect.top + self.rect.left +\
                  self.rect.width + self.rect.height

    def attachToWorld(self, world):
        self.world = world
        self.id = self.world.curWidgetID
        self.world.curWidgetID += 1

    def startAnimation(self, frames, startIndex, frameRate):
        self.frames = frames
        self.frameIndex = startIndex
        self.frameRate = frameRate
        self.image = self.frames[startIndex]
        self.lastUpdate = self.timeDelay

    def __str__(self):
        return str(self.rect.left) + str(self.rect.top) + str(self.id)

    def setMovement(self, vector):
        """Set movement with a pair"""
        if(self.movement != [0,0]
           and vector == [0,0]):
            self.world.dirtyGroup.add(self)
        self.movement = vector

    def getMovement(self):
        """Return movement as a pair"""
        return self.movement

    def setStop(self):
        """Set movement to 0"""
        self.setMovement([0,0])

    def setY(self, y):
        """Set y-component of movement"""
        self.movement[1] = y

    def setX(self, x):
        """Set x-component of movement"""
        self.movement[0] = x

    def getX(self):
        """Get x-component of movement"""
        return self.movement[0]
    def getY(self):
        """Set y-component of movement"""
        return self.movement[1]

    def setPosition(self, pair):
        """Set x and y coords of Widget"""
        self.rect.topleft = pair

    def getPosition(self):
        """Get x and y coords of Widget"""
        return self.rect.topleft

    def update(self):
        """Move sprite according to its movement vector"""
        # Widget needs to be animated
        if (len(self.frames) > 0):
            if self.lastUpdate <= 0:
                self.frameIndex = (self.frameIndex+1)%(len(self.frames))
                self.image = self.frames[self.frameIndex]
                self.lastUpdate = self.timeDelay
                self.world.dirtyGroup.add(self)
            else:
                self.lastUpdate -= 1

        elif(self.getMovement != [0,0]):
            self.lastRect = Rect(self.rect)
            self.rect.move_ip(self.movement)
            self.world.dirtyGroup.add(self)

    def undoUpdate(self):
        """Widget returns to state prior to last update()"""
        self.rect = self.lastRect

    def getShadow(self):
        shadow = Sprite()
        shadow.rect = self.lastRect.move(0,0)
        return shadow

    def getName(self):
        """Get name of Widget"""
        return self.name
Ejemplo n.º 33
0
class Camera:
    """
    Class for keeping track of the camera position. In early stage of development
    """
    def __init__(self, screen_res, level_rect, x_speed=15, y_speed=15,
                 left_threshold=10, right_threshold=75, up_threshold=10,
                 down_threshold=75):
        """

        :param screen_res: A tuple of int. (w, h)
        :param level_rect: A rectangle that covers all of the level
        :param x_speed: The horizontal speed of the camera
        :param y_speed: The vertical speed of the camera
        :param left_threshold:
            The percentage of screen to reach in order for the camera to scroll
            left
        :param right_threshold:
            The percentage of screen to reach in order for the camera to scroll
            right
        :param up_threshold:
            The percentage of screen to reach in order for the camera to scroll
            up
        :param down_threshold:
            The percentage of screen to reach in order for the camera to scroll
            down
        """
        self.level_rect = level_rect
        self.horizontal_speed = x_speed
        self.vertical_speed = y_speed
        self.screen_res = screen_res
        self.rect = Rect((0, 0), screen_res)

        self.x_bound = self.level_rect.width - self.rect.width
        self.y_bound = self.level_rect.height - self.rect.height

        self.right_threshold = self.rect.width * right_threshold / 100
        self.left_threshold = self.rect.width * left_threshold / 100
        self.up_threshold = self.rect.height * up_threshold / 100
        self.down_threshold = self.rect.height * down_threshold / 100

    def pan_left(self, h_speed):
        if self.rect.x == 0:
            return
        if self.rect.move(-h_speed, 0).x < 0:
            self.rect.move_ip(-self.rect.x, 0)
        else:
            self.rect.move_ip(-h_speed, 0)

    def pan_right(self, h_speed):
        if self.rect.x == self.x_bound:
            return
        if self.rect.x + h_speed + self.rect.width > self.level_rect.width:
            self.rect.move_ip((self.level_rect.width - (self.rect.x + self.rect.width)), 0)
        else:
            self.rect.move_ip(h_speed, 0)

    def pan_down(self, v_speed):
        if self.rect.y == self.y_bound:
            return
        if self.rect.y + v_speed + self.rect.height > self.level_rect.height:
            self.rect.move_ip(0, (self.level_rect.height - self.rect.y - self.rect.height))
        else:
            self.rect.move_ip(0, v_speed)

    def pan_up(self, v_speed):
        if self.rect.y == 0:
            return
        if self.rect.move(0, -v_speed).y < 0:
            self.rect.move_ip(0, -self.rect.y)
        else:
            self.rect.move_ip(0, -v_speed)

    def snap_to(self, player_rect):
        propose = self.rect.move(0, 0)
        propose.x = min(max(0, player_rect.x - self.screen_res[0] / 2), self.x_bound)
        propose.y = min(max(0, player_rect.y - self.screen_res[1] / 2), self.y_bound)
        self.rect = propose

    def update(self, player_rect, custom_speed=None):
        h_speed, v_speed = self.horizontal_speed, self.vertical_speed
        if custom_speed:
            h_speed, v_speed = custom_speed
        if player_rect.x - self.rect.x > self.right_threshold:
            self.pan_right(h_speed)
        elif player_rect.x - self.rect.x < self.left_threshold:
            self.pan_left(h_speed)
        if player_rect.y - self.rect.y > self.down_threshold:
            self.pan_down(v_speed)
        elif player_rect.y - self.rect.y < self.up_threshold:
            self.pan_up(v_speed)
Ejemplo n.º 34
0
class Ball(pygame.sprite.Sprite):
    def __init__(self, screenSize, loc, speed=200):
        super().__init__()
        self.image = pygame.image.load(r'./Image/ball.png').convert_alpha()
        self.image = transform.scale(self.image, (20, 20))
        self.rect = Rect(loc[0], loc[1], self.image.get_width(),
                         self.image.get_height())
        vx = random.randint(10, 100)
        vy = random.randint(10, 100)
        # 方向向量
        self.direction = Vector((vx, vy)).normalize()
        self.xlim = screenSize[0]
        self.ylim = screenSize[1]
        self.speed = speed

    def update(self, dt):
        if self.rect.bottom >= self.ylim:
            return False
        if self.rect.top <= 0:
            # 防止球已经超过边界,造成反复reverse的情况
            beyond = -self.rect.top
            if beyond > 0:
                self.move('down', beyond)
            self.reverseY()
        if self.rect.left <= 0:
            beyond = -self.rect.left
            if beyond > 0:
                self.move('right', beyond)
            self.reverseX()
        if self.rect.right >= self.xlim:
            beyond = self.rect.right - self.xlim
            if beyond > 0:
                self.move('left', beyond)
            self.reverseX()
        shift = self.direction * self.speed * dt
        self.rect = self.rect.move(shift.x, shift.y)
        return True

    def reverseX(self):
        self.direction.x = -self.direction.x

    def move(self, direction='up', by=0):
        """往某方向移动多少距离"""
        if direction == 'up':
            self.rect = self.rect.move(0, -by)
        elif direction == 'down':
            self.rect = self.rect.move(0, by)
        elif direction == 'left':
            self.rect = self.rect.move(-by, 0)
        elif direction == 'right':
            self.rect = self.rect.move(by, 0)

    def reverseY(self):
        self.direction.y = -self.direction.y

    def baffleCollisionDetect(self, baffle):
        point = pygame.sprite.collide_mask(self, baffle)
        if point:
            beyond = self.rect.bottom - baffle.rect.top
            if beyond > 0:
                self.move('up', beyond)
            self.reverseY()
            # print(point)

    def obstacleCollisionDetect(self, group):
        res = pygame.sprite.spritecollide(self, group, True)
        if res != []:
            print('Collision with', res)
            self.reverseY()
Ejemplo n.º 35
0
def advance_frame(input_get=pygame.event.get):
    global PLATFORMS, HATS, SPIKES, SPRINGS, ENEMIES, _ENEMIES, FLAGS, CHEESE, BACK, SPAWN
    global  X, Y, x_vel, y_vel, DOOR, HAT, STATE, CROUCH, mov, hub, DIR
    global counter, dframe, IGT, endcard
    plats = []
    allplats = []
    for pos, dim, idx in PLATFORMS:
        allplats.append(Rect(pos, (dim[0]*32, dim[1]*32)))
        if isnear(pos, dim): plats.append(Rect(pos, (dim[0]*32, dim[1]*32)))
    # update counters/clock
    counter += 1
    dframe = (dframe + 1) % 12
    IGT += CLOCK.tick(30)
    # draw update screen
    adjust_scroller()
    SCREEN.blit(get_screen(), (0, 0))
    SCREEN.blit(get_HUD(), (0, 0))
    pygame.display.update()

    # evaluate input
    jmp = 0
    door = 0
    for e in input_get():
        if e.type == QUIT or e.type == KEYDOWN and e.key == K_ESCAPE: quit()
        if e.type == KEYDOWN:
            if e.key == K_LEFT: mov = max(mov - 1, -1)
            if e.key == K_RIGHT: mov = min(mov + 1, 1)
            if e.key == K_DOWN: CROUCH = min(CROUCH+1, 1)
            if e.key == K_SPACE: jmp += 1
            if e.key == K_UP: door = True
        if e.type == KEYUP:
            if e.key == K_LEFT: mov = min(mov+1, 1)
            if e.key == K_RIGHT: mov = max(mov-1, -1)
            if e.key == K_DOWN: CROUCH = max(CROUCH-1, 0)

    # change state, update movement
    JUMP = _JUMP * 2 if HAT == "baseball" else _JUMP
    if STATE == "dmg":
        if counter == 1:
            sounds["death"].stop()
            sounds["death"].play()

        if counter < 10: return
        STATE = "stand"
        X, Y = SPAWN
        x_vel, y_vel = 0, 0
        HAT = None
        ENEMIES = deepcopy(_ENEMIES)
    elif jmp and (STATE in ["stand", "run0", "run1", "slide", "wall"] or HAT == "propeller"):
        sounds["jump"].stop()
        sounds["jump"].play()
        if HAT == "propeller": y_vel = JUMP
        if STATE == "wall":
            y_vel = JUMP
            DIR *= -1
            x_vel = max(SPEED * DIR, x_vel) if DIR > 0 else min(SPEED * DIR, x_vel)
        else:
            STATE = "squat"
            counter = 0
    elif STATE == "squat":
        if counter >= 3: y_vel = JUMP
    elif CROUCH: STATE = "crouch"
    elif mov and STATE not in ['crouch']:
        if DIR == mov: x_vel = max(SPEED * DIR, x_vel) if DIR > 0 else min(SPEED * DIR, x_vel)
        elif not x_vel or abs(x_vel) <= 3: DIR = mov
        if (x_vel > 0 and mov < 0) or (x_vel < 0 and mov > 0): STATE == "slide" 
    elif x_vel == 0: STATE = "stand"
    else: STATE = "slide"
        
    if mov and not STATE in ["run0", "run1", "crouch", "squat"]:
        if ((x_vel > 0 and mov < 0) or (x_vel < 0 and mov > 0)): STATE = "slide"
        else:
            STATE = "run0"
            counter = 0

    if STATE.startswith("run") and counter >= 5:
        STATE = "run" + str((int(STATE[-1]) + 1) % 2)
        counter = 0

    if y_vel < 0: STATE = "jump0"
    if y_vel > 0: STATE = "jump1"

    # friction and gravity
    if x_vel and not STATE.startswith("jump"): x_vel += friction if x_vel < 0 else -1
    y_vel += grav

    if STATE in ["jump1", "run0", "run1", "stand", "slide"] and HAT == "sombraro" and not CROUCH: y_vel = 0

    # animate relevent actors
    for spring in SPRINGS:
        if spring[3]: spring[3] -= 1

    # enemy logic
    remove = []
    for i in range(len(ENEMIES)):
        pos, name, d, f , c = ENEMIES[i]
        if not isnear(pos): continue
        c += 1
        if name == "bone":
            if c % 2:
                f = (f + 1) % 2
                pos = (pos[0] + BONESPEED, pos[1]) if d == 0 else (pos[0] - BONESPEED, pos[1])
            if c > 50: remove.append(i)
            
        if name == "skeleton":
            if abs(pos[0] - X) < 410:
                if f == 0: d = 0 if X > pos[0] else 1
                if c >= 8 and f == 0: f = 1
                elif c >= 30 and f == 1:
                    sounds["throw"].stop()
                    sounds["throw"].play()
 
                    f = 2
                    ENEMIES.append( [pos, 'bone', d, 0, 0] )
                elif c > 40: f, c = 0, 0
            else: f, c = 0, 0

        if name == "zombie":
            if c % 4 == 0 and abs(pos[0] - X) < 512:
                hitbox = Rect((pos[0]+8, pos[1]), (32, 64))
                if d == 0: footbox = Rect((pos[0] + 32 + ZOMBIESPEED, pos[1] + 64), (10, 10)) 
                else: footbox = Rect((pos[0] - ZOMBIESPEED, pos[1]+64), (10, 10))
                
                if hitbox.collidelist(allplats) == -1:
                    d = 0 if X > pos[0] else 1
                f = (f + 1) % 2
                pos = (pos[0] + ZOMBIESPEED, pos[1]) if d == 0 else (pos[0] - ZOMBIESPEED, pos[1])
                if hitbox.collidelist(allplats) != -1 or footbox.collidelist(allplats) == -1:
                    pos = (pos[0] - ZOMBIESPEED*2, pos[1]) if d == 0 else (pos[0] + ZOMBIESPEED*2, pos[1])

        if name == "snake":
            hitbox = Rect(pos, (64, 16))
            if c % 4 == 0:
                f = (f + 1) % 2
                pos = (pos[0] + SNAKESPEED, pos[1]) if d == 0 else (pos[0] - SNAKESPEED, pos[1])
                if hitbox.collidelist(allplats) != -1:
                    d = (d + 1) % 2
                    pos = (pos[0] + SNAKESPEED*2, pos[1]) if d == 0 else (pos[0] - SNAKESPEED*2, pos[1])

        if name == "ghost":
            d = 0 if X > pos[0] else 1
            if (d == 1 and DIR == 1) or (d == 0 and DIR == -1): f = 1
            else: f = 0
            if abs(pos[0] - X) + abs(pos[1] - Y) < 800 and f == 0:
                if abs(pos[0] - X) > 30:
                    x = -1 if X < pos[0] else 1
                else: x = 0
                if abs(pos[1] - Y) > 30:
                    y = -1 if Y < pos[1] else 1
                else: y = 0
                pos = (pos[0]+x, pos[1]+y)
                
                    
        ENEMIES[i] = [pos, name, d, f, c]

    for i in remove[::-1]: ENEMIES.pop(i) 
    
    # hit detection - platforms
    hitbox = Rect((X, Y), (32, 64)) if STATE != "crouch" else Rect((X, Y+32), (32, 32))
    checklist = plats
    if hitbox.collidelist(checklist) != -1:
        STATE = "dmg"
        return
    if x_vel:
        while hitbox.move(x_vel, 0).collidelist(checklist) != -1:
            if STATE.startswith("jump"): STATE = "wall"
            x_vel += 1 if x_vel < 0 else -1
    if y_vel:
        while hitbox.move(0, y_vel).collidelist(checklist) != -1: y_vel += 1 if y_vel < 0 else -1
    if x_vel and y_vel:
        while hitbox.move(x_vel, y_vel).collidelist(checklist) != -1:
            y_vel += 1 if y_vel < 0 else -1
            x_vel += 1 if x_vel < 0 else -1
    #                 hats
    checklist = [Rect(pos, (46, 46)) for pos, hat in HATS]
    i = hitbox.collidelist(checklist)
    if i != -1: HAT = HATS[i][1]
    #                 flags
    checklist = [Rect(pos, (46, 64)) for pos in FLAGS]
    i = hitbox.collidelist(checklist)
    if i != -1: SPAWN = FLAGS[i]
    #                 spikes and enemies
    checklist = []
    for pos, d in SPIKES:
        if not isnear(pos): continue
        if d == 0: checklist += [Rect((pos[0]+8, pos[1]), (16, 16)), Rect((pos[0], pos[1]+16), (32, 16))]
        elif d == 1: checklist += [Rect((pos[0], pos[1]+8), (16, 16)), Rect((pos[0]+16, pos[1]), (16, 32))]
        elif d == 2: checklist += [Rect((pos[0], pos[1]), (32, 16)), Rect((pos[0]+8, pos[1]+16), (16, 16))]
        elif d == 3: checklist += [Rect((pos[0], pos[1]), (16, 32)), Rect((pos[0]+16, pos[1]+8), (32, 16))]

    for pos, name, d, f, c in ENEMIES:
        if not isnear(pos): continue
        if name in ["bone", "ghost"]: checklist.append(Rect(pos, (32, 32)))
        elif name == "snake": checklist.append(Rect(pos, (64, 16)))
        else: checklist.append(Rect(pos, (32, 64)))
    i = hitbox.collidelist(checklist)
    if i != -1:
        STATE = "dmg"
        counter = 0
    #                 springs
    checklist = [Rect(pos, (48, 48)) for pos, d, s, f in SPRINGS]
    i = hitbox.collidelist(checklist)
    if i != -1:
        if SPRINGS[i][3] != 10:
            sounds["spring"].stop()
            sounds["spring"].play()

        SPRINGS[i][3] = 10
        if SPRINGS[i][1] == 0: y_vel = 0 - SPRINGS[i][2]
        elif SPRINGS[i][1] == 2: y_vel = SPRINGS[i][2]
        elif SPRINGS[i][1] == 3:
            DIR = 1
            x_vel = SPRINGS[i][2]
        elif SPRINGS[i][1] == 1:
            DIR = -1
            x_vel = -1 * SPRINGS[i][2]
    #                 cheese
    checklist = []
    for pos, idx in CHEESE:
        if idx == 3: checklist.append(Rect(pos, (64, 64)))
        else: checklist.append(Rect(pos, (32, 32)))
    i = hitbox.collidelist(checklist)
    if i != -1:
        sounds["get"].stop()
        sounds["get"].play()

        if not CHEESE[i][1] == 3: INV.append(CHEESE.pop(i))
        else:
            n = H
            end = True
            while end:
                CLOCK.tick(30)
                if n >= 0: n -= 10
                SCREEN.blit(get_screen(), (0, 0))
                SCREEN.blit(endcard, (0, n))
                pygame.draw.rect(SCREEN, (200, 200, 200), Rect((380, n + 530), (256, 104)))
                SCREEN.blit(HEL64.render(str(IGT // 60000) +":"+ ("0" + str(IGT // 1000 % 60))[-2:], 0, (0, 0, 0)), (400, n + 550))
                pygame.display.update()
                for e in pygame.event.get():
                    if e.type == QUIT or e.type == KEYDOWN and e.key == K_ESCAPE: quit()
                    if e.type == KEYDOWN:
                        if e.key == K_LEFT: mov += -1
                        if e.key == K_RIGHT: mov += 1
                        if e.key == K_DOWN: CROUCH += 1
                        if e.key == K_SPACE and n <= 0:
                            end = False
                            load_level(hublvl)
                            hub=True
                    if e.type == KEYUP:
                        if e.key == K_LEFT: mov -= -1
                        if e.key == K_RIGHT: mov -= 1
                        if e.key == K_DOWN: CROUCH -= 1
    #                 door
    if hub:
        doorlist = [Rect((256+(i*256), 64), (64, 64)) for i in range(len(LEVELS))]
        di = hitbox.collidelist(doorlist)
    # enter door
    if door and (hitbox.colliderect(Rect(DOOR, (64, 64))) or (hub and di != -1 and len(INV)>=needs[di] )):
        sounds["door"].stop()
        sounds["door"].play()

        n = 2
        if not hub: X, Y = DOOR[0] + 16, DOOR[1]
        adjust_scroller()
        STATE = "jump1"
        while n < 980:
            surf = rotate(get_screen(), n)
            SCREEN.blit(surf, ((W-surf.get_width())//2, (H - surf.get_height())//2))
            n += n // 2
            CLOCK.tick(30)
            pygame.display.update()
            for e in pygame.event.get():
                if e.type == QUIT or e.type == KEYDOWN and e.key == K_ESCAPE: quit()
                if e.type == KEYDOWN:
                    if e.key == K_LEFT: mov += -1
                    if e.key == K_RIGHT: mov += 1
                    if e.key == K_DOWN: CROUCH += 1
                if e.type == KEYUP:
                    if e.key == K_LEFT: mov -= -1
                    if e.key == K_RIGHT: mov -= 1
                    if e.key == K_DOWN: CROUCH -= 1
    
        if hub and di != -1:
            load_level(LEVELS[di])
            hub = False
        else:
            load_level(hublvl)
            hub = True
    # apply final calculated movement
    X += x_vel
    Y += y_vel
Ejemplo n.º 36
0
class GameObject:
    """
    GameObject class based on pygame.Rect.

    This is a simple square object with bounds properties,
    which also has speed and can move.

    :param x: left coordinate
    :param y: top coordinate
    :param w: object width
    :param h: object height
    :param speed: object speed
    """
    def __init__(self, x: int, y: int, w: int, h: int, speed: tuple = (0, 0)):
        """Init GameObject with certain features."""
        self.bounds = Rect(x, y, w, h)
        self.speed = speed

    @property
    def left(self):
        """Return left bound."""
        return self.bounds.left

    @property
    def right(self):
        """Return right bound."""
        return self.bounds.right

    @property
    def top(self):
        """Return top bound."""
        return self.bounds.top

    @property
    def bottom(self):
        """Return bottom bound."""
        return self.bounds.bottom

    @property
    def width(self):
        """Return width."""
        return self.bounds.width

    @property
    def height(self):
        """Return height."""
        return self.bounds.height

    @property
    def center(self):
        """Return rectangle center."""
        return self.bounds.center

    @property
    def centerx(self):
        """Return rectangle horisontal center."""
        return self.bounds.centerx

    @property
    def centery(self):
        """Return rectangle vertical center."""
        return self.bounds.centery

    def draw(self, surface):
        """
        Draw object.

        Needs to be updated in child classes
        """
        pass

    def move(self, dx: int, dy: int):
        """Move object.

        :param dx: horisontal step
        :param dy: vertical step
        """
        self.bounds = self.bounds.move(dx, dy)

    def update(self):
        """Update object position."""
        if self.speed == [0, 0]:
            return

        self.move(*self.speed)
Ejemplo n.º 37
0
class GameObject:
    def __init__(self, x, y, w, h, visible=True, speed=(0, 0)):
        self._bounds = Rect(x, y, w, h)
        self._visible = visible
        self._speed = speed

    @property
    def left(self):
        return self._bounds.left

    @property
    def right(self):
        return self._bounds.right

    @property
    def top(self):
        return self._bounds.top

    @property
    def bottom(self):
        return self._bounds.bottom

    @property
    def width(self):
        return self._bounds.width

    @property
    def height(self):
        return self._bounds.height

    @property
    def center(self):
        return self._bounds.center

    @property
    def centerx(self):
        return self._bounds.centerx

    @property
    def centery(self):
        return self._bounds.centery

    @property
    def visible(self):
        return self._visible

    def set_visible(self):
        self._visible = True

    def set_invisible(self):
        self._visible = False

    def in_bounds(self, pos):
        return self._bounds.collidepoint(pos)

    def draw(self, surface, dx=0, dy=0):
        pass

    def move(self, dx, dy):
        self._bounds = self._bounds.move(dx, dy)

    def update(self):
        pass
Ejemplo n.º 38
0
                else: y = 0
                pos = (pos[0]+x, pos[1]+y)
                
                    
        ENEMIES[i] = [pos, name, d, f, c]

    for i in remove[::-1]: ENEMIES.pop(i) 
    
    # hit detection - platforms
    hitbox = Rect((X, Y), (32, 64)) if STATE != "crouch" else Rect((X, Y+32), (32, 32))
    checklist = plats
    if hitbox.collidelist(checklist) != -1:
        STATE = "dmg"
        continue
    if x_vel:
        while hitbox.move(x_vel, 0).collidelist(checklist) != -1:
            if STATE.startswith("jump"): STATE = "wall"
            x_vel += 1 if x_vel < 0 else -1
    if y_vel:
        while hitbox.move(0, y_vel).collidelist(checklist) != -1: y_vel += 1 if y_vel < 0 else -1
    if x_vel and y_vel:
        while hitbox.move(x_vel, y_vel).collidelist(checklist) != -1:
            y_vel += 1 if y_vel < 0 else -1
            x_vel += 1 if x_vel < 0 else -1
    #                 hats
    checklist = [Rect(pos, (46, 46)) for pos, hat in HATS]
    i = hitbox.collidelist(checklist)
    if i != -1: HAT = HATS[i][1]
    #                 flags
    checklist = [Rect(pos, (46, 64)) for pos in FLAGS]
    i = hitbox.collidelist(checklist)