├── README.md ├── images ├── blank.png ├── distracted.png ├── drake.png ├── fine.png ├── images.pptx ├── rollsafe.png └── success.png ├── index.html ├── script.js └── styles.css /README.md: -------------------------------------------------------------------------------- 1 | # Continuous Deployment using AWS Code Pipeline and S3 2 | 3 | This repo contains the code files used in this [YouTube video](https://youtu.be/biYVW1TMYAU). 4 | 5 | ## TL;DR 6 | Code for a game is hosted in GitHub. We create an S3 bucket for static website hosting, then create a continuous deployment pipeline (using AWS Code Pipeline) to automatically deploy the code whenever changes are made. 7 | 8 | ## The Game 9 | A simple memory matching game. The user clicks two cards (images of memes) to try to match them. If there's a match, the cards disappear from the board. If there's no match, the cards are flipped back to their blank side so the user can try again. 10 | 11 | The game consists of HTML, CSS and JavaScript. 12 | 13 | Ideas for additional features: 14 | - A scoring mechanism 15 | - A timer 16 | - Add additional cards 17 | - Multi-player capabilities so you can compare scores 18 | 19 | ## The Deployment Environment 20 | The code will be deployed and hosted in S3. 21 | 22 | ## The Deployment Pipeline 23 | The pipeline is created using AWS Code Pipeline. The pipeline pulls the code from GitHub, and deploys it to S3 whenever a change is detected in the code. 24 | 25 | ## Cost 26 | All services used are eligible for the [AWS Free Tier](https://aws.amazon.com/free/). However, charges will incur at some point so it's recommended that you shut down resources after completing this tutorial. 27 | -------------------------------------------------------------------------------- /images/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinytechnicaltutorials/codepipeline-s3-game/4dc89322d0c8c801194a8834e529486e324421fb/images/blank.png -------------------------------------------------------------------------------- /images/distracted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinytechnicaltutorials/codepipeline-s3-game/4dc89322d0c8c801194a8834e529486e324421fb/images/distracted.png -------------------------------------------------------------------------------- /images/drake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinytechnicaltutorials/codepipeline-s3-game/4dc89322d0c8c801194a8834e529486e324421fb/images/drake.png -------------------------------------------------------------------------------- /images/fine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinytechnicaltutorials/codepipeline-s3-game/4dc89322d0c8c801194a8834e529486e324421fb/images/fine.png -------------------------------------------------------------------------------- /images/images.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinytechnicaltutorials/codepipeline-s3-game/4dc89322d0c8c801194a8834e529486e324421fb/images/images.pptx -------------------------------------------------------------------------------- /images/rollsafe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinytechnicaltutorials/codepipeline-s3-game/4dc89322d0c8c801194a8834e529486e324421fb/images/rollsafe.png -------------------------------------------------------------------------------- /images/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinytechnicaltutorials/codepipeline-s3-game/4dc89322d0c8c801194a8834e529486e324421fb/images/success.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Meme Matching Game 7 | 8 | 9 | 10 |
11 |

MEME MATCHING GAME

12 |

13 | Welcome to the Meme Matching Game! Flip over two cards at a time and try to find all the matching pairs. Be quick and remember where you saw the cards! 14 |

