雖然我們基本上已經重建了Axel編輯器,但我不想直接使用它。我想創建一個真正適合我們當前目的的編輯器,那就是編輯精靈(sprites)。這將是今天的一個大目標——創建一個基于模板的編輯器,用它作為我們實際編輯器的起點。
細節調整
在開始之前,有一些小細節我想修復。比如,滾動功能現在不太靈敏,尤其是在屏幕左側邊緣。我們需要讓滾動對左側邊緣更敏感一些。通過調整滾動X的值,我們現在已經解決了這個問題,使得滾動更加順暢。
消息系統優化
另一個我不喜歡的地方是,當我們導出時,它只使用一個調試系統來顯示消息。我希望有一個內置的更正式的消息系統,消息可以格式化并在一段時間后自動消失。因此,我決定添加一個MSG對象來處理這些消息,并在屏幕上顯示它們,每條消息顯示兩秒鐘后自動消失。
編輯器界面優化
我注意到,當列表項很多時,滾動到底部會變得非常繁瑣。因此,我決定添加鼠標滾輪滾動功能,這樣可以更快速地滾動列表。通過調整狀態變量m_scroll
,我們已經實現了這一功能。
創建精靈編輯器
現在,我想基于之前的編輯器模板,創建一個專門用于編輯精靈的編輯器。我將其命名為“Sprite Edit”。在這個編輯器中,我將保留表格視圖,但同時創建一個新的視圖來編輯精靈。這個新視圖將被稱為“列表視圖”。
列表視圖實現
在列表視圖中,我將顯示所有精靈的列表,每個精靈占據一行。用戶可以通過滾動快速瀏覽所有精靈,并通過選擇某個精靈來編輯它。我已經實現了刷新列表和繪制列表的功能,現在用戶可以看到一個簡潔的精靈列表。
顯示精靈預覽
為了讓用戶能夠直觀地看到他們正在編輯的精靈,我決定在列表視圖中添加精靈預覽功能。當用戶選擇某個精靈時,程序將在屏幕上繪制該精靈的預覽圖。為了實現這一點,我使用了mspr
函數來從精靈表中獲取精靈數據,并在屏幕上繪制它們。
中心點標記
為了讓用戶更清楚地了解精靈的中心點位置,我決定在精靈預覽圖上添加中心點標記。我使用了一個小紅點來表示精靈的中心點,并通過閃爍來引起用戶的注意。此外,我還繪制了從屏幕中心到精靈中心點的虛線,以幫助用戶更準確地定位精靈。
新增精靈功能
接下來,我實現了新增精靈的功能。用戶可以通過點擊底部的“+”按鈕來創建一個新的精靈條目。為了確保新創建的精靈條目是有效的,我添加了足夠的默認數據(如位置、寬度、高度和偏移量)。
編輯精靈模式
最后,我創建了一個編輯精靈的模式。在這個模式下,用戶可以選擇一個精靈并進入編輯狀態。我將編輯精靈的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=myspr----------------------debug={}msg={}_drw=draw_list_upd=update_listmenuitem(1,"export",export)reload(0x0,0x0,0x2000,"cowshmup.p8")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()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 selspr thenmspr(selspr,63,63)endif (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()local mymnu=menu[cury][curx]if mymnu.cmdy thenmspr(mymnu.cmdy,63,63)endif (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()
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_editendend
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+1elseif 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-- enterlocal mymnu=menu[cury][curx]poke(0x5f30,1)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_tablereturnelseif 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
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={}
endfunction 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), }})
end__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
0000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000