トップページ > 記事閲覧
箱同士が戦う3Dゲーム
名前:karumera0225 日時: 2018/07/25 18:57

こんにちは、こちらのほうで初めて質問させていただくのですが現在3Dゲームでの敵と軌跡の当たり判定について考えているのですがわからなくなったので質問させていただきました。 こちらがソースコードなんですけど #include "DxLib.h" #include <math.h> #include <list> #define MOVESPEED 10.0f #define ANIM_RUN 1 #define ANIM_NEUTRAL 4 #define CAMERA_ANGLE_SPEED 3.0f // カメラの注視点の高さ #define CAMERA_LOOK_AT_HEIGHT 400.0f // カメラと注視点の距離 #define CAMERA_LOOK_AT_DISTANCE 2150.0f // ラインを描く範囲 #define LINE_AREA_SIZE 10000.0f // ラインの数 #define LINE_NUM 50 // 残像の消えるスピードの速さ #define SHADOW_COUNT_DEC 2 #define SHADOW_MAXCOUNT 30 // 影の最大数 #define SHADOW_ALLAY_MAX (((int)(SHADOW_MAXCOUNT/SHADOW_COUNT_DEC)+6)*6) #define SWORD_COLLOR GetColor( 255 , 0 , 0 ) #define CALC_PI 3.14159265358979323846 //軌跡 struct SWORDSHADOW { int baseX, baseY; // 根元 int beforeX, beforeY; // 1フレーム前の剣先 int nowX, nowY; // 現在の剣先 int color; // 影の色 int count; // 残りタイマー }; std::list<SWORDSHADOW> g_shadow; // 影 int g_beforeX, g_beforeY; // 1フレ前の剣先 int g_beforeBX, g_beforeBY; void clearShadow(); void shadowTrem(); void drawShadow(); int calcDistance(int x1, int y1, int x2, int y2); // 二点の距離を求める int calcAngle(int x1, int y1, int x2, int y2); // 二点の角度を求める void calcMovePosition(int inX, int inY, int rota, int step, int *outX, int *outY); // 基点から角度の移動をした点を取る int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int ModelHandle; float AnimTotalTime; float AnimNowTime; int AnimAttachIndex; int RunFlag; int MoveAnimFrameIndex; VECTOR Position; int MoveFlag; float Angle; float CameraHAngle; float CameraVAngle; VECTOR MoveVector; float SinParam; float CosParam; SetMainWindowText("3D"); ChangeWindowMode(TRUE); if (DxLib_Init() < 0) return -1; ModelHandle = MV1LoadModel("Data\\Sikaku.mqo"); // カメラの向きを初期化 CameraHAngle = 0.0f; CameraVAngle = 40.0f; // 向きを初期化 Angle = 0.0f; RunFlag = FALSE; AnimAttachIndex = MV1AttachAnim(ModelHandle, ANIM_NEUTRAL); AnimTotalTime = MV1GetAttachAnimTotalTime(ModelHandle, AnimAttachIndex); AnimNowTime = 0.0f; MV1SetAttachAnimTime(ModelHandle, AnimAttachIndex, AnimNowTime); MoveAnimFrameIndex = MV1SearchFrame(ModelHandle, "BasePoint"); MV1SetFrameUserLocalMatrix(ModelHandle, MoveAnimFrameIndex, MV1GetFrameLocalMatrix(ModelHandle, MoveAnimFrameIndex)); // プレイヤー座標初期化 Position = VGet(0.0f, 0.0f, 0.0f); SetDrawScreen(DX_SCREEN_BACK); SetCameraNearFar(100.0f, 50000.0f); // 背景の色 SetBackgroundColor(255, 255, 255); // 剣先初期化 GetMousePoint(&g_beforeX, &g_beforeY); GetMousePoint(&g_beforeBX, &g_beforeBY); // メインループ(何かキーが押されたらループを抜ける) while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) { // 画面のクリア ClearDrawScreen(); // カメラ移動 if (CheckHitKey(KEY_INPUT_C) == 1) { CameraHAngle += CAMERA_ANGLE_SPEED; if (CameraHAngle >= 180.0f) { CameraHAngle -= 360.0f; } } if (CheckHitKey(KEY_INPUT_Z) == 1) { CameraHAngle -= CAMERA_ANGLE_SPEED; if (CameraHAngle <= -180.0f) { CameraHAngle += 360.0f; } } if (CheckHitKey(KEY_INPUT_S) == 1) { CameraVAngle += CAMERA_ANGLE_SPEED; if (CameraVAngle >= 80.0f) { CameraVAngle = 80.0f; } } if (CheckHitKey(KEY_INPUT_X) == 1) { CameraVAngle -= CAMERA_ANGLE_SPEED; if (CameraVAngle <= 0.0f) { CameraVAngle = 0.0f; } } // 移動ベクトルを初期化 MoveVector = VGet(0.0f, 0.0f, 0.0f); //移動してるかどうか MoveFlag = FALSE; // プレイヤー移動 if (CheckHitKey(KEY_INPUT_LEFT) == 1) { Angle = 90.0f - CameraHAngle; MoveFlag = TRUE; MoveVector.x = -MOVESPEED; } if (CheckHitKey(KEY_INPUT_RIGHT) == 1) { Angle = -90.0f - CameraHAngle; MoveFlag = TRUE; MoveVector.x = MOVESPEED; } if (CheckHitKey(KEY_INPUT_DOWN) == 1) { Angle = 0.0f - CameraHAngle; MoveFlag = TRUE; MoveVector.z = -MOVESPEED; } if (CheckHitKey(KEY_INPUT_UP) == 1) { Angle = 180.0f - CameraHAngle; MoveFlag = TRUE; MoveVector.z = MOVESPEED; } if (MoveFlag == TRUE) { VECTOR TempMoveVector; SinParam = sin(CameraHAngle / 180.0f * DX_PI_F); CosParam = cos(CameraHAngle / 180.0f * DX_PI_F); TempMoveVector.x = MoveVector.x * CosParam - MoveVector.z * SinParam; TempMoveVector.y = 0.0f; TempMoveVector.z = MoveVector.x * SinParam + MoveVector.z * CosParam; Position = VAdd(Position, TempMoveVector); } //アニメーション処理 if (RunFlag != MoveFlag) { RunFlag = MoveFlag; MV1DetachAnim(ModelHandle, AnimAttachIndex); if (RunFlag) { AnimAttachIndex = MV1AttachAnim(ModelHandle, ANIM_RUN); } else { AnimAttachIndex = MV1AttachAnim(ModelHandle, ANIM_NEUTRAL); } AnimTotalTime = MV1GetAttachAnimTotalTime(ModelHandle, AnimAttachIndex); AnimNowTime = 0.0f; } else { AnimNowTime += 200.0f; if (AnimNowTime >= AnimTotalTime) { AnimNowTime -= AnimTotalTime; } } MV1SetAttachAnimTime(ModelHandle, AnimAttachIndex, AnimNowTime); MV1SetRotationXYZ(ModelHandle, VGet(0.0f, Angle / 180.0f * DX_PI_F, 0.0f)); //座標セット MV1SetPosition(ModelHandle, Position); { VECTOR TempPosition1; VECTOR TempPosition2; VECTOR CameraPosition; VECTOR CameraLookAtPosition; CameraLookAtPosition = Position; CameraLookAtPosition.y += CAMERA_LOOK_AT_HEIGHT; SinParam = sin(CameraVAngle / 180.0f * DX_PI_F); CosParam = cos(CameraVAngle / 180.0f * DX_PI_F); TempPosition1.x = 0.0f; TempPosition1.y = SinParam * CAMERA_LOOK_AT_DISTANCE; TempPosition1.z = -CosParam * CAMERA_LOOK_AT_DISTANCE; SinParam = sin(CameraHAngle / 180.0f * DX_PI_F); CosParam = cos(CameraHAngle / 180.0f * DX_PI_F); TempPosition2.x = CosParam * TempPosition1.x - SinParam * TempPosition1.z; TempPosition2.y = TempPosition1.y; TempPosition2.z = SinParam * TempPosition1.x + CosParam * TempPosition1.z; CameraPosition = VAdd(TempPosition2, CameraLookAtPosition); SetCameraPositionAndTarget_UpVecY(CameraPosition, CameraLookAtPosition); } MV1DrawModel(ModelHandle); //地面処理 { int i; VECTOR Pos1; VECTOR Pos2; SetUseZBufferFlag(TRUE); Pos1 = VGet(-LINE_AREA_SIZE / 2.0f, 0.0f, -LINE_AREA_SIZE / 2.0f); Pos2 = VGet(-LINE_AREA_SIZE / 2.0f, 0.0f, LINE_AREA_SIZE / 2.0f); for (i = 0; i <= LINE_NUM; i++) { DrawLine3D(Pos1, Pos2, GetColor(0, 0, 0)); Pos1.x += LINE_AREA_SIZE / LINE_NUM; Pos2.x += LINE_AREA_SIZE / LINE_NUM; } Pos1 = VGet(-LINE_AREA_SIZE / 2.0f, 0.0f, -LINE_AREA_SIZE / 2.0f); Pos2 = VGet(LINE_AREA_SIZE / 2.0f, 0.0f, -LINE_AREA_SIZE / 2.0f); for (i = 0; i < LINE_NUM; i++) { DrawLine3D(Pos1, Pos2, GetColor(0, 0, 0)); Pos1.z += LINE_AREA_SIZE / LINE_NUM; Pos2.z += LINE_AREA_SIZE / LINE_NUM; } SetUseZBufferFlag(FALSE); } shadowTrem(); drawShadow(); ScreenFlip(); } // DXライブラリの後始末 clearShadow(); DxLib_End(); return 0; } // データクリア void clearShadow() { g_shadow.clear(); } // 影処理 void shadowTrem() { int nowX, nowY; int nowBX, nowBY; GetMousePoint(&nowX, &nowY); // つばの位置 calcMovePosition(320, 240, calcAngle(320, 240, nowX, nowY), (int)(calcDistance(320, 240, nowX, nowY) * 0.4), &nowBX, &nowBY); // 剣の軌跡(残像)処理 std::list<SWORDSHADOW>::iterator ite; for (ite = g_shadow.begin(); ite != g_shadow.end(); ite++) { if (ite->count < SHADOW_COUNT_DEC) { ite = g_shadow.erase(ite); } else { ite->count -= SHADOW_COUNT_DEC; } } // 追加処理 if (g_shadow.size() >= SHADOW_ALLAY_MAX) { } else { SWORDSHADOW addShadow; // ギザギザの残像 addShadow.baseX = g_beforeBX; addShadow.baseY = g_beforeBY; addShadow.beforeX = g_beforeX; addShadow.beforeY = g_beforeY; addShadow.color = SWORD_COLLOR; addShadow.count = SHADOW_MAXCOUNT; addShadow.nowX = nowX; addShadow.nowY = nowY; g_shadow.push_back(addShadow); // `` addShadow.baseX = nowX; addShadow.baseY = nowY; addShadow.beforeX = g_beforeBX; addShadow.beforeY = g_beforeBY; addShadow.color = SWORD_COLLOR; addShadow.count = SHADOW_MAXCOUNT; addShadow.nowX = nowBX; addShadow.nowY = nowBY; g_shadow.push_back(addShadow); } // OLD更新 g_beforeX = nowX; g_beforeY = nowY; g_beforeBX = nowBX; g_beforeBY = nowBY; } // 表示 void drawShadow() { std::list<SWORDSHADOW>::iterator ite; for (ite = g_shadow.begin(); ite != g_shadow.end(); ite++) { // 半透明設定 // if (ite->count > 255) // { // SetDrawBlendMode(DX_BLENDMODE_ALPHA, 255); // } // else // { // SetDrawBlendMode(DX_BLENDMODE_ALPHA, ite->count); // } // 半透明設定 if (ite->count > 0) { SetDrawBlendMode(DX_BLENDMODE_ALPHA, 140); } else { SetDrawBlendMode(DX_BLENDMODE_ALPHA, ite->count); } DrawTriangle(ite->baseX, ite->baseY, ite->beforeX, ite->beforeY, ite->nowX, ite->nowY, ite->color, true); } SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0); } // 二点間の距離を求める int calcDistance(int x1, int y1, int x2, int y2) { int max_distance; max_distance = (int)(sqrt(pow((double)(x1 - x2), 2) + pow((double)(y1 - y2), 2))); if (max_distance > 2)max_distance = 2; return max_distance; } // 二点間の角度を求める int calcAngle(int x1, int y1, int x2, int y2) { double angle; int returnAngle; if ((x1 - x2) == 0 && (y1 - y2) == 0) { angle = 0; } else { angle = -CALC_PI / 2 + (float)atan2(-(double)(y1 - y2), (double)(x1 - x2)); } returnAngle = (int)(angle / CALC_PI * 180) - 90; if (returnAngle < 0) { returnAngle += 360; } return returnAngle; } // 座標を向きと移動量で移動させる void calcMovePosition(int inX, int inY, int rota, int step, int *outX, int *outY) { float radRota = (float)(rota * CALC_PI / 180); *outX = (int)(cosf(radRota) * step + inX); *outY = (int)(-sinf(radRota) * step + inY); } 敵(まだ表示させていません)とマウスを動かすと出る軌跡をぶつけると敵が消えるというプログラムをうちたいんですけどヒントを教えてないでしょうか。 この軌跡に当たり判定をつける方法がわからないです、ちなみにSキーを押して上から見た画面でのゲームです。
メンテ

Page: 1 |

Re: 箱同士が戦う3Dゲーム ( No.1 )
名前:管理人 日時:2018/07/29 01:25

ご返信が遅くなり申し訳ありません 『3Dのゲームでマウスの軌跡をぶつけると敵が消える』方法が不明とのことですが、では 『2Dのゲームでマウスの軌跡をぶつけると敵が消える』のように、3Dではなく2Dであれば どのように組めば良いか分かりますでしょうか? もし2Dであれば分かるということでしたら、3Dの座標は ConvWorldPosToScreenPos で2D画面上の 座標に変換できますので、2Dでの判定の仕方が分かるのでしたらこちらで3Dの敵の座標を2Dに変換することで 当たり判定を行うことができます // ワールド座標をスクリーン座標に変換する VECTOR ConvWorldPosToScreenPos( VECTOR WorldPos ) ;
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存