C言語でゲームプログラムに関数を追加する方法

このQ&Aのポイント
  • C言語でゲームプログラムに関数を追加する方法を教えてください。
  • また、移動可能なマップを作成し、キャラクターの座標を操作することができるようにしたいです。
  • 具体的なプログラムの修正箇所や追加すべき関数などを教えてください。
回答を見る
  • ベストアンサー

C言語 ゲーム

このプログラムに関数を一つ増やしたいのですが、うまくできません。どこを、どうすればいいでしょう? 迷路の内容は未完成です。 #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> int KEY(int *Kn,int *Y,int *X); int main(void) { //数値格納 int kn; //入力キー int sty,stx; //座標 int fy,fx; //マップ範囲 int jm[25][40]; //移動可不判定 char mapc[3]={0};//複写されたマップ構成情報 //カウント int y,x; //判定生成、座標生成・描写用 //マップチップ char mc[2][3]={ /*mc[0] 移動可能*/" ", /*mc[1] 移動不可*/"■"}; //マップ構成 (最大値 25行x40列) char map[][81]={ /*00*/"■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■", /*01*/"■ ■                                    ■", /*02*/"■ ■■■■ ■                               ■", /*03*/"■ ■■   ■                               ■", /*04*/"■  ■ ■■■                               ■", /*05*/"■■ ■ ■                                 ■", /*06*/"■  ■ ■                                 ■", /*07*/"■ ■■ ■                                 ■", /*08*/"■    ■ ■                               ■", /*09*/"■                                      ■", /*10*/"■                                      ■", /*11*/"■                                      ■", /*12*/"■                                      ■", /*13*/"■                                      ■", /*14*/"■                                      ■", /*15*/"■                                      ■", /*16*/"■                                      ■", /*17*/"■                                      ■", /*18*/"■                                      ■", /*19*/"■                                      ■", /*20*/"■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■"}; //マップ範囲算出 fy=sizeof(map)/81; //行 fx=strlen(map[0])/2; //列 //キャラクター初期座標指定 sty=8,stx=8; /* 判定生成 */ for(y=0;y<fy;y++){ for(x=0;x<fx;x++){ strncpy(mapc ,&map[y][(x)*2] ,2 ); if(strncmp(mc[1],mapc,2)==0){jm[y][x]=1;} //移動不可判定 else if(strncmp(mc[0],mapc,2)==0){jm[y][x]=0;} //移動可能判定 } } /* 画面出力 */ while(1){ system("cls"); //画面消去 /* 座標生成、描写 */ for(y=0;y<fy;y++){ for(x=0;x<fx;x++){ strncpy(mapc ,&map[y][(x)*2] ,2); if(jm[y][x]==0){ if(y==sty&&x==stx) {printf("%s","○");} //キャラ表示 else if(strncmp(mc[0],mapc,2)==0) {printf("%s",mapc );} //移動可能表示 } else if (strncmp(mc[1],mapc,2)==0) {printf("%s",mapc );} //移動不可表示 } if(fx<40){printf("\n");} //fxが40未満の場合、改行 } if(sty==1&&stx==1){ printf("ゴールしました\n"); } /* 入力キー、移動座標出力 */ KEY(&kn,&sty,&stx); /* 壁、マップ外への侵入防止 */ for(y=0;y<sty+1;y++){ for(x=0;x<fx;x++){ if((y==sty&&x==stx&&jm[y][x]==1)||(fy<=sty||fx<=stx)){ if(kn==0x4b){stx++;} else if(kn==0x4d){stx--;} else if(kn==0x48){sty++;} else if(kn==0x50){sty--;} break; } } } /* 終了操作 */ if(kn==0x1b){printf("▼終了します。\n") ;break;} } } /* 入力キー、移動座標出力 */ int KEY(int *Kn,int *Y,int *X){ while(1){ *Kn=getch( ); //1:通常キー if (*Kn==0){ *Kn=getch( ); //2:特殊キー if (*Kn==0x4b){(*X)--;}// ← else if (*Kn==0x4d){(*X)++;}// → else if (*Kn==0x48){(*Y)--;}// ↑ else if (*Kn==0x50){(*Y)++;}// ↓ else if (*Kn==0x80){ }//特殊キー追加場所 else {continue;} break; } else if (*Kn==0x1b){}// Esc //else if (*Kn== ){} 通常キー追加場所 else {continue;} break; } return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

目的もなく、ただ「関数を一つ増やしたい」と言われても困ります。 目的を決まらなければ、どんな関数にしたらよいかがわかりません。 どんな関数にしたらよいかがわからなければ、プログラミングのしようがありません。 以下、余談にはなりますが。 > char map[][81]={ ■が2バイトだと決めつけていますが、UTF-8だと3バイトです。 プログラム中この2バイトであると決めつけた「2」という数値が出てきます。 これは「よくないプログラミング手法」です。 //マップチップ char mc[2][3]={ と用意しているのですから、マップデータを表示と同じにする必要はありません。 char map[][81]={ /*00*/"********************", /*01*/"* * * * *", ... などとすれば、2を掛けたり割ったりする必要がなくなります。 strncpy,strcmp関数もほとんど不要です。 あるいは int jm[25][40]; //移動可不判定 にマップ情報をいれるのですから、最初から int jm[][41]={ {1,1,1,1,1,1,1,1,1,1,....,1,2}, {1,0,1,0,0,1,1,1,1,1,0,....,1,2}, ... {2} } 等とjmに直接マップデータを記述して、 char map[][81] をまったく使用しない、という方法もあります。 // 列の終端、行の終端に 2 を使用しました。 // sizeofによる計算や、strlen関数の代りに、終端までの数を数えるようにします。 // 現行のmapでも、終端行の目印(空文字列とか)を入れて、そこまでの行数を数えるようにする方が、sizeofを使うものに比べて汎用性がよいです。 /* 壁、マップ外への侵入防止 */ for(y=0;y<sty+1;y++){ for(x=0;x<fx;x++){ if((y==sty&&x==stx&&jm[y][x]==1)||(fy<=sty||fx<=stx)){ 条件をよく見てください。 この条件が成立するのは、次のどちらかが成立している場合です。 1. (fy<=sty||fx<=stx) 2. (y==sty&&x==stx&&jm[y][x]==1) 1.には、変数 x,y が使われていないので、ループの影響は受けません。 2. では、 少なくとも、y==sty&&x==stx が成立している必要があります。これ以外のx,yでは不成立です。  つまり、 このforループでは、y==sty&&x==stxの1回以外は無駄なループです。 sty,stxが範囲外だと、jm[sty][stx]==1 で動作に不具合が出ます。 ですが、 (sty,stxが範囲外である) || (jm[sty][stx]==1) とすると、 || 演算子の特性( 左が真なら、右は計算しない) によって、 jm[sty][stx]==1 を評価するのは sty,stxが が範囲内の場合のみ、となります。 もっとも、私なら次のように作ります newX=stx ; newY=sty ; /* 入力キー、移動座標出力 */ KEY(&kn,&newY,&newX); /* 壁、マップ外への侵入防止 */ if ( newX,newYがマップの範囲内 && jm[newY][newX]==0 ) { stx=newX; sty=newY; } キーコードで判定して移動したものを、またキーコードで判定して元に戻す、なんて、面倒ではなかったですか? 「移動」に必要なのは、次の座標と、そこへ移動できるかどうかの判断だけで、キーコードは不要です。

tokkurisann
質問者

お礼

無茶なこと質問した自分にこんなにも回答ありがとうございます。すごくためになりました。 自分でももう一度考えてみたいと思います。

関連するQ&A

  • C言語 ゲーム

    今回が質問初めてです。見にくかったらすいません。下のプログラムですが、これに構造体を使わなくてはいけないのですが、まったくわかりません。みなさんはどう書き換えますか? #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> int KEY(int *Kn,int *Y,int *X); int main(void) { //数値格納 int kn; //入力キー int sty,stx; //座標 int fy,fx; //マップ範囲 int jm[25][40]; //移動可不判定 char mapc[3]={0};//複写されたマップ構成情報 //カウント int y,x; //判定生成、座標生成・描写用 //マップチップ char mc[2][3]={ /*mc[0] 移動可能*/" ", /*mc[1] 移動不可*/"■"}; //マップ構成 (最大値 25行x40列) char map[][81]={ /*00*/"■■■■■■■■■■", /*01*/"■ ■      ■", /*02*/"■ ■■■■ ■ ■", /*03*/"■ ■■   ■ ■", /*04*/"■  ■ ■■■ ■", /*05*/"■■ ■ ■   ■", /*06*/"■  ■ ■ ■■■", /*07*/"■ ■■ ■   ■", /*08*/"■    ■ ■ ■", /*09*/"■■■■■■■■■■"}; //マップ範囲算出 fy=sizeof(map)/81; //行 fx=strlen(map[0])/2; //列 //キャラクター初期座標指定 sty=8,stx=8; /* 判定生成 */ for(y=0;y<fy;y++){ for(x=0;x<fx;x++){ strncpy(mapc ,&map[y][(x)*2] ,2 ); if(strncmp(mc[1],mapc,2)==0){jm[y][x]=1;} //移動不可判定 else if(strncmp(mc[0],mapc,2)==0){jm[y][x]=0;} //移動可能判定 } } /* 画面出力 */ while(1){ system("cls"); //画面消去 /* 座標生成、描写 */ for(y=0;y<fy;y++){ for(x=0;x<fx;x++){ strncpy(mapc ,&map[y][(x)*2] ,2); if(jm[y][x]==0){ if(y==sty&&x==stx) {printf("%s","○");} //キャラ表示 else if(strncmp(mc[0],mapc,2)==0) {printf("%s",mapc );} //移動可能表示 } else if (strncmp(mc[1],mapc,2)==0) {printf("%s",mapc );} //移動不可表示 } if(fx<40){printf("\n");} //fxが40未満の場合、改行 } if(sty==1&&stx==1){ printf("ゴールしました\n"); } /* 入力キー、移動座標出力 */ KEY(&kn,&sty,&stx); /* 壁、マップ外への侵入防止 */ for(y=0;y<sty+1;y++){ for(x=0;x<fx;x++){ if((y==sty&&x==stx&&jm[y][x]==1)||(fy<=sty||fx<=stx)){ if(kn==0x4b){stx++;} else if(kn==0x4d){stx--;} else if(kn==0x48){sty++;} else if(kn==0x50){sty--;} break; } } } /* 終了操作 */ if(kn==0x1b){printf("▼終了します。\n") ;break;} } } /* 入力キー、移動座標出力 */ int KEY(int *Kn,int *Y,int *X){ while(1){ *Kn=getch( ); //1:通常キー if (*Kn==0){ *Kn=getch( ); //2:特殊キー if (*Kn==0x4b){(*X)--;}// ← else if (*Kn==0x4d){(*X)++;}// → else if (*Kn==0x48){(*Y)--;}// ↑ else if (*Kn==0x50){(*Y)++;}// ↓ else if (*Kn==0x80){ }//特殊キー追加場所 else {continue;} break; } else if (*Kn==0x1b){}// Esc //else if (*Kn== ){} 通常キー追加場所 else {continue;} break; } return 0; }

  • C言語にて至急質問!!

    授業でゲーム作成してますがタイム表示とえさの残り数表示と残りのライフ表示 のプログラムがわかりません プログラムは下にあります #include<stdio.h> #include<stdlib.h> #include<time.h> #include"utility.h" int map[25][40]; typedef struct{ int x; int y; int life; int col; }CHAR; void disp(int,int); void main(void) { FILE *fp; CHAR man,mapsize,teki[5]; int i,j,cnt = 0,x,y,flg,wx,wy,stime = 0,etime = 0 ; GetConsoleHandle( ); srand(time(NULL)); fp = fopen("map.txt","r"); if(fp == NULL){ printf("ファイルエラー\n"); return; } fscanf(fp,"%d %d",&mapsize.y,&mapsize.x); fscanf(fp,"%d %d",&man.y,&man.x); wy = man.y; wx = man.x; fscanf(fp,"%d" "%d",&y,&x); for(i = 0;i < mapsize.y;i++) for(j = 0;j < mapsize.x;j++){ fscanf(fp,"%d",&map[i][j]); if(map[i][j] == 1) cnt++; } fclose(fp); disp(mapsize.x,mapsize.y); Locate(man.x * 2 +10,man.y + 3); printf("Э"); if(map[man.y][man.x] == 1){ cnt--; map[man.y][man.x] = 0; } man.life = 10; man.col = 0x0e; for(i = 0;i < 5;i++){ teki[i].y = y; teki[i].x = x; teki[i].life = 1; teki[i].col = rand() % 7 + 9; } while(cnt && man.life){ Wait(100); if(KeyCheck(ESCAPE)) break; Locate(man.x * 2 + 10,man.y + 3); SetColor2(0x00); printf(" "); if(KeyCheck (LEFT) && map[man.y][man.x - 1] != 9){ man.x--; } if(KeyCheck (RIGHT) && map[man.y][man.x + 1] != 9){ man.x++; } if(KeyCheck (UP) && map[man.y - 1][man.x] != 9){ man.y--; } if(KeyCheck (DOWN) && map[man.y + 1][man.x] != 9){ man.y++; } flg = -1; for(i = 0;i < 5;i++){ if(man.y == teki[i].y && man.x == teki[i].x) flg = i; } if(flg == -1){ if(map[man.y][man.x] > 9){ j = map[man.y][man.x]; man.x = j / 100; man.y = j % 100; } if(map[man.y][man.x] == 1){ cnt--; map[man.y][man.x] = 0; } else if(map[man.y][man.x] == 2){ map[man.y][man.x] = 0; stime = time(NULL); etime = stime + 10; } }else{ stime = time(NULL); if(stime < etime){ teki[flg].life--; if(map[teki[flg].y][teki[flg].x] == 1){ map[teki[flg].y][teki[flg].x] = 0; cnt--; }else if(map[teki[flg].y][teki[flg].x] == 2){ map[man.y][man.x] = 0; stime = time(NULL); etime = stime + 10; } }else{ man.life--; SetColor(0x0f); Locate(60,3); Locate(teki[flg].x * 2,teki[flg].y); SetColor2(teki[flg].col); printf("Ψ"); man.x = wx; man.y = wy; Wait(3000); Locate(man.x * 2 + 10,man.y + 3); SetColor2(man.col); printf("Э"); } } Locate(man.x * 2 + 10,man.y + 3); SetColor2(man.col); printf("Э"); for(i = 0;i < 5;i++){ if(teki[i].life == 1){ Locate(teki[i].x * 2 + 10,teki[i].y +3); switch(map[teki[i].y][teki[i].x]){ case 0:SetColor2(0x0f); printf(" "); break; case 1:SetColor2(0x0f); printf("・"); break; case 2:SetColor2(0x0c); printf("♪"); break; } j = rand() % 4; if(j == 0 && map[teki[i].y - 1][teki[i].x] != 9){ teki[i].y--; } if(j == 1 && map[teki[i].y][teki[i].x + 1] != 9){ teki[i].x++; } if(j == 2 && map[teki[i].y + 1][teki[i].x] != 9){ teki[i].y++; } if(j == 3 && map[teki[i].y][teki[i].x - 1] != 9){ teki[i].x--; } Locate(teki[i].x * 2 + 10,teki[i].y + 3); stime = time(NULL); if(stime < etime) SetColor2(teki[i].col << 4); else SetColor2(teki[i].col); printf("Ψ"); }else{ stime = time(NULL); if(stime >= etime){ teki[i].life = 1; teki[i].y = y; teki[i].x = x; } } } } } void disp(int x,int y){ int i,j; for(i = 0;i < y;i++){ for(j = 0;j < x;j++){ Locate(j*2 + 10,i + 3); switch(map[i][j]){ case 0:SetColor2(0x00); printf(" "); break; case 1:SetColor2(0x0f); printf("・"); break; case 2:SetColor2(0x0c); printf("♪"); break; case 9:SetColor2(0x99); printf("■"); break; default:SetColor2(0x0d); printf(" "); } } } } このどこかに質問したプログラムがはいるかもおしえてほしいです。 至急回答をどうかおねがいします

  • C言語の問題がわからないです。

    C言語のプログラムで、列数を自分で決めて、 (例)3列         ●(この行を最後として)   □● ●□● 上記のプログラムを作りたいのですが、 上手くいきません。途中まで作ったのですが、なかなか思うようにいかないです。どうすれば上記のようになりますでしょうか? #include <stdio.h> void disp(int x, int y); main() { int i,n; printf("表示する列:"); scanf("%d",&n); disp(3,3); for(i=1;i<=n;i++){ if(i%2==0){ disp(n-i,4); disp(i,2); } else{ disp(n-i,4); disp(i,1); } disp(1,3); } } void disp(int x, int y) { int i; for(i=0;i<x;i++){ if(y==1){ printf("●"); } else if(y==2){ printf("□"); } else if(y==3){ printf("\n"); } else{ printf("\0"); } } }

  • C言語のプログラムについて

    三角形を判定するプログラムを作ったのですが直角三角形ができるはずがないのに直角三角形の判定が出てしまいます。簡単なことなのかもしれませんが自分ではわからなくなってしまったのでご指摘してもらいたいです。 #include<stdio.h> void tri(int x,int y,int z) { if((x*x==y*y+z*z)||(y*y==x*x+z*z)||(z*z==x*x+y*y)) { printf("これは直角三角形です。"); printf("これは三角形です。"); }else if((x+y>=z)||(x+z>=y)||(y+z>=x)) { printf("これは三角形ではありません。"); }else{ printf("これは三角形です。"); } } int main(void) { int e1,e2,e3; printf("3辺を入力してください"); scanf("%f,%f,%f",&e1,&e2,&e3); tri(e1,e2,e3); return(0); }

  • C言語のプログラムについて質問

    明解C言語という書籍に 大きい方を表示するプログラム #include <stdio.h> int maxof(int x, int y) {  if (x > y)   return (x);  else   return (y); } int main(void) {  int na, nb;  puts("二つの整数を入力してください。");  printf("整数1:"); scanf("%d", &na);  printf("整数1:"); scanf("%d", &na);  printf("大きいほうの値は%dです。\n", maxof(na, nb));  return (0); } の関数maxofを利用し、 int max4(int w, int x, int y, int z) {  return (maxof(maxof(w, x), maxof(y, z))); } を挿入して変えれば四つの整数から最大値を求められるとのことですが、 コンパイルがうまくいきません。 関数maxofのwとx,yとzをそれぞれ比較し最大値を求めてさらにmaxof(w, x)とmaxof(y, z)を比較して最大値を求めるということですよね?ですので、 maxof(w, x) {  if (w > x)   return (w);  else   return (x); } maxof(y, z) {  if(y > z)   return (y);  else   return (z); を挿入しようとしたらmaxofはすでにありますというようなことが表示されてだめでした。 また、 int maxof(maxof(int w, int x), maxof(int y, int z)) { if (w > x)   return (w); if (w < x)   return (x); if (y > z)   return (y); if (y < z)   return (z); if (maxof(w, x) > maxof(y, z))   return (maxof(w, x)); if (maxof(w, x) < maxof(y, z))   return (maxof(y, z)); } としてみましたがやはりだめでした。 前のページの説明を読み返したりネットで調べてもわかりませんでした。 何がわからないのかがわからないのでもうお手上げです。 長くなってすいません プログラム例と説明をお願いします。

  • c言語迷路問題!!!緊急

    以下のプログラム毎行一つずつ、コマンド書いてほしいです。地図大きから書いてないでず、他のコマンドよろしくお願いします、ありがとうございます。 #include <stdio.h> #define MAP_X 39 // X座標 #define MAP_Y 43 // Y座標 #define LOL 24 void map() ; // 地図 void cm() ; void trap() ; void map1() ; int ws[ LOL * MAP_X ] ; int wk[ MAP_X * MAP_Y ] = { }; int a = 1 ; char com ; int pz = 1599 ; int main( void ) { int flg = 1 ; map() ; while( flg != 0 ) { cm() ; switch( com ) { case 'w' : if( wk[ pz - 39 ] == 0 ) { wk[ pz - 39 ] = 2 ; wk[ pz ] = 0 ; pz -= 39 ; map() ; } else { printf( "コマンド入力 : " ) ; } break ; case 's' : if( wk[ pz + 39 ] == 0 ) { wk[ pz + 39 ] = 2 ; wk[ pz ] = 0 ; pz += 39 ; map() ; } else { printf( "コマンド入力 : " ) ; } break ; case 'a' : if( wk[ pz - 1 ] == 0 ) { wk[ pz - 1 ] = 2 ; wk[ pz ] = 0 ; pz -= 1 ; map() ; } else { printf( "コマンド入力 : " ) ; } break ; case 'd' : if( wk[ pz + 1 ] == 0 ) { wk[ pz + 1 ] = 2 ; wk[ pz ] = 0 ; pz += 1 ; map() ; } else { printf( "コマンド入力 : " ) ; } break ; case 'j' : if( wk[ pz + 2 ] == 0 ) { wk[ pz + 2 ] = 4 ; wk[ pz ] = 0 ; pz += 2 ; map() ; } else { printf( "コマンド入力 : " ) ; } break ; case 'e' : printf( "GAME OVER\n" ) ; flg = 0 ; break ; } } } void map() { int i ; map1() ; for( i = 0 ; i < MAP_X * LOL ; i++ ) { if( ( i / MAP_X ) == a ) { printf( "\n" ) ; a++ ; } switch( ws[ i ] ) { case 1 : printf( "■" ) ; break ; case 2 : printf( "※" ) ; break ; case 3 : printf( "宝" ) ; break ; case 4 : printf( "☆" ) ; break ; case 5 : printf( "" ) ; break ; default : printf( " " ) ; break ; } } a = 1 ; printf( "\n" ) ; printf( "コマンド入力 : " ) ; } void map1() { int i ; for ( i = 0 ; i < (LOL * MAP_X) ; i++ ) { ws[i] = wk[i + (MAP_X * 19 ) ] ; } } void cm() { scanf( "%s" , &com ) ; }

  • C言語による画像処理で出力時に文字化け

    http://image.onishi-lab.jp/002.html#1 ここを参考にsobelオペレータによるエッジ検出をしようとしています。 fxとfyのところを考えるのですが、とりあえず1にして出力したら文字化けしました。 文字化けの原因を教えてください。 読み込む画像は横160ピクセル、縦70ピクセルのP2形式のpgmファイルです。 #include <stdio.h> #include <stdlib.h> int pgm_read(char *filename, unsigned char *pimage){ FILE *fp; if((fp=fopen(filename,"rb"))==NULL){ printf("ファイル%sが開けません\n",filename); exit(-1); } fscanf(fp,"P2\n160 70\n255\n"); //ヘッダを読み飛ばす fread(pimage,sizeof(char),160*70,fp); fclose(fp); return 0; } int pgm_write(char *filename, unsigned char *pimage){ FILE *fp; fp=fopen(filename,"wb"); fprintf(fp,"P2\n160 70\n255\n"); fwrite(pimage,sizeof(char),160*70,fp); fclose(fp); return 0; } main(){ unsigned char *image; //取り込む画像 unsigned char *edge; //エッジ画像 int x,y; int fx,fy; //オペレータグラジエントの強度 FILE *fp; image = malloc(sizeof(char)*160*70); //メモリの確保 edge = malloc(sizeof(char)*160*70); pgm_read("input.pgm", image); //ファイルの読み込み for(y=1;y<70-1;y++){ //Sobel オペレータ for(x=1;x<160-1;x++){ fx = 1;// ここを考える fy = 1;// ここを考える if(fx*fx+fy*fy>500) *(edge+160*y+x) = 0x00; //閾値より大きいところは黒 else *(edge+160*y+x) = 0xff; //それ以外は白 } } pgm_write("output.pgm", edge); //ファイルの書き込み free(image); //メモリの開放 free(edge); } 文字化けの様子は P2 160 70 255 ^@^@^@^@^@^@^@^@・・・ ^@\377\377\377・・・ みたいな感じです。

  • 世界一周について

    現在RPGのマップを表示するプログラムを作成しているのですが 世界一周が出来ません LINE_Xの最大の長さが30,LINE_Yの最大の長さが25として 画面に表示する範囲はx(横)が20,y(縦)が15です。 キャラを画面の中心に表示し、キー入力された方向の逆にマップを 移動させていくことでキャラが入力された方向に移動する方法です。 お聞きしたいのは、マップのLINE_Xの最大値やLINE_Yの最大値に近づいたときに歩いている方向の先にマップのLINE_XやLINE_Yの最小値から移動した分を表示する記述方法です。 聞きたいことをうまく記述できなくて申し分けないのですがよろしくお願いしますm(_ _)m また、おかしな記述があったら注意・改善等よろしくおねがいします 例) LINE_X=30(横),LINE_Y=25(縦)で x = 20,y = 9としたとき 右に5歩移動したときに表示されているマップが 横が11~30,縦が1~15 の範囲としたとき y=0まで移動したとき上半分にLINE_Yの移動した分の(25-移動距離)~25を表示したい (ドラクエみたいにマップの端まで言ったらマップの反対を表示してエンドレスにマップ表示が終わらない) ソース> #include "DxLib.h" int WINAPI WinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTR lpCmdLine,int nCmdShow){ ChangeWindowMode(true); if( DxLib_Init() == -1)return -1; int i,j; int x,y,chx,chy,ax,ay; int UD,LR,wf,muki,chd,chd2,houkou,gi,flg; int keyL,keyR,keyU,keyD; int map[25][30],ch[12],fi,white; char key[256]; LoadDivGraph("char.bmp",12,3,4,32,32,ch); fi = LoadGraph("ftest.bmp"); ↑読み込んでいるのは自作画像です↓ white = LoadGraph("画像\\white.bmp"); SetDrawScreen(DX_SCREEN_BACK); ClearDrawScreen(); for(i=0;i<25;i++){ for(j=0;j<30;j++){ map[i][j] = 0; if(i==0||j==0||i==24||j==29) map[i][j] = 1; } } flg = chd2 = houkou = UD = LR = wf = 0; muki = chy = chx = 0; chd = 1; x = 640 / 2; y = (480 / 2) - 16; chx = (x / 32); chy = (y / 32); while(1){ GetHitKeyStateAll(key); ax = ay = 0; for(i=UD;i<25+UD;i++){ for(j=LR;j<30+LR;j++){ if((i<0 || j<0) || (i>24 || j>29)){ DrawGraph(ax,ay,white,false); }else DrawGraph(ax,ay,fi,false); ax += 32; } ax = 0; ay +=32; } if(x%32==0 && y%32==0){ wf = 1; keyU = keyD = keyL = keyR = 0; houkou = muki; if(key[ KEY_INPUT_UP] == 1){ muki = 0; keyU = 1; }else if(key[KEY_INPUT_RIGHT] == 1){ muki = 1; keyR = 1; }else if(key[ KEY_INPUT_DOWN] == 1){ muki = 2; keyD = 1; }else if(key[KEY_INPUT_LEFT] == 1){ muki = 3; keyL = 1; }else wf = 0; } if((keyU + keyD + keyL + keyR )!= 0){ chx = (x / 32); chy = (y / 32); if(keyU == 1){ if(map[(chy+UD)-1][chx+LR] != 0)UD -= 1; }else if(keyD == 1){ if(map[(chy+UD)+1][chx+LR] != 0)UD += 1; }else if(keyL == 1){ if(map[chy+UD][(chx+LR)-1] != 0)LR -= 1; }else if(keyR == 1){ if(map[chy+UD][(chx+LR)+1] != 0)LR += 1; } } if(wf==1){ if(muki == houkou){ if(chd == 1){ gi = ch[(muki*3) + chd]; if(chd2 == 0){ chd++; }else if(chd2 == 2){ chd--; } }else if(chd == 2){ gi = ch[(muki*3) + chd]; chd--; chd2 = 2; }else if(chd == 0){ gi = ch[(muki*3) + chd]; chd++; chd2 = 0; } } }else if(wf == 0){ if(chd == 1 && flg == 0){ gi = ch[(muki*3) + chd]; if(chd2 == 0){ chd++; }else if(chd2 == 2){ chd--; } flg = 1; }else if(chd == 2 && flg == 0){ gi = ch[(muki*3) + chd]; chd--; chd2 = 2; flg = 1; }else if(chd == 0 && flg == 0){ gi = ch[(muki*3) + chd]; chd++; chd2 = 0; flg = 1; }else if(flg == 1)flg = 0; } if(key[KEY_INPUT_ESCAPE] == 1)break; if(ProcessMessage() == -1)break; Sleep(100); DrawGraph(x,y,gi,true); ScreenFlip(); } DxLib_End(); return 0; } 上記のソースでは移動方向の先から反対側のエリアは出てきません 表示した範囲内でのみ移動可能になっていて端の0は移動エリアの限定と終端の確認のためです 参考サイトはhttp://l.huu.cc/g/#0です DxLib.hもここのリンクからDLしました

  • c 言語 B tree

    C言語で B-treeを実装するプログラムを書きました。 まだtreeに挿入する関数しか書いておりませんが。。 まず空の根を作ってからそこにどんどん要素を挿入していくのですが、どうも要素が 挿入されていないように思えます。 どこがいけないのか分かる方いらっしゃいませんか? よろしくお願いします。 #include <stdio.h> #define T 10 struct b_tree{ int key[2*T-1]; struct b_tree *node[2*T]; int size; int leaf;//この節点が葉であったら1とする }; void BTreeCreate(void); void BTreeSplitChild(struct b_tree x,int i,struct b_tree y); void BTreeInsert(struct b_tree t,int k); void BTreeInsertNonfull(struct b_tree x,int k); void PrintBtree(struct b_tree x); struct b_tree root; int main (int argc, const char * argv[]) { // insert code here... /*int t;*/ char command; int key; BTreeCreate(); /*scanf("%d",&t);*/ while (1) { scanf("%c %d",&command,&key); if (command=='E') break; if(command=='I') BTreeInsert(root,key);//木にkeyを挿入 } PrintBtree(root); //木を表示 return 0; } void BTreeCreate(void){//空のB-木の生成 struct b_tree x; x.leaf=1; x.size=0; root=x; } void BTreeSplitChild(struct b_tree x,int i,struct b_tree y){ /*B-木における節点の分割をする節点xのi番目の枝の先にある節点yが飽和であった 場合にyをyの中央値で分ける。yの中央値はxの新たなkeyとなりxの枝数は1つ増える*/ int j; struct b_tree z; z.leaf=y.leaf; //zが葉であるかどうかはyが葉であるかどうかに依る z.size=T-1; //また新しくできるxの子zは最小数のkey(T-1)を持たせる for (j=1; j<= T-1; j++) { z.key[j]=y.key[j+1]; //yの中央値よりおおきい値(T-1個)をzに渡す } if(y.leaf==0){ //またyが個をもつ場合は枝もzに渡す for (j=1; j<=T; j++) z.node[j]=y.node[T+j]; } y.size=T-1; //そしてyのサイズも中央値とzに渡した分小さくなる for (j= x.size+1; j>=i+1; j--) { //xにyの中央値を渡すのでx枝の右半分を1つずつ右へずらす x.node[j+1]=x.node[j]; } x.node[i+1]=&z; //i+1番目の枝に新たな子zのポインタを与える for (j=x.size; j>=i; j--) { //値も右へずらす x.key[j+1]=x.key[j]; } x.key[i]=y.key[T]; //xのi番目の値をyの中央値とする。 x.size=x.size+1; //xは1サイズup } void BTreeInsert(struct b_tree t,int k){ int Tsub=T; //条件部にTが使えなかったのでTsubに退避 struct b_tree r,s; r=t; if (r.size == Tsub) { /*根が飽和だった場合を考える新たな親を必要とするため それをsとする。するとsは葉ではなく、sizeは0, そして元々の根rのポインタを与える*/ s.leaf=0; s.size=0; s.node[1]=&r; root=s; BTreeSplitChild(s,1,r); BTreeInsertNonfull(r,k); } else { BTreeInsertNonfull(r,k); } } void BTreeInsertNonfull(struct b_tree x,int k){ /*未飽和の節点xにkを挿入しようと考える。*/ int i; int Tsub=T; if (x.leaf==1) { /*もし、xが葉であれば大小関係を考えて挿入。その際他のkey を右へ1つずつずらす。またxのサイズを1up*/ while (i>=1 && k<x.key[i]) { x.key[i+1]=x.key[i]; i--; } x.key[i+1]=k; x.size++; } else { /*もしxが葉でなければどこの枝をたどればいいのか考える*/ while (i>=1 && k<x.key[i]) { i--; } i++; if ((*x.node[i]).size == 2*Tsub-1) { /*たどる枝の先が飽和であった場合分割する*/ BTreeSplitChild(x, i, *x.node[i]); if (k > x.key[i]) { i++; } } BTreeInsertNonfull(*x.node[i],k);//枝をたどる } } void PrintBtree(struct b_tree x){ printf("abc"); printf("%d",x.leaf);//実行するとleafが1のままなので、数が挿入されていない? int i,l;        if(x.leaf==1){ for (i=1; i<=x.size; i++) { printf("%d def",x.key[i]); } if(l==0)printf("\n"); }else { for (i=1; i<=x.size; i++) { printf("%d ghi",x.key[i]); } if(l==0)printf("\n"); l++; printf(" jkl"); for (i=1; i <= x.size+1; i++) { PrintBtree(*x.node[i]); } } printf("\n"); }

  • パックマンゲーム 敵の動きについて c言語

    現在 簡単なパックマンゲームを作成しています。 以下のプログラムだと、 ・敵が壁にあたると全く動かなくなる という問題点があります。なので、例えば、「動ける(壁でない)方向のうち、移動後の距離が一番自機に近い方向に移動する」というアルゴリズムにしようと思ったのですが、全くコードが思い浮かべません。 どんなコードをかけばいいでしょうか。 できればコードを具体的に教えていただきたいです。 お願いいたします。 #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 POWER_FOOD 4 //パワーエサ #define PACMAN 3// 主人公 #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 point = 0;     int kx, ky;//自機の座標を保存     int mx, my;//敵機の座標を保存     int life = 3;     // 壁 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,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },     };               cx = 7, cy = 7; //パックマンの初期位置     ex = 1, ey = 1;//敵の初期位置     //エサの個数を数える     for (y = 0; y < SIZE; y++)     {         for (x = 0; x < SIZE; x++)         {             if (field[y][x] == FOOD)                 food_count++;         }       }       while (1)     {         // まずはPACMANの動き           if (kbhit())         {             key = getch();//             kx = cx, ky = cy;//自機の座標を保存する             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;             }             if (cx == ex && cy == ey)                 life--;         } // 敵機の動き         mx = ex; my = ey;//敵機の座標を保存する           if (ex > cx)             ex--;         else if (ex < cx)             ex++;         else if (ey > cy)             ey--;         else if (ey < cy)             ey++;                 if (field[ey][ex] == WALL)  //もし敵機が壁に当たったらもとの座標に戻す。         {             ex = mx; ey = my;         }         ex = (ex + SIZE) % SIZE; //ワープ           if (cx == ex && cy == ey) {             life--;             ex = 7, ey = 7;             Sleep(wait_time);         } //画面表示 for (y = 0; y < SIZE; y++) {             for (x = 0; x < SIZE; x++) {                 if (x == cx && y == cy)                     printf("C ");                 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");         }         printf("\n");         printf(" (cx,cy) = (%d, %d)\n", cx, cy);         printf(" point: %d\n", point);         printf("  LIFE: %d\n", life);           if (life == 0)         {             printf("game over\n");                       Sleep(wait_time);             break;         }           if (food_count == 0)             {             printf("game crer\n");             Sleep(wait_time);             break;           }         Sleep(wait_time);//