2021年 7月 5日
最後の要素としてパワーアップを実装してみたいと思う。
それぞれの武器がパワーアップできるように各 3段階を作成した。
ショット
炸裂弾
防衛衛星はレベルによって色が変わるようにした

コードとしてはこれだけだが
; power up パワーアップ
*powerup
kwc=7
repeat
ky=0 : k=0
repeat 1
if kwc>0 : kwc- : break
stick k,256
pw_key : ky=pw_keyn
loop
if k=256 {
if ky=0 : break ; 戻る
if ky=1 and slv<3 and pwp>=spwp(slv) : pwp-=spwp(slv) : slv+ ; ショットパワーアップ
if ky=2 and vlv<3 and pwp>=vpwp(vlv) : pwp-=vpwp(vlv) : vlv+ ; バルカンパワーアップ
if ky=3 and eblv<3 and pwp>=ebpwp(eblv) : pwp-=ebpwp(eblv) : eblv+ ; 炸裂弾パワーアップ
if ky=4 and llv<3 and pwp>=lpwp(llv) : pwp-=lpwp(llv) : llv+ ; レーザーパワーアップ
if ky=5 and gdlv<3 and pwp>=gdpwp(gdlv) : pwp-=gdpwp(gdlv) : gdlv+ ; 防衛衛星パワーアップ
kwc=7
if ky=6 and jhp<jhpb and pwp>=rep : pwp-=rep : jhp+ : kwc=1 ; 耐久度回復
}
; 画面表示
redraw 0 ; 表示 ----------
main_put
pw_put
redraw 1
await 1000/20 ; ウエイト、FPS 15
loop
k=0 : kwc=5
return
#deffunc pw_put ; パワーアップ画面
color 1,1,1 : boxf pwx1+1,pwy1+1,pwx2-1,pwy2-1
evw 0,pwx1,pwy1,62,32
s="POWER UP" : ftp s,pwx1+206,pwy2+9
color 255,229,98
repeat 5,2
line pwax(cnt),pwy1+1,pwax(cnt),pwy2-2
loop
s="SHOT" : ftp s,pwax(1)+16,pwy3
s="LEVEL" : ftp s,pwax(1)+12,pwy4
if slv<3 : s=str(slv) : ftp s,pwax(1)+31,pwy5
if slv=3 : s="MAX" : ftp s,pwax(1)+19,pwy5
pos pwax(1)+40,pwy6 : celput sw,slv-1
s="POW UP" : ftp s,pwx1+15,pwy7
repeat 1
if slv=3 : s="-" : ftp s,pwx1+39,pwy8,2 : break
s=str(spwp(slv)) : n=strlen(s)
if n=4 : nx=23 ; 間隔
if n=5 : nx=18
s=str(spwp(slv)) : ftp s,pwx1+nx,pwy8,2
loop
s="VULCAN" : ftp s,pwax(2)+7 ,pwy3
s="LEVEL" : ftp s,pwax(2)+13,pwy4
if vlv<3 : s=str(vlv) : ftp s,pwax(2)+32,pwy5
if vlv=3 : s="MAX" : ftp s,pwax(2)+22,pwy5
pos pwax(2)+40,pwy6
nf=0.8+0.2*double(vlv) : celput vw,,nf,nf
s="POW UP" : ftp s,pwax(2)+8,pwy7
repeat 1
if vlv=3 : s="-" : ftp s,pwax(2)+32,pwy8,2 : break
s=str(vpwp(vlv)) : n=strlen(s)
if n=4 : nx=16 ; 間隔
if n=5 : nx=11
s=str(vpwp(vlv)) : ftp s,pwax(2)+nx,pwy8,2
loop
s="EXPLOS" : ftp s,pwax(3)+7 ,pwy3
s="LEVEL" : ftp s,pwax(3)+13,pwy4
if eblv<3 : s=str(eblv) : ftp s,pwax(3)+32,pwy5
if eblv=3 : s="MAX" : ftp s,pwax(3)+22,pwy5
pos pwax(3)+40,pwy6 : celput ebaw,eblv-1,1.3,1.3
s="POW UP" : ftp s,pwax(3)+8,pwy7
repeat 1
if eblv=3 : s="-" : ftp s,pwax(3)+32,pwy8,2 : break
s=str(ebpwp(eblv)) : n=strlen(s)
if n=4 : nx=16 ; 間隔
if n=5 : nx=11
s=str(ebpwp(eblv)) : ftp s,pwax(3)+nx,pwy8,2
loop
s="LASER" : ftp s,pwax(4)+12,pwy3
s="LEVEL" : ftp s,pwax(4)+13,pwy4
if llv<3 : s=str(llv) : ftp s,pwax(4)+32,pwy5
if llv=3 : s="MAX" : ftp s,pwax(4)+22,pwy5
pos pwax(4)+40,pwy6 : celput lw,,0.25+0.25*llv,1.0
s="POW UP" : ftp s,pwax(4)+8,pwy7
repeat 1
if llv=3 : s="-" : ftp s,pwax(4)+32,pwy8,2 : break
s=str(lpwp(llv)) : n=strlen(s)
if n=4 : nx=16 ; 間隔
if n=5 : nx=11
s=str(lpwp(llv)) : ftp s,pwax(4)+nx,pwy8,2
loop
s="GUARD" : ftp s,pwax(5)+12,pwy3
s="LEVEL" : ftp s,pwax(5)+13,pwy4
if gdvlv<3 : s=str(gdlv) : ftp s,pwax(5)+32,pwy5
if gdlv=3 : s="MAX" : ftp s,pwax(5)+22,pwy5
pos pwax(5)+40,pwy6 : celput gdw,0
pos pwax(5)+40,pwy6
if gdlv=1 : n=4
if gdlv=2 : n=22
if gdlv=3 : n=23
celput gdw,n
s="POW UP" : ftp s,pwax(5)+8,pwy7
repeat 1
if gdlv=3 : s="-" : ftp s,pwax(5)+32,pwy8,2 : break
s=str(gdpwp(gdlv)) : n=strlen(s)
if n=4 : nx=16 ; 間隔
if n=5 : nx=11
s=str(gdpwp(gdlv)) : ftp s,pwax(5)+nx,pwy8,2
loop
s="HP" : ftp s,pwax(6)+30,pwy3
s=str(jhpb) : ftp s,pwax(6)+29,pwy4
s=str(jhp) : n=strlen(s)
if n=1 : ftp s,pwax(6)+39,pwy5
if n=2 : ftp s,pwax(6)+29,pwy5
jhpf=double(jhp)
jhpcn=int(round(jhpcf*jhpf))
pos pwax(6)+42,pwy6 : celput jw1,jhpcn ; 耐久度
s="REPAIR" : ftp s,pwax(6)+8,pwy7
s=str(rep) : ftp s,pwax(6)+22,pwy8,2
return
もちろん各武器の移動や当たり判定等に変更が加えられている。
ショットは威力が増すだけ。
バルカンは威力と 1回の発射数が変わる。
炸裂弾は威力と爆発の範囲が変わる。
レーザーは幅が変わるだけ。
防衛衛星は防げる弾の数が変わる。
スコアとは別にパワーアップポイントを作った。

