弾の発射がどうもうまくいきません、、、

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
cupa
記事: 117
登録日時: 2年前

弾の発射がどうもうまくいきません、、、

#1

投稿記事 by cupa » 2年前

DxLibで、ピエンのシューティングゲームを作ろうとしている者です。
オフトピック
#define WORLD_WIDTH 640
#define WORLD_HEIGHT 480
#define Tama 20

#include "DxLib.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int i;

int PienX, PienY, PienGraph;
int PienTamaGraph, PienTamaX[Tama], PienTamaY[Tama], PienTamaFlag[Tama];
int killer1X, killer2X, killer3X, killer1Y, killer2Y, killer3Y, killer1Graph, killer2Graph, killer3Graph;
int titlebackground, gamebackground, titlefont;

ChangeWindowMode(true);
SetGraphMode(WORLD_WIDTH, WORLD_HEIGHT, 64);
DxLib_Init();
SetDrawScreen(DX_SCREEN_BACK);
SetDrawMode(DX_DRAWMODE_BILINEAR);
SetWindowText("生姜");

for (i = 0; i < Tama; i++)
{
PienTamaFlag = 0;
}

titlebackground = LoadGraph("Game.title.jpg");
gamebackground = LoadGraph("title2.jpg");
PienGraph = LoadGraph("pien.png");
PienX = 320; PienY = 400;
PienTamaGraph = LoadGraph("pien.tama.png");
titlefont = CreateFontToHandle("HGP行書体", 50, 9, DX_FONTTYPE_ANTIALIASING_EDGE);


enum {
TITLE,

GAME,

END,
}status=TITLE;

while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
ClearDrawScreen();

switch (status)
{
case TITLE:
DrawGraph(0, 0, titlebackground, 0);
if (CheckHitKey(KEY_INPUT_Z)) {
status = GAME;
}
break;
case GAME:
DrawGraph(0, 0, gamebackground, 0);
break;
case END:
break;
}

if (status == TITLE)
{
DrawStringToHandle(70, 200, "シューティングゲーム", GetColor(255, 255, 255), titlefont);
}

if (status == GAME)
{
DrawGraph(PienX, PienY, PienGraph, true);

if (CheckHitKey(KEY_INPUT_W))PienY -= 3;
if (CheckHitKey(KEY_INPUT_A))PienX -= 3;
if (CheckHitKey(KEY_INPUT_S))PienY += 3;
if (CheckHitKey(KEY_INPUT_D))PienX += 3;


if (CheckHitKey(KEY_INPUT_SPACE) == 1)
{
int Pw, Ph, Tw, Th;

GetGraphSize(PienGraph, &Pw, &Ph);
GetGraphSize(PienTamaGraph, &Tw, &Th);

// 弾iの位置をセット、位置はボール君の中心にする
PienTamaX = (Pw - Tw) / 2 + PienX;
PienTamaY = (Ph - Th) / 2 + PienY;

PienTamaFlag = 1;



}

for (i = 0; i < Tama; i++)
{
// 自機の弾iの移動ルーチン( 存在状態を保持している変数の内容が1(存在する)の場合のみ行う )
if (PienTamaFlag == 1)
{
// 弾iを16ドット上に移動させる
PienTamaY -= 16;

// 画面外に出てしまった場合は存在状態を保持している変数に0(存在しない)を代入する
if (PienTamaY < -80)
{
PienTamaFlag = 0;
}

// 画面に弾iを描画する
DrawGraph(PienTamaX, PienTamaY, PienTamaGraph, FALSE);
}
}
}





if (PienX > 640 - 64) PienX = 640 - 64;
if (PienX <= 0) PienX = 0;
if (PienY > 480 - 64) PienY = 480 - 64;
if (PienY <= 0) PienY = 0;

ScreenFlip();

}


DxLib_End();

return 0;
}


このようなコードで、何に困っているかというと、弾の発射ができません。
前に教えてもらったサイトも見てみたのですが、最初から見ないと理解ができないし、自分のコードでの場合を知りたかったので投稿しました。どこを直せばいいのか、詳しく教えていただけると幸いです。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 弾の発射がどうもうまくいきません、、、

#2

投稿記事 by みけCAT » 2年前

ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態で、
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
offtopicタグはcodeタグではありません。
cupa さんが書きました:
2年前

コード:

			if (CheckHitKey(KEY_INPUT_SPACE) == 1)
			{
				int Pw, Ph, Tw, Th;

				GetGraphSize(PienGraph, &Pw, &Ph);
				GetGraphSize(PienTamaGraph, &Tw, &Th);

				// 弾iの位置をセット、位置はボール君の中心にする
				PienTamaX[i] = (Pw - Tw) / 2 + PienX;
				PienTamaY[i] = (Ph - Th) / 2 + PienY;

				PienTamaFlag[i] = 1;



			}
この部分において変数 i が適切に設定されていないため、 i はfor文を抜けた時のTamaになっており、
範囲外へのアクセスが発生してしまいます。
配列を走査し、空いている場所を見つけたらその添字を i に設定した状態で弾の情報を設定する、
というようにすると改善するでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 弾の発射がどうもうまくいきません、、、

