ページ 11

ドットイートゲーム 壁が動くし壁判定ができません

Posted: 2017年1月26日(木) 16:34
by けいすけ
先日質問させて頂いた者です。この前と同じプログラムについてお尋ねしたいことがあります。
①主人公("C")が動くと、壁が内側に詰めてきたリ外側にずれたりします。
②壁との当たり判定がうまくいきません。先生は、元の座標を保存しておく変数を宣言して、壁に当たった場合自機の座標(cx,cy)に元の変数を代入しろというので
という変数を作って、以下のようにプログラムしてみましたが、壁をすり抜けてしまいます。どうすればいいでしょうか。

コード:

#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h> // system()
#include <windows.h> // Sleep()
#include <conio.h> // kbhit()

#define SIZE 15 // 一辺の長さ
#define EMPTY 0 // 何もない場所は0
#define WALL 1	// 壁
#define FOOD 2	// えさ(ドット)
#define PACMAN 3// 主人公

int main()
{
	int wait_time = 300;
	int x, y;
	int food_count = 0;//エサの個数
	int cx = 0, cy = 0;//パックマン
	int key;
	int point = 0;
	int kx = cx, ky = cy;
	// 最も重要なデータ 1 は壁、えさは2、空白は 0
	// field[y][x]となるので注意!
	int field[SIZE][SIZE] =
	{
		{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
		{ 1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 },
		{ 1,2,1,1,1,2,1,1,1,2,1,2,1,2,1 },
		{ 1,2,1,0,1,2,1,0,1,2,1,2,2,2,1 },
		{ 1,2,1,1,1,2,1,1,1,2,1,2,1,2,1 },
		{ 1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 },
		{ 1,1,1,1,1,0,1,0,1,1,1,0,1,1,1 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 1,1,1,1,1,2,1,2,2,1,1,2,1,1,1 },
		{ 1,2,2,2,2,2,1,2,1,1,1,2,2,2,1 },
		{ 1,2,1,1,1,1,0,0,0,0,2,2,1,2,1 },
		{ 1,2,2,2,1,2,2,1,2,1,2,2,1,2,1 },
		{ 1,2,1,1,1,0,1,1,2,2,2,1,1,2,1 },
		{ 1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 },
		{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },


		// 自分で配列を完成させよう!
	};

	//まずはゲーム開始前の処理
	// パックマンを初期位置に配置
	cx = 7, cy = 7; //好きな場所に配置する!

						//エサの個数を数える
	for (y = 0; y < SIZE; y++)
	{
		for (x = 0; x < SIZE; x++)
		{
			if (field[y][x] == FOOD)
				food_count++;
		}
	}

	while (1)
	{
		// まずはPACMANの動き
		// キーが押されていたら、キーコードを取得する
		// 4なら左、6なら右、8なら上、2なら下
		if (kbhit()) // キーが入力されていれば真
		{
			key = getch();//一文字入力、エコーバックなし
			switch (key)
			{
			case '4':
				cx--;
				break;
			case '6':
				cx++;
				break;
			case '2':
				cy++;
				break;
			case '8':
				cy--;
				break;
			}
			cx = (cx + SIZE) % SIZE; //ワープ			
			switch (field[cy][cx])
			{
			case WALL://壁
				cx = kx,cy = ky; //動けないので cx, cy を元に戻す

				break;
			case FOOD:
				field[cy][cx] = 0;
				point += 10;
				food_count--;  //得点加算
				break;
			}
			


		}
		// ここまでPACMANの動き

		// 画面表示
		for (y = 0; y < SIZE; y++) {
			for (x = 0; x < SIZE; x++) {
				if (x == cx && y == cy)
					printf("C");
				else if (field[y][x] == FOOD)
					printf("◎");
				else if (field[y][x] == WALL)
					printf("■");
				else
					printf(" ");
			}
			printf("\n");
		}

		// すべての場所で field[y][x] の値を元に表示
		// shooting のコードを参考にしよう!(コピー可)

		printf("\n");
		printf(" (cx,cy) = (%d, %d)\n", cx, cy);
		printf(" point: %d\n", point);
		if (food_count == 0)
		{
			printf("GAME CLEAR\n");
			break;
		}
		Sleep(wait_time);// 1秒間(wait_timeミリ秒)何もしない
		system("cls");// 画面消去
	}
	return 0;
}



Re: ドットイートゲーム 壁が動くし壁判定ができません

Posted: 2017年1月26日(木) 17:33
by みけCAT
けいすけ さんが書きました:先日質問させて頂いた者です。
前のトピックを放置してはいけません。

フォーラムルールより
3. 禁止行為について

以下の行為を禁止行為として定めます。

(中略)

[C言語何でも質問掲示板でのみ適用される事項]

(中略)

質問後、お礼を言わずにトピックを閉じる、または去る行為
[hr]
けいすけ さんが書きました: ①主人公("C")が動くと、壁が内側に詰めてきたリ外側にずれたりします。
主人公以外(壁、エサ、空きマス)は全て半角文字2文字分なのに、主人公だけ半角文字1文字分の幅しかないからですね。
けいすけ さんが書きました: ②壁との当たり判定がうまくいきません。先生は、元の座標を保存しておく変数を宣言して、壁に当たった場合自機の座標(cx,cy)に元の変数を代入しろというので
という変数を作って、以下のようにプログラムしてみましたが、壁をすり抜けてしまいます。
コンパイルして実行したところ、コードを読んで予想したのと同じ
「壁に入ろうとすると一番左上のマスに飛ばされる」という現象が発生しましたが、
壁のすり抜けは確認できませんでした。
けいすけ さんが書きました: どうすればいいでしょうか。
最小限の・自己完結した・確認可能なサンプルコードを提示するといいでしょう。
今回提示されたコードは、主張された不都合が確認可能ではありませんでした。
不都合の再現に複雑な操作が必要な場合は、その操作手順も提示するといいでしょう。

また、あなたが見ているコード(提示するコード)と実行しているコードが同じであることを確認してください。
コンパイルしましたか?コンパイルする前にエディタ上のソースコードを保存しましたか?

提示されたソースコードから壁に入ろうとしても左上のマスに飛ばないようにするには、
cx, cyの更新処理を始める直前(67行目)でkx, kyに更新前のcx, cyの値を代入するようにするといいでしょう。
オフトピック
このサイトのシステムの糞仕様により、コード中の一部文字列が勝手にHTMLに置き換えられる不都合が発生しているようです。
引用ボタンを押すことで、もとのソースコードを得ることができます。
また、この不都合は「URL を自動的にパースしない」にチェックを入れて投稿することで(少なくとも今のところは)回避が可能です。

Re: ドットイートゲーム 壁が動くし壁判定ができません

Posted: 2017年1月26日(木) 18:30
by けいすけ
みけCAT さんが書きました:
けいすけ さんが書きました:先日質問させて頂いた者です。
前のトピックを放置してはいけません。

フォーラムルールより
3. 禁止行為について

以下の行為を禁止行為として定めます。

(中略)

[C言語何でも質問掲示板でのみ適用される事項]

(中略)

質問後、お礼を言わずにトピックを閉じる、または去る行為
[hr]
けいすけ さんが書きました: ①主人公("C")が動くと、壁が内側に詰めてきたリ外側にずれたりします。
主人公以外(壁、エサ、空きマス)は全て半角文字2文字分なのに、主人公だけ半角文字1文字分の幅しかないからですね。
けいすけ さんが書きました: ②壁との当たり判定がうまくいきません。先生は、元の座標を保存しておく変数を宣言して、壁に当たった場合自機の座標(cx,cy)に元の変数を代入しろというので
という変数を作って、以下のようにプログラムしてみましたが、壁をすり抜けてしまいます。
コンパイルして実行したところ、コードを読んで予想したのと同じ
「壁に入ろうとすると一番左上のマスに飛ばされる」という現象が発生しましたが、
壁のすり抜けは確認できませんでした。
けいすけ さんが書きました: どうすればいいでしょうか。
最小限の・自己完結した・確認可能なサンプルコードを提示するといいでしょう。
今回提示されたコードは、主張された不都合が確認可能ではありませんでした。
不都合の再現に複雑な操作が必要な場合は、その操作手順も提示するといいでしょう。

また、あなたが見ているコード(提示するコード)と実行しているコードが同じであることを確認してください。
コンパイルしましたか?コンパイルする前にエディタ上のソースコードを保存しましたか?

提示されたソースコードから壁に入ろうとしても左上のマスに飛ばないようにするには、
cx, cyの更新処理を始める直前(67行目)でkx, kyに更新前のcx, cyの値を代入するようにするといいでしょう。
オフトピック
このサイトのシステムの糞仕様により、コード中の一部文字列が勝手にHTMLに置き換えられる不都合が発生しているようです。
引用ボタンを押すことで、もとのソースコードを得ることができます。
また、この不都合は「URL を自動的にパースしない」にチェックを入れて投稿することで(少なくとも今のところは)回避が可能です。
いろいろとご指摘ありがとうございました。トピックをたてる時には、注意事項をきちんと守って投稿します。本当にすみませんでした。これからもよろしくおねがいいたします。

Re: ドットイートゲーム 壁が動くし壁判定ができません

Posted: 2017年1月26日(木) 18:39
by けいすけ
何度もすみません。先ほどの壁のあたり判定ができない件についてですが、プログラムを
[code=c]
int main()
{
int wait_time = 300;
int x, y;
int food_count = 0;//エサの個数
int cx , cy;//パックマン
int key;
int point = 0;
int kx , ky;
   :
   :
for (y = 0; y < SIZE; y++)
{
for (x = 0; x < SIZE; x++)
{
if (field[y][x] == FOOD)
food_count++;
}
kx = cx, ky = cy;
}
       :
       :
       :
      switch (field[cy][cx])
{
case WALL://壁
cx = kx,cy = ky; //動けないので cx, cy を元に戻す
[/code]

にすると、確かにCが一番左上のマスに飛ばされることもなくなりましたが、今度は壁にあたると中心(7,7)に戻ります。どう改善すればよいですか。

Re: ドットイートゲーム 壁が動くし壁判定ができません

Posted: 2017年1月26日(木) 18:55
by みけCAT
けいすけ さんが書きました:どう改善すればよいですか。
それは、あなたがどういう仕様にしたいかによります。
代入処理を私が指定した67行目、すなわちkey = getch();の所(直前でも直後でもよい)ではない場所に挿入したということは、
何か別の実験をしているのですよね?

Re: ドットイートゲーム 壁が動くし壁判定ができません

Posted: 2017年1月26日(木) 19:27
by けいすけ
みけCAT さんが書きました:
けいすけ さんが書きました:どう改善すればよいですか。
それは、あなたがどういう仕様にしたいかによります。
代入処理を私が指定した67行目、すなわちkey = getch();の所(直前でも直後でもよい)ではない場所に挿入したということは、
何か別の実験をしているのですよね?
ほんとにすみません。挿れる行をまちがっていました。おっしゃったとおりにするとちゃんと思い通りに行きました。ありがとうございます。