用python把AuroraGT的结果导成lua

来源:互联网 发布:stm32和51编程一样吗 编辑:程序博客网 时间:2024/06/11 02:17

自己用 love2d 做游戏,开了好几个头,最后都因为种种原因不了了之。。其中最最重要的原因之一,就是没有现成的图。

网上找到的图,经常是大章的,整合过的。自己在用起来的时候,就得自己拿着 photoshop 去量 每个小土块的 uv坐标,量好了手写到 lua 文件里。

为了快速出原形的时候,这不失为一种便捷的做法,但是每次自己去量的时候也很头疼。这时候就希望能有个工具,能自动给我量好了,然而这并不可能。。最多也就是可视化丈量了。于是想,干脆自己开发这么个工具得了(话说N多年前自己就有过这样的想法)。但是这样搞成本太高了,自己也没这个心思。于是怀念起来刚刚入职 gl 时,用的 AuroraGT.里面的 Sprite 编辑器其实就是一个可视化编辑的工具,非常符合我的需求。 

3,4年前上班的时候,自己搞过用 c++解析 AuroraGT 导出的 .sprite 文件,并且用  dx 渲染出来的小东西。那个时候我的做法,竟然是直接在主程序里,读取并解析 .sprite 文件。。而且写得效率并不高,分析一个大点的 .sprite 文件速度慢的要死。现在用  love2d, 打算直接把 .sprite 文件直接导成 .lua  代码。这个思路的主要来源有两个:1年前看cocosstudio ,记得有个功能是能直接根据 排版的 menu 布局,导出成 lua 代码;现在上班的公司,也是直接把 配置文件  csv 搞成 lua 代码的。这样 在 love2d 的游戏主程序里用起来,就省略了解析这一步,用起来 效率肯定会高出不少。

AuroraGT 这个软件,能够把图片,根据 uv 坐标,拆成许许多多的小块,称为 module。 一般我想象中的拆图工具,功能到此也就结束了;然而 AuroraGT 牛的地方在于,还可以自行拼装 这些 module ,组成 几个 module 合成的一个图块,成为 frame;到这里当然还没结束,还能把这些 frame 按照顺序,组成 animation

也就是说,AuroraGT 不是一个简单的拆图片软件,还能做帧动画编辑器,图片如果拆的够细致,图片的利用率就非常高,能在很省图片的情况下,完整保存帧动画数据。当然你也可以把 module 和 frame 视为 1对1 的,简单的把这个东西当成一个普通的帧动画编辑器也可以。


为了简单,我做的这个导出,只支持 一个.sprite 文件,对应一张图片。 我认为这样足够了, 对应多张实在有点乱。

下面3段分别是  AuroraGT 导出的 .sprite 文件, python 导出代码, lua 导出结果。

为了速度实现功能,代码没往美观的写,留在这里做个备忘


AuroraGT  .sprite 文件

