基於Pygame實現谷歌瀏覽器的恐龍快跑小遊戲(Python)

其實前段時間就寫完這個了,但是沒有什麼時間寫博客,因爲現在正好在複習python的一些東西,可以寫一下博客來複習梳理一下整個遊戲的流程。

1.效果展示

在這裏插入圖片描述

2.實現主窗體

先從最主要的開始入手,做一個遊戲的窗體,因爲導入了pygame,感覺在python中做一個小遊戲比Java中更加容易做。可以直接設置FPS什麼的,很方便。
下面是窗體部分實現代碼


import pygame
from pygame.locals import *  # 導入pygame中的常量

SCREENWIDTH = 822
SCREENHEIGHT = 260
FPS = 30  # 更新畫面的時間


def mainGame():
    global SCREEN, FPSCLOCK
    pygame.init()    # 使用pygame前先初始化
    # 要使用pygame時鐘,先創建clock對象的實例
    # 用於控制每個循環多長時間運行一次
    FPSCLOCK = pygame.time.Clock()
    # 先創建一個窗體
    SCREEN = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))
    pygame.display.set_caption('恐龍快跑')
    while True:
        #  判斷是否單擊關閉了窗體
        for event in pygame.event.get():
            # 單擊關閉窗體就關閉窗體
            if event.type == QUIT:
                exit()  # 關閉窗體
        pygame.display.update()  # 更新整個窗體
        FPSCLOCK.tick(FPS)  # 循環多久運行一次


if __name__ == '__main__':
    mainGame()

我們可以看下運行效果
在這裏插入圖片描述

3.遊戲背景的滾動

恐龍快跑的遊戲背景滾動其實是恐龍沒有動,背景一直在動,這一點和飛機大戰是一樣的,所以實現原理也是一樣,總共有兩張圖片,第一張圖片放完後就放第二張,第二張圖片放完後繼續放第一張。這個和我以前寫的飛機大戰的繪製背景是一樣的,在飛機大戰裏面有畫圖解釋,鏈接如下:
飛機大戰博客鏈接

先創建一個地圖類

class Map():

    def __init__(self, x, y):
        # 背景圖片加載
        self.bg = pygame.image.load("images/bg.png").convert_alpha()
        self.x = x
        self.y = y

    def map_move(self):
        if self.x < -790:  # 已經移動完畢
            self.x = 800   # 再次開始
        else:
            self.x -= 5  # 一次左移動5個像素點

    def map_update(self):
        SCREEN.blit(self.bg, (self.x, self.y))

當遊戲開始後,因爲地圖要移動,所以先在mainGame()定義兩張背景圖片的初始位置,然後在mainGame()的while True循環裏面加入地圖的更新
代碼如下:

 # 創建地圖對象
    bg1 = Map(0, 0)
    bg2 = Map(800, 0)

 if over == False:
            bg1.map_update()
            bg1.map_move()
            bg2.map_update()
            bg2.map_move()

實現效果如下:
在這裏插入圖片描述

3.加入恐龍圖片和加入鍵盤監聽實現恐龍跳躍動作

在實現完背景圖片的移動之後,我們應該考慮把恐龍的圖片加進來了,並且加上鍵盤監聽器,比如當按下空格鍵時實現恐龍的跳躍動作。
我們首先設置一個恐龍類,代碼如下:

class Dragon():
    def __init__(self):
        self.rect = pygame.Rect(0, 0, 0, 0)  # 小恐龍矩形圖片的初始化,Rect(left,top,width,height)
        self.jumpHeight = 130
        self.jumpState = False  # 跳躍狀態,true爲跳躍
        self.lowest_y = 140  # 最低座標
        self.jumpValue = 0  # 跳躍增變量

        # 小恐龍跳躍動作播放圖片,連續放三張圖片,造成一種gif的感覺
        self.DragonIndex = 0
        self.DragonIndexGen = cycle([0, 1, 2])  # 引入的迭代工具

        # 加載恐龍圖片,使用convert_alpha()背景圖片才爲透明,用convert則爲黑色背景
        self.dragon_img = (
            pygame.image.load("images/dargon1.png").convert_alpha(),
            pygame.image.load("images/dargon2.png").convert_alpha(),
            pygame.image.load("images/dargon3.png").convert_alpha(),
        )

        self.rect.size = self.dragon_img[0].get_size()
        self.x = 50  # 繪製恐龍x座標
        self.y = self.lowest_y  # 繪製恐龍y座標
        self.rect.topleft = (self.x, self.y)

    def jump(self):
        self.jumpState = True
        print("jump方法正在執行")

    def move(self):
        if  self.jumpState== True:  # 起跳的時候
            if self.rect.y >= self.lowest_y:
                self.jumpValue = -5  # 向上移動五個像素點
            if self.rect.y <= self.lowest_y - self.jumpHeight:  # 到頂後下降
                self.jumpValue = 5
            self.rect.y += self.jumpValue
            if self.rect.y >= self.lowest_y:  # 恐龍落地以後,跳躍狀態改爲False
                self.jumpState = False

    def draw(self):
        # 匹配恐龍動圖
        DragonIndex = next(self.DragonIndexGen)

        # 繪製小恐龍,blit()第一個爲圖片,第二個參數爲位置
        SCREEN.blit(self.dragon_img[DragonIndex], (self.x, self.rect.y))

