從零開始用Python做一個Minecraft成就(進度)生成器


最近看到mcmod百科上有個叫成就生成器的東西,於是也想用Python做一個。

大致思路:

一張成就圖像,需要有底圖,圖標和和說明文字三個部分。

成就的圖標比較難搞,我使用的是Minecraft Wiki上的物品欄圖標,大致思路是先把Sprite全圖下載下來,然后再從Wiki的Lua腳本里獲取物品名和圖標位置的映射關系,然后保存在一個字典里備用。

因為成就的底圖有透明度,所以不能上傳到博客園的相冊里,於是我把它放在了其他圖床(SM.MS)上,地址見代碼(base_url)。

Minecraft的英文字體(minecraft.otf)在網上是比較好找的,下載后和腳本文件放在同一目錄下即可。不過,現在網上還是找不到Minecraft原生的中文字體(即像素化的仿宋字體),所以要顯示中文,就只能用系統自帶的simsun.ttc將就一下了。

注意圖像的繪制需要用到Pillow模塊,html的處理和提取需要BeautifulSoup模塊,需使用pip命令安裝。

代碼如下:


from urllib.request import urlopen, urlretrieve
from bs4 import BeautifulSoup
from PIL import Image, ImageFont, ImageDraw
import re, string, os, requests

size = 32
listsize = 32
page_url = r'https://minecraft.gamepedia.com/Module:InvSprite'
sprite_url = r'https://static.wikia.nocookie.net/minecraft_gamepedia/images/4/44/InvSprite.png/revision/latest'
base_url = r'https://i.loli.net/2020/09/27/zwIY6nVJRmqbHaL.png' #使用SM.MS儲存成就底圖
catdict = {}
itemdict = {}

def init():
    #創建資源文件夾...
    if (not os.path.exists(r'./adv-maker/')):
        os.mkdir(r'./adv-maker/')
    
    #下載圖標文件...
    if (not os.path.exists(r'./adv-maker/inv-sprite.png')):
        print('Downloading Sprites file...')
        urlretrieve(sprite_url, './adv-maker/inv-sprite.png')

    #下載成就底圖...
    if (not os.path.exists(r'./adv-maker/advancement-base.png')):
        print('Downloading Advancement Background Image...')
        r = requests.get(base_url)
        with open(r'./adv-maker/advancement-base.png','wb') as bim:
            bim.write(r.content)
    
    #把Wiki上的Lua腳本先搞出來...
    if (not os.path.exists(r'./adv-maker/pos-info.txt')):
        resp = urlopen(page_url)
        print('Downloading HTML file...')
        cont = resp.read()
        soup = BeautifulSoup(cont,'html.parser')
        print('Extracting Lua script...')
        src = soup.select(".mw-code")[0].prettify().replace('&','&')
        print('Saving the script...')
        with open(r'./adv-maker/pos-info.txt','w+') as f:
            f.write(src)

    print('Reading Lua script...')
    f = open(r'./adv-maker/pos-info.txt','r')
    src = f.read()

    f.close()
    print('Getting Position Info...')
    #...然后提取物品名稱、物品分類、在圖中的位置等信息,存起來
    pat1 = re.compile(r'^\s*{ name = \'(.*)\', id = (.*) }',re.M)
    pat2 = re.compile(r'^\s*(.*) = { pos = (.*), section = (.*) }',re.M)

    res1 = pat1.findall(src)
    res2 = pat2.findall(src)

    for cat in res1:
        catdict[str(cat[1])] = cat[0]

    for itm in res2:
        #print('%-45s%-35s%-20s' %(itm[0][2:-2] if(itm[0][0]=='[') else itm[0], catdict[itm[2]], itm[1])) 如果要顯示物品列表,把這行的注釋符號去掉
        itemdict[(itm[0][2:-2] if(itm[0][0]=='[') else itm[0])] = int(itm[1])

def trans_paste(bg,fg,box=(0,0)):
    trans = Image.new("RGBA",bg.size)
    trans.paste(fg,box,mask=fg)
    nim = Image.alpha_composite(bg,trans)
    return nim

def show(tar="???",text1="Advancement Made!",color1=(255,255,0),text2="Minecraft Advancements!",color2=(255,255,255)):
    idx = 1
    if (tar in itemdict):
        idx = itemdict[tar]
    posx = int((idx - 1) // listsize)
    posy = (idx - 1 + listsize) % listsize
    
    print(idx,posx,posy)
    sprite = srci.crop((posy*size,posx*size,(posy+1)*size,(posx+1)*size))

    box = (17, 16, 17 + size, 16 + size)
    resi = trans_paste(advi,sprite,box)
    drw = ImageDraw.Draw(resi)
    drw.text((60, 12), text1, font=fnt, fill=color1)
    drw.text((60, 34), text2, font=fnt, fill=color2)
    resi.show()

def main():
    init()
    
    global srci, advi, fnt
    srci = Image.open('./adv-maker/inv-sprite.png').convert('RGBA')
    advi = Image.open('./adv-maker/advancement-base.png').convert('RGBA')
    fnt = ImageFont.truetype(r'minecraft.otf', 20)
    #fnt = ImageFont.truetype("simsun.ttc", 19) Use this to display Chinese characters
    
    #show('Wooden Pickaxe',text2='Stone Age')
    show(text1='Advancement Made!',text2='What the hell is this?')

if __name__ == '__main__':
    main()
    # print(__name__)

輸出:

 至此,一個自制的Minecraft成就生成器就算完成了,撒花!

SPECIAL THANKS TO:

Mcmod百科の成就生成器(靈感來源)

Minecraft Wiki(提供圖標支持)

SM.MS(提供圖像儲存服務)

Fonts2U(提供字體下載)

—————————————————————

Update(Mar 13th,2021):

這兩天又用JavaScript做了一個網頁版的,用起來更方便(圖標可以直接點擊選取),但由於反鋸齒的原因,繪制出的文本有點糊,只能將就一下了。

View on Codepen: https://codepen.io/devbobcorn/full/abBaGBr


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM