pygame 200行小遊戲之 FlappyBird

  • 開發準備
    pip install pygame
    新建文件夾將代碼和資源放在一起
  • 功能
  1. 鼠標移出窗口暫停遊戲,移入恢復
  2. 播放我喜歡的背景音樂 Chain Hang Low
  3. 標題欄顯示當前得分,撞柱子時遊戲終止
  • 效果

pygame 200行小遊戲之 FlappyBird的演示

  • 代碼
# -*- coding: UTF-8 -*-

#導入pygame庫
import pygame
#向sys模塊借一個exit函數用來退出程序
from sys import exit
# 導入 random(隨機數) 模塊
import random

FPS = 30 # 幀率
fpsClock = pygame.time.Clock()

#鳥
class Bird(object):
    # 初始化鳥
    def __init__(self, scene):
        # 加載相同張圖片資源,做交替實現地圖滾動
        self.image = pygame.image.load("pygame/bird.png")
        # 保存場景對象
        self.main_scene = scene
        # 尺寸
        self.size_x = 80
        self.size_y = 60
        # 輔助移動地圖
        self.x = 40
        self.y = 120
 
    # 計算鳥繪製座標
    def action(self, jump = 4):
        self.y = self.y + jump
        if self.y > 520 :
            self.y = 520
        if self.y < 0 :
            self.y = 0
 
    # 繪製鳥的圖片
    def draw(self):
        self.main_scene.scene.blit(self.image, (self.x, self.y))

# 地圖
class GameBackground(object):
    # 初始化地圖
    def __init__(self, scene):
        # 加載相同張圖片資源,做交替實現地圖滾動
        self.image1 = pygame.image.load("pygame/background.jpg")
        self.image2 = pygame.image.load("pygame/background.jpg")
        # 保存場景對象
        self.main_scene = scene
        # 輔助移動地圖
        self.x1 = 0
        self.x2 = self.main_scene.size[1]
        self.speed = 4
        # 柱子圖
        self.pillar = pygame.image.load("pygame/pillar.png")
        # 柱子 寬100 長1000 中間空隙200
        self.pillar_nums = 1
        self.pillar_positions_x = [800] 
        self.pillar_positions_y = [-200] 
 
    # 計算地圖圖片繪製座標
    def action(self, addPillar = False):
        # 計算柱子新位置
        for i in range(0, self.pillar_nums):
            self.pillar_positions_x[i] -=  self.speed
        
        if self.pillar_nums > 0 and self.pillar_positions_x[0] + 100 < 0:
            del self.pillar_positions_x[0]
            del self.pillar_positions_y[0]
            self.pillar_nums -= 1

        if addPillar:
            self.pillar_nums += 1
            self.pillar_positions_x.append(800)
            self.pillar_positions_y.append(random.randint(-400, 0)) 

        # 地圖
        self.x1 = self.x1 - self.speed
        self.x2 = self.x2 - self.speed
        if self.x1 <= -self.main_scene.size[1]:
            self.x1 = 0
        if self.x2 <= 0:
            self.x2 = self.main_scene.size[1]
 
    # 繪製地圖
    def draw(self):
        self.main_scene.scene.blit(self.image1, (self.x1, 0))
        self.main_scene.scene.blit(self.image2, (self.x2, 0))
        for i in range(0, self.pillar_nums):
            self.main_scene.scene.blit(self.pillar, (self.pillar_positions_x[i], self.pillar_positions_y[i]))

# 主場景
class MainScene(object):
    # 初始化主場景
    def __init__(self):
        # 場景尺寸
        self.size = (800, 600)
        # 場景對象
        self.scene = pygame.display.set_mode([self.size[0], self.size[1]])
        # 得分
        self.point = 0
        # 設置標題及得分
        pygame.display.set_caption("Flappy Bird v1.0        得分:" + str(int(self.point)))
        # 暫停
        self.pause = False
        # 創建地圖對象
        self.map = GameBackground(self)
        # 創建鳥對象
        self.bird = Bird(self)
        # 輸了嗎
        self.lose = False

    # 繪製
    def draw_elements(self):
        self.map.draw()
        self.bird.draw()
        pygame.display.set_caption("Flappy Bird v1.0      得分:" + str(float('%.2f' % self.point)))
 
    # 動作
    def action_elements(self, addPillar = False):
        self.map.action(addPillar)
        self.bird.action()
 
    # 處理事件
    def handle_event(self):
        for event in pygame.event.get():
            print(event.type)
            if event.type == 12:
                #接收到退出事件後退出程序
                exit()
            elif event.type == 1:
                #光標移出屏幕
                self.pause = True
            elif event.type == 4:
                 #光標移入屏幕
                self.pause = False
            elif event.type == 5:
                self.bird.action(-60)
            else:
                pass
    
    # 碰撞檢測, 碰到返回-1, 過了返回1, 其他0
    def detect_conlision(self):
        # 只要檢查第一個柱子
        if self.map.pillar_positions_x[0] <=  self.bird.size_x + self.bird.x and self.map.pillar_positions_x[0] >= -60:
            if self.map.pillar_positions_y[0] + 400 <  self.bird.y and self.bird.y < self.map.pillar_positions_y[0] + 600:
                if self.map.pillar_positions_x[0] == -60:
                    return 1
            else:
                return -1
        return 0

 
    # 主循環,主要處理各種事件
    def run_scene(self):
        #放段音樂聽
        pygame.mixer.init()
        pygame.mixer.music.load('pygame/Jibbs - Chain Hang Low.mp3')
        pygame.mixer.music.play(-1)
        now = 0
        while True:
            # 處理事件
            self.handle_event()
            # 不暫停
            if self.pause == False and self.lose == False:
                # 計算元素座標
                # 每3秒畫個新柱子
                if now == 90:
                    self.action_elements(True)
                    now = 0
                else:
                    self.action_elements(False)
                    now += 1
                # 繪製元素圖片
                self.draw_elements()
                # 碰撞檢測
                state = self.detect_conlision()
                if state == 1:
                    self.point += 1 
                elif state == -1:
                    pygame.display.set_caption("Flappy Bird v1.0 遊戲終止 得分:" + str(float('%.2f' % self.point))) 
                    self.lose = True
                # 刷新顯示
                pygame.display.update()
                fpsClock.tick(FPS)
 
 
# 入口函數
if __name__ == "__main__":
    # 創建主場景
    mainScene = MainScene()
    # 開始遊戲
    mainScene.run_scene()

  • 素材
    github 知乎同步發佈
    在這裏插入圖片描述
    pillar.png
    在這裏插入圖片描述
    bird.png
    在這裏插入圖片描述backgound.jpg
發佈了42 篇原創文章 · 獲贊 12 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章