因爲恐龍一直在原地,所以並沒有x軸上的移動,跳躍也只是在y軸上移動一下。只有背景圖片一直在動
效果如下:
在這裏插入圖片描述

4.障礙物的實現

遊戲的規則是恐龍越過障礙物就加一分,如果碰到障礙物則死亡,可以選擇重開遊戲,所以我們接下來要做的是障礙物的隨機出現。
和恐龍一樣,我們先建一個Obstacle障礙物類,然後實現Obstacle的move,draw方法。
代碼如下:


class Obstacle():
    def __init__(self):
        # 初始化障礙物矩形
        self.rect = pygame.Rect(0, 0, 0, 0)
        # 加載障礙物圖片
        self.stone = pygame.image.load("images/stone.png").convert_alpha()
        self.cacti = pygame.image.load("images/cacti.png").convert_alpha()
        # 生成0到1的隨機數
        r = random.randint(0, 1)
        if r == 0:  # 隨機數爲0則爲石頭,1爲仙人掌
            self.image = self.stone
        else:
            self.image = self.cacti

        # 根據障礙物位圖的寬和高來顯示仙人掌
        self.rect.size = self.image.get_size()

        # 獲取圖片寬高
        self.width, self.height = self.rect.size

        # 繪製障礙物的座標
        self.x = 800
        self.y = 200 - (self.height / 2)
        # self.y = 200
        self.rect.center = (self.x, self.y)

    def move(self):
        self.rect.x -= 5

    def draw(self):
        SCREEN.blit(self.image, (self.rect.x, self.rect.y))

然後我們在mainGame()的whileTrue裏面加入障礙物出現的時間和概率的判斷,並在whileTrue裏面調用Obstacle的move和draw方法

            if addObstacleTimer >= 1000:
                r = random.randint(0, 100)
                if r > 40:
                    # 創建障礙物對象
                    obstacle = Obstacle()
                    # 添加到列表
                    list.append(obstacle)
                # 重置時間,到下一次出現障礙物
                addObstacleTimer = 0

            # 循環遍歷障礙物
            for i in range(len(list)):
                # 障礙物移動與繪製
                list[i].move()
                list[i].draw()

        addObstacleTimer += 20

實現效果如下:
在這裏插入圖片描述

5.碰撞判斷

在上面的效果展示我們可以發現,恐龍碰到障礙物以後並沒有發生預料中的遊戲結束,因爲我們還沒有加入對碰撞的判斷,所以我們現在可以加入對碰撞的判斷過程。
我們可以直接在whileTrue裏面加入對碰撞的判斷

 # 判斷與障礙物是否碰撞
                if pygame.sprite.collide_rect(dragon, list[i]):
                    over = True
                    game_over()

可以發現如果碰撞發生,則遊戲結束,但是我們這裏調用的game_over()方法還沒有開始寫,所以還需要寫一個game_over()方法。

def game_over():
    # 獲取窗體寬度和高
    screen_w = pygame.display.Info().current_w
    screen_h = pygame.display.Info().current_h
    # 加載遊戲結束的圖片
    over_img = pygame.image.load("images/gameover.png").convert_alpha()
    # 遊戲結束的圖片控制在窗體的中間位置
    SCREEN.blit(over_img, ((screen_w - over_img.get_width()) / 2,
                (screen_h - over_img.get_height()) / 2))

這下就大功告成了,大家可以看下效果圖
在這裏插入圖片描述

6.分數的顯示

遊戲做到這裏基本已經結束了,但是我們可以再增加一個分數顯示的功能,當恐龍躍過一個障礙時就加一分。所以我們先實現一個獲取分數getScore()和顯示分數showScore()的方法

    def getScore(self):
        tmp = self.score
        self.score = 0
        return tmp

    def showScore(self, score):
        # 在窗體頂部中間的位置顯示分數
        self.scoreDigits = [int(x) for x in list(str(score))]
        totalWidth = 0  # 要顯示所有數字的總寬度
        for digit in self.scoreDigits:
            # 獲取積分圖片的寬度
            totalWidth += self.numbers[digit].get_width()
        # 分數橫向位置
        Xoffset = (SCREENWIDTH - totalWidth) / 2
        for digit in self.scoreDigits:
            # 繪製分數
            SCREEN.blit(self.numbers[digit], (Xoffset, SCREENHEIGHT * 0.1))
            # 數字增加也改變位置
            Xoffset += self.numbers[digit].get_width()

並且需要在是否碰撞的判斷加上一個else,如果沒有碰到的話,則加分

 # 判斷與障礙物是否碰撞
                if pygame.sprite.collide_rect(dragon, list[i]):
                    over = True
                    game_over()
                else:
                    if(list[i].rect.x + list[i].rect.width) < dragon.rect.x:
                        score += list[i].getScore()

                # 顯示分數
                list[i].showScore(score)

遊戲到這裏就整體就完成啦,下面是效果圖
在這裏插入圖片描述

有需要整份代碼的可以留郵箱。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章