Use clipping rect size. Determine which is smaller. Width or Height. If even then you can says it hit both angles.
Then you can compare rect.centerx or rect.centery to collision rect.centerx or rect.centery.
I like displacement the best. It the easiest to start with.
Example.
Then you can compare rect.centerx or rect.centery to collision rect.centerx or rect.centery.
I like displacement the best. It the easiest to start with.
Example.
import os import pygame import random from pygame.sprite import Sprite, Group, spritecollide class Block(Sprite): def __init__(self, image, position, group): Sprite.__init__(self) # Reference the image. Doesn't make new one self.image = image # Collision group reference self.group = group self.rect = image.get_rect() self.rect.topleft = position # Hold the floats position. Since rect only does int self.position = pygame.Vector2(position) self.direction = pygame.Vector2( (random.randint(0, 600) - 300) / 100 / Game.fps, (random.randint(0, 600) - 300) / 100 / Game.fps) def update(self): self.position += self.direction * Game.delta self.rect.topleft = self.position self.collision() def collision(self): self.wall_bounce() blocks = spritecollide(self, self.group, False) for block in blocks: if block != self: # Simple displacement w, h = self.rect.clip(block.rect).size if w < h: if self.rect.centerx > block.rect.centerx: self.rect.left = block.rect.right self.position.x = self.rect.x self.direction.x = abs(self.direction.x) block.direction.x = -abs(block.direction.x) else: self.rect.right = block.rect.left self.position.x = self.rect.x self.direction.x = -abs(self.direction.x) block.direction.x = abs(block.direction.x) else: if self.rect.centery > block.rect.centery: self.rect.top = block.rect.bottom self.position.y = self.rect.y self.direction.y = abs(self.direction.y) block.direction.y = -abs(block.direction.y) else: self.rect.bottom = block.rect.top self.position.y = self.rect.y self.direction.y = -abs(self.direction.y) block.direction.y = abs(block.direction.y) def wall_bounce(self): clamp = self.rect.clamp(Game.rect) if clamp.x != self.rect.x: self.rect.x = clamp.x self.position.x = clamp.x self.direction.x = -self.direction.x if clamp.y != self.rect.y: self.rect.y = clamp.y self.position.y = clamp.y self.direction.y = -self.direction.y class Scene: def __init__(self): self.sprites = Group() self.create_block_images() self.add_blocks(15) def add_blocks(self, number): for n in range(number): image = random.choice(self.block_images) position = (random.randint(30, Game.rect.width - 30), random.randint(30, Game.rect.height - 30)) block = Block(image, position, self.sprites) block.add(self.sprites) def create_block_images(self): self.block_images = [] for x in range(20): color = pygame.Color('black') while color.r < 100 and color.g < 100 and color.b < 100: color.r = random.randint(0, 255) color.g = random.randint(0, 255) color.b = random.randint(0, 255) low, high = 20, 30 size = random.randint(low, high), random.randint(low, high) surface = pygame.Surface(size) surface.fill(color) self.block_images.append(surface) def draw(self, surface): self.sprites.draw(surface) self.sprites.update() # Namespace for pygame game loop class Game: @classmethod def setup(cls, title, width, height): # Basic pygame setup pygame.display.set_caption(title) cls.surface = pygame.display.set_mode((width, height)) cls.rect = cls.surface.get_rect() cls.clock = pygame.time.Clock() cls.delta = 0 cls.fps = 30 cls.scene = Scene() @classmethod def mainloop(cls): cls.running = True while cls.running: for event in pygame.event.get(): if event.type == pygame.QUIT: cls.running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: cls.running = False cls.surface.fill(pygame.Color('black')) cls.scene.draw(cls.surface) pygame.display.flip() cls.delta = cls.clock.tick(cls.fps) if __name__ == '__main__': pygame.init() os.environ['SDL_VIDEO_CENTERED'] = '1' Game.setup('Block Bouncing', 800, 600) Game.mainloop() pygame.quit()
99 percent of computer problems exists between chair and keyboard.