2018年 5月12日
キャラをグラフィックにする。
座標と当たり判定をすっきりさせ、さらにグラを回転させて向きを表現する。
それからスマホ向けにマウスカーソルでは無くて「照準」のグラを用意する。
スマホではカーソル表示は無いため。
自機
![]()
ショット
![]()
敵
![]()
照準
![]()
使用する場合は「名前をつけて画像を保存」でダウンロードして下さい。
ソース
; 企画第一弾 : 1画面防衛シューティングを作ろう
; var.0.003
#include "hsp3dish.as" ; HSPdishの宣言
randomize ; 乱数の初期化
pai=3.141593
pai2=pai*2
rad45=0.7853982 ; ラジアンで45度
rad90=1.5707965 ; ラジアンで90度
wx=640 ; 画面の大きさx
wy=360 ; 画面の大きさy
gmode 2
jw=1 : jo=20 : jo2=jo/2 ; 自機
celload "jiki_1.png",jw
celdiv jw,jo,jo,jo2,jo2
sw=2 : so=6 : so2=so/2 ; ショット
celload "shot_1.png",sw
celdiv sw,so,so,so2,so2
ew=3 : eo=20 : eo2=eo/2 ; 敵
celload "ene_1.png",ew
celdiv ew,eo,eo,eo2,eo2
cw=4 : co=24 : co2=co/2 ; カーソル
celload "csr_1.png",cw
celdiv cw,co,co,co2,co2
; 自機 ----------
jx=wx/2 ; プレイヤーの座標x
jy=wy/2 ; プレイヤーの座標y
jx1=jx-jo2 ; 自機左座標
jx2=jx+jo2 ; 自機右座標
jy1=jy-jo2 ; 自機上座標
jy2=jy+jo2 ; 自機下座標
; SHOT ----------
sb=20 ; ショット最大数
dim sf,sb ; ショット発射フラグ
ddim sx,sb ; ショット座標x
ddim sy,sb ; ショット座標y
ddim sdx,sb ; ショット移動量x
ddim sdy,sb ; ショット移動量y
ssp=20.0 ; スピード
sc=0 ; 出現カウント
scb=1 ; 発射間隔(フレーム)
; ENEMY ----------
eb=40 ; 敵最大数
dim ef,eb ; 出現フラグ
ddim ex,eb ; 敵座標x
ddim ey,eb ; 敵座標y
ddim edx,eb ; 敵移動量x
ddim edy,eb ; 敵移動量y
ddim er,eb ; 向き
esp=3.0 ; 敵スピード
ec=0 ; 出現カウント
ecb=4 ; 出現間隔(フレーム)
scr=0 ; スコア
hiscr=0 ; ハイスコア
*main
mainf=0 ; ゲームフラグ
repeat ; メインループ ----------------------------------
switch mainf
case 0 ; タイトル ----------
stick k : if k=0 : swbreak ; ボタンでゲーム再開
mainf=1
swbreak ; ----------
case 1 ; ゲーム ----------
; 自機 ----------
x=mousex : y=mousey ; マウスの座標
; SHOT ----------
repeat 1 ; 発射
if sc>0 : sc- : break ; ウエイト中
repeat sb
if sf(cnt)>0 : continue ; 使用中
sf(cnt)=1 ; 使用フラグon
sx(cnt)=double(jx) : sy(cnt)=double(jy) ; 初期座標
xn=double(x-jx) ; 自機とマウスの距離x
yn=double(y-jy) ; 自機とマウスの距離y
rad=atan(xn,yn) ; 距離xyから角度を求める
sdx(cnt)=sin(rad)*ssp ; 角度とスピードから移動量xを求める
sdy(cnt)=cos(rad)*ssp ; 角度とスピードから移動量yを求める
break
loop
sc=scb ; 発射ウエイト
loop
repeat sb : scn=cnt ; ショット移動処理
if sf(scn)=0 : continue ; 無し
sx(scn)+=sdx(scn) ; xの移動
sy(scn)+=sdy(scn) ; yの移動
sx1=int(sx(scn))-so2 ; ショット左座標
sx2=int(sx(scn))+so2 ; ショット右座標
sy1=int(sy(scn))-so2 ; ショット上座標
sy2=int(sy(scn))+so2 ; ショット下座標
repeat eb ; 敵との当たり判定
if ef(cnt)=0 : continue
ex1=int(ex(cnt))-eo2 ; 敵左座標
ex2=int(ex(cnt))+eo2 ; 敵右座標
ey1=int(ey(cnt))-eo2 ; 敵上座標
ey2=int(ey(cnt))+eo2 ; 敵下座標
if sx1<ex2 and ex1<sx2 and sy1<ey2 and ey1<sy2 {
ef(cnt)=0 : sf(scn)=0 ; 当たった敵とショットを消す
scr+ ; スコア
if hiscr<scr : hiscr=scr ; ハイスコアの更新
break
}
loop
if sf(scn)=1 : if sx2<0 or wx<sx1 or sy2<0 or wy<sy1 : sf(scn)=0 ; 場外でフラグ off
loop
; ENEMY ----------
repeat 1 ; 敵出現
if ec>0 : ec- : break ; ウエイト中
repeat eb ; フラグ確認
if ef(cnt)>0 : continue ; 使用中
ef(cnt)=1 ; 使用フラグon
r=rnd(4) ; 出現方向
if r=0 : exs=rnd(wx)-eo2 : eys=0-eo2 ; 上
if r=1 : exs=rnd(wx)-eo2 : eys=wy+eo2 ; 下
if r=2 : exs=-eo2 : eys=rnd(wy)-eo2 ; 左
if r=3 : exs=wx+eo2 : eys=rnd(wy)-eo2 ; 右
ex(cnt)=double(exs) ; 初期位置x
ey(cnt)=double(eys) ; 初期位置y
xn=double(jx-exs) ; 敵と自機の距離x
yn=double(jy-eys) ; 敵と自機の距離y
rad=atan(xn,yn) ; 距離xyから角度を求める
edx(cnt)=sin(rad)*esp ; 角度とスピードから移動量xを求める
edy(cnt)=cos(rad)*esp ; 角度とスピードから移動量yを求める
er(cnt)=-rad+pai ; 向き
ec=ecb ; 出現ウエイト
break ; 登録終わり
loop
loop
repeat eb ; 敵移動処理
if ef(cnt)=0 : continue ; 無し
ex(cnt)+=edx(cnt) : ey(cnt)+=edy(cnt) ; 移動
ex1=int(ex(cnt))-eo2 ; 敵左座標
ex2=int(ex(cnt))+eo2 ; 敵右座標
ey1=int(ey(cnt))-eo2 ; 敵上座標
ey2=int(ey(cnt))+eo2 ; 敵下座標
if jx1<ex2 and ex1<jx2 and jy1<ey2 and ey1<jy2 {
mainf=2 : break ; 自機と当たりで GAME OVER
}
if ex2<0 or wx<ex1 or ey2<0 or wy<ey1 : ef(cnt)=0 ; 枠外でフラグ off
loop
swbreak ; ----------
case 2 ; gameover ----------
stick k : if k=0 : swbreak ; ボタンでゲーム再開
repeat eb
ef(cnt)=0 ; 敵リセット
loop
repeat sb
sf(cnt)=0 ; ショットリセット
loop
scr=0 ; スコアリセット
mainf=0 ; ゲーム再開
swbreak ; ----------
swend
redraw 0 ; 表示 ====================
color 1,1,1 : boxf : color 255,255,255 ; 画面クリア
pos jx,jy : celput jw ; 自機
repeat sb ; ショット
if sf(cnt)=0 : continue ; 無い
pos sx(cnt),sy(cnt) : celput sw ; ショット
loop
repeat eb ; 敵
if ef(cnt)=0 : continue ; 無い
pos ex(cnt),ey(cnt) : celput ew,,,,er(cnt) ; 敵
loop
pos x,y : celput cw
switch mainf
case 0 ; タイトル
pos wx/2-120,wy/2-50 : mes "1画面防衛シューティング"
pos wx/2-43,wy/2+30 : mes "var.0.003"
swbreak
case 1 ; ゲーム
swbreak
case 2 ; gameover
pos wx/2-43,wy/2+50 : mes "GAME OVER"
swbreak
swend
pos wx-300,5 : mes "SCORE "+scr
pos wx-150,5 : mes "HI SCORE "+hiscr
redraw 1 ; ====================
await 1000/15 ; ウエイト、FPS 15
loop ; --------------------------------------------------
end ; 終わり
プログラム解説
初期設定
|
pai=3.141593 pai2=pai*2 rad45=0.7853982 ; ラジアンで45度 円周率。 ゲームプログラムの時は大体書いてる。 jw=1 : 自機のグラフィックバッファNo. celload "jiki_1.png",jw celdiv jw,jo,jo,jo2,jo2 それから今回はグラの回転表示を行うが、その再の中心点になる。 当たり判定用の 4辺端座標。 たぶんこの程度のプログラムなら速度に影響は無い。 |
メインルーチン
|
sx1,sx2,sy1,sy2、ex1,ex2,ey1,ey2 今回はこれらショットや敵の当たり判定用の 4辺座標をあらかじめ用意しておく事で、見た目にもスッキリしたと思う。 合わせて場外判定のソースも分かりやすくなった。 そもそも celput(グラ表示)のラジアンの値も独自のような気もするし
つまりプログラム的には真上が 0で、時計周り(右回り)に真下までが π(パイ(3,141593))で、そこから真上が 2π(6.28・・・)という仕様らしい。 これはグラフィックが普通上向きだから 0が正位置なら合理的なんだと思う。 今回用意した敵のグラも正位置で上向きだし。 |
表示
|
pos ex(cnt),ey(cnt) : celput ew,,,,er(cnt) ; 敵 celput が HSPdish用のグラフィック表示命令になります。 先に設定した posの座標に表示します。 ew=グラのバッファNo. er=回転表示角度。 間の,,,,には、その画像バッファの何番目の画像を表示するか(celdivで区切った)と、xとyの拡大縮小表示率が設定できます。 |
今回ショットの大きさを 6ドットにし、当たり判定もその大きさで計算してるので、前回よりエイム(狙う)要素が増したと思います。

