Re: 就活のために デスクトップマスコットを作りたい!パート3 ( No.1 ) |
- 名前:kukaniki 日時:2025/01/03 15:29
失礼文脈がおかしくなってしまいました。
注意:MV1CollCheck_Lineに関係するのは当たり判定は、カーソルには適応されないんですか?
|
Re: 就活のために デスクトップマスコットを作りたい!パート3 ( No.2 ) |
- 名前:kukaniki 日時:2025/01/03 17:12
#include <DxLib.h>
#include <windows.h> // WinMainの注釈用
#include <cstdio>
#include <iostream>
#include <cmath> // sin, cos関数用
using namespace std;
// グローバル変数
float CameraX = 0.0f, CameraY = 9.5f, CameraZ = -70.0f; // カメラの位置
float PositionX = 0.0f, PositionY = 0.0f, PositionZ = 0.0f; // キャラクターの初期位置
const float MoveSpeed = 0.5f; // カメラ移動速度
const float CharacterSpeed = 0.5f; // キャラクター移動速度
const float GRAVITY = 0.5f; // 重力加速度
const float GROUND_Y = 0.0f; // 地面の高さ(Y軸)
VECTOR RotationXYZ = { 0.0f, 0.0f, 0.0f }; // キャラクターの回転値
VECTOR StartPos, EndPos;
const float RotationSpeed = 3.0f; // 回転速度(度単位)
void HandleMouseInput(int& MouseInput, bool& isDragging) {
MouseInput = GetMouseInput();
if (MouseInput & MOUSE_INPUT_LEFT) {
isDragging = true;
}
else {
isDragging = false;
}
}
void HandleKeyboardInput(bool& isKeyPressed) {
// WASDキーによるキャラクターの移動とアニメーション進行
if (CheckHitKey(KEY_INPUT_S)) {
PositionX += CharacterSpeed * sinf(RotationXYZ.y * DX_PI_F / 180.0f); // 前進
PositionZ += CharacterSpeed * cosf(RotationXYZ.y * DX_PI_F / 180.0f);
isKeyPressed = true;
}
if (CheckHitKey(KEY_INPUT_W)) {
PositionX -= CharacterSpeed * sinf(RotationXYZ.y * DX_PI_F / 180.0f); // 後退
PositionZ -= CharacterSpeed * cosf(RotationXYZ.y * DX_PI_F / 180.0f);
isKeyPressed = true;
}
if (CheckHitKey(KEY_INPUT_A)) {
PositionX += CharacterSpeed * cosf(RotationXYZ.y * DX_PI_F / 180.0f); // 左カニステップ
PositionZ -= CharacterSpeed * sinf(RotationXYZ.y * DX_PI_F / 180.0f);
isKeyPressed = true;
}
if (CheckHitKey(KEY_INPUT_D)) {
PositionX -= CharacterSpeed * cosf(RotationXYZ.y * DX_PI_F / 180.0f); // 右カニステップ
PositionZ += CharacterSpeed * sinf(RotationXYZ.y * DX_PI_F / 180.0f);
isKeyPressed = true;
}
// スペースキーによるキャラクターの前進
if (CheckHitKey(KEY_INPUT_SPACE)) {
PositionX -= CharacterSpeed * sinf(RotationXYZ.y * DX_PI_F / 180.0f); // 前進
PositionZ -= CharacterSpeed * cosf(RotationXYZ.y * DX_PI_F / 180.0f);
isKeyPressed = true;
}
// QRキーによる回転
if (CheckHitKey(KEY_INPUT_E)) {
RotationXYZ.y -= RotationSpeed;
isKeyPressed = true;
}
if (CheckHitKey(KEY_INPUT_Q)) {
RotationXYZ.y += RotationSpeed;
isKeyPressed = true;
}
}
void HandleKeyboardCamera(bool& isKeyPressed) {
}
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
// ウィンドウモードで起動
ChangeWindowMode(TRUE);
//透過ウインドウ設定
SetUseBackBufferTransColorFlag(TRUE);
//解像度
SetGraphMode(1920, 1080, 32);
MV1_COLL_RESULT_POLY HitPoly;
if (DxLib_Init() == -1)
return -1;
// カメラのクリップ距離を設定
SetCameraNearFar(1.0f, 1000.0f); // Near: 1.0f, Far: 1000.0f
// モデルを読み込む
int ModelHandle = MV1LoadModel("C:\\Users\\PC01k\\Downloads\\ボコボコにしてやんよ\\ボコボコにしてやんよ\\bokoboko.pmd");
if (ModelHandle == -1)
{
MessageBox(NULL, "モデルの読み込みに失敗しました。", "エラー", MB_OK);
DxLib_End();
return -1;
}
// アニメーション設定
int AttachIndex = MV1AttachAnim(ModelHandle, 1, -1, FALSE); // 初期アニメーションは1
float TotalTime = MV1GetAttachAnimTotalTime(ModelHandle, AttachIndex);
float PlayTime = 0.0f;
bool isKeyPressed = false;
//マウスの状況
int MouseInput;
bool isDragging = false;
//マウスの座標を取得
int MouseX, MouseY;
// 描画色設定
int White = GetColor(255, 255, 255);
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
POINT mouse;
if (GetCursorPos(&mouse)) {
cout << "Mouse X:" << mouse.x << ", Mouse Y: " << mouse.y << endl;
}
GetMousePoint(&MouseX, &MouseY);
// スクリーン座標をワールド座標に変換
VECTOR screenPos = VGet((float)MouseX, (float)MouseY, 0.0f); // スクリーン座標 (Z は 0)
// スクリーンの情報をワールドの座標に変換
StartPos = ConvScreenPosToWorldPos(screenPos);
EndPos = VGet(1000.0f, 300.0f, 600.0f);
HitPoly = MV1CollCheck_Line(ModelHandle, 0, StartPos, EndPos);
// 当たった場合はその位置を描画する線分の終点とする
if (HitPoly.HitFlag == 1)
{
EndPos = HitPoly.HitPosition;
}
//イベント処理
// キーが押されているかチェック
HandleMouseInput(MouseInput, isDragging);
HandleKeyboardInput(isKeyPressed);
HandleKeyboardCamera(isKeyPressed);
// 回転値をモデルに適用
MV1SetRotationXYZ(ModelHandle, VGet(
RotationXYZ.x * DX_PI_F / 180.0f,
RotationXYZ.y * DX_PI_F / 180.0f,
RotationXYZ.z * DX_PI_F / 180.0f));
// アニメーションの更新
if (isKeyPressed)
{
PlayTime += 0.5f; // アニメーション進行速度
if (PlayTime > TotalTime) PlayTime = 0.0f; // ループ再生
MV1SetAttachAnimTime(ModelHandle, AttachIndex, PlayTime);
}
// カメラ操作
if (CheckHitKey(KEY_INPUT_DOWN)) CameraZ -= MoveSpeed;
if (CheckHitKey(KEY_INPUT_UP)) CameraZ += MoveSpeed;
if (CheckHitKey(KEY_INPUT_LEFT)) CameraX -= MoveSpeed;
if (CheckHitKey(KEY_INPUT_RIGHT)) CameraX += MoveSpeed;
if (CheckHitKey(KEY_INPUT_PGUP)) CameraY += MoveSpeed;
if (CheckHitKey(KEY_INPUT_PGDN)) CameraY -= MoveSpeed;
// カメラの高さ制限
if (CameraY < 0.0f) CameraY = 0.0f;
if (PositionY < 0.0f) PositionY = 0.0f;
// 重力を適用してキャラクターのY位置を更新
PositionY -= GRAVITY; // 毎フレーム重力を加算
// 地面と衝突した場合、キャラクターが落下しないようにする
if (PositionY < GROUND_Y) PositionY = GROUND_Y;
// キャラクターの位置を設定
VECTOR CharacterPosition = VGet(PositionX, PositionY, PositionZ);
MV1SetPosition(ModelHandle, CharacterPosition);
// カメラの設定
VECTOR CameraPosition = VGet(CameraX, CameraY, CameraZ);
VECTOR CameraTarget = VGet(CameraX, CameraY, CameraZ + 1.0f);
SetCameraPositionAndTarget_UpVecY(CameraPosition, CameraTarget);
// 描画
ClearDrawScreen();
//Grand(40, 4); // グリッドの描画
MV1DrawModel(ModelHandle);
// カメラ情報の描画
DrawFormatString(0, 0, White, "Camera X: %.2f", CameraX);
DrawFormatString(0, 20, White, "Camera Y: %.2f", CameraY);
DrawFormatString(0, 40, White, "Camera Z: %.2f", CameraZ);
// キャラクター情報の描画
DrawFormatString(0, 60, White, "Target Position X: %.2f", PositionX);
DrawFormatString(0, 80, White, "Target Position Y: %.2f", PositionY);
DrawFormatString(0, 100, White, "Target Position Z: %.2f", PositionZ);
DrawFormatString(0, 120, White, "Rotation Y: %.2f", RotationXYZ.y);
//マウスカーソルの座標
DrawFormatString(0, 140, White, "Mouse X: %d", MouseX);
DrawFormatString(0, 160, White, "Mouse Y: %d", MouseY);
DrawFormatString(0, 180, White, "Dragging: %s", isDragging ? "True" : "False");
//ワールドの座標
DrawFormatString(0, 200, White, "World X: %.2f", StartPos.x);
DrawFormatString(0, 220, White, "World Y: %.2f", StartPos.y);
DrawFormatString(0, 240, White, "World Z: %.2f", StartPos.z);
DrawLine3D(StartPos, EndPos, GetColor(255, 0, 0)); // 赤色で線分を描画
DrawFormatString(0, 260, GetColor(255, 255, 255), "HIT:%d", HitPoly.HitFlag);
ScreenFlip();
}
MV1DeleteModel(ModelHandle);
DxLib_End();
return 0;
}
私なりにものすごい考えています。
線分を出すことに成功しましたが。ヒットするのが遠くなっています。改善する方法はありませんか?
|
Re: 就活のために デスクトップマスコットを作りたい!パート3 ( No.3 ) |
- 名前:管理人 日時:2025/01/04 00:07
MV1CollCheck_Line に渡す EndPos がマウスカーソルの位置に関わらず VGet(1000.0f,300.0f,600.0f) と
してしまっているのが原因ではないかと思います
EndPos に代入する値を以下のように変更すれば改善すると思いますので、試してみてください
VECTOR screenPos2 = VGet((float)MouseX, (float)MouseY, 1.0f); // スクリーン座標 (Z は 1)
EndPos = ConvScreenPosToWorldPos(screenPos2);
|
Re: 就活のために デスクトップマスコットを作りたい!パート3 ( No.4 ) |
- 名前:kukaniki 日時:2025/01/04 11:41
#include <DxLib.h>
#include <windows.h> // WinMainの注釈用
#include <cstdio>
#include <iostream>
#include <cmath> // sin, cos関数用
using namespace std;
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
// ウィンドウモードで起動
ChangeWindowMode(TRUE);
//透過ウインドウ設定
SetUseBackBufferTransColorFlag(TRUE);
//解像度
SetGraphMode(1920, 1080, 32);
MV1_COLL_RESULT_POLY HitPoly;
if (DxLib_Init() == -1)
return -1;
// カメラのクリップ距離を設定
SetCameraNearFar(1.0f, 1000.0f); // Near: 1.0f, Far: 1000.0f
// モデルを読み込む
int ModelHandle = MV1LoadModel("C:\\Users\\PC01k\\Downloads\\ボコボコにしてやんよ\\ボコボコにしてやんよ\\bokoboko.pmd");
if (ModelHandle == -1)
{
MessageBox(NULL, "モデルの読み込みに失敗しました。", "エラー", MB_OK);
DxLib_End();
return -1;
}
// アニメーション設定
int AttachIndex = MV1AttachAnim(ModelHandle, 1, -1, FALSE); // 初期アニメーションは1
float TotalTime = MV1GetAttachAnimTotalTime(ModelHandle, AttachIndex);
float PlayTime = 0.0f;
bool isKeyPressed = false;
//マウスの状況
int MouseInput;
bool isDragging = false;
//マウスの座標を取得
int MouseX, MouseY;
// 描画色設定
int White = GetColor(255, 255, 255);
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
POINT mouse;
if (GetCursorPos(&mouse)) {
cout << "Mouse X:" << mouse.x << ", Mouse Y: " << mouse.y << endl;
}
GetMousePoint(&MouseX, &MouseY);
// スクリーン座標をワールド座標に変換
VECTOR screenPos1 = VGet((float)MouseX, (float)MouseY, 0.0f); // スクリーン座標 (Z は 0)
VECTOR screenPos2 = VGet((float)MouseX, (float)MouseY, 1.0f); // スクリーン座標 (Z は 1)
// スクリーンの情報をワールドの座標に変換
StartPos = ConvScreenPosToWorldPos(screenPos1);
EndPos = ConvScreenPosToWorldPos(screenPos2);
HitPoly = MV1CollCheck_Line(ModelHandle, 0, StartPos, EndPos);
// 当たった場合はその位置を描画する線分の終点とする
if (HitPoly.HitFlag == 1)
{
EndPos = HitPoly.HitPosition;
}
//イベント処理
// キーが押されているかチェック
HandleMouseInput(MouseInput, isDragging);
HandleKeyboardInput(isKeyPressed);
HandleKeyboardCamera(isKeyPressed);
// 回転値をモデルに適用
MV1SetRotationXYZ(ModelHandle, VGet(
RotationXYZ.x * DX_PI_F / 180.0f,
RotationXYZ.y * DX_PI_F / 180.0f,
RotationXYZ.z * DX_PI_F / 180.0f));
// アニメーションの更新
if (isKeyPressed)
{
PlayTime += 0.5f; // アニメーション進行速度
if (PlayTime > TotalTime) PlayTime = 0.0f; // ループ再生
MV1SetAttachAnimTime(ModelHandle, AttachIndex, PlayTime);
}
// カメラの高さ制限
if (CameraY < 0.0f) CameraY = 0.0f;
if (PositionY < 0.0f) PositionY = 0.0f;
// 重力を適用してキャラクターのY位置を更新
PositionY -= GRAVITY; // 毎フレーム重力を加算
// 地面と衝突した場合、キャラクターが落下しないようにする
if (PositionY < GROUND_Y) PositionY = GROUND_Y;
// キャラクターの位置を設定
VECTOR CharacterPosition = VGet(PositionX, PositionY, PositionZ);
MV1SetPosition(ModelHandle, CharacterPosition);
// カメラの設定
VECTOR CameraPosition = VGet(CameraX, CameraY, CameraZ);
VECTOR CameraTarget = VGet(CameraX, CameraY, CameraZ + 1.0f);
SetCameraPositionAndTarget_UpVecY(CameraPosition, CameraTarget);
// 描画
ClearDrawScreen();
//Grand(40, 4); // グリッドの描画
MV1DrawModel(ModelHandle);
// カメラ情報の描画
DrawFormatString(0, 0, White, "Camera X: %.2f", CameraX);
DrawFormatString(0, 20, White, "Camera Y: %.2f", CameraY);
DrawFormatString(0, 40, White, "Camera Z: %.2f", CameraZ);
// キャラクター情報の描画
DrawFormatString(0, 60, White, "Target Position X: %.2f", PositionX);
DrawFormatString(0, 80, White, "Target Position Y: %.2f", PositionY);
DrawFormatString(0, 100, White, "Target Position Z: %.2f", PositionZ);
DrawFormatString(0, 120, White, "Rotation Y: %.2f", RotationXYZ.y);
//マウスカーソルの座標
DrawFormatString(0, 140, White, "Mouse X: %d", MouseX);
DrawFormatString(0, 160, White, "Mouse Y: %d", MouseY);
DrawFormatString(0, 180, White, "Dragging: %s", isDragging ? "True" : "False");
//ワールドの座標
DrawLine3D(StartPos, EndPos, GetColor(255, 0, 0)); // 赤色で線分を描画
DrawFormatString(0, 260, White, "HIT:%d", HitPoly.HitFlag);
DrawFormatString(0, 280, White, "Start X: %.2f, Y: %.2f, Z: %.2f", StartPos.x, StartPos.y, StartPos.z);
DrawFormatString(0, 300, White, "End X: %.2f, Y: %.2f, Z: %.2f", EndPos.x, EndPos.y, EndPos.z);
ScreenFlip();
}
MV1DeleteModel(ModelHandle);
DxLib_End();
return 0;
}
毎度毎度丁寧に対応して頂きありがとうございます。
カーソルでHitを出来るを確認できましたが。(*'▽')
モデルに対してHitはされませんでした。( ;∀;)
だが、一歩前進しました。ありがとうございます。
モデルに対してraycast(Hit)させるにはウィンドウ(2次元)→3D世界→カメラ→< StartPos<< EndPos < Hit<モデル
これを一言で表すと「野球みたいですね。」
モデルに対してHitさせることができますか?ご教示お願い致します。('◇')ゞ
|
Re: 就活のために デスクトップマスコットを作りたい!パート3 ( No.5 ) |
- 名前:kukaniki 日時:2025/01/04 16:53
#include <DxLib.h>
#include <windows.h> // WinMainの注釈用
#include <iostream>
using namespace std;
// マウス操作の状態
bool isDragging = false;
VECTOR dragOffset = { 0.0f, 0.0f, 0.0f };
int selectedModelHandle = -1;
float dragScale = 200.0f; // ドラッグスケール係数
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
// ウィンドウモードで起動
ChangeWindowMode(TRUE);
// 解像度設定
SetGraphMode(920, 870, 32);
if (DxLib_Init() == -1)
return -1;
// カメラのクリップ距離を設定
SetCameraNearFar(1.0f, 1000.0f);
// モデルを読み込む
int ModelHandle = MV1LoadModel("C:\\Users\\PC01k\\Downloads\\ボコボコにしてやんよ\\ボコボコにしてやんよ\\bokoboko.pmd");
if (ModelHandle == -1)
{
MessageBox(NULL, "モデルの読み込みに失敗しました。", "エラー", MB_OK);
DxLib_End();
return -1;
}
// カメラ初期位置
float CameraX = 0.0f, CameraY = 50.0f, CameraZ = -200.0f;
// 描画色設定
int White = GetColor(255, 255, 255);
// モデルの初期位置
VECTOR modelPosition = { 0.0f, 0.0f, 0.0f };
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
// マウス入力を取得
int MouseInput = GetMouseInput();
int MouseX, MouseY;
GetMousePoint(&MouseX, &MouseY);
// スクリーン座標をワールド座標に変換
VECTOR screenPos1 = VGet((float)MouseX, (float)MouseY, 0.0f);
VECTOR screenPos2 = VGet((float)MouseX, (float)MouseY, 1.0f);
VECTOR StartPos = ConvScreenPosToWorldPos(screenPos1);
VECTOR EndPos = ConvScreenPosToWorldPos(screenPos2);
// マウス左ボタンが押された場合
if (MouseInput & MOUSE_INPUT_LEFT)
{
if (!isDragging)
{
// ドラッグ開始判定
MV1_COLL_RESULT_POLY HitPoly = MV1CollCheck_Line(ModelHandle, -1, StartPos, EndPos);
if (HitPoly.HitFlag == 1)
{
isDragging = true;
selectedModelHandle = ModelHandle;
// ドラッグオフセットを計算
dragOffset = VSub(modelPosition, StartPos);
}
}
}
else
{
// ボタンが離されたらドラッグ終了
if (isDragging)
{
isDragging = false;
selectedModelHandle = -1;
dragOffset = VZero(); // ドラッグオフセットをリセット
}
}
// ドラッグ中のモデルを移動
if (isDragging && selectedModelHandle == ModelHandle)
{
// 現在のスクリーン座標からワールド座標を再計算
VECTOR newStartPos = ConvScreenPosToWorldPos(VGet((float)MouseX, (float)MouseY, 0.0f));
VECTOR moveVector = VSub(newStartPos, dragOffset);
moveVector = VScale(moveVector, dragScale); // スケールを掛ける
// z座標固定(現在の値を保持)
moveVector.z = modelPosition.z;
modelPosition = moveVector;
}
// マウスホイールでスケールを変更
int wheelInput = GetMouseWheelRotVol(); // ホイールの回転量を取得
if (wheelInput != 0)
{
// スケール変更(ホイールの回転量でスケールを加算・減算)
//dragScale += wheelInput * 0.0f; // 10.0fはスケール変更の感度
//if (dragScale < 100.0f) dragScale = 100.0f; // 最小スケール制限
//if (dragScale > 100.0f) dragScale = 100.0f; // 最大スケール制限
}
// 描画処理
ClearDrawScreen();
// モデルの描画
MV1SetPosition(ModelHandle, modelPosition);
MV1DrawModel(ModelHandle);
// カメラの設定
VECTOR CameraPosition = VGet(CameraX, CameraY, CameraZ);
VECTOR CameraTarget = VGet(CameraX, CameraY, CameraZ + 1.0f);
SetCameraPositionAndTarget_UpVecY(CameraPosition, CameraTarget);
// UI情報の描画
DrawFormatString(30, 30, White, "Mouse X: %d, Y: %d", MouseX, MouseY);
DrawFormatString(30, 60, White, "Dragging: %s", isDragging ? "True" : "False");
DrawFormatString(30, 90, White, "Model Position X: %.2f, Y: %.2f, Z: %.2f",
modelPosition.x, modelPosition.y, modelPosition.z);
DrawFormatString(30, 120, White, "Drag Scale: %.2f", dragScale);
ScreenFlip();
}
// モデルの解放
MV1DeleteModel(ModelHandle);
DxLib_End();
return 0;
}
Dragすることは成功しましたが、なぜか二回目以降変な挙動になります。どうすれば解決できますか?
Dragするところとモデルの座標の同期もさせたいです。((+_+))どうかお願いします。神様
目標:理想とするドラッグ&ムーブ&リリース。
|
Re: 就活のために デスクトップマスコットを作りたい!パート3 ( No.6 ) |
- 名前:管理人 日時:2025/01/05 00:20
ドラッグで移動した後に( ボタンを離した時のタイミングで ) MV1RefreshCollInfo という関数で
3Dモデルの当たり判定の情報を更新することで2回目以降も問題なくドラッグできるようになると
思いますので、よろしければお試しください m(_ _)m
// ボタンが離されたらドラッグ終了
if (isDragging)
{
isDragging = false;
selectedModelHandle = -1;
dragOffset = VZero(); // ドラッグオフセットをリセット
MV1RefreshCollInfo(ModelHandle); // 当たり判定情報を更新
}
|
|