トップページ > 過去ログ > 記事閲覧
14歳〜noC言語ゲームプログラミング(2008)第三章にて
名前:タク 日時: 2009/01/18 04:55

ベクトルでキャラクターを走らせるという項目で

Page: 1 |

Re: 14歳〜noC言語ゲームプログラミング(2008)第 ( No.1 )
名前:タク 日時:2009/01/18 05:01

すみません途中でした・・ const Vector RIGHTMOVEC = { 120, 0 }; const Vector LEFTMOVEC = { -120, 0 }; という項目を追加すると エラー 1 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません エラー 2 error C2146: 構文エラー : ';' が、識別子 'RIGHTMOVEC' の前に必要です 等の100個近いエラーが出ました。 どうすれば解決できるでしょうか?
Re: 14歳〜noC言語ゲームプログラミング(2008)第三章にて ( No.2 )
名前:キーチック 日時:2009/01/18 05:41

プログラムを見ないとはっきりいえませんが,単に本を見ながら2行追加しただけで 100個近いエラーが出たというなら,おそらく,その前の行の;を 消してしまっていると思います. ;はC言語で区切りになるのですが,これを消してしまうと, 2行分を1行分としてしまうので,予想外のエラーが発生し,それが 変数の初期宣言あたりだと,その変数を利用する,それ以降のすべてに 「そんな変数ないよ…」的なエラーが出ることが 良くあります.
Re: 14歳〜noC言語ゲームプログラミング(2008)第 ( No.3 )
名前:タク 日時:2009/01/18 15:27

返信ありがとうございます。 いろいろ試したところ #include "mymain.h" #include "myhelper.h" を #include "myhelper.h" #include "mymain.h" のように書き直したらエラーが取れました。なぜだかわかりませんが。 インクルードの順番って関係あるんですかね?
Re: 14歳〜noC言語ゲームプログラミング(2008)第 ( No.4 )
名前:タク 日時:2009/01/18 15:33

/**mymain.cpp * @file mymain.cpp * @brief . * @author Taku * @date 2008/00/00 Ver 1.00 Written by Taku<br> */ //---- Include File ----------------------------------------------------------- #include "myhelper.h" //←☆此処を逆にするとエラーがでます。なぜですかね? #include "mymain.h" //---- Macro Declaration ------------------------------------------------------ //---- Global Variable Declaration -------------------------------------------- Point2D g_jikipos = { 40, 400 }; //自キャラの座標 int g_jikiimage[11]; //画像ハンドル //---- Constant Declaration --------------------------------------------------- //---- Prototype Declaration -------------------------------------------------- //---- Data Type Declaration -------------------------------------------------- //---- Function Declaration --------------------------------------------------- void MyMain(){ //変数curvec1の宣言 Vector curve1 = { 0, 0 }; //キー入力のチェック int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ); if( key & PAD_INPUT_LEFT ){ curve1 = AddVector( curve1, LEFTMOVEC ); } if( key & PAD_INPUT_RIGHT ){ curve1 = AddVector( curve1, RIGHTMOVEC ); } //自キャラの座標計算 g_jikipos = AddVectorInFrameTime( g_jikipos, curve1 ); //自キャラの描画 DrawAnimation( g_jikipos.x, g_jikipos.y, 1, 0, FALSE, &g_jikiimage[2], 6, 12 ); } //色々なファイルの読み込み int LoadFiles(){ //画像ファイルの読み込み if (LoadDivGraph("media\\player01.bmp", 11,11,1,64,64,g_jikiimage) == -1){ return -1; } return 1; }
Re: 14歳〜noC言語ゲームプログラミング(2008)第 ( No.5 )
名前:タク 日時:2009/01/18 15:34

#ifndef _MYMAIN_H_ #define _MYMAIN_H_ /** * @file mymain.h * @brief . * @author Taku * @date 2008/00/00 Ver 1.00 Written by Taku<br> */ //---- Include File ----------------------------------------------------------- //---- Macro Declaration ------------------------------------------------------ //---- Constant Declaration --------------------------------------------------- //---- Global Variable Declaration -------------------------------------------- //---- Prototype Declaration -------------------------------------------------- //---- Data Type Declaration -------------------------------------------------- //自キャラの移動に関するデータ const Vector RIGHTMOVEC = {120, 0}; const Vector LEFTMOVEC = {-120, 0}; //---- Function Declaration --------------------------------------------------- void MyMain(); int LoadFiles(); #endif
Re: 14歳〜noC言語ゲームプログラミング(2008)第 ( No.6 )
名前:タク 日時:2009/01/18 15:36