#3

投稿記事 by みけCAT » 2年前

また、ここを修正した場合、スペースキーを押している間毎フレーム弾が出てしまいますね。
前のフレームにおけるスペースキーの状態を保持し、前のフレームでは押されていなかった場合のみ弾を出す、
のような処理を入れると動作が改善するかもしれません。
もちろん、毎フレーム弾を出したいのであればこのままでもいいかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

cupa
記事: 117
登録日時: 2年前

Re: 弾の発射がどうもうまくいきません、、、

#4

投稿記事 by cupa » 2年前

この部分において変数 i が適切に設定されていないため、 i はfor文を抜けた時のTamaになっており、
範囲外へのアクセスが発生してしまいます。
配列を走査し、空いている場所を見つけたらその添字を i に設定した状態で弾の情報を設定する、
というようにすると改善するでしょう。

みけさん回答ありがとうございます。
「配列を走査し、空いている場所を見つけたらその添字をiに設定」、というのはどういうことでしょうか、PienTamaX,PienTamaY,PienTamaFlagにをつければいいのでしょうか(そのことなら全部ついていました。)まだまだ初心者で内容がわかっていないのでコードのどこを変えたらいいのか教えてくれたら幸いです。

cupa
記事: 117
登録日時: 2年前

Re: 弾の発射がどうもうまくいきません、、、

#5

投稿記事 by cupa » 2年前

cupa さんが書きました:
2年前
PienTamaX,PienTamaY,PienTamaFlagにをつければいいのでしょうか

ここのところ、かっこiと書いてしまうと消えてしまうみたいなので修正します。~Flagにiをつければいいのでしょうか、に修正します。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 弾の発射がどうもうまくいきません、、、

#6

投稿記事 by みけCAT » 2年前

cupa さんが書きました:
2年前
~Flagにiをつければいいのでしょうか
いいえ。
cupa さんが書きました:
2年前
「配列を走査し、空いている場所を見つけたらその添字をiに設定」、というのはどういうことでしょうか、

コード:

if (CheckHitKey(KEY_INPUT_SPACE) == 1)
{
	i = -1;
	for (int p = 0; p < Tama; p++) // 配列を走査し
	{
		if (PienTamaFlag[p] != 1) // 空いている場所を見つけたら
		{
			i = p; // その添字をiに設定
			break;
		}
	}
	if (i >= 0)
	{
		int Pw, Ph, Tw, Th;

		GetGraphSize(PienGraph, &Pw, &Ph);
		GetGraphSize(PienTamaGraph, &Tw, &Th);

		// 弾iの位置をセット、位置はボール君の中心にする
		PienTamaX[i] = (Pw - Tw) / 2 + PienX;
		PienTamaY[i] = (Ph - Th) / 2 + PienY;

		PienTamaFlag[i] = 1;
	}


}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

cupa
記事: 117
登録日時: 2年前

Re: 弾の発射がどうもうまくいきません、、、

#7

投稿記事 by cupa » 2年前

みけCATさん、回答ありがとうございます。
試したところ本当にできました!!ありがとうございます!
ですが一点、弾は一応撃てるようになったのですが、スペースを長押しすると弾を保持?みたいな状態で、放すと飛びます、その弾が飛んでいるときにもう一度スペースを押すと弾が消えてしまい、もう一度振り出し(つまり一発しか打てないということ)になってしまいます。スペース長押・好きな時に弾を連射したいのですがどうしたらいいでしょうか、、、すみません、質問に言葉が足りませんでしたね、、、

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 弾の発射がどうもうまくいきません、、、

#8

投稿記事 by みけCAT » 2年前

cupa さんが書きました:
2年前
スペースを長押しすると弾を保持?みたいな状態で、放すと飛びます、その弾が飛んでいるときにもう一度スペースを押すと弾が消えてしまい、もう一度振り出し(つまり一発しか打てないということ)になってしまいます。
書いた通りに修正して実行してみましたが、再現せず、
予想通りスペースキーを押しっぱなしにすることで弾が連射され、
弾を20個出したところで配列に空き要素が無くなり、弾が止まりました。
(弾が画面外に抜けると、空き要素が再び生まれ、弾が再び発射されました)
screenshot.png
実行結果
screenshot.png (11.67 KiB) 閲覧数: 6334 回
cupa さんが書きました:
2年前
スペース長押・好きな時に弾を連射したいのですがどうしたらいいでしょうか、、、
なぜ思った通りの動作にならないかを調べ、思った通りの動作になるように修正するデバッグをしたらいいでしょう。
添付ファイル
tama_test_src.zip
検証用ソースコードと仮画像データ
(8.31 KiB) ダウンロード数: 99 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

cupa
記事: 117
登録日時: 2年前

Re: 弾の発射がどうもうまくいきません、、、

#9

投稿記事 by cupa » 2年前

脱字してたみたいです、、、ご迷惑かけてすみませんでした(´;ω;`)
でもそのおかげで弾が連射できるようになりました!!ここまで付き合ってくれてありがとうございました!

返信

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