国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Python課程設(shè)計 基于python的俄羅斯方塊小游戲

這篇具有很好參考價值的文章主要介紹了Python課程設(shè)計 基于python的俄羅斯方塊小游戲。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

基于python的俄羅斯方塊小游戲

目錄

基于python的俄羅斯方塊小游戲

1.概述

1.1 摘要

1.2 開發(fā)背景

1.3 開發(fā)環(huán)境

1.4 實現(xiàn)功能

2.代碼描述

2.1 模塊導(dǎo)入

2.2 初始化變量

2.3 播放音樂

2.4 創(chuàng)建方塊類

2.5?繪制游戲地圖

2.6?游戲初始化

2.7?繪制有邊框矩形

2.8 繪制我的文字

2.9?游戲主體

2.10?主程序運行

3.運行效果

4.注意事項

5.附錄源碼


1.概述

1.1 摘要

本文介紹了一個基于Python語言開發(fā)的簡單俄羅斯方塊小游戲。該游戲使用了pygame庫來實現(xiàn)圖形界面和聲音效果,并通過面向?qū)ο蟮脑O(shè)計方法來組織代碼。游戲的主要功能包括方塊的隨機生成、移動、旋轉(zhuǎn)、消除行以及得分計算等。游戲界面簡潔直觀,音效增強了游戲體驗。此外,游戲還提供了音樂開關(guān)和游戲暫停的功能,以增加游戲的可玩性和用戶友好性。

1.2 開發(fā)背景

俄羅斯方塊是一款經(jīng)典的益智游戲,自上世紀(jì)80年代推出以來一直備受歡迎。隨著計算機技術(shù)的不斷發(fā)展,越來越多的開發(fā)者嘗試將這款游戲移植到各種平臺上。Python作為一種易學(xué)易用且功能強大的編程語言,非常適合用于開發(fā)小游戲。同時,pygame庫提供了豐富的圖形、聲音和事件處理功能,使得開發(fā)過程更加便捷。

1.3 開發(fā)環(huán)境

Windows 11系統(tǒng)

pycharm 2021

python 3.9

1.4 實現(xiàn)功能

1.方塊生成與顯示:游戲會根據(jù)預(yù)設(shè)的方塊類型隨機生成一個新的方塊,并在游戲界面的頂部顯示。

2.方塊移動與旋轉(zhuǎn):玩家可以通過鍵盤控制方塊的左右移動和順時針/逆時針旋轉(zhuǎn)。

3.消除行與得分:當(dāng)玩家將一行方塊填滿時,該行會消除并給玩家加分。消除的行數(shù)越多,得分越高。

4.游戲結(jié)束條件:當(dāng)方塊堆積到游戲界面的頂部時,游戲結(jié)束。

5.音效與音樂:游戲中有方塊下落、消除行等音效,同時提供了開啟/關(guān)閉背景音樂的選項。

6.游戲暫停與恢復(fù):玩家可以隨時暫停游戲并在之后恢復(fù),方便玩家在需要時暫時離開。

7.等級與速度:隨著游戲的進行,方塊的生成速度會逐漸加快,增加游戲難度。

2.代碼描述

2.1 模塊導(dǎo)入

import pygame
from pygame.locals import *
from sys import exit
import random

分析:

1.pygame: 一個用于制作游戲的Python庫。

2.pygame.locals: 從pygame庫中導(dǎo)入的常量集合。

3.sys: Python標(biāo)準(zhǔn)庫中的模塊,用于與Python解釋器交互。

4.random: 用于生成隨機數(shù)。

2.2 初始化變量

# 使用pygame.init()初始化pygame庫
pygame.init()

# 常量
MAX_I = 34
MAX_J = 15
# 定義地圖的最大行數(shù)和列數(shù)
SIZE = 15
# 方塊的大小

