drag available cards

This commit is contained in:
Asuro
2025-04-07 17:58:48 +02:00
parent fd2654c944
commit 3fd8937b25
7 changed files with 128 additions and 41 deletions

Binary file not shown.

BIN
assets/textures/bridge.png LFS Normal file

Binary file not shown.

View File

@@ -366,10 +366,50 @@ namespace Game
LOG("finished setup!");
}
Vec3 GetMousePosWorld()
{
auto& window = GetShared().Window;
Vec2 mousePos = GetMousePos();
mousePos.x = mousePos.x / window.WindowWidth;
mousePos.y = mousePos.y / window.WindowHeight;
mousePos *= 2.0f;
mousePos -= 1.0f;
Vec4 mousePosView = {mousePos.x, -mousePos.y, 0.0f, 1.0f};
Vec4 mousePosCam4 = Mul(GetInstance().Player.ProjectionInverse, mousePosView);
Vec3 mousePosCam = Vec3{
mousePosCam4.x /= mousePosCam4.w,
mousePosCam4.y /= mousePosCam4.w,
mousePosCam4.z /= mousePosCam4.w,
};
return LocalToGlobalPoint(GetInstance().Player.PlayerCamTransform, mousePosCam);
}
bool IsQuadHovered(Transform& quadTransform, Vec3 mousePosWorld, Vec3& outQuadPlaneIntersectPos)
{
Vec3 quadPosWorld = quadTransform.Position;
Vec3 quadXWorld = LocalToGlobalPoint(quadTransform, {1, 0, 0});
Vec3 quadZWorld = LocalToGlobalPoint(quadTransform, {0, 0, 1});
if (RayPlaneIntersect(GetInstance().Player.PlayerCamTransform.Position,
mousePosWorld,
quadPosWorld,
quadXWorld,
quadZWorld,
outQuadPlaneIntersectPos))
{
Vec3 quadSpaceIntersect = GlobalToLocalPoint(quadTransform, outQuadPlaneIntersectPos);
if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f && quadSpaceIntersect.z >= -1.0f &&
quadSpaceIntersect.z <= 1.0f)
{
return true;
}
}
return false;
}
void WorldPuzzle::Update()
{
Level& level = GetInstance().GameLevel;
auto& window = GetShared().Window;
auto& staticCards = Puzzle::GetStaticPuzzleData().Cards;
auto& visuals = Puzzle::GetStaticPuzzleData().Visuals;
@@ -387,20 +427,7 @@ namespace Game
TranslateLocal(tileOriginTransform, Vec3{uiOffset.x, 0.0f, uiOffset.y} * 1.0f);
UpdateMatrix(tileOriginTransform);
Vec2 mousePos = GetMousePos();
mousePos.x = mousePos.x / window.WindowWidth;
mousePos.y = mousePos.y / window.WindowHeight;
mousePos *= 2.0f;
mousePos -= 1.0f;
Vec4 mousePosView = {mousePos.x, -mousePos.y, 0.0f, 1.0f};
Vec4 mousePosCam4 = Mul(GetInstance().Player.ProjectionInverse, mousePosView);
Vec3 mousePosCam = Vec3{
mousePosCam4.x /= mousePosCam4.w,
mousePosCam4.y /= mousePosCam4.w,
mousePosCam4.z /= mousePosCam4.w,
};
Vec3 mousePosWorld = LocalToGlobalPoint(camTransform, mousePosCam);
Vec3 mousePosWorld = GetMousePosWorld();
// Available Cards
for (int32_t i = 0; i < Puzzle::Config::MaxAvailableStacks; ++i)
@@ -424,6 +451,45 @@ namespace Game
quad.EData.Transform.Scale = {UICardScale, UICardScale, UICardScale};
quad.EData.DotColor = {1.0f, 1.0f, 1.0f, 1.0f};
quad.EData.BaseColor = {1.0f, 1.0f, 1.0f, 1.0f};
if (j == 0)
{
Vec3 quadPlaneIntersectPos;
if (IsQuadHovered(quad.EData.Transform, mousePosWorld, quadPlaneIntersectPos) &&
DraggedAvailableCardIdx == UINT16_MAX && DraggedCard.X == -1 &&
GetMouseButtonPressedNow(MouseButton::Left))
{
DraggedAvailableCardIdx = i;
}
if (DraggedAvailableCardIdx == i)
{
Vec3 dragPos = quadPlaneIntersectPos;
dragPos -= AxisForward(camTransform.M) * 0.01f;
quad.EData.Transform.Position = dragPos;
Vec3 boardPos = GlobalToLocalPoint(tileOriginTransform, quadPlaneIntersectPos);
Vec3 boardTilePos = boardPos / UICardOffset;
int32_t xPos = (int32_t)bx::round(boardTilePos.x);
int32_t yPos = (int32_t)bx::round(boardTilePos.z);
if (!GetMouseButton(MouseButton::Left))
{
if (xPos >= 0 && xPos < Data.WidthTiles / Puzzle::Config::CardSize && yPos >= 0 &&
yPos < Data.HeightTiles / Puzzle::Config::CardSize)
{
Gen::PuzPos targetCardPos = {(int8_t)xPos, (int8_t)yPos};
Gen::PlacedPuzzleCard& targetCard =
Data.PlacedCards[yPos * Puzzle::Config::MaxPuzzleSizeCards + xPos];
if (!Puzzle::IsValid(targetCard.RefCard) || targetCard.RefCard.Idx == 0)
{
Puzzle::DragAvailableCardTo(Data, targetCardPos, DraggedAvailableCardIdx, 0);
}
}
DraggedAvailableCardIdx = UINT16_MAX;
}
}
}
}
else
{
@@ -476,18 +542,10 @@ namespace Game
Rotate(quad.EData.Transform, Vec3{bx::kPi * 0.5f, 0.0f, (1.0f - card.Rotation * 0.5f) * bx::kPi});
quad.EData.Transform.Scale = {UICardScale, UICardScale, UICardScale};
Vec3 quadPosWorld = quad.EData.Transform.Position;
Vec3 quadXWorld = LocalToGlobalPoint(quad.EData.Transform, {1, 0, 0});
Vec3 quadZWorld = LocalToGlobalPoint(quad.EData.Transform, {0, 0, 1});
Vec3 intersectPos;
if (RayPlaneIntersect(
camTransform.Position, mousePosWorld, quadPosWorld, quadXWorld, quadZWorld, intersectPos))
Vec3 quadPlaneIntersectPos;
if (isValid && IsQuadHovered(quad.EData.Transform, mousePosWorld, quadPlaneIntersectPos))
{
Vec3 quadSpaceIntersect = GlobalToLocalPoint(quad.EData.Transform, intersectPos);
if (isValid && quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f &&
quadSpaceIntersect.z >= -1.0f && quadSpaceIntersect.z <= 1.0f)
{
if (!card.IsLocked && DraggedCard.X == -1)
if (!card.IsLocked && DraggedCard.X == -1 && DraggedAvailableCardIdx == UINT16_MAX)
{
if (GetMouseButtonPressedNow(MouseButton::Left))
{
@@ -500,14 +558,13 @@ namespace Game
}
}
}
}
if (DraggedCard.X == x && DraggedCard.Y == y)
{
Vec3 dragPos = intersectPos;
Vec3 dragPos = quadPlaneIntersectPos;
dragPos -= AxisForward(camTransform.M) * 0.01f;
quad.EData.Transform.Position = dragPos;
Vec3 boardPos = GlobalToLocalPoint(tileOriginTransform, intersectPos);
Vec3 boardPos = GlobalToLocalPoint(tileOriginTransform, quadPlaneIntersectPos);
Vec3 boardTilePos = boardPos / UICardOffset;
int32_t xPos = (int32_t)bx::round(boardTilePos.x);
int32_t yPos = (int32_t)bx::round(boardTilePos.z);
@@ -526,14 +583,36 @@ namespace Game
if (xPos >= 0 && xPos < Data.WidthTiles / Puzzle::Config::CardSize && yPos >= 0 &&
yPos < Data.HeightTiles / Puzzle::Config::CardSize)
{
PlacedPuzzleCard srcCardCopy = srcCard;
Gen::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);
int32_t foundIdx = -1;
for (int32_t availCardIdx = 0; availCardIdx < Data.AvailableCardCount; ++availCardIdx)
{
LOG("CHECK: %u", Data.AvailableCards[availCardIdx].RefCard.Idx);
if (Data.AvailableCards[availCardIdx].RefCard.Idx == srcCardCopy.RefCard.Idx)
{
foundIdx = availCardIdx;
break;
}
}
if (foundIdx >= 0)
{
Puzzle::DragAvailableCardTo(Data, targetCardPos, foundIdx, srcCard.Rotation);
}
else
{
LOG_ERROR("NOTFOUND: %u", srcCardCopy.RefCard.Idx);
}
}
}
else
{
Puzzle::ReturnPlacedCard(Data, srcCardPos);
}
DraggedCard.X = -1;
DraggedCard.Y = -1;
}

View File

@@ -151,6 +151,7 @@ namespace Game
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
UIQuadEntityHandle UIAvailableCards[Puzzle::Config::MaxAvailableStacks * UIAvailableCardMaxStackPreview];
Gen::PuzPos DraggedCard{-1, -1};
uint16_t DraggedAvailableCardIdx = UINT16_MAX;
bool IsSetup = false;
bool IsActive = false;

View File

@@ -91,5 +91,6 @@ void main()
vec3 rawTex = texture2D(s_texColor, uv).xyz;
vec3 col = rawTex * u_dotColor.xyz;
float brightness = lerp(0.5, 0.9, calcBrightnessDirectional(vec3(0.5, 0.3, 1.0), v_normal));
brightness = 1.0;
gl_FragColor = vec4(col * brightness, 1.0);
}

BIN
src/textures/bridge.ktx LFS Normal file

Binary file not shown.