今友人と一緒にC言語でゲームっぽいのを作ろうとしてるんだが、背景の作り方が分からない。
っで考えたのが多次元配列(二次元配列)で背景を描画し、キャラクタが重なったら消え、通り過ぎたら再描画しようと思ってます。再描画と言っても全画面すると重くなるので出来ればポイントだけ。
現段階では背景用の関数を作りそれをメインに渡し、表示させる関数に渡すという順路を考えてます。
しかし、ポインタで二次元配列を指定しポインタを渡せばOKという考えは甘く、うまくいきません。どこでエラーが出ているのかもよく分からない。
長くなったが、「二次元配列で背景を描画し、キャラが通り過ぎたらそのポイントだけ再描画したい」
C言語はポインタ、構造体は一応分かっているつもりです。
返答お願いします。
多次元配列の渡し方
Re:多次元配列の渡し方
> しかし、ポインタで二次元配列を指定しポインタを渡せばOKという考えは甘く、うまくいきません。どこでエラーが出ているのかもよく分からない。
どんなコードを書いてどんなエラーになったのかが分からないとどうすることもできません。
現状では、コンパイルエラーなのか、リンクエラーなのか、実行時エラーなのか、期待通りの動作をしなかっただけなのかもさっぱりわかりませんから。
どんなコードを書いてどんなエラーになったのかが分からないとどうすることもできません。
現状では、コンパイルエラーなのか、リンクエラーなのか、実行時エラーなのか、期待通りの動作をしなかっただけなのかもさっぱりわかりませんから。
Re:多次元配列の渡し方
説明不足orz
void haikei (void){
int hairetsu[30][60]={{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,…},
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,…}};
int *point_haikei;
pointer = &hairetsu[0][0];
(略)
}
void main (void){
int *point;
haikei(point);
(略)
print(point);
}
void print (int *point_print){
printf("%d",point_print[1]);
}
void haikei (void){
int hairetsu[30][60]={{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,…},
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,…}};
int *point_haikei;
pointer = &hairetsu[0][0];
(略)
}
void main (void){
int *point;
haikei(point);
(略)
print(point);
}
void print (int *point_print){
printf("%d",point_print[1]);
}
Re:多次元配列の渡し方
ソースを見る限り、多次元配列云々の話ではなく、根本的な理解不足がうかがえます。
> pointer = &hairetsu[0][0];
pointerが定義されていません。
> void main (void){
mainの返却値の型がintでなければ未定義の動作になります。
> haikei(point);
haikeiは引数を取れないはずでは?
> void print (int *point_print){
print関数の定義前に呼び出していますので、コンパイラは
int print()
と認識しています。
関数定義はこれと矛盾します。
> printf("%d",point_print[1]);
関数原型無しでprintfを呼び出した場合は未定義の動作になります。
> pointer = &hairetsu[0][0];
pointerが定義されていません。
> void main (void){
mainの返却値の型がintでなければ未定義の動作になります。
> haikei(point);
haikeiは引数を取れないはずでは?
> void print (int *point_print){
print関数の定義前に呼び出していますので、コンパイラは
int print()
と認識しています。
関数定義はこれと矛盾します。
> printf("%d",point_print[1]);
関数原型無しでprintfを呼び出した場合は未定義の動作になります。
Re:多次元配列の渡し方
開発環境とかも欲しいですね。printfを使ってるから、コンソールアプリケーションなんでしょうが、コンソールアプリケーションでのカーソル制御は開発環境によって違いますから…
WINAPIを使用してもよいのであれば、楽なんですけどね。
WINAPIを使用してもよいのであれば、楽なんですけどね。
Re:多次元配列の渡し方
WINAPIを使用したサンプルです。
変数名や書き方は私好みに変更していますが、コメントを入れてますので適当に解析してみてください。
無限ループしていて終了しないので、飽きたら終了させてください(^_^;)
変数名や書き方は私好みに変更していますが、コメントを入れてますので適当に解析してみてください。
無限ループしていて終了しないので、飽きたら終了させてください(^_^;)
#include <stdio.h> #include <windows.h> /* 定数 */ #define MAP_WIDTH 10 #define MAP_HEIGHT 11 #define MOVE_WAIT 100 /* グローバル変数 */ // コンソールウインドウ用出力ハンドル HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE); // プレイヤー座標 int px = 1; int py = 1; // 背景 /* プロトタイプ宣言 */ void printMap(int map[MAP_HEIGHT][MAP_WIDTH]); void printGrid(int x, int y, int grid); void printPlayer(int x, int y, int map[MAP_HEIGHT][MAP_WIDTH]); void moveUp(int start, int end, int map[MAP_HEIGHT][MAP_WIDTH]); void moveDown(int start, int end, int map[MAP_HEIGHT][MAP_WIDTH]); void moveLeft(int start, int end, int map[MAP_HEIGHT][MAP_WIDTH]); void moveRight(int start, int end, int map[MAP_HEIGHT][MAP_WIDTH]); /* メイン関数 */ void main(void) { // マップ用配列 // ※この程度の規模ならばグローバル変数にした方が制御が楽だとは思いますが、 // 多元配列を引数で渡す練習用にローカルで書いてます int map[MAP_HEIGHT][MAP_WIDTH] = { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} }; // 初期描画 printMap(map); printPlayer(1, 1, map); // プレイヤー移動制御 for(; ;) { moveRight(2, 8, map); moveDown(2, 3, map); moveLeft(7, 1, map); moveDown(4, 5, map); moveRight(2, 8, map); moveDown(6, 7, map); moveLeft(7, 1, map); moveDown(8, 9, map); moveRight(2, 8, map); moveUp(8, 7, map); moveLeft(7, 1, map); moveUp(6, 5, map); moveRight(2, 8, map); moveUp(4, 3, map); moveLeft(7, 1, map); moveUp(2, 1, map); } } /* 背景全描画 */ void printMap(int map[MAP_HEIGHT][MAP_WIDTH]) { for (int x = 0; x < 10; ++x) { for (int y = 0; y < 11; ++y) { printGrid(x, y, map[y][x]); } } } /* 背景1マスだけ描画 */ void printGrid(int x, int y, int grid) { COORD pos = {x, y}; SetConsoleCursorPosition(hout, pos); printf("%d", grid); } /* プレイヤーの描画 */ void printPlayer(int x, int y, int map[MAP_HEIGHT][MAP_WIDTH]) { // 移動する前のプレイヤー座標のマスをマップデータで上書きする printGrid(px, py, map[py][px]); // プレイヤー座標を更新(移動)する px = x; py = y; // 移動先の座標にプレイヤーを描画する COORD pos = {px, py}; SetConsoleCursorPosition(hout, pos); putc('@', stdout); } /* 上移動 */ void moveUp(int start, int end, int map[MAP_HEIGHT][MAP_WIDTH]) { for (int y = start; y >= end; --y) { printPlayer(px, y, map); Sleep(MOVE_WAIT); } } /* 下移動 */ void moveDown(int start, int end, int map[MAP_HEIGHT][MAP_WIDTH]) { for (int y = start; y <= end; ++y) { printPlayer(px, y, map); Sleep(MOVE_WAIT); } } /* 左移動 */ void moveLeft(int start, int end, int map[MAP_HEIGHT][MAP_WIDTH]) { for (int x = start; x >= end; --x) { printPlayer(x, py, map); Sleep(MOVE_WAIT); } } /* 右移動 */ void moveRight(int start, int end, int map[MAP_HEIGHT][MAP_WIDTH]) { for (int x = start; x <= end; ++x) { printPlayer(x, py, map); Sleep(MOVE_WAIT); } }