Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Game "Fluppy bird"
#1
The problem is that after the bird loses one life, as well as after restarting the game, the pipes do not disappear, so the bird remains in the same place where it collided with the pipe, and the user cannot continue the game, because a new collision is immediately initialized.
import pygame
import random
from user import create_user, get_user_by_nickname, get_user_by_mail, update_coin_collections, create_achievement, update_achievement, get_achievement, connect_db

pygame.init()  # Ініціалізація Pygame

# Визначення розмірів пташки
bird_width = 50
bird_height = 50

# Завантаження зображень
bird_image = pygame.image.load("images/bird.png")
bird_image = pygame.transform.scale(bird_image, (bird_width, bird_height))

bg_image = pygame.image.load("images/background.jpg")
bg_image = pygame.transform.scale(bg_image, (1000, 600))

pipe_bottom = pygame.image.load("images/pipe_bottom.png")
pipe_top = pygame.image.load("images/pipe_top.png")
pipe_bottom = pygame.transform.scale(pipe_bottom, (60, 400))
pipe_top = pygame.transform.scale(pipe_top, (60, 400))

pipes = []
pipe_width = pipe_top.get_width()
pipe_height = pipe_top.get_height()
space_between_pipes = 180  # Відстань між верхньою та нижньою трубами

coin_image = pygame.image.load("images/coin.png")
coin_image = pygame.transform.scale(coin_image, (30, 30))
coin_width, coin_height = coin_image.get_size()
coins = []

font = pygame.font.SysFont(None, 30)

# Глобальна змінна для лічильника монет
coin_counter = 0

def draw_background(screen):
    screen.blit(bg_image, (0, 0))

def add_pipe():
    pipe_x = 800  # Початкова позиція труби (за межами екрану справа)
    pipe_y = random.randint(-pipe_height, 0)  # Випадкова позиція труби по вертикалі
    pipes.append({'x': pipe_x, 'top_y': pipe_y, 'bottom_y': pipe_y + pipe_height + space_between_pipes})

def draw_pipes(screen):
    for pipe in pipes:
        screen.blit(pipe_top, (pipe['x'], pipe['top_y']))
        screen.blit(pipe_bottom, (pipe['x'], pipe['bottom_y']))
        pipe['x'] -= 2  # Рух труб вліво

    # Видалення труб, які вийшли за межі екрану
    pipes[:] = [pipe for pipe in pipes if pipe['x'] > -pipe_width]

    # Додавання нової труби, якщо остання труба досягла певної позиції
    if not pipes or pipes[-1]['x'] < 400:
        add_pipe()

def add_coin():
    coin_x = random.randint(800, 1200)
    coin_y = random.randint(100, 500)
    # Перевірка, чи монета знаходиться на трубі
    for pipe in pipes:
        if pipe['x'] < coin_x < pipe['x'] + pipe_width:
            return  # Якщо монета на трубі, не додаємо її
    coins.append({'x': coin_x, 'y': coin_y})

def draw_coins(screen):
    for coin in coins:
        screen.blit(coin_image, (coin['x'], coin['y']))
        coin['x'] -= 2  # Рух монет вліво

def collect_coins(bird_y):
    global coins, coin_counter
    bird_rect = pygame.Rect(100, bird_y, bird_width, bird_height)
    collected_coins = 0
    for coin in coins:
        if bird_rect.colliderect(pygame.Rect(coin['x'], coin['y'], coin_width, coin_height)):
            collected_coins += 1
            coin_counter += 1  # Оновлюйте coin_counter тут
    coins[:] = [coin for coin in coins if not bird_rect.colliderect(pygame.Rect(coin['x'], coin['y'], coin_width, coin_height))]
    return collected_coins

def draw_coin_counter(screen):
    global coin_counter
    font = pygame.font.SysFont(None, 30)
    text = font.render(f"Монети: {coin_counter}", True, (0, 0, 0))
    screen.blit(text, (10, 10))

def draw_bird(screen, bird_y):
    screen.blit(bird_image, (100, bird_y))

def check_collision(bird_y):
    bird_rect = pygame.Rect(100, bird_y, bird_width, bird_height)
    for pipe in pipes:
        top_pipe_rect = pygame.Rect(pipe['x'], pipe['top_y'], pipe_width, pipe_height)
        bottom_pipe_rect = pygame.Rect(pipe['x'], pipe['bottom_y'], pipe_width, pipe_height)
        if bird_rect.colliderect(top_pipe_rect) or bird_rect.colliderect(bottom_pipe_rect):
            return True
    return False