// E:\love2d\gamerepo\project\casualgame\assets\TestAnim.sprite// saved by AuroraGT v0.7.1 (SpriteEditor v0.8.1)/////////////////////////////////////////////////////////////////////////////////*SPRITE*/ {    VERSION 0001    // Images:  1    // Modules: 7    // Frames:  6    // Anims:   2////////////////////////////////////////////////////////////////////////////////// Images...// <Image> := IMAGE [id] "file" [TRANSP transp_color]    IMAGE 0x0000 "E:\love2d\gamerepo\project\casualgame\assets\Anime\img_phenix.png" TRANSP 0xFFFFFFFF // 0  size: 1024 x 1024  palettes: 1////////////////////////////////////////////////////////////////////////////////// Modules...// <Modules> := MODULES { <MD1> <MD2> ... }// <MDi>     := MD id Type [params] ["desc"]// Type      := MD_IMAGE | MD_RECT | ...// [params]  := if (Type == MD_IMAGE)     -> image x y width height//              if (Type == MD_RECT)      -> color width height//              if (Type == MD_FILL_RECT) -> color width height//              if (Type == MD_ARC)       -> color width height//              if (Type == MD_FILL_ARC)  -> color width height    MODULES    {        MD0x1000MD_IMAGE000128198        MD0x1001MD_IMAGE01198137190        MD0x1002MD_IMAGE01270172185        MD0x1003MD_IMAGE0298096162        MD0x1004MD_IMAGE0254186153165        MD0x1005MD_IMAGE0408163166156        MD0x1006MD_IMAGE0001616    }////////////////////////////////////////////////////////////////////////////////// Frames...// <Frame> := FRAME ["desc"] { id <RC1> [<RC2> ...] <FM1> [<FM2> ...] }// <RCi>   := RC x1 y1 x2 y2// <FMi>   := FM module_or_frame_id ox oy [FLAGS hex_flags] [+Flags]// Flags   := HYPER_FM | FLIP_X | FLIP_Y | ROT_90    FRAME "" // Index = 0, FModules = 3    {        0x2000        FM0x1000-3-164        FM0x1002-172-57        FM0x100100    }    FRAME "" // Index = 1, FModules = 1    {        0x2001        FM0x100100    }    FRAME "" // Index = 2, FModules = 1    {        0x2002        FM0x100200    }    FRAME "" // Index = 3, FModules = 1    {        0x2003        FM0x100300    }    FRAME "" // Index = 4, FModules = 1    {        0x2004        FM0x100400    }    FRAME "" // Index = 5, FModules = 1    {        0x2005        FM0x100500    }////////////////////////////////////////////////////////////////////////////////// Animations...// <Anim> := ANIM ["desc"] { id [<AF1> <AF2> ...] }// <AFi>  := AF frame_id time ox oy [FLAGS hex_flags] [+Flags]// Flags  := FLIP_X | FLIP_Y | ROT_90    ANIM "" // Index = 0, AFrames = 6    {        0x3000        AF0x20001-70-98        AF0x20018-70-89        AF0x20021-76-86        AF0x20031-54-73        AF0x20041-72-73        AF0x20051-78-64    }    ANIM "" // Index = 1, AFrames = 3    {        0x3001        AF0x2000100        AF0x2001100        AF0x2002100    }////////////////////////////////////////////////////////////////////////////////// Tilesets...    SPRITE_END} // SPRITE////////////////////////////////////////////////////////////////////////////////


python 脚本:

imageFile = NoneallModules = {}allFrames = {}allAnimates = {}LINE_FLAG_NONE=0LINE_FLAG_COMMENT=1LINE_FLAG_MODULE_START=2LINE_FLAG_FRAME_START=3LINE_FLAG_ANIM_START=4LINE_FLAG_IMAGE=5LINE_FLAG_L_BRACKETS=6LINE_FLAG_R_BRACKETS=7STATE_NONE=0STATE_MODULE=1STATE_FRAME=2STATE_ANIM=3curState = STATE_NONEcurKey = Nonedef dealImage(splitArray):global imageFileimageFile = splitArray[2]strLen = len(imageFile)imageFile = imageFile[1:strLen - 1]def dealModule(splitArray):global allModulesif len(splitArray) == 1:returnmoduleTag = splitArray[1]allModules[moduleTag] = {}allModules[moduleTag]['x'] = int(splitArray[4])allModules[moduleTag]['y'] = int(splitArray[5])allModules[moduleTag]['w'] = int(splitArray[6])allModules[moduleTag]['h'] = int(splitArray[7])def dealFrame(splitArray):global allFramesglobal curKeyif splitArray[0] == 'FRAME':returnif len(splitArray) == 1:curKey = splitArray[0]allFrames[curKey] = []returnif splitArray[0] == 'FM':frameModule = {}frameModule['moduleTag'] = splitArray[1]frameModule['xOffset'] = int(splitArray[2])frameModule['yOffset'] = int(splitArray[3])allFrames[curKey].append(frameModule)def dealAnim(splitArray):global allAnimatesglobal curKeyif splitArray[0] == 'ANIM':returnif len(splitArray) == 1:curKey = splitArray[0]allAnimates[curKey] = []returnif splitArray[0] == 'AF':animFrame = {}animFrame['frameTag'] = splitArray[1]animFrame['duration'] = splitArray[2]animFrame['xOffset'] = splitArray[3]animFrame['yOffset'] = splitArray[4]allAnimates[curKey].append(animFrame)def dealLine(line):global curStateif line.find('Modules...') >= 0:curState = STATE_MODULEcurKey = Nonereturn LINE_FLAG_MODULE_STARTif line.find('Frames...') >= 0:curState = STATE_FRAMEcurKey = Nonereturn LINE_FLAG_FRAME_STARTif line.find('Animations...') >= 0:curState = STATE_ANIMcurKey = Nonereturn LINE_FLAG_ANIM_STARTif len(line) == 0:return LINE_FLAG_NONEif line.find('////////////////////////////////////////////////////////////////////////////////') != -1:curState = STATE_NONEreturn LINE_FLAG_COMMENTif line.find('//') == 0:return LINE_FLAG_COMMENTif line.find('/*') != -1:return LINE_FLAG_COMMENTsplitBySpaceArray = line.split(' ')if len(splitBySpaceArray) <= 0:return LINE_FLAG_NONEif splitBySpaceArray[0] == 'IMAGE':dealImage(splitBySpaceArray)return LINE_FLAG_IMAGEif splitBySpaceArray[0] == '{':curKey = Nonereturn LINE_FLAG_L_BRACKETSif splitBySpaceArray[0] == '}':curKey = Nonereturn LINE_FLAG_R_BRACKETSif curState == STATE_MODULE:splitBySpaceArray = splitBySpaceArray[0].split('\t')dealModule(splitBySpaceArray)if curState == STATE_FRAME:splitBySpaceArray = splitBySpaceArray[0].split('\t')dealFrame(splitBySpaceArray)if curState == STATE_ANIM:splitBySpaceArray = splitBySpaceArray[0].split('\t')dealAnim(splitBySpaceArray)return LINE_FLAG_NONEdef fileToMem(filename):fileObject = open(filename,'r')allLines = fileObject.readlines()curLine = 0for line in allLines:curLine = curLine + 1line = line.strip()dealLine(line)def dumpModules():global allModulesprint('all modules:')print(allModules)def dumpFrames():global allFramesprint('all frames:')print(allFrames)def dumpAnims():global allAnimatesprint('all animates:')print(allAnimates)def dump():dumpModules()dumpFrames()dumpAnims()def exportAsJson(filename):''''''def generateLua(filename,wholeName):strLua = ''strLua = strLua + filename + ' = 'strLua = strLua + '{}\n'global imageFileimageFilePath = imageFile.replace('\\','\\\\')strLua = strLua + filename + '.image' + '=\'' + imageFilePath + '\'\n'strLua = strLua + filename + '.modules = {}\n'strLua = strLua + filename + '.frames = {}\n'strLua = strLua + filename + '.anims = {}\n'# construct modulesstrLua = strLua + '-- modules\n'modulePrefix = filename + '.modules'for (key,moduleItem) in allModules.items():strLua = strLua + modulePrefix + '[\'' + str(key) + '\']' + '={}'strLua = strLua + '\n'mItemPrefix = modulePrefix + '[\'' + str(key) + '\']'for fieldKey,fieldItem in moduleItem.items():strLua = strLua + mItemPrefix + '.' + fieldKey + '=' + str(fieldItem) + '\n'# construct framesstrLua = strLua + '-- frames\n'framePrefix = filename + '.frames'for (key,frameItem) in allFrames.items():strLua = strLua + framePrefix + '[\'' + str(key) + '\']' + '={}'strLua = strLua + '\n'fItemPrefix = framePrefix + '[\'' + str(key) + '\']'for i in range(0,len(frameItem)):strLua = strLua + fItemPrefix + '[' + str(i + 1) +'] = {}'strLua = strLua + '\n'frameModulePrefix = fItemPrefix + '[' + str(i + 1) +']'for (fmPropertyKey,fmPropertyVal) in frameItem[i].items():strLua = strLua + frameModulePrefix + '.' + fmPropertyKeyif fmPropertyKey == 'moduleTag':strLua = strLua + '=\'' + str(fmPropertyVal) + '\''else:strLua = strLua + '=' + str(fmPropertyVal)strLua = strLua + '\n'# construct animsstrLua = strLua + '-- anims\n'animPrefix = filename + '.anims'for (key,animItem) in allAnimates.items():strLua = strLua + animPrefix + '[\'' + str(key) + '\']' + '={}'strLua = strLua + '\n'aItemPrefix = animPrefix + '[\'' + str(key) + '\']'for i in range(0,len(animItem)):strLua = strLua + aItemPrefix + '[' + str(i + 1) +'] = {}'strLua = strLua + '\n'animFramePrefix = aItemPrefix + '[' + str(i + 1) + ']'for (afPropertyKey,afPropertyVal) in animItem[i].items():strLua = strLua + animFramePrefix + '.' + afPropertyKeyif afPropertyKey == 'frameTag':strLua = strLua + '=\'' + str(afPropertyVal) + '\''else:strLua = strLua + '=' + str(afPropertyVal)strLua = strLua + '\n'return strLuadef getFileName(filePath):filePath = filePath.split('/')filePath = filePath[len(filePath) - 1]filePath = filePath.split('.')return filePath[0]if __name__ == '__main__':filePath = 'project/casualgame/assets/TestAnim.sprite'fileToMem(filePath)#dump()fileName = getFileName(filePath)exportAsJson(fileName + '.json')strLua = generateLua(fileName,fileName + '.lua')luaFile = open('export/' + fileName + '.lua','w')luaFile.write(strLua)luaFile.close()


