ページ 11

アクションの無敵時間について

Posted: 2014年11月07日(金) 11:34
by megaman
こんにちは、またお世話になります。
現在ロックマン風アクションゲームを制作中なのですが、
タイトル通り無敵時間で悩んでいます。

コード:

void AtariHeroAndMonster(int idx){
	//プレイヤーとモンスターの当たり判定
	int muteki = 0; // 無敵時間のカウンタ
	float ax1 = g_stagedata.hero.x + 10;
	float ay1 = g_stagedata.hero.y + 10;
	float ax2 = g_stagedata.hero.x + IMG_CHIPSIZE - 10;
	float ay2 = g_stagedata.hero.y + IMG_CHIPSIZE - 10;
	float bx1 = g_stagedata.enemies[idx].x + 10;
	float by1 = g_stagedata.enemies[idx].y + 10;
	float bx2 = g_stagedata.enemies[idx].x + IMG_CHIPSIZE - 10;
	float by2 = g_stagedata.enemies[idx].y + IMG_CHIPSIZE - 10;

	if ((ax1 < bx2) && (bx1 < ax2) && (ay1 < by2) && (by1 < ay2) && muteki == 0){
		muteki = 10000; // 無敵時間をセット
		g_stagedata.hero.life--; //1ライフ減らす
		//ライフがなくなったらゲームオーバー
		if(g_stagedata.hero.life < 1){
			g_gamestate = GAME_OVER;
			g_timerstart = g_lasttime;
		}
	}

	if (muteki > 0) {
		--muteki;
		//点滅処理
		g_stagedata.hero.muteki = muteki;
		if (muteki <= 0) {
			// 無敵時間の終わり
			muteki = 0;
		}
	}
}
イメージだと変数mutekiの中が0になったら判定が復活するのですが、
今だとそれが出来ていないです。よろしくお願いします。

Re: アクションの無敵時間について

Posted: 2014年11月07日(金) 12:21
by Ryo
g_stagedata.hero.muteki に無敵残り時間を保存しているようですが
3行目で定義しているmutekiに、保存している値を移してから13行目の判定しないといけないのでは?

Re: アクションの無敵時間について

Posted: 2014年11月10日(月) 10:07
by megaman
>Ryoさん
返信ありがとうございます。
g_stagedata.hero.mutekiはコメントにある通り、キャラクターの点滅処理のみに使う変数
なので(無敵のカウンタが5で割り切れる場合画像を表示しない)、あまり活用していないです。

私の流れとしては、
被弾する→無敵変数(muteki)に入れる→変数が0になるまでデクリメント→0になったらまた被弾する
なのですが、Ryoさんの言う「保存している値を移してから」というのがよくわかりません。

理解できなくてすいません、上の流れのどこの部分に保存している値を入れればいいのでしょうか?

Re: アクションの無敵時間について

Posted: 2014年11月10日(月) 11:27
by usao
変数の 寿命 や 通用範囲 等といったことを把握できていますか?

変数 muteki は,関数AtariHeroAndMonster()内のローカルな変数であり,
そこに記憶した情報は 関数を抜けた時点で失われてしまっている,という点はOKですか?

Re: アクションの無敵時間について

Posted: 2014年11月10日(月) 12:00
by megaman
>usaoさん
返信ありがとうございます。
すいません、ヘッダーファイルにてグローバルな変数を読み込んでいることを表記
していませんでした。ヘッダーファイルにはこのような構造体があります。

コード:

 
struct CharaData{
	float x, y;		//操作キャラの座標
	BOOL turn;		//向き
	BOOL noground;	//空中か
	BOOL jumping;	//飛んでいるか
	float jumppower, jumpforward;	//ジャンプ力を記録
	BOOL living;	//b使用中か
	EnemyType type;	//モンスターの種類
	int life;	//体力
	int muteki;	//無敵時間
};

struct StageData{
	int stagenum;	//ステージの番号
	int mapwidth;	//実際のマップの長さ
	int animcounter;//ループカウンター
	CharaData hero;	//操作キャラのデータ
	float scrollx;	//スクロールの座標
	CharaData enemies[MAX_ENEMY];
	CharaData knives[MAX_KNIFE];
	BOOL g_bkey_prev;	//ボタン記憶
};
extern StageData g_stagedata;

