前回質問させていただいたプログラムでまた違う質問をさせて頂きます。
皆さんのおかげで、少しづつ完成に近づいていっているのですが、肝心な[敵]の表示がうまくできません。
先生はとりあえず一体でいいからと言われたので、まずは一体表示させたいところなんですが、
次のようにコードをかきました。
[code=C]
//////////////////////////////////////////////////////////////////////
//
// パックマンプログラム pacman.c
//
//
// 高等専門学校 情報工学科
// 平成29年1月26日
//
//////////////////////////////////////////////////////////////////////
#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, cy;//パックマン
int ex, ey;//敵機の座標
int key;
int r;
int point = 0;
int kx, ky;//自機の座標を保存するための変数
int mx, my;//敵機の座標を保存するための変数
// 最も重要なデータ 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,0,2,2,1,2,1,2,0,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,1,2,2,2,2,1 },
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
};
//まずはゲーム開始前の処理
cx = 7, cy = 7; // パックマンを初期位置に配置
ex = 6, ey = -6;//敵を初期位置に配置
//エサの個数を数える
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();//一文字入力、エコーバックなし
kx = cx, ky = cy;//自機の座標を保存する
mx = ex, my = ey;
switch (key)
{
case '4':
cx--;
break;
case '6':
cx++;
break;
case '2':
cy++;
break;
case '8':
cy--;
break;
}
cx = (cx + SIZE) % SIZE; //ワープ
//敵機の動き
r = rand() % 3; //3分の1の確率で自機をおいかける
if (r == 0) {
if (mx > cx) //敵機のx座標が自機のx座標より大きければx座標を減らして自機に向かう ex--;
if (mx < cx) //敵機のx座標が自機のx座標より小さければx座標を増やして自機に向かう
ex++;
if (my > cy) //敵機のy座標が自機のx座標より大きければy座標を減らして自機に向かう
ey--;
if (my < cy) //敵機のy座標が自機のx座標より小さければy座標を増やして自機に向かう
ey++;
}
switch (field[cy][cx])
{
case WALL://壁
cx = kx, cy = ky; //動けないので cx, cy を元に戻す
//壁に当たると自機の座標に元の座標を代入する
break;
case FOOD:
field[cy][cx] = 0;//餌を食べると餌が消える
point += 10; //得点加算
food_count--; //餌の数を減らしていく
break;
}
switch (field[ey][ex])
{
case WALL://壁
ex = mx, ey = my; //動けないので cx, cy を元に戻す
//壁に当たると自機の座標に元の座標を代入する
break;
}
}
// ここまでPACMANの動き
// 画面表示
for (y = 0; y < SIZE; y++) {
for (x = 0; x < SIZE; x++) {
if (x == cx && y == cy)
printf("C "); //注意するのは文字は半角2文字分にすること。じゃないと壁が動く。
else if (x == ex && y == ey)//敵の表示
printf("◇");
else if (field[y][x] == FOOD)
printf(". ");
else if (field[y][x] == WALL)
printf("■");
else
printf(" ");
}
printf("\n");
}
// すべての場所で field[y][x] の値を元に表示
printf("\n");
printf(" (cx,cy) = (%d, %d)\n", cx, cy);
printf(" (cx,cy) = (%d, %d)\n", ex, ey);
printf(" point: %d\n", point);
if (food_count == 0) //餌を食べきったとき(=CRER)の画面表示
{
printf("┏ ┏━┓┏━┓┏┳┓┳━┓ ┏━┓ ┳━┓ ┳━┓ ┳━┓ ┓\n");
printf("┃ ┃ ┓┣━┫┃┃┃┣┫ ┃ ┣┳┛ ┣┫ ┣┳┛ ┃\n");
printf("┗ ┗━┛┻ ┻┻ ┻┻━┛ ┗━┛ ┻┗┛ ┻━┛ ┻┗┛ ┛\n");
Sleep(wait_time);
break;
}
Sleep(wait_time);// 1秒間(wait_timeミリ秒)何もしない
system("cls");// 画面消去
}
return 0;
}
[/code]
自分ではどこが間違っているのかわかりません。どなたか教えてください。
ドットイートゲーム 敵の表示ができません
Re: ドットイートゲーム 敵の表示ができません
とりあえず実行せずにコードを読んだ感じでは、
- 敵の初期位置が画面外である上、eyやexの値をチェックせずにfield[ey][ex]を読んでいるので、範囲外へのアクセスにより未定義動作になる
- 敵が斜めに移動する場合がある (仕様?)
「うまくできません」だけでなく、具体的にどんな動きをさせたくて、どうなってしまうのかを書いてください。けいすけ さんが書きました:肝心な[敵]の表示がうまくできません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ドットイートゲーム 敵の表示ができません
すいません。説明不足でした。まず敵の動きは基本的に、自機と同じ仕様にしたいです。また、自機に近づいてくるようにプログラムしたつもりです。みけCAT さんが書きました:とりあえず実行せずにコードを読んだ感じでは、という問題がありそうですね。
- 敵の初期位置が画面外である上、eyやexの値をチェックせずにfield[ey][ex]を読んでいるので、範囲外へのアクセスにより未定義動作になる
- 敵が斜めに移動する場合がある (仕様?)
「うまくできません」だけでなく、具体的にどんな動きをさせたくて、どうなってしまうのかを書いてください。けいすけ さんが書きました:肝心な[敵]の表示がうまくできません。
そして、申し上げたように敵が表示されないのを改善して、まずは敵をちゃんと表示したいです。
Re: ドットイートゲーム 敵の表示ができません
いま、敵の初期位置を変えると、表示されました。けいすけ さんが書きました:すいません。説明不足でした。まず敵の動きは基本的に、自機と同じ仕様にしたいです。また、自機に近づいてくるようにプログラムしたつもりです。みけCAT さんが書きました:とりあえず実行せずにコードを読んだ感じでは、という問題がありそうですね。
- 敵の初期位置が画面外である上、eyやexの値をチェックせずにfield[ey][ex]を読んでいるので、範囲外へのアクセスにより未定義動作になる
- 敵が斜めに移動する場合がある (仕様?)
「うまくできません」だけでなく、具体的にどんな動きをさせたくて、どうなってしまうのかを書いてください。けいすけ さんが書きました:肝心な[敵]の表示がうまくできません。
そして、申し上げたように敵が表示されないのを改善して、まずは敵をちゃんと表示したいです。
しかし、うごきません。
なぜでしょう?
Re: ドットイートゲーム 敵の表示ができません
けいすけ さんが書きました:いま、敵の初期位置を変えると、表示されました。
しかし、うごきません。
なぜでしょう?
- キーを押していない
- 敵のy座標が自機のy座標と同じ
まず、kbhit()が真のときしか敵の移動処理をしていないので、キーを押さなければ敵は動きません。
さらに、コメントを取り除いて分かりやすいように{}を補うと というコードになっているので、mx > cxとmx < cxは同時に成立せず、キーを押しても敵のx座標は変わりません。
というのは誤りでした。みけCAT さんが書きました:敵が斜めに移動する場合がある (仕様?)
オフトピック
対応していないコンパイラがあるので、文字列でもコメントでもない場所に全角スペースを入れるべきではありません。
そもそも、インデントが崩れて表示される原因になるので、インデントにタブとスペースを混ぜるのはよくありません。
Emacsとかいうエディタの初期設定だとタブとスペースを混ぜてくるんだよ、あのクソが…
そもそも、インデントが崩れて表示される原因になるので、インデントにタブとスペースを混ぜるのはよくありません。
Emacsとかいうエディタの初期設定だとタブとスペースを混ぜてくるんだよ、あのクソが…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ドットイートゲーム 敵の表示ができません
敵の表示はうまくいきました!!アドバイス本当にありがとうございました。みけCAT さんが書きました:けいすけ さんが書きました:いま、敵の初期位置を変えると、表示されました。
しかし、うごきません。
なぜでしょう?という原因が考えられます。
- キーを押していない
- 敵のy座標が自機のy座標と同じ
まず、kbhit()が真のときしか敵の移動処理をしていないので、キーを押さなければ敵は動きません。
さらに、コメントを取り除いて分かりやすいように{}を補うと というコードになっているので、mx > cxとmx < cxは同時に成立せず、キーを押しても敵のx座標は変わりません。というのは誤りでした。みけCAT さんが書きました:敵が斜めに移動する場合がある (仕様?)
オフトピック対応していないコンパイラがあるので、文字列でもコメントでもない場所に全角スペースを入れるべきではありません。
そもそも、インデントが崩れて表示される原因になるので、インデントにタブとスペースを混ぜるのはよくありません。
Emacsとかいうエディタの初期設定だとタブとスペースを混ぜてくるんだよ、あのクソが…