|
|
|
@ -13,7 +13,8 @@ Solitaire*game; |
|
|
|
|
class Solitaire : public olc::PixelGameEngine |
|
|
|
|
{ |
|
|
|
|
std::default_random_engine generator; |
|
|
|
|
Renderable club_spr, spade_spr, diamond_spr, heart_spr; |
|
|
|
|
Renderable club_spr, spade_spr, diamond_spr, heart_spr, |
|
|
|
|
club_spr8, spade_spr8, diamond_spr8, heart_spr8; |
|
|
|
|
enum Suit { |
|
|
|
|
CLUB, |
|
|
|
|
DIAMOND, |
|
|
|
@ -50,13 +51,40 @@ class Solitaire : public olc::PixelGameEngine |
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Sprite* GetSpriteSprite(Suit s) { |
|
|
|
|
switch (s) { |
|
|
|
|
case CLUB: { |
|
|
|
|
return club_spr8.Sprite(); |
|
|
|
|
}break; |
|
|
|
|
case DIAMOND: { |
|
|
|
|
return diamond_spr8.Sprite(); |
|
|
|
|
}break; |
|
|
|
|
case HEART: { |
|
|
|
|
return heart_spr8.Sprite(); |
|
|
|
|
}break; |
|
|
|
|
case SPADE: { |
|
|
|
|
return spade_spr8.Sprite(); |
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RenderCard(vf2d pos, Suit s, int number) { |
|
|
|
|
if (number == -1) { return; } |
|
|
|
|
if (s == FACEDOWN) { |
|
|
|
|
if (!game->gameFinished) { |
|
|
|
|
FillRectDecal(pos, CARD_SIZE, DARK_CYAN); |
|
|
|
|
DrawRectDecal(pos, CARD_SIZE, BLACK); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
if (game->gameFinished) { |
|
|
|
|
FillRect(pos, CARD_SIZE, WHITE); |
|
|
|
|
DrawString(pos + vf2d{ 2,2 }, number == 1 ? "A" : number == 13 ? "K" : number == 12 ? "Q" : number == 11 ? "J" : std::to_string(number), s == CLUB || s == SPADE ? BLACK : DARK_RED); |
|
|
|
|
DrawSprite(pos + vf2d{ 2,12 }, GetSpriteSprite(s)); |
|
|
|
|
//DrawRotatedString(pos + CARD_SIZE - vf2d{ 2,2 }, number == 1 ? "A" : number == 13 ? "K" : number == 12 ? "Q" : number == 11 ? "J" : std::to_string(number), PI, { 0,0 }, s == CLUB || s == SPADE ? BLACK : DARK_RED, number == 10 ? vf2d{ 0.6,1 } : vf2d{ 1,1 });
|
|
|
|
|
//DrawRotatedSprite(pos + CARD_SIZE - vf2d{ 2,12 }, GetSprite(s), PI, { 0,0 });
|
|
|
|
|
DrawRect(pos, CARD_SIZE, BLACK); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
FillRectDecal(pos, CARD_SIZE, WHITE); |
|
|
|
|
DrawStringDecal(pos + vf2d{ 2,2 }, number == 1 ? "A" : number == 13 ? "K" : number == 12 ? "Q" : number == 11 ? "J" : std::to_string(number), s == CLUB || s == SPADE ? BLACK : DARK_RED, number == 10 ? vf2d{ 0.6,1 } : vf2d{ 1,1 }); |
|
|
|
@ -66,6 +94,7 @@ class Solitaire : public olc::PixelGameEngine |
|
|
|
|
DrawRectDecal(pos, CARD_SIZE, BLACK); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct CardSlot { |
|
|
|
|
vf2d pos; |
|
|
|
@ -73,6 +102,10 @@ class Solitaire : public olc::PixelGameEngine |
|
|
|
|
std::vector<Card> faceDownCards; |
|
|
|
|
std::vector<Card> faceUpCards; |
|
|
|
|
int cardSpacing = 16; |
|
|
|
|
int currentCard = 13; |
|
|
|
|
vf2d cardPos = { -1000,-1000 }; |
|
|
|
|
vf2d vel; |
|
|
|
|
vf2d lastCardDisplay = { -1000,-1000 }; |
|
|
|
|
void RenderCards() { |
|
|
|
|
game->DrawRectDecal(pos, CARD_SIZE, BLACK); |
|
|
|
|
switch (type) { |
|
|
|
@ -333,7 +366,16 @@ class Solitaire : public olc::PixelGameEngine |
|
|
|
|
} |
|
|
|
|
ResetDraggedCard(); |
|
|
|
|
draggedCardSuccess: |
|
|
|
|
int a; |
|
|
|
|
bool gameWon = true; |
|
|
|
|
for (int i = 0; i < Home.size(); i++) { |
|
|
|
|
if (Home[i].faceUpCards[Home[i].faceUpCards.size() - 1].number != 13) { |
|
|
|
|
gameWon = false; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (gameWon) { |
|
|
|
|
gameFinished = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -354,6 +396,9 @@ class Solitaire : public olc::PixelGameEngine |
|
|
|
|
std::vector<Card> draggedCard = {}; |
|
|
|
|
std::vector<Card*>previousCardInteraction = {}; |
|
|
|
|
CardSlot*previousCardSlotInteraction=NULL; |
|
|
|
|
bool gameFinished = false; |
|
|
|
|
bool spritesRendered = false; |
|
|
|
|
const float gravity = 16.f; |
|
|
|
|
|
|
|
|
|
Card DrawCard() { |
|
|
|
|
std::uniform_int_distribution<int> distribution(0, cardDeck.size()-1); |
|
|
|
@ -371,17 +416,26 @@ class Solitaire : public olc::PixelGameEngine |
|
|
|
|
cardDeck.push_back({ (Suit)i,j }); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
SetPixelMode(Pixel::MASK); |
|
|
|
|
Clear(VERY_DARK_GREEN); |
|
|
|
|
club_spr.Load("assets/club.png"); |
|
|
|
|
diamond_spr.Load("assets/diamond.png"); |
|
|
|
|
heart_spr.Load("assets/heart.png"); |
|
|
|
|
spade_spr.Load("assets/spade.png"); |
|
|
|
|
club_spr8.Load("assets/club8x8.png"); |
|
|
|
|
diamond_spr8.Load("assets/diamond8x8.png"); |
|
|
|
|
heart_spr8.Load("assets/heart8x8.png"); |
|
|
|
|
spade_spr8.Load("assets/spade8x8.png"); |
|
|
|
|
for (int i = 0; i < Field.size(); i++) { |
|
|
|
|
for (int j = 0; j < i; j++) { |
|
|
|
|
Field[i].faceDownCards.push_back(DrawCard()); |
|
|
|
|
} |
|
|
|
|
Field[i].faceUpCards.push_back(DrawCard()); |
|
|
|
|
} |
|
|
|
|
Home[0].faceUpCards.push_back({SPADE, 1}); |
|
|
|
|
Home[1].faceUpCards.push_back({ HEART, 1 }); |
|
|
|
|
Home[2].faceUpCards.push_back({ DIAMOND, 1 }); |
|
|
|
|
Home[3].faceUpCards.push_back({ CLUB, 1 }); |
|
|
|
|
for (int i = 0; i < Home.size();i++) { |
|
|
|
|
CardSlot&c = Home[i]; |
|
|
|
|
c.pos = vi2d{ 136 + i * 40,8 }; |
|
|
|
@ -403,6 +457,7 @@ class Solitaire : public olc::PixelGameEngine |
|
|
|
|
// called once per frame
|
|
|
|
|
//RenderCard({ 48,48 }, HEART, 7);
|
|
|
|
|
|
|
|
|
|
if (!gameFinished) { |
|
|
|
|
UpdateCardSlots(); |
|
|
|
|
|
|
|
|
|
PlayDeck.RenderCards(); |
|
|
|
@ -414,7 +469,58 @@ class Solitaire : public olc::PixelGameEngine |
|
|
|
|
c.RenderCards(); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < draggedCard.size(); i++) { |
|
|
|
|
RenderCard(GetMousePos() - CARD_SIZE / 2 + vi2d{0,i*16}, draggedCard[i].s, draggedCard[i].number); |
|
|
|
|
RenderCard(GetMousePos() - CARD_SIZE / 2 + vi2d{ 0,i * 16 }, draggedCard[i].s, draggedCard[i].number); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
if (!spritesRendered) { |
|
|
|
|
spritesRendered = true; |
|
|
|
|
|
|
|
|
|
PlayDeck.RenderCards(); |
|
|
|
|
ActivePlayDeck.RenderCards(); |
|
|
|
|
for (CardSlot& c : Home) { |
|
|
|
|
c.RenderCards(); |
|
|
|
|
} |
|
|
|
|
for (CardSlot& c : Field) { |
|
|
|
|
c.RenderCards(); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < draggedCard.size(); i++) { |
|
|
|
|
RenderCard(GetMousePos() - CARD_SIZE / 2 + vi2d{ 0,i * 16 }, draggedCard[i].s, draggedCard[i].number); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
std::uniform_real_distribution<float> randHorizontalVelocity(-30, 30); |
|
|
|
|
std::uniform_real_distribution<float> randVerticalVelocity(-30, -1); |
|
|
|
|
for (int i = 0; i < Home.size(); i++) { |
|
|
|
|
if (Home[i].cardPos.x<-CARD_SIZE.x || Home[i].cardPos.x>ScreenWidth()) { |
|
|
|
|
if (Home[i].currentCard > 0) { |
|
|
|
|
Home[i].currentCard--; |
|
|
|
|
Home[i].cardPos = Home[i].pos; |
|
|
|
|
Home[i].vel = { randHorizontalVelocity(generator), randVerticalVelocity(generator) }; |
|
|
|
|
if (std::abs(Home[i].vel.x) < 8) { |
|
|
|
|
if (Home[i].vel.x < 0) { |
|
|
|
|
Home[i].vel.x -= 8; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
Home[i].vel.x += 8; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
Home[i].cardPos += Home[i].vel * fElapsedTime; |
|
|
|
|
Home[i].vel.y += gravity * fElapsedTime; |
|
|
|
|
if (Home[i].cardPos.y + CARD_SIZE.y > ScreenHeight()) { |
|
|
|
|
Home[i].cardPos.y = ScreenHeight() - CARD_SIZE.y; |
|
|
|
|
Home[i].vel.y *= -0.95; |
|
|
|
|
} |
|
|
|
|
if (std::pow(Home[i].cardPos.x - Home[i].lastCardDisplay.x, 2) + std::pow(Home[i].cardPos.y - Home[i].lastCardDisplay.y, 2) > 9) { |
|
|
|
|
Home[i].lastCardDisplay = Home[i].cardPos; |
|
|
|
|
RenderCard(Home[i].cardPos, Home[i].faceUpCards[0].s, Home[i].currentCard); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|