Python: Hướng dẫn tạo trò chơi Flappy Bird bằng Pygame
4 Đánh giá
Flappy Bird là một trò chơi quen thuộc và từng tạo nên cơn sốt ở nhiều nơi trên toàn thế giới. Trong trò chơi này, mục tiêu chính của người chơi là đạt được càng nhiều càng tốt, bằng cách bảo vệ chú chim khỏi va chạm vào các chướng ngại vật. Bài viết này sẽ hướng dẫn cách tạo trò chơi Flappy Bird bằng Python, sử dụng thư viện Pygame.
Pygame là một thư viện mã nguồn mở được thiết kế để tạo các trò chơi điện tử. Nó giúp người dùng tạo các trò chơi và chương trình đa phương tiện đầy đủ chức năng trong Python.
Tạo dự án trong Python
Bước 1: Tạo tên dự án.
Đầu tiên, khi hoàn tất cài đặt Pycharm IDE trong máy tính của mình, hãy mở nó, tạo một dự án, nhập tên và nhấn vào nút Create.
Bước 2: Tạo tệp Python.
Sau khi tạo dự án, hãy nhấp chuột phải vào tên dự án của mình, chọn New và nhấn Python file.
Bước 3: Đặt tên cho tệp Python và chọn Enter.
Hướng dẫn tạo trò chơi Flappy Bird bằng Pygame
Bước 1: Cài đặt thư viện Pygame bằng lệnh:
pip install pygame
Bước 2: Thiết lập chiều cao và chiều rộng của màn hình trò chơi. Sau đó, xác định một số hình ảnh sẽ sử dụng trong trò chơi của mình như đường ống làm chướng ngại vật, hình ảnh những con chim và hình nền bối cảnh.
# For generating random height of pipesimport random
import sys
import pygame
from pygame.locals import*# Global Variables for the game
window_width =600
window_height =499# set height and width of window
window = pygame.display.set_mode((window_width, window_height))
elevation = window_height *0.8
game_images ={}
framepersecond =32
pipeimage ='images/pipe.png'
background_image ='images/background.jpg'
birdplayer_image ='/images/bird.png'
sealevel_image ='/images/base.jfif'
Mọi người có thể tải xuống thư mục hình ảnh đầy đủ cần có cho Flappy Bird trong link này.
Bước 3: Sau khi khai báo các biến trò chơi và nhập thư viện, đã đến lúc khởi tạo Pygame.
Khởi tạo chương trình bằng pygame.init () và đặt chú thích của cửa sổ. Ở đây pygame.time.Clock () sẽ được sử dụng thêm trong vòng lặp chính của trò chơi để thay đổi tốc độ của chú chim. Tải hình ảnh từ hệ thống trong Pygame bằng cách sử dụng pygame.image.load ().
# program where the game startsif __name__ =="__main__":# For initializing modules of pygame library
pygame.init()
framepersecond_clock = pygame.time.Clock()# Sets the title on top of game window
pygame.display.set_caption('Flappy Bird Game')# Load all the images which we will use in the game# images for displaying score
game_images['scoreimages']=(
pygame.image.load('images/0.png').convert_alpha(),
pygame.image.load('images/1.png').convert_alpha(),
pygame.image.load('images/2.png').convert_alpha(),
pygame.image.load('images/3.png').convert_alpha(),
pygame.image.load('images/4.png').convert_alpha(),
pygame.image.load('images/5.png').convert_alpha(),
pygame.image.load('images/6.png').convert_alpha(),
pygame.image.load('images/7.png').convert_alpha(),
pygame.image.load('images/8.png').convert_alpha(),
pygame.image.load('images/9.png').convert_alpha())
game_images['flappybird']= pygame.image.load(birdplayer_image).convert_alpha()
game_images['sea_level']= pygame.image.load(sealevel_image).convert_alpha()
game_images['background']= pygame.image.load(background_image).convert_alpha()
game_images['pipeimage']=(pygame.transform.rotate(pygame.image.load(pipeimage).convert_alpha(),180),
pygame.image.load(pipeimage).convert_alpha())print("WELCOME TO THE FLAPPY BIRD GAME")print("Press space or enter to start the game")
Bước 4: Khởi tạo vị trí của chú chim và bắt đầu vòng lặp trò chơi
Khởi tạo vị trí của chim và mực nước biển so với mặt đất. Thêm điều kiện trong vòng lặp xác định các điều kiện trò chơi. Biến chiều ngang và chiều dọc được sử dụng để đặt vị trí của con chim. Chương trình phải chạy cho đến khi người dùng dừng hoặc thoát (sử dụng sys.exit ()) và tạo một vòng lặp while vô hạn.
whileTrue:# sets the coordinates of flappy bird
horizontal = int(window_width/5)
vertical = int((window_height - game_images['flappybird'].get_height())/2)# for selevel
ground =0whileTrue:for event in pygame.event.get():# if user clicks on cross button, close the gameif event.type == QUIT or(event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()# Exit the program
sys.exit()# If the user presses space or up key,# start the game for themelif event.type == KEYDOWN and(event.key == K_SPACE or event.key == K_UP):
flappygame()# if user doesn't press anykey Nothing happenelse:
window.blit(game_images['background'],(0,0))
window.blit(game_images['flappybird'],(horizontal, vertical))
window.blit(game_images['sea_level'],(ground, elevation))# Just Refresh the screen
pygame.display.update()# set the rate of frame per second
framepersecond_clock.tick(framepersecond)
Bước 5: Tạo một hàm tạo để thiết lập đường ống mới có chiều cao ngẫu nhiên.
Trước hết, phải đặt chiều cao của đường ống bằng cách sử dụng hàm getheight (). Sau đó, tạo ra một số ngẫu nhiên từ 0 đến một số bất kỳ (sao cho chiều cao của đường ống có thể điều chỉnh được theo chiều cao cửa sổ trò chơi). Sau đó, tạo một danh sách các từ điển có chứa tọa độ của các đường ống trên và dưới và return nó.
Bước 6: Tạo một hàm GameOver () đại diện cho việc con chim đã rơi trúng ống hay rơi xuống biển.
# Checking if bird is above the sealevel.def isGameOver(horizontal, vertical, up_pipes, down_pipes):if vertical > elevation -25or vertical <0:returnTrue# Checking if bird hits the upper pipe or notfor pipe in up_pipes:
pipeHeight = game_images['pipeimage'][0].get_height()if(vertical < pipeHeight + pipe['y']and abs(horizontal - pipe['x'])< game_images['pipeimage'][0].get_width()):returnTrue# Checking if bird hits the lower pipe or notfor pipe in down_pipes:if(vertical + game_images['flappybird'].get_height()> pipe['y'])and abs(horizontal - pipe['x'])< game_images['pipeimage'][0].get_width():returnTruereturnFalse
Bước 7: Tạo hàm chính (flappygame ()).
Khởi tạo các biến và tạo 2 đường ống bằng hàm createPipe (). Tạo 2 danh sách đầu tiên là các đường ống thấp hơn. Xác định vận tốc chú chim tối đa và tối thiểu.
Xử lý các sự kiện quan trọng bằng cách sử dụng pygame.event.get () và kiểm tra xem trò chơi đã kết thúc hay chưa nếu nó quá thời gian trả về từ hàm. Cập nhật điểm số và hình ảnh trò chơi như nền, đường ống và chim trên cửa sổ.
def flappygame():
your_score =0
horizontal = int(window_width/5)
vertical = int(window_width/2)
ground =0
mytempheight =100# Generating two pipes for blitting on window
first_pipe = createPipe()
second_pipe = createPipe()# List containing lower pipes
down_pipes =[{'x': window_width+300-mytempheight,'y': first_pipe[1]['y']},{'x': window_width+300-mytempheight+(window_width/2),'y': second_pipe[1]['y']},]# List Containing upper pipes
up_pipes =[{'x': window_width+300-mytempheight,'y': first_pipe[0]['y']},{'x': window_width+200-mytempheight+(window_width/2),'y': second_pipe[0]['y']},]
pipeVelX =-4#pipe velocity along x
bird_velocity_y =-9# bird velocity
bird_Max_Vel_Y =10
bird_Min_Vel_Y =-8
birdAccY =1# velocity while flapping
bird_flap_velocity =-8# It is true only when the bird is flapping
bird_flapped =FalsewhileTrue:# Handling the key pressing eventsfor event in pygame.event.get():if event.type == QUIT or(event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()if event.type == KEYDOWN and(event.key == K_SPACE or event.key == K_UP):if vertical >0:
bird_velocity_y = bird_flap_velocity
bird_flapped =True# This function will return true if the flappybird is crashed
game_over = isGameOver(horizontal, vertical, up_pipes, down_pipes)if game_over:return# check for your_score
playerMidPos = horizontal + game_images['flappybird'].get_width()/2for pipe in up_pipes:
pipeMidPos = pipe['x']+ game_images['pipeimage'][0].get_width()/2if pipeMidPos <= playerMidPos < pipeMidPos +4:# Printing the score
your_score +=1print(f"Your your_score is {your_score}")if bird_velocity_y < bird_Max_Vel_Y andnot bird_flapped:
bird_velocity_y += birdAccY
if bird_flapped:
bird_flapped =False
playerHeight = game_images['flappybird'].get_height()
vertical = vertical + min(bird_velocity_y, elevation - vertical - playerHeight)# move pipes to the leftfor upperPipe, lowerPipe in zip(up_pipes, down_pipes):
upperPipe['x']+= pipeVelX
lowerPipe['x']+= pipeVelX
# Add a new pipe when the first is about# to cross the leftmost part of the screenif0< up_pipes[0]['x']<5:
newpipe = createPipe()
up_pipes.append(newpipe[0])
down_pipes.append(newpipe[1])# if the pipe is out of the screen, remove itif up_pipes[0]['x']<-game_images['pipeimage'][0].get_width():
up_pipes.pop(0)
down_pipes.pop(0)# Lets blit our game images now
window.blit(game_images['background'],(0,0))for upperPipe, lowerPipe in zip(up_pipes, down_pipes):
window.blit(game_images['pipeimage'][0],(upperPipe['x'], upperPipe['y']))
window.blit(game_images['pipeimage'][1],(lowerPipe['x'], lowerPipe['y']))
window.blit(game_images['sea_level'],(ground, elevation))
window.blit(game_images['flappybird'],(horizontal, vertical))# Fetching the digits of score.
numbers =[int(x)for x in list(str(your_score))]
width =0# finding the width of score images from numbers.for num in numbers:
width += game_images['scoreimages'][num].get_width()Xoffset=(window_width - width)/1.1# Blitting the images on the window.for num in numbers:
window.blit(game_images['scoreimages'][num],(Xoffset, window_width*0.02))Xoffset+= game_images['scoreimages'][num].get_width()# Refreshing the game window and displaying the score.
pygame.display.update()# Set the framepersecond
framepersecond_clock.tick(framepersecond)
Kết quả đầu ra khi hoàn thành quá trình code game Flappy Bird qua Pygame trong Python
Dưới đây là cách triển khai code game Flappy Bird đầy đủ trong Python bằng Pygame.
# Import moduleimport random
import sys
import pygame
from pygame.locals import*# All the Game Variables
window_width =600
window_height =499# set height and width of window
window = pygame.display.set_mode((window_width, window_height))
elevation = window_height *0.8
game_images ={}
framepersecond =32
pipeimage ='images/pipe.png'
background_image ='images/background.jpg'
birdplayer_image ='images/bird.png'
sealevel_image ='images/base.jfif'def flappygame():
your_score =0
horizontal = int(window_width/5)
vertical = int(window_width/2)
ground =0
mytempheight =100# Generating two pipes for blitting on window
first_pipe = createPipe()
second_pipe = createPipe()# List containing lower pipes
down_pipes =[{'x': window_width+300-mytempheight,'y': first_pipe[1]['y']},{'x': window_width+300-mytempheight+(window_width/2),'y': second_pipe[1]['y']},]# List Containing upper pipes
up_pipes =[{'x': window_width+300-mytempheight,'y': first_pipe[0]['y']},{'x': window_width+200-mytempheight+(window_width/2),'y': second_pipe[0]['y']},]# pipe velocity along x
pipeVelX =-4# bird velocity
bird_velocity_y =-9
bird_Max_Vel_Y =10
bird_Min_Vel_Y =-8
birdAccY =1
bird_flap_velocity =-8
bird_flapped =FalsewhileTrue:for event in pygame.event.get():if event.type == QUIT or(event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()if event.type == KEYDOWN and(event.key == K_SPACE or event.key == K_UP):if vertical >0:
bird_velocity_y = bird_flap_velocity
bird_flapped =True# This function will return true# if the flappybird is crashed
game_over = isGameOver(horizontal,
vertical,
up_pipes,
down_pipes)if game_over:return# check for your_score
playerMidPos = horizontal + game_images['flappybird'].get_width()/2for pipe in up_pipes:
pipeMidPos = pipe['x']+ game_images['pipeimage'][0].get_width()/2if pipeMidPos <= playerMidPos < pipeMidPos +4:
your_score +=1print(f"Your your_score is {your_score}")if bird_velocity_y < bird_Max_Vel_Y andnot bird_flapped:
bird_velocity_y += birdAccY
if bird_flapped:
bird_flapped =False
playerHeight = game_images['flappybird'].get_height()
vertical = vertical + \
min(bird_velocity_y, elevation - vertical - playerHeight)# move pipes to the leftfor upperPipe, lowerPipe in zip(up_pipes, down_pipes):
upperPipe['x']+= pipeVelX
lowerPipe['x']+= pipeVelX
# Add a new pipe when the first is# about to cross the leftmost part of the screenif0< up_pipes[0]['x']<5:
newpipe = createPipe()
up_pipes.append(newpipe[0])
down_pipes.append(newpipe[1])# if the pipe is out of the screen, remove itif up_pipes[0]['x']<-game_images['pipeimage'][0].get_width():
up_pipes.pop(0)
down_pipes.pop(0)# Lets blit our game images now
window.blit(game_images['background'],(0,0))for upperPipe, lowerPipe in zip(up_pipes, down_pipes):
window.blit(game_images['pipeimage'][0],(upperPipe['x'], upperPipe['y']))
window.blit(game_images['pipeimage'][1],(lowerPipe['x'], lowerPipe['y']))
window.blit(game_images['sea_level'],(ground, elevation))
window.blit(game_images['flappybird'],(horizontal, vertical))# Fetching the digits of score.
numbers =[int(x)for x in list(str(your_score))]
width =0# finding the width of score images from numbers.for num in numbers:
width += game_images['scoreimages'][num].get_width()Xoffset=(window_width - width)/1.1# Blitting the images on the window.for num in numbers:
window.blit(game_images['scoreimages'][num],(Xoffset, window_width*0.02))Xoffset+= game_images['scoreimages'][num].get_width()# Refreshing the game window and displaying the score.
pygame.display.update()
framepersecond_clock.tick(framepersecond)def isGameOver(horizontal, vertical, up_pipes, down_pipes):if vertical > elevation -25or vertical <0:returnTruefor pipe in up_pipes:
pipeHeight = game_images['pipeimage'][0].get_height()if(vertical < pipeHeight + pipe['y']and\
abs(horizontal - pipe['x'])< game_images['pipeimage'][0].get_width()):returnTruefor pipe in down_pipes:if(vertical + game_images['flappybird'].get_height()> pipe['y'])and\
abs(horizontal - pipe['x'])< game_images['pipeimage'][0].get_width():returnTruereturnFalsedef createPipe():
offset = window_height/3
pipeHeight = game_images['pipeimage'][0].get_height()
y2 = offset + \
random.randrange(0, int(window_height - game_images['sea_level'].get_height()-1.2* offset))
pipeX = window_width +10
y1 = pipeHeight - y2 + offset
pipe =[# upper Pipe{'x': pipeX,'y':-y1},# lower Pipe{'x': pipeX,'y': y2}]return pipe
# program where the game startsif __name__ =="__main__":# For initializing modules of pygame library
pygame.init()
framepersecond_clock = pygame.time.Clock()# Sets the title on top of game window
pygame.display.set_caption('Flappy Bird Game')# Load all the images which we will use in the game# images for displaying score
game_images['scoreimages']=(
pygame.image.load('images/0.png').convert_alpha(),
pygame.image.load('images/1.png').convert_alpha(),
pygame.image.load('images/2.png').convert_alpha(),
pygame.image.load('images/3.png').convert_alpha(),
pygame.image.load('images/4.png').convert_alpha(),
pygame.image.load('images/5.png').convert_alpha(),
pygame.image.load('images/6.png').convert_alpha(),
pygame.image.load('images/7.png').convert_alpha(),
pygame.image.load('images/8.png').convert_alpha(),
pygame.image.load('images/9.png').convert_alpha())
game_images['flappybird']= pygame.image.load(
birdplayer_image).convert_alpha()
game_images['sea_level']= pygame.image.load(
sealevel_image).convert_alpha()
game_images['background']= pygame.image.load(
background_image).convert_alpha()
game_images['pipeimage']=(pygame.transform.rotate(pygame.image.load(
pipeimage).convert_alpha(),180), pygame.image.load(
pipeimage).convert_alpha())print("WELCOME TO THE FLAPPY BIRD GAME")print("Press space or enter to start the game")# Here starts the main gamewhileTrue:# sets the coordinates of flappy bird
horizontal = int(window_width/5)
vertical = int((window_height - game_images['flappybird'].get_height())/2)
ground =0whileTrue:for event in pygame.event.get():# if user clicks on cross button, close the gameif event.type == QUIT or(event.type == KEYDOWN and \
event.key == K_ESCAPE):
pygame.quit()
sys.exit()# If the user presses space or# up key, start the game for themelif event.type == KEYDOWN and(event.key == K_SPACE or\
event.key == K_UP):
flappygame()# if user doesn't press anykey Nothing happenelse:
window.blit(game_images['background'],(0,0))
window.blit(game_images['flappybird'],(horizontal, vertical))
window.blit(game_images['sea_level'],(ground, elevation))
pygame.display.update()
framepersecond_clock.tick(framepersecond)