今の所、敵を倒すと増えてポイント分で各武装をパワーアップする。
2、操作方法を刷新した
スマホ向けというか武器の切り替えが煩雑なので、タップのみで各サブウエポンが発動するように変更した。
画面 1タップでバルカンを発射。
2タップで、その地点へ炸裂弾を発射。
画面を 10フレーム長押しするとレーザーを発射する。
照準は画面を押して 10ドット動かすと、そのまま動かす事ができる。
なぜ 10ドットなのかと言うと、レーザーの長押しがあるために多少のブレを許容しないといけない。
自機をクリックするとパワーアップのウインドウが開く、今回はこれをPAUSEの代わりとした。

キー入力のソースは次の通り
; 入力 ----------
x=mousex : y=mousey ; マウス、スマホの座標
k=0
repeat 1
if kwc>0 : kwc- : break ; ウエイト
stick k,256 ; マウス、スマホクリック
loop
if k=256 {
hx=double(jx-x) : hy=double(jy-y)
if (hx*hx)+(hy*hy)<30*30 : gosub *powerup
}
if k=256 { ; 押している
if kf=0 : kf=1 : kepx=x : kepy=y
if kf=1 { ; カーソル移動モード
if kepx-x>10 or x-kepx>10 or kepy-y>10 or y-kepy>10 : kf=2
}
if kf=2 : cx=double(x) : cy=double(y)
if kf=3 : kf=4 ; 2度押し
if kf=1 and kc>=10 {
repeat 1 ; レーザー
if lf>0 or le<leb: break ; 発射中 or エネルギーが無い
lf=1 : subf=0 ; レーザー発射
lxs=double(x) : lys=double(y); 目標地点
kf=6 : kc=0 ;: kwc=5
loop
}
kc+
}
if k!256 { ; 押してない
if kf=2 or kf=6 : kf=0 : kc=0 ; リセット
if kf=1 : kf=3 : kc=0 ; 放した
if kf=3 {
if kc>2 { ; 放してからnフレーム以上
repeat 1 ; バルカン
if vc=0 or vcn>0 : break; 弾切れ or バルカン発射中
esn_set 1 ; 近くの標的をセット
vcn+=vnb(vlv) ; バルカン発射
loop
kf=0
}
kc+
}
if kf=4 : kf=5 : kc=0 ; 放した
if kf=5 {
if kc>2 { ; 放してからnフレーム以上
repeat ebb : ebn=cnt ; 炸裂弾
if ebf(ebn)>0 : continue
ebf(ebn)=1 : ebxb(ebn)=double(kepx) : ebyb(ebn)=double(kepy)
kwc=5 : break
loop
kf=0
}
kc+
}
}
押してる場合と押してない場合に分けて、モードフラグ(kf)が変化するようにしてる。
最初は 0で押すと 1に、1の常態で放すと 3になって、その状態で 2フレーム以上入力が無いとバルカン発射、2フレーム以内に押すと 4になって、その常態で放すと炸裂弾発射。
モード 2はカーソル移動モード、1の常態で 10フレーム押すとレーザー発射。
のようになってる。
3、FPSを 15から 20にした
FPSは 1秒間に何回フレームを処理して表示するかを表す。
つまり 1フレームに 1回移動と当たり判定、キー入力等を処理して表示する。
FPSは表示の回数を表すものなので、処理はかならずしも 1フレームに 1回とは限らないが STGはだいたいそうだと思う。
今まで 15だったのは XPの時代のブラウザ起動に置いては、その辺が最低限だったためで、今はコンピューターの速度が上がってるし、スマホはデスクトップと同等以上になってるので 15以上でも問題ないと思う。
そもそもアクションゲームの表示に置いては、最低限 FPS20は欲しい、できれば 30くらいがオーソドックスだと思うし、市販のシューティングは普通 60で動いている。
60の方が、なめらかに速度を早く動かせる。
例えばショットのスピードを上げると、フレームが少ないと移動の中間点の表示が少なくなる。
今回、表示フレームを 15から 20にしたけど、各オブジェクトの移動スピードは変えてないので、その分ゲームスピードが増したと思う。
4、ウインドウ表示を作った
枠のグラを作って
![]()
プログラムで表示する
; ---------- イベントウインドウ ---------- #module #deffunc evw int _f,int _sx,int _sy,int _ox,int _oy ;(イベントウインドウ、 ; sx=描き始め座標x、sy=描き始め座標y、 ; ox=ブロック大きさx、oy=ブロック大きさy) f=_f sx=_sx sy=_sy ox=_ox oy=_oy bo=8 ; 1ブロックの大きさ x1=sx : x2=sx+((ox-1)*bo) y1=sy : y2=sy+((oy-1)*bo) gmode 2 ; 通常表示 ; 四隅 pos x1,y1 : celput ww@,0 ; 左上 pos x2,y1 : celput ww@,2 ; 右上 pos x1,y2 : celput ww@,6 ; 左下 pos x2,y2 : celput ww@,8 ; 右下 ; xライン nx=ox-2 repeat nx x=sx+bo+(cnt*bo) pos x,y1 : celput ww@,1 ; 上ライン pos x,y2 : celput ww@,7 ; 下ライン loop ; yライン ny=oy-2 repeat ny y=sy+bo+(cnt*bo) pos x1,y : celput ww@,3 ; 左ライン pos x2,y : celput ww@,5 ; 右ライン loop return #global
使い方は
evw 0,0,0,9,15
evw 0,0,wy1,9,15
evw 0,0,wy2,9,15
のように書いて、今回 1つめのパラメーターは未設定、2、3で描き始め座標x,yを 4、5のパラメーターで何ブロック描くか指定する。
今回の 1ブロックの大きさは 8ドットになってる。
今回の枠表示はこれで行っている