COLORS = [(0, 0, 0), (255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 255, 255)]
# 一個顏色列表,用于表示不同的方塊
gameMap = [[0 for j in range(MAX_J + 3)] for i in range(MAX_I + 3)]
# 一個二維列表,代表游戲地圖。初始化為全0,表示沒有方塊。
tetrisHeight = 0
# 記錄當(dāng)前塔的高度,即已放下的方塊行數(shù)
tetrises = [
    [
        [1, 0, 0, 0],
        [1, 0, 0, 0],
        [1, 0, 0, 0],
        [1, 0, 0, 0]
    ],
    [
        [0, 0, 0, 0],
        [0, 1, 1, 0],
        [0, 1, 1, 0],
        [0, 0, 0, 0]
    ],
    [
        [1, 0, 0, 0],
        [1, 1, 0, 0],
        [0, 1, 0, 0],
        [0, 0, 0, 0]
    ],
    [
        [0, 1, 0, 0],
        [1, 1, 0, 0],
        [1, 0, 0, 0],
        [0, 0, 0, 0]
    ],
    [
        [0, 1, 0, 0],
        [1, 1, 1, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ],
    [
        [1, 0, 0, 0],
        [1, 1, 1, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ],
    [
        [0, 0, 1, 0],
        [1, 1, 1, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
]
# 一個列表,包含7種不同的基本方塊形狀。每個形狀都是一個二維列表,表示方塊的各個部分。
# 分?jǐn)?shù)
score = 0
# 等級
level = 1
# 音樂開關(guān)
isMusic = True
# 游戲暫停
isPause = False

分析:

此代碼段只是游戲的初始化部分,沒有包含游戲的主循環(huán)、方塊的移動、旋轉(zhuǎn)、消除行以及得分等邏輯。但從這段代碼中,我們可以看出這是一個俄羅斯方塊游戲的基礎(chǔ)框架,接下來的代碼會包含游戲的主體邏輯和界面渲染等部分。

2.3 播放音樂

def playMyMusic(src):
    if isMusic:
        sound = pygame.mixer.Sound(src)
        sound.play()

分析:

這個函數(shù)接收一個參數(shù)src,這個參數(shù)應(yīng)該是音樂文件的路徑。如果isMusic變量為True(意味著音樂功能是開啟的),那么函數(shù)會加載音樂文件并播放它。這里使用了pygame.mixer.Sound來加載聲音文件,并調(diào)用play方法來播放聲音。

2.4 創(chuàng)建方塊類

2.4.1 定義私有屬性

class Tetris:
    __i = 0
    __j = 0
    __color = 0
    __nextColor = 0
    __nextType = 0

分析:?

1.__i: 方塊的行位置。

2.__j: 方塊的列位置。

3.__color: 方塊的顏色。

4.__nextColor: 下一個方塊的顏色。

5.__nextType: 下一個方塊的類型。

2.4.2??構(gòu)造函數(shù)__init__

這個構(gòu)造函數(shù)在創(chuàng)建Tetris類的實例時被調(diào)用。它初始化下一個方塊的顏色和類型,并調(diào)用createTetris方法來創(chuàng)建當(dāng)前的方塊。

    def __init__(self):
        self.__nextColor = random.randint(0, 3) + 1  # 一共四種顏色
        self.__nextType = random.randint(0, 6)  # 一共七種類型
        self.createTetris()

2.4.3 createTetris方法

    def createTetris(self):
        # 根據(jù)類型調(diào)整一下快出現(xiàn)的位置
        if self.__nextType == 0:
            self.__i = 1
            self.__j = 7
        else:
            self.__i = 2
            self.__j = 6
        self.__color = self.__nextColor

        # 根據(jù)方塊模板,放置整個到地圖
        for i in range(4):
            for j in range(4):
                if tetrises[self.__nextType][i][j] == 1:
                    if gameMap[self.__i + i][self.__j + j] == 0:
                        gameMap[self.__i + i][self.__j + j] = self.__color
                    else:
                        print('游戲失?。?)
                        exit()
                        return -1

        # 產(chǎn)生下一種類型和顏色
        self.__nextColor = random.randint(0, 3) + 1  # 一共四種顏色
        self.__nextType = random.randint(0, 6)  # 一共七種類型

        playMyMusic('music/get.wav')

分析:

該段代碼的主要功能是創(chuàng)建一個新的俄羅斯方塊(Tetris)并將其放置在游戲地圖上。以下是代碼的主要功能概述:

確定方塊的初始位置:根據(jù)方塊的類型(self.__nextType),代碼確定了方塊在游戲地圖上的初始位置(self.__i 和 self.__j)。不同的方塊類型可能需要不同的起始位置。

設(shè)置方塊的顏色:將方塊的顏色設(shè)置為下一個可用的顏色(self.__nextColor)。顏色是通過一個隨機數(shù)生成的,確保每種顏色都有可能被選中。

放置方塊到游戲地圖:通過兩個嵌套的循環(huán),代碼遍歷方塊的每個格子。如果方塊模板中的某個格子值為1(表示該格子被填充),則檢查游戲地圖中對應(yīng)的位置是否為空(值為0)。如果為空,則在該位置放置方塊(即將該位置的值設(shè)置為方塊的顏色)。如果對應(yīng)位置已經(jīng)被其他方塊占據(jù),則輸出“游戲失??!”并退出游戲。

生成下一種方塊類型和顏色:在成功放置當(dāng)前方塊后,代碼生成下一種方塊的類型和顏色。這是通過隨機數(shù)生成器實現(xiàn)的,確保每次生成的方塊類型和顏色都是隨機的。

播放音效:放置方塊后,播放一個音效文件('music/get.wav'),為玩家提供反饋。

總的來說,這段代碼是俄羅斯方塊游戲中生成和放置新方塊的關(guān)鍵部分,它負責(zé)處理方塊的初始位置、顏色、放置邏輯以及生成下一種方塊。

    def moveDown(self):
        global gameMap

        # 判斷是否可以下移
        for j in range(4):
            for i in range(3, -1, -1):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    # 判斷是否到底
                    if self.__i + i + 1 > MAX_I:
                        return 1

                    # 判斷前面是否有東西
                    if gameMap[self.__i + i + 1][self.__j + j] != 0:
                        return 1

                    break

        # 下移
        for j in range(4):
            for i in range(3, -1, -1):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    gameMap[self.__i + i][self.__j + j], gameMap[self.__i + i + 1][self.__j + j] = \
                        gameMap[self.__i + i + 1][self.__j + j], gameMap[self.__i + i][self.__j + j]

        self.__i += 1

分析:

該段代碼的主要功能是處理俄羅斯方塊游戲中方塊的下移操作。以下是代碼的主要功能概述:

判斷是否可以下移:通過兩個嵌套的循環(huán)遍歷方塊的每個格子,檢查當(dāng)前方塊是否可以下移。首先,它檢查方塊是否已經(jīng)到達地圖的底部(即是否超過了最大行數(shù)MAX_I),如果是,則不能下移,函數(shù)返回1。其次,它檢查方塊的下方是否有其他方塊占據(jù),如果有,則不能下移,函數(shù)同樣返回1。

執(zhí)行下移操作:如果上述檢查都通過,說明方塊可以下移,代碼將執(zhí)行下移操作。通過另一個兩個嵌套的循環(huán)遍歷方塊的每個格子,找到當(dāng)前方塊的每個格子,并將其與其下方的對應(yīng)格子交換位置。這實際上是將整個方塊向下移動了一行。

更新方塊位置:在成功執(zhí)行下移操作后,代碼更新方塊的__i屬性值,將其增加1,以反映方塊在游戲地圖中的新位置。

這個函數(shù)的目的是處理方塊的下移邏輯,包括檢查是否可以下移、執(zhí)行下移操作以及更新方塊的位置。它是俄羅斯方塊游戲中控制方塊移動的重要部分。

    def stopTetris(self):
        global tetrisHeight

        flag = True

        for i in range(4):
            for j in range(4):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    gameMap[self.__i + i][self.__j + j] += 10

                    # 找到第一個顏色方塊
                    if flag:
                        tetrisHeight = MAX_I - self.__i if tetrisHeight < MAX_I - self.__i else tetrisHeight
                        flag = False

        self.deleteRow()

?分析:

該段代碼的主要功能是停止當(dāng)前正在下落的俄羅斯方塊,并對其進行處理。以下是代碼的主要功能概述:

標(biāo)記方塊停止?fàn)顟B(tài):首先,代碼通過遍歷當(dāng)前方塊的每個格子,將其顏色值增加10,以標(biāo)記這些格子屬于已經(jīng)停止下落的方塊。這樣做通常是為了在游戲地圖上區(qū)分正在下落和已經(jīng)停止的方塊。

確定方塊高度:在標(biāo)記方塊的過程中,代碼還查找并記錄了當(dāng)前方塊的最高位置(即方塊中最頂部的行索引)。這是通過比較當(dāng)前方塊最高行與全局變量tetrisHeight的值來完成的,確保tetrisHeight始終存儲當(dāng)前游戲地圖中最高的方塊高度。

刪除完整行:在標(biāo)記完方塊并確定了其高度后,代碼調(diào)用deleteRow函數(shù)來檢查并刪除游戲地圖中的完整行。這是俄羅斯方塊游戲中的一個重要機制,當(dāng)玩家堆疊的方塊形成完整的一行時,該行會被消除,并為玩家?guī)矸謹(jǐn)?shù)和可能的等級提升。

總的來說,這段代碼負責(zé)在方塊停止下落時對其進行處理,包括標(biāo)記方塊狀態(tài)、確定方塊高度以及觸發(fā)行消除機制。這是俄羅斯方塊游戲中管理方塊狀態(tài)和控制游戲邏輯的關(guān)鍵部分。

    def moveLeft(self):
        # 判斷是否能夠左移
        for i in range(4):
            for j in range(4):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    if self.__j + j - 1 < 0:
                        return 1
                    if gameMap[self.__i + i][self.__j + j - 1] != 0:
                        return 1

                    break

        # 左移
        for i in range(4):
            for j in range(4):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    gameMap[self.__i + i][self.__j + j], gameMap[self.__i + i][self.__j + j - 1] = \
                        gameMap[self.__i + i][self.__j + j - 1], gameMap[self.__i + i][self.__j + j]

        self.__j -= 1

分析:

該段代碼的主要功能是處理俄羅斯方塊游戲中方塊的左移操作。以下是代碼的主要功能概述:

判斷是否可以左移:代碼首先通過兩個嵌套的循環(huán)遍歷方塊的每個格子,檢查當(dāng)前方塊是否可以向左移動。它首先檢查方塊的左側(cè)是否有足夠的空間(即是否超出了地圖的左邊界),如果是,則不能左移,函數(shù)返回1。其次,它檢查方塊的左側(cè)是否有其他方塊占據(jù),如果有,則不能左移,函數(shù)同樣返回1。

執(zhí)行左移操作:如果上述檢查都通過,說明方塊可以左移,代碼將執(zhí)行左移操作。通過另一個兩個嵌套的循環(huán)遍歷方塊的每個格子,找到當(dāng)前方塊的每個格子,并將其與其左側(cè)的對應(yīng)格子交換位置。這實際上是將整個方塊向左移動了一列。

更新方塊位置:在成功執(zhí)行左移操作后,代碼更新方塊的__j屬性值,將其減少1,以反映方塊在游戲地圖中的新位置。

這個函數(shù)的目的是處理方塊的左移邏輯,包括檢查是否可以左移、執(zhí)行左移操作以及更新方塊的位置。它是俄羅斯方塊游戲中控制方塊移動的重要部分。


    def moveRight(self):
        # 判斷是否能右移
        for i in range(4):
            for j in range(3, -1, -1):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    if self.__j + j + 1 >= MAX_J:
                        return 1
                    if gameMap[self.__i + i][self.__j + j + 1] != 0:
                        return 1

                    break

        # 右移
        for i in range(4):
            for j in range(3, -1, -1):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    gameMap[self.__i + i][self.__j + j], gameMap[self.__i + i][self.__j + j + 1] = \
                        gameMap[self.__i + i][self.__j + j + 1], gameMap[self.__i + i][self.__j + j]

        self.__j += 1

分析:

該段代碼的主要功能是處理俄羅斯方塊游戲中方塊的右移操作。以下是代碼的主要功能概述:

判斷是否可以右移:代碼首先通過兩個嵌套的循環(huán)遍歷方塊的每個格子,檢查當(dāng)前方塊是否可以向右移動。它首先檢查方塊的右側(cè)是否有足夠的空間(即是否超出了地圖的右邊界),如果是,則不能右移,函數(shù)返回1。其次,它檢查方塊的右側(cè)是否有其他方塊占據(jù),如果有,則不能右移,函數(shù)同樣返回1。

執(zhí)行右移操作:如果上述檢查都通過,說明方塊可以右移,代碼將執(zhí)行右移操作。通過另一個兩個嵌套的循環(huán)遍歷方塊的每個格子,找到當(dāng)前方塊的每個格子,并將其與其右側(cè)的對應(yīng)格子交換位置。這實際上是將整個方塊向右移動了一列。

更新方塊位置:在成功執(zhí)行右移操作后,代碼更新方塊的__j屬性值,將其增加1,以反映方塊在游戲地圖中的新位置。

這個函數(shù)的目的是處理方塊的右移邏輯,包括檢查是否可以右移、執(zhí)行右移操作以及更新方塊的位置。它是俄羅斯方塊游戲中控制方塊移動的重要部分。與左移操作類似,但方向相反。

    def change(self):
        tMap = [[0 for j in range(4)] for i in range(4)]

        # 將所有方塊順時針旋轉(zhuǎn)90度賦值到 tMap 中
        i = 0
        k = 3
        while i < 4:
            for j in range(4):
                if MAX_I > self.__i + j >= 0 and MAX_J > self.__j + k >= 0 and gameMap[self.__i + j][
                    self.__j + k] == 0 or \
                        gameMap[self.__i + j][self.__j + k] == self.__color:
                    tMap[j][k] = gameMap[self.__i + i][self.__j + j]

                else:
                    return

            i += 1
            k -= 1

        # 賦值
        for i in range(4):
            for j in range(4):
                gameMap[self.__i + i][self.__j + j] = tMap[i][j]

        playMyMusic('music/change.wav')

分析:

該段代碼的主要功能是改變(旋轉(zhuǎn))當(dāng)前方塊的狀態(tài),具體來說是將方塊順時針旋轉(zhuǎn)90度。以下是代碼的主要功能概述:

創(chuàng)建臨時地圖:首先,代碼創(chuàng)建了一個名為tMap的4x4二維列表,用于存儲旋轉(zhuǎn)后的方塊狀態(tài)。這個列表初始時所有元素都為0。

順時針旋轉(zhuǎn)方塊:接下來,代碼通過兩個嵌套的循環(huán)來實現(xiàn)方塊的順時針旋轉(zhuǎn)。外部循環(huán)控制旋轉(zhuǎn)的行,內(nèi)部循環(huán)控制旋轉(zhuǎn)的列。在循環(huán)中,代碼檢查原始方塊(在gameMap中)的每個格子,如果該格子為空(值為0)或者與當(dāng)前方塊的顏色相同,則將其值復(fù)制到tMap中相應(yīng)的位置。如果遇到任何障礙物(即非空且顏色不同的格子),旋轉(zhuǎn)操作將立即停止,并返回(不執(zhí)行任何旋轉(zhuǎn))。

更新游戲地圖:如果旋轉(zhuǎn)操作成功完成(即沒有遇到障礙物),代碼將tMap中的新狀態(tài)復(fù)制回gameMap,從而更新游戲地圖中方塊的位置和狀態(tài)。

播放音效:最后,代碼調(diào)用playMyMusic函數(shù)播放一個名為'change.wav'的音效文件,為玩家提供旋轉(zhuǎn)操作的反饋。

總的來說,這個函數(shù)的作用是改變當(dāng)前方塊的方向,將其順時針旋轉(zhuǎn)90度,并更新游戲地圖以反映這一變化。如果旋轉(zhuǎn)過程中遇到障礙物,則不會進行任何更改。

    def deleteRow(self):
        # 找到有方塊的最后一行
        lastRow = 0
        t = False
        for i in range(3, -1, -1):
            for j in range(4):
                if gameMap[self.__i + i][self.__j + j] == self.__color + 10:
                    lastRow = self.__i + i
                    t = True
                    break
            if t:
                break

        for i in range(lastRow, MAX_I - tetrisHeight - 1, -1):
            for j in range(MAX_J):
                if gameMap[i][j] == 0:
                    break
            else:
                global score
                score += 10
                playMyMusic('music/delete.wav')

                # 刪除行
                gameMap.pop(i)
                gameMap.insert(0, [0 for j in range(MAX_J + 3)])

                # 增加等級
                global level
                level += score // 1000

                # 再次調(diào)用刪除行函數(shù)操作刪行
                self.deleteRow()

分析:

該段代碼的主要功能是刪除俄羅斯方塊游戲中由玩家堆疊形成的完整行,并處理相應(yīng)的得分和等級提升。以下是代碼的主要功能概述:

找到有方塊的最后一行:代碼首先通過兩個嵌套的循環(huán)遍歷當(dāng)前方塊及其下方的行,查找最下方有方塊的行(即最頂層的完整行)。它檢查每個格子的值是否等于當(dāng)前方塊的顏色值加10(這是標(biāo)記已停止方塊的方式)。一旦找到這樣的格子,就記錄下其所在的行號,并跳出循環(huán)。

刪除完整行:接下來,代碼從最后一行開始向上遍歷游戲地圖。對于每一行,它檢查該行是否所有格子都非空(即該行是一個完整行)。如果找到一個完整行,它將執(zhí)行以下操作:

  • 增加玩家得分(通常增加10分)。
  • 播放一個音效文件('delete.wav'),為玩家提供反饋。
  • 從游戲地圖中移除該完整行。這是通過將該行從列表中移除(gameMap.pop(i))并在列表的開頭插入一個新行(所有格子都為空)來實現(xiàn)的。
  • 更新玩家的等級。這是通過將玩家的得分除以1000并向上取整來實現(xiàn)的,每1000分提升一個等級。

遞歸調(diào)用:在刪除一行后,代碼會再次調(diào)用自身(self.deleteRow()),以檢查是否由于刪除行而形成了新的完整行。這是必要的,因為在某些情況下,刪除一行可能會導(dǎo)致上方的多行也成為完整行。遞歸調(diào)用將繼續(xù)進行,直到?jīng)]有新的完整行可以刪除為止。

這個函數(shù)的目的是處理玩家堆疊形成的完整行,給予玩家相應(yīng)的得分,并更新游戲狀態(tài),包括游戲地圖、玩家得分和等級。它是俄羅斯方塊游戲中的重要機制之一,用于管理游戲進程和玩家表現(xiàn)。

    def nextTetris(self):
        return self.__nextType, self.__nextColor


# 全局變量
screen = ''  # 屏幕
gameTetris = Tetris()

分析:

該方法用于返回下一個方塊的類型和顏色。它返回兩個私有成員變量:self.__nextType?和?self.__nextColor。這兩個變量通常在類的其他部分被設(shè)置,表示下一個將要出現(xiàn)的方塊的類型(形狀)和顏色。

此外,代碼還定義了一個全局變量?screen,它被初始化為空字符串。這個變量可能用于表示游戲的屏幕或顯示界面,但在這段代碼中并沒有進一步的使用或說明。

另一個全局變量?gameTetris?是?Tetris?類的一個實例。Tetris?類可能包含了俄羅斯方塊游戲的所有邏輯和狀態(tài)信息,但由于代碼中并沒有給出?Tetris?類的具體實現(xiàn),所以無法確定其具體的功能和結(jié)構(gòu)。通常,這樣的類會包含游戲的狀態(tài)(如當(dāng)前方塊、下一個方塊、游戲地圖、得分等),以及控制游戲進程的方法(如開始新游戲、移動方塊、旋轉(zhuǎn)方塊、刪除行等)。

2.5?繪制游戲地圖