#include "DxLib.h" #include <limits.h> #include <math.h> //myhelper.hです //構造体宣言 //座標またはベクトルを記録する構造体 struct Vector{ float x,y; }; typedef Vector Point2D; //線を記録する構造体 struct Line2D{ Point2D startpos, endpos; float katamuki; //傾きをラジアン値で記録 Vector speed; //移動している場合は速度をセット }; //球体を記録する構造体 struct Ball2D{ Point2D position; float hankei; //半径 }; //四角形を記録する構造体 struct Rect2D{ Point2D lefttop; Point2D rightbottom; float width; float height; }; //ライブラリ関数 Point2D PosInView(Point2D in); int XInView(float inx); int YInView(float iny); void ScrollToLeft(float jikiposx); void ScrollToRight(float jikiposx); void ScrollToUp(float jikiposy); void ScrollToDown(float jikiposy); void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness); void DrawCircleInView(float x, float y, float r, int Color, int FillFlag); void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag, int *imgarray, int allframe, float fps); //ベクトル関数 Vector CreateVector(Vector in, float veclen); Vector AddVector(Vector v1, Vector v2); Vector SubVector(Vector v1, Vector v2); Vector AddVectorInFrameTime(Vector pos, Vector speed); Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel); Vector Normalize(Vector in); Vector RotateVector(Vector in, float radian); float VectorLengthSquare(Vector in); float DotProduct(Vector v1, Vector v2); float CrossProduct(Vector v1, Vector v2); void SetLine2DKatamuki(Line2D *in); void DrawLine2D(Line2D in, int Color, int Thickness); void DrawBall2D(Ball2D in, int Color, int Fill); //当たり判定関数 bool HitTestLineAndBall(Line2D linein, Ball2D ballin); bool IsPointAtLineFace(Line2D linein, Point2D ptin); bool HitTestLineAndLine(Line2D line1, Line2D line2); bool HitTestBallAndBall(Ball2D a, Ball2D b); bool HitTestPointAndBox(Rect2D rect, Point2D pt); //タイマー関数 void SetSimpleTimer(int idx, int time); int GetPassedTime(int idx); //グローバル変数 extern float g_frametime; extern Rect2D g_framerect; //画面領域(当たり判定) extern Point2D g_current_field_pos; //現在の左上座標 extern Rect2D g_stagesize; //ステージサイズ //定数宣言 const float ZEROVALUE = 1e-10f; const float PIE = 3.1415926f; const int SCROLL_LIMIT = 200;
Re: 14歳〜noC言語ゲームプログラミング(2008)第 ( No.7 )
名前:タク 日時:2009/01/18 15:37

