card dragging
This commit is contained in:
@@ -334,10 +334,9 @@ namespace Game
|
|||||||
boardTransform.Rotation = camTransform.Rotation;
|
boardTransform.Rotation = camTransform.Rotation;
|
||||||
Vec3 fw = {camTransform.M.M[8], camTransform.M.M[9], camTransform.M.M[10]};
|
Vec3 fw = {camTransform.M.M[8], camTransform.M.M[9], camTransform.M.M[10]};
|
||||||
Vec3 pos = cameraPos;
|
Vec3 pos = cameraPos;
|
||||||
pos += fw * 10.0f;
|
pos += fw * 1.0f;
|
||||||
boardTransform.SetPosition(pos);
|
boardTransform.SetPosition(pos);
|
||||||
|
|
||||||
bool clicked = GetMouseButtonPressedNow(MouseButton::Left);
|
|
||||||
Vec2 mousePos = GetMousePos();
|
Vec2 mousePos = GetMousePos();
|
||||||
mousePos.x = mousePos.x / window.WindowWidth;
|
mousePos.x = mousePos.x / window.WindowWidth;
|
||||||
mousePos.y = mousePos.y / window.WindowHeight;
|
mousePos.y = mousePos.y / window.WindowHeight;
|
||||||
@@ -362,70 +361,90 @@ namespace Game
|
|||||||
auto& tile = level.PuzzleTiles.Get(TileHandles[cardIdx]);
|
auto& tile = level.PuzzleTiles.Get(TileHandles[cardIdx]);
|
||||||
auto& quad = level.UIQuads.Get(UIPlacedCards[cardIdx]);
|
auto& quad = level.UIQuads.Get(UIPlacedCards[cardIdx]);
|
||||||
|
|
||||||
bool IsValid = Puzzle::IsValid(card.RefCard);
|
bool isValid = Puzzle::IsValid(card.RefCard);
|
||||||
|
|
||||||
tile.EData.Visible = true;
|
tile.EData.Visible = true;
|
||||||
tile.EData.ModelH = IsValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle;
|
tile.EData.ModelH = isValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle;
|
||||||
|
|
||||||
Vec3 cardPos = {
|
Vec3 cardPos = {
|
||||||
(float)card.Position.X * Puzzle::Config::CardScaleWorld,
|
(float)card.Position.X * Puzzle::Config::CardScaleWorld,
|
||||||
-5.0f,
|
-5.0f,
|
||||||
(float)card.Position.Y * Puzzle::Config::CardScaleWorld,
|
(float)card.Position.Y * Puzzle::Config::CardScaleWorld,
|
||||||
};
|
};
|
||||||
if (!IsValid)
|
if (!isValid)
|
||||||
{
|
{
|
||||||
cardPos = {x * Puzzle::Config::CardScaleWorld, -5.0f, y * Puzzle::Config::CardScaleWorld};
|
cardPos = {x * Puzzle::Config::CardScaleWorld, -5.0f, y * Puzzle::Config::CardScaleWorld};
|
||||||
}
|
}
|
||||||
tile.EData.Transform.SetPosition(cardPos);
|
tile.EData.Transform.SetPosition(cardPos);
|
||||||
bx::mtxRotateY(tile.EData.Transform.Rotation.M, card.Rotation * bx::kPi * 0.5f);
|
bx::mtxRotateY(tile.EData.Transform.Rotation.M, card.Rotation * bx::kPi * 0.5f);
|
||||||
|
|
||||||
quad.EData.Visible = IsValid;
|
quad.EData.Visible = isValid;
|
||||||
quad.EData.TextureHandle =
|
quad.EData.TextureHandle =
|
||||||
IsValid ? staticCards[card.RefCard.Idx].BoardTextureHandle : Generated::TextureHandle{};
|
isValid ? staticCards[card.RefCard.Idx].BoardTextureHandle : Generated::TextureHandle{};
|
||||||
|
|
||||||
quad.EData.Transform = boardTransform;
|
quad.EData.Transform = boardTransform;
|
||||||
quad.EData.Transform.TranslateLocal(Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * 3.0f);
|
quad.EData.Transform.TranslateLocal(Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} *
|
||||||
quad.EData.Transform.Scale = {1.0f, 1.0f, 1.0f};
|
UICardOffset);
|
||||||
// quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f};
|
quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f};
|
||||||
quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, bx::kPi});
|
quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, (1.0f + card.Rotation * 0.5f) * bx::kPi});
|
||||||
|
|
||||||
if (clicked && IsValid)
|
|
||||||
{
|
|
||||||
Vec3 quadPosWorld = quad.EData.Transform.GetPosition();
|
Vec3 quadPosWorld = quad.EData.Transform.GetPosition();
|
||||||
Vec3 quadXWorld = quad.EData.Transform.LocalToGlobalPoint({1, 0, 0});
|
Vec3 quadXWorld = quad.EData.Transform.LocalToGlobalPoint({1, 0, 0});
|
||||||
Vec3 quadYWorld = quad.EData.Transform.LocalToGlobalPoint({0, 0, 1});
|
Vec3 quadZWorld = quad.EData.Transform.LocalToGlobalPoint({0, 0, 1});
|
||||||
Vec3 intersectPos;
|
Vec3 intersectPos;
|
||||||
if (RayPlaneIntersect(camTransform.GetPosition(),
|
if (RayPlaneIntersect(
|
||||||
mousePosWorld,
|
camTransform.GetPosition(), mousePosWorld, quadPosWorld, quadXWorld, quadZWorld, intersectPos))
|
||||||
quadPosWorld,
|
|
||||||
quadXWorld,
|
|
||||||
quadYWorld,
|
|
||||||
intersectPos))
|
|
||||||
{
|
{
|
||||||
Vec3 quadSpaceIntersect = quad.EData.Transform.GlobalToLocalPoint(intersectPos);
|
Vec3 quadSpaceIntersect = quad.EData.Transform.GlobalToLocalPoint(intersectPos);
|
||||||
if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f &&
|
if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f &&
|
||||||
quadSpaceIntersect.z >= -1.0f && quadSpaceIntersect.z <= 1.0f)
|
quadSpaceIntersect.z >= -1.0f && quadSpaceIntersect.z <= 1.0f)
|
||||||
{
|
{
|
||||||
// LOG("---");
|
if (isValid && !card.IsLocked && DraggedCard.X == -1 &&
|
||||||
// LOG("%.03f %.03f: Click", mousePos.x, mousePos.y);
|
GetMouseButtonPressedNow(MouseButton::Left))
|
||||||
// LOG("%.03f %.03f %.03f: MouseCam", mousePosCam.x, mousePosCam.y, mousePosCam.z);
|
{
|
||||||
// LOG("%.03f %.03f %.03f: MouseWorld", mousePosWorld.x, mousePosWorld.y, mousePosWorld.z);
|
DraggedCard.X = x;
|
||||||
// LOG("%.03f %.03f %.03f: Player",
|
DraggedCard.Y = y;
|
||||||
// camTransform.Position.x,
|
|
||||||
// camTransform.Position.y,
|
|
||||||
// camTransform.Position.z);
|
|
||||||
// LOG("%.03f %.03f %.03f: QuadWorld", quadPosWorld.x, quadPosWorld.y, quadPosWorld.z);
|
|
||||||
// LOG("%.03f %.03f %.03f: QuadX", quadXWorld.x, quadXWorld.y, quadXWorld.z);
|
|
||||||
// LOG("%.03f %.03f %.03f: QuadY", quadYWorld.x, quadYWorld.y, quadYWorld.z);
|
|
||||||
// LOG("%.03f %.03f %.03f: Intersect", intersectPos.x, intersectPos.y, intersectPos.z);
|
|
||||||
// LOG("%.03f %.03f %.03f: IntersectQ",
|
|
||||||
// quadSpaceIntersect.x,
|
|
||||||
// quadSpaceIntersect.y,
|
|
||||||
// quadSpaceIntersect.z);
|
|
||||||
LOG("Clicked %u %u", x, y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (DraggedCard.X == x && DraggedCard.Y == y)
|
||||||
|
{
|
||||||
|
Vec3 dragPos = intersectPos;
|
||||||
|
dragPos -= fw * 0.01f;
|
||||||
|
quad.EData.Transform.SetPosition(dragPos);
|
||||||
|
|
||||||
|
Vec3 boardPos = boardTransform.GlobalToLocalPoint(intersectPos);
|
||||||
|
Vec3 boardTilePos = boardPos / UICardOffset;
|
||||||
|
int32_t xPos = (int32_t)bx::round(boardTilePos.x);
|
||||||
|
int32_t yPos = (int32_t)bx::round(boardTilePos.y);
|
||||||
|
Generated::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y};
|
||||||
|
Generated::PlacedPuzzleCard& srcCard =
|
||||||
|
Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X];
|
||||||
|
|
||||||
|
if (GetMouseButtonPressedNow(MouseButton::Right))
|
||||||
|
{
|
||||||
|
srcCard.Rotation += 1;
|
||||||
|
if (srcCard.Rotation >= 4) srcCard.Rotation = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetMouseButton(MouseButton::Left))
|
||||||
|
{
|
||||||
|
Generated::PuzPos targetCardPos = {(int8_t)xPos, (int8_t)yPos};
|
||||||
|
if (xPos >= 0 && xPos < Data.WidthTiles / Puzzle::Config::CardSize && yPos >= 0 &&
|
||||||
|
yPos < Data.HeightTiles / Puzzle::Config::CardSize)
|
||||||
|
{
|
||||||
|
Generated::PlacedPuzzleCard& targetCard =
|
||||||
|
Data.PlacedCards[yPos * Puzzle::Config::MaxPuzzleSizeCards + xPos];
|
||||||
|
bool canBeReplaced = !Puzzle::IsValid(targetCard.RefCard) || targetCard.RefCard.Idx == 0;
|
||||||
|
if (canBeReplaced && Puzzle::ReturnPlacedCard(Data, srcCardPos))
|
||||||
|
{
|
||||||
|
Puzzle::DragAvailableCardTo(Data, targetCardPos, 0, srcCard.Rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DraggedCard.X = -1;
|
||||||
|
DraggedCard.Y = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,10 +136,12 @@ namespace Game
|
|||||||
struct WorldPuzzle
|
struct WorldPuzzle
|
||||||
{
|
{
|
||||||
static constexpr Vec2 WorldCardSize{10.0f, 10.0f};
|
static constexpr Vec2 WorldCardSize{10.0f, 10.0f};
|
||||||
|
static constexpr float UICardOffset = 0.21f;
|
||||||
Generated::PuzzleData Data;
|
Generated::PuzzleData Data;
|
||||||
Vec3 WorldPosition;
|
Vec3 WorldPosition;
|
||||||
PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle];
|
PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle];
|
||||||
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
|
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
|
||||||
|
Generated::PuzPos DraggedCard{-1, -1};
|
||||||
bool IsSetup = false;
|
bool IsSetup = false;
|
||||||
|
|
||||||
void Setup();
|
void Setup();
|
||||||
|
|||||||
@@ -277,13 +277,16 @@ namespace Puzzle
|
|||||||
bx::snprintf(buf, bufSize, "%s/%u.pzl", Puzzle::PuzzleFileDir, puzID);
|
bx::snprintf(buf, bufSize, "%s/%u.pzl", Puzzle::PuzzleFileDir, puzID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: targetPos is of type CardPos
|
|
||||||
bool ReturnPlacedCard(PuzzleData& obj, PuzPos targetPos)
|
bool ReturnPlacedCard(PuzzleData& obj, PuzPos targetPos)
|
||||||
{
|
{
|
||||||
auto& placedCard = obj.PlacedCards[targetPos.Y * Config::MaxPuzzleSizeCards + targetPos.X];
|
auto& placedCard = obj.PlacedCards[targetPos.Y * Config::MaxPuzzleSizeCards + targetPos.X];
|
||||||
if (IsValid(placedCard.RefCard))
|
if (IsValid(placedCard.RefCard))
|
||||||
{
|
{
|
||||||
if (placedCard.IsLocked) return false;
|
if (placedCard.IsLocked)
|
||||||
|
{
|
||||||
|
LOG_WARN("Card at %i %i is locked!", targetPos.X, targetPos.Y);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int32_t i = 0; i < obj.AvailableCardCount; ++i)
|
for (int32_t i = 0; i < obj.AvailableCardCount; ++i)
|
||||||
{
|
{
|
||||||
@@ -304,7 +307,6 @@ namespace Puzzle
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: targetPos is of type CardPos
|
|
||||||
bool DragAvailableCardTo(PuzzleData& obj, PuzPos targetPos, int32_t availIdx, uint8_t rotation)
|
bool DragAvailableCardTo(PuzzleData& obj, PuzPos targetPos, int32_t availIdx, uint8_t rotation)
|
||||||
{
|
{
|
||||||
if (availIdx >= obj.AvailableCardCount)
|
if (availIdx >= obj.AvailableCardCount)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
#include "Gen.h"
|
#include "Gen.h" // IWYU pragma: keep
|
||||||
|
|
||||||
namespace Puzzle
|
namespace Puzzle
|
||||||
{
|
{
|
||||||
@@ -36,6 +36,11 @@ namespace Puzzle
|
|||||||
PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, uint8_t rotation, int8_t x, int8_t y);
|
PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, uint8_t rotation, int8_t x, int8_t y);
|
||||||
void DrawCard(const StaticPuzzleCard& card, uint8_t rotation, ImVec2 pos);
|
void DrawCard(const StaticPuzzleCard& card, uint8_t rotation, ImVec2 pos);
|
||||||
|
|
||||||
|
// TODO: targetPos is of type CardPos
|
||||||
|
bool ReturnPlacedCard(PuzzleData& obj, PuzPos targetPos);
|
||||||
|
// TODO: targetPos is of type CardPos
|
||||||
|
bool DragAvailableCardTo(PuzzleData& obj, PuzPos targetPos, int32_t availIdx, uint8_t rotation);
|
||||||
|
|
||||||
struct PuzzleSolver
|
struct PuzzleSolver
|
||||||
{
|
{
|
||||||
bool IsPuzzleSolved(const Generated::PuzzleData& puzzle);
|
bool IsPuzzleSolved(const Generated::PuzzleData& puzzle);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "../Tools.h"
|
#include "../Tools.h"
|
||||||
#include "Rendering.h"
|
#include "Rendering.h"
|
||||||
|
|
||||||
#include "SDL3/SDL_events.h"
|
#include "SDL3/SDL_events.h" // IWYU pragma: keep
|
||||||
#include "backends/imgui_impl_sdl3.h"
|
#include "backends/imgui_impl_sdl3.h"
|
||||||
#include "bgfx/defines.h"
|
#include "bgfx/defines.h"
|
||||||
#include "bx/bx.h"
|
#include "bx/bx.h"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <bx/string.h>
|
#include <bx/string.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "../Gen.h"
|
#include "../Gen.h" // IWYU pragma: keep
|
||||||
#include "../Global.h"
|
#include "../Global.h"
|
||||||
#include "Dither.h"
|
#include "Dither.h"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user