15 | 16 |
17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', () => { 2 | const grid = document.querySelector('#game-board'); 3 | const startButton = document.getElementById('start-game'); 4 | let cardsChosen = []; 5 | let cardsChosenId = []; 6 | let cardsWon = []; 7 | 8 | const cardArray = [ 9 | { name: 'card1', img: 'images/distracted.png' }, 10 | { name: 'card1', img: 'images/distracted.png' }, 11 | { name: 'card2', img: 'images/drake.png' }, 12 | { name: 'card2', img: 'images/drake.png' }, 13 | { name: 'card3', img: 'images/fine.png' }, 14 | { name: 'card3', img: 'images/fine.png' }, 15 | { name: 'card4', img: 'images/rollsafe.png' }, 16 | { name: 'card4', img: 'images/rollsafe.png' }, 17 | { name: 'card5', img: 'images/success.png' }, 18 | { name: 'card5', img: 'images/success.png' }, 19 | // ...add more pairs as needed 20 | ]; 21 | 22 | function shuffle(array) { 23 | array.sort(() => 0.5 - Math.random()); 24 | } 25 | 26 | function createBoard() { 27 | shuffle(cardArray); 28 | grid.innerHTML = ''; 29 | cardsWon = []; 30 | 31 | for (let i = 0; i < cardArray.length; i++) { 32 | const card = document.createElement('img'); 33 | card.setAttribute('src', 'images/blank.png'); 34 | card.setAttribute('data-id', i); 35 | card.addEventListener('click', flipCard); 36 | grid.appendChild(card); 37 | } 38 | } 39 | 40 | function flipCard() { 41 | let cardId = this.getAttribute('data-id'); 42 | if (!cardsChosenId.includes(cardId)) { 43 | cardsChosen.push(cardArray[cardId].name); 44 | cardsChosenId.push(cardId); 45 | this.setAttribute('src', cardArray[cardId].img); 46 | if (cardsChosen.length === 2) { 47 | setTimeout(checkForMatch, 500); 48 | } 49 | } 50 | } 51 | 52 | function checkForMatch() { 53 | const cards = document.querySelectorAll('#game-board img'); 54 | const firstCardId = cardsChosenId[0]; 55 | const secondCardId = cardsChosenId[1]; 56 | 57 | if (cardsChosen[0] === cardsChosen[1] && firstCardId !== secondCardId) { 58 | cards[firstCardId].style.visibility = 'hidden'; 59 | cards[secondCardId].style.visibility = 'hidden'; 60 | cards[firstCardId].removeEventListener('click', flipCard); 61 | cards[secondCardId].removeEventListener('click', flipCard); 62 | cardsWon.push(cardsChosen); 63 | } else { 64 | cards[firstCardId].setAttribute('src', 'images/blank.png'); 65 | cards[secondCardId].setAttribute('src', 'images/blank.png'); 66 | } 67 | 68 | cardsChosen = []; 69 | cardsChosenId = []; 70 | 71 | if (cardsWon.length === cardArray.length / 2) { 72 | alert('Congratulations! You found them all!'); 73 | } 74 | } 75 | 76 | startButton.addEventListener('click', createBoard); 77 | }); 78 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Roboto', sans-serif; 3 | background-color: #282c34; 4 | color: #ffffff; 5 | text-align: center; 6 | margin: 0; 7 | padding: 0; 8 | } 9 | 10 | .container { 11 | width: auto; 12 | margin: 40px auto; 13 | padding: 30px; 14 | background-color: #3c404d; 15 | box-shadow: 0 10px 20px rgba(0, 0, 0, 0.25); 16 | border-radius: 15px; 17 | } 18 | 19 | h1 { 20 | color: white; 21 | } 22 | 23 | .instructions { 24 | font-size: 20px; 25 | margin-bottom: 30px; 26 | color: #adbac7; 27 | } 28 | 29 | #game-board { 30 | display: grid; 31 | grid-template-columns: repeat(5, 1fr); 32 | grid-template-rows: repeat(2, 1fr); 33 | gap: 20px; 34 | justify-content: center; 35 | padding: 20px; 36 | } 37 | 38 | .card { 39 | width: 211.8px; 40 | height: 166.2px; 41 | background-color: #565c6f; 42 | border-radius: 10px; 43 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); 44 | cursor: pointer; 45 | display: flex; 46 | align-items: center; 47 | justify-content: center; 48 | overflow: hidden; 49 | } 50 | 51 | .card img { 52 | width: 100%; 53 | height: auto; 54 | visibility: hidden; /* Hide images by default */ 55 | display: block; 56 | } 57 | 58 | .card.show img { 59 | visibility: visible; /* Show image when card is flipped */ 60 | } 61 | 62 | #start-game { 63 | background-color: #4caf50; 64 | color: white; 65 | padding: 12px 24px; 66 | border: none; 67 | border-radius: 5px; 68 | cursor: pointer; 69 | font-size: 18px; 70 | transition: background-color 0.3s, transform 0.3s; 71 | } 72 | 73 | #start-game:hover { 74 | background-color: #43a047; /* Darker on hover */ 75 | transform: scale(1.05); /* Slightly enlarges on hover */ 76 | } 77 | --------------------------------------------------------------------------------