[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プロジェクトファイルはコチラ↓
https://blog.cnobi.jp/v1/blog/user/63629cf35d5259ece1529ed13f0745b1/1240117763
もっと簡単に実装出来るやろ~と思っていたのですが、思いの外苦戦しました。
というのも、自機以外の全てのオブジェクトに対して左右スクロールの概念を踏まえて表示
させなければならないと言う点。
例えば、自機のX座標が200だったとします。で、自機弾を表示させようと思ってX座標を200にすると
左右スクロールした時に上手く動いてくれないんですよね。
(左右に移動した時は自機弾も左右に移動して欲しいので)
で、色々と試して見た結果、自機弾の初期X座標を(自機位置X*左右にどれだけスクロールしているか)
として、自機弾移動中は「X座標に左右にどれだけスクロールしているか」をプラスするようにすると
上手く動いてくれました。
敵や敵弾、当たり判定なども同じ考え方で、左右にどれだけ移動しているか?
という概念を持たないと自機狙い弾なども上手く動いてくれなくて苦労しました。
出来たプログラムを見てみると本当にこの方法であっているのか不安になりますが
とりあえず、ちゃんと動いているようなので良しとしています^^;
背景がズレてしまったりして、イマイチでした。
で、キャラ自体を左右に動かす考え方ではなくて表示領域を移動させる感じで考えてみた。
まず、表示領域を移動させる為には、↓のような要素を考えないといけません。
この画面で考えると、背景表示範囲が360、自機の大きさを48だとすると
自機が移動する範囲は360-48で312となります。
背景の大きさが640だとすると、背景表示範囲が360なので、640-360で280ドット分が隠れている
事になります。
現在の自機のX座標の位置を0だとすると、右に312移動する間に背景は左に280移動すれば良い
感じになるのではないか?と思い簡単なプログラムを作ってみました。
プロジェクトファイルはコチラ↓
https://blog.cnobi.jp/v1/blog/user/63629cf35d5259ece1529ed13f0745b1/1239948355
背景の表示はこんな感じで表示させています↓
DrawGraph( g_haikei01x-(ch.x/(312./280.)) , g_haikei01y , g_haikei01 , FALSE ) ;
右に312移動する間に背景が左に280移動するという事は(312./280.)で移動量が計算出来ます。
それを自機の移動位置から割れば背景表示のX座標がわかる・・・はず。
この方法だと背景がズレる事もないので、良い感じではないかと自分では思っています^^
とりあえず、コレを踏まえて現在作成中のゲームに背景の左右スクロールを追加しようと思っています。
原因は、同じヘッダファイルを2重でインクルードしていた事でした。何と言う初歩的なミス^^;
ずっと、原因が解らなかったのですが、構造体の書き方を変えたりして試していたら偶然気づく事が
出来ました。
で、構造体の変数を増やす事が出来るようになったので、敵を倒した時に爆破アニメを表示するように
爆破処理を追加してみました。
とりあえず、一つの爆風が倒した位置で表示されるだけです。
プロジェクトファイルはコチラ↓
https://blog.cnobi.jp/v1/blog/user/63629cf35d5259ece1529ed13f0745b1/1239810430
爆風処理としてはこんな感じ
////////////////////////////////////////////////////////////////////////////////////////
if(enemy[i].e_life<=0) {//敵体力が無い時
enemy[i].ex=enemy[i].ex+enemy[i].emx-g_hidariscroll-g_migiscroll;//爆風の左右移動
SetDrawBlendMode( DX_BLENDMODE_ALPHA , 150 );
DrawGraph( enemy[i].ex-12 , enemy[i].ey-12 , g_bakuha01[enemy[i].eb_time] , TRUE ) ;
SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;
if(g_gtime%2 == 0) enemy[i].eb_time++;//爆破アニメ
if(enemy[i].eb_time>=16) {//爆破アニメが表示し終わったら
g_sc=g_sc+100;//得点プラス
enemy[i].ef=0;//敵削除
}
////////////////////////////////////////////////////////////////////////////////////////
敵体力が無くなったら、その場に爆破画像を表示して2フレームに1回アニメさせて表示が終わったら
敵の存在を無しにしています。
ただ、爆風の表示順位を敵よりも手前に持って来たいのですが、手前に表示されたり奥に表示されたりで
上手く表示出来てないんですよね。
プログラムの流れ的に、後から表示した物が手前に来そうな気がするのですが・・・悩み中です^^;
アーケードの縦STGは殆どの作品が左右にもスクロールします。
それを実装してみました。
プロジェクトファイルはコチラ↓
https://blog.cnobi.jp/v1/blog/user/63629cf35d5259ece1529ed13f0745b1/1239732102
見た目は全く変わってませんが、左右に移動すると敵や敵弾も左右に移動します。
実装方法としては、左右を押した時に他のキャラを移動させる為の変数を作って
移動させているだけです。
ただ、斜め移動の場合は左右の移動速度が遅くなるので、その分遅く移動させなければならないと思い
遅くなるように作ってみたのですが、逆に挙動がおかしく感じたので、単純に左右のみで
移動させるようにしてみました。
でも、そうすると背景が段々とずれてくるので、どういうふうに実装したらよいのか悩み中です。
とりあえず、色んな縦STGを研究してみます^^;
それとは別に、ちょっと問題が出てきて、構造体の変数の数を増やすとちゃんとプログラムが
動いてくれなくなりました・・・
具体的には
typedef struct{//敵構造体
int ef;//有無
int img;//画像用
int e_time;//生成時間
int e_sizex;//画像の大きさ
int e_sizey;//画像の大きさ
int e_life;//体力
double ex,ey,emx,emy;//座標、移動量
}enemy_t;
と書いている場合はOKなのに
typedef struct{//敵構造体
int ef;//有無
int img;//画像用
int e_time;//生成時間
int e_sizex;//画像の大きさ
int e_sizey;//画像の大きさ
int e_life;//体力
int eb_time;//爆破時間
double ex,ey,emx,emy;//座標、移動量
}enemy_t;
このような感じでint eb_time;と言う変数(変数の名前は何を使っても同じ)を増やすだけで
プログラムが起動はするのですが挙動がおかしくなってしまいます。
変数を増やしただけで何故???と言った感じですが、いくら考えてもわからないので
もう寝ます(汗)
自機弾と敵との当たり判定を追加しました。
敵の体力の概念を導入して、自機弾と当たっている時は
SetDrawBlendMode( DX_BLENDMODE_ADD , 255 )と言う感じで光ってるようにしてみました。
このプログラムのプロジェクトファイルはコチラ↓
https://blog.cnobi.jp/v1/blog/user/63629cf35d5259ece1529ed13f0745b1/1239650332
複数対複数の当たり判定の場合はコチラで書いていますが、ちょっとややこしいです。
例えば画面上に自機弾が3発、敵が3機いたとします。
すると判定する要素は
自機弾1
自機弾2
自機弾3
敵1
敵2
敵3
の6つの要素となります。
この全ての要素の当たり判定を行う為には、自機弾1と敵全部、自機弾2と敵全部、自機弾3と敵全部の
当たり判定を行う必要があると言う事です。
プログラムで考えると2重にループさせて判定するとわかりやすいと思います。
敵=3;
自機弾=3;
for(i=0;i<敵;i++){
for(k=0;k<自機弾;k++){
~当たり判定処理~
}
}
こんな感じで判定しています。実際には画面上に出現する要素数は変動するので
配列変数を使って、画面にある要素だけを判定するようにしています。
関数としてはこんな感じ↓
////////////////////////////自機弾と敵の当たり判定////////////////////////////////////////////////////////////
//引数 なし
//返値 なし
void hantei_jikitama_teki(){
int j;
int i;
int atari=0;
int Cr;
Cr = GetColor( 255 , 0 , 0 ) ; // 色を取得
for(i=0;i<ENEMY;i++){//敵の数だけ繰り返す
if(enemy[i].ef==0) continue;
if(enemy[i].ef==1) {
for(j=0;j<JIKITAMA;j++){//自機弾の数だけ繰り返す
if(jikitama[j].tf==0) continue;
if(jikitama[j].tf==1) {
if( jikitama[j].tx+JIKI_TAMA_ATARIHANTEI<(enemy[i].ex+enemy[i].e_sizex)-ENEMY_ATARIHANTEI && enemy[i].ex+ENEMY_ATARIHANTEI<(jikitama[j].tx+jikitama[j].sx)-JIKI_TAMA_ATARIHANTEI && jikitama[j].ty+JIKI_TAMA_ATARIHANTEI<(enemy[i].ey+enemy[i].e_sizey)-ENEMY_ATARIHANTEI && enemy[i].ey+ENEMY_ATARIHANTEI<(jikitama[j].ty+jikitama[j].sy)-JIKI_TAMA_ATARIHANTEI) atari=1;else atari=0;
if( atari==1 ) {//当たったとき
SetDrawBlendMode( DX_BLENDMODE_ADD , 255 );
DrawGraph( enemy[i].ex , enemy[i].ey , g_teki01image[enemy[i].img] , TRUE ) ;//敵表示
SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;
enemy[i].e_life--;
jikitama[j].tf=0;//自機弾消去
}
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
自機弾と敵が当たった時は自機弾を消去して敵の体力を減らしています。
で、敵の移動処理の部分に
if(enemy[i].e_life<=0) {
enemy[i].ef=0;//敵消去
g_sc=g_sc+100;//得点プラス
}
こんな感じで、体力が0以下になったら敵を消去して、得点を100プラスするようにしてみました。
そして、とりあえず左上にスコア表示もさせてみた。
普通に表示させると、得点が0の時は0としか表示されませんが、↓こんな感じで%08dと書けば
8桁表示”00000000”と表示されます。
DrawFormatString(60,30,color_white,"%08d",g_sc);
08の部分を02にすれば2桁、05とすれば5桁表示になります。
本当は画像で数字を表示させたいのですが、表示方法は勉強中です^^;
| 07 | 2026/08 | 09 |
| 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 | 31 |
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!