# 繪制游戲地圖
def drawMap():
    # 畫上邊框
    for i in range(MAX_I - 4):
        # 畫右邊
        myRect(screen, COLORS[2], [0, i * SIZE, SIZE, SIZE])
        # 畫左邊
        myRect(screen, COLORS[2], [(MAX_J + 1) * SIZE, i * SIZE, SIZE, SIZE])

    # 畫下面
    for i in range(MAX_J + 2):
        myRect(screen, COLORS[2], [i * SIZE, (MAX_I - 4) * SIZE, SIZE, SIZE])

    # 給地圖涂色
    for i in range(4, MAX_I):
        for j in range(MAX_J):
            t = gameMap[i][j] - 10 if gameMap[i][j] > 10 else gameMap[i][j]

            myRect(screen, COLORS[t], [(j + 1) * SIZE, (i - 4) * SIZE, SIZE, SIZE])

    # 文字內(nèi)容,下一個方塊
    drawMyText(screen, "下一塊:", 305, 18, 15, (255, 255, 255))

    # 繪制下一塊方塊
    startX = 270
    startY = 30

    nextType, nextColor = gameTetris.nextTetris()

    # 顯示下一個方塊的背景
    pygame.draw.rect(screen, COLORS[5], [startX, startY, SIZE * 4, SIZE * 4], 1)
    mySize = SIZE * 0.8  # 縮小下一個方塊大小

    # 根據(jù)形狀,修改方塊的位置(居中)
    if nextType == 0:
        startX += (SIZE * 4 - mySize) / 2
        startY += (SIZE * 4 - mySize * 4) / 2
    elif nextType == 2 or nextType == 3:
        startX += (SIZE * 4 - mySize * 2) / 2
        startY += (SIZE * 4 - mySize * 3) / 2
    elif nextType == 4 or nextType == 5 or nextType == 6:
        startX += (SIZE * 4 - mySize * 3) / 2
        startY += (SIZE * 4 - mySize * 2) / 2
    elif nextType == 1:
        startX += (SIZE * 4 - mySize * 4) / 2
        startY += (SIZE * 4 - mySize * 4) / 2

    # 繪制下一個方塊
    for i in range(4):
        for j in range(4):
            # 繪制有圖形地方
            if tetrises[nextType][i][j] == 1:
                # 根據(jù)不同的
                myRect(screen, COLORS[nextColor], [startX + j * mySize, startY + i * mySize, mySize, mySize])

    color = (255, 0, 0)
    # 繪制分?jǐn)?shù)
    scoreText = "分?jǐn)?shù):{}".format(score)
    drawMyText(screen, scoreText, 300, 120, 15, color)

    # 等級
    drawMyText(screen, "等級:{}".format(level), 300, 140, 15, color)

    color = (255, 0, 255)
    # 繪制音樂
    textMusic = "音樂:"

    if isMusic:
        textMusic += "開"
    else:
        textMusic += '關(guān)'

    drawMyText(screen, textMusic, 300, 220, 15, color)

    # 繪制游戲暫停
    textPause = "暫停:"

    if isPause:
        textPause += "開"
    else:
        textPause += '關(guān)'

    drawMyText(screen, textPause, 300, 240, 15, color)


    # 繪制鍵值
    color = (130, 205, 255)
    drawMyText(screen, "↑ 旋轉(zhuǎn)90度", 300, 300, 15, color)
    drawMyText(screen, "← 向左移動", 300, 320, 15, color)
    drawMyText(screen, "→ 向右移動", 300, 340, 15, color)
    drawMyText(screen, "↓ 快速向下", 300, 360, 15, color)

    # 繪制背景
    startY = 410
    color = (255, 255, 0)
    flower = "★"
    drawMyText(screen, flower, 300, startY + 0, 15, color)
    flower = "★★"
    drawMyText(screen, flower, 300, startY + 20, 15, color)
    flower = "★★★"
    drawMyText(screen, flower, 300, startY + 40, 15, color)

分析:

該段代碼的主要功能是繪制俄羅斯方塊游戲的游戲地圖和界面上的其他元素。具體來說,它執(zhí)行以下操作:

繪制游戲地圖邊框:首先,代碼通過循環(huán)繪制了游戲地圖的上、下、左、右四個邊框。這些邊框使用了一個特定的顏色(COLORS[2]),并且根據(jù)游戲地圖的尺寸(MAX_I?和?MAX_J)來確定位置和大小。

填充游戲地圖:接下來,代碼遍歷游戲地圖的每個格子,并根據(jù)格子的值(gameMap[i][j])來填充相應(yīng)的顏色。如果格子的值大于10,則減去10來獲取正確的顏色索引,因為游戲可能使用額外的值來表示特殊狀態(tài)(如方塊停止下落)。

繪制下一個方塊:代碼從gameTetris實例中獲取下一個方塊的類型(nextType)和顏色(nextColor)。然后,它繪制一個表示下一個方塊的背景框,并根據(jù)下一個方塊的形狀調(diào)整其內(nèi)部小方塊的位置。不同的方塊類型有不同的形狀,因此代碼通過條件語句來確定如何繪制每個小方塊。

繪制文本信息:代碼還繪制了界面上的文本信息,包括“下一塊:”來提示玩家下一個方塊即將出現(xiàn),以及玩家的“分?jǐn)?shù)”和“等級”。這些信息使用特定的顏色和字體大小繪制在屏幕上。

繪制音樂圖標(biāo):最后,代碼繪制了一個表示音樂的圖標(biāo)(盡管代碼中并沒有實際繪制圖標(biāo)的操作,只是預(yù)留了位置)。

2.6?游戲初始化

# 游戲初始化
def initGame():
    # 將地圖倒數(shù)對大行全部賦值為-1
    for j in range(MAX_J):
        gameMap[MAX_I][j] = -1

    # 將地圖倒數(shù)最大列全部賦值為-1
    for i in range(MAX_I):
        gameMap[i][MAX_J] = -1

    # 分?jǐn)?shù)初始化
    score = 0

    # 加載背景音樂文件
    pygame.mixer.music.load('music/bgm.mp3')

    if isMusic:
        # 播放背景音樂,第一個參數(shù)為播放的次數(shù)(-1表示無限循環(huán)),第二個參數(shù)是設(shè)置播放的起點(單位為秒)
        pygame.mixer.music.play(-1, 0.0)

分析:

該段代碼的主要功能是初始化俄羅斯方塊游戲。具體來說,它執(zhí)行了以下操作:

設(shè)置游戲地圖的邊緣:代碼通過兩個循環(huán)將游戲地圖的邊緣格子(即最底部和最右側(cè)的格子)設(shè)置為-1。這通常表示這些格子不屬于游戲區(qū)域,或者不可用于放置方塊。

初始化分?jǐn)?shù):將玩家的分?jǐn)?shù)(score)設(shè)置為0,表示游戲開始時玩家沒有獲得任何分?jǐn)?shù)。

加載并播放背景音樂:代碼使用pygame模塊的mixer組件加載一個名為'bgm.mp3'的背景音樂文件。如果isMusic變量為True(表示允許播放音樂),則音樂將開始播放,并且設(shè)置為無限循環(huán)(-1表示循環(huán)播放),從音樂的開頭(0.0秒處)開始播放。

這段代碼是俄羅斯方塊游戲初始化過程的一部分,確保游戲在開始時有正確的設(shè)置和配置,包括游戲地圖的邊緣定義、玩家分?jǐn)?shù)的初始值,以及背景音樂的加載和播放。這些初始化步驟是游戲能夠正常運行所必需的。

2.7?繪制有邊框矩形

def myRect(screen, colorRect, pos, lineColor=COLORS[0], bold=1):
    pygame.draw.rect(screen, colorRect, pos)
    pygame.draw.rect(screen, lineColor, pos, bold)

分析:

該函數(shù)?myRect?的主要功能是在游戲屏幕(screen)上繪制一個矩形。它接受以下參數(shù):

  • screen:這是一個pygame的Surface對象,通常代表游戲的主屏幕或窗口。
  • colorRect:這是矩形的填充顏色,通常是一個RGB元組,如?(255, 255, 255)?表示白色。
  • pos:這是一個包含矩形位置和大小的元組,格式為?(x, y, width, height)。
  • lineColor:這是一個可選參數(shù),用于指定矩形邊框的顏色。如果沒有提供,則默認為?COLORS[0]。
  • bold:這是一個可選參數(shù),用于指定矩形邊框的寬度。如果沒有提供,則默認為1。