def draw_lives(screen, lives):
    text = font.render(f"Життя: {lives}", True, (0, 0, 0))
    screen.blit(text, (700, 10))
    
def draw_player_level(screen, level):
    font = pygame.font.SysFont(None, 30)
    text = font.render(f"Рівень: {level}", True, (0, 0, 0))
    screen.blit(text, (10, 40))


import pygame
import random
import tkinter as tk
from tkinter import messagebox
from user import connect_db, create_user, get_player_level, get_user_by_nickname, get_user_by_mail, update_coin_collections, create_achievement, update_achievement, get_achievement
import game_interface
import sys

pygame.init()

current_user_id = None  # Глобальна змінна для зберігання поточного user_id
bg_image = pygame.image.load("images/background.jpg")
bg_image = pygame.transform.scale(bg_image, (1000, 600))

pipe_spawn_delay = 300  # Відстань, яку повинна пройти пташка перед появою першої труби

def initialize_game():
    global pipes, coins, bird_y, bird_velocity, background_x, pipe_spawn_delay
    pipes = []  # Очищення списку труб
    coins = []  # Очищення списку монет
    bird_y = 300  # Початкова позиція пташки
    bird_velocity = 0  # Початкова швидкість падіння пташки
    background_x = 0  # Початкова позиція фону
    pipe_spawn_delay = 300  # Затримка перед появою першої труби

def open_game_window(user_id):    
    global current_user_id, coin_counter, bird_y, bird_velocity, background_x, bg_image, pipe_spawn_delay
    current_user_id = user_id
    create_achievement(user_id)  # Встановлення життів і монет для користувача
    lives, coins = get_achievement(user_id)  # Отримуємо початкову кількість життів та монет
    coin_counter = coins  # Ініціалізуємо лічильник монет
    player_level = get_player_level(user_id)
    
    initialize_game()
        
    screen = pygame.display.set_mode((800, 600))
    pygame.display.set_caption("Пернатий пілот")
    clock = pygame.time.Clock()

    gravity = 0.3  # Гравітація, яка впливає на падіння пташки

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    bird_velocity = -3  # Пташка підстрибує вгору

        bird_velocity += gravity  # Збільшення швидкості падіння пташки
        bird_y += bird_velocity  # Оновлення позиції пташки
        
        background_x -= 1  # Рух фону вліво
        if background_x <= -bg_image.get_width():
            background_x = 0  # Повернення фону на початкову позицію

        screen.fill((255, 255, 255))
        game_interface.draw_background(screen)
        if random.randint(1, 100) == 1:  # Рандомне додавання монет
            game_interface.add_coin()
            
        pipe_spawn_delay -= 2
        if pipe_spawn_delay <= 0:
            game_interface.add_pipe()
            pipe_spawn_delay = 300

        game_interface.draw_pipes(screen)
        game_interface.draw_bird(screen, bird_y)
        collected_coins = game_interface.collect_coins(bird_y)
        coins += collected_coins
        update_achievement(user_id, lives, coins)
        game_interface.draw_player_level(screen, player_level)
        game_interface.draw_coins(screen)
        game_interface.draw_coin_counter(screen)  # Передаємо лічильник монет
        game_interface.draw_lives(screen, lives)

        if game_interface.check_collision(bird_y):
            lives -= 1
            update_achievement(user_id, lives, coins)
            if lives <= 0:
                # Завершення гри
                running = False
                game_over_window()
                initialize_game() 
            else:
                initialize_game()  # Повернення до початкових умов гри
                messagebox.showinfo("Життя втрачено", "У вас залишилось {} життів".format(lives))
                        
        level = update_level(user_id, coins)  # Оновлення рівня гравця
        if level is not None:
            player_level = level
            coins = 0  # Скидання лічильника монет
            update_achievement(user_id, lives, coins)  # Оновлення досягнень в базі даних

        pygame.display.update()
        clock.tick(60)  # Обмеження кадрів на секунду (FPS)

    pygame.quit()
    
