import pygame, sys class Player(pygame.sprite.Sprite): def __init__(self, pos, groups, obstacle_sprites): super().__init__(groups) self.image = pygame.Surface((48, 48 * 2), pygame.SRCALPHA) self.player_sprite_top = Tile('player.png', (0, 0), 16, 16, 16, 16, 3).image self.player_sprite_bottom = Tile('player.png', (0, 0), 16, 16, 16, 32, 3).image self.image.blit(self.player_sprite_top, (0, 0)) self.image.blit(self.player_sprite_bottom, (0, 48)) # Mask self.mask = pygame.mask.from_surface(self.image) # Normal Rect # self.rect = self.image.get_rect() # Bounding Rect self.rect = self.image.get_bounding_rect() self.image = self.image.subsurface(self.rect) self.rect.topleft = pos self.mask = pygame.mask.from_surface(self.image) self.direction = pygame.math.Vector2() self.speed = 5 self.status = 'right' # left or right self.obstacle_sprites = obstacle_sprites def input(self): keys = pygame.key.get_pressed() if keys[pygame.K_UP]: self.direction.y = -1 elif keys[pygame.K_DOWN]: self.direction.y = 1 else: self.direction.y = 0 if keys[pygame.K_RIGHT]: if self.status != 'right': self.image = pygame.transform.flip(self.image, True, False) self.status = 'right' self.direction.x = 1 elif keys[pygame.K_LEFT]: if self.status != 'left': self.image = pygame.transform.flip(self.image, True, False) self.status = 'left' self.direction.x = -1 else: self.direction.x = 0 def move(self, speed): if self.direction.magnitude() != 0: self.direction = self.direction.normalize() og_rect_x = self.rect.x og_rect_y = self.rect.y # Mask Collision # self.rect.x += self.direction.x * speed # self.rect.y += self.direction.y * speed # if self.mask_collision(): # self.rect.x = og_rect_x # self.rect.y = og_rect_y # Rect Collision self.rect.x += self.direction.x * speed self.rect_collision('horizontal') self.rect.y += self.direction.y * speed self.rect_collision('vertical') self.rect.center = self.rect.center def mask_collision(self): for sprite in self.obstacle_sprites: if pygame.sprite.collide_mask(self, sprite): return True def rect_collision(self, direction): if direction == 'horizontal': for sprite in self.obstacle_sprites: if sprite.rect.colliderect(self.rect): if self.direction.x > 0: self.rect.right = sprite.rect.left if self.direction.x < 0: self.rect.left = sprite.rect.right if direction == 'vertical': for sprite in self.obstacle_sprites: if sprite.rect.colliderect(self.rect): if self.direction.y > 0: self.rect.bottom = sprite.rect.top if self.direction.y < 0: self.rect.top = sprite.rect.bottom def update(self): self.input() self.mask = pygame.mask.from_surface(self.image) self.move(self.speed) class Tile(pygame.sprite.Sprite): def __init__(self, sprite_sheet, pos, width, height, x_start, y_start, scale): super(Tile, self).__init__() self.sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() self.image = self.get_sprite(width, height, x_start, y_start, scale) # Normal Rect # self.rect = self.image.get_rect() # Bounding Rect self.rect = self.image.get_bounding_rect() # self.image = self.image.subsurface(self.rect) # Causes Weird Glitch self.rect.topleft = pos self.mask = pygame.mask.from_surface(self.image) def get_sprite(self, width, height, x_start, y_start, scale): image = pygame.Surface((width, height), pygame.SRCALPHA) image.blit(self.sprite_sheet, (0, 0), (x_start, y_start, width, height)) image = pygame.transform.scale(image, (width * scale, height * scale)) return image pygame.init() display = pygame.display.set_mode((1280, 720)) clock = pygame.time.Clock() visible_sprites = pygame.sprite.Group() obstacle_sprites = pygame.sprite.Group() player = Player((0, 0), [visible_sprites], obstacle_sprites) fence = Tile('fences.png', (48, 48), 16, 16, 16, 48, 3) obstacle_sprites.add(fence) visible_sprites.add(fence) fence_2 = Tile('fences.png', (48 * 2, 48), 16, 16, 32, 48, 3) obstacle_sprites.add(fence_2) visible_sprites.add(fence_2) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: pygame.quit() sys.exit() visible_sprites.update() display.fill('#555358') visible_sprites.draw(display) pygame.display.update() clock.tick(60)