【Python】 python实现我的世界(Minecraft)计算器(重制版)

【Python】 python实现我的世界(Minecraft)计算器

文章目录

  • 【Python】 python实现我的世界(Minecraft)计算器
  • 1.引言与原理
  • 2.写代码之前的配置
  • 1.BuidTools.jar文件配置服务器
  • 2.raspberryjuice-1.12.1.jar用python控制服务器
  • 3.第三方库mcpi的基本方法
  • 4.计算器构建的思路
  • 5.源码展示
  • 6.操作示例
  • 7.结语
  • 这是配置资源以及教学视频链接


    配置资源及操作方法


    Python实现我的世界(Minecraft)计算器(附源码与教程)

    1.引言与原理

    ​ 想必mc玩家都见过红石计算器吧,非常宏大的工程,也非常的牛逼。我的红石还没有到达那种层次,所以我是造不出来那种层次的 计算器的。因为它需要将计算原理所需的结构都建造出来,而我这种小菜鸡肯定是不会的。不过,由于计算机内部已经帮我们构造好了计算的功能,我们就可以直接用计算机帮我们计算,将结果在mc中返回就好了。


    那做这件事的意义是什么呢?意义颇丰,可以提高你的算法思维以及工程能力,也可以在代码与游戏的交互下感受到无比的乐趣与成就感


    ​ 众所周知,Minecraft是用Java语言编写的。但是我们可以通过一些插件,结合python的第三方库mcpi来控制Minecraft

    mcpi可以用来填充方块、接收mc端的玩家发出的信息以及玩家的位置、将信息发送给mc端,然后进行处理。只用基于这四种功能,我们就可以利用python实现mc的计算器了。

    听起来是不是很简单,没错,做起来也很简单!下面一起跟着我来探索一下吧。

    2.写代码之前的配置

    写之前当然少不了安装一些东西,需要的东西以及操作方法我都放在一个文件中了,大家有需要自取

    点我获取文件

    1.BuidTools.jar文件配置服务器

    Spigot BuidTools是mc服务器

  • 1.新建一个文件夹,专门放置与服务器有关的文件

  • 2.将其放入其中

    该文件是一个jar包,直接在命令行上运行它便开始下载与服务器相关的文件

     java -jar BiudTools.jar --rev 1.19.2  # 运行命令
     # 1.19.2是你对应的mc版本号
    
  • 3.运行后生成的 spigot-1.19.2.jar这个jar包便是这个版本的服务器,将其放入一个新文件夹中,点击运行后生成了eula.txt和server.properties文件以及plugins文件夹

  • 4.点开eula.txt文件 将eula=false改成 eula=true

  • 5.点开server.properties文件,将online-mode改为false

  • 2.raspberryjuice-1.12.1.jar用python控制服务器
  • 1.将其放入plugins文件夹中

  • 2.点击spigot-1.19.2.jar启动服务器

  • 3.打开游戏,多人游戏,输入127.0.0.1进入游戏

  • 4.pip install mcpi 下载控制mc的第三方库

  • 5.随便新建一个py文件,输入以下三行代码,点击运行后查看游戏里的效果

    # 导入 Minecraft 模块,这是与 Minecraft 游戏交互的 Python API
    from mcpi.minecraft import Minecraft
    
    # 创建一个 Minecraft 对象,这将连接到 Minecraft 世界
    mcDriver = Minecraft.create()
    
    # 使用 postToChat 方法向游戏中的聊天窗口发送一条消息
    mcDriver.postToChat("Hello World!")
    
    
  • 3.第三方库mcpi的基本方法

    想要构建出计算器,只需要知道mcpi中的四种方法就可以了

    # 导入模块
    from mcpi.minecraft import Minecraft
    from mcpi.minecraft import CmdPositioner
    
    mcDriver=Minecraft.create()               # 与Minecraft进行交互,里面有很多交互的方法,通过mcDriver.方法名来使用
    
    # 方法一:获取玩家的位置x,y,z
    playerId=mcDriver.getPlayerEntityId('Janium')    # 获取玩家的Id,'Janium'为玩家名称
    positioner=CmdPositioner(mcDriver.conn,b'entity')# 用来处理实体的位置信息
    playerPosition=positioner.getTilePos(playerId)   # 获取玩家的位置
    x=playerPosition.x
    y=playerPosition.y								 # 玩家的坐标
    z=playerPosition.z
    
    # 方法二:向mc端发出信息
    mcDriver.postToChat("Hello World!")
    
    # 方法三:接受mc端玩家发来的信息,返回一个列表   列表元素格式:
    mcInfo=mcDriver.events.pollChatPosts()
    
    # 方法四:创建方块,前两个参数是创建方块的起始与结束的坐标,第三个方块的Id,152是红石。类似mc中的/fill
     mcDriver.setBlocks(subScreen[0],subScreen[1],152)
    
    

    只需掌握这四种方法,属于你的mc计算器也就可以搭建了。

    4.计算器构建的思路

    我写了两个文件,一个是创建显示结果的大屏幕,创建时返回你一个坐标,这就是你大屏幕的坐标。然后将这个坐标输入到第二个显示计算结果的文件中去,运行第二个文件,就可以开始使用了

    下面就来看看思路

  • 1.首先用方法四创建一个大屏幕,返回大屏幕的坐标。

  • 2.然后将大屏幕划分成小屏幕,每个小屏幕都显示一个数字。

  • 3.通过方法四写好构建数字以及符号的方法

  • 4.利用方法三接受mc端玩家发送来的信息

  • 5.在信息中提取算式

  • 6.通过eval()方法计算算式的结果

  • 7.转成字符串来遍历,依次显示结果

  • 只需要这七个步骤,属于你的mc计算器就大功告成了!是不是特别简单?

    当然还有一些细节,大家可以看我的B站视频,那里面有详细的思路解析

    点我观看视频

    下面直接给大家公布源码

    5.源码展示

    文件一

    # CreateBigScreen.py    (创建大屏幕并返回大屏幕坐标)
    
    from mcpi.minecraft import Minecraft
    from mcpi.minecraft import CmdPositioner
    
    mcDriver=Minecraft.create()  # 与Minecraft进行交互,里面有很多交互的方法,通过mcDriver.方法名来使用
    playerId=mcDriver.getPlayerEntityId('Janium')           # 获取玩家的Id,'Janium'为玩家名称
    positioner=CmdPositioner(mcDriver.conn,b'entity')       # 用来处理实体的位置信息
    playerPosition=positioner.getTilePos(playerId)          # 获取玩家的位置
    x=playerPosition.x
    y=playerPosition.y                                      # 玩家的坐标
    z=playerPosition.z
    
    def createBigScreen():
        mcDriver.setBlocks(x,y+48,z,x+98,y+20,z,123)
        
    createBigScreen()
    
    mcDriver.postToChat("创建大屏幕成功!创建时的坐标x,y,z分别是  {},{},{}".format(x,y,z))
    

    文件二

    # ProcessAndDisplay.py
    
    # 导入mcpi库
    from mcpi.minecraft import Minecraft
    import mcpi.block as block
    
    import time
    
    
    mcDriver=Minecraft.create()                          # 创建Minecraft对象,与Minecraft进行交互
    
    
    x,y,z=-44,-1,-170                                    # 就是在这里输入CreateBigScreen得到的坐标
    
    
    # 用相对坐标来划分每个子屏幕的位置,一共七个子屏幕,也就是可以处理七位数以内的计算。
    subScreen1=[[x+5,y+44,z-1],[x+15,y+44,z-1],[x+5,y+34,z-1],[x+15,y+34,z-1],[x+5,y+24,z-1],[x+15,y+24,z-1]]
    subScreen2=[[x+18,y+44,z-1],[x+28,y+44,z-1],[x+18,y+34,z-1],[x+28,y+34,z-1],[x+18,y+24,z-1],[x+28,y+24,z-1]]
    subScreen3=[[x+31,y+44,z-1],[x+41,y+44,z-1],[x+31,y+34,z-1],[x+41,y+34,z-1],[x+31,y+24,z-1],[x+41,y+24,z-1]]
    subScreen4=[[x+44,y+44,z-1],[x+54,y+44,z-1],[x+44,y+34,z-1],[x+54,y+34,z-1],[x+44,y+24,z-1],[x+54,y+24,z-1]]
    subScreen5=[[x+57,y+44,z-1],[x+67,y+44,z-1],[x+57,y+34,z-1],[x+67,y+34,z-1],[x+57,y+24,z-1],[x+67,y+24,z-1]]
    subScreen6=[[x+70,y+44,z-1],[x+80,y+44,z-1],[x+70,y+34,z-1],[x+80,y+34,z-1],[x+70,y+24,z-1],[x+80,y+24,z-1]]
    subScreen7=[[x+83,y+44,z-1],[x+93,y+44,z-1],[x+83,y+34,z-1],[x+93,y+34,z-1],[x+83,y+24,z-1],[x+93,y+24,z-1]]
    subScreenList=[subScreen1,subScreen2,subScreen3,subScreen4,subScreen5,subScreen6,subScreen7]
    
    
    # 在子屏幕内清除之前计算结果、创建数字以及符号的方法都在这个类里
    class CreateBlock:
        def clearScreen():
            mcDriver.setBlocks(x,y+48,z-1,x+98,y+20,z-1,block.AIR)
        def zero(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[1],152)
            mcDriver.setBlocks(subScreen[4],subScreen[5],152)
            mcDriver.setBlocks(subScreen[0],subScreen[4],152)
            mcDriver.setBlocks(subScreen[1],subScreen[5],152)
        def one(subScreen):
            mcDriver.setBlocks(subScreen[1],subScreen[5],152)
        def two(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[1],152)
            mcDriver.setBlocks(subScreen[1],subScreen[3],152)
            mcDriver.setBlocks(subScreen[2],subScreen[3],152)
            mcDriver.setBlocks(subScreen[2],subScreen[4],152)
            mcDriver.setBlocks(subScreen[4],subScreen[5],152)
        def three(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[1],152)
            mcDriver.setBlocks(subScreen[2],subScreen[3],152)
            mcDriver.setBlocks(subScreen[4],subScreen[5],152)
            mcDriver.setBlocks(subScreen[1],subScreen[5],152)
        def four(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[2],152)
            mcDriver.setBlocks(subScreen[2],subScreen[3],152)
            mcDriver.setBlocks(subScreen[1],subScreen[5],152)
        def five(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[1],152)
            mcDriver.setBlocks(subScreen[0],subScreen[2],152)
            mcDriver.setBlocks(subScreen[2],subScreen[3],152)
            mcDriver.setBlocks(subScreen[3],subScreen[5],152)
            mcDriver.setBlocks(subScreen[4],subScreen[5],152)
        def six(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[1],152)
            mcDriver.setBlocks(subScreen[0],subScreen[4],152)
            mcDriver.setBlocks(subScreen[2],subScreen[3],152)
            mcDriver.setBlocks(subScreen[4],subScreen[5],152)
            mcDriver.setBlocks(subScreen[3],subScreen[5],152)
        def seven(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[1],152)
            mcDriver.setBlocks(subScreen[1],subScreen[5],152)
        def eight(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[1],152)
            mcDriver.setBlocks(subScreen[2],subScreen[3],152)
            mcDriver.setBlocks(subScreen[4],subScreen[5],152)
            mcDriver.setBlocks(subScreen[0],subScreen[4],152)
            mcDriver.setBlocks(subScreen[1],subScreen[5],152)
        def nine(subScreen):
            mcDriver.setBlocks(subScreen[0],subScreen[1],152)
            mcDriver.setBlocks(subScreen[1],subScreen[5],152)
            mcDriver.setBlocks(subScreen[0],subScreen[2],152)
            mcDriver.setBlocks(subScreen[2],subScreen[3],152)
            mcDriver.setBlocks(subScreen[4],subScreen[5],152)
        # 创建小数点
        def point(subScreen):
            mcDriver.setBlock(subScreen[4],152)
        # 创建负号
        def minus(subScreen):
            mcDriver.setBlocks(subScreen[2],subScreen[3],152)
    
    
    # 算式所包含的字符,用来判断输入格式是否有效
    arithmeticSymbolList=['0','1','2','3','4','5','6','7','8','9','+','-','*','/','(',')','.','-']
    # 算式是否有效,有效为1,无效为0
    validOrNot=1 
    
    mcDriver.postToChat('计算器启动中......')
    time.sleep(0.5)
    mcDriver.postToChat('计算器已启动!')
    
    while True:
        # 子屏幕位置
        screenNumber=0
        while True:
            time.sleep(0.5)
            # 获取mc那边玩家输入的信息
            mcInfo=mcDriver.events.pollChatPosts()  
            if mcInfo != []:
                break
        # 在信息中提取算式
        equation=str(mcInfo[0])[31:-1]
    
        # 判断字符是否在算式列表里
        for num in equation:
            if num not in arithmeticSymbolList:
                validOrNot=0
                break
        # 有效,则开始计算结果
        if validOrNot==1:
            # 利用python自带的eval()方法直接算出算式的值
            numResult=eval(equation)
            # 字符串类型的算式计算结果,方便遍历每个数字,在屏幕中显示出来
            strResult=str(eval(equation))
            # 如果超过七位以上的浮点数,则取前七位(不是四舍五入)
            if type(numResult)==type(1.1):
                strResult=strResult[0:7]
            # 如果计算结果小于七位数,则开始显示
            if len(strResult)<=7:
                CreateBlock.clearScreen()
                # 遍历结果,显示数字
                for digitPosition in strResult:
                    time.sleep(0.5)
                    if   digitPosition=='0': CreateBlock.zero(subScreenList[screenNumber])
                    elif digitPosition=='1': CreateBlock.one(subScreenList[screenNumber])
                    elif digitPosition=='2': CreateBlock.two(subScreenList[screenNumber])
                    elif digitPosition=='3': CreateBlock.three(subScreenList[screenNumber])
                    elif digitPosition=='4': CreateBlock.four(subScreenList[screenNumber])
                    elif digitPosition=='5': CreateBlock.five(subScreenList[screenNumber])
                    elif digitPosition=='6': CreateBlock.six(subScreenList[screenNumber])
                    elif digitPosition=='7': CreateBlock.seven(subScreenList[screenNumber])
                    elif digitPosition=='8': CreateBlock.eight(subScreenList[screenNumber])
                    elif digitPosition=='9': CreateBlock.nine(subScreenList[screenNumber])
                    elif digitPosition=='.': CreateBlock.point(subScreenList[screenNumber])
                    elif digitPosition=='-': CreateBlock.minus(subScreenList[screenNumber])
                    screenNumber+=1
            # 如果超出七位数则显示结果溢出
            else:
                mcDriver.postToChat('结果溢出!')  
        # 无效,则提示输入错误    
        else:
            validOrNot=1
            mcDriver.postToChat('输入错误!')
    

    6.操作示例

  • 1.先运行第一个文件,运行之后你可以看到你的mc世界上方生成了一个大屏幕,并且收到了一个坐标

  • 2.将你得到的坐标输入到第二个文件代码中对应的位置,之后运行第二个文件

  • 3.在mc聊天栏中输入算式即可

  • 输入算式时,“ +-*/ ”分别对应” 加减乘除 “

  • 7.结语

    希望这个博客对大家有所帮助
    资源以及视频链接在文章开头以及文章中间都有,大家有兴趣可以看一下。

    本人资历尚浅,源码都是自己原创。如果有什么有问题或者不得体的地方,欢迎各位大佬批评指正,不过请别发表侮辱性言论。大家也可以在评论区多多交流,相互学习,共同成长。

    作者:杰九

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【Python】 python实现我的世界(Minecraft)计算器(重制版)

    发表回复