前言
今天給大家把flappybird小游戲重做一遍分享大家,廢話不多說,讓我們愉快的開始~
效果展示

開發工具
Python版本: 3.6.4
相關模塊:
pygame模塊;
以及一些python自帶的模塊,
環境搭建
安裝Python并添加到環境變數,pip安裝需要的相關模塊即可,
原理簡介
首先,我們來寫個開始界面,讓他看起來更像個游戲一些,效果大概是這樣的:

原理也簡單,關鍵點有三個:
(1)下方深綠淺綠交替的地板不斷往左移動來制造小鳥向前飛行的假象;
(2)每過幾幀切換一下小鳥的圖片來實作小鳥翅膀扇動的效果:

(3)有規律地改變小鳥豎直方向上的位置來實作上下移動的效果,
具體而言,代碼實作如下:
'''顯示開始界面'''
def startGame(screen, sounds, bird_images, other_images, backgroud_image, cfg):
base_pos = [0, cfg.SCREENHEIGHT*0.79]
base_diff_bg = other_images['base'].get_width() - backgroud_image.get_width()
msg_pos = [(cfg.SCREENWIDTH-other_images['message'].get_width())/2, cfg.SCREENHEIGHT*0.12]
bird_idx = 0
bird_idx_change_count = 0
bird_idx_cycle = itertools.cycle([0, 1, 2, 1])
bird_pos = [cfg.SCREENWIDTH*0.2, (cfg.SCREENHEIGHT-list(bird_images.values())[0].get_height())/2]
bird_y_shift_count = 0
bird_y_shift_max = 9
shift = 1
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
return {'bird_pos': bird_pos, 'base_pos': base_pos, 'bird_idx': bird_idx}
sounds['wing'].play()
bird_idx_change_count += 1
if bird_idx_change_count % 5 == 0:
bird_idx = next(bird_idx_cycle)
bird_idx_change_count = 0
base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)
bird_y_shift_count += 1
if bird_y_shift_count == bird_y_shift_max:
bird_y_shift_max = 16
shift = -1 * shift
bird_y_shift_count = 0
bird_pos[-1] = bird_pos[-1] + shift
screen.blit(backgroud_image, (0, 0))
screen.blit(list(bird_images.values())[bird_idx], bird_pos)
screen.blit(other_images['message'], msg_pos)
screen.blit(other_images['base'], base_pos)
pygame.display.update()
clock.tick(cfg.FPS)
點擊空格鍵或者↑鍵進入主程式,對于主程式,在進行了必要的初始化作業之后,在游戲開始界面中實作的內容的基礎上,主要還需要實作的內容有以下幾個部分:
(1) 管道和深綠淺綠交替的地板不斷往左移來實作小鳥向前飛行的效果;
(2) 按鍵檢測,當玩家點擊空格鍵或者↑鍵時,小鳥向上做加速度向下的均減速直線運動直至向上的速度衰減為0,否則小鳥做自由落體運動(實作時為了方便,可以認為在極短的時間段內小鳥的運動方式為勻速直線運動);
(3) 碰撞檢測,當小鳥與管道/游戲邊界碰撞到時,游戲失敗并進入游戲結束界面,注意,為了碰撞檢測更精確,我們使用:
pygame.sprite.collide_mask
來代替之前的:
pygame.sprite.collide_rect
(4) 進入游戲后,隨機產生兩對管道,并不斷左移,當最左邊的管道快要因為到達游戲界面的左邊界而消失時,重新生成一對管道(注意不要重復生成);
(5) 當小鳥穿越一個上下管道之間的缺口時,游戲得分加一(注意不要重復記分),
這里簡單貼下主程式的源代碼吧:
# 進入主游戲
score = 0
bird_pos, base_pos, bird_idx = list(game_start_info.values())
base_diff_bg = other_images['base'].get_width() - backgroud_image.get_width()
clock = pygame.time.Clock()
# --管道類
pipe_sprites = pygame.sprite.Group()
for i in range(2):
pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top'))
pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=(cfg.SCREENWIDTH+200+i*cfg.SCREENWIDTH/2, pipe_pos.get('top')[-1])))
pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=(cfg.SCREENWIDTH+200+i*cfg.SCREENWIDTH/2, pipe_pos.get('bottom')[-1])))
# --bird類
bird = Bird(images=bird_images, idx=bird_idx, position=bird_pos)
# --是否增加pipe
is_add_pipe = True
# --游戲是否進行中
is_game_running = True
while is_game_running:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
bird.setFlapped()
sounds['wing'].play()
# --碰撞檢測
for pipe in pipe_sprites:
if pygame.sprite.collide_mask(bird, pipe):
sounds['hit'].play()
is_game_running = False
# --更新小鳥
boundary_values = [0, base_pos[-1]]
is_dead = bird.update(boundary_values, float(clock.tick(cfg.FPS))/1000.)
if is_dead:
sounds['hit'].play()
is_game_running = False
# --移動base實作小鳥往前飛的效果
base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)
# --移動pipe實作小鳥往前飛的效果
flag = False
for pipe in pipe_sprites:
pipe.rect.left -= 4
if pipe.rect.centerx < bird.rect.centerx and not pipe.used_for_score:
pipe.used_for_score = True
score += 0.5
if '.5' in str(score):
sounds['point'].play()
if pipe.rect.left < 5 and pipe.rect.left > 0 and is_add_pipe:
pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top'))
pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=pipe_pos.get('top')))
pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=pipe_pos.get('bottom')))
is_add_pipe = False
elif pipe.rect.right < 0:
pipe_sprites.remove(pipe)
flag = True
if flag: is_add_pipe = True
# --系結必要的元素在螢屏上
screen.blit(backgroud_image, (0, 0))
pipe_sprites.draw(screen)
screen.blit(other_images['base'], base_pos)
showScore(screen, score, number_images)
bird.draw(screen)
pygame.display.update()
clock.tick(cfg.FPS)
游戲結束后,進入游戲界面,沒找到對應的游戲素材,所以只是讓游戲界面靜止了,然后小鳥做自由落體運行直到掉到地面上,代碼實作如下:
'''游戲結束界面'''
def endGame(screen, sounds, showScore, score, number_images, bird, pipe_sprites, backgroud_image, other_images, base_pos, cfg):
sounds['die'].play()
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
return
boundary_values = [0, base_pos[-1]]
bird.update(boundary_values, float(clock.tick(cfg.FPS))/1000.)
screen.blit(backgroud_image, (0, 0))
pipe_sprites.draw(screen)
screen.blit(other_images['base'], base_pos)
showScore(screen, score, number_images)
bird.draw(screen)
pygame.display.update()
clock.tick(cfg.FPS)
再點擊一下空格鍵或者↑鍵即可重新開始游戲,
文章到這里就結束了,感謝你的觀看,Python24個小游戲系列,下篇文章分享重做小恐龍跳一跳小游戲
為了感謝讀者們,我想把我最近收藏的一些編程干貨分享給大家,回饋每一個讀者,希望能幫到你們,
干貨主要有:
① 2000多本Python電子書(主流和經典的書籍應該都有了)
② Python標準庫資料(最全中文版)
③ 專案原始碼(四五十個有趣且經典的練手專案及原始碼)
④ Python基礎入門、爬蟲、web開發、大資料分析方面的視頻(適合小白學習)
⑤ Python學習路線圖(告別不入流的學習)
⑥ 兩天的Python爬蟲訓練營直播權限
All done~私信獲取完整源代碼,,
往期回顧
Python實作升級版坦克大戰小游戲
Python實作掃雷小游戲
Python實作2048小游戲
Python實作五子棋聯機對戰小游戲
Python實作炸彈人小游戲
Python實作經典吃豆豆小游戲
Python實作消消樂小游戲
Python實恐龍跳一跳小游戲現
Python實作簡易版飛機大戰小游戲
Python實作俄羅斯方塊小游戲
Python實作外星人入侵小游戲
Python實作“小兔子和Bun”游戲
Python實作八音符小游戲
Python實作拼圖小游戲
Python實作滑雪小游戲
Python實作經典90坦克大戰
Python實作FlappyBird的小游戲
Python實作塔防小游戲
Python實作接水果和金幣小游戲
Python實作推箱子小游戲
Python實作24點小游戲
Python實作乒乓球小游戲
Python實作打磚塊小游戲
Python實作過迷宮小游戲
Python實作打地鼠小游戲
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/293682.html
標籤:其他
