当前位置: 首页 > news >正文

制作一款打飞机游戏27:精灵编辑器UI

继续开发我们的编辑器——Sprit Edit。我们已经创建了这个小编辑器,它可以显示很多精灵(sprites),并且我们可以遍历所有精灵。这真的很棒,我们可以创建新的精灵,这也不错。但是,唉,我们目前还不能编辑单个精灵。这就是我们要做的事情——创建一个用户界面(UI)来编辑单个精灵。

编辑器的设计理念

这次,我的想法是,当你跳转到一个精灵时,我想看到精灵的所有值,并且能够单独编辑每个值。这有点像垂直布局,而不是水平布局,因为水平布局最终会因为空间不足而显得混乱,特别是当数字很长时。而且,我认为重要的是,当你编辑时,你应该能看到你正在编辑的内容,这样才有即时的反馈。

实现过程

首先,我们要在顶部菜单添加一个项目,显示当前正在编辑的精灵的名称。然后,我们要列出当前精灵的所有值。我们需要至少显示八个值,并且要检查是否有nil值。

接下来,我们要为每个值添加一个文本框,并在文本框后显示对应的标签(如X、Y、高度等),以便用户知道每个值代表什么。

遇到的问题与解决

在开发过程中,我遇到了一些问题。例如,当我在不同模式之间切换时,程序有时会崩溃。原因是我在切换模式后没有刷新界面。我通过添加刷新函数解决了这个问题。

另一个问题是,当编辑nil值时,我想在文本框中显示一个空字符串,而不是nil。这需要我在获取数据时做一些额外的检查。

后续计划

现在,我们的编辑器已经可以基本工作了,但还有一些小细节需要调整。例如,我们还需要添加删除精灵的功能,以及处理一些可能导致程序崩溃的边界情况(如设置下一个精灵为当前精灵时导致的无限循环)。

我希望大家能发挥自己的创造力,思考如何设计自己的UI,并尝试实现这些功能。

pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
function _init()--- customize here ---#include shmup_myspr.txtfile="shmup_myspr.txt"arrname="myspr"data=mysprreload(0x0,0x0,0x2000,"cowshmup.p8")----------------------debug={}msg={}_drw=draw_list_upd=update_listmenuitem(1,"export",export)curx=1cury=1scrolly=0scrollx=0poke(0x5f2d, 1)
endfunction _draw()_drw()if #msg>0 thenbgprint(msg[1].txt,64-#msg[1].txt*2,80,14)msg[1].t-=1if msg[1].t<=0 thendeli(msg,1)end  end-- debug --cursor(4,4)color(8)for txt in all(debug) doprint(txt)end
endfunction _update60()dokeys()mscroll=stat(36)_upd()
endfunction dokeys()if stat(30) thenkey=stat(31)if key=="p" thenpoke(0x5f30,1)endelsekey=nilendend
-->8
--draw
function draw_edit()-- backgroundfillp(0b11001100001100111100110000110011)rectfill(0,0,127,127,33)fillp(▒)line(63,0,63,127,13)line(0,63,127,63,13)fillp()draw_menu()-- draw spriteif selspr thenmspr(selspr,63,63)end-- blinking dotif (time()*2)%1<0.5 thenpset(63,63,rnd({8,13,7,15}))end
endfunction draw_list()fillp(0b11001100001100111100110000110011)rectfill(0,0,127,127,33)fillp(▒)line(63,0,63,127,13)line(0,63,127,63,13)fillp()draw_menu()if (time()*2)%1<0.5 thenpset(63,63,rnd({8,13,7,15}))end
endfunction draw_table()cls(2)draw_menu()
endfunction draw_menu()--spr(0,0,0,16,16)if menu thenfor i=1,#menu dofor j=1,#menu[i] dolocal mymnu=menu[i][j]local c=mymnu.c or 13if i==cury and j==curx thenc=7if _upd==upd_type thenc=0endendbgprint(mymnu.w,mymnu.x+scrollx,mymnu.y+scrolly,13)   bgprint(mymnu.txt,mymnu.x+scrollx,mymnu.y+scrolly,c) endendendif _upd==upd_type thenlocal mymnu=menu[cury][curx]local txt_bef=sub(typetxt,1,typecur-1)local txt_cur=sub(typetxt,typecur,typecur)local txt_aft=sub(typetxt,typecur+1)txt_cur=txt_cur=="" and " " or txt_cur if (time()*2)%1<0.5 thentxt_cur="\^i"..txt_cur.."\^-i"endlocal txt=txt_bef..txt_cur..txt_aftbgprint(txt,mymnu.x+scrollx,mymnu.y+scrolly,7)endend-->8
--update
function update_edit()refresh_edit()if btnp(⬆️) thencury-=1endif btnp(⬇️) thencury+=1endcury=(cury-1)%#menu+1cury-=mscrollcury=mid(1,cury,#menu)if cury==1 thencurx=1if btnp(⬅️) thenselspr-=1elseif btnp(➡️) thenselspr+=1endselspr=mid(1,selspr,#data)	elsecurx=2endif btnp(🅾️) then_drw=draw_list_upd=update_listrefresh_list()cury=selsprcurx=1returnendif btnp(❎) thenlocal mymnu=menu[cury][curx]if mymnu.cmd=="editval" then_upd=upd_typelocal s=tostr(data[mymnu.cmdy][mymnu.cmdx])if s==nil thens=""endtypetxt=stypecur=#typetxt+1typecall=enter_editendend
endfunction update_list()refresh_list()if btnp(⬆️) thencury-=1endif btnp(⬇️) thencury+=1endcury=(cury-1)%#menu+1cury-=mscrollcury=mid(1,cury,#menu)curx=1local mymnu=menu[cury][curx]if mymnu.y+scrolly>110 thenscrolly-=4endif mymnu.y+scrolly<10 thenscrolly+=4endscrolly=min(0,scrolly)if mymnu.x+scrollx>110 thenscrollx-=2endif mymnu.x+scrollx<20 thenscrollx+=2endscrollx=min(0,scrollx)if btnp(❎) thenlocal mymnu=menu[cury][curx]if mymnu.cmd=="newline" thenadd(data,{0,0,0,0,0,0})elseif mymnu.cmd=="editspr" thenselspr=mymnu.cmdy_upd=update_edit_drw=draw_editrefresh_edit()cury=1endend
endfunction update_table()refresh_table()if btnp(⬆️) thencury-=1endif btnp(⬇️) thencury+=1endcury=(cury-1)%#menu+1cury-=mscrollcury=mid(1,cury,#menu)if btnp(⬅️) thencurx-=1endif btnp(➡️) thencurx+=1endif cury<#menu thencurx=(curx-2)%(#menu[cury]-1)+2elsecurx=1endlocal mymnu=menu[cury][curx]if mymnu.y+scrolly>110 thenscrolly-=4endif mymnu.y+scrolly<10 thenscrolly+=4endscrolly=min(0,scrolly)if mymnu.x+scrollx>110 thenscrollx-=2endif mymnu.x+scrollx<20 thenscrollx+=2endscrollx=min(0,scrollx)if btnp(❎) thenlocal mymnu=menu[cury][curx]if mymnu.cmd=="edit" then_upd=upd_typetypetxt=tostr(mymnu.txt)typecur=#typetxt+1typecall=enter_tableelseif mymnu.cmd=="newline" thenadd(data,{0})  elseif mymnu.cmd=="newcell" thenadd(data[mymnu.cmdy],0)endend
endfunction upd_type()if key thenif key=="\r" then-- enter   poke(0x5f30,1)typecall()returnelseif key=="\b" then--backspaceif typecur>1 thenif typecur>#typetxt thentypetxt=sub(typetxt,1,#typetxt-1)elselocal txt_bef=sub(typetxt,1,typecur-2)local txt_aft=sub(typetxt,typecur)typetxt=txt_bef..txt_aftendtypecur-=1endelseif typecur>#typetxt thentypetxt..=keyelselocal txt_bef=sub(typetxt,1,typecur-1)local txt_aft=sub(typetxt,typecur)typetxt=txt_bef..key..txt_aftendtypecur+=1endendif btnp(⬅️) thentypecur-=1endif btnp(➡️) thentypecur+=1endtypecur=mid(1,typecur,#typetxt+1)
end
-->8
--toolsfunction bgprint(txt,x,y,c)print("\#0"..txt,x,y,c)
endfunction split2d(s)local arr=split(s,"|",false)for k, v in pairs(arr) doarr[k] = split(v)endreturn arr
endfunction mspr(si,sx,sy)local ms=myspr[si]sspr(ms[1],ms[2],ms[3],ms[4],sx-ms[5],sy-ms[6],ms[3],ms[4],ms[7]==1)if ms[7]==2 thensspr(ms[1],ms[2],ms[3],ms[4],sx-ms[5]+ms[3],sy-ms[6],ms[3],ms[4],true)endif ms[8] thenmspr(ms[8],sx,sy)end
endfunction spacejam(n)local ret=""for i=1,n doret..=" "endreturn ret
end
-->8
--i/o
function export()local s=arrname.."=split2d\""for i=1,#data doif i>1 thens..="|"endfor j=1,#data[i] doif j>1 thens..=","ends..=data[i][j]endends..="\""printh(s,file,true)add(msg,{txt="exported!",t=120})--debug[1]="exported!"
end
-->8
--ui
function refresh_edit()menu={}add(menu,{{txt="< sprite "..selspr.." >",w="",cmd="sprhead",x=2,y=2}})local lab={"  x:","  y:","wid:","hgt:"," ox:"," oy:"," fx:","nxt:"}for i=1,8 dolocal s=tostr(data[selspr][i])if s==nil thens="[nil]"endadd(menu,{{txt=lab[i],w="    ",x=2,y=3+i*7},{txt=s,w=spacejam(#s),cmd="editval",cmdy=selspr,cmdx=i,x=2+16,y=3+i*7}}) endendfunction refresh_list()menu={}for i=1,#data dolocal lne={}local linemax=#data[i]if i==cury thenlinemax+=1  endadd(lne,{txt="spr "..i,w="",cmd="editspr",cmdy=i,x=2,y=-4+6*i})add(menu,lne)endadd(menu,{{txt=" + ",w="   ",cmd="newline",x=2,y=-4+6*(#data+1)+2, }})
endfunction refresh_table()menu={}for i=1,#data dolocal lne={}local linemax=#data[i]if i==cury thenlinemax+=1  endadd(lne,{txt=i,w="   ",cmd="",x=4,y=-4+8*i,c=2  })for j=1,linemax doif j==#data[i]+1 thenadd(lne,{txt="+",w=" ",cmd="newcell",cmdy=i,x=-10+14*(j+1),y=-4+8*i, })elseadd(lne,{txt=data[i][j],cmd="edit",cmdx=j,cmdy=i,x=-10+14*(j+1),y=-4+8*i,w="   "})endendadd(menu,lne)endadd(menu,{{txt=" + ",w="   ",cmd="newline",x=4,y=-4+8*(#data+1), }})
endfunction enter_table()local mymnu=menu[cury][curx]local typeval=tonum(typetxt)if typeval==nil thenif mymnu.cmdx==#data[mymnu.cmdy] and typetxt=="" then--delete celldeli(data[mymnu.cmdy],mymnu.cmdx)if mymnu.cmdx==1 thendeli(data,mymnu.cmdy)end_upd=update_tablereturnend  typeval=0enddata[mymnu.cmdy][mymnu.cmdx]=typeval_upd=update_tablerefresh_table()
endfunction enter_edit()local mymnu=menu[cury][curx]local typeval=tonum(typetxt)if typeval==nil thentypeval=0enddata[mymnu.cmdy][mymnu.cmdx]=typeval_upd=update_editrefresh_edit()
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
0000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

相关文章:

  • python文本合并脚本
  • G1(Garbage-First)垃圾回收器与JVM内存
  • 闭包与装饰器(python)
  • Go语言企业级项目使用dlv调试
  • 30天通过软考高项-第五天
  • Python+jieba文本分析示例:实现统计《红楼梦》中的人物并生成词云图
  • Golang 类型方法
  • 可视化图解算法:对称的二叉树(判断二叉树是否为对称的)
  • 企业如何构建一个全面的Web安全防护体系
  • AVL树的介绍与学习
  • 【Pandas】pandas DataFrame rfloordiv
  • Python对比两张CAD图并标记差异的解决方案
  • 软件功能设计视角下的能源管理系统功能清单构建与实践
  • LeetCode -- Flora -- edit 2025-04-27
  • PostSwigger Web 安全学习:CSRF漏洞2
  • SpringMVC框架
  • Linux中的31个普通信号
  • Redis03-基础-C#客户端
  • Javase 基础入门 —— 06 final + 单例
  • 数据库MySQL学习——day6(多表查询(JOIN)基础)
  • 我国已形成完整人工智能产业体系,专利申请量位居全球首位
  • 美国政府将暂时恢复部分受影响留学生的合法身份,并将制订新标准
  • 俄罗斯准备在没有先决条件的情况下与乌克兰进行谈判
  • 价格周报|猪价继续回暖:二次育肥热度仍存,对猪价仍有一定支撑
  • 经济日报金观平:充分发挥增量政策的经济牵引力
  • 人民日报任仲平:为什么中国意味着确定性、未来性、机遇性