diff --git a/Solitaire/assets/club8x8.png b/Solitaire/assets/club8x8.png new file mode 100644 index 0000000..017673b Binary files /dev/null and b/Solitaire/assets/club8x8.png differ diff --git a/Solitaire/assets/diamond8x8.png b/Solitaire/assets/diamond8x8.png new file mode 100644 index 0000000..677eaa2 Binary files /dev/null and b/Solitaire/assets/diamond8x8.png differ diff --git a/Solitaire/assets/heart8x8.png b/Solitaire/assets/heart8x8.png new file mode 100644 index 0000000..9d2467b Binary files /dev/null and b/Solitaire/assets/heart8x8.png differ diff --git a/Solitaire/assets/spade8x8.png b/Solitaire/assets/spade8x8.png new file mode 100644 index 0000000..0ff60ac Binary files /dev/null and b/Solitaire/assets/spade8x8.png differ diff --git a/Solitaire/main.cpp b/Solitaire/main.cpp index 4d323a8..558711c 100644 --- a/Solitaire/main.cpp +++ b/Solitaire/main.cpp @@ -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,20 +51,48 @@ 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) { - FillRectDecal(pos, CARD_SIZE, DARK_CYAN); - DrawRectDecal(pos, CARD_SIZE, BLACK); + if (!game->gameFinished) { + FillRectDecal(pos, CARD_SIZE, DARK_CYAN); + DrawRectDecal(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 }); - DrawDecal(pos + vf2d{ 2,12 }, GetSprite(s), { 0.25,0.25 }); - DrawRotatedStringDecal(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 }); - DrawRotatedDecal(pos + CARD_SIZE - vf2d{ 2,12 }, GetSprite(s), PI, { 0,0 }, { 0.25, 0.25 }); - DrawRectDecal(pos, CARD_SIZE, BLACK); + 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 }); + DrawDecal(pos + vf2d{ 2,12 }, GetSprite(s), { 0.25,0.25 }); + DrawRotatedStringDecal(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 }); + DrawRotatedDecal(pos + CARD_SIZE - vf2d{ 2,12 }, GetSprite(s), PI, { 0,0 }, { 0.25, 0.25 }); + DrawRectDecal(pos, CARD_SIZE, BLACK); + } } } @@ -73,6 +102,10 @@ class Solitaire : public olc::PixelGameEngine std::vector faceDownCards; std::vector 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 draggedCard = {}; std::vectorpreviousCardInteraction = {}; CardSlot*previousCardSlotInteraction=NULL; + bool gameFinished = false; + bool spritesRendered = false; + const float gravity = 16.f; Card DrawCard() { std::uniform_int_distribution 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,18 +457,70 @@ class Solitaire : public olc::PixelGameEngine // called once per frame //RenderCard({ 48,48 }, HEART, 7); - UpdateCardSlots(); + if (!gameFinished) { + UpdateCardSlots(); - PlayDeck.RenderCards(); - ActivePlayDeck.RenderCards(); - for (CardSlot& c : Home) { - c.RenderCards(); - } - for (CardSlot& c : Field) { - c.RenderCards(); + 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); + } } - for (int i = 0; i < draggedCard.size(); i++) { - 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 randHorizontalVelocity(-30, 30); + std::uniform_real_distribution 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; }