导出的结果 lua 文件:

TestAnim = {}TestAnim.image='E:\\love2d\\gamerepo\\project\\casualgame\\assets\\Anime\\img_phenix.png'TestAnim.modules = {}TestAnim.frames = {}TestAnim.anims = {}-- modulesTestAnim.modules['0x1002']={}TestAnim.modules['0x1002'].w=172TestAnim.modules['0x1002'].h=185TestAnim.modules['0x1002'].y=0TestAnim.modules['0x1002'].x=127TestAnim.modules['0x1005']={}TestAnim.modules['0x1005'].w=166TestAnim.modules['0x1005'].h=156TestAnim.modules['0x1005'].y=163TestAnim.modules['0x1005'].x=408TestAnim.modules['0x1000']={}TestAnim.modules['0x1000'].w=128TestAnim.modules['0x1000'].h=198TestAnim.modules['0x1000'].y=0TestAnim.modules['0x1000'].x=0TestAnim.modules['0x1004']={}TestAnim.modules['0x1004'].w=153TestAnim.modules['0x1004'].h=165TestAnim.modules['0x1004'].y=186TestAnim.modules['0x1004'].x=254TestAnim.modules['0x1003']={}TestAnim.modules['0x1003'].w=96TestAnim.modules['0x1003'].h=162TestAnim.modules['0x1003'].y=0TestAnim.modules['0x1003'].x=298TestAnim.modules['0x1006']={}TestAnim.modules['0x1006'].w=16TestAnim.modules['0x1006'].h=16TestAnim.modules['0x1006'].y=0TestAnim.modules['0x1006'].x=0TestAnim.modules['0x1001']={}TestAnim.modules['0x1001'].w=137TestAnim.modules['0x1001'].h=190TestAnim.modules['0x1001'].y=198TestAnim.modules['0x1001'].x=1-- framesTestAnim.frames['0x2000']={}TestAnim.frames['0x2000'][1] = {}TestAnim.frames['0x2000'][1].moduleTag='0x1000'TestAnim.frames['0x2000'][1].yOffset=-164TestAnim.frames['0x2000'][1].xOffset=-3TestAnim.frames['0x2000'][2] = {}TestAnim.frames['0x2000'][2].moduleTag='0x1002'TestAnim.frames['0x2000'][2].yOffset=-57TestAnim.frames['0x2000'][2].xOffset=-172TestAnim.frames['0x2000'][3] = {}TestAnim.frames['0x2000'][3].moduleTag='0x1001'TestAnim.frames['0x2000'][3].yOffset=0TestAnim.frames['0x2000'][3].xOffset=0TestAnim.frames['0x2001']={}TestAnim.frames['0x2001'][1] = {}TestAnim.frames['0x2001'][1].moduleTag='0x1001'TestAnim.frames['0x2001'][1].yOffset=0TestAnim.frames['0x2001'][1].xOffset=0TestAnim.frames['0x2002']={}TestAnim.frames['0x2002'][1] = {}TestAnim.frames['0x2002'][1].moduleTag='0x1002'TestAnim.frames['0x2002'][1].yOffset=0TestAnim.frames['0x2002'][1].xOffset=0TestAnim.frames['0x2003']={}TestAnim.frames['0x2003'][1] = {}TestAnim.frames['0x2003'][1].moduleTag='0x1003'TestAnim.frames['0x2003'][1].yOffset=0TestAnim.frames['0x2003'][1].xOffset=0TestAnim.frames['0x2004']={}TestAnim.frames['0x2004'][1] = {}TestAnim.frames['0x2004'][1].moduleTag='0x1004'TestAnim.frames['0x2004'][1].yOffset=0TestAnim.frames['0x2004'][1].xOffset=0TestAnim.frames['0x2005']={}TestAnim.frames['0x2005'][1] = {}TestAnim.frames['0x2005'][1].moduleTag='0x1005'TestAnim.frames['0x2005'][1].yOffset=0TestAnim.frames['0x2005'][1].xOffset=0-- animsTestAnim.anims['0x3001']={}TestAnim.anims['0x3001'][1] = {}TestAnim.anims['0x3001'][1].frameTag='0x2000'TestAnim.anims['0x3001'][1].yOffset=0TestAnim.anims['0x3001'][1].duration=1TestAnim.anims['0x3001'][1].xOffset=0TestAnim.anims['0x3001'][2] = {}TestAnim.anims['0x3001'][2].frameTag='0x2001'TestAnim.anims['0x3001'][2].yOffset=0TestAnim.anims['0x3001'][2].duration=1TestAnim.anims['0x3001'][2].xOffset=0TestAnim.anims['0x3001'][3] = {}TestAnim.anims['0x3001'][3].frameTag='0x2002'TestAnim.anims['0x3001'][3].yOffset=0TestAnim.anims['0x3001'][3].duration=1TestAnim.anims['0x3001'][3].xOffset=0TestAnim.anims['0x3000']={}TestAnim.anims['0x3000'][1] = {}TestAnim.anims['0x3000'][1].frameTag='0x2000'TestAnim.anims['0x3000'][1].yOffset=-98TestAnim.anims['0x3000'][1].duration=1TestAnim.anims['0x3000'][1].xOffset=-70TestAnim.anims['0x3000'][2] = {}TestAnim.anims['0x3000'][2].frameTag='0x2001'TestAnim.anims['0x3000'][2].yOffset=-89TestAnim.anims['0x3000'][2].duration=8TestAnim.anims['0x3000'][2].xOffset=-70TestAnim.anims['0x3000'][3] = {}TestAnim.anims['0x3000'][3].frameTag='0x2002'TestAnim.anims['0x3000'][3].yOffset=-86TestAnim.anims['0x3000'][3].duration=1TestAnim.anims['0x3000'][3].xOffset=-76TestAnim.anims['0x3000'][4] = {}TestAnim.anims['0x3000'][4].frameTag='0x2003'TestAnim.anims['0x3000'][4].yOffset=-73TestAnim.anims['0x3000'][4].duration=1TestAnim.anims['0x3000'][4].xOffset=-54TestAnim.anims['0x3000'][5] = {}TestAnim.anims['0x3000'][5].frameTag='0x2004'TestAnim.anims['0x3000'][5].yOffset=-73TestAnim.anims['0x3000'][5].duration=1TestAnim.anims['0x3000'][5].xOffset=-72TestAnim.anims['0x3000'][6] = {}TestAnim.anims['0x3000'][6].frameTag='0x2005'TestAnim.anims['0x3000'][6].yOffset=-64TestAnim.anims['0x3000'][6].duration=1TestAnim.anims['0x3000'][6].xOffset=-78


AuroraGT 除了 sprite 编辑器外,还有个 Game编辑器,和 Map 编辑器的功能。

这两个编辑器我还不太明白具体的用法。将来了解一下,如果好用的话,我会再搞相应的 python脚本 去导出这两种工具的 结果文件。


记录结束,赶紧睡了。




0 0
原创粉丝点击