まったくのプログラミング素人の筆者がC++/HSPを使用してSTG(シューティングゲーム)を作っていく過程を書くブログでしたが最近は脱線気味。プログラミング以外にも、ゲーム関連の記事、日々の戯言など。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
敵の種類を増やそうと思って、一つ作ってみました。
敵攻撃を多彩にする為には、同時に色んな種類の弾を撃たせなければなりませんが、ここでちょっとつまづきました。
敵弾の座標変数は1種類しかありません。(と言うか弾の種類だけ変数を別で用意したら、当り判定なんかが大変)
どうするんだ?と思って色々試した所、gcopyの値を配列変数で換えれば出来ました。
ついでに自機弾も3方向に撃てるようにし、Zボタンを押した時はスピードダウン&連射速度アップ出来るようにした。
スプリクトはコチラ↓雑魚以上中ボス以下のちょっと強い敵をイメージしてみました。
*************************************
;初期設定
#include "CK_JOYFORCE.AS"
dialog "fullscreenで起動しますか?「はい」を選択した場合、画面解像度を640×480に変更します。",2
if stat=6:fullscreen=0
if stat=7:fullscreen=1
if fullscreen=0 : chgdisp 1,640,480 : mouse -1 ;ディスプレイ解像度を640×480に。マウスを表示しない
*start
buffer 3 ;ウィンドウ3をバッファ画面として用意
picload "stg10.gif";画像をバッファ3に読み込み
buffer 4 ; ウィンドウ4をバッファ画面として用意
picload "s396.jpg" ;背景画像をバッファ4に読み込み
buffer 5 ; ウィンドウ4をバッファ画面として用意
picload "bomb.gif" ;ボム画像をバッファ5に読み込み
ssp=482 ;スクロール速度
wxs=320 :wys=480 ;ゲーム画面の座標設定
screen 2,640,480,1;メイン画面(ウィンドウ2を480*640で用意)
bgscr 2,640,480,2 : gsel 2,1 ;メイン画面を初期化して枠のないウィンドウを作成。メイン画面をアクティブに
gtime=0 ;フレーム数
px=304:py=448;自機の初期位置
tmx=40 ;自機弾の数
dim tx,tmx ;自機弾のX座標の配列変数
dim ty,tmx ;自機弾のY座標の配列変数
dim tf,tmx ;自機弾が画面にあるか無いかを調べる配列変数
dim txv,tmx;自機弾のx軸移動量
dim tyv,tmx;自機弾のy軸移動量
emx=50;敵の数
dim ex,emx : dim ey,emx;敵の初期位置
dim dx,emx : dim dy,emx;敵の移動量
dim ef,emx;敵のフラグ
dim em,emx;敵の種類
dim et,emx;敵出現からの時間
dim bbmx,emx;ボムで爆破時の爆発のx座標
dim bbmy,emx;ボムで爆破時の爆発のy座標
dim bbmc,emx;ボムカウント
emt=2000;敵の弾
dim etx,emt : dim ety,emt ;敵弾の位置、移動量
dim etxv,emt; etxv 敵弾x方向運動量
dim etyv,emt; etyv 敵弾y方向運動量
dim etf,emt;敵弾のフラグ
dim etxp,emt;敵弾画像のx軸の座標
dim etyp,emt;敵弾画像のy軸の座標
dim etxs,emt;敵弾画像のx軸の大きさ
dim etys,emt;敵弾画像のy軸の大きさ
sc=0;スコア
gend=0;ゲームオーバー処理の為の変数
bombcnt=-1;ボム処理の為の変数(-1でボムを撃っていない)
nbomb=30;ボムの数
*main
redraw 0 ;仮想画面を指定
color 0,0,0 ;色に黒を指定
;スクロール処理
gmode 1 ; ノーマルコピーモード
scr=(scr+ssp)¥wys ; コピー元座標を算出
pos 160,scr :gcopy 4,0,0,wxs,wys-scr ;
if scr!0 { pos 160,0 ; 背景画像をコピー
gcopy 4,0,wys-scr,wxs,scr ;
} ;
;面データ読み込み
gosub *men ;*men(タイムテーブル)へ移動
;自機移動処理
pk=0 ;自機の傾きの為の変数
ck_joystick ky,15;キーボードのチェック
if ky&1 :px-=move :pk=32 :if px<160 :px=160;カーソルキー左(←)を押した時pxよりmoveを引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=move :pk=64 :if px>448 :px=448
if ky&2 :py-=move :if py<0 :py=0
if ky&8 :py+=move :if py>448 :py=448
gmode 2 ;透明化処理の為の命令
pos px,py;自機の座標指定
gcopy 3,pk,0,32,32;バッファ画面(ウィンドウ3)より自機画像をコピー
;自機弾発射処理
shottime-- ;連射為の処理
if shottime<0: st=1 ;shottimeが0以下の時、stに1を代入
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)=0 : if st=1{ ;tf(cnt)が0の時=画面に弾がない時、かつstが1の時(shottimeが0以下の時){}内の命令を行う
th=th+1;一回で撃てる弾数の為の変数
tf(cnt)=1 ;tf(cnt)に1を代入。画面に弾があると言う事
st=0 ;連射の為の処理
shottime=2 ;連射の為の処理
ts=10 ;自機弾の速さ
if th=1 :tx(cnt)=px : ty(cnt)=py-12 : r=double(4.712) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts;直進弾
if th=2 :tx(cnt)=px-6 : ty(cnt)=py-12 : r=double(4.61) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts;左弾
if th=3 :tx(cnt)=px+6 : ty(cnt)=py-12 : r=double(4.813) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts : th=0;右弾
}
if tf(cnt)=1{ ;画面に弾があるとき、{}内の命令を行う
tx(cnt)=tx(cnt)+txv(cnt) : ty(cnt)=ty(cnt)+tyv(cnt) ;自機弾の移動量
pos tx(cnt),ty(cnt) ;自機弾の座標指定
gcopy 3,96,0,32,32 ;バッファ画面(ウィンドウ3)より自機弾画像をコピー
if ty(cnt)<-32 : tf(cnt)=0 : st=0 ;画面から自機弾が消えたら弾を消す
}
loop
ck_joystick ky,2048 ;Zキーのチェック
if ky&2048 { ;Zキーが押されていた時はmove(自機移動速度)を2にして連射速度を上げる。そうでなければmoveを4にする
move=2 : shottime=0 }else{
move=4
}
;ボム処理
ck_joystick ky,4096 ;Xキーのチェック
if ky&4096 { ;Xキーが押された時は{}内の命令を行う
if (bombcnt=-1)&(nbomb>0) { ;ボムが画面に出てなく、ボム数が0以上の時
nbomb=nbomb-1 ;ボム数を1減らす
bombcnt=0:bombp=17 ;ボムの存在を有にする。ボムアニメの為に変数を用意。
bpx=px-152 : bpy=py-400;ボムの座標指定
}
}
if bombcnt!-1 { ;ボムが画面に有る時。!は-1以外の時という事
repeat emt ;弾の存在を調べ画面に弾がある時は、弾の存在を消す(etf(cnt)=0)
if etf(cnt)<1 : continue
etf(cnt)=0
loop
bombcnt=bombcnt+1 ;ボムの効いている時間処理
if bombcnt=20 { bombcnt=-1 } ;20フレーム過ぎたらボムが効かなくなる
}
;敵移動処理
repeat emx ;repeat〜loop間をemx回繰り返す
ent=cnt
et(cnt)++ ;敵出現時間を+
if ef(cnt)<1 : continue ;ef(cnt)が1以下(敵が画面にいない)ならばrepeatに戻る
if enm(cnt)=4 : gosub *em04 ;敵の名前が4の時*em04へ移動
loop
;敵弾発射処理
repeat emt ;repeat〜loop間をemt回繰り返す
if etf(cnt)=1 { ;etf(cnt)が1(敵弾が画面にあるなら){}内の命令を行う
etx(cnt)=etx(cnt)+etxv(cnt) ;敵弾x座標に敵弾移動速度をプラス
ety(cnt)=ety(cnt)+etyv(cnt) ;敵弾y座標に敵弾移動速度をプラス
pos etx(cnt),ety(cnt) ;敵弾の座標指定
gcopy 3,etxp(cnt),etyp(cnt),etxs(cnt),etys(cnt) ;バッファ画面(ウィンドウ3)より敵弾画像をコピー
if etx(cnt)>480 : etf(cnt)=0 ;敵弾x座標が480以上になったら弾の存在を消す
if etx(cnt)<152 : etf(cnt)=0
if ety(cnt)>480 : etf(cnt)=0
if ety(cnt)<-16 : etf(cnt)=0
}
loop
;敵弾当り判定
repeat emt ;emt回繰り返す
if etf(cnt)=0 : continue
if etxs(cnt)=16 : ddx=(etx(cnt)+8)-(px+16) : if ddx<0 : ddx=-ddx ;自機と弾の中心座標の差の絶対値を求める
if etys(cnt)=16 : ddy=(ety(cnt)+8)-(py+16) : if ddy<0 : ddy=-ddy
if etxs(cnt)=8 : ddx=(etx(cnt)+4)-(px+16) : if ddx<0 : ddx=-ddx
if etys(cnt)=8 : ddy=(ety(cnt)+4)-(py+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<3))&(abs(ddy<3)) { ;x軸とy軸の差が3以下の時、ゲームオーバー
gend=1 ;1にするとゲームオーバー
}
loop
;爆風とボムのアニメ処理
if bombp>0 { ;ボムのアニメ処理変数が0以上の時{}内の命令を行う
bombp- : pos bpx,bpy
gcopy 5,320*(16-bombp),0,320,480
}
repeat emx ;敵のアニメ処理変数が0以上の時{}内の命令を行う
if bbmc(cnt)>0 {
bbmc(cnt)- : pos bbmx(cnt),bbmy(cnt)
gcopy 3,128+48*(16-bbmc(cnt)),0,48,48
}
loop
color 0,0,0 ;色に黒を指定
boxf 0,0,160,480 ;画面右側を黒で塗りつぶす
boxf 480,0,640,480 ;画面左側を黒で塗りつぶす
;スコア表示
font msmincho,18,3 ;フォントをMS明朝に、大きさを18に、イタリック体太字に指定
color 255,255,255 ;色に白を指定
pos 0,0
mes"Escで終了"
pos 496,0
mes"SCORE-"+sc+"-"
pos 496,462
mes"BOMB-"+nbomb+"-"
;fps表示
fp++
time=gettime(6)
if time!=time2{
fpc=fp
fp=0}
pos 0,462
mes " Fps "+fpc
time2=time
if gend=1 : gosub *gameover ;gendが1(ゲームオーバーの時)*gameoverに移動
redraw 1 ;メイン画面を更新
await 16 ;これを入れないとパソコンが固まる
gtime=gtime+1 ;タイムテーブルの為の変数
getkey syuryo,27:if syuryo=1:end ;Escキーのチェック。押されたら終了
goto *main ;*mainに戻る
;サブルーチン
*men ;タイムテーブル
if gtime=1 : bx=240 : by=-64 : gosub *eb04
if gtime=500 : gtime=0
return
*eb04;敵発生処理
repeat emx
if ef(cnt)>0 : continue ;画面に敵がいなければrepeatに戻る
enm(cnt)=4 ;敵の名前
ef(cnt)=100 ;敵の体力
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=0 : dy(cnt)=1 ;移動方向
et(cnt)=0 ;敵弾生成時間をリセット
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return
*em04;敵移動処理
if (et(cnt)>60)&(et(cnt)<250) : if gtime¥20=0 : gosub *tekitama4 ;敵生成時間が60以上250以下の時かつgtimeを20で割った余りが0の時*tekitama4へ移動
if (et(cnt)>60)&(et(cnt)<250) : if gtime¥20=0 : gosub *tekitama5
if (et(cnt)>30)&(et(cnt)<300) : if gtime¥5=0 : gosub *tekitama6
ex(cnt)=ex(cnt)+dx(cnt) ;敵の移動量決定
ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if et(cnt)<20 : dy(cnt)=5
if et(cnt)>21 : dy(cnt)=0
if et(cnt)>300 : dy(cnt)=3
if ey(cnt)>480 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 3,256,80,160,80 ;敵4の表示
;敵と自機との当り判定
ddx=(ex(cnt)+80)-(px+16) : if ddx<0 : ddx=-ddx
ddy=(ey(cnt)+40)-(py+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<70))&(abs(ddy<30)) {
gend=1
}
;自機弾と敵との当り判定
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)<1 : continue ;tf(cnt)が1以下(弾が画面にいない)ならばrepeatに戻る
ddx=(ex(ent)+80)-(tx(cnt)+16) : if ddx<0 : ddx=-ddx
ddy=(ey(ent)+40)-(ty(cnt)+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<70))&(abs(ddy<30)) { ;自機弾と敵のx軸とy軸の座標差を求め(敵と自機弾全て)、どちらも32以下であれば{}}内の命令を行う
tf(cnt)=0 ;弾が当った時は弾の存在を消す
ef(ent)- ;弾が当った時は敵の存在を消す
pos ex(ent),ey(ent)
gcopy 3,416,80,160,80
if ef(ent)=0 : sc+10000 : gosub *bomb2
}
loop
;ボム処理
if bombcnt!-1 {
ef(cnt)-
pos ex(cnt),ey(cnt)
gcopy 3,416,80,160,80
if ef(cnt)=0 : gosub *bomb2
}
return
*tekitama4;敵左側3方向弾
repeat emt
if etf(cnt)>0 : continue ;etfが0以上の時repeatに戻る
eh=eh+1 : etf(cnt)=1 ;弾数の為の処理。弾の存在を有にする
etx(cnt)=double(ex(ent)+37) : ety(cnt)=double(ey(ent)+80) ;弾の初期座標
etxp(cnt)=96 : etyp(cnt)=40;弾画像の場所指定
etxs(cnt)=8 : etys(cnt)=8;弾画像の大きさ指定
if eh=1 :ds=2 :r=atan(py-ey(ent), px-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=2 :ds=2 : r=atan(py-ey(ent), px+90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=3 :ds=2 : r=atan(py-ey(ent), px-90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=4 :ds=2.5 : r=atan(py-ey(ent), px-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=5 :ds=2.5 : r=atan(py-ey(ent), px+90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=6 :ds=2.5 : r=atan(py-ey(ent), px-90-ex(ent)): etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=7 :ds=3 : r=atan(py-ey(ent), px-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=8 :ds=3 : r=atan(py-ey(ent), px+90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=9 :ds=3 : r=atan(py-ey(ent), px-90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds:eh=0 :break
loop
return
*tekitama5;敵右側3方向弾
repeat emt
if etf(cnt)>0 : continue
eh=eh+1 : etf(cnt)=1
etx(cnt)=double(ex(ent)+115) : ety(cnt)=double(ey(ent)+80)
etxp(cnt)=96 : etyp(cnt)=40
etxs(cnt)=8 : etys(cnt)=8
if eh=1 :ds=2 :r=atan(py-ey(ent), px-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=2 :ds=2 : r=atan(py-ey(ent), px+90-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=3 :ds=2 : r=atan(py-ey(ent), px-90-(ex(ent)+100)): etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=4 :ds=2.5 : r=atan(py-ey(ent), px-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=5 :ds=2.5 : r=atan(py-ey(ent), px+90-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=6 :ds=2.5 : r=atan(py-ey(ent), px-90-(ex(ent)+100)): etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=7 :ds=3 : r=atan(py-ey(ent), px-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=8 :ds=3 : r=atan(py-ey(ent), px+90-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=9 :ds=3 : r=atan(py-ey(ent), px-90-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds:eh=0 :break
loop
return
*tekitama6;敵5方向弾
repeat emt
if etf(cnt)>0 : continue
eh=eh+1 : etf(cnt)=1
etx(cnt)=double(ex(ent)+72) : ety(cnt)=double(ey(ent)+60)
ds=6 ;敵弾の速さ
etxp(cnt)=96 : etyp(cnt)=48
etxs(cnt)=16 : etys(cnt)=16
if eh=1 : r=double(1.57) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=2 : r=double(1.97) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=3 : r=double(2.57) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=4 : r=double(1.17) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=5 : r=double(0.57) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds : eh=0 :break
loop
return
*bomb2;敵爆破処理
bbmx(ent)=ex(ent)+60 : bbmy(ent)=ey(ent)+20 ;爆風の座標指定
bbmc(ent)=17 ;爆風アニメの為の変数
return
*gameover
color rnd(255),rnd(255),rnd(255) ;色指定
pos 280,228
mes "Game Over"
pos 230,248
mes"Press X to Continue"
redraw 1
wait 1
ck_joystick ky ;Xキーのチェック。押されたら*startに戻る
if ky=4096 :goto *start
getkey syuryo,27:if syuryo=1:end
goto *gameover
*************************************
HSP3.0使用 CK_JOYFORCE.DLL使用 画像は↓を使用
これを実行すると5方向に青い弾を撃ちつつ、弾速の違う3方向自機狙い弾を左右の砲座から撃ってきます。
こんな感じで敵を増やしていけば、そこそこの物が出来そうな感じです^^
でも音楽もまだだし、完成までは程遠いと言った感じですが・・・
敵攻撃を多彩にする為には、同時に色んな種類の弾を撃たせなければなりませんが、ここでちょっとつまづきました。
敵弾の座標変数は1種類しかありません。(と言うか弾の種類だけ変数を別で用意したら、当り判定なんかが大変)
どうするんだ?と思って色々試した所、gcopyの値を配列変数で換えれば出来ました。
ついでに自機弾も3方向に撃てるようにし、Zボタンを押した時はスピードダウン&連射速度アップ出来るようにした。
スプリクトはコチラ↓雑魚以上中ボス以下のちょっと強い敵をイメージしてみました。
*************************************
;初期設定
#include "CK_JOYFORCE.AS"
dialog "fullscreenで起動しますか?「はい」を選択した場合、画面解像度を640×480に変更します。",2
if stat=6:fullscreen=0
if stat=7:fullscreen=1
if fullscreen=0 : chgdisp 1,640,480 : mouse -1 ;ディスプレイ解像度を640×480に。マウスを表示しない
*start
buffer 3 ;ウィンドウ3をバッファ画面として用意
picload "stg10.gif";画像をバッファ3に読み込み
buffer 4 ; ウィンドウ4をバッファ画面として用意
picload "s396.jpg" ;背景画像をバッファ4に読み込み
buffer 5 ; ウィンドウ4をバッファ画面として用意
picload "bomb.gif" ;ボム画像をバッファ5に読み込み
ssp=482 ;スクロール速度
wxs=320 :wys=480 ;ゲーム画面の座標設定
screen 2,640,480,1;メイン画面(ウィンドウ2を480*640で用意)
bgscr 2,640,480,2 : gsel 2,1 ;メイン画面を初期化して枠のないウィンドウを作成。メイン画面をアクティブに
gtime=0 ;フレーム数
px=304:py=448;自機の初期位置
tmx=40 ;自機弾の数
dim tx,tmx ;自機弾のX座標の配列変数
dim ty,tmx ;自機弾のY座標の配列変数
dim tf,tmx ;自機弾が画面にあるか無いかを調べる配列変数
dim txv,tmx;自機弾のx軸移動量
dim tyv,tmx;自機弾のy軸移動量
emx=50;敵の数
dim ex,emx : dim ey,emx;敵の初期位置
dim dx,emx : dim dy,emx;敵の移動量
dim ef,emx;敵のフラグ
dim em,emx;敵の種類
dim et,emx;敵出現からの時間
dim bbmx,emx;ボムで爆破時の爆発のx座標
dim bbmy,emx;ボムで爆破時の爆発のy座標
dim bbmc,emx;ボムカウント
emt=2000;敵の弾
dim etx,emt : dim ety,emt ;敵弾の位置、移動量
dim etxv,emt; etxv 敵弾x方向運動量
dim etyv,emt; etyv 敵弾y方向運動量
dim etf,emt;敵弾のフラグ
dim etxp,emt;敵弾画像のx軸の座標
dim etyp,emt;敵弾画像のy軸の座標
dim etxs,emt;敵弾画像のx軸の大きさ
dim etys,emt;敵弾画像のy軸の大きさ
sc=0;スコア
gend=0;ゲームオーバー処理の為の変数
bombcnt=-1;ボム処理の為の変数(-1でボムを撃っていない)
nbomb=30;ボムの数
*main
redraw 0 ;仮想画面を指定
color 0,0,0 ;色に黒を指定
;スクロール処理
gmode 1 ; ノーマルコピーモード
scr=(scr+ssp)¥wys ; コピー元座標を算出
pos 160,scr :gcopy 4,0,0,wxs,wys-scr ;
if scr!0 { pos 160,0 ; 背景画像をコピー
gcopy 4,0,wys-scr,wxs,scr ;
} ;
;面データ読み込み
gosub *men ;*men(タイムテーブル)へ移動
;自機移動処理
pk=0 ;自機の傾きの為の変数
ck_joystick ky,15;キーボードのチェック
if ky&1 :px-=move :pk=32 :if px<160 :px=160;カーソルキー左(←)を押した時pxよりmoveを引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=move :pk=64 :if px>448 :px=448
if ky&2 :py-=move :if py<0 :py=0
if ky&8 :py+=move :if py>448 :py=448
gmode 2 ;透明化処理の為の命令
pos px,py;自機の座標指定
gcopy 3,pk,0,32,32;バッファ画面(ウィンドウ3)より自機画像をコピー
;自機弾発射処理
shottime-- ;連射為の処理
if shottime<0: st=1 ;shottimeが0以下の時、stに1を代入
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)=0 : if st=1{ ;tf(cnt)が0の時=画面に弾がない時、かつstが1の時(shottimeが0以下の時){}内の命令を行う
th=th+1;一回で撃てる弾数の為の変数
tf(cnt)=1 ;tf(cnt)に1を代入。画面に弾があると言う事
st=0 ;連射の為の処理
shottime=2 ;連射の為の処理
ts=10 ;自機弾の速さ
if th=1 :tx(cnt)=px : ty(cnt)=py-12 : r=double(4.712) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts;直進弾
if th=2 :tx(cnt)=px-6 : ty(cnt)=py-12 : r=double(4.61) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts;左弾
if th=3 :tx(cnt)=px+6 : ty(cnt)=py-12 : r=double(4.813) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts : th=0;右弾
}
if tf(cnt)=1{ ;画面に弾があるとき、{}内の命令を行う
tx(cnt)=tx(cnt)+txv(cnt) : ty(cnt)=ty(cnt)+tyv(cnt) ;自機弾の移動量
pos tx(cnt),ty(cnt) ;自機弾の座標指定
gcopy 3,96,0,32,32 ;バッファ画面(ウィンドウ3)より自機弾画像をコピー
if ty(cnt)<-32 : tf(cnt)=0 : st=0 ;画面から自機弾が消えたら弾を消す
}
loop
ck_joystick ky,2048 ;Zキーのチェック
if ky&2048 { ;Zキーが押されていた時はmove(自機移動速度)を2にして連射速度を上げる。そうでなければmoveを4にする
move=2 : shottime=0 }else{
move=4
}
;ボム処理
ck_joystick ky,4096 ;Xキーのチェック
if ky&4096 { ;Xキーが押された時は{}内の命令を行う
if (bombcnt=-1)&(nbomb>0) { ;ボムが画面に出てなく、ボム数が0以上の時
nbomb=nbomb-1 ;ボム数を1減らす
bombcnt=0:bombp=17 ;ボムの存在を有にする。ボムアニメの為に変数を用意。
bpx=px-152 : bpy=py-400;ボムの座標指定
}
}
if bombcnt!-1 { ;ボムが画面に有る時。!は-1以外の時という事
repeat emt ;弾の存在を調べ画面に弾がある時は、弾の存在を消す(etf(cnt)=0)
if etf(cnt)<1 : continue
etf(cnt)=0
loop
bombcnt=bombcnt+1 ;ボムの効いている時間処理
if bombcnt=20 { bombcnt=-1 } ;20フレーム過ぎたらボムが効かなくなる
}
;敵移動処理
repeat emx ;repeat〜loop間をemx回繰り返す
ent=cnt
et(cnt)++ ;敵出現時間を+
if ef(cnt)<1 : continue ;ef(cnt)が1以下(敵が画面にいない)ならばrepeatに戻る
if enm(cnt)=4 : gosub *em04 ;敵の名前が4の時*em04へ移動
loop
;敵弾発射処理
repeat emt ;repeat〜loop間をemt回繰り返す
if etf(cnt)=1 { ;etf(cnt)が1(敵弾が画面にあるなら){}内の命令を行う
etx(cnt)=etx(cnt)+etxv(cnt) ;敵弾x座標に敵弾移動速度をプラス
ety(cnt)=ety(cnt)+etyv(cnt) ;敵弾y座標に敵弾移動速度をプラス
pos etx(cnt),ety(cnt) ;敵弾の座標指定
gcopy 3,etxp(cnt),etyp(cnt),etxs(cnt),etys(cnt) ;バッファ画面(ウィンドウ3)より敵弾画像をコピー
if etx(cnt)>480 : etf(cnt)=0 ;敵弾x座標が480以上になったら弾の存在を消す
if etx(cnt)<152 : etf(cnt)=0
if ety(cnt)>480 : etf(cnt)=0
if ety(cnt)<-16 : etf(cnt)=0
}
loop
;敵弾当り判定
repeat emt ;emt回繰り返す
if etf(cnt)=0 : continue
if etxs(cnt)=16 : ddx=(etx(cnt)+8)-(px+16) : if ddx<0 : ddx=-ddx ;自機と弾の中心座標の差の絶対値を求める
if etys(cnt)=16 : ddy=(ety(cnt)+8)-(py+16) : if ddy<0 : ddy=-ddy
if etxs(cnt)=8 : ddx=(etx(cnt)+4)-(px+16) : if ddx<0 : ddx=-ddx
if etys(cnt)=8 : ddy=(ety(cnt)+4)-(py+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<3))&(abs(ddy<3)) { ;x軸とy軸の差が3以下の時、ゲームオーバー
gend=1 ;1にするとゲームオーバー
}
loop
;爆風とボムのアニメ処理
if bombp>0 { ;ボムのアニメ処理変数が0以上の時{}内の命令を行う
bombp- : pos bpx,bpy
gcopy 5,320*(16-bombp),0,320,480
}
repeat emx ;敵のアニメ処理変数が0以上の時{}内の命令を行う
if bbmc(cnt)>0 {
bbmc(cnt)- : pos bbmx(cnt),bbmy(cnt)
gcopy 3,128+48*(16-bbmc(cnt)),0,48,48
}
loop
color 0,0,0 ;色に黒を指定
boxf 0,0,160,480 ;画面右側を黒で塗りつぶす
boxf 480,0,640,480 ;画面左側を黒で塗りつぶす
;スコア表示
font msmincho,18,3 ;フォントをMS明朝に、大きさを18に、イタリック体太字に指定
color 255,255,255 ;色に白を指定
pos 0,0
mes"Escで終了"
pos 496,0
mes"SCORE-"+sc+"-"
pos 496,462
mes"BOMB-"+nbomb+"-"
;fps表示
fp++
time=gettime(6)
if time!=time2{
fpc=fp
fp=0}
pos 0,462
mes " Fps "+fpc
time2=time
if gend=1 : gosub *gameover ;gendが1(ゲームオーバーの時)*gameoverに移動
redraw 1 ;メイン画面を更新
await 16 ;これを入れないとパソコンが固まる
gtime=gtime+1 ;タイムテーブルの為の変数
getkey syuryo,27:if syuryo=1:end ;Escキーのチェック。押されたら終了
goto *main ;*mainに戻る
;サブルーチン
*men ;タイムテーブル
if gtime=1 : bx=240 : by=-64 : gosub *eb04
if gtime=500 : gtime=0
return
*eb04;敵発生処理
repeat emx
if ef(cnt)>0 : continue ;画面に敵がいなければrepeatに戻る
enm(cnt)=4 ;敵の名前
ef(cnt)=100 ;敵の体力
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=0 : dy(cnt)=1 ;移動方向
et(cnt)=0 ;敵弾生成時間をリセット
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return
*em04;敵移動処理
if (et(cnt)>60)&(et(cnt)<250) : if gtime¥20=0 : gosub *tekitama4 ;敵生成時間が60以上250以下の時かつgtimeを20で割った余りが0の時*tekitama4へ移動
if (et(cnt)>60)&(et(cnt)<250) : if gtime¥20=0 : gosub *tekitama5
if (et(cnt)>30)&(et(cnt)<300) : if gtime¥5=0 : gosub *tekitama6
ex(cnt)=ex(cnt)+dx(cnt) ;敵の移動量決定
ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if et(cnt)<20 : dy(cnt)=5
if et(cnt)>21 : dy(cnt)=0
if et(cnt)>300 : dy(cnt)=3
if ey(cnt)>480 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 3,256,80,160,80 ;敵4の表示
;敵と自機との当り判定
ddx=(ex(cnt)+80)-(px+16) : if ddx<0 : ddx=-ddx
ddy=(ey(cnt)+40)-(py+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<70))&(abs(ddy<30)) {
gend=1
}
;自機弾と敵との当り判定
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)<1 : continue ;tf(cnt)が1以下(弾が画面にいない)ならばrepeatに戻る
ddx=(ex(ent)+80)-(tx(cnt)+16) : if ddx<0 : ddx=-ddx
ddy=(ey(ent)+40)-(ty(cnt)+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<70))&(abs(ddy<30)) { ;自機弾と敵のx軸とy軸の座標差を求め(敵と自機弾全て)、どちらも32以下であれば{}}内の命令を行う
tf(cnt)=0 ;弾が当った時は弾の存在を消す
ef(ent)- ;弾が当った時は敵の存在を消す
pos ex(ent),ey(ent)
gcopy 3,416,80,160,80
if ef(ent)=0 : sc+10000 : gosub *bomb2
}
loop
;ボム処理
if bombcnt!-1 {
ef(cnt)-
pos ex(cnt),ey(cnt)
gcopy 3,416,80,160,80
if ef(cnt)=0 : gosub *bomb2
}
return
*tekitama4;敵左側3方向弾
repeat emt
if etf(cnt)>0 : continue ;etfが0以上の時repeatに戻る
eh=eh+1 : etf(cnt)=1 ;弾数の為の処理。弾の存在を有にする
etx(cnt)=double(ex(ent)+37) : ety(cnt)=double(ey(ent)+80) ;弾の初期座標
etxp(cnt)=96 : etyp(cnt)=40;弾画像の場所指定
etxs(cnt)=8 : etys(cnt)=8;弾画像の大きさ指定
if eh=1 :ds=2 :r=atan(py-ey(ent), px-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=2 :ds=2 : r=atan(py-ey(ent), px+90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=3 :ds=2 : r=atan(py-ey(ent), px-90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=4 :ds=2.5 : r=atan(py-ey(ent), px-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=5 :ds=2.5 : r=atan(py-ey(ent), px+90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=6 :ds=2.5 : r=atan(py-ey(ent), px-90-ex(ent)): etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=7 :ds=3 : r=atan(py-ey(ent), px-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=8 :ds=3 : r=atan(py-ey(ent), px+90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=9 :ds=3 : r=atan(py-ey(ent), px-90-ex(ent)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds:eh=0 :break
loop
return
*tekitama5;敵右側3方向弾
repeat emt
if etf(cnt)>0 : continue
eh=eh+1 : etf(cnt)=1
etx(cnt)=double(ex(ent)+115) : ety(cnt)=double(ey(ent)+80)
etxp(cnt)=96 : etyp(cnt)=40
etxs(cnt)=8 : etys(cnt)=8
if eh=1 :ds=2 :r=atan(py-ey(ent), px-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=2 :ds=2 : r=atan(py-ey(ent), px+90-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=3 :ds=2 : r=atan(py-ey(ent), px-90-(ex(ent)+100)): etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=4 :ds=2.5 : r=atan(py-ey(ent), px-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=5 :ds=2.5 : r=atan(py-ey(ent), px+90-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=6 :ds=2.5 : r=atan(py-ey(ent), px-90-(ex(ent)+100)): etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=7 :ds=3 : r=atan(py-ey(ent), px-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=8 :ds=3 : r=atan(py-ey(ent), px+90-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=9 :ds=3 : r=atan(py-ey(ent), px-90-(ex(ent)+100)) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds:eh=0 :break
loop
return
*tekitama6;敵5方向弾
repeat emt
if etf(cnt)>0 : continue
eh=eh+1 : etf(cnt)=1
etx(cnt)=double(ex(ent)+72) : ety(cnt)=double(ey(ent)+60)
ds=6 ;敵弾の速さ
etxp(cnt)=96 : etyp(cnt)=48
etxs(cnt)=16 : etys(cnt)=16
if eh=1 : r=double(1.57) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=2 : r=double(1.97) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=3 : r=double(2.57) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=4 : r=double(1.17) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=5 : r=double(0.57) : etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds : eh=0 :break
loop
return
*bomb2;敵爆破処理
bbmx(ent)=ex(ent)+60 : bbmy(ent)=ey(ent)+20 ;爆風の座標指定
bbmc(ent)=17 ;爆風アニメの為の変数
return
*gameover
color rnd(255),rnd(255),rnd(255) ;色指定
pos 280,228
mes "Game Over"
pos 230,248
mes"Press X to Continue"
redraw 1
wait 1
ck_joystick ky ;Xキーのチェック。押されたら*startに戻る
if ky=4096 :goto *start
getkey syuryo,27:if syuryo=1:end
goto *gameover
*************************************
HSP3.0使用 CK_JOYFORCE.DLL使用 画像は↓を使用
これを実行すると5方向に青い弾を撃ちつつ、弾速の違う3方向自機狙い弾を左右の砲座から撃ってきます。
こんな感じで敵を増やしていけば、そこそこの物が出来そうな感じです^^
でも音楽もまだだし、完成までは程遠いと言った感じですが・・・
PR
この記事にコメントする
カレンダー
10 | 2024/11 | 12 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
リンク
カテゴリー
最新記事
(04/04)
(12/26)
(12/25)
(11/17)
(10/11)
プロフィール
HN:
kt.
性別:
男性
自己紹介:
プログラミング経験は昔ファミリーベーシックでちょっとさわったくらい。
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!
ブログ内検索
最古記事