Ira
Ira

Reputation: 41

How to save flappy bird (made with pygame on python 3.9) scores into sql database

I m new to pygame and started learning it by making flappy bird by watching tutorials. I need to save the player's name and score to the sql database ( the table already has been created by me to store data) for a project. But whenever the program comes to saving the name and score, the GUI gets hanged rather than restarting the game and the data doesn't get saved. Here's the code:-

import pygame, sys, random
def sql():
    import mysql.connector as c
    m=c.connect(host="localhost",user="root",password= "password",database="flappy 
bird")
    my=m.cursor()
    n=input('enter your name')
    r = score
    my.execute("insert into table(name, score) values({},'{}')".format(n,r))
    m.commit()
    my.execute("select * from table")
    for i in my:
      print(i)

def draw_floor():
    screen.blit(floor_surface,(floor_x_pos,900))
    screen.blit(floor_surface,(floor_x_pos + 576,900))

def create_pipe():
    random_pipe_pos = random.choice(pipe_height)
    bottom_pipe = pipe_surface.get_rect(midtop = (700,random_pipe_pos))
    top_pipe = pipe_surface.get_rect(midbottom = (700,random_pipe_pos - 300))
    return bottom_pipe,top_pipe

def move_pipes(pipes):
    for pipe in pipes:
        pipe.centerx -= 5
    visible_pipes = [pipe for pipe in pipes if pipe.right > -50]
    return visible_pipes

def draw_pipes(pipes):
    for pipe in pipes:
        if pipe.bottom >= 1024:
            screen.blit(pipe_surface,pipe)
        else:
            flip_pipe = pygame.transform.flip(pipe_surface,False,True)
            screen.blit(flip_pipe,pipe)

def check_collision(pipes):
    global can_score
    for pipe in pipes:
        if bird_rect.colliderect(pipe):
            death_sound.play()
            can_score = True
            return False

    if bird_rect.top <= -100 or bird_rect.bottom >= 900:
        can_score = True
        return False

    return True

def rotate_bird(bird):
    new_bird = pygame.transform.rotozoom(bird,-bird_movement * 3,1)
    return new_bird

def bird_animation():
    new_bird = bird_frames[bird_index]
    new_bird_rect = new_bird.get_rect(center = (100,bird_rect.centery))
    return new_bird,new_bird_rect

def score_display(game_state):
    if game_state == 'main_game':
        score_surface = game_font.render(str(int(score)),True,(255,255,255))
        score_rect = score_surface.get_rect(center = (288,100))
        screen.blit(score_surface,score_rect)
    if game_state == 'game_over':
        score_surface = game_font.render(f'Score: {int(score)}' ,True,(255,255,255))
        score_rect = score_surface.get_rect(center = (288,100))
        screen.blit(score_surface,score_rect)

        high_score_surface = game_font.render(f'High score: {int(high_score)}',True, 
        (255,255,255))
        high_score_rect = high_score_surface.get_rect(center = (288,850))
        screen.blit(high_score_surface,high_score_rect)

def update_score(score, high_score):
    if score > high_score:
        high_score = score
    return high_score

def pipe_score_check():
    global score, can_score 

    if pipe_list:
        for pipe in pipe_list:
            if 95 < pipe.centerx < 105 and can_score:
                score += 1
                score_sound.play()
                can_score = False
            if pipe.centerx < 0:
                can_score = True

#pygame.mixer.pre_init(frequency = 44100, size = 16, channels = 2, buffer = 1024)
pygame.init()
screen = pygame.display.set_mode((576,1024))
clock = pygame.time.Clock()
game_font = pygame.font.Font('04B_19.ttf',40)

# Game Variables
gravity = 0.5
bird_movement = 0
game_active = True
score = 0
high_score = 0
can_score = True
bg_surface = 
pygame.image.load('assets/background- 
day.png').convert()
bg_surface = pygame.transform.scale2x(bg_surface)

floor_surface = 
pygame.image.load('assets/base.png').convert()
floor_surface = 
pygame.transform.scale2x(floor_surface)
floor_x_pos = 0

bird_downflap = 
pygame.transform.scale2x(pygame.image.load('assets/bluebird- 
downflap.png').convert_alpha())
bird_midflap = pygame.transform.scale2x(pygame.image.load('assets/bluebird- 
midflap.png').convert_alpha())
bird_upflap = pygame.transform.scale2x(pygame.image.load('assets/bluebird- 
upflap.png').convert_alpha())
bird_frames = [bird_downflap,bird_midflap,bird_upflap]
bird_index = 0
bird_surface = bird_frames[bird_index]
bird_rect = bird_surface.get_rect(center = (100,512))

BIRDFLAP = pygame.USEREVENT + 1
pygame.time.set_timer(BIRDFLAP,200)

# bird_surface = pygame.image.load('assets/bluebird-midflap.png').convert_alpha()
# bird_surface = pygame.transform.scale2x(bird_surface)
# bird_rect = bird_surface.get_rect(center = (100,512))

pipe_surface = pygame.image.load('assets/pipe-green.png')
pipe_surface = pygame.transform.scale2x(pipe_surface)
pipe_list = []
SPAWNPIPE = pygame.USEREVENT
pygame.time.set_timer(SPAWNPIPE,1200)
pipe_height = [400,600,800]

game_over_surface = 
pygame.transform.scale2x(pygame.image.load('assets/message.png').convert_alpha())
game_over_rect = game_over_surface.get_rect(center = (288,512))

flap_sound = pygame.mixer.Sound('sound/sfx_wing.wav')
death_sound = pygame.mixer.Sound('sound/sfx_hit.wav')
score_sound = pygame.mixer.Sound('sound/sfx_point.wav')
score_sound_countdown = 100
SCOREEVENT = pygame.USEREVENT + 2
pygame.time.set_timer(SCOREEVENT,100)

while True:
   for event in pygame.event.get():
       if event.type == pygame.QUIT:
           pygame.quit()
           sys.exit()
       if event.type == pygame.KEYDOWN:
           if event.key == pygame.K_SPACE and game_active:
               bird_movement = 0
               bird_movement -= 12
               flap_sound.play()
           if event.key == pygame.K_SPACE and game_active == False:
               game_active = True
               pipe_list.clear()
               bird_rect.center = (100,512)
               bird_movement = 0
               score = 0

       if event.type == SPAWNPIPE:
           pipe_list.extend(create_pipe())

       if event.type == BIRDFLAP:
           if bird_index < 2:
               bird_index += 1
           else:
               bird_index = 0

           bird_surface,bird_rect = bird_animation()

   screen.blit(bg_surface,(0,0))

   if game_active:
       # Bird
       bird_movement += gravity
       rotated_bird = rotate_bird(bird_surface)
       bird_rect.centery += bird_movement
       screen.blit(rotated_bird,bird_rect)
       game_active = check_collision(pipe_list)

       # Pipes
       pipe_list = move_pipes(pipe_list)
       draw_pipes(pipe_list)
    
       # Score
       pipe_score_check()
       score_display('main_game')
   else:
       screen.blit(game_over_surface,game_over_rect)
       high_score = update_score(score,high_score)
       score_display('game_over')
       sql()
    


   # Floor
   floor_x_pos -= 1
   draw_floor()
   if floor_x_pos <= -576:
       floor_x_pos = 0


   pygame.display.update()
   clock.tick(120)

please tell how to solve this. Thank you!

Upvotes: 2

Views: 551

Answers (1)

import random
import random

Reputation: 3245

As commenters have pointed out, calling input() will block your program from processing events, so the operating system will think your program has frozen.

To achieve your goals with minimal redesign, you can incorporate the built-in tkinter dialogs to obtain a user name instead of using input(). The application will still block, but your operating system won't think it is non-responsive.

import tkinter
import tkinter.simpledialog

def prompt_username():
    """Create a Tk file dialog and cleanup when finished"""
    top = tkinter.Tk()
    top.withdraw()  # hide window
    user_name = tkinter.simpledialog.askstring(
        "Name?", "What is your name?", parent=top
    )
    top.destroy()
    return user_name

In your sql() function, replace n=input('enter your name') with n = prompt_username(). Although you could do yourself a favour and use variable names with more than one character.

You'll see a dialog like this:

Username dialog

Check the documentation for more information.

Upvotes: 1

Related Questions