Задать вопрос
Ivannavi555
@Ivannavi555

Не зачитываются очки, проблема в коде?

Переделка flappyBird, когда птица пролетает трубу, должно выдаваться одно очко, но не выдается. Код вроде бы правильный.
spoiler
import pygame
from pygame.locals import *
import random
import sys

pygame.init()

clock = pygame.time.Clock()
fps = 60

screen_width = 864
screen_height = 936

screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('BatBird')

#define font
font = pygame.font.SysFont('Bauhaus 93', 60)

#define colours
white = (255, 255, 255)

#define game variables
ground_scroll = 0
scroll_speed = 4
flying = False
game_over = False
pipe_gap = 150
pipe_frequency = 1500 #milliseconds
last_pipe = pygame.time.get_ticks() - pipe_frequency
score = 0
pass_pipe = False


#load images
bg = pygame.image.load('img/bg1.png')
ground_img = pygame.image.load('img/ground.png')
button_img = pygame.image.load('img/restart.png')
exit_button_img = pygame.image.load('img/exit.png')
start_img = pygame.image.load('img/start.png')
shop_button_img = pygame.image.load('img/shop_button.png')
shop_img = pygame.image.load('img/shop.png')
start_img = pygame.transform.scale(start_img, (screen_width, screen_height))

pygame.mixer.music.load('sounds/theme.mp3')
pygame.mixer.music.set_volume(0.1)
pygame.mixer.music.play(-1)

sndFall = pygame.mixer.Sound('sounds/fall.wav')

#function for outputting text onto the screen
def draw_text(text, font, text_col, x, y):
    img = font.render(text, True, text_col)
    screen.blit(img, (x, y))

def reset_game():
    global score
    pipe_group.empty()
    flappy.rect.x = 100
    flappy.rect.y = int(screen_height / 2)
    score = 0
    return score

class Bird(pygame.sprite.Sprite):

    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.images = []
        self.index = 0
        self.counter = 0
        for num in range(1, 4):
            img = pygame.image.load(f"img/Batbird{num}.png")
            self.images.append(img)
        self.image = self.images[self.index]
        self.rect = self.image.get_rect()
        self.rect.center = [x, y]
        self.vel = 0
        self.clicked = False

    def update(self):

        if flying == True:
            #apply gravity
            self.vel += 0.5
            if self.vel > 8:
                self.vel = 8
            if self.rect.bottom < 768:
                self.rect.y += int(self.vel)

        if game_over == False:
            #jump
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                self.vel = -10
            if pygame.mouse.get_pressed()[0] == 0:
                self.clicked = False

            #handle the animation
            flap_cooldown = 5
            self.counter += 1

            if self.counter > flap_cooldown:
                self.counter = 0
                self.index += 1
                if self.index >= len(self.images):
                    self.index = 0
                self.image = self.images[self.index]


            #rotate the bird
            self.image = pygame.transform.rotate(self.images[self.index], self.vel * -2)
        else:
            #point the bird at the ground
            self.image = pygame.transform.rotate(self.images[self.index], -90)



class Pipe(pygame.sprite.Sprite):

    def __init__(self, x, y, position):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("img/pipe.png")
        self.rect = self.image.get_rect()
        #position variable determines if the pipe is coming from the bottom or top
        #position 1 is from the top, -1 is from the bottom
        if position == 1:
            self.image = pygame.transform.flip(self.image, False, True)
            self.rect.bottomleft = [x, y - int(pipe_gap / 2)]
        elif position == -1:
            self.rect.topleft = [x, y + int(pipe_gap / 2)]


    def update(self):
        self.rect.x -= scroll_speed
        if self.rect.right < 0:
            self.kill()



class Button():
    def __init__(self, x, y, image):
        self.image = image
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)

    def draw(self):
        action = False

        #get mouse position
        pos = pygame.mouse.get_pos()

        #check mouseover and clicked conditions
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0] == 1:
                action = True

        #draw button
        screen.blit(self.image, (self.rect.x, self.rect.y))

        return action


class ExitButton():
    def __init__(self, x, y, image):
        self.image = image
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)

    def draw(self):
        action = False

        #get mouse position
        pos = pygame.mouse.get_pos()

        #check mouseover and clicked conditions
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0] == 1:
                action = True

        #draw button
        screen.blit(self.image, (self.rect.x, self.rect.y))

        return action




pipe_group = pygame.sprite.Group()
bird_group = pygame.sprite.Group()

flappy = Bird(100, int(screen_height / 2))

bird_group.add(flappy)