5、PNGフォント
mes表示だと、環境によって表示がまちまちなので、改めてドットフォントを作って表示する。

今回は 16ドットで作った。
表示プログラムは次の通り
;----------- PNGフォント表示 -------------------------------- #module #deffunc ftp str _s,int _x,int _y,int _t ; figure、数字専用 ; s=文字列、x=x座標、y=y座標、t=文字色 x=_x y=_y t=_t s=_s ; 文字列 sg=strlen(s) ; 文字長さ、個数 t2=t*40 ; 文字色 gmode 2 repeat sg ; 文字の数だけ繰り返し n=peek(s,cnt) ; 1文字読み出し、n=アスキーコード if n=32 : continue ; " " スペース pos x+cnt*10,y if n>=65 and n<=90 : n2=n-65 : celput ftw@,n2+t2 : continue ; 小文字も大文字で表示 if n>=97 and n<=122 : n2=n-97 : celput ftw@,n2+t2 : continue ; アルファベット if n>=48 and n<=57 : n2=n-48 : celput ftw@,n2+t2+30 : continue; 数字 if n=46 : n2=26 ; . if n=47 : n2=27 ; / if n=43 : n2=28 ; + if n=45 : n2=29 ; - celput ftw@,n2+t2 loop return #defcfunc fpk int _fpkn,int _fpkb ; ケタ数に応じて+座標xの間隔を返す fpkn=_fpkn ; 判定する数 fpkb=_fpkb ; 最大ケタ s=str(fpkn) : nn=strlen(s) nx=(fpkb*11)-nn*10 ; 4ケタになってる、1数字11ドット間隔 return nx #global
#defcfunc fpkはケタの違う数字の、右そろえ用の座標計算プログラムだけど、今回使ってない。
6、背景を用意した
背景が黒のままだと殺風景なので、適当にそれらしい画像を用意した。
画像を横 640ドットに縮小して使ってる

この画像に黒の背景画像を半透明合成して暗めにして表示している。

#deffunc clr ; 画面クリア pos 0,0 : celput haiw gmode 3,,,48 pos 0,0 : celput hai2w return
単に背景画像を半透明表示だと白くなってしまう。
もちろん背景素材をグラソフトで加工して 1枚で表示しても良い。
1MAP_STG_ver.0.011.ZIP ファイル
1MAP_STG_ver.0.011