#include "myhelper.h" #include "mymain.h" //myhelper.cppです //グローバル変数 int g_lasttime; //前回のループ終了時間(ミリ秒) float g_frametime = 0.017f; //1フレームの表示にかかった時間(秒) // プログラムの開始関数 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { if (strcmp(lpCmdLine, "-f") != 0) ChangeWindowMode(TRUE); //DXライブラリの初期化処理 if( DxLib_Init() == -1 ) return -1; //描画対象を裏画面に設定 SetDrawScreen(DX_SCREEN_BACK); //ファイルの読み込み if( LoadFiles() == -1 ) return -1; //画面サイズ(当たり判定用)の初期化 Rect2D gf = { {-64,-64}, {640+64,480+64}, 768, 608}; memcpy( &g_framerect, &gf, sizeof(Rect2D) ); //スクロール開始点の初期化 g_current_field_pos.x = 0; g_current_field_pos.y = 0; //ステージサイズの初期化 Rect2D gs = { {0,0}, {639,479}, 640,480} ; memcpy( &g_stagesize, &gs, sizeof(Rect2D) ); //メインループ g_lasttime = GetNowCount() & INT_MAX; while(ProcessMessage()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){ ClsDrawScreen(); //画面を消去 MyMain(); ScreenFlip(); //画面を切り替え //1ループにかかった時間を計測 int curtime = GetNowCount() & INT_MAX; g_frametime = (float)(curtime - g_lasttime) / 1000.0f; g_lasttime = curtime; if (g_frametime > 0.03f) g_frametime = 0.03f; } DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 } //スクロール用データ Rect2D g_framerect = { {-64,-64}, {640+64,480+64}, 768, 608}; //画面領域(当たり判定) Point2D g_current_field_pos = {0,0}; //現在の左上座標 Rect2D g_stagesize = { {0,0}, {639,479}, 640,480}; //ステージサイズ //スクロール用関数 //データ上の座標を画面表示用座標に変更する Point2D PosInView(Point2D in){ return SubVector(in, g_current_field_pos); } //そのX座標版とY座標版 int XInView(float inx){ return (int)(inx - g_current_field_pos.x); } int YInView(float iny){ return (int)(iny - g_current_field_pos.y); } /*画面を左へスクロール (自キャラから200ピクセルを保つようスクロール)*/ void ScrollToLeft(float jikiposx){ //スクロール可能かをチェック if ((int)jikiposx - SCROLL_LIMIT > (int)g_stagesize.lefttop.x){ g_current_field_pos.x = jikiposx - SCROLL_LIMIT; g_framerect.lefttop.x = g_current_field_pos.x - 64; g_framerect.lefttop.y = g_current_field_pos.y - 64; g_framerect.rightbottom.x = g_current_field_pos.x + 640 + 64; g_framerect.rightbottom.y = g_current_field_pos.y + 480 + 64; } } /*画面を右へスクロール (自キャラから200ピクセルを保つようスクロール)*/ void ScrollToRight(float jikiposx){ if ((int)jikiposx + SCROLL_LIMIT < (int)g_stagesize.rightbottom.x){ g_current_field_pos.x = jikiposx - (640 - SCROLL_LIMIT); g_framerect.lefttop.x = g_current_field_pos.x - 64; g_framerect.lefttop.y = g_current_field_pos.y - 64; g_framerect.rightbottom.x = g_current_field_pos.x + 640 + 64; g_framerect.rightbottom.y = g_current_field_pos.y + 480 + 64; } } /*画面を上へスクロール*/ void ScrollToUp(float jikiposy){ //スクロール可能かをチェック if ((int)jikiposy - SCROLL_LIMIT > (int)g_stagesize.lefttop.y){ g_current_field_pos.y = jikiposy - SCROLL_LIMIT; g_framerect.lefttop.x = g_current_field_pos.x - 64; g_framerect.lefttop.y = g_current_field_pos.y - 64; g_framerect.rightbottom.x = g_current_field_pos.x + 640 + 64; g_framerect.rightbottom.y = g_current_field_pos.y + 480 + 64; } } /*画面を下へスクロール*/ void ScrollToDown(float jikiposy){ if ((int)jikiposy + SCROLL_LIMIT < (int)g_stagesize.rightbottom.y){ g_current_field_pos.y = jikiposy - (480 - SCROLL_LIMIT); g_framerect.lefttop.x = g_current_field_pos.x - 64; g_framerect.lefttop.y = g_current_field_pos.y - 64; g_framerect.rightbottom.x = g_current_field_pos.x + 640 + 64; g_framerect.rightbottom.y = g_current_field_pos.y + 480 + 64; } } /*スクロールを計算に入れた描画関数*/ void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness){ DrawLine(XInView(x1), YInView(y1), XInView(x2), YInView(y2), Color, Thickness); } void DrawCircleInView(float x, float y, float r, int Color, int FillFlag){ DrawCircle(XInView(x), YInView(y), (int)r, Color, FillFlag); } /*アニメーション表示をする関数 画像を表示する座標xとy、 イメージデータの配列imgarray、総コマ数framenum、アニメの表示速度fps アニメーション用の一時データanimtmpを引数とする。 1枚絵を表示する場合は、 imgarrayにint型変数のアドレス、allframeに1、fpsに1.0fを指定すること。 */ void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag, int *imgarray, int allframe, float fps){ //現在の経過秒数を求める float t = (float)( GetNowCount() & INT_MAX ); //表示すべきコマ数を求める int animpat = (int)(t/(1000/fps)) % allframe; //そのコマを描画 DrawRotaGraph(XInView(x),YInView(y), ExtRate, Angle, imgarray[animpat], TRUE, TurnFlag); } /*ベクトルを作成する関数 入力ベクトルを正規化してから長さを掛ける*/ Vector CreateVector(Vector in, float veclen){ Vector result; in = Normalize(in); result.x = in.x * veclen; result.y = in.y * veclen; return result; } /*ベクトルの足し算を行う関数*/ Vector AddVector(Vector v1, Vector v2){ Vector result; result.x = v1.x + v2.x; result.y = v1.y + v2.y; return result; } /*ベクトルの引き算を行う関数 座標からベクトルを求める場合にも使える その場合v1は終点、v2は始点とする*/ Vector SubVector(Vector v1, Vector v2){ Vector result; result.x = v1.x - v2.x; result.y = v1.y - v2.y; return result; } /*座標に速度ベクトルを足す関数(等速運動用) g_frametimeを考慮する*/ Vector AddVectorInFrameTime(Vector pos, Vector speed){ Vector result; result.x = pos.x + speed.x * g_frametime; result.y = pos.y + speed.y * g_frametime; return result; } /*座標に速度ベクトルと加速度を足す関数(等加速度運動用) g_frametimeを考慮する*/ Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel){ Vector result; result.x = pos.x + speed.x * g_frametime + accel.x * pow(g_frametime,2) / 2; result.y = pos.y + speed.y * g_frametime + accel.y * pow(g_frametime,2) / 2; return result; } /*ベクトルを正規化する関数*/ Vector Normalize(Vector in){ Vector result; float l = sqrt( in.x * in.x + in.y * in.y ); result.x = in.x / l; result.y = in.y / l; return result; } /*内積を求める関数*/ float DotProduct(Vector v1, Vector v2){ return v1.x * v2.x + v1.y * v2.y; } /*外積を求める関数*/ float CrossProduct(Vector v1, Vector v2){ return v1.x * v2.y - v1.y * v2.x; } /*ベクトルを回転させる関数*/ Vector RotateVector(Vector in, float radian){ Vector result; result.x = -sin(radian)*in.y + cos(radian)*in.x; result.y = cos(radian)*in.y + sin(radian)*in.x; return result; } /*ベクトルの長さの二乗を求める関数 長さが必要なときはsqrtで平方根を求める*/ float VectorLengthSquare(Vector in){ return in.x * in.x + in.y * in.y; } /*Line2Dを描画する関数*/ void DrawLine2D(Line2D in, int Color, int Thickness){ DrawLine(XInView(in.startpos.x), YInView(in.startpos.y), XInView(in.endpos.x), YInView(in.endpos.y), Color, Thickness); } /*Ball2Dを描画する関数*/ void DrawBall2D(Ball2D in, int Color, int FillFlag){ DrawCircle(XInView(in.position.x), YInView(in.position.y), (int)in.hankei, Color, FillFlag); } /*線の傾きを求めてLine2Dのメンバkatamukiにセットする関数*/ void SetLine2DKatamuki(Line2D *in){ in->katamuki = atan2(in->endpos.y - in->startpos.y, in->endpos.x - in->startpos.x); } /*Ball2DとLine2Dの当たり判定を行う関数*/ bool HitTestLineAndBall(Line2D linein, Ball2D ballin){ Vector avec, bvec; avec = SubVector(ballin.position, linein.startpos); bvec = SubVector(linein.endpos, linein.startpos); float dot = DotProduct(avec, bvec); //内積を求める float bl = VectorLengthSquare(bvec); //ベクトルbの長さの二乗を求める if ( (dot > -ZEROVALUE) && (dot < bl) ) { //衝突の可能性有り //円と線の距離を求める //ボールの中心から垂直におろした線の交点を求める Vector bnvec = Normalize(bvec); //ベクトルbの正規化 float dot2 = DotProduct(avec, bnvec); bnvec.x *= dot2; bnvec.y *= dot2; Point2D kouten = AddVector(linein.startpos, bnvec); Vector dist = SubVector(ballin.position, kouten); float al = VectorLengthSquare(dist); #ifdef _DEBUG DrawBall2D(ballin, GetColor(128,128,128),FALSE); DrawLineInView(linein.startpos.x, linein.startpos.y, linein.startpos.x+avec.x, linein.startpos.y+avec.y, 65535,1); DrawLineInView(linein.startpos.x, linein.startpos.y, kouten.x, kouten.y, GetColor(255,0,0),1); DrawLineInView(kouten.x, kouten.y, ballin.position.x, ballin.position.y, GetColor(255,0,0),1); #endif if ( al < (ballin.hankei * ballin.hankei) ){ return TRUE; } } return FALSE; } /*頂点と線の位置関係を調べる関数 線の左または上側にあればTRUE、右または下側にあればFALSEを返す*/ bool IsPointAtLineFace(Line2D linein, Point2D ptin){ Vector avec, bvec; avec = SubVector(ptin, linein.startpos); bvec = SubVector(linein.endpos, linein.startpos); float cross = CrossProduct(avec, bvec); //外積が正なら点は線の表側(左側)にある if ( cross > -ZEROVALUE ) return TRUE; return FALSE; } /*Line2D同士の当たり判定を行う関数*/ bool HitTestLineAndLine(Line2D line1, Line2D line2){ Vector avec, bvec, cvec, dvec, evec, fvec; avec = SubVector(line1.endpos, line1.startpos); //a2-a1 bvec = SubVector(line2.startpos, line1.startpos); //b1-a1 cvec = SubVector(line2.endpos, line1.startpos); //b2-a1 dvec = SubVector(line2.endpos, line2.startpos); //b2-b1 evec = SubVector(line1.startpos, line2.startpos); //a1-b1 fvec = SubVector(line1.endpos, line2.startpos); //a2-b1 float a,b,c,d; a = CrossProduct(avec, bvec); b = CrossProduct(avec, cvec); c = CrossProduct(dvec, evec); d = CrossProduct(dvec, fvec); if( ((a*b) < ZEROVALUE) && ((c*d) < ZEROVALUE) ){ return TRUE; } return FALSE; } /*Ball2D同士の当たり判定を行う関数*/ bool HitTestBallAndBall(Ball2D ball1, Ball2D ball2){ #ifdef _DEBUG DrawBall2D(ball1, GetColor(128,128,128),FALSE); DrawBall2D(ball2, GetColor(128,128,128),FALSE); #endif if ( pow(ball1.position.x - ball2.position.x, 2) + pow(ball1.position.y - ball2.position.y,2) < pow(ball1.hankei+ball2.hankei, 2) ){ return TRUE; }else{ return FALSE; } } /*Point2DとRect2Dの当たり判定を行う関数*/ bool HitTestPointAndBox(Rect2D rect, Point2D pt){ if ( (rect.lefttop.x < pt.x) && (pt.x < rect.rightbottom.x) && (rect.lefttop.y < pt.y) && (pt.y < rect.rightbottom.y) ){ return TRUE; } return FALSE; } //シンプルタイマー関数 const int MAXTIMER = 32; int g_goaltimes[MAXTIMER]; /*タイマーに目標値を設定して始動させる関数 目標値timeはミリ秒で設定する*/ void SetSimpleTimer(int idx, int time){ if(idx>MAXTIMER) return; g_goaltimes[idx] = (GetNowCount() & INT_MAX) + time; } /*タイマーの結果を取得する関数 返値が負ならまだ目標値に達していない 正なら目標値を超えている*/ int GetPassedTime(int idx){ return (GetNowCount() & INT_MAX) - g_goaltimes[idx]; }
Re: 14歳〜noC言語ゲームプログラミング(2008)第 ( No.8 )
名前:タク 日時:2009/01/18 15:40

これがプログラムです。 上から mymain.cpp(自分で書いた) mymain.h(自分で書いた) myhelper.h(本についてたソース) myhelper.cpp(本についてたソース)
Re: 14歳〜noC言語ゲームプログラミング(2008)第三章にて ( No.9 )
名前:管理人 日時:2009/01/19 01:05

今回貼り付けて頂いた例だと関係があります まず今回挙げて頂いたエラーは コンパイラ「Vector って何?こんな識別子知らないよ」 というものです 何故か、というと Vector 構造体は myhelper.h で定義されているからです なので、myhelper.h → mymain.h の順でインクルードすると Vector 構造体の 定義をした後で const Vector RIGHTMOVEC = {120,0}; の定義が行われるので 問題がありませんが、逆の mymain.h → myhelper.h の順でインクルードしてしまうと Vector 構造体の定義がされないまま mymain.h で Vector 構造体を使用した 定数定義文にきてしまうのでエラーが発生する、というわけです
Re: 14歳〜noC言語ゲームプログラミング(2008)第 ( No.10 )
名前:タク 日時:2009/01/19 19:22

自分のプログラムのままだと定義してない状態だったんですね。 #includeの順番もちゃんと考えないといけないんですね。 丁寧に教えていただきありがとうございました!

Page: 1 |