増殖ゲーム


環境
spalm iアプリ版
spalm more iアプリ版
確認機種
SH-06B
内容
宇宙船を方向キーで上下左右に動かし、選択ボタンでビームを発射します。
アメーバのような敵が次第に増殖していくので、ビームで倒してください。
また、敵もコアからミサイルで攻撃してくるので、うまく避けてください。

補足
敵は、コアの部分(#の文字の部分)にビームを当てると倒せます。100点加算されます。
ビームは、選択ボタンを押し続けると連射になります。

画面右上のレベル(難易度)は、ある程度上がると0になり、敵の攻撃がしばらく弱まります。
その後、レベルの上限が増えて、再度レベルが上がっていきます。

画面はループ構造で、上下左右はつながっており、スクロールします。
(プレイには関係ありませんが、スタート時に左上で点滅している星が、画面の原点です。)

今回、arctanは、近似式(90*|y|)/(|x|+|y|)で計算しています。
0〜90度までをこの式で計算して、場合分けで0〜360度にしています。
ただ、精度についてはあまりよくないらしいです。

履歴
2011-2-7 初版
2011-2-9 プログラムにコメントを追加
2011-2-11 難易度調整(ゲームが進むと敵ミサイル速度が少し上がる)

'プログラム初期化'
WAIT=1;
wd=width;
ht=height;
sw=stwide("0");
sh=sthigh;
soft2("end");
hs=load();
maxy=(ht/sh)-1;
bg1="";
bg2="";
bg3="";
bg4="";
for(i=1;i<=100;i++){
bg1=bg1." ";
bg2=bg2."+";
bg3=bg3."#";
bg4=bg4.">";
}

'ゲーム開始初期化'
label 1000;
sc=0;
k=0;k2=0;
x=10;y=maxy/2+1;
mr=1;mmr=12;mmmr=20;
for(i=1;i<=mmmr;i++){
rf[i]=0;
rx[i]=0;ry[i]=0;
rxd[i]=0;ryd[i]=0;
rr[i]=0;
}
rsp=8;
rtmp=0;
bx=0;bxd=bx*10;
by=1;byd=by*10;
bbgp=1;
for(i=1;i<=50;i++){
bbg[i]=bg1;
}
for(i=1;i<=200;i++){
bbx=abs(rand%100);
bby=abs(rand%50)+1;
bbg[bby]=substr(bbg[bby],0,bbx).".".substr(bbg[bby],bbx+1,99-bbx);
}
cbx=0;cby=0;
cdx=0;cdy=0;
sx=0;sy=0;
sbx=0;sby=0;

'ここからはメインループ'
'画面設定とスコア処理'
label 1001;
lock();
col(0x0000FF);
frect(0,0,wd,ht);
sc=sc+1;
if(sc>1000000){sc=1000000;}
if(sc>hs){hs=sc;}
if((sc%50)==0){
mr=mr+1;
if(mr>mmr){
mr=0;
mmr=min(mmr+2,mmmr);
rsp=min(rsp+1,10);
}
}
if((sc%20)==0){
do{
cbx=abs(rand%100);
cby=abs(rand%50)+1;
cdx=min(abs(cbx-(x+bx)),100-abs(cbx-(x+bx)));
cdy=min(abs(cby-(y+by)),50-abs(cby-(y+by)));
}while(((cdx*cdx)+(cdy*cdy))<=(19*19));
tcircle(cbx,cby,9,bg2);
tcircle(cbx,cby,5,bg3);
}
if((sc%4)<2){
bbg[1]=".".substr(bbg[1],1,99);
}else{
bbg[1]=" ".substr(bbg[1],1,99);
}
col(0xFFFF00);
text("SCORE:".sc,0,0,0);
col(0xFF0000);
text("HI-SCORE:".hs,84,0,0);
col(0xFFFF00);
text("Lv.".mr."/".mmr,192,0,0);

'自機'
k=scan;k2=input(0);
if(k2==262144){end;}
col(0xFFFF00);
text("LL",x*sw,y*sh,0);
text("Oo>",x*sw,(y+1)*sh,0);

'背景スクロール'
bxd=bxd+5*(((k&16384)&&1)-((k&8192)&&1));
byd=byd+5*(((k&32768)&&1)-((k&4096)&&1));
bx=bxd/10;
by=byd/10;
if(bx<0){bx=bx+100;bxd=bxd+1000;}
if(bx>99){bx=bx-100;bxd=bxd-1000;}
if(by<1){by=by+50;byd=byd+500;}
if(by>50){by=by-50;byd=byd-500;}
bbgp=by;
for(i=1;i<=25;i++){
if(bx<=(99-40)){
bg[i]=substr(bbg[bbgp],bx,40);
}else{
bg[i]=substr(bbg[bbgp],bx,100-bx).substr(bbg[bbgp],0,40-(100-bx));
}
bbgp=bbgp+1;
if(bbgp>50){bbgp=1;}
}

'ビーム発射'
if(k==65536){
sy=y+1;
for(sx=x+2;sx<40;sx++){
sbx=sx+bx;
if(sbx>99){sbx=sbx-100;}
sby=sy+by-1;
if(sby>50){sby=sby-50;}
if(strat(bbg[sby],sbx)=="+"){
bbg[sby]=substr(bbg[sby],0,sbx)." ".substr(bbg[sby],sbx+1,99-sbx);
break;
}
if(strat(bbg[sby],sbx)=="#"){
tcircle(sbx,sby,15,bg1);
sc=sc+100;
break;
}
}
if(sx>=40){sx=39;}
bg[sy]=substr(bg[sy],0,x+2).substr(bg4,0,sx-(x+2)+1).substr(bg[sy],sx+1,39-sx);
}

'敵ミサイル'
for(i=1;i<=mmr;i++){
if((rf[i]==0)&&(i<=mr)){
rx[i]=abs(rand%40);
ry[i]=abs(rand%maxy)+1;
if(strat(bg[ry[i]],rx[i])=="#"){
rf[i]=1;
rxd[i]=rx[i]*10;
ryd[i]=ry[i]*10;
rr[i]=tarctan(x,y,rx[i],ry[i]);
}
}
if(rf[i]==1){
rxd[i]=rxd[i]-10*(((k&16384)&&1)-((k&8192)&&1));
ryd[i]=ryd[i]-10*(((k&32768)&&1)-((k&4096)&&1));
rxd[i]=rxd[i]-(rsp*cos(rr[i])/100);
ryd[i]=ryd[i]-(rsp*sin(rr[i])/100);
rx[i]=rxd[i]/10;
ry[i]=ryd[i]/10;
if((rx[i]<0)||(rx[i]>39)||(ry[i]<1)||(ry[i]>25)){
rf[i]=0;
}else{
bg[ry[i]]=substr(bg[ry[i]],0,rx[i])."o".substr(bg[ry[i]],rx[i]+1,39-rx[i]);
'未使用ここから
ホーミング処理
rtmp=tarctan(x,y,rx[i],ry[i])-rr[i];
if((rtmp>0)&&(rtmp<180)){rr[i]=rr[i]+3;}
if((rtmp<0)&&(rtmp>-180)){rr[i]=rr[i]-3;}
if((rtmp>=180)&&(rtmp<360)){rr[i]=rr[i]-3;}
if((rtmp<=-180)&&(rtmp>-360)){rr[i]=rr[i]+3;}
未使用ここまで'
}
}
}

'画面表示'
col(0xFFFFFF);
for(i=1;i<=25;i++){
text(bg[i],0,i*sh,0);
}

'衝突判定'
if(((strat(bg[y],x)!=" ")&&(strat(bg[y],x)!="."))||((strat(bg[y],x+1)!=" ")&&(strat(bg[y],x+1)!="."))||((strat(bg[y+1],x)!=" ")&&(strat(bg[y+1],x)!="."))||((strat(bg[y+1],x+1)!=" ")&&(strat(bg[y+1],x+1)!="."))){
col(0xFF0000);
text("@@",x*sw,y*sh,0);
text("@@",x*sw,(y+1)*sh,0);
unlock(1);
save(hs);
sleep(1500);
clearkey();
k=input();
if(k==262144){end;}
goto 1000;
}

'画面更新とウェイト'
unlock(1);
sleep(WAIT);
goto 1001;

'ここからはサブルーチン'
'テキスト円表示'
func tcircle(x100,y100,r100,bg100){
'未使用ここから
x100=int(x100);
y100=int(y100);
r100=int(r100);
未使用ここまで'
r100=abs(r100);
for(y200=0;y200<=r100;y200++){
for(x200=0;x200<=r100;x200++){
if(((x200*x200)+4*(y200*y200))>=(r100*r100)){
break;
}
}
x101=x100-x200;
x102=x100+x200;
y101=y100-y200;
if(y101<1){y101=y101+50;}
y102=y100+y200;
if(y102>50){y102=y102-50;}
if((x101>=-20)&&(x101<=119)&&(x102>=-20)&&(x102<=119)&&(y101>=1)&&(y101<=50)&&(y102>=1)&&(y102<=50)){
if((x102-x101)>99){
bbg[y101]=substr(bg100,0,100);
bbg[y102]=substr(bg100,0,100);

}elsif(x101<0){
bbg[y101]=substr(bg100,0,x102).substr(bbg[y101],x102,100-x102+x101).substr(bg100,0,-x101);
bbg[y102]=substr(bg100,0,x102).substr(bbg[y102],x102,100-x102+x101).substr(bg100,0,-x101);

}elsif(x102>99){
bbg[y101]=substr(bg100,0,x102-99).substr(bbg[y101],x102-99,x101-x102+99).substr(bg100,0,100-x101);
bbg[y102]=substr(bg100,0,x102-99).substr(bbg[y102],x102-99,x101-x102+99).substr(bg100,0,100-x101);

}else{
bbg[y101]=substr(bbg[y101],0,x101).substr(bg100,0,x102-x101).substr(bbg[y101],x102,100-x102);
bbg[y102]=substr(bbg[y102],0,x101).substr(bg100,0,x102-x101).substr(bbg[y102],x102,100-x102);
}
}
}
}

'アークタンジェント近似計算'
func tarctan(x301,y301,x302,y302){
dx300=abs(x302-x301);
dy300=abs(y302-y301);
((x302-x301)>0)?sx300=1:sx300=-1;
((y302-y301)>0)?sy300=1:sy300=-1;
if((dx300+dy300)==0){
r300=0;
}else{
r300=(90*dy300)/(dx300+dy300);
if((sx300==-1)&&(sy300==1)){r300=180-r300;}
if((sx300==-1)&&(sy300==-1)){r300=180+r300;}
if((sx300==1)&&(sy300==-1)){r300=360-r300;}
}
return r300;
}