Помощь в игре Brick Breaker, мяч подпрыгивает - PullRequest
1 голос
/ 28 апреля 2020

Я закончил небольшой игровой проект, посвященный прорывной игре, но моя главная проблема в том, что мяч, кажется, застревает при движении из стороны в сторону гораздо чаще, чем я бы согласился с этим. Это определенно проблема со скоростью мяча, и я попытался возиться с числами, но я не могу заставить его перестать застрять. Будем очень благодарны за любые идеи о том, как это исправить или даже улучшить какой-либо код.

import sys
import pygame as pg
from random import randint

black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
score = 0
lives = 3


def run_game():
    pg.init()

    screen = pg.display.set_mode((800,600))
    pg.display.set_caption("Brick Breaker")
    bg_color = (0, 0, 0)
    screen.fill(bg_color)

    class Paddle(pg.sprite.Sprite):
        def __init__(self, color, width, height):
            super().__init__()
            self.image = pg.Surface([width, height])
            self.image.fill(black)
            self.image.set_colorkey(black)
            pg.draw.rect(self.image, color, [0, 0, width, height])
            self.rect = self.image.get_rect()
        def moveLeft(self,pixels):
            self.rect.x -= pixels
            if self.rect.x < 0:
                self.rect.x = 0
        def moveRight(self,pixels):
            self.rect.x += pixels
            if self.rect.x > 700:
                self.rect.x = 700

    class Ball(pg.sprite.Sprite):
        def __init__(self, color, width, height):
            super().__init__()
            self.image = pg.Surface([width, height])
            self.image.fill(black)
            self.image.set_colorkey(black)
            pg.draw.rect(self.image, color, [0, 0, width, height])
            self.velocity = [randint(4,8),randint(-8,8)]
            self.rect = self.image.get_rect()
        def update(self):
            self.rect.x += self.velocity[0]
            self.rect.y += self.velocity[1]
        def bounce(self):
            self.velocity[0] = -self.velocity[0]
            self.velocity[1] = randint(-8,10)

    class Brick(pg.sprite.Sprite):
        def __init__(self, color, width, height):
            super().__init__()
            self.image = pg.Surface([width, height])
            self.image.fill(black)
            self.image.set_colorkey(black)
            pg.draw.rect(self.image, color, [0, 0, width, height])
            self.rect = self.image.get_rect()

    clock = pg.time.Clock()

    all_sprites_list = pg.sprite.Group()
    paddle = Paddle(white,100,10)
    paddle.rect.x = 350
    paddle.rect.y = 560
    ball = Ball(white,10,10)
    ball.rect.x = 345
    ball.rect.y = 195
    all_bricks = pg.sprite.Group()
    for i in range(7):
        brick = Brick(red,80,30)
        brick.rect.x = 60 + i* 100
        brick.rect.y = 60
        all_sprites_list.add(brick)
        all_bricks.add(brick)
    for i in range(7):
        brick = Brick(blue,80,30)
        brick.rect.x = 60 + i* 100
        brick.rect.y = 100
        all_sprites_list.add(brick)
        all_bricks.add(brick)
    for i in range(7):
        brick = Brick(green,80,30)
        brick.rect.x = 60 + i* 100
        brick.rect.y = 140
        all_sprites_list.add(brick)
        all_bricks.add(brick)
    all_sprites_list.add(paddle)
    all_sprites_list.add(ball)

    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                sys.exit()

        keys = pg.key.get_pressed()
        if keys[pg.K_LEFT]:
            paddle.moveLeft(10)
        if keys[pg.K_RIGHT]:
            paddle.moveRight(10)

        all_sprites_list.update()

        if ball.rect.x>=790:
            ball.velocity[0] = -ball.velocity[0]
        if ball.rect.x<=0:
            ball.velocity[0] = -ball.velocity[0]
        if ball.rect.y>590:
            ball.velocity[1] = -ball.velocity[1]
            global lives
            lives-=1
            if lives == 0:
                font = pg.font.Font(None, 74)
                text = font.render("YOU LOSE", 1, red)
                screen.blit(text,(280,250))
                pg.display.flip()
                sys.exit()
        if ball.rect.y<40:
            ball.velocity[1] = -ball.velocity[1]
        if pg.sprite.collide_mask(ball, paddle):
            ball.rect.x -= ball.velocity[0]
            ball.rect.y -= ball.velocity[1]
            ball.bounce()

        brick_collision_list = pg.sprite.spritecollide(ball,all_bricks,False)
        for brick in brick_collision_list:
          ball.bounce()
          brick.kill()
          if len(all_bricks)==0:
            font = pg.font.Font(None, 74)
            text = font.render("YOU WIN", 1, green)
            screen.blit(text,(280,250))
            pg.display.flip()
            sys.exit()

        screen.fill(black)
        font = pg.font.Font(None, 40)
        text = font.render("lives: " + str(lives), 1, white)
        screen.blit(text, (10,10))

        all_sprites_list.draw(screen)
        pg.display.flip()
        clock.tick(50)
run_game()

1 Ответ

1 голос
/ 28 апреля 2020

Когда мяч попадает на ракетку, установите нижнюю часть мяча на вершину ракетки. Нет необходимости менять направление мяча, потому что его направление изменяется в ball.bounce()

if pg.sprite.collide_mask(ball, paddle):
    ball.rect.bottom = paddle.rect.top 
    #ball.rect.x -= ball.velocity[0]
    #ball.rect.y -= ball.velocity[1]
    ball.bounce() 

В Ball.bounce инвертирует направление y мяча и вычисляет новое случайное направление x:

class Ball(pg.sprite.Sprite):
    def __init__(self, color, width, height):
        # [...]

        self.velocity = [randint(-8,8), randint(4,8)]

    def bounce(self):
        # invert y
        self.velocity[1] = -self.velocity[1]

        # either random x
        # self.velocity[0] = randint(-8, 8)

        # or slightly changed x
        self.velocity[0] = max(-8, min(8, self.velocity[0] + randint(-3, 3)))
...