Python背单词记单词小程序源代码,背单词记单词小游戏源代码

背单词小游戏,要有多界面交互,界面整洁、美观,可调节游戏等级难度,可配置游戏信息。
有游戏分数,游戏时间,动画特效,背景音乐,不同游戏等级的历史最高分记录。
拼写成功的英文单词显示中文意思。支持长按回删键[backspace],快速删除单词字母。
多种游戏困难等级让玩家可以侧重提高打字速度、或者练习英语单词。
完整程序代码下载地址:Python背单词记单词小程序源代码
在这里插入图片描述

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Description: { 背单词小游戏主入口模块 }
"""
import os
import sys
import time
import json
import traceback
import Game_View
from Game_View import *
from Game_Sprite import *


def center_pos():
    """
    设置游戏窗口相对电脑屏幕居中
    """
    game_x = (Game_Info.SCREEN_X - Game_Info.SCREEN_RECT.width) / 2
    game_y = (Game_Info.SCREEN_Y - Game_Info.SCREEN_RECT.height) / 2
    os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" % (game_x, game_y)


def random_music():
    """随机播放背景音乐"""
    # 判断是否是静音模式
    print(Game_View.GameStartWin.voice_flag())
    try:
        pygame.mixer.init()
        pygame.mixer.music.load(random.choice(Game_Info.GAME_MUSICS))
        pygame.mixer.music.play(loops=0)
    except Exception as e:
        print("无法加载音频,请检查电脑配置" + str(e))
        print(traceback.format_exc())

    if not Game_View.GameStartWin.voice_flag():
        pygame.mixer_music.set_volume(0)


class TypingGame(object):
    """打字小游戏主类"""

    spell_ok = False  # 用于标识单词拼写成功
    game_pause_flag = False  # 游戏暂停标志
    game_over_flag = False  # 游戏结束标志
    game_quit_flag = False  # 游戏退出标志
    game_total_blood = Game_Info.GAME_BLOOD_RECT.width  # 游戏总能量(血条)

    # 游戏等级对照字典
    game_level_dict = {
        1: {"word_fall_speed": 0.3, "level_text": "简单", "level_color": "green"},
        2: {"word_fall_speed": 0.5, "level_text": "上手", "level_color": "blue"},
        3: {"word_fall_speed": 1.0, "level_text": "中等", "level_color": "orange"},
        4: {"word_fall_speed": 1.5, "level_text": "困难", "level_color": "red"},
        5: {"word_fall_speed": 2.0, "level_text": "魔鬼", "level_color": "purple"}
    }

    @staticmethod
    def game_init():
        """游戏初始化"""
        pygame.init()

        # 初始化游戏字体
        pygame.font.init()

        # 设置游戏标题和图标
        pygame.display.set_caption(Game_Info.GAME_NAME)
        pygame.display.set_icon(pygame.image.load(Game_Info.GAME_ICON_32))

    @staticmethod
    def set_game_event():
        """设置游戏事件"""
        # 设置创建单词的定时器
        pygame.time.set_timer(Game_Info.CREATE_WORD_EVENT, Game_Info.CREATE_WORD_INTERVAL)

        # 设置游戏音乐结束事件
        try:
            pygame.mixer.music.set_endevent(Game_Info.MUSIC_END_EVENT)
        except Exception as e:
            print("无法设置音乐结束事件\t" + str(e))
            print(traceback.format_exc())

    @staticmethod
    def load_words() -> dict:
        """
        加载英语单词
        return:
        {
            "CET4": [
                {
                  "eng_word": "a",
                  "cn_comment": "art.一(个);每一(个)"
                },
                ...
            ]
        }
        """
        with open(Game_Info.GAME_WORD_JSON, "r", encoding="utf-8") as file:
            word_json = file.read()
            word_dict = json.loads(word_json)
        return word_dict

    def __init__(self):
        self.words = self.load_words().get("CET4")
        self.game_conf = GameConfig()  # 游戏配置信息
        self.game_default_voice = 20  # 游戏默认音量
        self.use_time = 0  # 记录游戏使用的时间
        self.total_score = 0  # 记录游戏拼写成功了多少个单词
        self.word_content = ""  # 记录键盘输入的单词
        self.backspace_count = 0  # 回删键按下的次数

        # 预先创建动画对象
        self.animates = [Animation(self) for _ in range(5)]

        # 游戏初始血条值
        self.game_blood = int(self.game_conf.game_init_blood) * 10
        self.game_clock = pygame.time.Clock()
        self.screen = pygame.display.set_mode(Game_Info.SCREEN_RECT.size)

        self.game_init()
        self.set_game_event()  # 设置游戏事件
        self.__create_sprite()  # 创建游戏精灵

    def __create_sprite(self):
        """创建精灵和精灵组"""

        # 背景精灵
        back_sprite = ImageSprite(Game_Info.GAME_BACKGROUND)
        # 根据游戏屏幕的大小适配背景图(可能会导致背景图变形)
        back_sprite.transform_scale(
            back_sprite.image,
            (Game_Info.SCREEN_RECT.width, Game_Info.SCREEN_RECT.height)
        )
        self.back_group = pygame.sprite.Group(back_sprite)

        # 英文单词显示框
        input_rect_sprite = ImageSprite(Game_Info.INPUT_BACKGROUND)
        # 缩放图片
        input_rect_sprite.transform_scale(
            input_rect_sprite.image,
            (Game_Info.INPUT_RECT_WIDTH, Game_Info.INPUT_RECT_HEIGHT)
        )
        # 水平居中显示
        input_rect_sprite.hor_center(Game_Info.SCREEN_RECT)
        self.input_rect_group = pygame.sprite.Group(input_rect_sprite)

        # 创建“游戏设置”图片
        self.game_set_sprite = ImageSprite(Game_Info.GAME_SET_PINK)
        set_x = Game_Info.SCREEN_RECT.width - self.game_set_sprite.rect.width - 10
        set_y = Game_Info.SCREEN_RECT.height - self.game_set_sprite.rect.height - 10
        self.game_set_sprite.set_pos(set_x, set_y)
        self.game_set_sprite_group = pygame.sprite.Group(self.game_set_sprite)

        # 拼写的单词
        spell_word_sprite = SpellSprite(
            "",
            size=26,
            color=pygame.color.Color(self.game_conf.spell_ok_color)
        )
        spell_word_sprite.hor_center(Game_Info.SCREEN_RECT)
        spell_word_sprite.set_pos(spell_word_sprite.rect.x, 40)
        self.spell_word_group = pygame.sprite.Group(spell_word_sprite)

        # 创建单词精灵组
        self.word_group = pygame.sprite.Group()
        self.__random_generate_word(Game_Info.GENERATE_WORD_NUM)

        # 创建显示游戏时间精灵
        time_sprite = TextSprite(text="Time: 0", size=28, color=Game_Info.BLUE)
        time_sprite.set_pos(5, 0)
        self.time_group = pygame.sprite.Group(time_sprite)

        # 游戏分数
        self.score_sprite = TextSprite("Score: 0", size=30, color=Game_Info.BLUE)
        self.score_sprite.set_pos(Game_Info.SCREEN_RECT.width - self.score_sprite.rect.width - 20, 3)
        self.score_group = pygame.sprite.Group(self.score_sprite)

        # 游戏结束精灵(组)
        self.__game_over_sprite()

    def __game_over_sprite(self):
        """创建游戏结束的精灵(组)"""
        self.game_over_group = pygame.sprite.Group()

        game_over_sprite = TextSprite("Game  Over", 100, Game_Info.BLUE)
        game_over_sprite.rect.y = (Game_Info.SCREEN_RECT.height - game_over_sprite.rect.height - 400) / 2
        game_over_sprite.hor_center(Game_Info.SCREEN_RECT)

        game_level_text = self.game_level_dict[int(self.game_conf.game_level)]["level_text"]
        game_level_color = pygame.color.Color(self.game_level_dict[int(self.game_conf.game_level)]["level_color"])
        self.game_level_sprite = TextSprite(u"游戏等级: " + game_level_text, 50, game_level_color)
        self.game_level_sprite.rect.y = game_over_sprite.rect.y + 100 + 50
        self.game_level_sprite.hor_center(Game_Info.SCREEN_RECT)

        self.game_score_sprite = TextSprite(u"游戏分数: ", 50, Game_Info.BLUE)
        self.game_score_sprite.rect.y = game_over_sprite.rect.y + 200 + 50
        self.game_score_sprite.hor_center(Game_Info.SCREEN_RECT)

        self.highest_sprite = TextSprite(u"历史最高: ", 50, Game_Info.BLUE)
        self.highest_sprite.rect.y = game_over_sprite.rect.y + 300 + 50
        self.highest_sprite.hor_center(Game_Info.SCREEN_RECT)

        self.quit_sprite = TextSprite(u"退出", 50, Game_Info.BLUE)
        self.quit_sprite.set_pos(
            game_over_sprite.rect.x - self.quit_sprite.rect.width,
            game_over_sprite.rect.y + 400 + 10
        )

        self.reset_sprite = TextSprite(u"重 玩", 50, Game_Info.BLUE)
        self.reset_sprite.set_pos(
            game_over_sprite.rect.x + game_over_sprite.rect.width,
            game_over_sprite.rect.y + 400 + 10
        )

        self.game_over_group.add(
            game_over_sprite,
            self.game_level_sprite,
            self.game_score_sprite,
            self.highest_sprite,
            self.quit_sprite, self.reset_sprite
        )

    def __update_sprite(self):
        """更新精灵"""
        self.back_group.update()
        self.back_group.draw(self.screen)

        self.game_set_sprite_group.update()
        self.game_set_sprite_group.draw(self.screen)

        self.input_rect_group.update()
        self.input_rect_group.draw(self.screen)

        # 计算游戏使用时间
        if not self.game_pause_flag and not self.game_over_flag:
            self.use_time += 0.1

        display_time = "Time: " + str(self.use_time / 6)
        self.time_group.update(display_time[:12])
        self.time_group.draw(self.screen)

        self.score_sprite.set_pos(Game_Info.SCREEN_RECT.width - self.score_sprite.rect.width - 20, 3)
        self.score_group.update("Score: " + str(self.total_score))
        self.score_group.draw(self.screen)

        # 判断是否游戏结束
        if self.game_over_flag:
            self.__game_over()
            game_level_text = self.game_level_dict[int(self.game_conf.game_level)]["level_text"]
            self.game_level_sprite.update("游戏等级: " + str(game_level_text))
            self.game_over_group.draw(self.screen)
        else:
            if not self.game_pause_flag:
                self.word_group.update(self)
            self.word_group.draw(self.screen)

            spell_ok_color = pygame.Color(self.game_conf.spell_ok_color)
            self.spell_word_group.update(self.word_content, spell_ok_color)
            self.spell_word_group.draw(self.screen)

            # 更新游戏能量条
            if 0 <= self.game_blood <= self.game_total_blood:
                self.__draw_game_blood()

        # 单词精灵拼写成功动画
        for animate in self.animates:
            if animate.visible:
                animate.draw()

    def start_game(self):
        """打字游戏开启"""
        # 随机播放背景音乐
        random_music()

        # 利用多线程完成游戏持续掉血
        drop_blood_t = threading.Thread(target=self.__drop_blood)
        drop_blood_t.start()

        while True:
            # 是否设置成静音
            if not Game_View.GameStartWin.voice_flag():
                pygame.mixer_music.set_volume(0)
            else:
                pygame.mixer_music.set_volume(self.game_default_voice)

            # 设置游戏刷新帧率
            self.game_clock.tick(Game_Info.FRAME_PRE_SEC)

            # 判断游戏结束
            if self.game_blood < 0:
                TypingGame.game_over_flag = True
            else:
                self.__animate_action()
                self.__check_spell_word()

            self.__update_sprite()
            self.__event_handle()
            pygame.display.update()

    def __event_handle(self):
        """游戏事件监听"""

        # 遍历所有事件
        for event in pygame.event.get():
            try:
                if pygame.mixer.music.get_endevent() == Game_Info.MUSIC_END_EVENT and \
                        not pygame.mixer.music.get_busy():
                    # 如果music播放结束且没有音乐在播放就随机下一首
                    print("下一首")
                    random_music()
            except:
                pass

            # 如果单击关闭窗口,则退出
            if event.type == pygame.QUIT and not self.game_pause_flag:
                pygame.quit()
                TypingGame.game_quit_flag = True
                sys.exit()

            # 创建单词事件
            elif event.type == Game_Info.CREATE_WORD_EVENT:
                if not self.game_over_flag and not self.game_pause_flag:
                    # 游戏结束或者暂停就停止生成单词了
                    self.__random_generate_word(word_num=3)

            # 鼠标移动事件
            elif event.type == pygame.MOUSEMOTION:
                x, y = event.pos  # 获取屏幕坐标位置
                if self.__is_on_set(x, y):
                    self.game_set_sprite.image = pygame.image.load(Game_Info.GAME_SET_BLUE)
                else:
                    self.game_set_sprite.image = pygame.image.load(Game_Info.GAME_SET_PINK)

                # 游戏结束鼠标悬浮在确定按钮上变色
                if self.quit_sprite.rect.x <= x <= self.quit_sprite.rect.x + self.quit_sprite.rect.width and \
                        self.quit_sprite.rect.y <= y <= self.quit_sprite.rect.y + self.quit_sprite.rect.height:
                    self.quit_sprite.color = Game_Info.PINK
                    self.quit_sprite.update(self.quit_sprite.text)
                else:
                    self.quit_sprite.color = Game_Info.BLUE
                    self.quit_sprite.update(self.quit_sprite.text)

                # 游戏结束鼠标悬浮在重玩按钮上变色
                if self.reset_sprite.rect.x <= x <= self.reset_sprite.rect.x + self.reset_sprite.rect.width and \
                        self.reset_sprite.rect.y <= y <= self.reset_sprite.rect.y + self.reset_sprite.rect.height:
                    self.reset_sprite.color = Game_Info.PINK
                    self.reset_sprite.update(self.reset_sprite.text)
                else:
                    self.reset_sprite.color = Game_Info.BLUE
                    self.reset_sprite.update(self.reset_sprite.text)

            # 鼠标点击事件
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos  # 获取屏幕坐标位置

                # 点击游戏设置
                if self.__is_on_set(x, y):
                    # 判断游戏是否暂停
                    if not self.game_pause_flag:
                        TypingGame.game_pause_flag = True

                # 游戏结束鼠标点击退出按钮
                if self.quit_sprite.rect.x <= x <= self.quit_sprite.rect.x + self.quit_sprite.rect.width and \
                        self.quit_sprite.rect.y <= y <= self.quit_sprite.rect.y + self.quit_sprite.rect.height:
                    pygame.quit()
                    TypingGame.game_quit_flag = True
                    sys.exit()

                # 游戏结束鼠标点击重玩按钮
                if self.reset_sprite.rect.x <= x <= self.reset_sprite.rect.x + self.reset_sprite.rect.width and \
                        self.reset_sprite.rect.y <= y <= self.reset_sprite.rect.y + self.reset_sprite.rect.height:
                    self.__reset_game()

            # 键盘事件
            elif event.type == pygame.KEYDOWN and not self.game_over_flag and not self.game_pause_flag:
                # 英文单引号的ASCII值是39、-是45、.是46
                # print(event.key)
                if (pygame.K_a <= event.key <= pygame.K_z) or event.key in (39, 45, 46):
                    if self.spell_ok:
                        # 如果单词拼写成功再按下键盘时清空内容
                        self.word_content = ""
                        self.spell_ok = False

                    # 控制单词长度
                    if len(self.word_content) < 40:
                        # 记录键盘输入的字符
                        self.word_content += pygame.key.name(event.key)
                    else:
                        print("Word to long")
                    print(self.word_content)
                if event.key == pygame.K_BACKSPACE:
                    self.__delete_words()
            elif event.type == pygame.KEYUP:
                self.backspace_count = 0

        # 实现长按backspace连续回删
        # 使用键盘提供的方法获取键盘按键 - 按键元组
        keys_pressed = pygame.key.get_pressed()

        # 判断元组中对应的按键索引值 1
        if keys_pressed[pygame.K_BACKSPACE]:
            self.backspace_count += 1
            if self.backspace_count > 20:
                self.__delete_words()

    def __is_on_set(self, x, y):
        """
        检查是否在设置图片上
        :param x,y 鼠标的位置
        """
        img_set_x = self.game_set_sprite.rect.x
        img_set_y = self.game_set_sprite.rect.y
        img_set_w = self.game_set_sprite.rect.width
        img_set_h = self.game_set_sprite.rect.height

        if (img_set_x <= x <= img_set_x + img_set_w) and \
                (img_set_y <= y <= img_set_y + img_set_h):
            return True
        else:
            return False

    def __delete_words(self):
        """单词回删"""
        if self.word_content != "":
            self.word_content = self.word_content[:-1]
            print(self.word_content + "---" + str(len(self.word_content)))
            if self.spell_ok:
                # 如果单词拼写成功再按下键盘回删键时清空内容
                self.word_content = ""
                self.spell_ok = False

    def __random_generate_word(self, word_num=5):
        """
        随机生成单词精灵
        :param word_num:精灵数量 默认5
        :return:
        """
        count = 0
        while len(self.word_group.sprites()) <= 30:
            index = random.randint(0, len(self.words) - 1)
            eng_word = self.words[index]["eng_word"]
            cn_comment = self.words[index]["cn_comment"]
            # print(eng_word + "----" + cn_comment)
            word_sprite = WordSprite(
                eng_word,
                cn_comment,
                speed=self.game_level_dict[int(self.game_conf.game_level)]['word_fall_speed'],
                size=int(self.game_conf.word_size),
                color=pygame.color.Color(str(self.game_conf.word_normal_color))
            )

            # 单词位置随机
            word_sprite.random_pos()

            # 检查新单词精灵是否与单词精灵组中的精灵碰撞(重叠)
            words = pygame.sprite.spritecollide(
                word_sprite, self.word_group, False,
            )

            is_collide = pygame.sprite.spritecollideany(word_sprite, self.word_group)
            print("碰撞", is_collide)

            # 碰撞(释放内存重新随机生成单词精灵)
            if len(words) > 0:
                word_sprite.kill()
                print("重叠")
                continue
            else:
                self.word_group.add(word_sprite)
                count += 1
            if count >= word_num:
                break

    def __game_over(self):
        """游戏结束"""
        self.game_score_sprite.hor_center(Game_Info.SCREEN_RECT)
        self.highest_sprite.hor_center(Game_Info.SCREEN_RECT)
        self.game_score_sprite.update("游戏分数: %s" % self.total_score)

        """
        history_score_dict
        {
            'level_0': "{'score': None,'use_time': None,'create_time': None}",
            'level_1': "{'score': None,'use_time': None,'create_time': None}",
            'level_2': "{...}",
            ...
        }
        """
        # 显示历史最高
        highest_score_str = self.game_conf.history_score_dict['level_' + str(int(self.game_conf.game_level))]
        highest_score_dict = eval(highest_score_str)
        highest_score = highest_score_dict['score']
        if highest_score is None or int(self.total_score) > int(highest_score):
            # 更新历史记录
            highest_score = self.total_score
            highest_score_dict['score'] = str(self.total_score)
            highest_score_dict['use_time'] = str(self.use_time)[:5] + 's'
            highest_score_dict['create_time'] = str(time.strftime("%Y-%m-%d %H:%M"))
            self.game_conf.set_highest_score(str(highest_score_dict), 'level_' + str(int(self.game_conf.game_level)))
        else:
            highest_score = highest_score_dict['score']

        self.highest_sprite.update("历史最高: %s" % highest_score)

    def __check_spell_word(self):
        """检查拼写单词是否正确"""
        word_sprites = self.word_group.sprites()
        for word_sprite in word_sprites:

            # 判断单词内容是否相同
            if self.word_content.lower() == word_sprite.text.lower():

                # 判断血条是否超过总血条数
                if self.game_blood < self.game_total_blood:
                    self.game_blood += 10

                self.total_score += 1
                self.spell_ok = True
                self.word_content = self.word_content + "\t" + str(word_sprite.cn_comment)
                word_sprite.kill()

                # 从预先创建完毕的动画中取出一个动画对象
                for animate in self.animates:
                    if not animate.visible:
                        # 设置动画位置
                        animate.set_pos(word_sprite.rect.x, word_sprite.rect.y)
                        # 动画对象状态设置为True
                        animate.visible = True
                        break

    def __draw_game_blood(self, color=Game_Info.GREEN):
        """绘制游戏能量"""

        if self.game_blood <= 3 * 10:
            color = Game_Info.RED
        if self.game_blood >= 25 * 10:
            color = Game_Info.BLUE
        if self.game_total_blood - 30 <= self.game_blood <= self.game_total_blood:
            color = Game_Info.ORANGE

        # 绘制游戏能量
        pygame.draw.rect(
            self.screen, color,
            pygame.Rect(
                Game_Info.GAME_BLOOD_RECT.x + 2,
                Game_Info.GAME_BLOOD_RECT.y,
                self.game_blood,
                Game_Info.GAME_BLOOD_RECT.height
            )
        )
        pygame.draw.rect(self.screen, Game_Info.WHITE, Game_Info.GAME_BLOOD_RECT, 2)

    def __drop_blood(self):
        """持续掉血"""
        # if not self.game_pause_flag:
        #     if int(self.use_time) > 0 and (int(self.use_time) / 6) % 2 == 0:
        #         self.game_blood -= 0.5

        while not self.game_over_flag:
            if self.game_pause_flag:
                self.game_clock.tick(60)
            else:
                # 根据不同游戏等级掉血
                self.game_clock.tick(int(self.game_conf.game_level))
                self.game_blood -= 1

    def __animate_action(self):
        """开启单词拼写成功动画"""
        for animate in self.animates:
            if animate.visible:
                animate.action()

    def __reset_game(self):
        """游戏重玩"""
        del self  # 释放内存
        pygame.quit()
        pygame.init()
        random_music()
        TypingGame.game_over_flag = False
        TypingGame.game_quit_flag = False
        TypingGame().start_game()


def main():
    center_pos()
    # 启动游戏开始界面
    GameStartWin(title="Word Sprite").run()


if __name__ == '__main__':
    main()

在这里插入图片描述
完整程序代码下载地址:Python背单词记单词小程序源代码

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python代码大全

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值