• ベストアンサー

[Windows][C] ゲームプログラムが実行途中に止まってしまいます

いつもお世話になっております。 今アクションゲームの基盤となる簡単な動きをさせるプログラムを作成したのですが、なぜだか時間が経つと止まるという不思議な現象に陥っています。 プログラムの内容はジャンプや移動をするだけの単純なもので、描画やキャラの移動はスレッドで個別に行っています。 キャラが止まったとき、FPSは動いていたので、描画の方のスレッドにたぶん問題はないと思っています。 キャラが止まると同時にゲーム自体もおかしくなってしまうのですが、それはキャラ動作のスレッドが異常によって止まってしまったからなのでしょうか? 解決法のわかる方、すみませんがご指導お願いいたします。 以下に問題のあると思われるスレッドを貼ります。 描画やプロシージャに問題があると思われる方がいましたら補足で追加いたします。 /*************** キャラクターを動かす ****************/ DWORD WINAPI CharacterMove(LPVOID vdParam) {  HDC hdc;  RECT rect;  ThreadParam * param;  HRGN hit = CreateRectRgn(0, 0, 0, 0);  int JUMP = 0;  int DBJUMP = 0;  int position = 0;  int flag = 0;  param = (ThreadParam *)vdParam;  GetClientRect(param->owner, &rect);  while(TRUE){   /* 左移動 */   if(character.x > rect.left + 5){    if(GetAsyncKeyState(37)){     if(CombineRgn(           hit,           CreateEllipticRgn(character.x - 12, character.y, character.x - 12 + 25, character.y + 25),           S_RGN, RGN_AND) == NULLREGION){      character.x -= 12;     }    }   }   /* 右移動 */   if(character.x + 25 < rect.right - 5){    if(GetAsyncKeyState(39)){     if(CombineRgn(           hit,           CreateEllipticRgn(character.x + 12, character.y, character.x + 12 + 25, character.y + 25),           S_RGN, RGN_AND) == NULLREGION){      character.x += 12;     }    }   }   /*** ジャンプ ***/   if(CombineRgn(         hit,         CreateEllipticRgn(character.x, character.y + 1, character.x + 25, character.y + 1 + 25),         S_RGN, RGN_AND) != NULLREGION){    if(GetAsyncKeyState(38)){     JUMP = 32;    }   }   /***** ジャンプ時・落下時 *****/   if(CombineRgn(         hit,         CreateEllipticRgn(character.x, character.y + 1, character.x + 25, character.y + 1 + 25),         S_RGN, RGN_AND) == NULLREGION || JUMP == 32){    /*** 一度キーを離さないと2段ジャンプは成立しない ***/    if(!GetAsyncKeyState(38)){     flag = 1;    }    /*** 2段ジャンプ ***/    if(GetAsyncKeyState(38) && flag == 1 && DBJUMP < 1){     JUMP = 26;     DBJUMP++;    }    /*** 慣性 ***/    if(CombineRgn(          hit,          CreateEllipticRgn(character.x, character.y - JUMP, character.x + 25, character.y - JUMP + 25),          S_RGN, RGN_AND) != NULLREGION){     flag = 0;     DBJUMP = 0;     if(JUMP < 0){      while(CombineRgn(             hit,             CreateEllipticRgn(character.x, character.y + 1, character.x + 25, character.y + 1 + 25),             S_RGN, RGN_AND) == NULLREGION){       character.y++;      }     }else{      while(CombineRgn(             hit,             CreateEllipticRgn(character.x, character.y -1, character.x + 25, character.y + 1 + 25),             S_RGN, RGN_AND) == NULLREGION){       character.y--;      }     }     JUMP = 0;    }else{     character.y -= JUMP;    }    /* 最大落下速度 */    if(JUMP > -20){     JUMP -= 3;    }   }   Sleep(16);  }  DeleteObject(hit);  ReleaseDC(param->owner, hdc);  return TRUE; }

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

  • ベストアンサー
