【Python游戏】Python魔塔样板,自带Demo游戏内容(Powered by Pygame)| 附带源码

相关文件

想学Python的小伙伴可以关注小编的公众号【Python日志】
有很多的资源可以白嫖的哈,不定时会更新一下Python的小知识的哈!!
需要源码的小伙伴可以在公众号回复魔塔
Python源码、问题解答学习交流群:773162165

开发环境

Python版本:3.6.7
相关模块:
pygame
json
os

以及一些python自带的模块。

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

运行说明

电脑需要安装:
Python3.6或3.7
Pygame(从pip安装即可)
运行test.py即可进行游戏~

操作说明

Demo的游戏内容取自《中秋2019:桂魄》的咸鱼难度,应该挺容易的。目前游戏内容基本完整,实现了事件流,能够解析的事件会不断增加。游戏可以不依靠背包内的初始道具通关!不过如果实在是连咸鱼难度都打不过的话,那就随便用道具吧~

当前可用的快捷键:

  • X = 怪物手册
  • G = 楼层传送器
  • T = 玩家背包(带分类二级菜单)
  • S = 存档界面
  • D = 读档界面
  • A =撤回上一关键步(打怪&开门)
  • Z = 勇士转身(顺时针)
  • H = 帮助界面
  • B = 文本框Demo(测试用)
  • P =开关显伤层(默认开启)
  • ESC = 一般情况用来在各种菜单中进行返回操作
  • Enter = 一般情况用来在各种菜单中进行确认操作

在例如怪物手册,存档界面等菜单中,可以通过左右方向键快速跨页面移动高亮光标。

/tools文件夹下有一个使用Tkinter写的地图数据编辑器。这个编辑器非常简陋,但是能用,而且编辑完数值后会自动保存。

/tools文件夹下还有一个”一键H5魔塔地图转Python魔塔地图“工具,目前没有写GUI。这个转换器需要使用到json5这个包,因为H5魔塔中的地图文件并不是符合规范的JSON文件(关于这个问题可以搜索”trailing comma json“来了解更多)。常规的json包无法解析这样的JSON文件,所以只能使用json5。

效果展示

在这里插入图片描述
在这里插入图片描述

代码展示

