敵がうまく表示できません、、、

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

敵がうまく表示できません、、、

#1

投稿記事 by cupa » 2年前

敵パターンをもち、ランダムで敵が落ちてくるというのを作りたいのですがうまくいきません。
ptn という変数をもって0~640のどこかにランダムで敵が落ちてくるようにしたいです。
まず、ランダムの作り方がわかりません、GetRandで試してみたところ、左右に拘束に揺れながら少しずつ落ちてきてしまいました。それをちょっといじくって配列を持つのをやめてみたのですが、
一瞬だけ右上に敵が現れ、すぐに消えてしまいます。
環境は、 OS:Windows 10 Home 64bit
     実行環境:Visual Studio 2022 PRE
     実力:初心者(THE SHOSINSHA)

これが実際のコードです、、、

コード:

#define WORLD_WIDTH 640
#define WORLD_HEIGHT 480
#define Tama 500
#define TEKI_MAX 5

#include "DxLib.h"

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

	int JikiX, JikiY, JikiGraph;
	int JikiTamaGraph, JikiTamaX[Tama], JikiTamaY[Tama], JikiTamaFlag[Tama];
	int Teki1X, Teki1Y, Teki1Flag, Teki1Graph;
	int titlebackground, gamebackground, titlefont, titlemojifont;
	int sht_sound;
	int ptn, ptn2;
	

	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++)
	{
		JikiTamaFlag[i] = 0;
	}

	for (j = 0; j < TEKI_MAX; j++)
	{
		Teki1Flag = 0;
	}

	titlebackground = LoadGraph("Game.title.jpg");
	gamebackground = LoadGraph("title2.jpg");
	JikiGraph = LoadGraph("sprite.png");
	JikiX = 320; JikiY = 400;
	JikiTamaGraph = LoadGraph("sht.jikishot.png");
	Teki1Graph = LoadGraph("killerT.png");
	Teki1X = 0; Teki1Y = 0;
	titlefont = CreateFontToHandle("けいふぉんと", 50, 9, DX_FONTTYPE_ANTIALIASING_EDGE);
	titlemojifont = CreateFontToHandle("07やさしさゴシック手書き", 20, 5, DX_FONTTYPE_ANTIALIASING_EDGE);
	sht_sound = LoadSoundMem("sht.c.z.mp3");
	ptn = 75;
	ptn2 = 200;

	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;
				PlaySoundMem(sht_sound, DX_PLAYTYPE_BACK);
			}
			break;
		case GAME:
			DrawGraph(0, 0, gamebackground, 0);
			break;
		case END:
			break;
		}

		if (status == TITLE)
		{
			DrawStringToHandle(70, 200, "シューティングゲーム", GetColor(255, 255, 255), titlefont);
			DrawStringToHandle(30, 420, "Zでゲーム開始", GetColor(255, 255, 255), titlemojifont);
			DrawStringToHandle(30, 450, "ESCでゲーム終了", GetColor(255, 255, 255), titlemojifont);

		}

		if (status == GAME)
		{
			DrawGraph(JikiX, JikiY, JikiGraph, true);

			if (CheckHitKey(KEY_INPUT_W))JikiY -= 3;
			if (CheckHitKey(KEY_INPUT_A))JikiX -= 3;
			if (CheckHitKey(KEY_INPUT_S))JikiY += 3;
			if (CheckHitKey(KEY_INPUT_D))JikiX += 3;


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

					GetGraphSize(JikiGraph, &Pw, &Ph);
					GetGraphSize(JikiTamaGraph, &Tw, &Th);

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

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

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

					// 画面に弾iを描画する
					DrawGraph(JikiTamaX[i] + 10, JikiTamaY[i] - 30, JikiTamaGraph, true);
					DrawGraph(JikiTamaX[i] - 10, JikiTamaY[i] - 30, JikiTamaGraph, true);
				}
			}
			
			for (int f = 0; f <= TEKI_MAX; f++)
			{
				if (Teki1Flag == 0)
				{
					

					Teki1X = ptn,ptn2;

					Teki1Y += 3;

					DrawGraph(Teki1X, Teki1Y, Teki1Graph, true);

					Teki1Flag = 1;
				}
			}

			if (Teki1Y >= WORLD_HEIGHT && Teki1Y <= -64)
			{
				Teki1Flag = 0;
			}

			if (JikiX > 640 - 64) JikiX = 640 - 64;
			if (JikiX <= 0) JikiX = 0;
			if (JikiY > 480 - 64) JikiY = 480 - 64;
			if (JikiY <= 0) JikiY = 0;


		}
		ScreenFlip();

	}


	DxLib_End();

	return 0;
}
お願いします、、、(´;ω;`)

参照魚
記事: 109
登録日時: 6年前

Re: 敵がうまく表示できません、、、

#2

投稿記事 by 参照魚 » 2年前

コード:

int Teki1X[TAMA_MAX], Teki1Y[TAMA_MAX], ...
敵関連の変数が配列になっていないです。

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

Re: 敵がうまく表示できません、、、

#3

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

cupa さんが書きました:
2年前
ptn という変数をもって0~640のどこかにランダムで敵が落ちてくるようにしたいです。
ptnをどう絡めるかがよくわかりませんが、敵を出す時に位置を乱数で決めるといいと思います。
cupa さんが書きました:
2年前
一瞬だけ右上に敵が現れ、すぐに消えてしまいます。
敵を出した時にしか敵を描画していないからですね。
cupa さんが書きました:
2年前

コード:

if (Teki1Y >= WORLD_HEIGHT && Teki1Y <= -64)
この条件式は常に偽であり、不自然です。
&& ではなく || の方がいいのではないでしょうか?
参照魚 さんが書きました:
2年前

コード:

int Teki1X[TAMA_MAX], Teki1Y[TAMA_MAX], ...
敵関連の変数が配列になっていないです。
「配列を持つのをやめてみた」とちゃんと書いてありますね。
無駄なループがあるのは若干気になりますが、
配列じゃないのに余計な添字をつけるなどの不適切なコードも無く、敵を1体だけ出すなら問題ないでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: 敵がうまく表示できません、、、

#4

投稿記事 by cupa » 2年前

敵を出した時にしか敵を描画していないからですね。
というのと、
この条件式は常に偽であり、不自然です。
&& ではなく || の方がいいのではないでしょうか?
というのは分かったのですが、
敵を出す時に位置を乱数で決めるといいと思います。
とありますが、乱数で位置を決めるにはどうすればいいのでしょうか、GetRandでやっても左右に高速に揺れながら少しずつ落ちていってしまうんですけど、、、(書いてありますが、漢字を間違えていました)これだけわかりませんのでご指摘お願いします。

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

Re: 敵がうまく表示できません、、、

#5

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

cupa さんが書きました:
2年前
乱数で位置を決めるにはどうすればいいのでしょうか、

コード:

for (int f = 0; f <= TEKI_MAX; f++)
{
	if (Teki1Flag == 0)
	{
		

		Teki1X = ptn,ptn2;

		Teki1Y += 3;

		DrawGraph(Teki1X, Teki1Y, Teki1Graph, true);

		Teki1Flag = 1;
	}
}

if (Teki1Y >= WORLD_HEIGHT && Teki1Y <= -64)
{
	Teki1Flag = 0;
}
この部分のかわりに、例えば

コード:

if (Teki1Flag == 0)
{
	// 敵を出す時に

	Teki1X = GetRand(640); // 位置を乱数で決める

	Teki1Y = -60;

	Teki1Flag = 1;
}
else
{
	DrawGraph(Teki1X, Teki1Y, Teki1Graph, true);
	Teki1Y += 3;

	if (Teki1Y >= WORLD_HEIGHT || Teki1Y <= -64)
	{
		Teki1Flag = 0;
	}
}
とすればいいでしょう。
添付ファイル
teki_test.zip
テスト用ソースコードと仮素材
(11.57 KiB) ダウンロード数: 113 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: 敵がうまく表示できません、、、

#6

投稿記事 by cupa » 2年前

いわれてた通り、やってみたのですが敵が一体がランダムなY座標に出てきて落ちてくる、
だけのプログラムになってしまいました。3体ぐらい、画面に出れるようにして画面から消えたら
TEKI_MAX?みたいなのをー1にして、常に三体いる状況を作りたいのですがどうしたらよいでしょうか。毎回聞いちゃってすみません、、、(頑張って試行錯誤しているも......)

littlestream
記事: 48
登録日時: 7年前

Re: 敵がうまく表示できません、、、

#7

投稿記事 by littlestream » 2年前

はじめまして!littlestramというものです。
変数の使いかたが若干不自然なのと
これだと敵の種類が増えたらもっとグローバル変数
を作らなくてはいけなくなるかもしれません。

なので、構造体(C++だとクラス扱い)で
変数をまとめてみます。

構造体という言葉に難しさを覚えたとしたら
この先に行うゲーム作りが冗長になってしまいます。

まず、敵の構造体からです。

コード:

typedef struct Enemy_{
	double x,y;
	double hp;
	bool useflag;
	int ImageHandle;
	int kind;
	//こんな感じの情報が
}Enemy_;

#define MAX (100)

Enemy_ Teki[MAX];
//これで100(MAX)個用意出来ました。

void PrepareShowEnemy(double x,double y,int image)
{
	for(int i=0;i<MAX;i++)
	{
		if(Teki[i].useflag==false)
		{
			Teki[i].useflag=true;
			Teki[i].x=x;
			Teki[i].y=y;
			Teki[i].ImageHandle=image;
			return;
		}
	}
	return;
}

void MoveAndDrawEnemy()
{
	for(int i=0;i<MAX;i++)
	{
		if(Teki[i].useflag==true)
		{
			DrawGraph(Teki[i].x,Teki[i].y,
			Teki[i].ImageHandle,TRUE);
			if(Teki[i].y>SCREEN_HEIGHT){
				Teki[i].useflag=false;
			}
		}
	}
}

//mainloop内にて以下を付け足す
	PrepareShowEnemy(rand()%640,-32,Image[zero]);
	MoveAndDrawEnemy();
敵が作れるなら自機も同様です。頑張ってみてください。(^^;)

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

Re: 敵がうまく表示できません、、、

#8

投稿記事 by cupa » 2年前

littlestream さん、はじめまして。
最近、C言語のサイトを見ていると殆どのサイトがその様になっていて「C言語はそうやって書くのかなぁ」を思っていました(笑)。これからは気をつけます、、、(C++を主にやっている人です、、)

返信

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