首頁 > 軟體

Python+Pygame實現簡單的單詞小遊戲

2023-03-31 06:01:41

前言

語言是一種藝術,但是作為語言的基礎——詞彙,卻不像藝術那樣賞心悅目。不斷的記憶與複習,讓詞彙成為很多孩子在學習英語時,最難完全攻克的關卡。

今天這篇程式碼文章為大家介紹了一個簡單好玩兒的單詞小遊戲程式,將原本枯燥無味的單詞與生動有趣的遊戲相結合,寓教於樂。

這種兼具挑戰性和趣味性的遊戲,很容易激起孩子的興趣,並且色彩斑斕的畫面,幫助他們更好的把形與意結合。小編認為,雖然單詞對於英語的學習很重要,家長也不能強行讓他們去記憶,而是嘗試以各種形式引導,化解抵觸與畏難情緒,才有利於後續的學習哦~

記單詞,也可以玩遊戲一樣打通關,又緊張又興奮,不刻意,還過癮,馬上跟我一起來體驗吧!

一、環境準備

1)執行環境 

環境安裝:python 3.8: 直譯器、pycharm: 程式碼編輯器、pygame、numpy、部分自帶的模組直接安裝Python就可以使用了。

 2)模組安裝

 第三方庫的安裝方式如下:

 一般安裝:pip install +模組名 映象源安裝:pip install -i 

pypi.douban.com/simple/+模組名 (還有很多國內映象源,這裡是豆瓣的用習慣了) 

3)圖片文字素材等

二、程式碼展示

主程式——

import pygame
import sys
import traceback
import os
from pygame.locals import *
from random import *
import numpy as np
import linecache

pygame.init()  # 遊戲初始化
pygame.mixer.init()  # 音效初始化

bg_size = width, height = 480, 700  # 螢幕大小
screen = pygame.display.set_mode(bg_size)
pygame.display.set_caption("英語單詞挑戰")  # 標題

# 背景圖片
background = pygame.image.load("source/背景.png")  # .convert()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# 遊戲音樂
pygame.mixer.music.load("source/背景音樂.mp3")
pygame.mixer.music.set_volume(0.2)
success_sound = pygame.mixer.Sound("source/正確.wav")
success_sound.set_volume(0.2)
lost_sound = pygame.mixer.Sound("source/失敗.wav")
lost_sound.set_volume(0.2)
win_sound = pygame.mixer.Sound("source/勝利.wav")
win_sound.set_volume(0.2)

class Word(pygame.sprite.Sprite):
    def __init__(self, bg_size, showword):
        pygame.sprite.Sprite.__init__(self)

        self.word = showword  # 獲取單詞
        self.length = len(self.word)  # 單詞長度
        self.wordfont = pygame.font.SysFont("arial", 36)  # 使用系統字型
        self.wordtext = self.wordfont.render(self.word, True, WHITE, BLACK)  # 單詞
        self.promptword = "*"*self.length
        self.showtext = self.wordfont.render(self.promptword, True, WHITE, BLACK)  # 隱藏單詞
        self.succtext = self.wordfont.render("", True, WHITE)
        self.rect = self.wordtext.get_rect()  # 單詞座標
        self.width, self.height = bg_size[0], bg_size[1]
        self.rect.left, self.rect.top = (self.width - self.rect.width) // 2, 20  # 定義座標
        self.speed = 1  # 下移速度
        # self.destroy_images = []
        # self.destroy_images.extend([pygame.image.load("爆炸小.png").convert_alpha()])
        self.active = True  # 活動標誌
        self.success = False  # 正確標誌

    # 判斷輸入字母是否正確,並顯示
    def show(self, a):
        for i in range(self.length):
            if self.promptword[i] == "*":
                if self.word[i] == a:
                    self.promptword =self.promptword[:i] + a + self.promptword[i+1:]
                    self.showtext = self.wordfont.render(self.promptword, True, WHITE, BLACK)  # 隱藏單詞
                if self.promptword == self.word:
                    self.success = True
                break
            else:
                continue

    # 單詞移動
    def move(self):
        if self.rect.top < self.height - 50:
            self.rect.top += self.speed
        else:
            self.reset()

    # 單詞重置
    def reset(self):
        self.active = True
        self.success = False
        self.rect.left, self.rect.top = (self.width - self.rect.width) // 2, 20

    # 中文提示
    def describe(self, prop):
        myprop = prop
        self.propfont = pygame.font.Font("source/楷體_GB2312.ttf", 20)  # 使用楷體字型
        # print(myprop)
        self.describetext = self.propfont.render(myprop, True, BLACK)  # 中文提示
        self.proprect = self.describetext.get_rect()  # 提示座標
        self.proprect.left, self.proprect.top = (self.width - self.proprect.width) // 2, (self.height - 30 - self.proprect.height / 2)
        screen.blit(self.describetext, self.proprect)

