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

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
megaman

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

#1

投稿記事 by megaman » 10年前

こんにちは、またお世話になります。
現在ロックマン風アクションゲームを制作中なのですが、
タイトル通り無敵時間で悩んでいます。

コード:

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になったら判定が復活するのですが、
今だとそれが出来ていないです。よろしくお願いします。

Ryo

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

#2

投稿記事 by Ryo » 10年前

g_stagedata.hero.muteki に無敵残り時間を保存しているようですが
3行目で定義しているmutekiに、保存している値を移してから13行目の判定しないといけないのでは?

megaman

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

#3

投稿記事 by megaman » 10年前

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

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

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

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

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

#4

投稿記事 by usao » 10年前

変数の 寿命 や 通用範囲 等といったことを把握できていますか?

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

megaman

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

#5

投稿記事 by megaman » 10年前

>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;

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

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

#6

投稿記事 by softya(ソフト屋) » 10年前

usaoさんと話が噛み合っていません。
int muteki = 0; // 無敵時間のカウンタ はローカル変数。
g_stagedata.hero.muteki はグローバル変数。
2つの違いを理解されていないのでは? と言うのがusaoさんの指摘です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

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

#7

投稿記事 by usao » 10年前

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

より具体的に書き直し.


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

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

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


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

megaman

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

#8

投稿記事 by megaman » 10年前

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

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

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

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

#9

投稿記事 by usao » 10年前

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

megaman

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

#10

投稿記事 by megaman » 10年前

>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;
		}
	}
}

megaman

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

#11

投稿記事 by megaman » 10年前

すいません、解決にチェックを入れてませんでした。

閉鎖

“C言語何でも質問掲示板” へ戻る