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

制作一款打飞机游戏47:跳转

编辑器的问题

我们开始为不同的敌人编写一些行为,到目前为止进展顺利,一切都很棒。但上次我们遇到了一些问题,我们发现在这个编辑器中编写代码有时有点困难,因为当你想要在某行之间插入内容时,你不得不删除一切然后重新构建。

我在想,如果我们能在每行的末尾添加一个加号按钮会怎么样呢?就像Excel编辑器中的列表视图那样,每行都有一个加号按钮,点击它就可以在下面添加一行。我觉得这主意不错,当然,如果你们有更好的解决方案,欢迎告诉我。


实现加号按钮

好的,现在我们在每行的末尾都添加了一个加号按钮。这样,当我们按下这个按钮时,就可以在下面添加一行了。不过,目前这个加号总是显示在所有行的末尾,而不仅仅是当前选中的行。我想我们可以通过一些智能检测来实现,只有当光标在当前行时,才显示该行的加号按钮。

经过一番尝试,我成功实现了这个功能。现在,只有当光标停留在某行时,该行的末尾才会显示加号按钮,这样我们就可以方便地在那里插入新行了。


调整敌人移动逻辑

接下来,我们要解决敌人移动速度和位置控制的问题。目前,敌人的移动速度和它们在屏幕上到达的位置是相关联的,因为我们有一个weight语句来控制这些。但这样很不方便,因为每次我们想要调整敌人的移动速度时,还得同时调整weight值。

我想到了一个更好的办法,那就是不再等待一定数量的帧,而是等待敌人移动了一定数量的像素后再继续执行代码。这样,我们就可以只调整速度值,而不用担心位置会发生变化了。

经过一番修改和测试,我成功实现了这个功能。现在,无论我们如何调整敌人的移动速度,它们都会在屏幕上到达相同的位置。


引入“跳转”命令

最后,我想引入一个非常强大的新命令——“跳转”(Go To)。这是一个在旧式编程中常用的命令,它允许程序直接跳转到代码中的某一行开始执行。虽然现代编程中很少使用这种命令,因为它可能会导致代码难以理解和维护,但在我们的游戏中,它可能会有一些有趣的用途。

例如,在BOSS战中,我们可以将BOSS的不同阶段分成多个“大脑”(Brain),然后在每个阶段的末尾使用“跳转”命令切换到下一个“大脑”。这样,我们就可以将BOSS战分成多个部分来编写,而不需要在一个巨大的“大脑”中处理所有逻辑。

当然,使用“跳转”命令也需要小心谨慎,因为它可能会引入一些难以调试的错误。所以,我还实现了一些额外的检查来确保“跳转”命令的正确性。

pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
--todo
-- animate speed-- goal
-- 3 turnaround
-- 4 shoot on retreat
-- 5 snek
-- 6 bumrush
-- 7 boss-- todo
--- change brains?!function _init()--- customize here ---#include shmup_brains.txt#include shmup_brains_meta.txtfile="shmup_brains.txt"filem="shmup_brains_meta.txt"arrname="brains"data=brains#include shmup_myspr.txt#include shmup_enlib.txt#include shmup_anilib.txt----------------------debug={}msg={}_drw=draw_brain_upd=update_brainmenuitem(1,"export",export)reload(0x0,0x0,0x2000,"cowshmup.p8")curx=1cury=1scrolly=0scrollx=0selbrain=1cmdlist={"hed","wai","asp","got"}scroll=0enemies={}poke(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)endendfunction _update60()dokeys()mscroll=stat(36)scroll+=0.2scroll=scroll%16_upd()
endfunction dokeys()if stat(30) thenkey=stat(31)if key=="p" thenpoke(0x5f30,1)endelsekey=nilendend
-->8
--drawfunction draw_brain()cls(13)if flr(scroll)%2==0 thenfillp(0b0000111100001111.1)elsefillp(0b1111000011110000.1)endfor i=0,7 doline(i*16,0,i*16,128,5)endfillp(▥)for i=-1,7 doline(0,i*16+scroll,128,i*16+scroll,5)endfillp()for e in all(enemies) dodrawobj(e)enddrawmenu()
endfunction draw_table()cls(2)--spr(0,0,0,16,16)drawmenu()--[[for i=1,#data dofor j=1,#data[i] dobgprint(data[i][j],2+18*j,2+8*i,7)endend]]
endfunction drawmenu()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 menui thenfor i=1,#menui dofor j=1,#menui[i] dolocal mymnui=menui[i][j]local c=mymnui.c or 13if i==cury and j==curx thenc=7if _upd==upd_type thenc=0endend bgprint(mymnui.w,mymnui.x+scrollx,mymnui.y+scrolly,13)   bgprint(mymnui.txt,mymnui.x+scrollx,mymnui.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
end-->8
--updatefunction update_setup()refresh_setup()if btnp(⬆️) thencury-=1endif btnp(⬇️) thencury+=1endcury=mid(2,cury,#menu)curx=2if btnp(❎) thenlocal mymnu=menu[cury][curx]if mymnu.cmd=="meta" then_upd=upd_typetypetxt=tostr(mymnu.txt)typecur=#typetxt+1callback=enter_metaendendif btnp(🅾️) then_upd=update_brainrefresh_brain()returnendif data[selbrain] thenif #enemies==0 thenlocal selmeta=meta[selbrain]if enlib[selmeta[1]]!=nil thenspawnen(selmeta[1],selmeta[2],selmeta[3])end  enddoenemies()elseenemies={}endendfunction update_brain()refresh_brain()if btnp(⬆️) thencury-=1endif btnp(⬇️) thencury+=1endcury=mid(1,cury,#menu)if cury==1 thenif btnp(⬅️) thenselbrain-=1enemies={}endif btnp(➡️) thenselbrain+=1enemies={}endselbrain=mid(1,selbrain,#data+1)elseif btnp(⬅️) thencurx-=1endif btnp(➡️) thencurx+=1endcurx=mid(1,curx,#menu[cury])endif btnp(❎) thenlocal mymnu=menu[cury][curx]if mymnu.cmd=="edit" then_upd=upd_typetypetxt=tostr(mymnu.txt)typecur=#typetxt+1callback=enter_brainelseif mymnu.cmd=="newline" thenadd(data[mymnu.cmdb],"wai",mymnu.cmdi)add(data[mymnu.cmdb],0,mymnu.cmdi+1)add(data[mymnu.cmdb],0,mymnu.cmdi+2)cury+=1curx=1elseif mymnu.cmd=="setup" thenrefresh_setup()_upd=update_setupreturnelseif mymnu.cmd=="newbrain" thenadd(data,{"wai",0,0})add(meta,{1,64,10})endreturn endif data[selbrain] thenif #enemies==0 thenlocal selmeta=meta[selbrain]if enlib[selmeta[1]]!=nil thenspawnen(selmeta[1],selmeta[2],selmeta[3])endenddoenemies()elseenemies={}end
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+1callback=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-- enterpoke(0x5f30,1)callback()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 spacejam(n)local ret=""for i=1,n doret..=" "endreturn ret
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 cyc(age,arr,anis)local anis=anis or 1return arr[(age\anis-1)%#arr+1]
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 onscreen(obj)if obj.x<-8 then return false endif obj.y<-8 then return false endif obj.x>136 then return false endif obj.y>136 then return false end return true
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)local s="meta=split2d\""for i=1,#meta doif i>1 thens..="|"endfor j=1,#meta[i] doif j>1 thens..=","ends..=meta[i][j]endends..="\""printh(s,filem,true)add(msg,{txt="exported!",t=120})--debug[1]="exported!"
end
-->8
--uifunction refresh_setup()menu={}menui={}add(menu,{{txt="brain "..selbrain,w="        ",cmd="",x=3,y=3,c=13  }})local cap={"en:"," x:"," y:"}local selmeta=meta[selbrain]for i=1,3 dolocal lne={}add(lne,{txt=cap[i],w="  ",cmd="",x=3,y=3+i*6+2,c=13  })add(lne,{txt=selmeta[i],w="   ",cmd="meta",cmdy=i,x=3+12,y=3+i*6+2,c=13  })add(menu,lne)endendfunction refresh_brain()menu={}menui={}if selbrain>#data then--empty brain slotadd(menu,{{txt="< new brain ",w="           ",cmd="newbrain",x=3,y=3,c=13  }}) returnendadd(menu,{{txt="< brain "..selbrain.." >",w="            ",cmd="head",x=3,y=3,c=13  }}) add(menu,{{txt="◆setup",w="       ",cmd="setup",x=3,y=3+8,c=13 }})local mybra=brains[selbrain]local ly=19for i=1,#mybra,3 dolocal lne={}add(lne,{txt=mybra[i],w="   ",cmd="edit",cmdi=i,cmdb=selbrain,x=3,y=ly,c=13    })local lx=3+14 for j=1,2 dolocal mytxt=tostr(mybra[i+j])add(lne,{txt=mytxt,w=spacejam(#mytxt),cmd="edit",cmdi=i+j,cmdb=selbrain,x=lx,y=ly,c=13    })lx+=#mytxt*4+2endif cury==#menu+1 thenadd(lne,{txt="+",w=" ",cmd="newline",cmdi=i+3,cmdb=selbrain,x=lx,y=ly,c=13    })endadd(menu,lne)ly+=8endif menu[cury] thenlocal mymnu=menu[cury][curx]if mymnu and mymnu.cmd=="edit" thenadd(menui,{{txt="i:"..mymnu.cmdi,w="    ",cmd="",x=3,y=120,c=15    }})endend
endfunction refresh_table()menu={}menui={}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=typetxtif typeval==nil or typeval=="" 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=0end   data[mymnu.cmdy][mymnu.cmdx]=typeval_upd=update_table
endfunction enter_brain()_upd=update_brainlocal mymnu=menu[cury][curx]local typeval=typetxtenemies={}if mymnu.cmdi%3==1 then--editing command entryif typeval=="" thendeli(data[mymnu.cmdb],mymnu.cmdi)deli(data[mymnu.cmdb],mymnu.cmdi)deli(data[mymnu.cmdb],mymnu.cmdi)if #data[mymnu.cmdb]==0 thendeli(data,mymnu.cmdb)deli(meta,mymnu.cmdb)add(msg,{txt="brain deleted!",t=120})endreturnelse local found=false for c in all(cmdlist) doif typeval==c thenfound=trueend endif not found thentypeval="wai"endendelse--editing parameterstypeval=tonum(typetxt)if typeval==nil thentypeval=0endenddata[mymnu.cmdb][mymnu.cmdi]=typevalendfunction enter_meta()_upd=update_setuplocal mymnu=menu[cury][curx]local typeval=tonum(typetxt)enemies={}if typeval==nil thentypeval=0endmeta[selbrain][mymnu.cmdy]=typevalend
-->8
--enemyfunction dobrain(e)--★ remove robustnessif braincheck(e)==false then return endlocal mybra=brains[e.brain]local quit=falseif e.bri<#mybra thenlocal cmd=mybra[e.bri]local par1=mybra[e.bri+1]local par2=mybra[e.bri+2]if cmd=="hed" then--set heading / speede.ang=par1e.spd=par2e.aspt=nilelseif cmd=="wai" then--wait x framese.wait=par1e.dist=par2quit=trueelseif cmd=="asp" then--animate speede.aspt=par1e.asps=par2elseif cmd=="got" then--★ remove robustnesse.brain=par1e.bri=par2-3else--★ extra robustnessreturnende.bri+=3if quit then return enddobrain(e)end
endfunction doenemies()for e in all(enemies) doif e.wait>0 thene.wait-=1elseif e.dist<=0 thendobrain(e)endif e.aspt thene.spd+=e.aspsif abs(e.aspt-e.spd)<abs(e.asps) thene.spd=e.aspte.aspt=nilendende.sx=sin(e.ang)*e.spde.sy=cos(e.ang)*e.spde.dist=max(0,e.dist-abs(e.spd))e.x+=e.sxe.y+=e.sye.age+=1if not onscreen(e) thendel(enemies,e)endendendfunction spawnen(eni,enx,eny)local en=enlib[eni]add(enemies,{x=enx,y=eny,ani=anilib[en[1]],anis=en[2],sx=0,sy=0,ang=0,spd=0,brain=selbrain,bri=1,age=0,flash=0,hp=en[4],col=en[5],wait=0,dist=0})endfunction braincheck(e)if brains[e.brain]==nil thenif #msg>0 thenmsg[1].t=5elseadd(msg,{txt="bad brain "..e.brain,t=5})endreturn falseendlocal mybra=brains[e.brain]if e.bri<1 thenif #msg>0 thenmsg[1].t=5elseadd(msg,{txt="brain command index < 1",t=5})endreturn falseelseif e.bri<#mybra thenlocal cmd=mybra[e.bri]local found=falsefor c in all(cmdlist) doif c==cmd thenfound=trueendendif found==false thenif #msg>0 thenmsg[1].t=5elseadd(msg,{txt="bad command "..cmd,t=5})endreturn falseendendreturn true
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
0000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

http://www.xdnf.cn/news/433153.html

相关文章:

  • ESP32C3连接wifi
  • java架构设计
  • 笔记项目 day02
  • 蓝卓生态赋能“星链计划”火热招募中
  • CAElinux系统详解
  • 保护数据安全的关键一步-安装加密软件
  • 进程与线程:07 CPU调度策略
  • python无法导入自己的包
  • Qt 样式表qss学习
  • 6大住宅代理IP服务商测评(2025更新)
  • 【xxl-job调度器的源码分析】
  • 结构化数据处理
  • GPU服务器集群部署
  • 【越狱检测】HSF: Defending against Jailbreak Attacks with Hidden State Filtering
  • c语言第一个小游戏:贪吃蛇小游戏06
  • 逃离 AI 困境:保障 “说不” 的权利,守护数字自由
  • Selenium自动化测试
  • git cherry-pick和git stash命令详解
  • Python爬虫如何应对网站的反爬加密策略?
  • 第九届御网杯网络安全大赛初赛WP
  • 多线程与并发之进程
  • Focal Loss 原理详解及 PyTorch 代码实现
  • 运行Spark程序-在shell中运行
  • 思路解析:第一性原理解 SQL
  • 2025.5.13山东大学软件学院计算机图形学期末考试回忆版本
  • msyql8.0.xx忘记密码解决方法
  • 2025.05.11阿里云机考真题算法岗-第二题
  • 重置集群(有异常时)
  • Spring 集成 SM4(国密对称加密)
  • Springboot | 如何上传文件