函數(shù)內(nèi)部調(diào)用了兩次?pygame.draw.rect?方法。第一次調(diào)用繪制了填充了顏色的矩形,第二次調(diào)用繪制了矩形的邊框。通過這種方式,myRect?函數(shù)能夠在一個步驟中同時繪制矩形的填充和邊框。

需要注意的是,pygame.draw.rect?方法的第四個參數(shù)通常用于指定線條的粗細(邊框?qū)挾龋?。在這個函數(shù)中,當(dāng)?bold?參數(shù)被傳遞時,它會被用作?pygame.draw.rect?方法的第四個參數(shù)。如果?bold?參數(shù)未被傳遞或設(shè)置為1,則邊框?qū)挾葘⒛J為1。

2.8 繪制我的文字

# 繪制我的文字
def drawMyText(screen, text, x, y, bold, fColor, bColor=None):
    # 通過字體文件獲得字體對象
    fontObj = pygame.font.Font('font/SIMYOU.TTF', bold)

    # 配置要顯示的文字
    textSurfaceObj = fontObj.render(text, False, fColor, bColor)

    # 獲得要顯示的對象的rect
    textRectObj = textSurfaceObj.get_rect()

    # 設(shè)置顯示對象的坐標(biāo)
    textRectObj.center = (x, y)

    # 繪制字體
    screen.blit(textSurfaceObj, textRectObj)

分析:

獲取字體對象:使用pygame.font.Font函數(shù)和一個指定的字體文件(在這里是'font/SIMYOU.TTF')以及字體大?。ㄓ?code>bold參數(shù)指定)來創(chuàng)建一個字體對象。

渲染文本:使用字體對象的render方法來創(chuàng)建一個文本Surface對象。這個方法需要文本字符串、一個布爾值(在這里是False,表示文本不是抗鋸齒的)、前景色和可選的背景色。

獲取文本矩形:通過調(diào)用文本Surface對象的get_rect方法來獲取一個矩形對象,這個矩形代表了文本在屏幕上占據(jù)的空間。

設(shè)置文本坐標(biāo):將文本矩形的中心坐標(biāo)設(shè)置為函數(shù)參數(shù)中指定的xy坐標(biāo)。

繪制文本:最后,使用screen.blit方法將文本Surface對象繪制到屏幕上的指定位置。

2.9?游戲主體

def my_game():
    # 得到屏幕
    global screen, isMusic, isPause
    screen = pygame.display.set_mode((350, 465))

    # 設(shè)置標(biāo)題
    pygame.display.set_caption('俄羅斯方塊')

    # 初始化游戲
    initGame()

    # 用于控制下落速度
    count = 0

    while True:

        if count == 3 + level * 2:
            if not isPause:  # 只有暫停是 False 才能下移
                if gameTetris.moveDown() == 1:
                    gameTetris.stopTetris()
                    gameTetris.createTetris()

            count = 0

        # 事件判斷
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                # 停止播放背景音樂
                pygame.mixer.music.stop()

                pygame.quit()
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 控制音樂開關(guān)
                if 270 < event.pos[0] < 330 and 210 < event.pos[1] < 225:
                    # 處理音樂開關(guān)
                    if isMusic:
                        # 停止播放背景音樂
                        pygame.mixer.music.stop()
                    else:
                        # 播放背景音樂,第一個參數(shù)為播放的次數(shù)(-1表示無限循環(huán)),第二個參數(shù)是設(shè)置播放的起點(單位為秒)
                        pygame.mixer.music.play(-1, 0.0)

                    isMusic = not isMusic

                # 處理游戲暫停開關(guān)
                if 270 < event.pos[0] < 327 and 233 < event.pos[1] < 248:
                    isPause = not isPause

                    if isPause:
                        pygame.display.set_caption('俄羅斯方塊:已暫停')
                    else:
                        pygame.display.set_caption('俄羅斯方塊')

            elif event.type == pygame.KEYDOWN:
                if event.key == K_UP:
                    gameTetris.change()

        keyPressList = pygame.key.get_pressed()

        if keyPressList[K_DOWN]:
            gameTetris.moveDown()
        elif keyPressList[K_LEFT]:
            gameTetris.moveLeft()
        elif keyPressList[K_RIGHT]:
            gameTetris.moveRight()

        screen.fill((0, 0, 0))
        drawMap()
        pygame.display.update()
        count += 1

        pygame.time.Clock().tick(10)

分析:

該函數(shù)?my_game?是俄羅斯方塊游戲的主函數(shù),它負責(zé)初始化游戲、處理用戶輸入和事件、更新游戲狀態(tài)以及渲染游戲畫面。以下是該函數(shù)的主要功能:

初始化游戲:首先,它設(shè)置了一個全局的屏幕對象?screen?和一些全局變量(如?isMusic?和?isPause)。然后,它調(diào)用?initGame?函數(shù)來初始化游戲,包括設(shè)置游戲地圖的邊緣、初始化分?jǐn)?shù)以及加載并可能播放背景音樂。

控制下落速度:通過一個計數(shù)器?count?來控制方塊的下落速度。當(dāng)計數(shù)器達到一定的值時(由當(dāng)前游戲級別?level?決定),如果游戲沒有暫停(isPause?為?False),則嘗試將當(dāng)前方塊下移一格。如果下移成功,則停止當(dāng)前方塊的下落并創(chuàng)建一個新的方塊。

事件處理:函數(shù)使用一個循環(huán)來處理pygame事件。這些事件可能包括用戶點擊關(guān)閉按鈕(退出游戲)、點擊鼠標(biāo)(控制音樂的播放和暫停以及游戲的暫停和繼續(xù))、以及按下鍵盤鍵(旋轉(zhuǎn)方塊)。

  • 當(dāng)用戶點擊關(guān)閉按鈕時,停止播放背景音樂并退出游戲。
  • 當(dāng)用戶在特定的屏幕區(qū)域內(nèi)點擊鼠標(biāo)時,切換音樂的播放狀態(tài)或游戲的暫停狀態(tài)。
  • 當(dāng)用戶按下鍵盤上的上箭頭鍵時,旋轉(zhuǎn)當(dāng)前方塊。

鍵盤輸入處理:函數(shù)還檢查是否有鍵盤鍵被按下,并據(jù)此移動方塊。如果下箭頭鍵被持續(xù)按下,方塊會持續(xù)下移;如果左或右箭頭鍵被按下,方塊會向左或向右移動。

渲染游戲畫面:最后,函數(shù)使用黑色填充屏幕,并調(diào)用?drawMap?函數(shù)來繪制游戲地圖和方塊。這一步通常在每次循環(huán)的末尾進行,以確保游戲畫面能夠?qū)崟r更新。

2.10?主程序運行

if __name__ == '__main__':
    my_game()

詳細分析一下:

在Python中,if __name__ == '__main__':?是一個常見的代碼塊,用于判斷當(dāng)前腳本是否作為主程序運行。如果當(dāng)前腳本是作為主程序直接運行的,而不是被其他腳本導(dǎo)入作為一個模塊,那么?__name__?這個內(nèi)置變量就會被設(shè)置為?'__main__'。

在你提供的代碼片段中,if __name__ == '__main__':?這一行之后緊跟著調(diào)用了?my_game()?函數(shù)。這意味著,只有當(dāng)這個腳本被直接運行時,my_game()?函數(shù)才會被執(zhí)行。如果這個腳本被其他腳本導(dǎo)入作為一個模塊,那么?my_game()?函數(shù)將不會自動執(zhí)行。

這樣做的好處是,你可以在一個文件中既定義函數(shù)和類(用于在其他腳本中導(dǎo)入和使用),又包含一些只在當(dāng)前腳本直接運行時才需要執(zhí)行的代碼(比如啟動游戲的主函數(shù))。

