Use vector2 in pygame. Collide with the window frame and restrict the ball to the rectangular area

前端 未结 1 513
梦谈多话
梦谈多话 2020-12-06 22:42

Hey i am trying to create a breakout clone with pyame, and i used

self.course(180 - self.course) % 360

To bounce the ball of the paddle, h

相关标签:
1条回答
  • 2020-12-06 23:18

    A vector defines a direction and an amount. You have to add the vector to the location of the ball. Sadly pygame.Rect stores integral numbers only, so the location of the object has to be stored in a pygame.math.Vector2, too. You need 1 vector for the location of the object and a 2nd one for the direction. Every time when the location changes, then the .rect attribute has to be set by the rounded location. If the object hits a surface then the Ball is reflected (.reflect()) by the Normal vector to the surface.

    Minimal example: repl.it/@Rabbid76/PyGame-BallBounceOffFrame

    import pygame
    import random
    
    class Ball(pygame.sprite.Sprite):
    
        def __init__(self, startpos, velocity, startdir):
            super().__init__()
            self.pos = pygame.math.Vector2(startpos)
            self.velocity = velocity
            self.dir = pygame.math.Vector2(startdir).normalize()
            self.image = pygame.image.load("ball.png").convert_alpha()
            self.rect = self.image.get_rect(center = (round(self.pos.x), round(self.pos.y)))
    
        def reflect(self, NV):
            self.dir = self.dir.reflect(pygame.math.Vector2(NV))
    
        def update(self):
            self.pos += self.dir * self.velocity
            self.rect.center = round(self.pos.x), round(self.pos.y)
       
    pygame.init()
    window = pygame.display.set_mode((500, 500))
    clock = pygame.time.Clock()
    
    all_groups = pygame.sprite.Group()
    start, velocity, direction = (250, 250), 5, (random.random(), random.random())
    ball = Ball(start, velocity, direction)
    all_groups.add(ball)
    
    run = True
    while run:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
    
        all_groups.update()
    
        if ball.rect.left <= 100:
            ball.reflect((1, 0))
        if ball.rect.right >= 400:
            ball.reflect((-1, 0))
        if ball.rect.top <= 100:
            ball.reflect((0, 1))
        if ball.rect.bottom >= 400:
            ball.reflect((0, -1))
    
        window.fill(0)
        pygame.draw.rect(window, (255, 0, 0), (100, 100, 300, 300), 1)
        all_groups.draw(window)
        pygame.display.flip()
    

    Lets assume you have a group of blocks:

    block_group = pygame.sprite.Group()
    

    Detect the collision of the ball and the block_group. Once a collision (pygame.sprite.spritecollide()) is detected, reflect the ball on the block:

    block_hit = pygame.sprite.spritecollide(ball, block_group, False)
    if block_hit:
        bl = block_hit[0].rect.left  - ball.rect.width/4
        br = block_hit[0].rect.right + ball.rect.width/4
        nv = (0, 1) if bl < ball.rect.centerx < br else (1, 0)
        ball.reflect(nv)
    
    0 讨论(0)
提交回复
热议问题