def init():
    global_var.set_value("font_name", FONT_NAME)
    global_var.set_value("RootScreen", RootScreen)
    global_var.set_value("action_control", action_control)
    
    # 设置PlayerCon为全局变量(必须要在CurrentMap.set_map之前完成)
    global_var.set_value("PlayerCon", PlayerCon)
    
    # 初始化地图
    CurrentMap.set_map(PLAYER_FLOOR)
    CurrentMap.add_sprite(PlayerCon)
    global_var.set_value("CurrentMap", CurrentMap)
    WriteLog.debug(__name__, "初始化地图完成")

    # 初始化BlockData(建立通过id反查地图编号的字典)
    BlockDataReverse = {
    
    }
    for map_obj in BlockData:
        block_id = BlockData[map_obj]["id"]
        BlockDataReverse[block_id] = map_obj
    global_var.set_value("BlockDataReverse", BlockDataReverse)

    # 状态栏占位(如果删除,会影响游戏内地图的位置)
    StatusBarArea = RootScreen.add_child("left", BLOCK_UNIT * 4)
    StatusBarArea.priority = 15
    RootScreen.add_child(CurrentMap)  
    
    # 初始化UI图层
    # --- UI0 - 状态栏
    STATUSBAR = ui.StatusBar(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    STATUSBAR.priority = 145
    RootScreen.add_child(STATUSBAR)  
    global_var.set_value("STATUSBAR", STATUSBAR)
    WriteLog.debug(__name__, "初始化状态栏图层完成")
    # --- UI1 - 怪物手册
    BOOK = ui.Book(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    BOOK.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(BOOK)
    global_var.set_value("BOOK", BOOK)
    WriteLog.debug(__name__, "初始化怪物手册图层完成")
    # --- UI2 - 开始界面
    STARTMENU = ui.StartMenu(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    STARTMENU.priority = 500  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(STARTMENU)
    global_var.set_value("STARTMENU", STARTMENU)
    WriteLog.debug(__name__, "初始化开始界面图层完成")
    # --- UI3 - 背包界面
    BACKPACK = ui.Backpack(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    BACKPACK.priority = 150  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(BACKPACK)
    global_var.set_value("BACKPACK", BACKPACK)
    WriteLog.debug(__name__, "初始化背包图层完成")
    # --- UI4 - 存档界面
    SAVE = ui.SaveMenu(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    SAVE.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(SAVE)
    global_var.set_value("SAVE", SAVE)
    WriteLog.debug(__name__, "初始化存档图层完成")
    # --- UI5 - 读档界面
    LOAD = ui.LoadMenu(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    LOAD.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(LOAD)
    global_var.set_value("LOAD", LOAD)
    WriteLog.debug(__name__, "初始化读档图层完成")
    # --- UI6 - 楼层传送器界面
    FLY = ui.Fly(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    FLY.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(FLY)
    global_var.set_value("FLY", FLY)
    WriteLog.debug(__name__, "初始化楼层传送器图层完成")
    # --- UI7 - 帮助界面
    HELP = ui.Help(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    HELP.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(HELP)
    global_var.set_value("HELP", HELP)
    WriteLog.debug(__name__, "初始化帮助图层完成")
    # --- UI8 - 商店1界面
    Shop1 = ui.Shop1(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    Shop1.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(Shop1)
    global_var.set_value("Shop1", Shop1)
    WriteLog.debug(__name__, "初始化商店1图层完成")
    # --- UI9 - 商店2界面
    Shop2 = ui.Shop2(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    Shop2.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(Shop2)
    global_var.set_value("Shop2", Shop2)
    WriteLog.debug(__name__, "初始化商店2图层完成")
    # --- UI10 - 文本框界面
    TEXTBOX = ui.TextBox(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    TEXTBOX.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(TEXTBOX)
    global_var.set_value("TEXTBOX", TEXTBOX)
    WriteLog.debug(__name__, "初始化文本框图层完成")
    # --- UI11 - 选择框界面
    CHOICEBOX = ui.ChoiceBox(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    CHOICEBOX.priority = 140  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(CHOICEBOX)
    global_var.set_value("CHOICEBOX", CHOICEBOX)
    WriteLog.debug(__name__, "初始化选择框图层完成")
    # --- UI12 - 显伤层
    SHOWDAMAGE = ui.ShowDamage(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    SHOWDAMAGE.priority = 65  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(SHOWDAMAGE)
    global_var.set_value("SHOWDAMAGE", SHOWDAMAGE)
    WriteLog.debug(__name__, "初始化显伤层完成")
    # --- UI13 - 色调层
    CURTAIN = ui.Curtain(mode='copy', surface=RootScreen) # 必须按ground的方式初始化
    CURTAIN.priority = 125  # 显示的优先级 高于地图 所以在地图上
    RootScreen.add_child(CURTAIN)
    global_var.set_value("CURTAIN", CURTAIN)
    WriteLog.debug(__name__, "初始化色调层完成")
    WriteLog.info(__name__, "初始化全部UI图层完成")
def init_actions():
    # QUIT:
    def quit(e):
        global running
        running = False
        return True
    
    # 注册事件
    action_control.register_action('QUIT', pygame.QUIT, quit)
    action_control.register_action('BOOK', pygame.KEYUP, global_var.get_value('BOOK').action)
    action_control.register_action('STARTMENU', pygame.KEYUP, global_var.get_value('STARTMENU').action)
    action_control.register_action('BACKPACK', pygame.KEYUP, global_var.get_value('BACKPACK').action)
    action_control.register_action('SAVE', pygame.KEYUP, global_var.get_value('SAVE').action)
    action_control.register_action('LOAD', pygame.KEYUP, global_var.get_value('LOAD').action)
    action_control.register_action('FLY', pygame.KEYUP, global_var.get_value('FLY').action)
    action_control.register_action('HELP', pygame.KEYUP, global_var.get_value('HELP').action)
    action_control.register_action('Shop1', pygame.KEYUP, global_var.get_value('Shop1').action)
    action_control.register_action('Shop2', pygame.KEYUP, global_var.get_value('Shop2').action)
    action_control.register_action('TEXTBOX', pygame.KEYUP, global_var.get_value('TEXTBOX').action)
    action_control.register_action('CHOICEBOX', pygame.KEYUP, global_var.get_value('CHOICEBOX').action)
    action_control.register_action('SHOWDAMAGE', pygame.KEYUP, global_var.get_value('SHOWDAMAGE').action)
    action_control.register_action('STATUSBAR', pygame.KEYUP, global_var.get_value('STATUSBAR').action)
    action_control.register_action('CURTAIN', pygame.KEYUP, global_var.get_value('CURTAIN').action)
    WriteLog.info(__name__, "事件全部注册完成")


def init_sound():
    Music = music.MusicWrapper()
    global_var.set_value("Music", Music)
    WriteLog.info(__name__, "初始化音效完成")

def init_event_flow():
    EVENTFLOW = EventFlow()
    global_var.set_value("EVENTFLOW", EVENTFLOW)
    EVENT = Event()
    global_var.set_value("EVENT", EVENT)
    EVENT.get_event_flow_module()
    EVENTFLOW.get_event_module()
    WriteLog.info(__name__, "初始化事件流完成")

def init_function():
    FUNCTION = global_var.get_value("FUNCTION")
    FUNCTION.init_var()
    WriteLog.info(__name__, "初始化function完成")

# 主程序
while running:
    # a = pygame.time.get_ticks()
    # 展示开始菜单
    if STARTMENU.new_game == True:
        STARTMENU.open()
        STARTMENU.new_game = False
        # 默认开启显伤
        show_damage = global_var.get_value("SHOWDAMAGE")
        show_damage.open()
        # 默认开启状态栏
        status_bar = global_var.get_value("STATUSBAR")
        status_bar.open()
        # 地图确保为active状态
        CurrentMap.active = True
        # 载入初始事件
        EVENTFLOW = global_var.get_value("EVENTFLOW")
        with open(os.path.join(os.getcwd(),"project", "start_text.json")) as f:
            start_text = json.load(f)
        EVENTFLOW.insert_action(start_text["startText"])
    pygame.display.update()
    # 背景
    RootScreen.flush(screen)  # 显示刷新到屏幕
    action_control.action_render()  # 检查动作消息
    # b = pygame.time.get_ticks()
    # print(b - a)

想学Python的小伙伴可以关注小编的公众号【Python日志】
需要源码的小伙伴可以在公众号回复魔塔
Python源码、问题解答学习交流群:773162165

猜你喜欢

转载自blog.csdn.net/Gtieguo/article/details/123994611