總結(jié)來說,if __name__ == '__main__':?這一行用于區(qū)分直接運行和模塊導(dǎo)入兩種情況,并據(jù)此決定是否執(zhí)行某些代碼。在你提供的代碼中,它確保了?my_game()?函數(shù)只有在該腳本被直接運行時才會被執(zhí)行。

3.運行效果

Python課程設(shè)計 基于python的俄羅斯方塊小游戲,數(shù)據(jù)分析與數(shù)據(jù)可視化,python,課程設(shè)計,pygame,python,pip,pandas,numpy

4.注意事項

1.所有的代碼放到同一個py文件中

2.在數(shù)據(jù)可視化過程中,難免會需要導(dǎo)入不同的庫,這里建議使用WIN+R打開命令提示符,并使用國內(nèi)鏡像安裝庫(下載快),比如安裝wordcloud庫是,使用下列代碼:

pip install wordcloud -i https://pypi.tuna.tsinghua.edu.cn/simple/

這里用的是清華的鏡像,其他鏡像:

企業(yè)貢獻:

(1)網(wǎng)易開源鏡像站:http://mirrors.163.com/

(2)華為開源鏡像站:https://mirrors.huaweicloud.com/

(3)阿里開源鏡像站:https://developer.aliyun.com/mirror/

大學(xué)教學(xué):

(1)清華大學(xué)開源鏡像站:https://mirrors.tuna.tsinghua.edu.cn/

(2)浙江大學(xué)開源鏡像站:http://mirrors.zju.edu.cn/

(3)東北大學(xué)開源鏡像站:http://mirror.neu.edu.cn/

安裝庫的時候,建議更新一下你的pip庫,命令:

python -m pip install --upgrade pip

游戲窗口的創(chuàng)建和初始化:你需要使用Pygame庫創(chuàng)建一個游戲窗口,并設(shè)置其寬度、高度、標(biāo)題等屬性。你還需要初始化一些Pygame模塊,如pygame.init()來初始化所有導(dǎo)入的Pygame模塊。

游戲循環(huán):游戲的核心是一個循環(huán),通常稱為游戲主循環(huán)或事件循環(huán)。在這個循環(huán)中,你需要處理用戶輸入(如鍵盤按鍵、鼠標(biāo)點擊等)、更新游戲狀態(tài)(如方塊的位置、得分等)和繪制游戲界面。

方塊的繪制和移動:你需要定義方塊的形狀和顏色,并在游戲窗口中繪制它們。你還需要實現(xiàn)方塊的移動功能,包括旋轉(zhuǎn)、左右移動和下落。你可能需要使用鍵盤事件來捕捉用戶的輸入,并根據(jù)輸入更新方塊的位置。

消除行和得分:當(dāng)方塊下落并填滿一行時,你需要實現(xiàn)消除行的功能,并相應(yīng)地更新得分。這可能需要你檢查每一行是否已經(jīng)填滿,如果是,則消除該行并增加得分。

游戲結(jié)束條件:你需要設(shè)置游戲結(jié)束的條件,如當(dāng)方塊堆積到游戲窗口的頂部時,游戲結(jié)束。在游戲結(jié)束時,你可以顯示一條消息或彈出一個對話框來通知玩家。

5.附錄源碼

import pygame
from pygame.locals import *
from sys import exit
import random

# 使用pygame.init()初始化pygame庫
pygame.init()

# 常量
MAX_I = 34
MAX_J = 15
# 定義地圖的最大行數(shù)和列數(shù)
SIZE = 15
# 方塊的大小

COLORS = [(0, 0, 0), (255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 255, 255)]
# 一個顏色列表,用于表示不同的方塊
gameMap = [[0 for j in range(MAX_J + 3)] for i in range(MAX_I + 3)]
# 一個二維列表,代表游戲地圖。初始化為全0,表示沒有方塊。
tetrisHeight = 0
# 記錄當(dāng)前塔的高度,即已放下的方塊行數(shù)

