まったくのプログラミング素人の筆者がC++/HSPを使用してSTG(シューティングゲーム)を作っていく過程を書くブログでしたが最近は脱線気味。プログラミング以外にも、ゲーム関連の記事、日々の戯言など。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
ずっとなやんでた自機狙い弾がなんとか上手く動くようになってくれました^^
ただ単に配列変数を二重で使ってしまっていた為に動かなかっただけでした。敵一体一体に弾一個づつ処理しようと思って
二重にしてたんですが、そんな事する必要なかった。敵一体に対し弾全部の処理をすれば良かったんですね。
で、自機狙い弾なのですがこれも敵と自機の方向を計算して、その結果に弾の速さを掛けて距離で割ればよいみたい。
じゃ昨日の使ったMIAさんのスプリクトを使えば良いかな?と思ったら、それでは若干弾の速さが変わるみたい。(計算が正確ではないので)
遊々窓々さんのHSP講座を見てみると、距離を求めるためには・・・
c2=a2+b2
この式で求めるらしい。ちなみにこの式が三平方の定理。遠い昔に習った記憶が・・・今更、役に立つとは思ってもみませんでした。
つまり、自機と敵とのx軸とy軸を足した物の平方根を求めれば距離がわかる訳です。
ただここで問題があるようで、HSPには平方根を扱う命令がないようで、本当に正確な計算が必要な場合は外部プラグインが必要との事。
でも、筆者はとりあえず最初は基本命令だけで作って行こうと思っているので、遊々窓々さんのスプリクトを参考にさせてもらいました。
その平方根の計算方法ですが、まず平方根の計算の答えを沢山用意しておき
自機と敵とのx軸とy軸を足して2乗した物と比べるって方法です。
これだと、メチャクチャ正確には計算出来ませんが、ほぼ正確な計算が出来るのでシューティングでは問題ありません。
そのスプリクトがコレ↓
*************************************
;敵2スプリクト
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg3.gif";画像をバッファ1に読み込み
wxs=480 :wys=640 ;メイン画面の座標指定
screen 0,wxs,wys,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
px=208:py=576;自機の初期位置
tmx=10 ;自機弾の数
dim tx,tmx ;自機弾のX座標の配列変数
dim ty,tmx ;自機弾のY座標の配列変数
dim tf,tmx ;自機弾が画面にあるか無いかを調べる配列変数
emx=120;敵の数
dim ex,emx : dim ey,emx;敵の初期位置
dim dx,emx : dim dy,emx;敵の移動量
dim ef,emx;敵のフラグ
dim em,emx;敵の種類
dim et,emx;敵出現からの時間
emt=100;敵の弾
dim etx,emt : dim ety,emt ;敵弾の位置、移動量
dim etxv,emt ; etxv 敵弾x方向運動量
dim etyv,emt ; etyv 敵弾y方向運動量
dim etf,emt;敵弾のフラグ
;■ 平方根の準備
dim calc,900 ;平方根の為の配列変数
repeat 900 ;900回繰り返す。640x480の斜めの長さは約832なので
temp=cnt : calc(cnt)=temp*temp ;calc(cnt)にtempの2乗の値を入れておく
loop
*main
redraw 0 ;仮想画面を指定
color 0,0,0 ;色に黒を指定
boxf 0,0,480,640 ;仮想画面を黒で塗りつぶす
;面データ読み込み
gosub *men ;*men(タイムテーブル)へ移動
;自機移動処理
pk=0 ;自機の傾きの為の変数
stick ky,15;キーボードのチェック
if ky&1 :px-=8 :pk=64 :if px<0 :px=0;カーソルキー左(←)を押した時pxより-8を引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=8 :pk=128 :if px>416 :px=416
if ky&2 :py-=8 :if py<0 :py=0
if ky&8 :py+=8 :if py>576 :py=576
gmode 2 ;透明化処理の為の命令
pos px,py;自機の座標指定
gcopy 1,pk,0,64,64;バッファ画面(ウィンドウ1)より自機画像をコピー
;敵移動処理
repeat emx ;repeat〜loop間をemx回繰り返す
et(cnt)++ ;敵出現時間を+
if ef(cnt)<1 : continue ;ef(cnt)が1以下(敵が画面にいない)ならばrepeatに戻る
if enm(cnt)=2 : gosub *em02
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 1,192,64,16,16 ;バッファ画面(ウィンドウ1)より敵弾画像をコピー
if etx(cnt)>480 : etf(cnt)=0 ;敵弾x座標が480以上になったら弾の存在を消す
if etx(cnt)<0 : etf(cnt)=0
if ety(cnt)>640 : etf(cnt)=0
if ety(cnt)<0 : etf(cnt)=0
}
loop
redraw 1 ;メイン画面を更新
await 1 ;これを入れないとパソコンが固まる
gtime=gtime+1 ;タイムテーブルの為の変数
goto *main ;*mainに戻る
;サブルーチン
*men ;タイムテーブル
if gtime=150 : bx=0 : by=-64 : gosub *eb02
if gtime=151 : bx=415 : by=-64 : gosub *eb02
if gtime=200 : bx=0 : by=-64 : gosub *eb02
if gtime=201 : bx=415 : by=-64 : gosub *eb02
if gtime=250 : bx=0 : by=-64 : gosub *eb02
if gtime=251 : bx=415 : by=-64 : gosub *eb02
if gtime=252 : gtime=0
return
*eb02
repeat emx
if ef(cnt)>0 : continue
enm(cnt)=2 ;敵の名前
ef(cnt)=1 ;敵の有無(1=有)
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=3 : dy(cnt)=1 ;移動方向
et(cnt)=0 ;敵弾生成時間をリセット
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return
*em02
ex(cnt)=ex(cnt)+dx(cnt) ;敵の移動量決定
if(ex(cnt)<1)|(ex(cnt)>415) :dx(cnt)=-dx(cnt) ;画面の端まで行ったら反転させる
ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if ey(cnt)>640 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 1,0,128,64,64 ;敵2の表示
;敵弾移動速度&方向決定
dxh=px-ex(cnt) : mx=dxh : if dxh<0 : dxh=0-dxh ;dxhの絶対値の計算
dyh=py-ey(cnt) : my=dyh : if dyh<0 : dyh=0-dyh ;dyhの絶対値の計算
dst=(dxh*dxh)+(dyh*dyh) ;平方根計算の為の変数dst
repeat 900
if dst loop
;敵弾発生処理
sx=px-ex(cnt) ;自機と敵とのx軸の差
sy=py-ey(cnt) ;自機と敵とのy軸の差
txv=sx : tyv=sy ;txv,tyvにそれぞれ代入
if sx<0 : sx=0-sx ;sxの絶対値の計算
if sy<0 : sy=0-sy ;syの絶対値の計算
su=sx : if su ;suは自機と敵との大体の距離となる
if su>250 { ;suが250以上の場合if{}内の命令を行う
if ef(cnt)=1 { ;ef(cnt)が1(敵が画面にいる時){}内の命令を行う
if etf(cnt)=0 : if enm(cnt)=2 { ;etf(cnt)が0(画面に敵弾が無い)enm(cnt)が2(敵の名前が2の時){}内の命令を行う
etf(cnt)=1 ;画面に敵弾が存在する
etx(cnt)=ex(cnt)+24 : ety(cnt)=ey(cnt)+55 ;敵弾の初期座標指定。少しずらしておかないと敵と重なって発射される為
ds=7 ;敵弾の速度
etxv(cnt)=mx*ds/dst ;敵弾のx軸の移動量計算
etyv(cnt)=my*ds/dst ;敵弾のy軸の移動量計算
}
}
}
return
************************************
hsp3.0使用 画像は5月6日の画像を使用
これを実行すると、敵が左右にうごきつつ自機狙い弾を撃ってきます。
ずっと悩んでいたので動いた時は感動的でした^^
ただ単に配列変数を二重で使ってしまっていた為に動かなかっただけでした。敵一体一体に弾一個づつ処理しようと思って
二重にしてたんですが、そんな事する必要なかった。敵一体に対し弾全部の処理をすれば良かったんですね。
で、自機狙い弾なのですがこれも敵と自機の方向を計算して、その結果に弾の速さを掛けて距離で割ればよいみたい。
じゃ昨日の使ったMIAさんのスプリクトを使えば良いかな?と思ったら、それでは若干弾の速さが変わるみたい。(計算が正確ではないので)
遊々窓々さんのHSP講座を見てみると、距離を求めるためには・・・
c2=a2+b2
この式で求めるらしい。ちなみにこの式が三平方の定理。遠い昔に習った記憶が・・・今更、役に立つとは思ってもみませんでした。
つまり、自機と敵とのx軸とy軸を足した物の平方根を求めれば距離がわかる訳です。
ただここで問題があるようで、HSPには平方根を扱う命令がないようで、本当に正確な計算が必要な場合は外部プラグインが必要との事。
でも、筆者はとりあえず最初は基本命令だけで作って行こうと思っているので、遊々窓々さんのスプリクトを参考にさせてもらいました。
その平方根の計算方法ですが、まず平方根の計算の答えを沢山用意しておき
自機と敵とのx軸とy軸を足して2乗した物と比べるって方法です。
これだと、メチャクチャ正確には計算出来ませんが、ほぼ正確な計算が出来るのでシューティングでは問題ありません。
そのスプリクトがコレ↓
*************************************
;敵2スプリクト
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg3.gif";画像をバッファ1に読み込み
wxs=480 :wys=640 ;メイン画面の座標指定
screen 0,wxs,wys,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
px=208:py=576;自機の初期位置
tmx=10 ;自機弾の数
dim tx,tmx ;自機弾のX座標の配列変数
dim ty,tmx ;自機弾のY座標の配列変数
dim tf,tmx ;自機弾が画面にあるか無いかを調べる配列変数
emx=120;敵の数
dim ex,emx : dim ey,emx;敵の初期位置
dim dx,emx : dim dy,emx;敵の移動量
dim ef,emx;敵のフラグ
dim em,emx;敵の種類
dim et,emx;敵出現からの時間
emt=100;敵の弾
dim etx,emt : dim ety,emt ;敵弾の位置、移動量
dim etxv,emt ; etxv 敵弾x方向運動量
dim etyv,emt ; etyv 敵弾y方向運動量
dim etf,emt;敵弾のフラグ
;■ 平方根の準備
dim calc,900 ;平方根の為の配列変数
repeat 900 ;900回繰り返す。640x480の斜めの長さは約832なので
temp=cnt : calc(cnt)=temp*temp ;calc(cnt)にtempの2乗の値を入れておく
loop
*main
redraw 0 ;仮想画面を指定
color 0,0,0 ;色に黒を指定
boxf 0,0,480,640 ;仮想画面を黒で塗りつぶす
;面データ読み込み
gosub *men ;*men(タイムテーブル)へ移動
;自機移動処理
pk=0 ;自機の傾きの為の変数
stick ky,15;キーボードのチェック
if ky&1 :px-=8 :pk=64 :if px<0 :px=0;カーソルキー左(←)を押した時pxより-8を引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=8 :pk=128 :if px>416 :px=416
if ky&2 :py-=8 :if py<0 :py=0
if ky&8 :py+=8 :if py>576 :py=576
gmode 2 ;透明化処理の為の命令
pos px,py;自機の座標指定
gcopy 1,pk,0,64,64;バッファ画面(ウィンドウ1)より自機画像をコピー
;敵移動処理
repeat emx ;repeat〜loop間をemx回繰り返す
et(cnt)++ ;敵出現時間を+
if ef(cnt)<1 : continue ;ef(cnt)が1以下(敵が画面にいない)ならばrepeatに戻る
if enm(cnt)=2 : gosub *em02
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 1,192,64,16,16 ;バッファ画面(ウィンドウ1)より敵弾画像をコピー
if etx(cnt)>480 : etf(cnt)=0 ;敵弾x座標が480以上になったら弾の存在を消す
if etx(cnt)<0 : etf(cnt)=0
if ety(cnt)>640 : etf(cnt)=0
if ety(cnt)<0 : etf(cnt)=0
}
loop
redraw 1 ;メイン画面を更新
await 1 ;これを入れないとパソコンが固まる
gtime=gtime+1 ;タイムテーブルの為の変数
goto *main ;*mainに戻る
;サブルーチン
*men ;タイムテーブル
if gtime=150 : bx=0 : by=-64 : gosub *eb02
if gtime=151 : bx=415 : by=-64 : gosub *eb02
if gtime=200 : bx=0 : by=-64 : gosub *eb02
if gtime=201 : bx=415 : by=-64 : gosub *eb02
if gtime=250 : bx=0 : by=-64 : gosub *eb02
if gtime=251 : bx=415 : by=-64 : gosub *eb02
if gtime=252 : gtime=0
return
*eb02
repeat emx
if ef(cnt)>0 : continue
enm(cnt)=2 ;敵の名前
ef(cnt)=1 ;敵の有無(1=有)
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=3 : dy(cnt)=1 ;移動方向
et(cnt)=0 ;敵弾生成時間をリセット
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return
*em02
ex(cnt)=ex(cnt)+dx(cnt) ;敵の移動量決定
if(ex(cnt)<1)|(ex(cnt)>415) :dx(cnt)=-dx(cnt) ;画面の端まで行ったら反転させる
ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if ey(cnt)>640 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 1,0,128,64,64 ;敵2の表示
;敵弾移動速度&方向決定
dxh=px-ex(cnt) : mx=dxh : if dxh<0 : dxh=0-dxh ;dxhの絶対値の計算
dyh=py-ey(cnt) : my=dyh : if dyh<0 : dyh=0-dyh ;dyhの絶対値の計算
dst=(dxh*dxh)+(dyh*dyh) ;平方根計算の為の変数dst
repeat 900
if dst loop
;敵弾発生処理
sx=px-ex(cnt) ;自機と敵とのx軸の差
sy=py-ey(cnt) ;自機と敵とのy軸の差
txv=sx : tyv=sy ;txv,tyvにそれぞれ代入
if sx<0 : sx=0-sx ;sxの絶対値の計算
if sy<0 : sy=0-sy ;syの絶対値の計算
su=sx : if su
if su>250 { ;suが250以上の場合if{}内の命令を行う
if ef(cnt)=1 { ;ef(cnt)が1(敵が画面にいる時){}内の命令を行う
if etf(cnt)=0 : if enm(cnt)=2 { ;etf(cnt)が0(画面に敵弾が無い)enm(cnt)が2(敵の名前が2の時){}内の命令を行う
etf(cnt)=1 ;画面に敵弾が存在する
etx(cnt)=ex(cnt)+24 : ety(cnt)=ey(cnt)+55 ;敵弾の初期座標指定。少しずらしておかないと敵と重なって発射される為
ds=7 ;敵弾の速度
etxv(cnt)=mx*ds/dst ;敵弾のx軸の移動量計算
etyv(cnt)=my*ds/dst ;敵弾のy軸の移動量計算
}
}
}
return
************************************
hsp3.0使用 画像は5月6日の画像を使用
これを実行すると、敵が左右にうごきつつ自機狙い弾を撃ってきます。
ずっと悩んでいたので動いた時は感動的でした^^
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が特に好きで、並木学氏は最高!
ブログ内検索
最古記事