回答No.1

 こんにちは。  リソースリークしているからではないでしょうか・・・。  一箇所だけではなく、沢山有ります。 if(CombineRgn(hit,        CreateEllipticRgn(character.x - 12, character.y, character.x - 12 + 25, character.y + 25),//ココ        S_RGN, RGN_AND) == NULLREGION) { character.x -= 12; } ↓--------------------------------------------------------------------------------------------------------- //後始末しないといけません。 HRGN hRgn = CreateEllipticRgn(character.x - 12, character.y, character.x - 12 + 25, character.y + 25); if(CombineRgn(hit, hRgn,S_RGN, RGN_AND) == NULLREGION) { character.x -= 12; } ::DeleteObject(hRgn);

smily_k_c
質問者

お礼

あ、もしかしてif文の判定条件で生成してるリージョンでしょうか? 条件文の中で作成してるので忘れてました・・・ ということは判定の前に作成して、それを判定後削除、という形を取らなければいけないのでしょうか?

smily_k_c
質問者

補足

お早いご回答ありがとうございます。 毎回上書きして最後にWM_DESTOROYメッセージが出た時にまとめてDeleteしているので大丈夫だと思います。 文字数の関係ですべてのプログラムが書けないので情報が少ないですね・・・すみません。 以下がプロシージャの記述です。 LRESULT CALLBACK WindowProc(  HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){  HDC hdc;  PAINTSTRUCT ps;  static ThreadParam param;  static HBITMAP hBitmap;  DWORD dwID;  RECT rect;  switch(uMsg){   case WM_DESTROY:    postQuitMessage(0);    DeleteObject(S_RGN);    DeleteObject(C_RGN);    DeleteDC(param.hScreenDC);    return 0;   case WM_CREATE:    param.size.cx = 1000;    param.size.cy = 600;    param.owner = hWnd;    param.dwFps = 60;    hdc = GetDC(hWnd);    hBitmap = CreateCompatibleBitmap(hdc, param.size.cx, param.size.cy);    param.hScreenDC = CreateCompatibleDC(hdc);    SelectObject(param.hScreenDC, hBitmap);    SelectObject(param.hScreenDC, GetStockObject(WHITE_PEN));    SelectObject(param.hScreenDC, GetStockObjec(WHITE_BRUSH));    SelectObject(param.hScreenDC, GetStockObjec(SYSTEM_FONT));    SetTextColor(param.hScreenDC, RGB(0, 0, 0));    SetBkMode(param.hScreenDC, TRANSPARENT);    ReleaseDC(hWnd,hdc);    CreateThread(NULL, 0, PICTURE_FUNC, (LPVOID)¶m, 0, &dwID);    CreateThread(NULL, 0, CharacterMove, (LPVOID)¶m, 0, &dwID);    return 0;   }  return DefWindowProc(hWnd, uMsg, wParam, lParam); }

その他の回答 (1)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★アドバイス >あ、もしかしてif文の判定条件で生成してるリージョンでしょうか?  ↑  はい。その通りです。 >ということは判定の前に作成して、それを判定後削除、という形を取らなければいけないのでしょうか?  ↑  はい。その通りです。 ・回答者 No.1 さんのアドバイスが最も適切な回答となります。  できれば CreateEllipticRgn 関数でも戻り値でエラーをチェックすべきです。  めったにエラーが起こらないとは思いますが、CombineRgn でエラーチェックしているなら  一緒にエラーチェックした方が好ましいです。念のために。  また、エラーで CombineRgn の hit が作られなかったときを考えて  当たり判定なども修正する必要があると思います。 ・またスレッドの終了条件が見つかりませんが大丈夫でしょうか。  『while(TRUE)』のため次の2行は処理されない気がします。 >DeleteObject(hit); >ReleaseDC(param->owner, hdc);  ↑  文字数の関係で記述を省略しているなら良いですが。  どうなんでしょうか?

smily_k_c
質問者

お礼

ネットにつなげられなかったためにお礼が大分遅くなってしまいました、すみません。 おかげ様で解決することができました。 while(TRUE)は条件を一時ループにしているだけなので問題ないです。

関連する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*/"■                                      ■", /*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; }

  • processingのプログラムの書き方について。

    課題で、どこからマウスをプレスしても20個もの四角を(0,0)まで数珠つなぎみたいにするプログラムをかいているんですが全然わかりません。 そのため大きさなどは瞬時に計算をするからmouse x, mouse yをつかいます だからrect(mouseX,mouseY,mouseX,mouseY)になると思うんですが。。 とにかく全部わかりません。教えてください。 自分が書いたのはこんなのですが、全然違います。 forループ、mouseX, mouseYを使うのはわかります int s = 600; int n = 20; int i = mouseX; void setup() { size(s,s); background(255); noStroke(); rectMode(CENTER); } void draw() { if(mousePressed) { for(int i=0; i<s; i++); { fill(255,0,0); rect(mouseX,mouseY,mouseX,mouseY); } } }

  • 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)); } としてみましたがやはりだめでした。 前のページの説明を読み返したりネットで調べてもわかりませんでした。 何がわからないのかがわからないのでもうお手上げです。 長くなってすいません プログラム例と説明をお願いします。

  • H8 3052 のプログラムで、少数のべき乗計算

    H8 3052 のプログラムで、少数のべき乗計算がしたいです。 y=4610.6x^(-1.156) という計算を入れたいです。 H8 3052 ヘッダファイル 3052f.h stdio.h math.h メイン関数で 1 x2=ad1_val; 2 y2=4610.6*pow(x2,-1.156); 3 if(y2>20){s2_flag = CW;} 4 if(y2<20){s2_flag = CCW;} このプログラムだと動作しません。 1 x2=ad1_val; 2 y2=x2/2; 3 if(y2>150){s2_flag = CW;} 4 if(y2<150){s2_flag = CCW;} このプログラムだと動作しました。 2行目のpowの式のせいで動作エラーするみたいなんですけど、 pow関数はH8 3052 では使えないのですか? それとも他に書き足すことがあるのですか? pow関数が使えないのなら他に方法はないですか? コンパイラは CC38H.exe です。 お願いします。

  • 色描画

    以下は、ウインドウプロシージャ内でのプログラムです。 RGB( )ですが、0xFFは、255の事ですよね? x*0xFF/rect.rightこの計算式は、何を求めているんですか? 教えてください。 HDC         hdc; PAINTSTRUCT  ps; COLORREF    color; LONG        x,y; RECT        rect; switch(umsg){   case  WM_PAINT:       hdc =BeginPaint(hwnd,&ps);       GetClientRect(hwnd,&rect);       for(y=0;y<rect.bottom;y++){          for(x=0;x<rect.right;x++){            color=RGB(x*0xFF/rect.right,0,0);            SetPixel(hdc,x,y,color);          }       }

  • 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); }

  • 迷路を解くプログラムについて

    迷路を脱出する経路を探索するプログラムを作成したいのですが、 何をすればいいのかまったくわかりません 以下のプログラムはあるんですが、このプログラムを改良していくということなんでしょうか?左上からスタートして右下がゴールらしいのですがやり方教えてください #include <stdlib.h> #include <stdio.h> #include "List.h" #define LEN 256 int maze[LEN][LEN]; void readMaze(char* filename, int *w, int *h, int maze[LEN][LEN]) { FILE *fp; int x, y; if (0 != fopen_s(&fp, filename, "r")) { fprintf(stderr, "指定された迷路の入力ファイルを開くことができませんでした.\n"); exit(-1); } fscanf_s(fp, "%d,%d\n", w, h); for (y = 0; y < 2 * *h + 1; y++) { for (x = 0; x < 2 * *w + 1; x++) { fscanf_s(fp, "%d%*[^-0-9]", &(maze[y][x])); } } fclose(fp); } void writeMaze(char* filename, int w, int h, int maze[LEN][LEN]) { FILE *fp; int x, y; if (0 != fopen_s(&fp, filename, "w")) { fprintf(stderr, "指定された迷路の出力ファイルを開くことができませんでした.\n"); exit(-1); } fprintf_s(fp, "%d,%d\n", w, h); for (y = 0; y < 2 * h + 1; y++) { for (x = 0; x < 2 * w + 1; x++) { fprintf_s(fp, "%d", maze[y][x]); if (x < 2 * w) { fprintf_s(fp, ","); } else { fprintf_s(fp, "\n"); } } } fclose(fp); } // シンプルなバージョン:なるべく右下へ行けるなら右下へ int main(int argc, char** argv) { int w, h; int x, y; if (argc < 3) { fprintf(stderr, "迷路の入出力ファイル名を指定してください.\n"); exit(-1); } // 迷路読込 readMaze(argv[1], &w, &h, maze); // maze[1][1] から maze[2*h-1][2*w-1] までのルートを探す x = 1; //座標の初期化 y = 1; while (x != 2 * w - 1 || y != 2 * h - 1){ if (maze[y][x + 1] == 0) { // 右にまだ行ってない? maze[y][x] = 1000; x = x + 1; } else if (maze[y + 1][x] == 0) { // 下にまだ行ってない? maze[y][x] = 1000; y = y + 1; } else if (maze[y][x - 1] == 0) { // 左にまだ行ってない? maze[y][x] = 1000; x = x - 1; } else if (maze[y - 1][x] == 0) { // 上にまだ行ってない? maze[y][x] = 1000; y = y - 1; } else if (maze[y][x + 1] == 1000) { // 行き止まりなので右に引き返す maze[y][x] = 1; x = x + 1; } else if (maze[y + 1][x] == 1000) { // 行き止まりなので下に引き返す maze[y][x] = 1; y = y + 1; } else if (maze[y][x - 1] == 1000) { // 行き止まりなので左に引き返す maze[y][x] = 1; x = x - 1; } else if (maze[y - 1][x] == 1000) { // 行き止まりなので上に引き返す maze[y][x] = 1; y = y - 1; } } maze[2 * h - 1][2 * w - 1] = 1000; // ゴール // 答えを濃い色に // 上記のプログラムはすでに答えを濃い色(1000)にしている // 迷路書出 writeMaze(argv[2], w, h, maze); return 0; }

  • C言語によるハノイの塔のプログラムの実行の流れ

    解きながら学ぶC言語の問題8-9のハノイの塔のプログラムについです。ソースコードは #include<stdio.h> #define N 3 void move(int no,int x,int y) { if(no>1) move(no-1,x,6-x-y); printf("%dを%d軸から%d軸へ移動\n",no,x,y); if(no>1) move(no-1,6-x-y,y); } int main(void) { move(N,1,3); return 0; } ============================== 実行結果 1を1軸から3軸へ移動 2を1軸から2軸へ移動 1を3軸から2軸へ移動 3を1軸から3軸へ移動 1を2軸から1軸へ移動 2を2軸から3軸へ移動 1を1軸から3軸へ移動 ============================== 最近大学の講義でこのプログラムの実行の流れを習ったのですが、どうにもよく理解することができません。 まず、move(no,x,y)にはそれぞれno=3,x=1,y=3の数が入っていますよね。 そして、no>1なので、move(no-1,6-x-y,y)の式に代入してmove(3-1,1,6-1-3)となるとno=2,x=1,y=2となるのでmove(2-1,1,6-1-2)となるのでこのときno=1,x=1,y=3。 この時点でno>1ではなくなりprintf関数によって、1を1軸から3軸へ移動、2を1軸から2軸へ移動と表示されると言うことだと思っているのですが。 ここから先がさっぱりです、なぜ1を3軸から2軸へ移動となるのでしょうか? 一つもどってno=2,x=1,y=2のときmove(no-1,6-x-y,y)の式に代入されるということなのでしょうか? どうして急にmove(no-1,x,6-x-y)の式で計算していたものがmove(no-1,6-x-y,y)の式で計算するようになるのか、がわかりません。 どちらも条件分岐はif(no>1)ですし、このif文が何のためにあるのかもよくわからないのです。 自分でも書いていて要点がはっきりしませんが、どなたかお願いいたします。

  • プログラムのスレッド化について。

    以下の処理をスレッド化しようとしています。 public class FCP{ int N=10 long LOOP_MAX=100 double x[][] = new double[N][4] int g[][] = new int[N][4] boolean y[][] = new boolean[N][4]//出力 boolean A[][] = new boolean[N][10] double T=0.5 Set_Adjacent_Matrix() //A配列にtrueとfalseを代入 Set_initial_value() //y配列に初期値を代入(Math.random()>0.5) g1(int i, int j) //k<4 sum=1 if( y[i][k] == true ) --sum return(double)sum g2(int i, int j) //k<N sum=0 if( y[i][j] == true ) if( y[k][j] == true && A[i][k] == true ) --sum return(double)sum Display_output() //結果表示 if( y[i][j] ) System.out.print("0") else System.out.print(".") public static void main(String args[]) { long loop; int i, j, k; Set_Adjacent_Matrix(); Set_initial_value(); for( loop=0; loop<LOOP_MAX; loop++ ){ for( i=0; i<N; i++ ){ for( j=0; j<4; j++ ){ x[i][j] = g1( i, j ) + g2( i, j ); if( y[i][j] ){ x[i][j] += T; }else{ x[i][j] -= T; } if( x[i][j] > 0.0){ y[i][j] = true; }else{ y[i][j] = false; } } } Display_output(); } } 今回Threadクラスの継承を使ってスレッド化しようと考えました。runメソッドには上のプログラムのmain部分の処理をさせようと思っています。そしてstartメソッドで必要な数(Nの値=10コ)のスレッドを生成しrunメソッドを実行する。 と、ここまではわかったのですが、「生成された各スレッドの番号を保持し、そのスレッドに担当させる処理を決める」という部分をどうすればいいのかわかりません。 「i(1~10)番目のスレッドはN(1~10)列目の処理を担当している」という風にするにはどうしたらいいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • C言語に関する質問

    初期位置を1mとして、ある物体の自由落下をシミュレートするプログラムを 「高さ=1-1/2×重力加速度×経過時間の二乗」 という考え方を 「初期位置を1m,落下速度を「重力加速度×1ループにかかる時間」とし, 高さを,「1ループ前の高さ」+「落下速度×1ループにかかる時間」」という考え方に変更して計算するようなプログラムにしたいのですが、どのように変えれば分かりません。(というか意味が分からないです) 何か公式などのヒントやソースコードより、どの部分をこのように変えれば良いという指摘があれば分かりやすく教えてください。 #include <windows.h> #include <mmsystem.h> #include <stdio.h> #include <conio.h> #pragma comment(lib, "winmm.lib") int main(void) { int command;//キーボード入力の文字判別用変数 int quit_flag = 1;//プログラム終了フラグ 0で停止 int c_flag = 0;//カウント状態取得用フラグ 1:カウント中,0:停止中 int h,m,s,ms;//左から,時間,分,秒,ミリ秒 double y=1; DWORD start; printf("使い方:小文字の's'でカウントスタート.カウント中,小文字の's'で停止.次の's'でまた0からスタート\n"); printf("使い方:どんな状態でも小文字の'r'でカウントリセットして停止\n"); printf("使い方:qでプログラム終了\n\n"); h=m=s=ms=0; while(quit_flag != 0)//quit_flagが0以外ならループ { while(!_kbhit())//何かキーが押されるまでループ { if(c_flag != 0)//c_flagが0以外であればカウント中ということ. { h=m=s=ms = timeGetTime() - start; y=1-(1.0/2.0)*(9.8/1000000)*ms*ms; printf("t=%d[ms],y=%f[m]\r",ms,y); //printf("t=%02d:%02d:%02d:%03d,y=%f[m]\r",h/3600000,(m/60000)%60,(s/1000)%60,ms%1000,y); } //printf("%02d:%02d:%02d:%03d\r",h/3600000,(m/60000)%60,(s/1000)%60,ms%1000); if(c_flag==0){ printf("t=%d[ms],y=%f[m]\r",ms,y); //printf("t=%02d:%02d:%02d:%03d,y=%f[m]\r",h/3600000,(m/60000)%60,(s/1000)%60,ms%1000,y); } } command=_getch();//ループを抜けるために押されたキーの内容をcommandに代入. if(command=='s' && c_flag == 0) { printf("\n計測開始\n"); c_flag = 1; start = timeGetTime() ; h=m=s=ms=0; /* if(y==0){ printf("\n終了\n"); quit_flag = 0; } */ } else if(command=='s') { printf("\n計測中止\n"); c_flag = 0; } else if(command=='r') { printf("\nカウンタリセット,停止\n"); c_flag = 0; h=m=s=ms=0; } else if(command=='q') { printf("\n終了\n"); quit_flag = 0; } } return 0; }

専門家に質問してみよう