制作一款打飞机游戏37:调度器预览
在次里,我们要创建UFO(不明飞行物)。没错,这就是我的目标,我只想创建UFO。
挑战部分
这个挑战是:你看那些矩形,它们应该是敌人,但不应该只是矩形的敌人,它们应该是UFO。所以,我们今天的目标是用实际的UFO替换这些矩形。
创建一个UFO不仅仅是画出它的形状,还需要考虑驱动它出现的所有系统,并将这些系统整合到编辑器中。
实现过程
首先,我们需要考虑UFO作为敌人的所有相关系统。我们有一个N Lib系统,它类似于敌人的“图书馆”,存储了敌人的数据。这些数据中包含了动画信息,而动画本身又依赖于我们的精灵系统。所以,为了让一个UFO出现在屏幕上,我们需要将这三个系统整合到编辑器中。
接下来,我开始从我们的射击游戏中“窃取”一些现成的函数,这样可以节省很多时间。我复制了绘制精灵、绘制碰撞框等函数,并将它们添加到编辑器中。
通过一系列的编码和调试,我成功地在屏幕上绘制出了UFO,并且让它们能够动起来。但是,很快我就发现了一个问题:敌人的Y轴位置有些模糊,不清楚它们是从屏幕外同一位置不同时间出现,还是从不同位置同时出现。
功能扩展
为了解决这个问题,我决定添加一个新功能:允许玩家通过点击鼠标来生成敌人。这样做可以直观地看到敌人的生成位置,并帮助我们更好地调整系统。
在实现这个功能的过程中,我又遇到了一个新问题:生成的敌人并没有按照预期的顺序出现。经过检查,我发现是因为敌人生成的时间表是乱序的。为了解决这个问题,我实现了一个简单的排序算法——冒泡排序,来确保敌人按照正确的顺序生成。
现在,我们已经能够在编辑器中创建和生成UFO敌人了,但编辑器还有一些需要完善的地方。比如,我需要添加删除敌人的功能,允许玩家创建不同类型的敌人,以及能够移动已经生成的敌人。
pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
--show cursor
--move the cursor
--backspacefunction _init()--- customize here ---#include shmup_sched.txtfile="shmup_sched.txt"arrname="sched"data=sched#include shmup_mapsegs.txt#include shmup_enlib.txt#include shmup_anilib.txt#include shmup_myspr.txt----------------------debug={}msg={}_drw=draw_map_upd=update_mapmenuitem(1,"export",export)reload(0x0,0x0,0x2000,"cowshmup.p8")reload(0x1000, 0x1000, 0x2000, "cowshmup.p8")curx=1cury=1scrolly=0scrollx=0scroll=0xscroll=0poke(0x5f2d, 1)t=0
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()t+=1dokeys()domouse()mscroll=stat(36)_upd()
endfunction dokeys()if stat(30) thenkey=stat(31)if key=="p" thenpoke(0x5f30,1)endelsekey=nilendendfunction domouse()mousex=stat(32)mousey=stat(33)if stat(34)==0 thenclkwait=falseendclkl=falseclkr=falseif not clkwait thenif stat(34)==1 thenclkl=trueclkwait=trueelseif stat(34)==2 thenclkl=trueclkwait=true endendend
-->8
--drawfunction draw_map()cls(2)for i=1,#mapsegs dolocal segnum=mapsegs[i]local sx=segnum\4*18local sy=segnum%4*8map(sx,sy,xscroll,scroll-((i-2)*64),18,8)endcamera(-xscroll,0)for sch in all(sched) dolocal schx=sch[3]local schy=sch[4]+scroll-sch[1]local en=enlib[sch[2]]local ani=anilib[en[1]]mspr(cyc(t,ani,en[2]),schx,schy)--rectfill(schx,schy,schx+16,schy+16,8)endcamera()drawcur(mousex,mousey)--debug[1]=scrollendfunction draw_table()cls(2)--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)end--[[for i=1,#data dofor j=1,#data[i] dobgprint(data[i][j],2+18*j,2+8*i,7)endend]]
endfunction drawcur(cx,cy)local col=rnd({6,7})line(cx,cy-1,cx,cy-2,col)line(cx,cy+1,cx,cy+2,col)line(cx-1,cy,cx-2,cy,col)line(cx+1,cy,cx+2,cy,col)end
-->8
--updatefunction update_map()refresh_map()scroll+=mscroll*8xscroll=mid(0,(mousex-10)/108,1)\-0.0625if btnp(⬇️) thenscroll-=1endif btnp(⬆️) thenscroll+=1 endif clkl thenlocal sch={}sch[1]=scroll-mousey-8sch[2]=1sch[3]=mousex-xscrollsch[4]=-8add(sched,sch)endif key=="t" then_drw=draw_table_upd=update_table end
endfunction update_table()refresh_table()if key=="m" then_drw=draw_map_upd=update_map endif 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 _x,_y,_w,_h,_ox,_oy,_fx,_nx=unpack(myspr[si])sspr(_x,_y,_w,_h,sx-_ox,sy-_oy,_w,_h,_fx==1)if _fx==2 thensspr(_x,_y,_w,_h,sx-_ox+_w,sy-_oy,_w,_h,true)endif _nx thenmspr(_nx,sx,sy)end
endfunction msprc(si,sx,sy)local _x,_y,_w,_h,_ox,_oy,_fx,_nx=unpack(myspr[si])rect(sx-_ox,sy-_oy,sx-_ox+_w-1,sy-_oy+_h-1,rnd({8,14,15}))
endfunction drawobj(obj)mspr(cyc(obj.age,obj.ani,obj.anis),obj.x,obj.y)--★if coldebug and obj.col thenmsprc(obj.col,obj.x,obj.y)end
endfunction cyc(age,arr,anis)local anis=anis or 1return arr[(age\anis-1)%#arr+1]
endfunction sortsched()if #sched<2 then return endrepeatlocal switch=falsefor i=1,#sched-1 doif sched[i][1]>sched[i+1][1] then sched[i],sched[i+1]=sched[i+1],sched[i]switch=trueendenduntil switch==falseend
-->8
--i/o
function export()sortsched()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
--uifunction refresh_map()menu={}
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