Re: アクションの無敵時間について

Posted: 2014年11月10日(月) 13:20
by softya(ソフト屋)
usaoさんと話が噛み合っていません。
int muteki = 0; // 無敵時間のカウンタ はローカル変数。
g_stagedata.hero.muteki はグローバル変数。
2つの違いを理解されていないのでは? と言うのがusaoさんの指摘です。

Re: アクションの無敵時間について

Posted: 2014年11月10日(月) 13:51
by usao
>変数 muteki は,関数AtariHeroAndMonster()内のローカルな変数であり,
>そこに記憶した情報は 関数を抜けた時点で失われてしまっている,という点はOKですか?

より具体的に書き直し.


関数AtariHeroAndMonster()の中にあるローカル変数 muteki というのは,

(1)初期値0な変数として生成され(line3)て
(2)場合によっては,10000が代入されたり(line14),デクリメントされたり(line24)して
(3)そして関数を抜ける際には捨てられる

という感じになっています.


AtariHeroAndMonster()と言う関数は,ゲーム進行のために繰り返し呼ばれるのだろうな,と思いますが,
AtariHeroAndMonster()が呼ばれるたびに毎回↑のようなことが起きるので,
(2)の演算結果は毎回即座に(3)の時点で失われているわけですが,ここのところの認識は大丈夫ですか?

Re: アクションの無敵時間について

Posted: 2014年11月11日(火) 09:49
by megaman
>softya(ソフト屋) さん
usaoさんの返信で理解しました。関数が呼ばれるたびに変数がなくなったり
代入されたりするわけですね。だから1ライフ減らす処理にいかない。

>usaoさん
確かに話がかみ合っていませんでしたね・・・変数の特徴を理解していませんでした。
つまり変数の代入をAtariHeroAndMonster()の外で行えばいいのでしょうか?

Re: アクションの無敵時間について

Posted: 2014年11月11日(火) 10:15
by usao
今後の制作活動においても絶対に必要なことだと思うので,まずは
>変数の 寿命 や 通用範囲 等といったこと
を復習されることをお勧めします.
(何か適当なC言語の入門みたいな本なりサイトなりで半日ほど学べば
 今のこの問題は簡単に解決できるようになると思いますよ.
 掲示板で回答を待つよりも きっと 安くて早くてうまい.)

Re: アクションの無敵時間について

Posted: 2014年11月11日(火) 11:26
by megaman
>usaoさん
そうですね、もう一度Cについて学ぼうと思います。
ローカルとグローバルは初期で理解すべきところですしね

お二人とも返信ありがとうございました。無敵判定については
解決できたので、ソースを貼っておきます。

コード:

void AtariHeroAndMonster(int idx){
	//プレイヤーとモンスターの当たり判定
	float ax1 = g_stagedata.hero.x + 10;
	float ay1 = g_stagedata.hero.y + 10;
	float ax2 = g_stagedata.hero.x + IMG_CHIPSIZE - 10;
	float ay2 = g_stagedata.hero.y + IMG_CHIPSIZE - 10;
	float bx1 = g_stagedata.enemies[idx].x + 10;
	float by1 = g_stagedata.enemies[idx].y + 10;
	float bx2 = g_stagedata.enemies[idx].x + IMG_CHIPSIZE - 10;
	float by2 = g_stagedata.enemies[idx].y + IMG_CHIPSIZE - 10;

	if ((ax1 < bx2) && (bx1 < ax2) && (ay1 < by2) && (by1 < ay2) && g_stagedata.hero.muteki == 0){
		g_stagedata.hero.life--; //1ライフ減らす
		//無敵時間
		g_stagedata.hero.muteki = 100;
		//ライフがなくなったらゲームオーバー
		if(g_stagedata.hero.life < 1){
			g_gamestate = GAME_OVER;
			g_timerstart = g_lasttime;
		}
	}

	if (g_stagedata.hero.muteki > 0) {
		--g_stagedata.hero.muteki;
		if (g_stagedata.hero.muteki <= 0) {
			// 無敵時間の終わり
			g_stagedata.hero.muteki = 0;
		}
	}
}

Re: アクションの無敵時間について

Posted: 2014年11月11日(火) 11:28
by megaman
すいません、解決にチェックを入れてませんでした。