こんにちは、こちらのほうで初めて質問させていただくのですが現在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キーを押して上から見た画面でのゲームです。