# 獲取單詞,讀取字典檔案
def Getletters(filename):
    words = []  # 儲存單詞
    prompts = []  # 儲存中文提示
    worddict = {}  # 單詞字典
    f = open(filename, encoding='utf-8')  # 開啟文字,定義格式,能夠讀取中文
    for line in f.readlines():  # 讀取行
        line = line.strip()  # 去掉/n
        word = line.split(":")[0]  # 擷取單詞
        prompt = line.split(":")[1]  # .split(";")[0]  # 擷取中文提示
        words.append(word)
        prompts.append(prompt)
        worddict.update({word : prompt})  # 字典新增元素
    f.close()
    return worddict

# 儲存字典檔案
def SaveDict(dict1, filename):
    # 開啟字典檔案
    with open(filename, mode='w', encoding='utf-8') as f:
        for k, v in dict1.items():
            str = f"{k}:{v}n"
            f.write(str)
        f.close()


# 隨機抽取字典的資料
def ChoseWord(dict1):
    n = len(dict1)
    random.choice(list(dict1.keys()))
    words = dict1.keys()
    prompts = dict1.values()
    i = randint(0, n)
    key = words[i]
    value = prompts[i]
    return key, value


# 主函數
def main():
    pygame.mixer.music.play(-1)  # 播放背景音樂
    running = True  # 判斷執行狀態
    clock = pygame.time.Clock()  # 時鐘
    delay = 100
    olingefile = "source/words.txt"  # 原始單詞檔案
    myfile = "source/newword.txt"  # 使用單詞檔案
    historyfile = "source/record.txt"  # 最高記錄檔案
    olindict = Getletters(olingefile)  # 獲取原始單詞
    num = len(olindict)  # 總單詞數量
    # getnum = 0
    # record_score = 0  # 最高得分記錄
    # record_rate = 0.00  # 最高進度
    myfont_big = pygame.font.SysFont("arial", 36)  # 使用系統大字型
    myfont_small = pygame.font.SysFont("arial", 24)  # 使用系統小字型
    # 標誌是否暫停遊戲
    paused = False
    paused_image = pygame.image.load("source/暫停.png").convert_alpha()
    resume_image = pygame.image.load("source/播放.png").convert_alpha()
    paused_rect = paused_image.get_rect()
    paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
    paused_show_image = paused_image
    # 主頁
    mained = False  # 主頁標誌
    main_image = pygame.image.load("source/主頁.png").convert_alpha()
    main_rect = main_image.get_rect()
    main_rect.left, main_rect.top = width - paused_rect.width - 70, 10
    # 成功頁面
    success_image = pygame.image.load("source/成功.png").convert_alpha()
    # 底部頁面
    bottom_image = pygame.image.load("source/底部.png").convert_alpha()
    # 統計得分
    # score = 0  # 當前得分
    # rate = 0.00  # 當前進度
    # 主頁面
    goon_image = pygame.image.load("source/繼續遊戲.png").convert_alpha()
    goon_rect = goon_image.get_rect()
    restart_image = pygame.image.load("source/重新開始.png").convert_alpha()
    restart_rect = restart_image.get_rect()
    gameover_image = pygame.image.load("source/結束遊戲.png").convert_alpha()
    gameover_rect = gameover_image.get_rect()
    flag = False  # 新單詞標記
    promptflag = False  # 空格提示單詞標記
    nextflag = False  # 回車下一個單詞標記
    winflag = False  # 勝利標誌
    keyvalue = ""  # 獲取按鍵
    if os.path.exists(myfile) and os.path.exists(historyfile):  # 如果有記錄
        mydict = Getletters(myfile)
        getnum = num - len(mydict)  # 完成數量
        mained = True
        with open(historyfile, mode='r', encoding='utf-8') as f:
            record_score = int(linecache.getline(historyfile, 1))  # 讀取最高記錄
            record_rate = float(linecache.getline(historyfile, 2))  # 讀取最高進度
            score = int(linecache.getline(historyfile, 3))  # 讀取上一次記錄
            f.close()
        # print(record_score, record_rate)
    else:
        mydict = Getletters(olingefile)
        getnum = 0
        score = 0
        rate = 0.00
        record_score = score
        record_rate = rate
        mained = False

    while running:
        for event in pygame.event.get():
            if event.type == QUIT:  # 退出
                # 寫入記錄檔案
                with open(historyfile, mode='w', encoding='utf-8') as f:
                    f.write(str(record_score))
                    f.write("n")
                    f.write(str(record_rate))
                    f.write("n")
                    f.write(str(score))
                    f.close()
                # 儲存剩餘單詞
                SaveDict(mydict, myfile)
                pygame.quit()
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:  # 滑鼠按下
                # 按下暫停鍵
                if event.button == 1 and paused_rect.collidepoint(event.pos):  # 檢測滑鼠是否在範圍內
                    paused = not paused
                    if paused:
                        pygame.mixer.music.pause()  # 背景音樂暫停
                        pygame.mixer.pause()  # 音效暫停
                        paused_show_image = resume_image
                    else:
                        pygame.mixer.music.unpause()  # 背景音樂暫停
                        pygame.mixer.unpause()  # 音效暫停
                        paused_show_image = paused_image
                # 按下主頁鍵
                if event.button == 1 and main_rect.collidepoint(event.pos):  # 檢測滑鼠是否在範圍內
                    mained = True
                    if mained:
                        pygame.mixer.music.pause()  # 背景音樂暫停
                        pygame.mixer.pause()  # 音效暫停

            elif event.type == KEYDOWN:  # 按鍵
                if event.key == K_TAB:  # tab鍵
                    promptflag = True
                elif event.key == K_RETURN:  # 確認鍵
                    nextflag = True
                else:
                    keyvalue = chr(event.key)  # 獲取ASCII碼轉字串
        screen.blit(background, (0, 0))  # 載入背景圖片
        screen.blit(bottom_image, (0, height - 60))  # 載入底部圖片
        # 繪製得分
        score_text = myfont_big.render(f"score:{str(score)}", True, WHITE)
        screen.blit(score_text, (10, 5))
        # 暫停/播放
        screen.blit(paused_show_image, paused_rect)  # 暫停圖片
        # 繪製主頁
        screen.blit(main_image, main_rect)  # 主頁圖片
        # 繪製進度
        pygame.draw.rect(screen, WHITE, ((10, 60), (200, 20)), 2)  # 畫矩形,座標(10,60),長寬(200,20),線寬2

        # 當進度大於80%顯示綠色,否則顯示紅色
        rate = getnum / num
        if rate > 0.8:
            rate_color = GREEN
        else:
            rate_color = RED
        pygame.draw.rect(screen, rate_color, ((10, 60), (200 * rate, 20)), 0)  # 填充
        remaintext = myfont_small.render(f"{rate*100:.2f}%", True, WHITE)
        screen.blit(remaintext, (220, 55))
        if not paused and not mained:
            if not flag:
                # 生成單詞
                showword = np.random.choice(list(mydict.keys()))  # 隨機選擇單詞
                showprompt = mydict[showword]  # 單詞中文提示
                # print(showword, showprompt)
                myword = Word(bg_size, showword)  # 生成單詞
                flag = True  # 新單詞
            else:
                myword.move()  # 單詞向下移動
                myword.describe(showprompt)
                myword.show(keyvalue)  # 獲取鍵盤按鍵
                if promptflag:
                    screen.blit(myword.wordtext, myword.rect)
                else:
                    screen.blit(myword.showtext, myword.rect)
                    # 成功
                    if myword.success:
                        screen.blit(myword.succtext, myword.rect)  # 清空
                        screen.blit(success_image, myword.rect)  # 成功圖片
                        success_sound.play()
                        if not (delay % 10):  # 延時
                            myword.reset()
                            flag = False
                            score += 5
                            getnum += 1
                            del mydict[showword]
                            if getnum == num:
                                winflag = True
                                mained = True
                if nextflag:
                    myword.reset()
                    flag = False
                    nextflag = False
                if myword.rect.top > height - 118:
                    lost_sound.play()
                    flag = False
                    score -= 2
        # 暫停時
        elif paused and not mained:
            myword.active = False
            screen.blit(myword.showtext, myword.rect)
            myword.describe(showprompt)
        # 顯示主頁
        elif mained and not winflag:
            # myword.active = False
            screen.blit(background, (0, 0))  # 載入背景圖片
            # 繪製結束介面
            # 更新最高分
            if score > record_score:
                record_score = score
            # 更新進度
            if rate > record_rate:
                record_rate = rate
            # 最高分
            record_score_text = myfont_big.render(f"Highest Score:{record_score}", True, WHITE)
            screen.blit(record_score_text, (50, 50))
            # 最高進度
            record_rate_text = myfont_big.render(f"Highest Rate:{record_rate*100:.2f}%", True, WHITE)
            screen.blit(record_rate_text, (50, 100))
            # 當前得分
            nowscore_text1 = myfont_big.render("Your Score:", True, WHITE)
            nowscore_text1_rect = nowscore_text1.get_rect()
            nowscore_text1_rect.left, nowscore_text1_rect.top = 50, 150
            screen.blit(nowscore_text1, nowscore_text1_rect)
            nowscore_text2 = myfont_big.render(str(score), True, RED)
            nowscore_text2_rect = nowscore_text2.get_rect()
            nowscore_text2_rect.left, nowscore_text2_rect.top = 50 + nowscore_text1_rect.width, nowscore_text1_rect.top
            screen.blit(nowscore_text2, nowscore_text2_rect)
            # 當前進度
            nowrate_text1 = myfont_big.render("Your Rate:", True, WHITE)
            nowrate_text1_rect = nowrate_text1.get_rect()
            nowrate_text1_rect.left, nowrate_text1_rect.top = 50, 200
            screen.blit(nowrate_text1, nowrate_text1_rect)
            nowrate_text2 = myfont_big.render(f"{rate*100:.2f}%", True, RED)
            nowrate_text2_rect = nowrate_text2.get_rect()
            nowrate_text2_rect.left, nowrate_text2_rect.top = 50 + nowrate_text1_rect.width, nowrate_text1_rect.top
            screen.blit(nowrate_text2, nowrate_text2_rect)

            # 繼續遊戲
            goon_rect.left, goon_rect.top = (width - goon_rect.width) // 2, 300
            screen.blit(goon_image, goon_rect)
            # 重新開始
            restart_rect.left, restart_rect.top = (width - restart_rect.width) // 2, goon_rect.bottom + 20
            screen.blit(restart_image, restart_rect)
            # 結束遊戲
            gameover_rect.left, gameover_rect.top = (width - gameover_rect.width) // 2, restart_rect.bottom + 20
            screen.blit(gameover_image, gameover_rect)

            # 檢測使用者滑鼠操作
            # 如果使用者按下滑鼠左鍵
            if pygame.mouse.get_pressed()[0]:
                # 獲取滑鼠位置
                pos = pygame.mouse.get_pos()
                # 如果使用者點選繼續遊戲
                if goon_rect.left < pos[0] < goon_rect.right and goon_rect.top < pos[1] < goon_rect.bottom:
                    # 跳出主頁面
                    mained = False
                # 重新開始
                elif restart_rect.left < pos[0] < restart_rect.right and restart_rect.top < pos[1] < restart_rect.bottom:
                    # 判斷最高記錄是否更新,儲存記錄
                    if score > record_score:
                        record_score = score
                    # 寫入記錄檔案
                    with open(historyfile, mode='w', encoding='utf-8') as f:
                        f.write(str(record_score))
                        f.write("n")
                        f.write(str(record_rate))
                        f.close()
                    # 儲存剩餘單詞
                    SaveDict(mydict, myfile)
                    # 退出主頁
                    mained = False
                    score = 0
                    mydict = Getletters(olingefile)  # 獲取原始單詞
                    getnum = 0

                # 如果使用者點選結束遊戲
                elif gameover_rect.left < pos[0] < gameover_rect.right and gameover_rect.top < pos[1] < gameover_rect.bottom:
                    # 寫入記錄檔案
                    with open(historyfile, mode='w', encoding='utf-8') as f:
                        f.write(str(record_score))
                        f.write("n")
                        f.write(str(record_rate))
                        f.write("n")
                        f.write(str(score))
                        f.close()
                    # 儲存剩餘單詞
                    SaveDict(mydict, myfile)
                    # 退出遊戲
                    pygame.quit()
                    sys.exit()
        else:
            # screen.blit(background, (0, 0))  # 載入背景圖片
            pygame.mixer.music.pause()  # 背景音樂暫停
            win_sound.play()
            win_text = myfont_big.render("Congratulations! You WIN!!!", True, WHITE)
            screen.blit(win_text, (50, 300))


        # 時間間隔
        delay -= 1
        if not delay:
            delay = 50
            promptflag = False
        pygame.display.flip()  # 頁面重新整理

        clock.tick(60)


if __name__ == "__main__":
    try:
        main()
    except SystemExit:
        pass
    except:
        traceback.print_exc()
        pygame.quit()
        input()

三、效果展示

1)介面展示

到此這篇關於Python+Pygame實現簡單的單詞小遊戲的文章就介紹到這了,更多相關Python Pygame單詞遊戲內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com