tetrises = [
    [
        [1, 0, 0, 0],
        [1, 0, 0, 0],
        [1, 0, 0, 0],
        [1, 0, 0, 0]
    ],
    [
        [0, 0, 0, 0],
        [0, 1, 1, 0],
        [0, 1, 1, 0],
        [0, 0, 0, 0]
    ],
    [
        [1, 0, 0, 0],
        [1, 1, 0, 0],
        [0, 1, 0, 0],
        [0, 0, 0, 0]
    ],
    [
        [0, 1, 0, 0],
        [1, 1, 0, 0],
        [1, 0, 0, 0],
        [0, 0, 0, 0]
    ],
    [
        [0, 1, 0, 0],
        [1, 1, 1, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ],
    [
        [1, 0, 0, 0],
        [1, 1, 1, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ],
    [
        [0, 0, 1, 0],
        [1, 1, 1, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
]
# 一個列表,包含7種不同的基本方塊形狀。每個形狀都是一個二維列表,表示方塊的各個部分。
# 分?jǐn)?shù)
score = 0
# 等級
level = 1
# 音樂開關(guān)
isMusic = True
# 游戲暫停
isPause = False


# 播放音樂
def playMyMusic(src):
    if isMusic:
        sound = pygame.mixer.Sound(src)
        sound.play()


# 方塊類
class Tetris:
    __i = 0
    __j = 0
    __color = 0
    __nextColor = 0
    __nextType = 0

    def __init__(self):
        self.__nextColor = random.randint(0, 3) + 1  # 一共四種顏色
        self.__nextType = random.randint(0, 6)  # 一共七種類型
        self.createTetris()

    def createTetris(self):
        # 根據(jù)類型調(diào)整一下快出現(xiàn)的位置
        if self.__nextType == 0:
            self.__i = 1
            self.__j = 7
        else:
            self.__i = 2
            self.__j = 6
        self.__color = self.__nextColor

        # 根據(jù)方塊模板,放置整個到地圖
        for i in range(4):
            for j in range(4):
                if tetrises[self.__nextType][i][j] == 1:
                    if gameMap[self.__i + i][self.__j + j] == 0:
                        gameMap[self.__i + i][self.__j + j] = self.__color
                    else:
                        print('游戲失敗!')
                        exit()
                        return -1

        # 產(chǎn)生下一種類型和顏色
        self.__nextColor = random.randint(0, 3) + 1  # 一共四種顏色
        self.__nextType = random.randint(0, 6)  # 一共七種類型

        playMyMusic('music/get.wav')

    def moveDown(self):
        global gameMap

        # 判斷是否可以下移
        for j in range(4):
            for i in range(3, -1, -1):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    # 判斷是否到底
                    if self.__i + i + 1 > MAX_I:
                        return 1

                    # 判斷前面是否有東西
                    if gameMap[self.__i + i + 1][self.__j + j] != 0:
                        return 1

                    break

        # 下移
        for j in range(4):
            for i in range(3, -1, -1):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    gameMap[self.__i + i][self.__j + j], gameMap[self.__i + i + 1][self.__j + j] = \
                        gameMap[self.__i + i + 1][self.__j + j], gameMap[self.__i + i][self.__j + j]

        self.__i += 1

    def stopTetris(self):
        global tetrisHeight

        flag = True

        for i in range(4):
            for j in range(4):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    gameMap[self.__i + i][self.__j + j] += 10

                    # 找到第一個顏色方塊
                    if flag:
                        tetrisHeight = MAX_I - self.__i if tetrisHeight < MAX_I - self.__i else tetrisHeight
                        flag = False

        self.deleteRow()

    def moveLeft(self):
        # 判斷是否能夠左移
        for i in range(4):
            for j in range(4):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    if self.__j + j - 1 < 0:
                        return 1
                    if gameMap[self.__i + i][self.__j + j - 1] != 0:
                        return 1

                    break

        # 左移
        for i in range(4):
            for j in range(4):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    gameMap[self.__i + i][self.__j + j], gameMap[self.__i + i][self.__j + j - 1] = \
                        gameMap[self.__i + i][self.__j + j - 1], gameMap[self.__i + i][self.__j + j]

        self.__j -= 1

    def moveRight(self):
        # 判斷是否能右移
        for i in range(4):
            for j in range(3, -1, -1):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    if self.__j + j + 1 >= MAX_J:
                        return 1
                    if gameMap[self.__i + i][self.__j + j + 1] != 0:
                        return 1

                    break

        # 右移
        for i in range(4):
            for j in range(3, -1, -1):
                if gameMap[self.__i + i][self.__j + j] == self.__color:
                    gameMap[self.__i + i][self.__j + j], gameMap[self.__i + i][self.__j + j + 1] = \
                        gameMap[self.__i + i][self.__j + j + 1], gameMap[self.__i + i][self.__j + j]

        self.__j += 1

    def change(self):
        tMap = [[0 for j in range(4)] for i in range(4)]

        # 將所有方塊順時針旋轉(zhuǎn)90度賦值到 tMap 中
        i = 0
        k = 3
        while i < 4:
            for j in range(4):
                if MAX_I > self.__i + j >= 0 and MAX_J > self.__j + k >= 0 and gameMap[self.__i + j][
                    self.__j + k] == 0 or \
                        gameMap[self.__i + j][self.__j + k] == self.__color:
                    tMap[j][k] = gameMap[self.__i + i][self.__j + j]

                else:
                    return

            i += 1
            k -= 1

        # 賦值
        for i in range(4):
            for j in range(4):
                gameMap[self.__i + i][self.__j + j] = tMap[i][j]

        playMyMusic('music/change.wav')

    def deleteRow(self):
        # 找到有方塊的最后一行
        lastRow = 0
        t = False
        for i in range(3, -1, -1):
            for j in range(4):
                if gameMap[self.__i + i][self.__j + j] == self.__color + 10:
                    lastRow = self.__i + i
                    t = True
                    break
            if t:
                break

        for i in range(lastRow, MAX_I - tetrisHeight - 1, -1):
            for j in range(MAX_J):
                if gameMap[i][j] == 0:
                    break
            else:
                global score
                score += 10
                playMyMusic('music/delete.wav')

                # 刪除行
                gameMap.pop(i)
                gameMap.insert(0, [0 for j in range(MAX_J + 3)])

                # 增加等級
                global level
                level += score // 1000

                # 再次調(diào)用刪除行函數(shù)操作刪行
                self.deleteRow()

    def nextTetris(self):
        return self.__nextType, self.__nextColor


# 全局變量
screen = ''  # 屏幕
gameTetris = Tetris()


# 繪制游戲地圖
def drawMap():
    # 畫上邊框
    for i in range(MAX_I - 4):
        # 畫右邊
        myRect(screen, COLORS[2], [0, i * SIZE, SIZE, SIZE])
        # 畫左邊
        myRect(screen, COLORS[2], [(MAX_J + 1) * SIZE, i * SIZE, SIZE, SIZE])

    # 畫下面
    for i in range(MAX_J + 2):
        myRect(screen, COLORS[2], [i * SIZE, (MAX_I - 4) * SIZE, SIZE, SIZE])

    # 給地圖涂色
    for i in range(4, MAX_I):
        for j in range(MAX_J):
            t = gameMap[i][j] - 10 if gameMap[i][j] > 10 else gameMap[i][j]

            myRect(screen, COLORS[t], [(j + 1) * SIZE, (i - 4) * SIZE, SIZE, SIZE])

    # 文字內(nèi)容,下一個方塊
    drawMyText(screen, "下一塊:", 305, 18, 15, (255, 255, 255))

    # 繪制下一塊方塊
    startX = 270
    startY = 30

    nextType, nextColor = gameTetris.nextTetris()

    # 顯示下一個方塊的背景
    pygame.draw.rect(screen, COLORS[5], [startX, startY, SIZE * 4, SIZE * 4], 1)
    mySize = SIZE * 0.8  # 縮小下一個方塊大小

    # 根據(jù)形狀,修改方塊的位置(居中)
    if nextType == 0:
        startX += (SIZE * 4 - mySize) / 2
        startY += (SIZE * 4 - mySize * 4) / 2
    elif nextType == 2 or nextType == 3:
        startX += (SIZE * 4 - mySize * 2) / 2
        startY += (SIZE * 4 - mySize * 3) / 2
    elif nextType == 4 or nextType == 5 or nextType == 6:
        startX += (SIZE * 4 - mySize * 3) / 2
        startY += (SIZE * 4 - mySize * 2) / 2
    elif nextType == 1:
        startX += (SIZE * 4 - mySize * 4) / 2
        startY += (SIZE * 4 - mySize * 4) / 2

    # 繪制下一個方塊
    for i in range(4):
        for j in range(4):
            # 繪制有圖形地方
            if tetrises[nextType][i][j] == 1:
                # 根據(jù)不同的
                myRect(screen, COLORS[nextColor], [startX + j * mySize, startY + i * mySize, mySize, mySize])

    color = (255, 0, 0)
    # 繪制分?jǐn)?shù)
    scoreText = "分?jǐn)?shù):{}".format(score)
    drawMyText(screen, scoreText, 300, 120, 15, color)

    # 等級
    drawMyText(screen, "等級:{}".format(level), 300, 140, 15, color)

    color = (255, 0, 255)
    # 繪制音樂
    textMusic = "音樂:"

    if isMusic:
        textMusic += "開"
    else:
        textMusic += '關(guān)'

    drawMyText(screen, textMusic, 300, 220, 15, color)

    # 繪制游戲暫停
    textPause = "暫停:"

    if isPause:
        textPause += "開"
    else:
        textPause += '關(guān)'

    drawMyText(screen, textPause, 300, 240, 15, color)


    # 繪制鍵值
    color = (130, 205, 255)
    drawMyText(screen, "↑ 旋轉(zhuǎn)90度", 300, 300, 15, color)
    drawMyText(screen, "← 向左移動", 300, 320, 15, color)
    drawMyText(screen, "→ 向右移動", 300, 340, 15, color)
    drawMyText(screen, "↓ 快速向下", 300, 360, 15, color)

    # 繪制背景
    startY = 410
    color = (255, 255, 0)
    flower = "★"
    drawMyText(screen, flower, 300, startY + 0, 15, color)
    flower = "★★"
    drawMyText(screen, flower, 300, startY + 20, 15, color)
    flower = "★★★"
    drawMyText(screen, flower, 300, startY + 40, 15, color)


# 游戲初始化
def initGame():
    # 將地圖倒數(shù)對大行全部賦值為-1
    for j in range(MAX_J):
        gameMap[MAX_I][j] = -1

    # 將地圖倒數(shù)最大列全部賦值為-1
    for i in range(MAX_I):
        gameMap[i][MAX_J] = -1

    # 分?jǐn)?shù)初始化
    score = 0

    # 加載背景音樂文件
    pygame.mixer.music.load('music/bgm.mp3')

    if isMusic:
        # 播放背景音樂,第一個參數(shù)為播放的次數(shù)(-1表示無限循環(huán)),第二個參數(shù)是設(shè)置播放的起點(單位為秒)
        pygame.mixer.music.play(-1, 0.0)


# 繪制有邊框矩形
def myRect(screen, colorRect, pos, lineColor=COLORS[0], bold=1):
    pygame.draw.rect(screen, colorRect, pos)
    pygame.draw.rect(screen, lineColor, pos, bold)


# 繪制我的文字
def drawMyText(screen, text, x, y, bold, fColor, bColor=None):
    # 通過字體文件獲得字體對象
    fontObj = pygame.font.Font('font/SIMYOU.TTF', bold)

    # 配置要顯示的文字
    textSurfaceObj = fontObj.render(text, False, fColor, bColor)

    # 獲得要顯示的對象的rect
    textRectObj = textSurfaceObj.get_rect()

    # 設(shè)置顯示對象的坐標(biāo)
    textRectObj.center = (x, y)

    # 繪制字體
    screen.blit(textSurfaceObj, textRectObj)


# 游戲主體
def my_game():
    # 得到屏幕
    global screen, isMusic, isPause
    screen = pygame.display.set_mode((350, 465))

    # 設(shè)置標(biāo)題
    pygame.display.set_caption('俄羅斯方塊')

    # 初始化游戲
    initGame()

    # 用于控制下落速度
    count = 0

    while True:

        if count == 3 + level * 2:
            if not isPause:  # 只有暫停是 False 才能下移
                if gameTetris.moveDown() == 1:
                    gameTetris.stopTetris()
                    gameTetris.createTetris()

            count = 0

        # 事件判斷
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                # 停止播放背景音樂
                pygame.mixer.music.stop()

                pygame.quit()
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 控制音樂開關(guān)
                if 270 < event.pos[0] < 330 and 210 < event.pos[1] < 225:
                    # 處理音樂開關(guān)
                    if isMusic:
                        # 停止播放背景音樂
                        pygame.mixer.music.stop()
                    else:
                        # 播放背景音樂,第一個參數(shù)為播放的次數(shù)(-1表示無限循環(huán)),第二個參數(shù)是設(shè)置播放的起點(單位為秒)
                        pygame.mixer.music.play(-1, 0.0)

                    isMusic = not isMusic

                # 處理游戲暫停開關(guān)
                if 270 < event.pos[0] < 327 and 233 < event.pos[1] < 248:
                    isPause = not isPause

                    if isPause:
                        pygame.display.set_caption('俄羅斯方塊:已暫停')
                    else:
                        pygame.display.set_caption('俄羅斯方塊')

            elif event.type == pygame.KEYDOWN:
                if event.key == K_UP:
                    gameTetris.change()

        keyPressList = pygame.key.get_pressed()

        if keyPressList[K_DOWN]:
            gameTetris.moveDown()
        elif keyPressList[K_LEFT]:
            gameTetris.moveLeft()
        elif keyPressList[K_RIGHT]:
            gameTetris.moveRight()

        screen.fill((0, 0, 0))
        drawMap()
        pygame.display.update()
        count += 1

        pygame.time.Clock().tick(10)


if __name__ == '__main__':
    my_game()

注意:由于源碼中有音樂、圖片等不方便放在博客里,需要可私信或者評論區(qū)留言。文章來源地址http://www.zghlxwxcb.cn/news/detail-835316.html

到了這里,關(guān)于Python課程設(shè)計 基于python的俄羅斯方塊小游戲的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • python畢設(shè)分享 俄羅斯方塊小游戲設(shè)計與實現(xiàn) (源碼)

    python畢設(shè)分享 俄羅斯方塊小游戲設(shè)計與實現(xiàn) (源碼)

    ?? Hi,各位同學(xué)好呀,這里是L學(xué)長! ??今天向大家分享一個今年(2022)最新完成的畢業(yè)設(shè)計項目作品 python小游戲畢設(shè) 俄羅斯方塊小游戲設(shè)計與實現(xiàn) (源碼) ?? 學(xué)長根據(jù)實現(xiàn)的難度和等級對項目進行評分(最低0分,滿分5分) 難度系數(shù):3分 工作量:3分 創(chuàng)新點:4分 項目獲?。?/p>

    2024年02月03日
    瀏覽(25)
  • 基于Python+Pygame實現(xiàn)一個俄羅斯方塊小游戲【完整代碼】

    基于Python+Pygame實現(xiàn)一個俄羅斯方塊小游戲【完整代碼】

    俄羅斯方塊,一款起源于上世紀(jì)80年代的經(jīng)典電子游戲,憑借簡單的規(guī)則和獨特的魅力,一躍成為全球家喻戶曉的經(jīng)典。你知道其實只需要一些基礎(chǔ)的編程知識,就可以自己實現(xiàn)它嗎?今天,我們將使用Python的Pygame庫,一步步帶你構(gòu)建屬于自己的俄羅斯方塊小游戲! 游戲初始

    2024年02月04日
    瀏覽(26)
  • python制作俄羅斯方塊

    python制作俄羅斯方塊

    作者簡介 :一名后端開發(fā)人員,每天分享后端開發(fā)以及人工智能相關(guān)技術(shù),行業(yè)前沿信息,面試寶典。 座右銘 :未來是不可確定的,慢慢來是最快的。 個人主頁 :極客李華-CSDN博客 合作方式 :私聊+ 這個專欄內(nèi)容 :BAT等大廠常見后端java開發(fā)面試題詳細講解,更新數(shù)目10

    2024年02月12日
    瀏覽(24)
  • 免費分享一套Python俄羅斯方塊源碼 PyQt5俄羅斯方塊源碼,太好玩了~

    免費分享一套Python俄羅斯方塊源碼 PyQt5俄羅斯方塊源碼,太好玩了~

    大家好,我是java1234_小鋒老師,看到一個不錯的Python俄羅斯方塊源碼 PyQt5俄羅斯方塊源碼,分享下哈。 【免費】Python俄羅斯方塊源碼 PyQt5俄羅斯方塊源碼 Python小游戲源碼_嗶哩嗶哩_bilibili 【免費】Python俄羅斯方塊源碼 PyQt5俄羅斯方塊源碼 Python小游戲源碼項目來自互聯(lián)網(wǎng),免

    2024年01月25日
    瀏覽(24)
  • 用python制作俄羅斯方塊

    代碼如下,可以直接運行:

    2024年02月11日
    瀏覽(26)
  • python基礎(chǔ)項目實戰(zhàn)-俄羅斯方塊

    python基礎(chǔ)項目實戰(zhàn)-俄羅斯方塊

    一、俄羅斯方塊游戲設(shè)計分析: 俄羅斯方塊是一款風(fēng)靡全球,從一開始到現(xiàn)在都一直經(jīng)久不衰的電腦、手機、掌上游戲機產(chǎn)品,是一款游戲規(guī)則簡單,但又不缺乏樂趣的簡單經(jīng)典小游戲,上手容易,適用范圍廣泛,人所共知。俄羅斯方塊游戲基本規(guī)則是油4個小方塊組成的7種不

    2024年02月12日
    瀏覽(27)
  • 軟件設(shè)計實戰(zhàn):基于Java的俄羅斯方塊游戲【完整版】

    軟件設(shè)計實戰(zhàn):基于Java的俄羅斯方塊游戲【完整版】

    ?個人簡介 ???????個人主頁:陳橘又青 ?????♂?博客記錄心情,代碼編寫人生。 ??如果文章對你有用,麻煩關(guān)注點贊收藏走一波,感謝支持! ??強力推薦我平時學(xué)習(xí)編程和準(zhǔn)備面試的刷題網(wǎng)站:點這里! 前言 大家好,今天用Java編程實現(xiàn)一個GUI界面的經(jīng)典俄羅斯方

    2024年02月02日
    瀏覽(30)
  • 用python寫一個俄羅斯方塊程序

    用python寫一個俄羅斯方塊程序

    2024年04月23日
    瀏覽(26)
  • python實現(xiàn)俄羅斯方塊【含代碼和講解】

    Python實現(xiàn)俄羅斯方塊:打造經(jīng)典游戲的代碼實現(xiàn)教程 俄羅斯方塊是世界上最受歡迎的電子游戲之一,源自俄羅斯。這是一個簡單卻富有挑戰(zhàn)和樂趣的游戲,讓玩家必須思考如何將各種形狀的積木放入底部的平面上,以便完整地填滿一行或多行,每填滿一行就會消失并獲得分?jǐn)?shù)

    2024年02月11日
    瀏覽(29)
  • 基于STM32F407的俄羅斯方塊小游戲的設(shè)計

    基于STM32F407的俄羅斯方塊小游戲的設(shè)計

    ? ? 本文講述的是基于STM32F407的俄羅斯方塊小游戲的設(shè)計思路和測試結(jié)果,具體的代碼分析見文章?基于STM32F407的俄羅斯方塊游戲代碼分析_鉆仰彌堅的博客-CSDN博客 1.1 可行性分析 可行性分析能夠?qū)π孪到y(tǒng)進行各方面的分析與研究,確定新系統(tǒng)是否具有開發(fā)的可行性和必要性

    2024年02月11日
    瀏覽(68)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包