def game_over_window():
    game_over = tk.Tk()
    game_over.title("Гра завершена")
    center_window(game_over, 300, 200)
    game_over.configure(bg='#f0f0f0')

    def restart_game():
        game_over.destroy()
        initialize_game()  # Очищення труб, монет, затримок
        open_game_window(current_user_id)

    label = tk.Label(game_over, text="Гра завершена!", bg='#f0f0f0', font=("Arial", 14))
    label.pack(pady=10)

    restart_button = tk.Button(game_over, text="Почати заново", command=restart_game, bg="#4CAF50", fg="black", width=15, height=2, relief="flat", cursor="hand2")
    restart_button.pack(pady=5)

    exit_button = tk.Button(game_over, text="Вихід", command=lambda: [game_over.destroy(), sys.exit()], bg="#2196F3", fg="black", width=15, height=2, relief="flat", cursor="hand2")
    exit_button.pack()

    game_over.mainloop()

def restart_game():
    pygame.init()  # Реініціалізація Pygame
    open_game_window(current_user_id)
    
def update_level(user_id, coins):
    if coins >= 5:
        conn = connect_db()
        cursor = conn.cursor()
        cursor.execute("SELECT level FROM progress WHERE user_id = ?", (user_id,))
        result = cursor.fetchone()
        if result:
            level = result[0]
            new_level = level + 1
            cursor.execute("UPDATE progress SET level = ? WHERE user_id = ?", (new_level, user_id))
            conn.commit()
            return new_level
        else:
            new_level = 1
            cursor.execute("INSERT INTO progress (user_id, level) VALUES (?, ?)", (user_id, new_level))
            conn.commit()
        conn.close()
        return new_level
    return None

def center_window(window, width, height):
    screen_width = window.winfo_screenwidth()
    screen_height = window.winfo_screenheight()
    x = (screen_width - width) // 2
    y = (screen_height - height) // 2
    window.geometry(f'{width}x{height}+{x}+{y}')

def register_user():
    nickname = entry_nickname.get()
    mail = entry_mail.get()

    if not nickname or not mail:
        messagebox.showerror("Помилка", "Будь ласка, заповніть усі поля.")
    elif get_user_by_nickname(nickname) or get_user_by_mail(mail):
        messagebox.showerror("Помилка", "Користувач з таким нікнеймом або емейлом вже існує.")
    else:
        user_id = create_user(nickname, mail)
        messagebox.showinfo("Успіх", "Реєстрація успішна.")
        open_game_window(user_id)

def login_user():
    nickname = entry_nickname.get()
    user = get_user_by_nickname(nickname)

    if user:
        messagebox.showinfo("Успіх", f"Вхід успішний. Вітаємо в грі, {user[1]}!")
        window.destroy()
        open_game_window(user[0])
    else:
        messagebox.showerror("Помилка", "Користувача з таким нікнеймом не знайдено.")

# Створення вікна
window = tk.Tk()
window.title("Вхід та Реєстрація")
center_window(window, 300, 300)
window.configure(bg='white')  # Зробити вікно білого кольору

# Створення та розміщення елементів інтерфейсу
frame = tk.Frame(window, padx=20, pady=20, bg='white')  # Зробити фрейм білого кольору
frame.pack(expand=True)

label_nickname = tk.Label(frame, text="Нікнейм:", bg='white')  # Зробити лейбл білого кольору
label_nickname.pack()

entry_nickname = tk.Entry(frame)
entry_nickname.pack(pady=5)

label_mail = tk.Label(frame, text="Емейл:", bg='white')  # Зробити лейбл білого кольору
label_mail.pack()

entry_mail = tk.Entry(frame)
entry_mail.pack(pady=5)

button_register = tk.Button(frame, text="Реєстрація", command=register_user, cursor="hand2", bg="#4CAF50", fg="black", width=20, height=2, relief="flat")
button_register.pack(pady=(20, 5))  # Додати відстань зверху над кнопкою

button_login = tk.Button(frame, text="Вхід", command=login_user, cursor="hand2", bg="#2196F3", fg="black", width=20, height=2, relief="flat")
button_login.pack(pady=5)

# Запуск головного циклу
window.mainloop()
I just want the pipes to disappear and start appearing again from the edge of the window, I don't know where to make changes.
deanhystad write Apr-19-2024, 04:33 PM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Reply
#2
You have a list named "pipes", but the pipes that appear on the screen and collide with the birds are in the game_interface. You need to clear the game_interface pipes to resume. Resetting pipes = [] does nothing to the pipes in game_interface.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] bird jump in flappy bird games syafiq14 1 2,221 Dec-14-2020, 02:31 PM
Last Post: MK_CodingSpace

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020