#create restart button instance
restart_button = Button(screen_width // 2 - 50, screen_height // 2 -30, button_img)
exit_button = ExitButton(screen_width // 2 - 50, screen_height // 2 +40, exit_button_img)
shop_button = Button(screen_width // 2 - 50, screen_height // 2 - 100, shop_button_img)

# Shop variables
shop_open = False

start = True
while start:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            start = False

    screen.blit(bg, (0, +70))
    screen.blit(start_img, (0, +70))
    pygame.display.update()

run = True
while run:

    clock.tick(fps)

    #draw background
    screen.blit(bg, (0,0))
    pipe_group.update()
    pipe_group.draw(screen)
    bird_group.draw(screen)
    bird_group.update()

    #draw and scroll the ground
    screen.blit(ground_img, (ground_scroll, 768))

    #check the score
    if len(pipe_group) > 0:
        pipe = pipe_group.sprites()[0]
        if bird_group.sprites()[0].rect.left > pipe.rect.left and bird_group.sprites()[0].rect.right < pipe.rect.right and not pass_pipe:
            pass_pipe = True
        if pass_pipe and bird_group.sprites()[0].rect.left > pipe.rect.right:
            score += 1
            pass_pipe = False
    draw_text(str(score), font, white, int(screen_width / 2), 20)

    #look for collision
    if pygame.sprite.groupcollide(bird_group, pipe_group, False, False) or flappy.rect.top < 0:
        game_over = True
    # once the bird has hit the ground it's game over
    if flappy.rect.bottom >= 768:
        game_over = True
        flying = False

    if game_over == False and flying == True:

        #generate new pipes
        time_now = pygame.time.get_ticks()
        if time_now - last_pipe > pipe_frequency:
            pipe_height = random.randint(-100, 100)
            btm_pipe = Pipe(screen_width, int(screen_height / 2) + pipe_height, -1)
            top_pipe = Pipe(screen_width, int(screen_height / 2) + pipe_height, 1)
            pipe_group.add(btm_pipe)
            pipe_group.add(top_pipe)
            last_pipe = time_now

        ground_scroll -= scroll_speed
        if abs(ground_scroll) > 35:
            ground_scroll = 0

        pipe_group.update()

    if game_over == True:
        if restart_button.draw():
            game_over = False
            score = reset_game()

        if exit_button.draw():
            pygame.quit()
            sys.exit()

        if shop_button.draw():
            screen.blit(shop_img, (0, 0))
            pygame.display.update()
            pygame.time.wait(3000)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            # Обработка события нажатия на кнопку магазина
            if event.type == pygame.MOUSEBUTTONDOWN and shop_button.draw():
                shop_open = True

        if shop_open:
            # Создание поверхности с прозрачным фоном
            shop_surface = pygame.Surface((screen_width, screen_height), pygame.SRCALPHA)

            # Задание пользовательских размеров для растяжения
            desired_width = int(screen_width * 1)
            desired_height = int(screen_height * 0.5)

            # Масштабирование изображения магазина с сохранением пропорций
            scaled_shop_img = pygame.transform.smoothscale(shop_img, (desired_width, desired_height))

            # Определение координат верхнего левого угла изображения магазина
            shop_x = int((screen_width - desired_width) / 2)
            shop_y = int((screen_height - desired_height) / 2)

            # Нарисовать масштабированное изображение магазина на поверхности
            shop_surface.blit(scaled_shop_img, (shop_x, shop_y))

            # Отрисовка поверхности магазина на основном окне
            screen.blit(shop_surface, (0, 0))

            pygame.display.update()
            pygame.time.wait(3000)
            shop_open = False

        if event.type == pygame.MOUSEBUTTONDOWN and flying == False and game_over == False:
            flying = True

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN and flying == False and game_over == False:
            flying = True

    pygame.display.update()
  • Вопрос задан
  • 51 просмотр
Подписаться 1 Средний 2 комментария
Пригласить эксперта
Ответы на вопрос 1
@dima20155
you don't choose c++. It chooses you
Очевидно, вам нужно задебажить этот кусочек кода и посмотреть почему же у вас левый край спрайта трубы больше, чем левый край птицы.
#check the score
    if len(pipe_group) > 0:
        pipe = pipe_group.sprites()[0]
        if bird_group.sprites()[0].rect.left > pipe.rect.left and bird_group.sprites()[0].rect.right < pipe.rect.right and not pass_pipe:
            pass_pipe = True
        if pass_pipe and bird_group.sprites()[0].rect.left > pipe.rect.right:
            score += 1
            pass_pipe = False


Например, распечатайте все спрайты труб и посмотрите их границы/координаты. Для большей ясности можно отрисовать их на игровом экране (многие игры/движки поддерживают дебажный режим с отрисовкой коллизий и т.п.)

Также я не увидел кода, который удаляет уже пройденные трубы, что странно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы