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

制作一款打飞机游戏48:敌人转向

射击功能

有一个重要的功能我们还没实现,那就是射击。目前,敌人还不能射击,这显然是不行的。因此,我们决定添加一个射击命令,暂时用一个显示圆圈的方式来表示射击动作。

编程语言的调试

有趣的是,我们创造了自己的编程语言,现在还需要为它编写调试工具,以确保我们编写的代码没有bug。这听起来有点讽刺,但确实是必要的。

射击命令的实现

我们决定将这个射击命令命名为“fir”(fire的缩写)。当我们执行这个命令时,敌人会发射一个子弹,尽管现在我们还不知道子弹的具体类型和参数。我们会在后续的开发中逐步完善这些细节。

射击动画与效果

为了让射击效果更逼真,我们决定在敌人身上添加一个“muzzle flash”(枪口闪光)效果。这个效果会跟随敌人移动,并在射击时显示。我们还设置了一个简单的逻辑,当闪光效果的年龄(存在时间)超过一定值时,就将其删除。

无限循环的问题

在开发过程中,我们遇到了一个无限循环的问题。由于“do brain”函数是递归的,如果在“brain”中没有适当的等待命令来中断循环,就会导致程序陷入无限循环。为了解决这个问题,我们添加了一个深度检查机制,当递归深度超过一定值时,就停止执行。

敌人的转向与动画

接下来,我们想让敌人能够执行转向动作。我们通过设置敌人的朝向(heading)和速度(speed)来实现这一点。为了让转向动作更自然,我们还引入了动画速度(ASP)和动画方向(ADR)的概念,使敌人的移动更加平滑。

射击后撤退的动作

我们尝试实现一个“射击后撤退”的动作,但效果并不理想。这个问题我们会在下一集中继续探讨。

代码的执行状态显示

为了方便调试,我们决定在编辑器中添加一个功能,显示当前正在执行的代码行。我们通过添加一个可移动的红色线条来实现这一点,当代码执行到某一行时,这条线就会移动到对应的位置。

pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
--todo-- goal
-- 5 snek
-- 6 bumrush
-- 7 boss-- todofunction _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","fir","adr"}execy=0scroll=0enemies={}muzz={}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)end-- temp muzzle flashesfor m in all(muzz) dom.r-=1if m.en thencircfill(m.en.x,m.en.y,m.r,7)endif m.r<=0 thendel(muzz,m)endenddrawmenu()line(1,execy,1,execy+6,9)
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={}execy=-16if 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 doif enemies[1] thenlocal myen=enemies[1]if myen.brain==selbrain and myen.bri==i thenexecy=ly-9endendlocal 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,depth)--★ remove robustnessif braincheck(e)==false then return endlocal depth=depth or 1if depth>100 thenif #msg>0 thenmsg[1].t=5elseadd(msg,{txt="infinite loop",t=5})endreturnend -- robustness code 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=="adr" then--animate directione.adrt=par1e.adrs=par2elseif cmd=="got" then--gotoe.brain=par1e.bri=par2-3elseif cmd=="fir" then--firefirebul(e,par1,par2)else--★ extra robustnessreturnende.bri+=3if quit then return enddobrain(e,depth+1)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=nilendendif e.adrt thene.ang+=e.adrsif abs(e.adrt-e.ang)<abs(e.adrs) thene.ang=e.adrte.adrt=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
endfunction firebul(_en,par1,par2)add(muzz,{en=_en,r=8})
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
0000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

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

相关文章:

  • 嵌入式学习笔记 D20 :单向链表的基本操作
  • 3DMAX脚本病毒Spy CA查杀方法
  • 计算机网络笔记(二十八)——4.10软件定义网络SDN简介
  • 【0415】Postgres内核 释放指定 memory context 中所有内存 ④
  • 5.14 BGP作业
  • Linux操作系统实战:进程创建的底层原理(转)
  • 朱老师, 3518e系列,第三季
  • 【Python】杂乱-[代码]Python 替换字符串中相关字符的方法
  • 容器安全-核心概述
  • OpenCV人脸识别LBPH算法原理、案例解析
  • Codeforces Round 1003 (Div. 4)
  • 分布式一致性协议Raft
  • 动物乐园-第16届蓝桥第5次STEMA测评Scratch真题第5题
  • 11-SGM41299-TEC驱动芯片--40℃至+125℃-3A
  • 1. Go 语言环境安装
  • 数据清洗的艺术:如何为AI模型准备高质量数据集?
  • 《Python星球日记》 第71天:命名实体识别(NER)与关系抽取
  • 拓展篇、github的账号创建
  • Oracle中的select1条、几条、指定范围的语句
  • 【证书与信任机制​】证书透明度(Certificate Transparency):如何防止恶意证书颁发?​​
  • 【1000以内具有12个以上因子的整数并输出它的因子】2021-12-27
  • 如何在Mac电脑上的VScode去配置C/C++环境
  • 生成式AI:人工智能的新纪元
  • 请求内存算法题
  • 综述:拓扑材料的热磁性质
  • WordPress 和 GPL – 您需要了解的一切
  • 【leetcode】349. 两个数组的交集
  • WindTerm终端工具功能与优缺点分析
  • mysql的一个缺点
  • libmemcached库api接口讲解一