diff --git a/.DS_Store b/.DS_Store index 582eb05131..32591e8c5b 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.github/CONTRIBUTING_GUIDELINE.md b/.github/CONTRIBUTING_GUIDELINE.md index db19b5a2b2..86cd10f12e 100644 --- a/.github/CONTRIBUTING_GUIDELINE.md +++ b/.github/CONTRIBUTING_GUIDELINE.md @@ -24,6 +24,43 @@ in case you are stuck:
+### Alternatively contribute using GitHub Desktop + +1. **Open GitHub Desktop:** + Launch GitHub Desktop and log in to your GitHub account if you haven't already. + +2. **Clone the Repository:** + - If you haven't cloned the GameZone repository yet, you can do so by clicking on the "File" menu and selecting "Clone Repository." + - Choose the GameZone repository from the list of repositories on GitHub and clone it to your local machine. + +3. **Switch to the Correct Branch:** + - Ensure you are on the branch that you want to submit a pull request for. + - If you need to switch branches, you can do so by clicking on the "Current Branch" dropdown menu and selecting the desired branch. + +4. **Make Changes:** + Make your changes to the code or files in the repository using your preferred code editor. + +5. **Commit Changes:** + - In GitHub Desktop, you'll see a list of the files you've changed. Check the box next to each file you want to include in the commit. + - Enter a summary and description for your changes in the "Summary" and "Description" fields, respectively. Click the "Commit to " button to commit your changes to the local branch. + +6. **Push Changes to GitHub:** + After committing your changes, click the "Push origin" button in the top right corner of GitHub Desktop to push your changes to your forked repository on GitHub. + +7. **Create a Pull Request:** + - Go to the GitHub website and navigate to your fork of the GameZone repository. + - You should see a button to "Compare & pull request" between your fork and the original repository. Click on it. + +8. **Review and Submit:** + - On the pull request page, review your changes and add any additional information, such as a title and description, that you want to include with your pull request. + - Once you're satisfied, click the "Create pull request" button to submit your pull request. + +9. **Wait for Review:** + Your pull request will now be available for review by the project maintainers. They may provide feedback or ask for changes before merging your pull request into the main branch of the GameZone repository. + +⭐️ Support the Project +If you find this project helpful, please consider giving it a star on GitHub! Your support helps to grow the project and reach more contributors. + ## **Issue Report Process 📌** 1. Go to the project's issues. @@ -36,17 +73,48 @@ in case you are stuck:
## **File naming conventions 📁** -- Give unique name for your game that is not already existed +- Give unique name for your game that don't exist already. * Folder naming convention - - ```Game_Name``` ex. ```Tilting_Maze``` (first letter should be capital and if you need space use _ ) + - ```Game_Name``` ex. ```Tilting_Maze```,```Rock_Paper_Scissors``` (first letter should be capital and if you need space use underscore **_** ) * files in the folder - - ```index.html``` , ```script.js``` , ```style.css```(not stictly to follow this but you should have separate ) + - Main html file should be named as **index.html** , not something else like ```Tilting_Maze.html```(Preferred) + - Game files - ```index.html``` , ```script.js``` , ```style.css```(not stictly to follow this but you should have separate file for each kind) + - It is preferred if the main html file is directly added to the main folder of you game like ```Tilting_Maze/index.html``` along with other files like **style.css**, **script.js** - you can have other folders if you are having assets for your game - - ```README.md``` for your folder using template [TEMPLATE](../Games/FOLDER_README_TEMPLATE.md) - - It is not compulsory to follow this README template only you can have your own + - Create```README.md``` for your Game using this [TEMPLATE](../Games/FOLDER_README_TEMPLATE.md).Although, it is not compulsory to follow this README template ,you can use your own *README* template whichever you prefer, to explain functionality and code of your Game * naming convention for the screenshot you will add in ```assets/images``` - - name of image should be same as your game name - - ex. ```Tilting_Maze.jpeg``` or .jpg or .png any of the image formate + - Remember preview image should be in ```assets/images``` and not in main folder of Game itself. + - Name of image should be same as your Game name + - ex. ```Tilting_Maze.jpeg``` or .jpg or .png any of the image format, but don't add image format in the name itself , it is self-assigned to a image, you don't need to add it manually, otherwise it becomes ```Tilting_Maze.jpeg.jpeg``` + - There should be only one ScreenShot of the game in ```assets/images``` and that too with same name as the Game (Exactly Same). +* Note:-All Other data except the ScreenShot of your Game, should be in it's main folder , don't add it to other folders of the project. + +
+ +## Add Game to assets/js/gamesData.json + +* This is to Show your game on the main Website + - Go to the end of gamesData.json and add : + - **,** + " **No.** ":{ + "gameTitle" : " **Title** ", + "gameUrl": " **Main Folder** ", + "thumbnailUrl":" **Preview Image** " + } + - **No.**: Number for your Game , it should be the next number with respect to the file. eg: if the last no. in file at present is *625* you should put *626* at the place of **No.** + - **Title:** this is the title for your game that will be shown on the website, if your game name is ```Super_Mario_Game``` ,put Title as ```Super Mario Game``` + - **Main Folder :** This is the reference to *index.html* + - if your index.html is directly in main game folder ,put the main folder name eg: ```Super_Mario_Game``` + - if your index.html is in subfolder , give path to it + eg: ```Super_Mario_Game/public``` (assuming index.html is in public folder of Super_Mario_Game folder) + - if your main html file's name is not index.html , you need to specify the main html file also. eg:```Super_Mario_Game/mario.html``` or if in sub folder ```Super_Mario_Game/public/mario.html``` + - **Preview Image:** This is the image that will be shown as preview for your game , here you provide the name of the image that you added to **assets/images** folder, along with format type. Eg. ```Super_Mario_Game.png``` or ```Super_Mario_Game.jpg``` or with any other format. + +**Note:-** + + - Do not modify anything else in the rest of the file, you only need to add your game in the end of the file. + - Don't forget to add the comma for new entry (already give in above sample but this is a reminder as one might miss it to see in the sample) +
@@ -54,11 +122,13 @@ in case you are stuck: 1. Ensure that you have self reviewed your code 😀 2. Make sure you have added the proper description for the functionality of the code -3. You have added README file in your repository . -4. You have added the thumbnail of the project into ```assets/images``` for website preview -5. Add your game screenshot in the assets folder by following the proper conversion specified over here -6. You have added your game name and link in main README.md -7. Submit your PR by giving the necesarry information in PR template and hang tight we will review it really soon 🚀 +3. You have added README file in your Game folder. +4. You have added the thumbnail of the project/Game into ```assets/images``` for website preview +5. Added your game screenshot in the assets folder by following the proper conversion specified over here +6. You have added your game name and link in GameZone's README.md +7. You have Added your game to ```assets\js\gamesData.json```. +8. you have reviewed that your Game loads on the website with preview image and works when opened. +9. Submit your PR by giving the necesarry information in PR template and hang tight we will review it really soon 🚀
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3c364b3fb2..20bc5bbfdb 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -15,10 +15,11 @@ Fixes # - [ ] My changes generates no new warnings. - [ ] I have followed proper naming convention showed in [CONTRIBUTING GUIDELINE](https://github.com/kunjgit/GameZone/blob/main/.github/CONTRIBUTING_GUIDELINE.md) - [ ] I have added screenshot for website preview in assets/images -- [ ] I have added entries for my game in main README.md -- [ ] I have added README.md in my folder +- [ ] I have added entries for my game in GameZone's README.md +- [ ] I have added README.md in my Game folder - [ ] I have added working video of the game in README.md (optional) - [ ] I have specified the respective issue number for which I have requested the new game. +- [ ] I have added my Game to gamesData.json file and it is loading properly on main website as intended.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 860bc55dac..6f922535fc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -73,29 +73,60 @@ If you find this project helpful, please consider giving it a star on GitHub! Yo
## **File naming conventions 📁** -- Give unique name for your game that is not already existed +- Give unique name for your game that don't exist already. * Folder naming convention - - ```Game_Name``` ex. ```Tilting_Maze``` (first letter should be capital and if you need space use _ ) + - ```Game_Name``` ex. ```Tilting_Maze```,```Rock_Paper_Scissors``` (first letter should be capital and if you need space use underscore **_** ) * files in the folder - - ```index.html``` , ```script.js``` , ```style.css```(not stictly to follow this but you should have separate ) + - Main html file should be named as **index.html** , not something else like ```Tilting_Maze.html```(Preferred) + - Game files - ```index.html``` , ```script.js``` , ```style.css```(not stictly to follow this but you should have separate file for each kind) + - It is preferred if the main html file is directly added to the main folder of you game like ```Tilting_Maze/index.html``` along with other files like **style.css**, **script.js** - you can have other folders if you are having assets for your game - - ```README.md``` for your folder using template [TEMPLATE](../Games/FOLDER_README_TEMPLATE.md) - - It is not compulsory to follow this README template only you can have your own + - Create```README.md``` for your Game using this [TEMPLATE](../Games/FOLDER_README_TEMPLATE.md).Although, it is not compulsory to follow this README template ,you can use your own *README* template whichever you prefer, to explain functionality and code of your Game * naming convention for the screenshot you will add in ```assets/images``` - - name of image should be same as your game name - - ex. ```Tilting_Maze.jpeg``` or .jpg or .png any of the image formate + - Remember preview image should be in ```assets/images``` and not in main folder of Game itself. + - Name of image should be same as your Game name + - ex. ```Tilting_Maze.jpeg``` or .jpg or .png any of the image format, but don't add image format in the name itself , it is self-assigned to a image, you don't need to add it manually, otherwise it becomes ```Tilting_Maze.jpeg.jpeg``` + - There should be only one ScreenShot of the game in ```assets/images``` and that too with same name as the Game (Exactly Same). +* Note:-All Other data except the ScreenShot of your Game, should be in it's main folder , don't add it to other folders of the project.
+ +## Add Game to assets/js/gamesData.json + +* This is to Show your game on the main Website + - Go to the end of gamesData.json and add : + - **,** + " **No.** ":{ + "gameTitle" : " **Title** ", + "gameUrl": " **Main Folder** ", + "thumbnailUrl":" **Preview Image** " + } + - **No.**: Number for your Game , it should be the next number with respect to the file. eg: if the last no. in file at present is *625* you should put *626* at the place of **No.** + - **Title:** this is the title for your game that will be shown on the website, if your game name is ```Super_Mario_Game``` ,put Title as ```Super Mario Game``` + - **Main Folder :** This is the reference to *index.html* + - if your index.html is directly in main game folder ,put the main folder name eg: ```Super_Mario_Game``` + - if your index.html is in subfolder , give path to it + eg: ```Super_Mario_Game/public``` (assuming index.html is in public folder of Super_Mario_Game folder) + - if your main html file's name is not index.html , you need to specify the main html file also. eg:```Super_Mario_Game/mario.html``` or if in sub folder ```Super_Mario_Game/public/mario.html``` + - **Preview Image:** This is the image that will be shown as preview for your game , here you provide the name of the image that you added to **assets/images** folder, along with format type. Eg. ```Super_Mario_Game.png``` or ```Super_Mario_Game.jpg``` or with any other format. + +**Note:-** + + - Do not modify anything else in the rest of the file, you only need to add your game in the end of the file. + - Don't forget to add the comma for new entry (already give in above sample but this is a reminder as one might miss it to see in the sample) +
## **Pull Request Process 🚀** 1. Ensure that you have self reviewed your code 😀 2. Make sure you have added the proper description for the functionality of the code -3. You have added README file in your repository . -4. You have added the thumbnail of the project into ```assets/images``` for website preview -5. Add your game screenshot in the assets folder by following the proper conversion specified over here -6. You have added your game name and link in main README.md -7. Submit your PR by giving the necesarry information in PR template and hang tight we will review it really soon 🚀 +3. You have added README file in your Game folder. +4. You have added the thumbnail of the project/Game into ```assets/images``` for website preview +5. Added your game screenshot in the assets folder by following the proper conversion specified over here +6. You have added your game name and link in GameZone's README.md +7. You have Added your game to ```assets\js\gamesData.json```. +8. you have reviewed that your Game loads on the website with preview image and works when opened. +9. Submit your PR by giving the necesarry information in PR template and hang tight we will review it really soon 🚀
diff --git a/Games/.DS_Store b/Games/.DS_Store index 2446c112bf..442634d4c6 100644 Binary files a/Games/.DS_Store and b/Games/.DS_Store differ diff --git a/Games/1icon.png b/Games/1icon.png deleted file mode 100644 index 821142c96f..0000000000 Binary files a/Games/1icon.png and /dev/null differ diff --git a/Games/2048_win/script.js b/Games/2048_win/script.js index 04aab052b8..1545915c32 100644 --- a/Games/2048_win/script.js +++ b/Games/2048_win/script.js @@ -51,14 +51,17 @@ function cellCreator(c, timeOut) { } var randomValue = Math.floor(Math.random() * 4 + 1); //create value 1, 2, 3 or 4 + if (randomValue == 2){ + randomValue =2; + } if (randomValue == 3) { - randomValue = 2; + randomValue = 4; } //3 --> 4 if (randomValue == 1) { randomValue = 2; } //1 --> 2 if (randomValue == 4) { - randomValue = 2; + randomValue = 4; } //4-->2 var position = document.getElementById("" + randomX + randomY); var tile = document.createElement("DIV"); //create div at x, y diff --git a/Games/Alien_Invasion/asset/Macbook-Air.png b/Games/Alien_Invasion/asset/Macbook-Air.png new file mode 100644 index 0000000000..a1fa56b1d8 Binary files /dev/null and b/Games/Alien_Invasion/asset/Macbook-Air.png differ diff --git a/Games/Alien_Invasion/asset/Mobile.png b/Games/Alien_Invasion/asset/Mobile.png new file mode 100644 index 0000000000..8c0ec401ec Binary files /dev/null and b/Games/Alien_Invasion/asset/Mobile.png differ diff --git a/Games/Alien_Invasion/asset/iPad-PRO-11.png b/Games/Alien_Invasion/asset/iPad-PRO-11.png new file mode 100644 index 0000000000..4040d94f1a Binary files /dev/null and b/Games/Alien_Invasion/asset/iPad-PRO-11.png differ diff --git a/Games/Alien_Invasion/index.html b/Games/Alien_Invasion/index.html index 760bb1af1b..cbb245a886 100644 --- a/Games/Alien_Invasion/index.html +++ b/Games/Alien_Invasion/index.html @@ -1,44 +1,18 @@ - - - - AttackAlienInvader Game - - - + + Bubble Shooter Game - - - - - - - - - - - - +
+
Score: 0
+
+ +
+ - - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/Games/Alien_Invasion/script.js b/Games/Alien_Invasion/script.js index 5e50da0a0c..b905db022b 100644 --- a/Games/Alien_Invasion/script.js +++ b/Games/Alien_Invasion/script.js @@ -1,543 +1,70 @@ -window.addEventListener('load', function () { - //canvas setup - const canvas = document.getElementById('canvas1'); - const ctx = canvas.getContext('2d'); - canvas.width = 1000; - canvas.height = 500; - - class InputHandler { - constructor(game) { - this.game = game; - window.addEventListener('keydown', e => { - if (((e.key === 'ArrowUp') || - (e.key === 'ArrowDown') - ) && this.game.keys.indexOf(e.key) === - 1) { - this.game.keys.push(e.key); - } else if (e.key === ' ') { - this.game.player.shootTop(); - } else if (e.key === 'd') { - this.game.debug = !this.game.debug; - } - }); - window.addEventListener('keyup', e => { - if (this.game.keys.indexOf(e.key) > -1) { - this.game.keys.splice(this.game.keys.indexOf(e.key), 1); - } - }); - } - } - - class Projectile { - constructor(game, x, y) { - this.game = game; - this.x = x; - this.y = y; - this.width = 10; - this.height = 3; - this.speed = 3; - this.markedForDeletion = false; - this.image = document.getElementById('projectile'); - } - update() { - this.x += this.speed; - if (this.x > this.game.width * 0.8) this.markedForDeletion = true; - } - draw(context) { - context.drawImage(this.image, this.x, this.y); - } - } - - class Particle { - constructor(game, x, y) { - this.game = game; - this.x = x; - this.y = y; - this.image = document.getElementById('gears'); - this.frameX = Math.floor(Math.random() * 3); - this.frameY = Math.floor(Math.random() * 3); - this.spriteSize = 50; - this.sizeModifier = (Math.random() * 0.5 + 0.5).toFixed(1); - this.size = this.spriteSize * this.sizeModifier; - this.speedX = Math.random() * 6 - 3; - this.speedY = Math.random() * -15; - this.gravity = 0.5; - this.markedForDeletion = false; - this.angle = 0; - this.va = Math.random() * 0.2 - 0.1; - this.bounced = 0; - this.bottomBounceBoundary = Math.random() * 80 + 60; - } - update() { - this.angle += this.va; - this.speedY += this.gravity; - this.x -= this.speedX - this.game.speed; - this.y += this.speedY; - if (this.y > this.game.height + this.size || this.x < 0 - this.size) this.markedForDeletion = true; - if (this.y > this.game.height - this.bottomBounceBoundary && this.bounced < 5) { - this.bounced++; - this.speedY *= -0.7; - } - } - draw(context) { - context.save(); - context.translate(this.x, this.y); - context.rotate(this.angle); - context.drawImage(this.image, this.frameX * this.spriteSize, - this.frameY * this.spriteSize, this.spriteSize, this.spriteSize, this.size * -0.5, - this.size * -0.5, this.size, this.size); - context.restore(); - } - } - - class Player { - constructor(game) { - this.game = game; - this.width = 120; - this.height = 190; - this.x = 20; - this.y = 100; - this.frameX = 0; - this.frameY = 0; - this.maxFrame = 37; - this.speedY = 0; - this.maxSpeed = 3; - this.projectiles = []; - this.image = document.getElementById('player'); - this.powerUp = false; - this.powerUpTimer = 0; - this.powerUpLimit = 10000; - } - update(deltaTime) { - if (this.game.keys.includes('ArrowUp')) this.speedY = -this.maxSpeed; - else if (this.game.keys.includes('ArrowDown')) this.speedY = this.maxSpeed; - else this.speedY = 0; - this.y += this.speedY; - // vertical boundaries - if (this.y > this.game.height - this.height * 0.5) this.y = this.game.height - this.height * 0.5; - else if (this.y < -this.height * 0.5) this.y - this.height * 0.5; - //handle projectiles - this.projectiles.forEach(projectile => { - projectile.update(); - }); - this.projectiles = this.projectiles.filter(projectile => !projectile.markedForDeletion); - //sprite animation - if (this.frameX < this.maxFrame) { - this.frameX++; - } else { - this.frameX = 0; +document.addEventListener("DOMContentLoaded", function() { + const gameArea = document.getElementById('game-area'); + const scoreDisplay = document.getElementById('score-value'); + const restartButton = document.getElementById('restart-btn'); + let score = 0; + let gameEnded = false; + + // Function to generate a random bubble + function createBubble() { + if (gameEnded) return; // Exit if game has ended + + const colors = ['red', 'green', 'blue', 'orange', 'yellow', 'purple']; + const randomColor = colors[Math.floor(Math.random() * colors.length)]; + const bubble = document.createElement('div'); + bubble.className = `bubble ${randomColor}`; + + // Set initial position at the bottom randomly + bubble.style.left = `${Math.random() * (gameArea.clientWidth - 30)}px`; + bubble.style.top = `${gameArea.clientHeight}px`; + + gameArea.appendChild(bubble); + + // Move the bubble upwards + let bubbleInterval = setInterval(function() { + bubble.style.top = `${parseInt(bubble.style.top) - 1}px`; + + // Check if bubble reaches the top of the game area + if (parseInt(bubble.style.top) <= 0) { + clearInterval(bubbleInterval); + gameArea.removeChild(bubble); + endGame(); } - // power up - if (this.powerUp) { - if (this.powerUpTimer > this.powerUpLimit) { - this.powerUpTimer = 0; - this.powerUp = false; - this.frameY = 0; - } else { - this.powerUpTimer += deltaTime; - this.frameY = 1; - this.game.ammo += 0.1; - } - } - } - draw(context) { - if (this.game.debug) context.strokeRect(this.x, this.y, this.width, this.height); - this.projectiles.forEach(projectile => { - projectile.draw(context); - }); - context.drawImage(this.image, this.frameX * this.width, this.frameY * this.height, this.width, this.height, this.x, this.y, this.width, this.height); - - } - shootTop() { - if (this.game.ammo > 0) { - this.projectiles.push(new Projectile(this.game, this.x + 80, this.y + 30)); - this.game.ammo--; - } - if (this.powerUp) this.shootBottom(); - } - shootBottom() { - if (this.game.ammo > 0) { - this.projectiles.push(new Projectile(this.game, this.x + 80, this.y + 175)); - } - } - - enterPowerUp() { - this.powerUpTimer = 0; - this.powerUp = true; - if (this.game.ammo < this.game.maxAmmo) this.game.ammo = this.game.maxAmmo; - } - } - class Enemy { - constructor(game) { - this.game = game; - this.x = this.game.width; - this.speedX = Math.random() * -1.5 - 0.5; - this.markedForDeletion = false; - this.frameX = 0; - this.frameY = 0; - this.maxFrame = 37; - } - update() { - this.x += this.speedX - this.game.speed; - if (this.x + this.width < 0) this.markedForDeletion = true; - // sprite animation - if (this.frameX < this.maxFrame) { - this.frameX++; - } else this.frameX = 0; - } - draw(context) { - if (this.game.debug) context.strokeRect(this.x, this.y, this.width, this.height); - context.drawImage(this.image, this.frameX * this.width, this.frameY * this.height, this.width, this.height, this.x, this.y, this.width, this.height); - if (this.game.debug) { - context.font = '20px Bangers'; - context.fillText(this.lives, this.x, this.y); + }, 10); + + // Handle click on bubble + bubble.addEventListener('click', function() { + if (!bubble.clicked) { + bubble.clicked = true; + clearInterval(bubbleInterval); + gameArea.removeChild(bubble); + score += 10; + scoreDisplay.textContent = score; } - } - } - class Angler1 extends Enemy { - constructor(game) { - super(game); - this.width = 228; - this.height = 169; - this.y = Math.random() * (this.game.height * 0.95 - this.height); - this.image = document.getElementById('angler1'); - this.frameY = Math.floor(Math.random() * 3); - this.lives = 5; - this.score = this.lives; - } - - } - class Angler2 extends Enemy { - constructor(game) { - super(game); - this.width = 213; - this.height = 165; - this.y = Math.random() * (this.game.height * 0.95 - this.height); - this.image = document.getElementById('angler2'); - this.frameY = Math.floor(Math.random() * 2); - this.lives = 6; - this.score = this.lives; - } - - } - - class LuckyFish extends Enemy { - constructor(game) { - super(game); - this.width = 99; - this.height = 95; - this.y = Math.random() * (this.game.height * 0.95 - this.height); - this.image = document.getElementById('lucky'); - this.frameY = Math.floor(Math.random() * 2); - this.lives = 5; - this.score = 15; - this.type = 'lucky' - } - } - - class HiveWhale extends Enemy { - constructor(game) { - super(game); - this.width = 400; - this.height = 227; - this.y = Math.random() * (this.game.height * 0.95 - this.height); - this.image = document.getElementById('hivewhale'); - this.frameY = 0; - this.lives = 20; - this.score = this.lives; - this.type = 'hive'; - this.speedX = Math.random() * -1.2 - 0.2; - } - } - - class Drone extends Enemy { - constructor(game, x, y) { - super(game); - this.width = 115; - this.height = 95; - this.x = x; - this.y = y; - this.image = document.getElementById('drone'); - this.frameY = Math.floor(Math.random() * 2); - this.lives = 3; - this.score = this.lives; - this.type = 'drone'; - this.speedX = Math.random() * -4.2 - 0.5; - } - } - - - class Layer { - constructor(game, image, speedModifier) { - this.game = game; - this.image = image; - this.speedModifier = speedModifier; - this.width = 1768; - this.height = 500; - this.x = 0; - this.y = 0; - } - update() { - if (this.x <= -this.width) this.x = 0; - this.x -= this.game.speed * this.speedModifier; - } - draw(context) { - context.drawImage(this.image, this.x, this.y); - context.drawImage(this.image, this.x + this.width, this.y); - } - } - - class Background { - constructor(game) { - this.game = game; - this.image1 = document.getElementById('layer1'); - this.image2 = document.getElementById('layer2'); - this.image3 = document.getElementById('layer3'); - this.image4 = document.getElementById('layer4'); - this.layer1 = new Layer(this.game, this.image1, 0.2); - this.layer2 = new Layer(this.game, this.image2, 0.4); - this.layer3 = new Layer(this.game, this.image3, 1); - this.layer4 = new Layer(this.game, this.image4, 1.5); - this.layers = [this.layer1, this.layer2, this.layer3, this.layer4]; - } - update() { - this.layers.forEach(layer => layer.update()); - } - draw(context) { - this.layers.forEach(layer => layer.draw(context)); - } - - } - - class Explosion { - constructor(game, x, y) { - this.game = game; - this.frameX = 0; - this.spriteWidth = 200; - this.spriteHeight = 200; - this.width = this.spriteWidth; - this.height = this.spriteHeight; - this.x = x - this.width * 0.5; - this.y = y - this.height * 0.5; - this.fps = 30; - this.time = 0; - this.interval = 1000 / this.fps; - this.markedForDeletion = false; - this.maxFrame = 8; - } - update(deltaTime) { - this.x -= this.game.speed; - if (this.timer > this.interval) { - this.frameX++; - this.timer = 0; - } else { - this.timer += deltaTime; - } - if (this.frameX > this.maxFrame) this.markedForDeletion = true; - } - draw(context) { - context.drawImage(this.image, this.frameX * this.spriteWidth, 0, this.spriteWidth, - this.spriteHeight, this.x, this.y, this.width, this.height); - } - } - - class SmokeExplosion extends Explosion { - constructor(game, x, y) { - super(game, x, y); - this.image = document.getElementById('smokeExplosion'); - } - } - - class FireExplosion extends Explosion { - constructor(game, x, y) { - super(game, x, y); - this.image = document.getElementById('fireExplosion'); - } - } - - - class UI { - constructor(game) { - this.game = game; - this.fontSize = 25; - this.fontFamily = 'Bangers'; - this.color = 'yellow'; - } - draw(context) { - context.save(); - context.fillStyle = this.color; - context.shadowOffsetX = 2; - context.shadowOffsetY = 2; - context.shadowColor = 'black'; - context.font = this.fontSize + 'px' + this.fontFamily; - //score - context.font = '20px Bangers'; - context.fillText('Score: ' + this.game.score, 20, 40); - - //timer - const formattedTime = (this.game.gameTime * 0.001).toFixed(1); - context.font = '20px Bangers'; - context.fillText('Timer:' + formattedTime, 20, 100); - - //game over messages - if (this.game.gameOver) { - context.textAlign = 'center'; - let message1; - let message2; - if (this.game.score > this.game.winningScore) { - message1 = 'Most Wondrous!'; - message2 = 'Well Done explorer!'; - } else { - message1 = 'Blazes!'; - message2 = 'Get my repair kit and try again!'; - } - context.font = '50px Bangers'; - context.fillText(message1, this.game.width * 0.5, this.game.height * 0.5 - 20); - context.font = '25px Bangers'; - context.fillText(message2, this.game.width * 0.5, this.game.height * 0.5 + 20); - } - //ammo - if (this.game.player.powerUp) context.fillStyle = '#ffffbd'; - for (let i = 0; i < this.game.ammo; i++) { - context.fillRect(20 + 5 * i, 50, 3, 20); - } - context.restore(); - } - } - class Game { - constructor(width, height) { - this.width = width; - this.height = height; - this.background = new Background(this); - this.player = new Player(this); - this.input = new InputHandler(this); - this.ui = new UI(this); - this.keys = []; - this.enemies = []; - this.particles = []; - this.explosions = []; - this.enemyTimer = 0; - this.enemyInterval = 2000; - this.ammo = 20; - this.maxAmmo = 50; - this.ammoTimer = 0; - this.ammoInterval = 350; - this.gameOver = false; - this.score = 0; - this.winningScore = 80; - this.gameTime = 0; - this.timeLimit = 30000; - this.speed = 1; - this.debug = false; - - } - update(deltaTime) { - if (!this.gameOver) this.gameTime += deltaTime; - if (this.gameTime > this.timeLimit) this.gameOver = true; - this.background.update(); - this.background.layer4.update(); - this.player.update(deltaTime); - if (this.ammoTimer > this.ammoInterval) { - if (this.ammo < this.maxAmmo) this.ammo++; - this.ammoTimer = 0; - } else { - this.ammoTimer += deltaTime; - } - this.particles.forEach(particle => particle.update()); - this.particles = this.particles.filter(particle => !particle.markedForDeletion); - this.explosions.forEach(explosion => explosion.update(deltaTime)); - this.explosions = this.explosions.filter(explosion => !explosion.markedForDeletion); - this.enemies.forEach(enemy => { - enemy.update(); - if (this.checkCollision(this.player, enemy)) { - enemy.markedForDeletion = true; - this.addExplosion(enemy); - for (let i = 0; i < enemy.score; i++) { - this.particles.push(new Particle(this, enemy.x + enemy.width * 0.5, enemy.y + enemy.height * 0.5)); - } - if (enemy.type === 'lucky') this.player.enterPowerUp(); - else if (!this.gameOver) this.score--; - } - this.player.projectiles.forEach(projectile => { - if (this.checkCollision(projectile, enemy)) { - enemy.lives--; - projectile.markedForDeletion = true; - this.particles.push(new Particle(this, enemy.x + enemy.width * 0.5, enemy.y + enemy.height * 0.5)); - if (enemy.lives <= 0) { - for (let i = 0; i < enemy.score; i++) { - this.particles.push(new Particle(this, enemy.x + enemy.width * 0.5, enemy.y + enemy.height * 0.5)); - } - enemy.markedForDeletion = true; - this.addExplosion(enemy); - if (enemy.type === 'hive') { - for (let i = 0; i < 5; i++) { - this.enemies.push(new Drone(this, enemy.x + Math.random() * enemy.width, - enemy.y + Math.random() * enemy.height + 0.5)); - } - } - if (!this.gameOver) this.score += enemy.score; - /*if (this.score > this.winningScore) this.gameOver = true;*/ - } - } - }); - }); - this.enemies = this.enemies.filter(enemy => !enemy.markedForDeletion); - if (this.enemyTimer > this.enemyInterval && !this.gameOver) { - this.addEnemy(); - this.enemyTimer = 0; - } else { - this.enemyTimer += deltaTime; - } - } - draw(context) { - this.background.draw(context); - this.ui.draw(context); - this.player.draw(context); - this.particles.forEach(particle => particle.draw(context)); - this.enemies.forEach(enemy => { - enemy.draw(context); - }); - this.explosions.forEach(explosion => { - explosion.draw(context); - }); - this.background.layer4.draw(context); - } - addEnemy() { - const randomize = Math.random(); - if (randomize < 0.3) this.enemies.push(new Angler1(this)); - else if (randomize < 0.6) this.enemies.push(new Angler2(this)); - else if (randomize < 0.7) this.enemies.push(new HiveWhale(this)); - else this.enemies.push(new LuckyFish(this)); - } - addExplosion(enemy) { - const randomize = Math.random(); - if (randomize < 0.5) { - this.explosions.push(new SmokeExplosion(this, enemy.x + enemy.width * 0.5, enemy.y + enemy.height * 0.5)); - } - else { - this.explosions.push(new FireExplosion(this, enemy.x + enemy.width * 0.5, enemy.y + enemy.height * 0.5)); - } - } - checkCollision(rect1, rect2) { - return (rect1.x < rect2.x + rect2.width && - rect1.x + rect1.width > rect2.x && - rect1.y < rect2.y + rect2.height && - rect1.height + rect1.y > rect2.y) - } - - } - - const game = new Game(canvas.width, canvas.height); - let lastTime = 0; - //animation loop - function animate(timeStamp) { - const deltaTime = timeStamp - lastTime; - console.log(deltaTime); - lastTime = timeStamp; - ctx.clearRect(0, 0, canvas.width, canvas.height); - game.draw(ctx); - game.update(deltaTime); - requestAnimationFrame(animate); - } - animate(0); + }); + } + + // Function to end the game + function endGame() { + gameEnded = true; + alert(`Game Over! Your score is ${score}`); + removeAllBubbles(); // Remove all remaining bubbles when game ends + } + + // Function to remove all bubbles from game area + function removeAllBubbles() { + const bubbles = document.querySelectorAll('.bubble'); + bubbles.forEach(bubble => gameArea.removeChild(bubble)); + } + + // Generate bubbles every 2 seconds + setInterval(createBubble, 2000); + + // Event listener for restart button + restartButton.addEventListener('click', function() { + removeAllBubbles(); // Remove all bubbles before restarting + score = 0; + scoreDisplay.textContent = score; + gameEnded = false; + }); }); - diff --git a/Games/Alien_Invasion/style.css b/Games/Alien_Invasion/style.css index 268a5f3b93..f705373767 100644 --- a/Games/Alien_Invasion/style.css +++ b/Games/Alien_Invasion/style.css @@ -1,34 +1,61 @@ -* { +body { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; margin: 0; - padding: 0; - box-sizing: border-box; + background-color: #f0f0f0; } -#canvas1 { - border: 5px solid black; +#game-container { + text-align: center; + background-color: #fff; + border: 1px solid #ccc; + padding: 20px; + max-width: 800px; + width: 90%; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +#game-area { + width: 100%; + max-height: 600px; + height: 90vh; + background-color: #e0e0e0; + position: relative; + overflow: hidden; +} +#score{ + font-family: monospace; + font-weight: 600; + font-size: 1.3rem; + margin: 1rem; +} +.bubble { + width: 30px; + height: 30px; + border-radius: 50%; position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - background: #4d79bc; - max-width: 100%; - max-height: 100%; - font-family: 'Bangers', cursive; + cursor: pointer; } -#layer1, -#layer2, -#layer3, -#layer4, -#player, -#angler1, -#angler2, -#lucky, -#projectile, -#gears, -#hivewhale, -#drone, -#smokeExplosion, -#fireExplosion { - display: none; -} \ No newline at end of file +button{ + padding: 0.8rem 3rem; + background: black; + margin: 0.5rem; + border: 2px solid transparent; + border-radius: 0.6rem; + font-weight: 700; + color: white; +} +button:hover{ + background: transparent; + color: black; + border: 2px solid black; +} +.red { background-color: red; } +.green { background-color: green; } +.blue { background-color: blue; } +.orange { background-color: orange; } +.yellow { background-color: yellow; } +.purple { background-color: purple; } diff --git a/Games/Align_4_Game/Readme.md b/Games/Align_4_Game/Readme.md new file mode 100644 index 0000000000..635478339c --- /dev/null +++ b/Games/Align_4_Game/Readme.md @@ -0,0 +1,30 @@ +# **ALIEN_SHOOTERS** + +--- + +
+ +## **Description 📃** +- The logic of the game is basically there is computer and player so we are the player the main task of the player is to stop computer to align 4 balls horizontally or vertically or zigzagcally straight order. + + +## **functionalities 🎮** +- Easy to play +- Scoring system so that you can compare points with computer. +- Responsive design for most of the monitors. +
+ +## **How to play? 🕹️** +- Start the game by clicking on start and then press the grid. +- Your aim is to stop the computer to making or aligning 4 balls in a line . +
+ +## **Screenshots 📸** + +
+ +![Game image](../../assets/images/Align_4_Game.png) + +
+ + diff --git a/Games/Align_4_Game/index.html b/Games/Align_4_Game/index.html new file mode 100644 index 0000000000..b9dee26252 --- /dev/null +++ b/Games/Align_4_Game/index.html @@ -0,0 +1,81 @@ + + + + + + + Align 4 Game + + + + + + +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/Games/Align_4_Game/scripts/index.js b/Games/Align_4_Game/scripts/index.js new file mode 100644 index 0000000000..b31f45eac3 --- /dev/null +++ b/Games/Align_4_Game/scripts/index.js @@ -0,0 +1,253 @@ +// constants +const WEB_WORKER_URL = 'scripts/worker.js'; +const BLURBS = { + 'start': { + header: 'Get Ready', + blurb: 'Select your difficulty and start the game.' + }, + 'p1-turn': { + header: 'Your Turn', + blurb: 'Click on the board to drop your chip.' + }, + 'p2-turn': { + header: 'Computer\'s Turn', + blurb: 'The computer is trying to find the best way to make you lose.' + }, + 'p1-win': { + header: 'You Win', + blurb: 'You are a winner. Remember this moment. Carry it with you, forever.' + }, + 'p2-win': { + header: 'Computer Wins', + blurb: 'Try again when you\'re done wiping your tears of shame.' + }, + 'tie': { + header: 'Tie', + blurb: 'Everyone\'s a winner! Or loser. Depends on how you look at it.' + } +}; +const OUTLOOKS = { + 'win-imminent': 'Uh oh, computer is feeling saucy!', + 'loss-imminent': 'Computer is unsure. Now\'s your chance!' +}; + +// global variables +var worker; +var currentGameState; + +// document ready +$(function() { + $('.start button').on('click', startGame); + setBlurb('start'); + setOutlook(); + + // create worker + worker = new Worker(WEB_WORKER_URL); + worker.addEventListener('message', function(e) { + switch(e.data.messageType) { + case 'reset-done': + startHumanTurn(); + break; + case 'human-move-done': + endHumanTurn(e.data.coords, e.data.isWin, e.data.winningChips, e.data.isBoardFull); + break; + case 'progress': + updateComputerTurn(e.data.col); + break; + case 'computer-move-done': + endComputerTurn(e.data.coords, e.data.isWin, e.data.winningChips, e.data.isBoardFull, + e.data.isWinImminent, e.data.isLossImminent); + break; + } + }, false); +}); + +function setBlurb(key) { + $('.info h2').text(BLURBS[key].header); + $('.info .blurb').text(BLURBS[key].blurb); +} + +function setOutlook(key) { + var $outlook = $('.info .outlook'); + if(key) { + $outlook + .text(OUTLOOKS[key]) + .show(); + } else { + $outlook.hide(); + } +} + +function startGame() { + $('.dif').addClass('freeze'); + $('.dif input').prop('disabled', true); + $('.lit-cells, .chips').empty(); + + worker.postMessage({ + messageType: 'reset', + }); +} + +function startHumanTurn() { + setBlurb('p1-turn'); + $('.click-columns div').addClass('hover'); + + // if mouse is already over a column, show cursor chip there + var col = $('.click-columns div:hover').index(); + if(col !== -1) { + createCursorChip(1, col); + } + + $('.click-columns') + .on('mouseenter', function() { + var col = $('.click-columns div:hover').index(); + createCursorChip(1, col); + }) + .on('mouseleave', function() { + destroyCursorChip(); + }); + + $('.click-columns div') + .on('mouseenter', function() { + var col = $(this).index(); + moveCursorChip(col); + }) + .on('click', function() { + $('.click-columns, .click-columns div').off(); + + var col = $(this).index(); + worker.postMessage({ + messageType: 'human-move', + col: col + }); + }); +} + +function endHumanTurn(coords, isWin, winningChips, isBoardFull) { + $('.click-columns div').removeClass('hover'); + if(!coords) { + // column was full, human goes again + startHumanTurn(); + } else { + dropCursorChip(coords.row, function() { + if(isWin) { + endGame('p1-win', winningChips); + } else if(isBoardFull) { + endGame('tie'); + } else { + // pass turn to computer + startComputerTurn(); + } + }); + } +} + +function startComputerTurn() { + setBlurb('p2-turn'); + + // computer's cursor chip starts far left and moves right as it thinks + createCursorChip(2, 0); + + var maxDepth = parseInt($('input[name=dif-options]:checked').val(), 10) + 1; + worker.postMessage({ + messageType: 'computer-move', + maxDepth: maxDepth + }); +} + +function updateComputerTurn(col) { + moveCursorChip(col); +} + +function endComputerTurn(coords, isWin, winningChips, isBoardFull, isWinImminent, isLossImminent) { + moveCursorChip(coords.col, function() { + dropCursorChip(coords.row, function() { + if (isWin) { + endGame('p2-win', winningChips); + } else if (isBoardFull) { + endGame('tie'); + } else { + if(isWinImminent) { + setOutlook('win-imminent'); + } else if (isLossImminent) { + setOutlook('loss-imminent'); + } else { + setOutlook(); + } + + // pass turn to human + startHumanTurn(); + } + }); + }); +} + +function endGame(blurbKey, winningChips) { + $('.dif').removeClass('freeze'); + $('.dif input').prop('disabled', false); + setBlurb(blurbKey); + setOutlook(); + + if(winningChips) { + // not a tie, highlight the chips in the winning run + for(var i = 0; i < winningChips.length; i++) { + createLitCell(winningChips[i].col, winningChips[i].row); + } + } +} + +function createLitCell(col, row) { + $('
') + .css({ + 'left': indexToPixels(col), + 'bottom': indexToPixels(row) + }) + .appendTo('.lit-cells'); +} + +function createCursorChip(player, col) { + var playerClass = 'p' + player; + $('
', { 'class': 'cursor ' + playerClass }) + .css('left', indexToPixels(col)) + .appendTo('.chips'); + + // also highlight column + $('.lit-columns div').eq(col).addClass('lit'); +} + +function destroyCursorChip() { + $('.chips .cursor').remove(); + $('.lit-columns .lit').removeClass('lit'); +} + +function moveCursorChip(col, callback) { + $('.chips .cursor').css('left', indexToPixels(col)); + $('.lit-columns .lit').removeClass('lit'); + $('.lit-columns div').eq(col).addClass('lit'); + + // callback is only used when the computer is about to drop a chip + // give it a slight delay for visual interest + setTimeout(callback, 300); +} + +function dropCursorChip(row, callback) { + // speed of animation depends on how far the chip has to drop + var ms = (7 - row) * 40; + var duration = (ms / 1000) + 's'; + + $('.chips .cursor') + .removeClass('cursor') + .css({ + 'bottom': indexToPixels(row), + 'transition-duration': duration, + 'animation-delay': duration + }) + .addClass('dropped'); + + $('.lit-columns .lit').removeClass('lit'); + setTimeout(callback, ms); +} + +function indexToPixels(index) { + return (index * 61 + 1) + 'px'; +} \ No newline at end of file diff --git a/Games/Align_4_Game/scripts/worker.js b/Games/Align_4_Game/scripts/worker.js new file mode 100644 index 0000000000..09a379f74c --- /dev/null +++ b/Games/Align_4_Game/scripts/worker.js @@ -0,0 +1,236 @@ +// constants +const TOTAL_COLUMNS = 7; +const TOTAL_ROWS = 7; +const HUMAN_WIN_SCORE = -4; +const COMPUTER_WIN_SCORE = 4; +const NO_WIN_SCORE = 0; + +// global variables +var currentGameState; + +// game state object +var GameState = function(cloneGameState) { + this.board = []; + this.score = NO_WIN_SCORE; + this.winningChips = undefined; + + // initialize an empty board + for(var col = 0; col < TOTAL_COLUMNS; col++) { + this.board[col] = []; + } + + // clone from existing game state (if one was passed in) + if(cloneGameState) { + for (var col = 0; col < TOTAL_COLUMNS; col++) { + for (var row = 0; row < cloneGameState.board[col].length; row++) { + this.board[col][row] = cloneGameState.board[col][row]; + } + } + this.score = cloneGameState.score; + } +} +GameState.prototype.makeMove = function(player, col) { + var coords = undefined; + var row = this.board[col].length; + if (row < TOTAL_ROWS) { + this.board[col][row] = player; + this.setScore(player, col, row); + coords = { col: col, row: row }; + } + return coords; +} +GameState.prototype.isBoardFull = function() { + for (var col = 0; col < TOTAL_COLUMNS; col++) { + if (this.board[col].length < TOTAL_ROWS) { + // found an unfilled column + return false; + } + } + return true; +} +GameState.prototype.setScore = function(player, col, row) { + var isWin = + this.checkRuns(player, col, row, 0, 1) || // vertical + this.checkRuns(player, col, row, 1, 0) || // horizontal + this.checkRuns(player, col, row, 1, 1) || // diagonal "/" + this.checkRuns(player, col, row, 1, -1) // diagonal "\" + + if(isWin) { + this.score = (player === 1) ? HUMAN_WIN_SCORE : COMPUTER_WIN_SCORE; + } else { + this.score = NO_WIN_SCORE; + } +} +GameState.prototype.checkRuns = function(player, col, row, colStep, rowStep) { + var runCount = 0; + + // check from 3 chips before to 3 chips after the specified chip + // this covers all possible runs of 4 chips that include the specified chip + for (var step = -3; step <= 3; step++) { + if (this.getPlayerForChipAt(col + step * colStep, row + step * rowStep) === player) { + runCount++; + if (runCount === 4) { + // winning run, step backwards to find the chips that make up this run + this.winningChips = []; + for(var backstep = step; backstep >= step - 3; backstep--) { + this.winningChips.push({ + col: col + backstep * colStep, + row: row + backstep * rowStep + }); + } + return true; + } + } else { + runCount = 0; + if(step === 0) { + // no room left for a win + break; + } + } + } + + // no winning run found + return false; +} +GameState.prototype.getPlayerForChipAt = function(col, row) { + var player = undefined; + if (this.board[col] !== undefined && this.board[col][row] !== undefined) { + player = this.board[col][row]; + } + return player; +} +GameState.prototype.isWin = function() { + return (this.score === HUMAN_WIN_SCORE || this.score === COMPUTER_WIN_SCORE); +} + +// listen for messages from the main thread +self.addEventListener('message', function(e) { + switch(e.data.messageType) { + case 'reset': + resetGame(); + break; + case 'human-move': + makeHumanMove(e.data.col); + break; + case 'computer-move': + makeComputerMove(e.data.maxDepth); + break; + } +}, false); + +function resetGame() { + currentGameState = new GameState(); + + self.postMessage({ + messageType: 'reset-done' + }); +} + +function makeHumanMove(col) { + // coords is undefined if the move is invalid (column is full) + var coords = currentGameState.makeMove(1, col); + var isWin = currentGameState.isWin(); + var winningChips = currentGameState.winningChips; + var isBoardFull = currentGameState.isBoardFull(); + self.postMessage({ + messageType: 'human-move-done', + coords: coords, + isWin: isWin, + winningChips: winningChips, + isBoardFull: isBoardFull + }); +} + +function makeComputerMove(maxDepth) { + var col; + var isWinImminent = false; + var isLossImminent = false; + for (var depth = 0; depth <= maxDepth; depth++) { + var origin = new GameState(currentGameState); + var isTopLevel = (depth === maxDepth); + + // fun recursive AI stuff kicks off here + var tentativeCol = think(origin, 2, depth, isTopLevel); + if (origin.score === HUMAN_WIN_SCORE) { + // AI realizes it can lose, thinks all moves suck now, keep move picked at previous depth + // this solves the "apathy" problem + isLossImminent = true; + break; + } else if (origin.score === COMPUTER_WIN_SCORE) { + // AI knows how to win, no need to think deeper, use this move + // this solves the "cocky" problem + col = tentativeCol; + isWinImminent = true; + break; + } else { + // go with this move, for now at least + col = tentativeCol; + } + } + + var coords = currentGameState.makeMove(2, col); + var isWin = currentGameState.isWin(); + var winningChips = currentGameState.winningChips; + var isBoardFull = currentGameState.isBoardFull(); + self.postMessage({ + messageType: 'computer-move-done', + coords: coords, + isWin: isWin, + winningChips: winningChips, + isBoardFull: isBoardFull, + isWinImminent: isWinImminent, + isLossImminent: isLossImminent + }); +} + +function think(node, player, recursionsRemaining, isTopLevel) { + var scoreSet = false; + var childNodes = []; + + // consider each column as a potential move + for (var col = 0; col < TOTAL_COLUMNS; col++) { + if(isTopLevel) { + self.postMessage({ + messageType: 'progress', + col: col + }); + } + + // make sure column isn't already full + var row = node.board[col].length; + if (row < TOTAL_ROWS) { + // create new child node to represent this potential move + var childNode = new GameState(node); + childNode.makeMove(player, col); + childNodes[col] = childNode; + + if(!childNode.isWin() && recursionsRemaining > 0) { + // no game stopping win and there are still recursions to make, think deeper + var nextPlayer = (player === 1) ? 2 : 1; + think(childNode, nextPlayer, recursionsRemaining - 1); + } + + if (!scoreSet) { + // no best score yet, just go with this one for now + node.score = childNode.score; + scoreSet = true; + } else if (player === 1 && childNode.score < node.score) { + // assume human will always pick the lowest scoring move (least favorable to computer) + node.score = childNode.score; + } else if (player === 2 && childNode.score > node.score) { + // computer should always pick the highest scoring move (most favorable to computer) + node.score = childNode.score; + } + } + } + + // collect all moves tied for best move and randomly pick one + var candidates = []; + for (var col = 0; col < TOTAL_COLUMNS; col++) { + if (childNodes[col] != undefined && childNodes[col].score === node.score) { + candidates.push(col); + } + } + var moveCol = candidates[Math.floor(Math.random() * candidates.length)]; + return moveCol; +} \ No newline at end of file diff --git a/Games/Align_4_Game/styles/index.processed.css b/Games/Align_4_Game/styles/index.processed.css new file mode 100644 index 0000000000..f33b212fd4 --- /dev/null +++ b/Games/Align_4_Game/styles/index.processed.css @@ -0,0 +1,236 @@ +html { + display: table; + width: 100%; + height: 100%; + } + + body { + display: table-row; + background: #000 radial-gradient(1000px 500px, #3f546b, #000); + } + + .wrapper { + display: table-cell; + vertical-align: middle; + text-align: center; + } + + .content { + display: inline-block; + width: 668px; + margin: 0 auto; + padding: 10px 20px; + } + + .sidebar { + float: left; + margin-right: 20px; + width: 220px; + text-align: left; + font-family: 'Doppio One', sans-serif; + color: #ccc; + } + + h1, + h2 { + color: #fff; + margin: 0; + font-weight: normal; + } + + h1 { + height: 68px; + line-height: 68px; + font-size: 40px; + text-align: right; + } + + h2 { + font-size: 18px; + } + + .panel { + padding: 12px; + margin-bottom: 20px; + background-color: rgba(255, 255, 255, 0.1); + border-radius: 8px; + } + + .dif-options { + clear: both; + overflow: hidden; + margin: 20px -7px 0; + } + + .dif-options div { + float: left; + width: 20%; + } + + .dif-options input { + display: none; + } + + .dif-options input:checked+label { + color: #fff; + background-color: #593f6b; + border-color: #fff; + cursor: default; + } + + .dif-options label { + display: block; + margin: 0 auto; + width: 24px; + height: 24px; + background-color: #666; + border: solid 2px #ccc; + border-radius: 8px; + color: #999; + text-align: center; + line-height: 24px; + cursor: pointer; + } + + .freeze .dif-options input:not(:checked)+label { + font-size: 0; + margin: 7px auto; + width: 10px; + height: 10px; + border-radius: 4px; + color: transparent; + line-height: 10px; + cursor: default; + transition: .2s; + } + + .start { + margin-top: 20px; + } + + .start button { + display: block; + width: 100%; + padding: 2px 12px 4px; + font-family: inherit; + font-size: 24px; + border: solid 2px #ccc; + border-radius: 8px; + background-color: #593f6b; + color: #fff; + cursor: pointer; + } + + .start button:focus { + outline: none; + } + + .freeze .start { + display: none; + } + + .info div { + margin-top: 10px; + } + + .board { + position: relative; + float: left; + width: 428px; + height: 428px; + margin-top: 68px; + background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/77020/board.png"); + box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.4); + } + + .lit-columns, + .lit-cells, + .chips, + .click-columns { + position: absolute; + width: 428px; + height: 428px; + } + + .lit-columns div { + float: left; + width: 60px; + height: 426px; + margin: 1px 0 1px 1px; + transition: background-color 0.1s; + } + + .lit-columns .lit { + background-color: rgba(255, 255, 255, 0.1); + transition: background-color 0.1s; + } + + .lit-cells div { + position: absolute; + width: 60px; + height: 60px; + background-color: rgba(255, 255, 255, 0.3); + } + + .chips div { + position: absolute; + width: 60px; + height: 60px; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + } + + .chips .p1 { + background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/77020/p1-chip.png"); + } + + .chips .p2 { + background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/77020/p2-chip.png"); + } + + .chips .cursor { + bottom: 428px; + transition: left 0.1s ease-out; + } + + .chips .dropped { + transition: bottom ease-in; + animation: bounce 0.3s; + } + + .click-columns div { + float: left; + width: 61px; + height: 428px; + } + + .click-columns div:first-child { + padding-left: 1px; + } + + .click-columns .hover { + cursor: pointer; + } + + @keyframes bounce { + 0% { + animation-timing-function: ease-out; + transform: translateY(0); + } + 30% { + animation-timing-function: ease-in; + transform: translateY(-40px); + } + 60% { + animation-timing-function: ease-out; + transform: translateY(0); + } + 80% { + animation-timing-function: ease-in; + transform: translateY(-10px); + } + 100% { + animation-timing-function: ease-out; + transform: translateY(0); + } + } \ No newline at end of file diff --git a/Games/Align_4_Game/styles/index.scss b/Games/Align_4_Game/styles/index.scss new file mode 100644 index 0000000000..eba1709aeb --- /dev/null +++ b/Games/Align_4_Game/styles/index.scss @@ -0,0 +1,223 @@ +$asset-path: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/77020/'; + +html { + display: table; + width: 100%; + height: 100%; +} + +body { + display: table-row; + background: #000 radial-gradient(1000px 500px, #3f546b, #000); +} + +.wrapper { + display: table-cell; + vertical-align: middle; + text-align: center; +} + +.content { + display: inline-block; + width: 668px; + margin: 0 auto; + padding: 10px 20px; +} + +.sidebar { + float: left; + margin-right: 20px; + width: 220px; + text-align: left; + font-family: 'Doppio One', sans-serif; + color: #ccc; +} + +h1, h2 { + color: #fff; + margin: 0; + font-weight: normal; +} + +h1 { + height: 68px; + line-height: 68px; + font-size: 40px; + text-align: right; +} + +h2 { + font-size: 18px; +} + +.panel { + padding: 12px; + margin-bottom: 20px; + background-color: rgba(255, 255, 255, 0.1); + border-radius: 8px; +} + +.dif-options { + clear: both; + overflow: hidden; + margin: 20px -7px 0; + + div { + float: left; + width: 20%; + } + + input { + display: none; + + &:checked + label { + color: #fff; + background-color: #593f6b; + border-color: #fff; + cursor: default; + } + } + + label { + display: block; + margin: 0 auto; + width: 24px; + height: 24px; + background-color: #666; + border: solid 2px #ccc; + border-radius: 8px; + color: #999; + text-align: center; + line-height: 24px; + cursor: pointer; + } +} + +.freeze .dif-options input:not(:checked) + label { + font-size: 0; + margin: 7px auto; + width: 10px; + height: 10px; + border-radius: 4px; + color: transparent; + line-height: 10px; + cursor: default; + transition: .2s; +} + +.start { + margin-top: 20px; + + button { + display: block; + width: 100%; + padding: 2px 12px 4px; + font-family: inherit; + font-size: 24px; + border: solid 2px #ccc; + border-radius: 8px; + background-color: #593f6b; + color: #fff; + cursor: pointer; + + &:focus { + outline: none; + } + } +} + +.freeze .start { + display: none; +} + +.info div { + margin-top: 10px; +} + +.board { + position: relative; + float: left; + width: 428px; + height: 428px; + margin-top: 68px; + background-image: url($asset-path + 'board.png'); + box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.4); +} + +.lit-columns, .lit-cells, .chips, .click-columns { + position: absolute; + width: 428px; + height: 428px; +} + +.lit-columns { + div { + float: left; + width: 60px; + height: 426px; + margin: 1px 0 1px 1px; + transition: background-color 0.1s; + } + + .lit { + background-color: rgba(255, 255, 255, 0.1); + transition: background-color 0.1s; + } +} + +.lit-cells div { + position: absolute; + width: 60px; + height: 60px; + background-color: rgba(255, 255, 255, 0.3); +} + +.chips { + div { + position: absolute; + width: 60px; + height: 60px; + backface-visibility: hidden; + } + + .p1 { + background-image: url($asset-path + 'p1-chip.png'); + } + + .p2 { + background-image: url($asset-path + 'p2-chip.png'); + } + + .cursor { + bottom: 428px; + transition: left 0.1s ease-out; + } + .dropped { + transition: bottom ease-in; + animation: bounce 0.3s; + } +} + +.click-columns { + div { + float: left; + width: 61px; + height: 428px; + + &:first-child { + padding-left: 1px; + } + } + + .hover { + cursor: pointer; + } +} + +@keyframes bounce { + 0% { animation-timing-function: ease-out; transform: translateY(0); } + 30% { animation-timing-function: ease-in; transform: translateY(-40px); } + 60% { animation-timing-function: ease-out; transform: translateY(0); } + 80% { animation-timing-function: ease-in; transform: translateY(-10px); } + 100% { animation-timing-function: ease-out; transform: translateY(0); } +} diff --git a/Games/Avoider_Game/app.js b/Games/Avoider_Game/app.js index 660af432fd..3d6b47234f 100644 --- a/Games/Avoider_Game/app.js +++ b/Games/Avoider_Game/app.js @@ -69,11 +69,12 @@ function startGame() { function loop() { let stopGame = false; - + // adjust the screen size Logic + let cellsCalculate=window.innerWidth<600?6:8 for (let i = enemyCells.length - 1; i >= 0; i--) { // From 29 till it reaches 0 const cell = enemyCells[i]; - const nextCell = cells[i + 8]; + const nextCell = cells[i + cellsCalculate]; const enemy = cell.children[0]; // Continue and move on diff --git a/Games/Avoider_Game/assets/Desktop.png b/Games/Avoider_Game/assets/Desktop.png new file mode 100644 index 0000000000..fa4528852b Binary files /dev/null and b/Games/Avoider_Game/assets/Desktop.png differ diff --git a/Games/Avoider_Game/assets/iPad.png b/Games/Avoider_Game/assets/iPad.png new file mode 100644 index 0000000000..2d1076adfd Binary files /dev/null and b/Games/Avoider_Game/assets/iPad.png differ diff --git a/Games/Avoider_Game/assets/mobile.png b/Games/Avoider_Game/assets/mobile.png new file mode 100644 index 0000000000..6d2165df83 Binary files /dev/null and b/Games/Avoider_Game/assets/mobile.png differ diff --git a/Games/Avoider_Game/style.css b/Games/Avoider_Game/style.css index 95050ba7c3..8f6e7619ff 100644 --- a/Games/Avoider_Game/style.css +++ b/Games/Avoider_Game/style.css @@ -21,6 +21,7 @@ body { width: 90vh; background-color: rgba(20, 198, 243, 0.25); padding: 2%; + max-width: 700px; border-radius: 10%; box-shadow: 0 0 50px 0 rgba(20, 198, 243, 0.3); } @@ -116,4 +117,9 @@ hr { .author a:hover { text-decoration: underline; +} +@media (max-width:600px) { + .container{width:95% !important;} + .grid{grid-template-columns: repeat(6, 40px) !important;} + .cell{height:40px !important;} } \ No newline at end of file diff --git a/Games/Balloon_Popup/Balloon_Popup.png b/Games/Balloon_Popup/Balloon_Popup.png new file mode 100644 index 0000000000..9b14903ac8 Binary files /dev/null and b/Games/Balloon_Popup/Balloon_Popup.png differ diff --git a/Games/Balloon_Popup/Readme.md b/Games/Balloon_Popup/Readme.md new file mode 100644 index 0000000000..3557d3f931 --- /dev/null +++ b/Games/Balloon_Popup/Readme.md @@ -0,0 +1,50 @@ +# **Balloon Popper Game** + +--- + +
+ +## **Description 📃** + +- The Balloon Popper Game is a fun and interactive game where players need to pop balloons of different colors and sizes as they float up the screen. Built using HTML, CSS, and JavaScript, this game provides an engaging and enjoyable experience for all ages. + +## **Functionalities 🎮** + +- Colorful balloons that float up the screen. +- Click to pop the balloons and score points. +- Different balloon sizes to add variety. +- Timer to challenge the player. +- Score tracking to keep track of your performance. + +
+ +## **How to Play? 🕹️** + +- Open the game in your web browser. +- Balloons will start floating up the screen. +- Click on the balloons to pop them and score points. +- The game ends when the timer runs out. +- Try to score as many points as possible before the time runs out! + +
+ +## **Screenshots 📸** + +
+ + + +Screenshot 2023-07-09 235520 +
+ + +
+ +## **Getting Started** + +To get a local copy of the game up and running, follow these simple steps. + +### Prerequisites + +Make sure you have a web browser installed on your computer. + diff --git a/Games/Balloon_Popup/app.js b/Games/Balloon_Popup/app.js new file mode 100644 index 0000000000..df704721bc --- /dev/null +++ b/Games/Balloon_Popup/app.js @@ -0,0 +1,29 @@ +let popped = 0; + +document.addEventListener('mouseover', function(e){ + + if (e.target.className === "balloon"){ + + e.target.style.backgroundColor = "#ededed"; + e.target.textContent = "POP!"; + popped++; + removeEvent(e); + checkAllPopped(); + } +}); + +function removeEvent(e){ + e.target.removeEventListener('mouseover', function(){ + + }) +}; + +function checkAllPopped(){ + if (popped === 24){ + console.log('all popped!'); + let gallery = document.querySelector('#balloon-gallery'); + let message = document.querySelector('#yay-no-balloons'); + gallery.innerHTML = ''; + message.style.display = 'block'; + } +}; \ No newline at end of file diff --git a/Games/Balloon_Popup/index.html b/Games/Balloon_Popup/index.html new file mode 100644 index 0000000000..9f0ecaf673 --- /dev/null +++ b/Games/Balloon_Popup/index.html @@ -0,0 +1,44 @@ + + + + + + + + Pop the Ballons + + +
+

Pop the balloons by moving
your mouse over them

+
Wow! All balloons popped!
+ + +
+ + + \ No newline at end of file diff --git a/Games/Balloon_Popup/style.css b/Games/Balloon_Popup/style.css new file mode 100644 index 0000000000..63f5583378 --- /dev/null +++ b/Games/Balloon_Popup/style.css @@ -0,0 +1,74 @@ +body{ + font-family:sans-serif; + padding: 30px; + background:#ededed; +} + +.wrapper{ + max-width: 690px; + margin: 0 auto; +} + +.blue { + color:#3f7abe; +} + +h1{ + margin: auto; + margin-top: 50px; + margin-bottom: 50px; + color: #08a3d9; + text-transform: uppercase; + font-size: 30px; + color: #000380; +} + +#balloon-gallery div{ + background: #ff3300; + height: 121px; + width: 119px; + text-align: center; + color: #ff3300; + font-size: 40px; + font-family: sans-serif, arial; + border-radius: 100%; + margin-top: 20px; + display: inline-block; + /* float: left; */ + margin: 2.5px 5 px 2.5px 0px; +} + +#balloon-gallery div:nth-child(3n){ + background: #ffce00; + color: #ffce00; +} + +#balloon-gallery div:nth-child(3n-1){ + background:#3f7abe; + color:#3f7abe; +} + +#balloon-gallery div:nth-child(5n){ + background:#8e7a8e; + color:#8e7a8e; +} + +#balloon-gallery div:nth-child(13){ + background:#8e7a8e; + color:#8e7a8e; +} + +#balloon-gallery div:nth-child(10n){ + background:#ff3300; + color: #ff3300; +} + +#balloon-gallery div:nth-child(4n){ + clear:right; +} + +#yay-no-balloons { + display:none; + color:#ff3300; + font-size:100px; +} \ No newline at end of file diff --git a/Games/Beat_a_mole/README.md b/Games/Beat_a_mole/README.md new file mode 100644 index 0000000000..8e61994d35 --- /dev/null +++ b/Games/Beat_a_mole/README.md @@ -0,0 +1,35 @@ +# **Beat_a_Mole** + +--- + +
+ +## **Description 📃** +- The Beat-a-Mole game is a classic arcade game implemented using HTML, CSS, and JavaScript. Players must hit moles that randomly pop up on the screen but if you hit the plant the game will be over. The game features a simple and intuitive user interface with responsive design elements. + +## **functionalities 🎮** +- Hit moles that randomly pop up from holes on the screen +- Score points for successfully hitting moles +- Track your score as you play +- Game ends if you hit the plant +- Responsive design for easy play on different devices +- Start a new round to play again +
+ +## **How to play? 🕹️** + +- Start the game by clicking on the "Start" button +- Moles will randomly appear from different holes on the screen +- Use your mouse or touch screen to click on the moles as quickly as possible +- Each successful hit on a mole will earn you points +- Aim to achieve the highest score. +- The game ends when you hit the plant +- Your final score will be displayed on the screen +
+ +## **Screenshots 📸** +
+ +![image](../../assets/Beat_a_mole.png) + +
diff --git a/Games/Beat_a_mole/assets/Beat_a_mole.png b/Games/Beat_a_mole/assets/Beat_a_mole.png new file mode 100644 index 0000000000..ba3c6c84bd Binary files /dev/null and b/Games/Beat_a_mole/assets/Beat_a_mole.png differ diff --git a/Games/Beat_a_mole/assets/mario-bg.jpg b/Games/Beat_a_mole/assets/mario-bg.jpg new file mode 100644 index 0000000000..d2e4aa344f Binary files /dev/null and b/Games/Beat_a_mole/assets/mario-bg.jpg differ diff --git a/Games/Beat_a_mole/assets/monty-mole.png b/Games/Beat_a_mole/assets/monty-mole.png new file mode 100644 index 0000000000..523a515233 Binary files /dev/null and b/Games/Beat_a_mole/assets/monty-mole.png differ diff --git a/Games/Beat_a_mole/assets/pipe.png b/Games/Beat_a_mole/assets/pipe.png new file mode 100644 index 0000000000..fb1d6be633 Binary files /dev/null and b/Games/Beat_a_mole/assets/pipe.png differ diff --git a/Games/Beat_a_mole/assets/piranha-plant.png b/Games/Beat_a_mole/assets/piranha-plant.png new file mode 100644 index 0000000000..ad5fb991b9 Binary files /dev/null and b/Games/Beat_a_mole/assets/piranha-plant.png differ diff --git a/Games/Beat_a_mole/assets/soil.png b/Games/Beat_a_mole/assets/soil.png new file mode 100644 index 0000000000..94e3b38d2c Binary files /dev/null and b/Games/Beat_a_mole/assets/soil.png differ diff --git a/Games/Beat_a_mole/assets/start-bg.png b/Games/Beat_a_mole/assets/start-bg.png new file mode 100644 index 0000000000..d90aff74ee Binary files /dev/null and b/Games/Beat_a_mole/assets/start-bg.png differ diff --git a/Games/Beat_a_mole/game.html b/Games/Beat_a_mole/game.html new file mode 100644 index 0000000000..ecb31c988d --- /dev/null +++ b/Games/Beat_a_mole/game.html @@ -0,0 +1,17 @@ + + + + + + Beat a Mole + + + + +

Beat a Mole

+

0

+ +
+
+ + diff --git a/Games/Beat_a_mole/index.html b/Games/Beat_a_mole/index.html new file mode 100644 index 0000000000..e39b66cede --- /dev/null +++ b/Games/Beat_a_mole/index.html @@ -0,0 +1,22 @@ + + + + + + Whack a Mole + + + +
+
+

Beat a Mole

+
+
+
+
+ Start +
+
+
+ + \ No newline at end of file diff --git a/Games/Beat_a_mole/mole.css b/Games/Beat_a_mole/mole.css new file mode 100644 index 0000000000..7f05841809 --- /dev/null +++ b/Games/Beat_a_mole/mole.css @@ -0,0 +1,52 @@ +body { + font-family: Arial, Helvetica, sans-serif; + text-align: center; + background: url("assets/mario-bg.jpg"); + background-size: cover; +} + +#board { + max-width: 540px; /* Set maximum width */ + width: 90%; /* Set width to a percentage */ + aspect-ratio: 1; /* Maintain aspect ratio */ + margin: 0 auto; + display: flex; + flex-wrap: wrap; + background: url("assets/soil.png"); + background-size: cover; + border: 3px solid white; + border-radius: 25px; +} + +#board div { + width: 33.33%; /* Set width to 1/3 of the parent */ + padding-bottom: 33.33%; /* Maintain a square aspect ratio */ + background-image: url("assets/pipe.png"); + background-size: cover; + position: relative; +} + +#board div img { + width: 60%; /* Adjust size of mole image */ + height: auto; /* Maintain aspect ratio */ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.beat{ + margin-left: 10px; +} + +@media (max-width: 600px) { + #board { + max-width: 400px; + } +} + +@media (max-width: 400px) { + #board { + max-width: 300px; + } +} diff --git a/Games/Beat_a_mole/mole.js b/Games/Beat_a_mole/mole.js new file mode 100644 index 0000000000..2cde9e2e0c --- /dev/null +++ b/Games/Beat_a_mole/mole.js @@ -0,0 +1,77 @@ +let currMoleTile; +let currPlantTile; +let score = 0; +let gameOver = false; + +window.onload = function() { + setGame(); +} + +function setGame() { + //set up the grid in html + for (let i = 0; i < 9; i++) { //i goes from 0 to 8, stops at 9 + //
+ let tile = document.createElement("div"); + tile.id = i.toString(); + tile.addEventListener("click", selectTile); + document.getElementById("board").appendChild(tile); + } + setInterval(setMole, 1000); // 1000 miliseconds = 1 second, every 1 second call setMole + setInterval(setPlant, 2000); // 2000 miliseconds = 2 seconds, every 2 second call setPlant +} + +function getRandomTile() { + //math.random --> 0-1 --> (0-1) * 9 = (0-9) --> round down to (0-8) integers + let num = Math.floor(Math.random() * 9); + return num.toString(); +} + +function setMole() { + if (gameOver) { + return; + } + if (currMoleTile) { + currMoleTile.innerHTML = ""; + } + let mole = document.createElement("img"); + mole.src = "assets/monty-mole.png"; + + let num = getRandomTile(); + if (currPlantTile && currPlantTile.id == num) { + return; + } + currMoleTile = document.getElementById(num); + currMoleTile.appendChild(mole); +} + +function setPlant() { + if (gameOver) { + return; + } + if (currPlantTile) { + currPlantTile.innerHTML = ""; + } + let plant = document.createElement("img"); + plant.src = "assets/piranha-plant.png"; + + let num = getRandomTile(); + if (currMoleTile && currMoleTile.id == num) { + return; + } + currPlantTile = document.getElementById(num); + currPlantTile.appendChild(plant); +} + +function selectTile() { + if (gameOver) { + return; + } + if (this == currMoleTile) { + score += 10; + document.getElementById("score").innerText = score.toString(); //update score html + } + else if (this == currPlantTile) { + document.getElementById("score").innerText = "GAME OVER: " + score.toString(); //update score html + gameOver = true; + } +} \ No newline at end of file diff --git a/Games/Beat_a_mole/start.css b/Games/Beat_a_mole/start.css new file mode 100644 index 0000000000..d92f3d6e27 --- /dev/null +++ b/Games/Beat_a_mole/start.css @@ -0,0 +1,64 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Times New Roman', Times, serif; +} + +html, body { + height: 100%; +} + +.main { + height: 100vh; + width: 100%; + background-image: linear-gradient(rgba(0,0,0,0.4),rgba(0,0,0,0.4)), url(assets/start-bg.png); + background-position: center; + background-size: cover; + display: flex; + justify-content: center; + align-items: center; +} + +.form-box { + width: 80%; + max-width: 600px; + padding: 20px; + background-color: rgb(196, 125, 31); + text-align: center; + border-radius: 8px; +} + +.text { + font-size: 2.5rem; + margin-bottom: 40px; + font-family: 'Courier New', Courier, monospace; +} + +.start-btn a { + text-decoration: none; + color: white; + padding: 10px 20px; + font-size: 1.25rem; + border: 2px solid rgba(0, 0, 0, 0.265); + border-radius: 8px; + background-color: rgb(204, 7, 14); + display: inline-block; + transition: background-color 0.2s linear, border 0.2s linear; +} + +.start-btn a:hover { + background-color: rgba(134, 4, 4, 0.943); + border: 2px solid rgb(19, 18, 18); +} + +@media (max-width: 600px) { + .text { + font-size: 2rem; + } + + .start-btn a { + font-size: 1rem; + padding: 8px 16px; + } +} diff --git a/Games/Beyblade/3D Stadium.glb b/Games/Beyblade/3D Stadium.glb new file mode 100644 index 0000000000..74dcc0727e Binary files /dev/null and b/Games/Beyblade/3D Stadium.glb differ diff --git a/Games/Beyblade/BB-LOGO.png b/Games/Beyblade/BB-LOGO.png new file mode 100644 index 0000000000..c1527dbbaf Binary files /dev/null and b/Games/Beyblade/BB-LOGO.png differ diff --git a/Games/Beyblade/README.md b/Games/Beyblade/README.md index 45417abcf3..8d0110ec8d 100644 --- a/Games/Beyblade/README.md +++ b/Games/Beyblade/README.md @@ -1,35 +1,35 @@ -# **Beyblade** - -
- -## **Description 📃** - -- This Beyblade game is developed using HTML, CSS, and JavaScript. -The game will simulate a spinning battle between two Beyblades, where players can launch their Beyblades and compete to earn a high score and determine the winner. - -## **functionalities 🎮** - -1. Players can choose their Beyblade from a variety of options, each with unique characteristics and abilities. -2. Players can launch their Beyblade into the battle arena by clicking a launch button. -3. The Beyblade will spin continuously after being launched, creating an engaging visual effect. -4. The game will keep track of each player's score based on the performance of their Beyblade during the battle. -5. Each Beyblade will have a stamina value that decreases over time. -6. The game will end when a Beyblade's stamina reaches zero. -7. The game is be designed to work on various screen sizes and devices, ensuring a seamless gaming experience. -
- -## **How to play? 🕹️** - -- To play the Beyblade game, click the "Player 1 Launch" button to launch Player 1's Beyblade, then wait for it to stop spinning and see if there's a collision, with the scores and stamina updated accordingly. - -
- -## **Screenshots 📸** - -
- - -Screenshot 2023-07-02 172036 -Screenshot 2023-07-02 172053 - -
\ No newline at end of file +# **Beyblade** + +
+ +## **Description 📃** + +- This Beyblade game is developed using HTML, CSS, and JavaScript. +The game will simulate a spinning battle between two Beyblades, where players can launch their Beyblades and compete to earn a high score and determine the winner. + +## **functionalities 🎮** + +1. Players can choose their Beyblade from a variety of options, each with unique characteristics and abilities. +2. Players can launch their Beyblade into the battle arena by clicking a launch button. +3. The Beyblade will spin continuously after being launched, creating an engaging visual effect. +4. The game will keep track of each player's score based on the performance of their Beyblade during the battle. +5. Each Beyblade will have a stamina value that decreases over time. +6. The game will end when a Beyblade's stamina reaches zero. +7. The game is be designed to work on various screen sizes and devices, ensuring a seamless gaming experience. +
+ +## **How to play? 🕹️** + +- To play the Beyblade game, read the note written by clicking on "How to Play?" and then Click on "Play now" button then click the "Player 1 Launch" and "Player 2 Launch" button to launch Player 1's & 2's Beyblade, then wait for it to stop spinning and see if there's a collision, with the scores and stamina updated accordingly. + +
+ +## **Screenshots 📸** + +
+ + +Screenshot 2023-07-02 172036 + + +
diff --git a/Games/Beyblade/assets/Webpage.png b/Games/Beyblade/assets/Webpage.png new file mode 100644 index 0000000000..ee1fa2e649 Binary files /dev/null and b/Games/Beyblade/assets/Webpage.png differ diff --git a/Games/Beyblade/assets/b1.jpg b/Games/Beyblade/assets/b1.jpg new file mode 100644 index 0000000000..732a0b58dc Binary files /dev/null and b/Games/Beyblade/assets/b1.jpg differ diff --git a/Games/Beyblade/assets/b2.png b/Games/Beyblade/assets/b2.png new file mode 100644 index 0000000000..8e8372e98d Binary files /dev/null and b/Games/Beyblade/assets/b2.png differ diff --git a/Games/Beyblade/assets/bey1.png b/Games/Beyblade/assets/bey1.png new file mode 100644 index 0000000000..c3c32bddfb Binary files /dev/null and b/Games/Beyblade/assets/bey1.png differ diff --git a/Games/Beyblade/assets/bey2.jpg b/Games/Beyblade/assets/bey2.jpg new file mode 100644 index 0000000000..e856706889 Binary files /dev/null and b/Games/Beyblade/assets/bey2.jpg differ diff --git a/Games/Beyblade/index.html b/Games/Beyblade/index.html index de44bb9a8d..6597dc425c 100644 --- a/Games/Beyblade/index.html +++ b/Games/Beyblade/index.html @@ -1,31 +1,66 @@ - - - - - Beyblade Game - - - - -

Beyblade Game

-
-
-

Player 1

- -

Score: 0

-

Stamina: 100

- Blade 1 -
-
-

Player 2

- -

Score: 0

-

Stamina: 100

- Blade 2 -
-
- - - - + + + + + + Beyblade Game + + + + + +
+
+ + +
+
+
+

Player 1

+ +

Score: 0

+

Stamina: 100

+ Blade 1 +
+
+
+
+ + +
+ + +
+
+
+
+

Player 2

+ +

Score: 0

+

Stamina: 100

+ Blade 2 +
+
+
+
+

3D Beyblade Stadium

+ +
+ + + + \ No newline at end of file diff --git a/Games/Beyblade/script.js b/Games/Beyblade/script.js index e444f2e000..0e3f7a06f5 100644 --- a/Games/Beyblade/script.js +++ b/Games/Beyblade/script.js @@ -1,112 +1,142 @@ -const MAX_STAMINA = 100; - -let score1 = 0; -let score2 = 0; -let stamina1 = MAX_STAMINA; -let stamina2 = MAX_STAMINA; - -function launchBlade(player) { - - const score = Math.floor(Math.random() * 100) + 1; - const decreaseStamina = Math.floor(Math.random() * 20) + 1; - - if (player === 1) { - score1 += score; - stamina1 -= decreaseStamina; - if (stamina1 < 0) stamina1 = 0; - document.getElementById("score1").textContent = score1; - document.getElementById("stamina1").textContent = stamina1; - const blade1 = document.getElementById("blade1"); - blade1.classList.add("spin-animation"); - blade1.addEventListener("animationend", () => { - blade1.classList.remove("spin-animation"); - }, { once: true }); - } else { - score2 += score; - stamina2 -= decreaseStamina; - if (stamina2 < 0) stamina2 = 0; - document.getElementById("score2").textContent = score2; - document.getElementById("stamina2").textContent = stamina2; - const blade2 = document.getElementById("blade2"); - blade2.classList.add("spin-animation"); - blade2.addEventListener("animationend", () => { - blade2.classList.remove("spin-animation"); - }, { once: true }); - } - - if (stamina1 === 0 || stamina2 === 0) { - endGame(); - } -} - -function endGame() { - document.getElementById("player1").getElementsByTagName("button")[0].disabled = true; - document.getElementById("player2").getElementsByTagName("button")[0].disabled = true; - - let winner; - if (score1 > score2) { - winner = "Player 1"; - } else if (score2 > score1) { - winner = "Player 2"; - } else { - winner = "It's a tie!"; - } - - const resultDiv = document.createElement("div"); - resultDiv.innerHTML = "

Game Over!

Winner: " + winner + "

"; - document.getElementById("game-container").appendChild(resultDiv); -} - -function handlePowerUp(player) { - const powerUpChance = Math.random(); - if (powerUpChance <= 0.2) { - if (player === 1) { - player1Score += 5; - player1Stamina += 10; - } else { - player2Score += 5; - player2Stamina += 10; - } - } - updateUI(); -} - -function displayPowerUpMessage(player) { - const messageElement = document.getElementById('power-up-message'); - if (player === 1) { - messageElement.textContent = 'Player 1 got a Power-Up!'; - } else { - messageElement.textContent = 'Player 2 got a Power-Up!'; - } - messageElement.classList.add('show'); - setTimeout(() => { - messageElement.classList.remove('show'); - }, 2000); -} - -function generatePowerUps() { - setInterval(() => { - const player = Math.random() < 0.5 ? 1 : 2; - handlePowerUp(player); - displayPowerUpMessage(player); - }, 10000); -} - -function updateTimer() { - const timerElement = document.getElementById('game-timer'); - let seconds = 0; - setInterval(() => { - seconds++; - const minutes = Math.floor(seconds / 60); - const remainingSeconds = seconds % 60; - timerElement.textContent = `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`; - }, 1000); -} - -function startGame() { - resetGame(); - generatePowerUps(); - updateTimer(); -} - -startGame(); +const MAX_STAMINA = 100; + +let score1 = 0; +let score2 = 0; +let stamina1 = MAX_STAMINA; +let stamina2 = MAX_STAMINA; + +var display=1; +var div1 = document.getElementById("container3D"); +div1.style.display='none'; +function hideShow(){ + if(display==0){ + div1.style.display='none'; + display=1; + } + else{ + div1.style.display='block'; + display=0; + } +} + +let popup=document.getElementById("popup"); +function openPopup(){ + popup.classList.add("open-popup"); +} +function closePopup(){ + popup.classList.remove("open-popup"); +} + + +if(display==1){ + function launchBlade(player) { + + const score = Math.floor(Math.random() * 100) + 1; + const decreaseStamina = Math.floor(Math.random() * 20) + 1; + + if (player === 1) { + score1 += score; + stamina1 -= decreaseStamina; + if (stamina1 < 0) stamina1 = 0; + document.getElementById("score1").textContent = score1; + document.getElementById("stamina1").textContent = stamina1; + const blade1 = document.getElementById("blade1"); + blade1.classList.add("spin-animation"); + blade1.addEventListener("animationend", () => { + blade1.classList.remove("spin-animation"); + }, { once: true }); + } else { + score2 += score; + stamina2 -= decreaseStamina; + if (stamina2 < 0) stamina2 = 0; + document.getElementById("score2").textContent = score2; + document.getElementById("stamina2").textContent = stamina2; + const blade2 = document.getElementById("blade2"); + blade2.classList.add("spin-animation"); + blade2.addEventListener("animationend", () => { + blade2.classList.remove("spin-animation"); + }, { once: true }); + } + + if (stamina1 === 0 || stamina2 === 0) { + endGame(); + } + } +} + +function endGame() { + document.getElementById("player1").getElementsByTagName("button")[0].disabled = true; + document.getElementById("player2").getElementsByTagName("button")[0].disabled = true; + + let winner; + if (score1 > score2) { + winner = "Player 1"; + } else if (score2 > score1) { + winner = "Player 2"; + } else { + winner = "It's a tie!"; + } + + const resultDiv = document.createElement("div"); + resultDiv.innerHTML = "

Game Over!

Winner: " + winner + "

"; + document.getElementById("container3D").appendChild(resultDiv); + var div = document.getElementById("hide"); + div.style.display='none'; +} + +function handlePowerUp(player) { + const powerUpChance = Math.random(); + if (powerUpChance <= 0.2) { + if (player === 1) { + player1Score += 5; + player1Stamina += 10; + } else { + player2Score += 5; + player2Stamina += 10; + } + } + updateUI(); +} + +function displayPowerUpMessage(player) { + const messageElement = document.getElementById('container3D'); + if (player == 1) { + messageElement.textContent = 'Player 1 got a Power-Up!'; + } else { + messageElement.textContent = 'Player 2 got a Power-Up!'; + } + messageElement.classList.add('show'); + setTimeout(() => { + messageElement.classList.remove('show'); + }, 2000); +} + +function generatePowerUps() { + setInterval(() => { + const player = Math.random() < 0.5 ? 1 : 2; + handlePowerUp(player); + displayPowerUpMessage(player); + }, 1000); +} + +function updateTimer() { + const timerElement = document.getElementById('game-timer'); + let seconds = 0; + setInterval(() => { + seconds++; + const minutes = Math.floor(seconds / 60); + const remainingSeconds = seconds % 60; + timerElement.textContent = `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`; + }, 100); + if(seconds==60&& (stamina1==0||stamina2==0)){ + endGame(); + } +} + +function startGame() { + resetgame(); + generatePowerUps(); + updateTimer(); +} + +startGame(); diff --git a/Games/Beyblade/style.css b/Games/Beyblade/style.css index c2b76b077a..477591d96a 100644 --- a/Games/Beyblade/style.css +++ b/Games/Beyblade/style.css @@ -1,216 +1,362 @@ -body { - font-family: Arial, sans-serif; - text-align: center; - background-color: #e8e5c4; -} - -h1 { - margin-top: 30px; - color: #333; -} - -#game-container { - display: flex; - justify-content: space-around; - margin-top: 50px; -} - -#player1, -#player2 { - border: 1px solid #dccbcb; - padding: 20px; - width: 200px; - background-color: #c3e7b1; - border-radius: 5px; - box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); -} - -button { - margin-top: 10px; - padding: 10px 20px; - background-color: #333; - color: #fff; - border: none; - border-radius: 3px; - cursor: pointer; - transition: background-color 0.3s; -} - -button:hover { - background-color: #555; -} - -p { - margin-top: 20px; - color: #555; -} - -img { - width: 150px; - height: 150px; - margin-top: 20px; - animation: none; - border-radius: 50%; -} - -.spin-animation { - animation: spin 1s infinite linear; -} - -@keyframes spin { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } -} - -.result { - margin-top: 30px; - font-size: 20px; - font-weight: bold; -} - -.score-label { - font-size: 18px; - font-weight: bold; - color: #555; - text-transform: uppercase; - margin-bottom: 5px; -} - -.score-value { - font-size: 24px; - color: #333; -} - -.stamina-label { - font-size: 18px; - font-weight: bold; - color: #555; - text-transform: uppercase; - margin-bottom: 5px; -} - -.stamina-value { - font-size: 24px; - color: #333; -} - -.game-over { - margin-top: 30px; - font-size: 24px; - font-weight: bold; - color: #333; -} - -.winner { - font-size: 30px; - color: #333; -} - -.tie { - color: #777; -} - -/* Additional Styling */ - -.container { - max-width: 800px; - margin: 0 auto; - padding: 20px; -} - -.row { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 20px; -} - -.col-6 { - flex-basis: 50%; -} - -@media (max-width: 600px) { - #game-container { - flex-direction: column; - } - - #player1, - #player2 { - width: 100%; - margin-bottom: 20px; - } -} - -.beyblade { - width: 100px; - height: 100px; - border-radius: 50%; - object-fit: cover; -} - -.launch-button { - background-color: #4caf50; - color: white; - padding: 10px 20px; - border: none; - border-radius: 5px; - cursor: pointer; - font-size: 16px; -} - -.score-container, -.stamina-container { - display: flex; - align-items: center; - margin-bottom: 10px; -} - -.score-container span, -.stamina-container span { - font-weight: bold; - margin-right: 5px; -} - -#game-result { - text-align: center; - margin-top: 20px; -} - -.winner { - font-size: 24px; - font-weight: bold; - color: #4caf50; -} - -#power-up-message { - display: none; - text-align: center; - font-weight: bold; - font-size: 18px; - margin-top: 10px; -} - -.show { - display: block; -} - -#game-timer { - font-size: 20px; - font-weight: bold; - margin-top: 10px; -} - -#reset-button { - background-color: #f44336; - color: white; - padding: 10px 20px; - border: none; - border-radius: 5px; - cursor: pointer; - font-size: 16px; +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap'); + +*{ + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body{ + background: #020827; + font-family: 'Poppins','sans-serif'; + height: 350vh; +} + +/* Header Starts here */ + +.container{ + width: 100%; + height: 100vh; + background: linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.1)); + background-size: cover; + background-position: top; + /* display: flex; */ +} + +.logo img{ + height: 100px ; + width:60%; +} + +header{ + width: 100%; + height: 10vh; + background-position: rgba(0,0,0,0.5); + display: flex; + justify-content: space-between; + align-items: center; +} + +.logo img{ + width: 80%; +} + +.popup{ + width: 400px; + background: #fff; + border-radius: 6px; + position: absolute; + top: 0; + left: 50%; + transform: translate(-50%,-50%) scale(0.1); + text-align: center; + padding: 0 30px 30px; + color: #333; + visibility: hidden; + transition: transform 0.4s, top 0.4s;; +} + +.open-popup{ + visibility: visible; + top: 50%; + transform: translate(-50%,-50%) scale(1); +} + +.popup i{ + color: #6fd649; +} + +.popup h2{ + font-size: 38px; + font-weight: 500; + margin: 30px 0 10px; +} + +.popup button{ + width: 100%; + margin-top: 50px; + padding: 10px 0; + background: #6fd649; + color: #fff; + border: 0; + outline: none; + font-size: 18px; + border-radius: 4px; + cursor: pointer; + box-shadow: 0 5px 5px rgba(0, 0, 0, 0.2); +} + +.logo{ + width: 300px; + height: 13vh; + background: #031157; + display: flex; + align-items: center; + color: #fff; + clip-path: polygon(0 0,100% 0,64% 100%,0 100%); + padding: 10px; + line-height: 2rem; + margin-top: -10px; +} + +#btn{ + clip-path: polygon(0 0,100% 0,64% 100%,0 100%); +} + +.navbar{ + display: flex; + list-style: none; + height: 50px; +} + +ul.navbar li{ + width: 120px; + margin-left: 100px; + margin-top: 10px; +} + +ul.navbar li a{ + text-decoration: none; + color: #fff; + font-weight: 600; + font-size: 26px; +} + +ul.navbar li i.fa-solid{ + color: #fff; + margin-right: 10px; +} + +ul.navbar li a:hover,ul.navbar li i:hover{ + color: #fec53a; +} + +#btn{ + width: 250px; + height: 10vh; + background: #fec53a; + color: #000; + outline: none; + border: none; + clip-path: polygon(40% 0,100% 0,100% 100%,0 100%); + font-size: 1.2rem; + font-weight: bold; + text-align: right; + padding-right: 40px; + transition: transform 0.2s ease; +} + +#btn:active{ + transform: scale(0.96); +} + +@keyframes ani{ + 0%{ + transform: rotate(0deg); + } + 100%{ + transform: rotate(360deg); + } +} + +@keyframes ani2{ + 0%{ + transform: rotate(360deg); + } + 100%{ + transform: rotate(0deg); + } +} + +.game-timer{ + color: white; + font-size: 20px; +} + + +/* Header ends here */ + +#player1, +#player2 { + border: 1px solid #dccbcb; + padding: 20px; + width: 300px; + background-color: #c3e7b1; + border-radius: 5px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); + justify-content: center; + align-items: center; +} + +.launch-button { + background-color: #4caf50; + color: white; + padding: 10px 20px; + border: none; + border-radius: 5px; + cursor: pointer; + font-size: 16px; + } + +.blader1{ + height: 300px; + width: 250px; +} + +.blader2{ + height: 240px; + width: 250px; +} + +.circle1{ + align-items: center; + justify-content: center; + height: 180px; + width: 180px; + border-radius: 50%; + border: transparent; + border-top: 3px solid #fec53a; + animation: ani2 2s linear infinite; + /* background-image: url("assets/bey2.jpg"); */ + +} + +.circle2{ + width: 130px; + height: 130px; + border-radius: 50%; + border: transparent; + border-top: 3px solid rgb(0, 225, 255); + animation: ani 0.7s linear infinite; + margin-top: -50px; +} + +.circle1 #blade1{ + margin-left: 100px; +} + +.circle1 #blade2{ + width: 70px; + height: 80px; + margin-left: -20px; + margin-top: 0px; +} + +button { + margin-top: 10px; + padding: 10px 20px; + background-color: #333; + color: #fff; + border: none; + border-radius: 3px; + cursor: pointer; + transition: background-color 0.3s; +} + +button:hover { + background-color: #555; +} + +.circle2 img{ + height: 50px; + width: 50px; +} + + +.spin-animation { + animation: spin 1s infinite linear; + } + + @keyframes spin{ + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + + +.result { + margin-top: 30px; + font-size: 20px; + font-weight: bold; + } + +.score-label { + font-size: 18px; + font-weight: bold; + color: #555; + text-transform: uppercase; + margin-bottom: 5px; + } + +.score-value { + font-size: 24px; + color: #333; + } + + .stamina-label { + font-size: 18px; + font-weight: bold; + color: #555; + text-transform: uppercase; + margin-bottom: 5px; + } + + .stamina-value { + font-size: 24px; + color: #333; + } + + .game-over { + margin-top: 30px; + font-size: 24px; + font-weight: bold; + color: #333; + } + + .winner { + font-size: 30px; + color: #333; + } + + .tie { + color: #777; + } + + + +#game-container{ + display: flex; + justify-content: space-between; + align-items: left; + margin-top: 100px; + margin: 40px; +} + +#Stadium{ + width: 100%; + height: 500px; + align-items: center; + justify-content: center; + margin-top: 50px; +} + +.model{ + height: 400px; + width: 50%; + margin-left: 300px; +} + +#Stadium h2{ + color: white; + margin-top: 80px; + font-size: 30px; + align-items: center; +} + +#container3D{ + color: white; } \ No newline at end of file diff --git a/Games/Blink_Beat/README.md b/Games/Blink_Beat/README.md new file mode 100644 index 0000000000..e1d03d6596 --- /dev/null +++ b/Games/Blink_Beat/README.md @@ -0,0 +1,8 @@ + +# Blink Beat +A web-based game inspired by the classic Simon game, built using HTML, CSS, and JavaScript. + + +## Live Website + +https://github.com/Shantnu-singh/Blink-Beat \ No newline at end of file diff --git a/Games/Blink_Beat/Script.js b/Games/Blink_Beat/Script.js new file mode 100644 index 0000000000..8c92aa7113 --- /dev/null +++ b/Games/Blink_Beat/Script.js @@ -0,0 +1,121 @@ +var colorOptions = ["red", "blue", "yellow", "green"]; +var gamePattern = []; +var userChosenColor = []; +var levelCount = 0; +var started = false; + +// Generate the game sequence +function gameSequence() { + userChosenColor = []; + levelCount++; + document.querySelector("#level-title").innerHTML = "Level " + levelCount; + + var randomDigit = Math.floor(Math.random() * 4); + var newColor = colorOptions[randomDigit]; + gamePattern.push(newColor); + + $("." + newColor).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100); + playSound(newColor); +} + +// Handle user click/touch events +function handleUserClick(event) { + if (event.type === "touchstart") { + event.preventDefault(); + } + + var colorName = event.target.id; + userChosenColor.push(colorName); + + playSound(colorName); + animatePress(colorName); + + checkAnswer(userChosenColor.length - 1); +} + +// Play sound for a given color +function playSound(name) { + var audio = new Audio("sounds/" + name + ".mp3"); + audio.play(); +} + +// Animate the button press +function animatePress(name) { + $("#" + name).addClass("pressed"); + setTimeout(function() { + $("#" + name).removeClass("pressed"); + }, 100); +} + +// Start the game +function startGame(event) { + if (event.type === "touchstart") { + event.preventDefault(); + } + + if (!started) { + document.querySelector("#level-title").innerHTML = "Level " + (levelCount + 1); + gameSequence(); + started = true; + } +} + +// Check the user's answer +function checkAnswer(currentLevel) { + if (gamePattern[currentLevel] === userChosenColor[currentLevel]) { + if (userChosenColor.length === gamePattern.length) { + setTimeout(function() { + gameSequence(); + }, 1000); + } + } else { + document.querySelector("#level-title").innerHTML = "Game Over, Press Any Key or Touch the Screen to Restart"; + document.querySelector("body").classList.add("game-over"); + setTimeout(function() { + document.querySelector("body").classList.remove("game-over"); + }, 200); + playSound("wrong"); + + // Set up the event listeners to restart the game + document.addEventListener("keydown", restartGameOnEvent, { once: true }); + document.addEventListener("touchstart", restartGameOnEvent, { once: true }); + } +} + +// Restart the game +function restartGameOnEvent(event) { + if (event.type === "touchstart") { + event.preventDefault(); + } + restartTheGame(); +} + +function restartTheGame() { + levelCount = 0; + gamePattern = []; + started = false; + + // Remove existing event listeners to avoid multiple bindings + document.removeEventListener("keydown", restartGameOnEvent); + document.removeEventListener("touchstart", restartGameOnEvent); + + // Add event listeners to restart the game on key press or touch + document.addEventListener("keydown", startGame, { once: true }); + document.addEventListener("touchstart", startGame, { once: true }); +} + +// Initial event listeners to start the game +document.addEventListener("keydown", startGame, { once: true }); +document.addEventListener("touchstart", handleTouchStart, { once: true }); + +// Handle touch start event to start the game +function handleTouchStart(event) { + event.preventDefault(); + startGame(event); +} + +// Add event listeners to buttons +document.querySelectorAll(".btn").forEach(button => { + button.addEventListener("click", handleUserClick); + button.addEventListener("touchstart", handleUserClick); +}); diff --git a/Games/Blink_Beat/assets/images/Blibk_Beat_1.jpg b/Games/Blink_Beat/assets/images/Blibk_Beat_1.jpg new file mode 100644 index 0000000000..44d49260b3 Binary files /dev/null and b/Games/Blink_Beat/assets/images/Blibk_Beat_1.jpg differ diff --git a/Games/Blink_Beat/assets/images/Blink_Beat.png b/Games/Blink_Beat/assets/images/Blink_Beat.png new file mode 100644 index 0000000000..98bf0df247 Binary files /dev/null and b/Games/Blink_Beat/assets/images/Blink_Beat.png differ diff --git a/Games/Blink_Beat/assets/images/Blink_Beat_2.jpg b/Games/Blink_Beat/assets/images/Blink_Beat_2.jpg new file mode 100644 index 0000000000..e9c1fa8188 Binary files /dev/null and b/Games/Blink_Beat/assets/images/Blink_Beat_2.jpg differ diff --git a/Games/Blink_Beat/assets/images/Blink_Beat_3.jpg b/Games/Blink_Beat/assets/images/Blink_Beat_3.jpg new file mode 100644 index 0000000000..cd1314dcd5 Binary files /dev/null and b/Games/Blink_Beat/assets/images/Blink_Beat_3.jpg differ diff --git a/Games/Blink_Beat/assets/sounds/blue.mp3 b/Games/Blink_Beat/assets/sounds/blue.mp3 new file mode 100644 index 0000000000..ae68cbae3d Binary files /dev/null and b/Games/Blink_Beat/assets/sounds/blue.mp3 differ diff --git a/Games/Blink_Beat/assets/sounds/green.mp3 b/Games/Blink_Beat/assets/sounds/green.mp3 new file mode 100644 index 0000000000..896b9f968e Binary files /dev/null and b/Games/Blink_Beat/assets/sounds/green.mp3 differ diff --git a/Games/Blink_Beat/assets/sounds/red.mp3 b/Games/Blink_Beat/assets/sounds/red.mp3 new file mode 100644 index 0000000000..e7738ae95e Binary files /dev/null and b/Games/Blink_Beat/assets/sounds/red.mp3 differ diff --git a/Games/Blink_Beat/assets/sounds/wrong.mp3 b/Games/Blink_Beat/assets/sounds/wrong.mp3 new file mode 100644 index 0000000000..5ece8fd768 Binary files /dev/null and b/Games/Blink_Beat/assets/sounds/wrong.mp3 differ diff --git a/Games/Blink_Beat/assets/sounds/yellow.mp3 b/Games/Blink_Beat/assets/sounds/yellow.mp3 new file mode 100644 index 0000000000..b360c086d3 Binary files /dev/null and b/Games/Blink_Beat/assets/sounds/yellow.mp3 differ diff --git a/Games/Blink_Beat/index.html b/Games/Blink_Beat/index.html new file mode 100644 index 0000000000..b22cca46a8 --- /dev/null +++ b/Games/Blink_Beat/index.html @@ -0,0 +1,29 @@ + + + + + + Blink Beat + + + + + + +
+
+
+
+

Blink Beat

+

Test your memory and reflexes with Blink Beat! Follow the pattern of lights and sounds, and repeat the sequence. See how long you can go without making a mistake!

+ Play +
+ + + + + diff --git a/Games/Blink_Beat/landing_style.css b/Games/Blink_Beat/landing_style.css new file mode 100644 index 0000000000..20beb4553a --- /dev/null +++ b/Games/Blink_Beat/landing_style.css @@ -0,0 +1,73 @@ +body { + margin: 0; + padding: 0; + font-family: 'Press Start 2P', cursive; + background-color: #011F3F; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; +} + +.image-background { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: url('sounds/bg.png'); + background-size: cover; + background-position: center; + filter: brightness(50%); /* Adjust the opacity of the background image */ + z-index: -1; +} + +.overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(1, 31, 63, 0.7); /* Overlay color with opacity */ +} + +.container { + text-align: center; + color: #FEF2BF; + max-width: 600px; /* Constrain the width of the container */ + padding: 20px; /* Add some padding for better spacing */ +} + +#level-title { + font-size: 3rem; + margin: 20px 0; +} + +.description { + font-size: 1.5rem; + margin: 20px 0; + line-height: 1.5; +} + +.play-button { + display: inline-block; + padding: 15px 30px; + font-size: 2rem; + color: #FEF2BF; + background-color: #FF5733; /* Red background color */ + border: none; + border-radius: 10px; + text-decoration: none; + display: flex; + align-items: center; + justify-content: center; + margin-top: 30px; +} + +.play-button i { + margin-left: 10px; /* Adjust icon position */ +} + +.play-button:hover { + background-color: #FF6347; /* Darker red on hover */ +} diff --git a/Games/Blink_Beat/page.html b/Games/Blink_Beat/page.html new file mode 100644 index 0000000000..a0e04cbc7e --- /dev/null +++ b/Games/Blink_Beat/page.html @@ -0,0 +1,41 @@ + + + + + + Simon + + + + + +

Press A Key to Start

+
+
+ +
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + + + + diff --git a/Games/Blink_Beat/styles.css b/Games/Blink_Beat/styles.css new file mode 100644 index 0000000000..de4993c577 --- /dev/null +++ b/Games/Blink_Beat/styles.css @@ -0,0 +1,87 @@ +body { + text-align: center; + background-color: #011F3F; +} + +#level-title { + font-family: 'Press Start 2P', cursive; + font-size: 3rem; + margin: 5%; + color: #FEF2BF; +} + +.container { + display: block; + width: 50%; + margin: auto; +} + +.btn { + margin: 25px; + display: inline-block; + height: 200px; + width: 200px; + border: 10px solid black; + border-radius: 20%; +} + +.game-over { + background-color: red; + opacity: 0.8; +} + +.red { + background-color: red; +} + +.green { + background-color: green; +} + +.blue { + background-color: blue; +} + +.yellow { + background-color: yellow; +} + +.pressed { + box-shadow: 0 0 20px white; + background-color: grey; +} + +/* Media Queries for responsiveness */ +@media (max-width: 768px) { + #level-title { + font-size: 2rem; + margin: 5%; + } + + .container { + width: 80%; + } + + .btn { + height: 150px; + width: 150px; + margin: 15px; + } +} + +@media (max-width: 480px) { + #level-title { + font-size: 1.5rem; + margin: 5%; + } + + .container { + width: 100%; + } + + .btn { + height: 100px; + width: 100px; + margin: 10px; + } +} diff --git a/Games/Block_Dodger/README.md b/Games/Block_Dodger/README.md new file mode 100644 index 0000000000..9e15067a99 --- /dev/null +++ b/Games/Block_Dodger/README.md @@ -0,0 +1,43 @@ +# **Block Dodger Game** + + +
+ +## **Description 📃** +Block Dodger is a simple and addictive browser-based game where players control a character to dodge falling blocks. The goal is to survive as long as possible while accumulating a high score. + +
+ +## **functionalities 🎮** + +•Character Movement: The player can move the character left and right using the keyboard arrow keys. + +•Falling Blocks: Blocks fall from the top of the game area, and the player must dodge them to stay alive. + +•Score Tracking: The game tracks the player's score based on how many blocks they successfully dodge. + +•Game Over Display: When the game ends, the player's score is displayed on the screen. + +
+ +## **How to play? 🕹️** + +• Open index.html in a web browser to start the game. + +• Use the left (←) and right (→) arrow keys to move the character. + +• Avoid falling blocks and try to stay on screen as long as possible. + +• The game ends if the character goes off the top of the screen. + +• Your score is displayed when the game ends. +
+ +## **Screenshots 📸** +![image](https://github.com/AshishPandey04/GameZone/blob/newBranch/assets/images/Block_Dodger.png) +![image](https://github.com/AshishPandey04/GameZone/blob/newBranch/assets/images/Block_Dodger2.png) + +
+ + ## **Working video 📹** + ![vedio](https://github.com/AshishPandey04/GameZone/blob/newBranch/assets/animations/Block_Dodger.mp4) diff --git a/Games/Block_Dodger/index.html b/Games/Block_Dodger/index.html new file mode 100644 index 0000000000..a255907cf8 --- /dev/null +++ b/Games/Block_Dodger/index.html @@ -0,0 +1,32 @@ + + + + + + Falling Ball Game + + + + + + +
+
+ +
+ +

Use arrows keys to play game

+
+ + +
+ + + + + + \ No newline at end of file diff --git a/Games/Block_Dodger/script.js b/Games/Block_Dodger/script.js new file mode 100644 index 0000000000..04bdf3910a --- /dev/null +++ b/Games/Block_Dodger/script.js @@ -0,0 +1,119 @@ +var character = document.getElementById("character"); +var game = document.getElementById("game"); +var interval; +var both = 0; +var counter = 0; +var currentBlocks = []; + +function moveLeft() { + // to move the ball left + var left = parseInt( + window.getComputedStyle(character).getPropertyValue("left") + ); + if (left > 0) { + character.style.left = left - 2 + "px"; + } +} +function moveRight() { + // to move the ball right + var left = parseInt( + window.getComputedStyle(character).getPropertyValue("left") + ); + if (left < 380) { + character.style.left = left + 2 + "px"; + } +} +document.addEventListener("keydown", event => { + if (both == 0) { + both++; + if (event.key === "ArrowLeft") { + interval = setInterval(moveLeft, 1); + } + if (event.key === "ArrowRight") { + interval = setInterval(moveRight, 1); + } + } +}); +document.addEventListener("keyup", event => { + clearInterval(interval); + both = 0; +}); + +var blocks = setInterval(function () { + var blockLast = document.getElementById("block" + (counter - 1)); + var holeLast = document.getElementById("hole" + (counter - 1)); + if (counter > 0) { + var blockLastTop = parseInt( + window.getComputedStyle(blockLast).getPropertyValue("top") + ); + var holeLastTop = parseInt( + window.getComputedStyle(holeLast).getPropertyValue("top") + ); + } + if (blockLastTop < 400 || counter == 0) { + var block = document.createElement("div"); + var hole = document.createElement("div"); + block.setAttribute("class", "block"); + hole.setAttribute("class", "hole"); + block.setAttribute("id", "block" + counter); + hole.setAttribute("id", "hole" + counter); + block.style.top = blockLastTop + 100 + "px"; + hole.style.top = holeLastTop + 100 + "px"; + var random = Math.floor(Math.random() * 360); + hole.style.left = random + "px"; + game.appendChild(block); + game.appendChild(hole); + currentBlocks.push(counter); + counter++; + } + var characterTop = parseInt( + window.getComputedStyle(character).getPropertyValue("top") + ); + var characterLeft = parseInt( + window.getComputedStyle(character).getPropertyValue("left") + ); + var drop = 0; + if (characterTop <= 0) { + resultBox.innerHTML = "Game over. Score: " + (counter - 9); + resultBox.style.display = "block"; + clearInterval(blocks); + return; + } + for (var i = 0; i < currentBlocks.length; i++) { + let current = currentBlocks[i]; + let iblock = document.getElementById("block" + current); + let ihole = document.getElementById("hole" + current); + let iblockTop = parseFloat( + window.getComputedStyle(iblock).getPropertyValue("top") + ); + let iholeLeft = parseFloat( + window.getComputedStyle(ihole).getPropertyValue("left") + ); + iblock.style.top = iblockTop - 0.5 + "px"; + ihole.style.top = iblockTop - 0.5 + "px"; + if (iblockTop < -20) { + currentBlocks.shift(); + iblock.remove(); + ihole.remove(); + } + if (iblockTop - 20 < characterTop && iblockTop > characterTop) { + drop++; + if (iholeLeft <= characterLeft && iholeLeft + 20 >= characterLeft) { + drop = 0; + } + } + } + if (drop == 0) { + if (characterTop < 480) { + character.style.top = characterTop + 2 + "px"; + } + } else { + character.style.top = characterTop - 0.5 + "px"; + } +}, 1); + +function restartGame() { + location.reload(); +} + +startGame(); \ No newline at end of file diff --git a/Games/Block_Dodger/style.css b/Games/Block_Dodger/style.css new file mode 100644 index 0000000000..63c86a2432 --- /dev/null +++ b/Games/Block_Dodger/style.css @@ -0,0 +1,103 @@ +* { + padding: 0; + margin: 0; + box-sizing: border-box; + + } + + + .header { + margin-top: 1rem; + + padding: 3rem; + display: flex; + align-items: center; + justify-content: center; + font-size: 3rem; + background-color: rgb(3, 3, 45); + color: white; + border-radius: 5rem; + cursor: pointer; + } + + #game { + + width: 400px; + height: 500px; + border: 2px solid rgb(14, 7, 106); + margin: auto; + margin-top: 2rem; + overflow: hidden; + } + + #character { + width: 20px; + height: 20px; + background-color: rgba(8, 144, 255, 0.979); + border-radius: 50%; + position: relative; + top: 400px; + left: 190px; + z-index: 1000000; + } + + + h3{ + font-size: 1.25rem; + } + + #resultBox { + display: none; + position: absolute; + top: 45%; + left: 50%; + transform: translate(-50%, -50%); + background-color: white; + border: 2px solid black; + padding: 20px; + text-align: center; + font-weight: bold; + + } + + + .block { + width: 400px; + height: 20px; + background-color: rgb(70, 65, 65); + position: relative; + top: 100px; + margin-top: -20px; + } + + .hole { + width: 40px; + height: 20px; + background-color: white; + position: relative; + top: 100px; + margin-top: -20px; + } + + #restartButton { + display: flex; + align-items: center; + justify-content: center; + width: 10vw; + margin: 10px auto; + padding: 10px 20px; + background-color:rgb(3, 3, 45); + color: white; + border: 2px solid rgba(92, 90, 90, 0.242); + box-shadow: 10cap; + font-size: 2rem; + border-radius: 2cap; + cursor: pointer; + + } + + #restartButton:hover { + background-color: #45a049; + } + + \ No newline at end of file diff --git a/Games/Boom_Blast/asset/images/Boom_Blast_gameplay.png b/Games/Boom_Blast/asset/images/Boom_Blast_gameplay.png new file mode 100644 index 0000000000..c2a764b170 Binary files /dev/null and b/Games/Boom_Blast/asset/images/Boom_Blast_gameplay.png differ diff --git a/Games/Boom_Blast/asset/images/Boom_Blast_option.png b/Games/Boom_Blast/asset/images/Boom_Blast_option.png new file mode 100644 index 0000000000..670724faac Binary files /dev/null and b/Games/Boom_Blast/asset/images/Boom_Blast_option.png differ diff --git a/Games/Boom_Blast/asset/images/Boom_Blast_scoring.png b/Games/Boom_Blast/asset/images/Boom_Blast_scoring.png new file mode 100644 index 0000000000..eeb5e11098 Binary files /dev/null and b/Games/Boom_Blast/asset/images/Boom_Blast_scoring.png differ diff --git a/Games/Boom_Blast/asset/images/Boom_Blast_start.png b/Games/Boom_Blast/asset/images/Boom_Blast_start.png new file mode 100644 index 0000000000..06f103bd96 Binary files /dev/null and b/Games/Boom_Blast/asset/images/Boom_Blast_start.png differ diff --git a/Games/Boom_Blast/asset/images/desktop.ini b/Games/Boom_Blast/asset/images/desktop.ini new file mode 100644 index 0000000000..a649d61466 --- /dev/null +++ b/Games/Boom_Blast/asset/images/desktop.ini @@ -0,0 +1,5 @@ +[LocalizedFileNames] +Screenshot 2024-07-23 101337.png=@Screenshot 2024-07-23 101337,0 +Screenshot 2024-07-23 101316.png=@Screenshot 2024-07-23 101316,0 +Screenshot 2024-07-23 101249.png=@Screenshot 2024-07-23 101249,0 +Screenshot 2024-07-23 101237.png=@Screenshot 2024-07-23 101237,0 diff --git a/Games/Boom_Blast/index.html b/Games/Boom_Blast/index.html new file mode 100644 index 0000000000..890dcb7da5 --- /dev/null +++ b/Games/Boom_Blast/index.html @@ -0,0 +1,27 @@ + + + + + + BOOM BLAST + + + +
BOOM BLAST
+
Score: 0
+
Time: 30s
+
+
+
+
+ + +
+ + + \ No newline at end of file diff --git a/Games/Boom_Blast/readme.md b/Games/Boom_Blast/readme.md new file mode 100644 index 0000000000..8a3649cc7b --- /dev/null +++ b/Games/Boom_Blast/readme.md @@ -0,0 +1,62 @@ +# BOOM BLAST + +BOOM BLAST is a fun and colorful browser-based game where players click on balloons to score points before time runs out. + +## Table of Contents + +- [Features](#features) +- [Installation](#installation) +- [How to Play](#how-to-play) +- [Game Mechanics](#game-mechanics) +- [Customization](#customization) +- [Technologies Used](#technologies-used) + +## Features + +- Vibrant, dynamic background +- Colorful balloons with gradient effects +- Customizable game duration +- Real-time score and timer display +- Responsive design + +## Installation + +1. Clone this repository . +```bash + clone git https://github.com/kunjgit/GameZone/tree/main/Games/Boom_Blast +``` +2. Open the `index.html` file in a web browser to start the game. + +## How to Play + +1. Open the game in a web browser. +2. Select the desired game duration from the dropdown menu. +3. Click the "Start Game" button to begin. +4. Click on the balloons as they appear to score points. +5. Try to click as many balloons as possible before time runs out. +6. When the game ends, your final score will be displayed. +7. Click "Start Game" again to play another round. + +## Game Mechanics + +- Balloons appear randomly within the game area every second. +- Each balloon has a random size and color gradient. +- Clicking a balloon adds 1 point to your score and removes the balloon. +- Balloons automatically disappear after 2 seconds if not clicked. +- The game ends when the timer reaches zero. + +## Customization + +You can customize the game by modifying the following: + +- Game duration options in the HTML file +- Colors and animations in the CSS file +- Balloon spawn rate and game logic in the JavaScript file + +## Technologies Used + +- HTML5 +- CSS3 +- JavaScript (ES6+) + +Feel free to fork this project and customize it to your liking. Enjoy playing BOOM BLAST! \ No newline at end of file diff --git a/Games/Boom_Blast/script.js b/Games/Boom_Blast/script.js new file mode 100644 index 0000000000..cebdc588bc --- /dev/null +++ b/Games/Boom_Blast/script.js @@ -0,0 +1,98 @@ +const gameArea = document.getElementById('game-area'); +const startButton = document.getElementById('start-button'); +const scoreElement = document.getElementById('score'); +const timerElement = document.getElementById('timer'); +const gameOverElement = document.getElementById('game-over'); +const timeSelect = document.getElementById('time-select'); + +let score = 0; +let timeLeft = 30; +let gameInterval; +let balloonInterval; + +startButton.addEventListener('click', startGame); + +function startGame() { + score = 0; + timeLeft = parseInt(timeSelect.value); + updateScore(); + updateTimer(); + startButton.disabled = true; + timeSelect.disabled = true; + gameOverElement.style.display = 'none'; + clearInterval(gameInterval); + clearInterval(balloonInterval); + + gameInterval = setInterval(() => { + timeLeft--; + updateTimer(); + if (timeLeft <= 0) { + endGame(); + } + }, 1000); + + balloonInterval = setInterval(createBalloon, 1000); +} + +function createBalloon() { + const balloon = document.createElement('div'); + balloon.classList.add('balloon'); + const size = Math.random() * 50 + 20; + const colors = getRandomGradient(); + + balloon.style.width = `${size}px`; + balloon.style.height = `${size}px`; + balloon.style.background = colors; + balloon.style.left = `${Math.random() * (gameArea.clientWidth - size)}px`; + balloon.style.top = `${Math.random() * (gameArea.clientHeight - size)}px`; + + balloon.addEventListener('click', () => { + score++; + updateScore(); + gameArea.removeChild(balloon); + }); + + gameArea.appendChild(balloon); + + setTimeout(() => { + if (gameArea.contains(balloon)) { + gameArea.removeChild(balloon); + } + }, 2000); +} + +function getRandomGradient() { + const color1 = getRandomColor(); + const color2 = getRandomColor(); + return `radial-gradient(circle, ${color1}, ${color2})`; +} + +function getRandomColor() { + const letters = '0123456789ABCDEF'; + let color = '#'; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; +} + +function updateScore() { + scoreElement.textContent = `Score: ${score}`; +} + +function updateTimer() { + timerElement.textContent = `Time: ${timeLeft}s`; +} + +function endGame() { + clearInterval(gameInterval); + clearInterval(balloonInterval); + gameOverElement.textContent = `Game Over! Final Score: ${score}`; + gameOverElement.style.display = 'block'; + startButton.disabled = false; + timeSelect.disabled = false; + while (gameArea.firstChild) { + gameArea.removeChild(gameArea.firstChild); + } + gameArea.appendChild(gameOverElement); +} \ No newline at end of file diff --git a/Games/Boom_Blast/style.css b/Games/Boom_Blast/style.css new file mode 100644 index 0000000000..7bc846cdc3 --- /dev/null +++ b/Games/Boom_Blast/style.css @@ -0,0 +1,101 @@ +body { + margin: 0; + padding: 0; + font-family: Arial, sans-serif; + background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); + background-size: 400% 400%; + animation: gradient 15s ease infinite; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +#game-title { + font-size: 48px; + font-weight: bold; + color: #fff; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); + margin-bottom: 20px; +} + +#game-area { + width: 600px; + height: 400px; + background-color: rgba(255, 255, 255, 0.2); + border-radius: 10px; + position: relative; + overflow: hidden; +} + +.balloon { + position: absolute; + border-radius: 50%; + cursor: pointer; + animation: float 2s ease-in-out infinite; +} + +@keyframes float { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} + +#score, #timer { + font-size: 24px; + color: #fff; + margin: 10px 0; +} + +#controls { + display: flex; + gap: 10px; + margin-top: 10px; +} + +#start-button, #time-select { + font-size: 20px; + padding: 10px 20px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.3s; +} + +#start-button:hover { + background-color: #45a049; +} + +#time-select { + background-color: #3498db; +} + +#time-select:hover { + background-color: #2980b9; +} + +#game-over { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 36px; + font-weight: bold; + color: #fff; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); + display: none; +} \ No newline at end of file diff --git a/Games/Brain_card_game/assets/braincard.png b/Games/Brain_card_game/assets/braincard.png new file mode 100644 index 0000000000..6cd7eaaeaa Binary files /dev/null and b/Games/Brain_card_game/assets/braincard.png differ diff --git a/Games/Brain_card_game/index.html b/Games/Brain_card_game/index.html new file mode 100644 index 0000000000..b4bbd6c577 --- /dev/null +++ b/Games/Brain_card_game/index.html @@ -0,0 +1,26 @@ + + + + + + + Brain Game + + + + +
+
+ +
+
0 moves
+
Time: 0 sec
+
+
+
+
+
You won!
+
+
+ + \ No newline at end of file diff --git a/Games/Brain_card_game/index.js b/Games/Brain_card_game/index.js new file mode 100644 index 0000000000..d2618fb511 --- /dev/null +++ b/Games/Brain_card_game/index.js @@ -0,0 +1,148 @@ +const selectors = { + boardContainer: document.querySelector('.board-container'), + board: document.querySelector('.board'), + moves: document.querySelector('.moves'), + timer: document.querySelector('.timer'), + start: document.querySelector('button'), + win: document.querySelector('.win') +} + +const state = { + gameStarted: false, + flippedCards: 0, + totalFlips: 0, + totalTime: 0, + loop: null +} + +const shuffle = array => { + const clonedArray = [...array] + + for (let index = clonedArray.length - 1; index > 0; index--) { + const randomIndex = Math.floor(Math.random() * (index + 1)) + const original = clonedArray[index] + + clonedArray[index] = clonedArray[randomIndex] + clonedArray[randomIndex] = original + } + + return clonedArray +} + +const pickRandom = (array, items) => { + const clonedArray = [...array] + const randomPicks = [] + + for (let index = 0; index < items; index++) { + const randomIndex = Math.floor(Math.random() * clonedArray.length) + + randomPicks.push(clonedArray[randomIndex]) + clonedArray.splice(randomIndex, 1) + } + + return randomPicks +} + +const generateGame = () => { + const dimensions = selectors.board.getAttribute('data-dimension') + + if (dimensions % 2 !== 0) { + throw new Error("The dimension of the board must be an even number.") + } + + const emojis = ['🥔', '🍒', '🥑', '🌽', '🥕', '🍇', '🍉', '🍌', '🥭', '🍍'] + const picks = pickRandom(emojis, (dimensions * dimensions) / 2) + const items = shuffle([...picks, ...picks]) + const cards = ` +
+ ${items.map(item => ` +
+
+
${item}
+
+ `).join('')} +
+ ` + + const parser = new DOMParser().parseFromString(cards, 'text/html') + + selectors.board.replaceWith(parser.querySelector('.board')) +} + +const startGame = () => { + state.gameStarted = true + selectors.start.classList.add('disabled') + + state.loop = setInterval(() => { + state.totalTime++ + + selectors.moves.innerText = `${state.totalFlips} moves` + selectors.timer.innerText = `time: ${state.totalTime} sec` + }, 1000) +} + +const flipBackCards = () => { + document.querySelectorAll('.card:not(.matched)').forEach(card => { + card.classList.remove('flipped') + }) + + state.flippedCards = 0 +} + +const flipCard = card => { + state.flippedCards++ + state.totalFlips++ + + if (!state.gameStarted) { + startGame() + } + + if (state.flippedCards <= 2) { + card.classList.add('flipped') + } + + if (state.flippedCards === 2) { + const flippedCards = document.querySelectorAll('.flipped:not(.matched)') + + if (flippedCards[0].innerText === flippedCards[1].innerText) { + flippedCards[0].classList.add('matched') + flippedCards[1].classList.add('matched') + } + + setTimeout(() => { + flipBackCards() + }, 100) + } + + // If there are no more cards that we can flip, we won the game + if (!document.querySelectorAll('.card:not(.flipped)').length) { + setTimeout(() => { + selectors.boardContainer.classList.add('flipped') + selectors.win.innerHTML = ` + + You won!
+ with ${state.totalFlips} moves
+ under ${state.totalTime} seconds +
+ ` + + clearInterval(state.loop) + }, 1000) + } +} + +const attachEventListeners = () => { + document.addEventListener('click', event => { + const eventTarget = event.target + const eventParent = eventTarget.parentElement + + if (eventTarget.className.includes('card') && !eventParent.className.includes('flipped')) { + flipCard(eventParent) + } else if (eventTarget.nodeName === 'BUTTON' && !eventTarget.className.includes('disabled')) { + startGame() + } + }) +} + +generateGame() +attachEventListeners() \ No newline at end of file diff --git a/Games/Brain_card_game/readme.md b/Games/Brain_card_game/readme.md new file mode 100644 index 0000000000..99a6127349 --- /dev/null +++ b/Games/Brain_card_game/readme.md @@ -0,0 +1,28 @@ +# **BRAIN Card GAME** + +--- + +
+ +## **Description 📃** +- This project is built on a basic web tech stacks such as HTML, CSS and Javascript. +- This is a single-player game. + +
+ +## **Functionalities 🎮** +- Click on the boxes that are formed randomly. +- The boxes with same image will remain opened and without will be closed instantly +- There will be timer and moves to note in how much moves and time have you solve this game. +
+ + +
+ +## **Screenshots 📸** + +
+ +![image](./assets/braincard.png) + +
diff --git a/Games/Brain_card_game/style.css b/Games/Brain_card_game/style.css new file mode 100644 index 0000000000..60b8e9f609 --- /dev/null +++ b/Games/Brain_card_game/style.css @@ -0,0 +1,127 @@ + +html { + width: 100%; + height: 100%; + background: linear-gradient(325deg, #03001e 0%, #7303c0 30%, #ec38bc 70%, #fdeff9 100%); + font-family: Arial, Helvetica, sans-serif; + overflow: hidden; +} + +.container { + display: flex; +} + +.game { + position: relative; + margin-left: 40px; +} + +.game { + position: absolute; + top: 50%; + left: 70%; + transform: translate(-50%, -50%); +} +.controls { + display: flex; + gap: 20px; + margin-bottom: 20px; +} +button { + background: #282A3A; + color: #FFF; + border-radius: 5px; + padding: 10px 20px; + border: 0; + cursor: pointer; + font-family: Arial, Helvetica, sans-serif; + font-size: 18pt; + font-weight: bold; +} +button:hover { + color: yellow; + transform: scale(1.1); + transition: 0.4s ease; +} +.disabled { + color: #757575; +} +.stats { + color: #FFF; + font-size: 14pt; + font-weight: bold; +} +.board-container { + position: relative; +} +.board, +.win { + border-radius: 5px; + box-shadow: 0 25px 50px rgb(33 33 33 / 25%); + background: linear-gradient(135deg, #03001e 0%,#7303c0 0%,#ec38bc 50%, #fdeff9 100%); + transition: transform .6s cubic-bezier(0.4, 0.0, 0.2, 1); + backface-visibility: hidden; +} +.board { + padding: 20px; + display: grid; + grid-template-columns: repeat(4, auto); + grid-gap: 20px; +} +.board-container.flipped .board { + transform: rotateY(180deg) rotateZ(50deg); +} +.board-container.flipped .win { + transform: rotateY(0) rotateZ(0); +} +.card { + position: relative; + width: 100px; + height: 100px; + cursor: pointer; +} +.card-front, +.card-back { + position: absolute; + border-radius: 5px; + width: 100%; + height: 100%; + background: #282A3A; + transition: transform .6s cubic-bezier(0.4, 0.0, 0.2, 1); + backface-visibility: hidden; +} +.card-back { + transform: rotateY(180deg) rotateZ(50deg); + font-size: 28pt; + user-select: none; + text-align: center; + line-height: 100px; + background: #FDF8E6; +} +.card.flipped .card-front { + transform: rotateY(180deg) rotateZ(50deg); +} +.card.flipped .card-back { + transform: rotateY(0) rotateZ(0); +} +.win { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; + background: #FDF8E6; + transform: rotateY(180deg) rotateZ(50deg); +} +.win-text { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 21pt; + color: #282A3A; +} +.highlight { + color: #7303c0; +} \ No newline at end of file diff --git a/Games/Bubble_Shooter/Bubble Shooter.png b/Games/Bubble_Shooter/Bubble Shooter.png new file mode 100644 index 0000000000..b052c8f86e Binary files /dev/null and b/Games/Bubble_Shooter/Bubble Shooter.png differ diff --git a/Games/Bubble_Shooter/README.md b/Games/Bubble_Shooter/README.md new file mode 100644 index 0000000000..b7488c4fcc --- /dev/null +++ b/Games/Bubble_Shooter/README.md @@ -0,0 +1,17 @@ +# **Game_Name** + +Bubble Shooter + +## **Description 📃** + +Bubble Shooter is a frontend game developed using HTML, CSS, JavaScript. +Bubble Shooter is a classic arcade-style game where players aim and shoot colored bubbles from a cannon at the bottom of the screen to match three or more bubbles of the same color. +Players earn points in Bubble Shooter by successfully matching and popping groups of three or more bubbles of the same color, with larger groups and chain reactions yielding higher scores. + +## **How to play? 🕹️** + +Aim the cannon using your mouse or touchscreen, then shoot bubbles to match three or more of the same color to make them pop. + +## **Screenshots 📸** + +![image](https://github.com/SiriAmarlapudi/GameZone/blob/main/assets/images/Bubble%20Shooter.png) diff --git a/Games/Bubble_Shooter/index.html b/Games/Bubble_Shooter/index.html new file mode 100644 index 0000000000..77ae09a82f --- /dev/null +++ b/Games/Bubble_Shooter/index.html @@ -0,0 +1,47 @@ + + + +

Bubble Shooter

+ + + + Bubble Shooter + + + + +
+ +
+ + + + + + + + + diff --git a/Games/Bubble_Shooter/script.js b/Games/Bubble_Shooter/script.js new file mode 100644 index 0000000000..bcb69c2f28 --- /dev/null +++ b/Games/Bubble_Shooter/script.js @@ -0,0 +1,342 @@ +var canvas = document.getElementById("game-canvas"); +var ctx = canvas.getContext("2d"); +var rectangle = canvas.getBoundingClientRect(); +var mouse = {}; +var game_grid = null; + +var game_width = canvas.width; +var game_height = canvas.height; +var fixed = false; + +var defaultZ = canvas.style.zIndex + +var initial_colors = ['red', 'blue', '#eddd2d', '#54e202'] +var add_colors = ['#00d8ff', 'magenta', '#c46907'] +var game_colors = initial_colors.slice(0) + +mouse.x = 0; +mouse.y = 0; +mouse.down = 0; +mouse.prev_down = 0; +mouse.held = 0; + +//setup mouse listener +document.addEventListener('mousemove', mouse_move, false) +canvas.addEventListener('mousedown', function(evt) {mouse.down = 1}, false) +canvas.addEventListener('mouseup', function(evt) {mouse.down = 0; click_buttons(evt)}, false) +document.addEventListener('touchmove', touch_move, false) +canvas.addEventListener('touchstart', function(evt) {mouse.down = 1; touch_move(evt)}, false) +canvas.addEventListener('touchend', function(evt) {mouse.down = 0; click_buttons(evt)}, false) + +//setup rescale listener +window.onresize = function(evt) {rescale()}; + +var delay = 10 //delay between frames, 10 ms +//Get start time +var prev_time = new Date().getTime() + +//List of all things to draw on the screen. +var game_objects = {} +var object_layers = {} +var buttons = {} +var layers = [] +var added = 0 +var sf = 1 + +//Max elapsed time per frame +var max_elapsed = 25 + +//call setup function +setup() + +function get_color() +{ + return game_colors[Math.floor(Math.random() * game_colors.length)]; +} + +function touch_move(e) +{ + var touch = e.touches[0]; + rectangle = canvas.getBoundingClientRect(); + var x = touch.clientX - rectangle.left; + var y = touch.clientY - rectangle.top; + mouse.x = x / sf; + mouse.y = y / sf; +} + +//function to track mouse movement +function mouse_move(e) +{ + rectangle = canvas.getBoundingClientRect(); + var x = e.clientX - rectangle.left; + var y = e.clientY - rectangle.top; + mouse.x = x / sf; + mouse.y = y / sf; +} + +function click_buttons(evt) { + if(mouse.down == 0 && mouse.prev_down == 1) { + button_ids = Object.keys(buttons); + for(var index = 0; index < button_ids.length; index++) { + button = buttons[button_ids[index]] + if (button.intersect(mouse.x, mouse.y)) { + button.fn() + } + } + } +} + +//Adds a button to the screen +function add_button(button, layer=0) +{ + id = add_object(button, layer) + buttons[id] = button + return id +} + +//Removes a button from the screen +function remove_button(id) +{ + console.log(id) + if(id in buttons) { + remove_object[id] + delete buttons[id] + } +} + +//Adds an object and returns the object's id +function add_object(object, layer=0) +{ + game_objects[added] = object + object.id = added + object.layer = layer; + //check if the layer exists, if not create it + if (!(layer in object_layers)) { + object_layers[layer] = {} + layers.push(layer); + layers.sort(function(a, b) { + aNum = parseInt(a) + bNum = parseInt(b); + if (aNum == bNum) + return 0 + if (aNum > bNum) + return 1 + return 0 + }) + } + //Add object to layer + object_layers[layer][object.id] = 0 + added += 1 + return object.id +} + +//Removes an object from the draw hash table +function remove_object(id) +{ + //find object layer and delete it from layer + for (var index = 0; index < layers.length; index++) { + layer = layers[index] + if(id in object_layers[layer]) { + delete object_layers[layer][id] + } + } + //remove object from game_objects + return delete game_objects[id] +} + +//resets the game +function reset() +{ + game_colors = initial_colors.slice(0); + game_manager.remove_self() + ball_shooter.remove_self() + game_grid.remove_self() + + //add ball shooter + ball_shooter = new shooter(game_width / 2, game_height - 20, 10, 75, 400, get_color); + add_object(ball_shooter, -1) + ball_shooter.load(get_color); + + //Create game grid + game_grid = new grid(22, 10, 1, 14, 10); + //add game grid + add_object(game_grid) + //add a ball to the grid + game_grid.add_rows(get_color, 5) + + game_manager = new manager(ball_shooter, game_grid) + add_object(game_manager, 10) +} + +//draw function +function draw() +{ + //clear canvas at start of frame + clear(); + + //get current time + var date = new Date() + var time = date.getTime() + //calculate elapsed (in seconds) + var elapsed = (time - prev_time) / 1000.0 + elapsed = Math.min(elapsed, max_elapsed) + + //iterate over the game objects and draw them all + //start out at layer 0, then progress up + layers.forEach( function(layer) { + //get keys + object_keys = Object.keys(object_layers[layer]) + for(var index = 0; index < object_keys.length; index++) + { + if (object_keys[index] in game_objects) + game_objects[object_keys[index]].draw(elapsed) + } + }) + + //update mouse + mouse.prev_down = mouse.down + if (mouse.down) + { + mouse.held += elapsed + } + else + { + mouse.held = 0 + } + + //update previous time + prev_time = time +} + +function rescale() { + canvas.width = game_width + canvas.height = game_height + sf = 1 + canvas.style.zIndex = defaultZ + canvas.style.position = 'relative' + ctx.scale(1, 1) + canvas.style.left = 0 + canvas.style.top = 0 + if(fixed) { + width = window.innerWidth; + height = window.innerHeight; + temp_sf = Math.min(width / canvas.width, height / canvas.height) + sf = temp_sf + canvas.width = canvas.width * sf + canvas.height = canvas.height * sf + ctx.scale(sf, sf) + canvas.style.position = 'fixed' + canvas.style.zIndex = '999' + canvas.style.left = window.innerWidth / 2 - canvas.width / 2 + canvas.style.top = window.innerHeight / 2 - canvas.height / 2 + } +} + +//This function will clear the canvas between frames +function clear() +{ + ctx.clearRect(0, 0, game_width, game_height); +} + +var ball_shooter +var game_grid +var game_manager + +//setup the scene +function setup() +{ + //add ball shooter + ball_shooter = new shooter(game_width / 2, game_height - 20, 10, 75, 400, get_color); + add_object(ball_shooter, -1) + ball_shooter.load(get_color); + + //Create game grid + game_grid = new grid(22, 10, 1, 14, 10); + //add game grid + add_object(game_grid) + //add a ball to the grid + game_grid.add_rows(get_color, 5) + + game_manager = new manager(ball_shooter, game_grid) + add_object(game_manager, 10) + + rescale() +} + +function draw_button(x, y, content, gap=10, text_size=30, border_radius = 10, + border_thickness=3, font="Comic Sans MS", fill='#eee', text_color='red', + fill_hover='#ccc', text_hover='#ddd', fill_down='#aaa', text_down='#bbb', + border='black', text_border='red') +{ + ctx.textAlign = "center"; + pressed = false + ctx.font = text_size + "px " + font; + var retry = content + var box_width = ctx.measureText(retry).width + + if(mouse.x >= x - box_width / 2 - gap && + mouse.x <= x - box_width / 2 + box_width + gap && + mouse.y >= y && mouse.y <= y + text_size + gap) + { + fill = fill_hover + text_color = text_hover + if(mouse.down) { + fill = fill_down + text_color = text_down + } + if(mouse.prev_down && !mouse.down) + { + pressed = true; + } + } + ctx.fillStyle = fill; + fillRoundRect(x - box_width / 2 - gap, y, + box_width + gap * 2, text_size + gap, border_radius) + ctx.fillStyle = border + roundRect(x - box_width / 2 - gap, y, + box_width + gap * 2, text_size + gap, border_radius, border_thickness) + ctx.fillStyle = text_color + ctx.fillText(retry, x, y + text_size) + ctx.fillStyle = text_border + ctx.lineWidth = 1 + ctx.strokeText(retry, x, y + text_size) + return pressed; +} + +function fillRoundRect(x, y, w, h, radius) +{ + var r = x + w; + var b = y + h; + ctx.beginPath(); + ctx.lineWidth="4"; + ctx.moveTo(x+radius, y); + ctx.lineTo(r-radius, y); + ctx.quadraticCurveTo(r, y, r, y+radius); + ctx.lineTo(r, y+h-radius); + ctx.quadraticCurveTo(r, b, r-radius, b); + ctx.lineTo(x+radius, b); + ctx.quadraticCurveTo(x, b, x, b-radius); + ctx.lineTo(x, y+radius); + ctx.quadraticCurveTo(x, y, x+radius, y); + ctx.fill(); +} + +function roundRect(x, y, w, h, radius, thickness=4) +{ + var r = x + w; + var b = y + h; + ctx.beginPath(); + ctx.lineWidth=thickness; + ctx.moveTo(x+radius, y); + ctx.lineTo(r-radius, y); + ctx.quadraticCurveTo(r, y, r, y+radius); + ctx.lineTo(r, y+h-radius); + ctx.quadraticCurveTo(r, b, r-radius, b); + ctx.lineTo(x+radius, b); + ctx.quadraticCurveTo(x, b, x, b-radius); + ctx.lineTo(x, y+radius); + ctx.quadraticCurveTo(x, y, x+radius, y); + ctx.stroke(); +} + +setInterval(draw, delay) diff --git a/Games/Bubble_Shooter/style.css b/Games/Bubble_Shooter/style.css new file mode 100644 index 0000000000..c5dbb3603d --- /dev/null +++ b/Games/Bubble_Shooter/style.css @@ -0,0 +1,34 @@ +:root { + --background-light-color: #67ebd7; + --background-dark-color: #24a88b; + --main-background-gradient: linear-gradient(to right, var(--background-light-color) 0%, var(--background-dark-color) 100%); + } + + + body{ + background: var(--main-background-gradient); + overflow: hidden; + margin: 0; + padding: 0; + text-align: center; + } + #container{ + margin-top: 10%; + display: inline-block; + } + canvas{ + background: #cecece; + border: 1px solid #181818; + } + h1{ + color: black; + font-size: 50px; + font-weight: bold; + font-style: italic; + text-decoration: underline; + background-color: pink; + padding: 10px; + border: 2px solid red; + text-align: center; + font-family: 'Arial', sans-serif; +} diff --git a/Games/Buliding Block Game/Readme.md b/Games/Building Block Game/Readme.md similarity index 100% rename from Games/Buliding Block Game/Readme.md rename to Games/Building Block Game/Readme.md diff --git a/Games/Buliding Block Game/assets b/Games/Building Block Game/assets similarity index 100% rename from Games/Buliding Block Game/assets rename to Games/Building Block Game/assets diff --git a/Games/Buliding Block Game/index.html b/Games/Building Block Game/index.html similarity index 100% rename from Games/Buliding Block Game/index.html rename to Games/Building Block Game/index.html diff --git a/Games/Buliding Block Game/script.js b/Games/Building Block Game/script.js similarity index 100% rename from Games/Buliding Block Game/script.js rename to Games/Building Block Game/script.js diff --git a/Games/Buliding Block Game/style.css b/Games/Building Block Game/style.css similarity index 100% rename from Games/Buliding Block Game/style.css rename to Games/Building Block Game/style.css diff --git a/Games/Bulls_And_Cows_New/README.MD b/Games/Bulls_And_Cows_New/README.MD new file mode 100644 index 0000000000..24f91eaf53 --- /dev/null +++ b/Games/Bulls_And_Cows_New/README.MD @@ -0,0 +1,24 @@ +## Description:- +- The computer will have a unique 4-digit number while the player tries to guess it. +- The number to be guessed must be a 4 digit number, using unique digits only from 0 - 9(0 should not be the first digit) +- e.g. 1874 is valid, 0172 is not valid, 9877 is not valid, 9536 is valid. + +### For every guess that the player makes, he gets 2 values - the number of bulls and the number of cows. +- 1 bull means the guess and the target number have 1 digit in common, and in the correct position. +- 1 cow means the guess and the target number have 1 digit in common, but not in correct position. +Eg. Let the target be 1234. Guessing 4321 will give 0 bulls and 4 cows. 3241 will give 1 bull and 3 cows. 4 bulls means you have won the game! + +## Rules:- +The player gets total 7 chances to correctly guess the entire number and is awarded points in accordance to the number of guesses it took to win + +- 1 guess - 70 points +- 2 guess - 60 points +- 3 guess - 50 points +- 4 guess - 40 points +- 5 guess - 30 points +- 6 guess - 20 points +- 7 guess - 10 points +- if the player cannot guess then 0 points + +## Screenshot:- +![Bulls And Cows game Image](./assets/Bulls_And_Cows_New.png) \ No newline at end of file diff --git a/Games/Bulls_And_Cows_New/assets/Bulls_And_Cows_New.png b/Games/Bulls_And_Cows_New/assets/Bulls_And_Cows_New.png new file mode 100644 index 0000000000..a0c74dc9e2 Binary files /dev/null and b/Games/Bulls_And_Cows_New/assets/Bulls_And_Cows_New.png differ diff --git a/Games/Bulls_And_Cows_New/assets/arcade_game.jpg b/Games/Bulls_And_Cows_New/assets/arcade_game.jpg new file mode 100644 index 0000000000..363905984d Binary files /dev/null and b/Games/Bulls_And_Cows_New/assets/arcade_game.jpg differ diff --git a/Games/Bulls_And_Cows_New/index.html b/Games/Bulls_And_Cows_New/index.html new file mode 100644 index 0000000000..d5f9bf00b7 --- /dev/null +++ b/Games/Bulls_And_Cows_New/index.html @@ -0,0 +1,48 @@ + + + + + + Code Cracker Game + + + + +
+
+

Bulls And Cows

+
+ +
+
+ + +
+
+
    +
  • Bulls: Correct digit in the correct position.
  • +
  • Cows: Correct digit in the wrong position.
  • +
+ How to Play: +
    +
  • You have 7 chances to guess the entire 4-digit number.
  • +
  • You will be awarded points based on the number of guesses it took to win.
  • +
  • 1 guess - 70 points, 2 guesses - 60 points,..., 7 guesses - 10 points.
  • +
  • If you cannot guess the number in 7 attempts, you will score 0 points.
  • + +
  • Keep guessing until you crack the code!
  • +
+
+
+ + + + + + \ No newline at end of file diff --git a/Games/Bulls_And_Cows_New/script.js b/Games/Bulls_And_Cows_New/script.js new file mode 100644 index 0000000000..7c6861c51c --- /dev/null +++ b/Games/Bulls_And_Cows_New/script.js @@ -0,0 +1,95 @@ +// JavaScript +let hiddenPattern = createRandomSequence(); +let attemptLog = []; +let attempts = 0; +let score = 0; + +function createRandomSequence() { + const distinctNumbers = new Set(); + while (distinctNumbers.size < 4) { + distinctNumbers.add(Math.floor(Math.random() * 10)); + } + return Array.from(distinctNumbers).join(""); +} + +function evaluateGuess() { + const userAttempt = document.getElementById("guess-input").value; + let exactMatches = 0; + let partialMatches = 0; + + for (let i = 0; i < 4; i++) { + if (userAttempt[i] === hiddenPattern[i]) { + exactMatches++; + } else if (hiddenPattern.includes(userAttempt[i]) && userAttempt[i]!== hiddenPattern[i]) { + partialMatches++; + } + } + + const resultMessage = `${exactMatches} Bull${exactMatches!== 1? "s" : ""} and ${partialMatches} Cow${partialMatches!== 1? "es" : ""}`; + const attemptSummary = `Attempt: ${userAttempt} - ${resultMessage}`; + attemptLog.push(attemptSummary); + + document.getElementById("output-panel").innerText = attemptSummary; + document.getElementById("guess-log").innerHTML = `Attempt History:
${attemptLog.join("
")}`; + + attempts++; + + if (exactMatches === 4) { + // Show the custom modal + document.getElementById("modal-message").innerText = "Congratulations, you cracked the code!"; + document.getElementById("modal").style.display = "block"; + + // Calculate score based on the number of attempts + switch (attempts) { + case 1: + score = 70; + break; + case 2: + score = 60; + break; + case 3: + score = 50; + break; + case 4: + score = 40; + break; + case 5: + score = 30; + break; + case 6: + score = 20; + break; + case 7: + score = 10; + break; + default: + score = 0; + } + alert(`You scored ${score} points!`); + // Reset the game + hiddenPattern = createRandomSequence(); + attemptLog = []; + attempts = 0; + score = 0; + document.getElementById("guess-input").value = ""; // Clear the guess input + document.getElementById("output-panel").innerText = ""; + document.getElementById("guess-log").innerHTML = ""; + document.getElementById("container").classList.add("celebration"); // Add celebration class + setTimeout(() => { + document.getElementById("container").classList.remove("celebration"); // Remove celebration class after 2 seconds + }, 2000); + } else if (attempts === 7) { + document.getElementById("modal-message").innerText = "Sorry, you didn't guess the code in 7 attempts. You scored 0 points."; + document.getElementById("modal").style.display = "block"; + // Reset the game + hiddenPattern = createRandomSequence(); + attemptLog = []; + attempts = 0; + score = 0; + document.getElementById("guess-input").value = ""; // Clear the guess input + document.getElementById("output-panel").innerText = ""; + document.getElementById("guess-log").innerHTML = ""; + } +} + +document.getElementById("submit").addEventListener("click", evaluateGuess); \ No newline at end of file diff --git a/Games/Bulls_And_Cows_New/style.css b/Games/Bulls_And_Cows_New/style.css new file mode 100644 index 0000000000..381f3f1a97 --- /dev/null +++ b/Games/Bulls_And_Cows_New/style.css @@ -0,0 +1,196 @@ +html, body { + height: 100%; + margin: 0; + text-align: center; + font-family: 'Press Start 2P', cursive; /* Arcade-like font */ + background: url('./assets/arcade_game.jpg') no-repeat center center fixed; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + height: 100%; +} + +.container { + max-width: 800px; + margin: 40px auto; + padding: 20px; + background-color: #333; + border: 1px solid #666; + box-shadow: 0 0 60px 30px rgb(56, 56, 42), /* Inner neon yellow glow */ + 0 0 140px 90px rgb(29, 29, 29); /* Outer cyan glow */ + border-radius: 10px; /* Add a slight rounded corner effect */ + padding: 20px; /* Add some padding to the container */ +} + +.header-bar { + background-color: #222; + padding: 10px; + border-bottom: 1px solid #333; + display: flex; + justify-content: space-between; + align-items: center; +} + +.header-bar h1 { + font-size: 24px; + color: #C7F464; /* Neon pink */ + margin: 0; + text-align: center; + display: block; /* Make the h1 a block element */ + width: 100%; + text-shadow: 0 0 10px #C7F464; +} + +.header-bar .home-icon { + font-size: 24px; + color: #33CC33; /* Neon green */ + margin-left: 10px; +} + +#output-panel { + padding: 20px; + background-color: #444; + border: 1px solid #666; + border-radius: 10px; + margin-top: 20px; + margin-bottom: 20px; + color: #FFFF00; /* Neon yellow */ + text-shadow: 0 0 10px #FFFF00; +} + +#guess-input { + width: 100%; + padding: 10px; + font-size: 18px; + border: 1px solid #ccc; + border-radius: 10px; + margin-bottom: 10px; + background-color: #333; + color: #FFFFFF; /* White */ +} + +#submit-btn { + background-color: #55b94d; /* Neon pink */ + color: #FFFFFF; /* White */ + padding: 10px 20px; + border: none; + border-radius: 10px; + cursor: pointer; +} + +#submit-btn:hover { + background-color: #FFC0CB; /* Pastel pink */ +} + +#guess-log { + padding: 20px; + background-color: #444; + border: 1px solid #666; + border-radius: 10px; + margin-top: 20px; + overflow-y: auto; + max-height: 200px; + color: #33CC33; /* Neon green */ + text-shadow: 0 0 10px #33CC33; +} + +#guess-log strong { + font-weight: bold; + color: #FFFF00; /* Neon yellow */ + text-shadow: 0 0 10px #FFFF00; +} + +#game-rules { + padding: 20px; + background-color: #444; + border: 1px solid #666; + border-radius: 10px; + margin-top: 20px; + color: #FFFFFF; /* White */ + text-shadow: 0 0 10px #FFFFFF; +} + +#game-rules ul { + list-style: none; + padding: 0; + margin: 0; +} + +#game-rules li { + margin-bottom: 10px; +} + +#game-rules strong { + font-weight: bold; + color: #FF69B4; /* Neon pink */ + text-shadow: 0 0 10px #FF69B4; +} + +/* Celebration animation */ +.celebration { + animation: celebration 2s ease-in-out; +} + +.modal { + display: none; + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + } + + .modal-content { + background-color: #f1f1f1; + margin: 15% auto; + padding: 20px; + border: 1px solid #888; + width: 80%; + max-width: 800px; + } + + .close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + } + + .close:hover, + .close:focus { + color: black; + text-decoration: none; + cursor: pointer; + } + +@keyframes celebration { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } + 100% { + transform: scale(1); + } +} + +/* Responsive design */ +@media (max-width: 600px) { + .container { + margin: 20px 20px; + padding: 10px; + } + #output-panel, #guess-log, #game-rules { + padding: 10px; + } + #guess-input { + width: 80%; + } + #submit-btn { + padding: 10px 15px; + } +} \ No newline at end of file diff --git a/Games/Carrom/carrom.html b/Games/Carrom/index.html similarity index 100% rename from Games/Carrom/carrom.html rename to Games/Carrom/index.html diff --git a/Games/Catch Him/README.md b/Games/Catch Him/README.md new file mode 100644 index 0000000000..e835bf56ee --- /dev/null +++ b/Games/Catch Him/README.md @@ -0,0 +1,18 @@ +## Catch him +"Catch Him" is a fun and engaging game that involves quick reflexes and strategic thinking. The main objective of the game is to catch a character named Ralph, who moves swiftly across the screen. Players must click or tap on Ralph as he appears in different locations, often disappearing and reappearing quickly to increase the challenge. The game typically includes various levels of difficulty, with Ralph moving faster and more unpredictably as players advance. It's a great game for testing hand-eye coordination and speed, providing an entertaining and competitive experience for players of all ages. + +## How to play ?: + +1. **Objective**: Your goal is to catch Ralph by clicking or tapping on him whenever he appears on the screen. + +2. **Gameplay**: + - Ralph will move around the screen and may disappear and reappear in different locations. + - Use your mouse (if on a computer) tap to catch Ralph. + - Each time you successfully catch Ralph, you earn points. + +3. **Time Limit**: The game may have a time limit . Try to catch Ralph as many times as possible before time runs out. + +4. **Score**: Your score is based on how many times you catch Ralph. Aim for a high score and challenge yourself to improve with each playthrough. + +## Screenshot + \ No newline at end of file diff --git a/Games/Catch Him/audios/hit.m4a b/Games/Catch Him/audios/hit.m4a new file mode 100644 index 0000000000..d747823dd2 Binary files /dev/null and b/Games/Catch Him/audios/hit.m4a differ diff --git a/Games/Catch Him/images/Catch_him.png b/Games/Catch Him/images/Catch_him.png new file mode 100644 index 0000000000..d0d25ec8f4 Binary files /dev/null and b/Games/Catch Him/images/Catch_him.png differ diff --git a/Games/Catch Him/images/favicon.jpg b/Games/Catch Him/images/favicon.jpg new file mode 100644 index 0000000000..8c5153aafc Binary files /dev/null and b/Games/Catch Him/images/favicon.jpg differ diff --git a/Games/Catch Him/images/player.png b/Games/Catch Him/images/player.png new file mode 100644 index 0000000000..3d320717ff Binary files /dev/null and b/Games/Catch Him/images/player.png differ diff --git a/Games/Catch Him/images/ralph.png b/Games/Catch Him/images/ralph.png new file mode 100644 index 0000000000..e8e5b9dd5b Binary files /dev/null and b/Games/Catch Him/images/ralph.png differ diff --git a/Games/Catch Him/images/wall.png b/Games/Catch Him/images/wall.png new file mode 100644 index 0000000000..7e4216a480 Binary files /dev/null and b/Games/Catch Him/images/wall.png differ diff --git a/Games/Catch Him/index.html b/Games/Catch Him/index.html new file mode 100644 index 0000000000..31f90f2703 --- /dev/null +++ b/Games/Catch Him/index.html @@ -0,0 +1,63 @@ + + + + + + + + + Ctch Ralph + + + + + + + + + + + + + +
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/Games/Catch Him/scripts/engine.js b/Games/Catch Him/scripts/engine.js new file mode 100644 index 0000000000..c5622f0995 --- /dev/null +++ b/Games/Catch Him/scripts/engine.js @@ -0,0 +1,65 @@ +const state = { + view: { + squares: document.querySelectorAll(".square"), + enemy: document.querySelector(".enemy"), + timeLeft: document.querySelector("#time-left"), + score: document.querySelector("#score"), + }, + values: { + gameVelocity: 1000, + hitPosition: 0, + result: 0, + curretTime: 60, + }, + actions: { + timerId: setInterval(randomSquare, 1000), + countDownTimerId: setInterval(countDown, 1000), + }, +}; + +function countDown() { + state.values.curretTime--; + state.view.timeLeft.textContent = state.values.curretTime; + + if (state.values.curretTime <= 0) { + clearInterval(state.actions.countDownTimerId); + clearInterval(state.actions.timerId); + alert("Game Over! O seu resultado foi: " + state.values.result); + } +} + +function playSound(audioName) { + let audio = new Audio(`./src/audios/${audioName}.m4a`); + audio.volume = 0.2; + audio.play(); +} + +function randomSquare() { + state.view.squares.forEach((square) => { + square.classList.remove("enemy"); + }); + + let randomNumber = Math.floor(Math.random() * 9); + let randomSquare = state.view.squares[randomNumber]; + randomSquare.classList.add("enemy"); + state.values.hitPosition = randomSquare.id; +} + +function addListenerHitBox() { + state.view.squares.forEach((square) => { + square.addEventListener("mousedown", () => { + if (square.id === state.values.hitPosition) { + state.values.result++; + state.view.score.textContent = state.values.result; + state.values.hitPosition = null; + playSound("hit"); + } + }); + }); +} + +function initialize() { + addListenerHitBox(); +} + +initialize(); diff --git a/Games/Catch Him/styles/main.css b/Games/Catch Him/styles/main.css new file mode 100644 index 0000000000..ca1e684fd5 --- /dev/null +++ b/Games/Catch Him/styles/main.css @@ -0,0 +1,48 @@ +.container { + display: flex; + flex-direction: column; + height: 100vh; + background-image: url("../images/wall.png"); +} + +.menu { + display: flex; + justify-content: space-evenly; + align-items: center; + + height: 90px; + width: 100%; + background-color: #000000; + color: #ffffff; + border-bottom: 5px solid #ffd700; +} + +.panel { + margin-top: 1rem; + display: flex; + align-items: center; + justify-content: center; +} + +.square { + height: 150px; + width: 150px; + border: 1px solid #000000; + background-color: #1aeaa5; +} + +.enemy { + background-image: url("../images/ralph.png"); + background-size: cover; +} + +.menu-lives { + display: flex; + align-items: center; + justify-content: center; +} + +.menu-time h2:nth-child(2), +.menu-score h2:nth-child(2) { + margin-top: 1rem; +} \ No newline at end of file diff --git a/Games/Catch Him/styles/reset.css b/Games/Catch Him/styles/reset.css new file mode 100644 index 0000000000..47b93fe8e4 --- /dev/null +++ b/Games/Catch Him/styles/reset.css @@ -0,0 +1,7 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + /* font-family: "Bebas Neue", sans-serif; */ + font-family: "Press Start 2P", cursive; +} diff --git a/Games/Cooking_Challenge_Game/README.md b/Games/Cooking_Challenge_Game/README.md new file mode 100644 index 0000000000..3f1819b48b --- /dev/null +++ b/Games/Cooking_Challenge_Game/README.md @@ -0,0 +1,56 @@ +# Cooking Challenge Game + +Welcome to the Cooking Challenge Game! This is a simple web-based game where players must match a given order by selecting the correct ingredients within a limited time. + +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [Game Mechanics](#game-mechanics) +- [Technologies Used](#technologies-used) +- [Contributing](#contributing) +- [License](#license) + +## Installation + +To get a copy of this project up and running on your local machine, follow these steps: + +1. Clone the repository: + ```bash + git clone https://github.com/yourusername/cooking-challenge-game.git + ``` +2. Navigate to the project directory: + ```bash + cd cooking-challenge-game + ``` + +## Usage + +To start the game, simply open the `index.html` file in your preferred web browser. + +## Game Mechanics + +1. **Objective:** + - Match the order by selecting the correct ingredients within the given time limit. + +2. **Controls:** + - Click on the ingredient icons to select them. + - Click the "Serve" button to check if the selected ingredients match the order. + +3. **Scoring:** + - Each correct order gives you 10 points. + - The game lasts for 60 seconds. Your score is displayed at the end of the game. + +## Technologies Used + +- **HTML:** Structure of the game. +- **CSS:** Styling and layout. +- **JavaScript:** Game logic and interactivity. + +## File Structure + +```plaintext +. +├── index.html +├── styles.css +└── script.js diff --git a/Games/Cooking_Challenge_Game/index.html b/Games/Cooking_Challenge_Game/index.html new file mode 100644 index 0000000000..a22c7f9555 --- /dev/null +++ b/Games/Cooking_Challenge_Game/index.html @@ -0,0 +1,28 @@ + + + + + + Cooking Challenge Game + + + +
+
+
🍅
+
🥬
+
🧀
+
🍞
+
+
+
Order:
+ +
+
+

Score: 0

+

Time: 60 seconds

+
+
+ + + diff --git a/Games/Cooking_Challenge_Game/script.js b/Games/Cooking_Challenge_Game/script.js new file mode 100644 index 0000000000..8a2a63ee60 --- /dev/null +++ b/Games/Cooking_Challenge_Game/script.js @@ -0,0 +1,74 @@ +// script.js +const ingredients = document.querySelectorAll('.ingredient'); +const orderDisplay = document.getElementById('order'); +const serveButton = document.getElementById('serveButton'); +const scoreDisplay = document.getElementById('score'); +const timeDisplay = document.getElementById('time'); + +let currentOrder = []; +let selectedIngredients = []; +let score = 0; +let time = 60; + +const allIngredients = ['tomato', 'lettuce', 'cheese', 'bread']; + +function getRandomIngredient() { + return allIngredients[Math.floor(Math.random() * allIngredients.length)]; +} + +function generateOrder() { + currentOrder = []; + for (let i = 0; i < 3; i++) { + currentOrder.push(getRandomIngredient()); + } + orderDisplay.innerHTML = 'Order: ' + currentOrder.join(', '); +} + +ingredients.forEach(ingredient => { + ingredient.addEventListener('click', () => { + if (!selectedIngredients.includes(ingredient.id)) { + selectedIngredients.push(ingredient.id); + ingredient.style.backgroundColor = '#dcdcdc'; + } + }); +}); + +serveButton.addEventListener('click', () => { + if (arraysEqual(selectedIngredients, currentOrder)) { + score += 10; + scoreDisplay.innerHTML = score; + resetRound(); + } else { + alert('Wrong ingredients!'); + } +}); + +function resetRound() { + selectedIngredients = []; + ingredients.forEach(ingredient => { + ingredient.style.backgroundColor = '#fff'; + }); + generateOrder(); +} + +function arraysEqual(a, b) { + if (a.length !== b.length) return false; + a.sort(); + b.sort(); + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } + return true; +} + +function updateTimer() { + time--; + timeDisplay.innerHTML = time; + if (time <= 0) { + clearInterval(timer); + alert('Game over! Your score is ' + score); + } +} + +generateOrder(); +const timer = setInterval(updateTimer, 1000); diff --git a/Games/Cooking_Challenge_Game/styles.css b/Games/Cooking_Challenge_Game/styles.css new file mode 100644 index 0000000000..f69833df46 --- /dev/null +++ b/Games/Cooking_Challenge_Game/styles.css @@ -0,0 +1,51 @@ +/* styles.css */ +body { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background: #f0f0f0; + margin: 0; + font-family: Arial, sans-serif; +} + +#gameContainer { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +#kitchen { + display: flex; + justify-content: center; + gap: 10px; + margin-bottom: 20px; +} + +.ingredient { + padding: 20px; + background: #fff; + border: 1px solid #ccc; + cursor: pointer; + font-size: 2rem; + transition: background 0.3s; +} + +.ingredient:hover { + background: #f9f9f9; +} + +#orderBoard { + margin-bottom: 20px; +} + +#serveButton { + padding: 10px; + font-size: 1rem; + cursor: pointer; +} + +#scoreBoard p { + margin: 5px 0; +} diff --git a/Games/DNA_Sequencer/README.md b/Games/DNA_Sequencer/README.md new file mode 100644 index 0000000000..ff53dec530 --- /dev/null +++ b/Games/DNA_Sequencer/README.md @@ -0,0 +1,32 @@ +# **DNA Sequencer Game** + +--- + +
+ +## **Description 📃** +DNA Sequencer is an interactive puzzle game where players must arrange DNA bases (A, T, C, G) in the correct order within a given time limit. + +## **Functionalities 🎮** +- Control the sequence by dragging and dropping the DNA bases. +- Shuffle the sequence for added difficulty. +- Timer-based challenge with a 120-second countdown. +- Immediate feedback on the correctness of the arranged sequence. +- Responsive design for easy play on different devices. +- Option to restart the game after the timer runs out or sequence is completed. + +## **How to Play? 🕹️** +- Arrange the DNA bases in the correct order by dragging and dropping them into place. +- Shuffle the sequence using the "Shuffle" button for a new challenge. +- Check your sequence with the "Check Sequence" button to see if it's correct. +- Aim to complete the sequence within the 120-second time limit. +- The game ends when the timer runs out or the correct sequence is achieved. +- Your final result will be displayed on the screen, indicating if the sequence is correct or not. + +## **Screenshots 📸** +![image](../../assets/DNA_Sequencer.png) + +
+ +--- + diff --git a/Games/DNA_Sequencer/index.html b/Games/DNA_Sequencer/index.html new file mode 100644 index 0000000000..1551a8874f --- /dev/null +++ b/Games/DNA_Sequencer/index.html @@ -0,0 +1,28 @@ + + + + + + DNA Sequencer Game + + + +
+

DNA Sequencer

+

Guess the DNA Sequence order by shuffling +
(You can shuffle manually as well)!

+
+
+
+
+ + + +
+
Time: 00:00
+
+
+
+ + + \ No newline at end of file diff --git a/Games/DNA_Sequencer/script.js b/Games/DNA_Sequencer/script.js new file mode 100644 index 0000000000..23cdb95ed6 --- /dev/null +++ b/Games/DNA_Sequencer/script.js @@ -0,0 +1,117 @@ +document.addEventListener('DOMContentLoaded', function() { + let dnaSequence = generateRandomDnaSequence(8); + let currentSequence = [...dnaSequence]; + let timeLimit = 120; + let timer; + + function shuffleArray(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + } + + function generateRandomDnaSequence() { + let sequence = ["A", "A", "T", "T", "C", "C", "G", "G"]; + for (let i = sequence.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [sequence[i], sequence[j]] = [sequence[j], sequence[i]]; + } + return sequence; + } + + function renderSequence() { + const sequenceContainer = document.getElementById('dna-sequence'); + sequenceContainer.innerHTML = ''; + currentSequence.forEach((base, index) => { + const baseElement = document.createElement('div'); + baseElement.textContent = base; + baseElement.className = 'base'; + baseElement.draggable = true; + baseElement.setAttribute('data-index', index); + baseElement.addEventListener('dragstart', dragStart); + sequenceContainer.appendChild(baseElement); + }); + } + + function dragStart(e) { + e.dataTransfer.setData('text/plain', e.target.getAttribute('data-index')); + } + + function dragOver(e) { + e.preventDefault(); + } + + function drop(e) { + e.preventDefault(); + const originIndex = e.dataTransfer.getData('text'); + const targetIndex = e.target.getAttribute('data-index'); + if (targetIndex) { + [currentSequence[originIndex], currentSequence[targetIndex]] = [currentSequence[targetIndex], currentSequence[originIndex]]; + renderSequence(); + } + } + + function startLevel() { + shuffleArray(currentSequence); + renderSequence(); + startTimer(); + } + + + function startTimer() { + const timerElement = document.getElementById('timer'); + timerElement.textContent = `Time: ${timeLimit}s`; + timer = setInterval(() => { + timeLimit--; + timerElement.textContent = `Time: ${timeLimit}s`; + if (timeLimit <= 0) { + clearInterval(timer); + const resultElement = document.getElementById('result'); + resultElement.textContent = dnaSequence.join(''); + resultElement.style.color = 'red'; + alert('Time is up! Try again.'); + resetGame(); + } + }, 1000); + } + + function resetGame() { + clearInterval(timer); + timeLimit = 120; + dnaSequence = generateRandomDnaSequence(); + currentSequence = [...dnaSequence]; + startLevel(); + } + + document.getElementById('dna-sequence').addEventListener('dragover', dragOver); + document.getElementById('dna-sequence').addEventListener('drop', drop); + document.getElementById('shuffle').addEventListener('click', () => { + shuffleArray(currentSequence); + renderSequence(); + }); + document.getElementById('check').addEventListener('click', () => { + console.log(currentSequence); + console.log(dnaSequence); + const resultElement = document.getElementById('result'); + if (JSON.stringify(currentSequence) === JSON.stringify(dnaSequence)) { + resultElement.textContent = 'Correct sequence! Well done.'; + resultElement.style.color = 'green'; + clearInterval(timer); + updateScore(true); + currentSequence = generateSequence(dnaSequence.length + 2); + startLevel(); + } else { + resultElement.textContent = 'Incorrect sequence. Try again.'; + resultElement.style.color = 'red'; + updateScore(false); + } + }); + const playAgainButton = document.getElementById('play-again'); + playAgainButton.addEventListener('click', () => { + document.getElementById('result').textContent = ''; + resetGame(); + }); + + startLevel(); +}); \ No newline at end of file diff --git a/Games/DNA_Sequencer/style.css b/Games/DNA_Sequencer/style.css new file mode 100644 index 0000000000..faf5bdc1a5 --- /dev/null +++ b/Games/DNA_Sequencer/style.css @@ -0,0 +1,61 @@ +body { + font-family: Arial, sans-serif; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background: linear-gradient(135deg, #6e8efb, #a777e3); + margin: 0; +} +.container { + text-align: center; + background: #fff; + padding: 20px; + border-radius: 8px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} +.dna-container { + display: flex; + justify-content: center; + margin: 20px 0; +} +.dna-sequence { + display: flex; + gap: 5px; +} +.dna-sequence .base { + padding: 10px; + border: 1px solid #ccc; + cursor: pointer; + border-radius: 4px; + background-color: #eee; + transform: perspective(100px) rotateX(10deg) rotateY(10deg); + transition: transform 0.3s; +} +.dna-sequence .base:hover { + transform: perspective(100px) rotateX(0deg) rotateY(0deg); + box-shadow: 0 10px 20px rgba(0,0,0,0.2); +} +.controls { + margin: 20px 0; +} +.controls button { + padding: 10px 20px; + margin: 0 10px; + border: none; + background-color: #007bff; + color: white; + border-radius: 4px; + cursor: pointer; +} +.controls button:hover { + background-color: #0056b3; +} +.result { + margin-top: 20px; + font-weight: bold; +} +.level { + font-size: 20px; + margin-top: 10px; +} \ No newline at end of file diff --git a/Games/Detona/index.html b/Games/Detona/index.html new file mode 100644 index 0000000000..e13220afa2 --- /dev/null +++ b/Games/Detona/index.html @@ -0,0 +1,63 @@ + + + + + + + + + Detona Ralph + + + + + + + + + + + + + +
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/Games/Detona/readme.md b/Games/Detona/readme.md new file mode 100644 index 0000000000..cb352df934 --- /dev/null +++ b/Games/Detona/readme.md @@ -0,0 +1,49 @@ +## Awesome JSGame Detona Ralph + +``` + #game-development + #javascript-game + #html-css-javascript + #html-css-javascript-games + #ifood + #dio-bootcamp +``` + + +# Bem-vindo ao **JSGame Detona Ralph**! + +Um projeto que, além do entretenimento, demonstra várias técnicas avançadas de desenvolvimento de jogos em JavaScript. + + +Aqui, no repositório, você encontrará os arquivos do projeto. + +Nesta [página do jogo](https://netopaiva.github.io/detona-ralph/) você poderá se divertir com um *game* baseado no famoso filme "Detona Ralph". + +### Tecnologias Utilizadas + +- HTML5 e CSS3 para a estrutura e aparência do jogo. +- JavaScript para a lógica de programação e interatividade. +- Sprites e imagens customizadas para criar a estética única do universo de Detona Ralph. + +### Funcionalidades Incríveis + +- **Sistema de Pontuação**: Acompanhe sua pontuação à medida que progride no jogo e desafie seus amigos a superá-la, clique no quadrado que o Ralph se encontre + +### Como Jogar + +1. Clone este repositório para sua máquina local. +2. Abra o arquivo `index.html` em seu navegador web. +3. Use as setas direcionais para mover o personagem e a barra de espaço para interagir. +4. Divirta-se explorando e coletando moedas, mas fique atento aos inimigos! + +### Contribuição + +Contribuições são bem-vindas! Se você deseja melhorar este jogo, adicionar novos recursos ou corrigir problemas, sinta-se à vontade para abrir um _pull request_. + +### Créditos + +Este jogo foi desenvolvido como parte de um projeto educacional da Digital Innovation One. + +--- + +Divirta-se [jogando o **JSGame Detona Ralph**](https://netopaiva.github.io/detona-ralph/) enquanto explora as técnicas modernas de desenvolvimento de jogos em JavaScript. Lembre-se de conferir o repositório original [aqui](https://github.com/digitalinnovationone/jsgame-detona-ralph) e deixar uma ⭐️ se você gostou do projeto! diff --git a/Games/Detona/src/audios/hit.m4a b/Games/Detona/src/audios/hit.m4a new file mode 100644 index 0000000000..d747823dd2 Binary files /dev/null and b/Games/Detona/src/audios/hit.m4a differ diff --git a/Games/Detona/src/images/favicon.jpg b/Games/Detona/src/images/favicon.jpg new file mode 100644 index 0000000000..8c5153aafc Binary files /dev/null and b/Games/Detona/src/images/favicon.jpg differ diff --git a/Games/Detona/src/images/player.png b/Games/Detona/src/images/player.png new file mode 100644 index 0000000000..3d320717ff Binary files /dev/null and b/Games/Detona/src/images/player.png differ diff --git a/Games/Detona/src/images/ralph.png b/Games/Detona/src/images/ralph.png new file mode 100644 index 0000000000..e8e5b9dd5b Binary files /dev/null and b/Games/Detona/src/images/ralph.png differ diff --git a/Games/Detona/src/images/wall.png b/Games/Detona/src/images/wall.png new file mode 100644 index 0000000000..7e4216a480 Binary files /dev/null and b/Games/Detona/src/images/wall.png differ diff --git a/Games/Detona/src/scripts/engine.js b/Games/Detona/src/scripts/engine.js new file mode 100644 index 0000000000..4dd1859e8b --- /dev/null +++ b/Games/Detona/src/scripts/engine.js @@ -0,0 +1,65 @@ +const state = { + view: { + squares: document.querySelectorAll(".square"), + enemy: document.querySelector(".enemy"), + timeLeft: document.querySelector("#time-left"), + score: document.querySelector("#score"), + }, + values: { + gameVelocity: 1000, + hitPosition: 0, + result: 0, + curretTime: 60, + }, + actions: { + timerId: setInterval(randomSquare, 1000), + countDownTimerId: setInterval(countDown, 1000), + }, +}; + +function countDown() { + state.values.curretTime--; + state.view.timeLeft.textContent = state.values.curretTime; + + if (state.values.curretTime <= 0) { + clearInterval(state.actions.countDownTimerId); + clearInterval(state.actions.timerId); + alert("Game Over! O seu resultado foi: " + state.values.result); + } +} + +function playSound(audioName) { + let audio = new Audio(`./src/audios/${audioName}.m4a`); + audio.volume = 0.2; + audio.play(); +} + +function randomSquare() { + state.view.squares.forEach((square) => { + square.classList.remove("enemy"); + }); + + let randomNumber = Math.floor(Math.random() * 9); + let randomSquare = state.view.squares[randomNumber]; + randomSquare.classList.add("enemy"); + state.values.hitPosition = randomSquare.id; +} + +function addListenerHitBox() { + state.view.squares.forEach((square) => { + square.addEventListener("mousedown", () => { + if (square.id === state.values.hitPosition) { + state.values.result++; + state.view.score.textContent = state.values.result; + state.values.hitPosition = null; + playSound("hit"); + } + }); + }); +} + +function initialize() { + addListenerHitBox(); +} + +initialize(); diff --git a/Games/Detona/src/styles/main.css b/Games/Detona/src/styles/main.css new file mode 100644 index 0000000000..ade1402bdb --- /dev/null +++ b/Games/Detona/src/styles/main.css @@ -0,0 +1,48 @@ +.container { + display: flex; + flex-direction: column; + height: 100vh; + background-image: url("../images/wall.png"); +} + +.menu { + display: flex; + justify-content: space-evenly; + align-items: center; + + height: 90px; + width: 100%; + background-color: #000000; + color: #ffffff; + border-bottom: 5px solid #ffd700; +} + +.panel { + margin-top: 1rem; + display: flex; + align-items: center; + justify-content: center; +} + +.square { + height: 150px; + width: 150px; + border: 1px solid #000000; + background-color: #1aeaa5; +} + +.enemy { + background-image: url("../images/ralph.png"); + background-size: cover; +} + +.menu-lives { + display: flex; + align-items: center; + justify-content: center; +} + +.menu-time h2:nth-child(2), +.menu-score h2:nth-child(2) { + margin-top: 1rem; +} diff --git a/Games/Detona/src/styles/reset.css b/Games/Detona/src/styles/reset.css new file mode 100644 index 0000000000..9395805ea8 --- /dev/null +++ b/Games/Detona/src/styles/reset.css @@ -0,0 +1,7 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + /* font-family: "Bebas Neue", sans-serif; */ + font-family: "Press Start 2P", cursive; +} diff --git a/Games/Dice_rolling_simulator/README.md b/Games/Dice_rolling_simulator/README.md new file mode 100644 index 0000000000..51e88fc0b6 --- /dev/null +++ b/Games/Dice_rolling_simulator/README.md @@ -0,0 +1,65 @@ +### Description +The dice rolling simulator is a simple application built using Python and the Tkinter library for the graphical user interface (GUI). The simulator mimics the action of rolling a dice, providing a random outcome between 1 and 6 each time the user interacts with the interface. This application is useful for games, educational purposes, or simply for fun. + +### Game_Logic + +- Initialization: When the program starts, it initializes the main window using Tkinter. +- Dice Roll: A function generates a random number between 1 and 6 using Python's random module. +- Display: The result of the dice roll is displayed on the GUI, typically as a number or a graphical representation of a dice face. +- Interaction: The user can roll the dice by clicking a button on the GUI, which triggers the dice roll function. + +### FEATURES +Random Dice Roll: Uses the random.randint(1, 6) function to generate a number between 1 and 6. +Graphical Interface: A user-friendly interface built with Tkinter, making it easy to interact with the simulator. +Roll Button: A button that the user clicks to roll the dice. +Display Area: Shows the result of the dice roll, either as a numeric value or a visual representation. + +### Screenshot![Dice_Rolling_simulator_Game](https://github.com/priyashuu/GameZone/assets/150767072/46569298-3844-4240-a3c3-544fc47c524e) +### Video + +https://github.com/priyashuu/GameZone/assets/150767072/0d88b796-9125-4bf4-bb58-7178a456ecc8 + + + + +### Tech Stack Overview + +The dice rolling simulator utilizes a combination of technologies and libraries to create a functional and interactive application. Below is a breakdown of the tech stack used: + +#### **Programming Language:** +- **Python** + +#### **Graphical User Interface (GUI):** +- **Tkinter** + +#### **Libraries and Modules:** +- **Random** + +#### **Development Environment:** +- **IDLE** +- **VS Code** +#### **Version Control:** +- **Git** +- **GitHub** +### Example of Tech Stack in Action +1. **Python**: The logic of the dice roll is implemented in Python using simple functions and conditional statements. +2. **Tkinter**: Used to create the main window, buttons, and labels that make up the user interface. +3. **Random Module**: Utilized within the dice roll function to generate a random number between 1 and 6 each time the user clicks the roll button. +4. **Git and GitHub**: The code is version-controlled using Git and hosted on GitHub, making it easy to share and collaborate with others. + +### Installation Instructions +1. **Install Python**: Download and install Python from [python.org](https://www.python.org/). +2. **Install Tkinter**: Tkinter is included with Python, so no additional installation is required. +3. **Clone the Repository**: If the project is hosted on GitHub, clone the repository using Git. + ```bash + git clone https://github.com/username/repository-name.git + ``` +4. **Run the Application**: Navigate to the project directory and run the Python script. + ```bash + cd repository-name + python dice_simulator.py + ``` +<<<<<<< HEAD + +======= +>>>>>>> priyashuu-patch-1 diff --git a/Games/Dice_rolling_simulator/dice_1.png b/Games/Dice_rolling_simulator/dice_1.png new file mode 100644 index 0000000000..7a2623ff08 Binary files /dev/null and b/Games/Dice_rolling_simulator/dice_1.png differ diff --git a/Games/Dice_rolling_simulator/dice_2.png b/Games/Dice_rolling_simulator/dice_2.png new file mode 100644 index 0000000000..6f04a93f11 Binary files /dev/null and b/Games/Dice_rolling_simulator/dice_2.png differ diff --git a/Games/Dice_rolling_simulator/dice_3.png b/Games/Dice_rolling_simulator/dice_3.png new file mode 100644 index 0000000000..cd4c14725f Binary files /dev/null and b/Games/Dice_rolling_simulator/dice_3.png differ diff --git a/Games/Dice_rolling_simulator/dice_4.png b/Games/Dice_rolling_simulator/dice_4.png new file mode 100644 index 0000000000..5cf0420bc4 Binary files /dev/null and b/Games/Dice_rolling_simulator/dice_4.png differ diff --git a/Games/Dice_rolling_simulator/dice_5.png b/Games/Dice_rolling_simulator/dice_5.png new file mode 100644 index 0000000000..113ee44b6a Binary files /dev/null and b/Games/Dice_rolling_simulator/dice_5.png differ diff --git a/Games/Dice_rolling_simulator/dice_6.png b/Games/Dice_rolling_simulator/dice_6.png new file mode 100644 index 0000000000..0d6c378c0d Binary files /dev/null and b/Games/Dice_rolling_simulator/dice_6.png differ diff --git a/Games/Dice_rolling_simulator/main3.py b/Games/Dice_rolling_simulator/main3.py new file mode 100644 index 0000000000..07fd4a4e5f --- /dev/null +++ b/Games/Dice_rolling_simulator/main3.py @@ -0,0 +1,60 @@ +import tkinter as tk +from PIL import Image, ImageTk +import random +import time +import os + +# Initialize the Tkinter window +window = tk.Tk() +window.geometry("500x360") +window.title("Dice Roll") +window.configure(bg='black') + +# Define a list of dice images +dice = ["dice_1.png", "dice_2.png", "dice_3.png", "dice_4.png", "dice_5.png", "dice_6.png"] + +# Verify that all dice images exist +for dice_image in dice: + if not os.path.exists(dice_image): + print(f"Error: {dice_image} not found.") + exit() + +# Define a list of colors for the animation +colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'pink'] + +# Choose a random image for each dice and display them initially on the window +image1 = ImageTk.PhotoImage(Image.open(random.choice(dice))) +image2 = ImageTk.PhotoImage(Image.open(random.choice(dice))) +label1 = tk.Label(window, image=image1, bg='black') +label2 = tk.Label(window, image=image2, bg='black') +label1.image = image1 +label2.image = image2 +label1.place(x=40, y=100) +label2.place(x=900, y=100) + +# Define a function named "dice_roll" with animation +def dice_roll(): + for _ in range(10): # Number of frames in the animation + color = random.choice(colors) # Choose a random color for the background + image1 = ImageTk.PhotoImage(Image.open(random.choice(dice))) + label1.configure(image=image1, bg=color) + label1.image = image1 + image2 = ImageTk.PhotoImage(Image.open(random.choice(dice))) + label2.configure(image=image2, bg=color) + label2.image = image2 + window.update() # Update the window to show changes + time.sleep(0.1) # Pause to create animation effect + # Set the final images and background to black after animation + image1 = ImageTk.PhotoImage(Image.open(random.choice(dice))) + label1.configure(image=image1, bg='black') + label1.image = image1 + image2 = ImageTk.PhotoImage(Image.open(random.choice(dice))) + label2.configure(image=image2, bg='black') + label2.image = image2 + +# Define a button widget labeled "ROLL" with green background and white text, positioned at the top of the window +button = tk.Button(window, text="ROLL", bg="green", fg="white", font="Times 20 bold", command=dice_roll) +button.place(x=660, y=10) + +# Display the Tkinter window and wait for user interaction +window.mainloop() diff --git a/Games/Dodge the Blocks/README.md b/Games/Dodge the Blocks/README.md new file mode 100644 index 0000000000..94eda46dfd --- /dev/null +++ b/Games/Dodge the Blocks/README.md @@ -0,0 +1,43 @@ +# Dodge the Blocks Game + +"Dodge the Blocks" is a simple and fun web-based game where the player controls a character that must avoid falling blocks. The goal is to survive as long as possible without being hit by the blocks. + +## Table of Contents + +- [Demo](#demo) +- [Installation](#installation) +- [How to Play](#how-to-play) +- [Technologies Used](#technologies-used) +- [Contributing](#contributing) +- [License](#license) + +## Demo + +You can see a live demo of the game [here](#). (Add your live demo link here) + +## Installation + +To run this game locally, follow these steps: + + +## How to Play + +1. Open the game in your web browser. +2. Use the left and right arrow keys to move the player left and right. +3. Avoid the falling blocks. +4. Try to survive as long as possible. Your score increases with time. +5. If a block hits the player, the game is over, and your final score will be displayed. + +## Technologies Used + +- HTML +- CSS +- JavaScript + +## Contributing + +Contributions are welcome! If you have any suggestions or improvements, feel free to submit a pull request or open an issue. + +## License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details. diff --git a/Games/Dodge the Blocks/index.html b/Games/Dodge the Blocks/index.html new file mode 100644 index 0000000000..a947d9e950 --- /dev/null +++ b/Games/Dodge the Blocks/index.html @@ -0,0 +1,16 @@ + + + + + + Dodge the Blocks + + + +
+
+
+
Score: 0
+ + + diff --git a/Games/Dodge the Blocks/script.js b/Games/Dodge the Blocks/script.js new file mode 100644 index 0000000000..d94ee891c4 --- /dev/null +++ b/Games/Dodge the Blocks/script.js @@ -0,0 +1,57 @@ +const gameContainer = document.getElementById('gameContainer'); +const player = document.getElementById('player'); +const scoreDisplay = document.getElementById('score'); + +let score = 0; +let gameOver = false; + +// Player movement +document.addEventListener('keydown', (e) => { + const left = parseInt(window.getComputedStyle(player).getPropertyValue('left')); + if (e.key === 'ArrowLeft' && left > 0) { + player.style.left = left - 10 + 'px'; + } else if (e.key === 'ArrowRight' && left < 270) { + player.style.left = left + 10 + 'px'; + } +}); + +// Generate blocks +function createBlock() { + const block = document.createElement('div'); + block.classList.add('block'); + block.style.left = Math.floor(Math.random() * 270) + 'px'; + gameContainer.appendChild(block); + + // Collision detection + const blockInterval = setInterval(() => { + const blockTop = parseInt(window.getComputedStyle(block).getPropertyValue('top')); + const playerLeft = parseInt(window.getComputedStyle(player).getPropertyValue('left')); + const playerRight = playerLeft + 30; + const blockLeft = parseInt(block.style.left); + const blockRight = blockLeft + 30; + + if (blockTop > 470 && blockTop < 500 && playerLeft < blockRight && playerRight > blockLeft) { + gameOver = true; + alert('Game Over! Final Score: ' + score); + clearInterval(blockInterval); + location.reload(); + } + }, 10); + + // Remove block after it falls + setTimeout(() => { + block.remove(); + }, 3000); +} + +// Update score +function updateScore() { + if (!gameOver) { + score++; + scoreDisplay.textContent = 'Score: ' + score; + setTimeout(updateScore, 1000); + } +} + +updateScore(); +setInterval(createBlock, 1500); diff --git a/Games/Dodge the Blocks/style.css b/Games/Dodge the Blocks/style.css new file mode 100644 index 0000000000..0342e14a26 --- /dev/null +++ b/Games/Dodge the Blocks/style.css @@ -0,0 +1,49 @@ +body { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + background-color: #f0f0f0; + font-family: Arial, sans-serif; +} + +#gameContainer { + position: relative; + width: 300px; + height: 500px; + background-color: #fff; + border: 2px solid #000; + overflow: hidden; +} + +#player { + position: absolute; + width: 30px; + height: 30px; + background-color: #3498db; + bottom: 10px; + left: 135px; +} + +.block { + position: absolute; + width: 30px; + height: 30px; + background-color: #e74c3c; + animation: fall 3s linear infinite; +} + +@keyframes fall { + 0% { + top: -30px; + } + 100% { + top: 500px; + } +} + +#score { + margin-top: 20px; + font-size: 24px; +} diff --git a/Games/Drum_kit/Readme.md b/Games/Drum_kit/Readme.md new file mode 100644 index 0000000000..f88fd547b9 --- /dev/null +++ b/Games/Drum_kit/Readme.md @@ -0,0 +1,20 @@ +# **Game_Name** + +Drum Kit [Issue #4876] + +
+ +## **Description 📃** +Drum kit game is developed using HTML, CSS, JavaScript. +Main target is to have experience of drum kit sound and have fun. + + +## **functionalities 🎮** +1. Have experience of drum kit sound and have fun. +
+ +## **How to play? 🕹️** +1. User can click on drum image. +2. User can play using keyboard too. +## **Screenshots 📸** +![Drum_kit](./images/asset.png) diff --git a/Games/Drum_kit/images/asset.png b/Games/Drum_kit/images/asset.png new file mode 100644 index 0000000000..b4da7adf8d Binary files /dev/null and b/Games/Drum_kit/images/asset.png differ diff --git a/Games/Drum_kit/images/crash.png b/Games/Drum_kit/images/crash.png new file mode 100644 index 0000000000..a992fa0f53 Binary files /dev/null and b/Games/Drum_kit/images/crash.png differ diff --git a/Games/Drum_kit/images/kick.png b/Games/Drum_kit/images/kick.png new file mode 100644 index 0000000000..b64877e70d Binary files /dev/null and b/Games/Drum_kit/images/kick.png differ diff --git a/Games/Drum_kit/images/snare.png b/Games/Drum_kit/images/snare.png new file mode 100644 index 0000000000..1e089bacd7 Binary files /dev/null and b/Games/Drum_kit/images/snare.png differ diff --git a/Games/Drum_kit/images/tom1.png b/Games/Drum_kit/images/tom1.png new file mode 100644 index 0000000000..855b211177 Binary files /dev/null and b/Games/Drum_kit/images/tom1.png differ diff --git a/Games/Drum_kit/images/tom2.png b/Games/Drum_kit/images/tom2.png new file mode 100644 index 0000000000..3e9f3636f4 Binary files /dev/null and b/Games/Drum_kit/images/tom2.png differ diff --git a/Games/Drum_kit/images/tom3.png b/Games/Drum_kit/images/tom3.png new file mode 100644 index 0000000000..762cbf8549 Binary files /dev/null and b/Games/Drum_kit/images/tom3.png differ diff --git a/Games/Drum_kit/images/tom4.png b/Games/Drum_kit/images/tom4.png new file mode 100644 index 0000000000..e79c49e1b1 Binary files /dev/null and b/Games/Drum_kit/images/tom4.png differ diff --git a/Games/Drum_kit/index.html b/Games/Drum_kit/index.html new file mode 100644 index 0000000000..03dcb3b280 --- /dev/null +++ b/Games/Drum_kit/index.html @@ -0,0 +1,27 @@ + + + + + + Drum Kit + + + + + + +

Drum 🥁 Kit

+
+ + + + + + + +
+ + + + + diff --git a/Games/Drum_kit/index.js b/Games/Drum_kit/index.js new file mode 100644 index 0000000000..9f1a61a214 --- /dev/null +++ b/Games/Drum_kit/index.js @@ -0,0 +1,103 @@ +// document.querySelector("button").addEventListener("click" , handleClick); + +// function handleClick(){ +// alert("I got clicked"); +// } + + +// SOUND EVENT ONLY + +// var noOfButtons = document.querySelectorAll(".drum").length ; +// for(var i=0; i< noOfButtons ; i++){ +// document.querySelectorAll(".drum")[i].addEventListener("click" , function(){ +// var buttonInnerHTML = this.innerHTML; +// switch(buttonInnerHTML){ +// case "w" : +// var tom1 = new Audio("sounds/tom-1.mp3"); +// tom1.play(); +// break; +// case "a" : +// var tom2 = new Audio("sounds/tom-2.mp3"); +// tom2.play(); +// break; +// case "s" : +// var tom3 = new Audio("sounds/tom-3.mp3"); +// tom3.play(); +// break; +// case "d" : +// var tom4 = new Audio("sounds/tom-4.mp3"); +// tom4.play(); +// break; +// case "j" : +// var snare = new Audio("sounds/snare.mp3"); +// snare.play(); +// case "k" : +// var crash = new Audio("sounds/crash.mp3"); +// crash.play(); +// break; +// case "l" : +// var kick = new Audio("sounds/kick-bass.mp3"); +// kick.play(); +// break; +// default : console.log(); +// } +// }); +// } + + +// DETECT BUTTON PRESS +var noOfButtons = document.querySelectorAll(".drum").length ; +for(var i=0; i< noOfButtons ; i++){ + document.querySelectorAll(".drum")[i].addEventListener("click" , function(){ + var buttonInnerHTML = this.innerHTML; + makeSound(buttonInnerHTML); + buttonAnimation(buttonInnerHTML); + }); +} +// DETECT KEYBOARD PRESS +document.addEventListener("keydown" , function(event){ + makeSound(event.key); + buttonAnimation(event.key); +}); + +function makeSound(key){ + switch(key){ + case "w" : + var tom1 = new Audio("sounds/tom-1.mp3"); + tom1.play(); + break; + case "a" : + var tom2 = new Audio("sounds/tom-2.mp3"); + tom2.play(); + break; + case "s" : + var tom3 = new Audio("sounds/tom-3.mp3"); + tom3.play(); + break; + case "d" : + var tom4 = new Audio("sounds/tom-4.mp3"); + tom4.play(); + break; + case "j" : + var snare = new Audio("sounds/snare.mp3"); + snare.play(); + case "k" : + var crash = new Audio("sounds/crash.mp3"); + crash.play(); + break; + case "l" : + var kick = new Audio("sounds/kick-bass.mp3"); + kick.play(); + break; + default : console.log(); + } +} + +function buttonAnimation(currentKey){ + var active = document.querySelector("." + currentKey); + active.classList.add("pressed"); + + setTimeout(function(){ + active.classList.remove("pressed"); + },100); +} diff --git a/Games/Drum_kit/sounds/crash.mp3 b/Games/Drum_kit/sounds/crash.mp3 new file mode 100644 index 0000000000..d568062695 Binary files /dev/null and b/Games/Drum_kit/sounds/crash.mp3 differ diff --git a/Games/Drum_kit/sounds/kick-bass.mp3 b/Games/Drum_kit/sounds/kick-bass.mp3 new file mode 100644 index 0000000000..faf06c6cea Binary files /dev/null and b/Games/Drum_kit/sounds/kick-bass.mp3 differ diff --git a/Games/Drum_kit/sounds/snare.mp3 b/Games/Drum_kit/sounds/snare.mp3 new file mode 100644 index 0000000000..e7cf5b841b Binary files /dev/null and b/Games/Drum_kit/sounds/snare.mp3 differ diff --git a/Games/Drum_kit/sounds/tom-1.mp3 b/Games/Drum_kit/sounds/tom-1.mp3 new file mode 100644 index 0000000000..7dc3003d0c Binary files /dev/null and b/Games/Drum_kit/sounds/tom-1.mp3 differ diff --git a/Games/Drum_kit/sounds/tom-2.mp3 b/Games/Drum_kit/sounds/tom-2.mp3 new file mode 100644 index 0000000000..f3c04855c9 Binary files /dev/null and b/Games/Drum_kit/sounds/tom-2.mp3 differ diff --git a/Games/Drum_kit/sounds/tom-3.mp3 b/Games/Drum_kit/sounds/tom-3.mp3 new file mode 100644 index 0000000000..38060330a7 Binary files /dev/null and b/Games/Drum_kit/sounds/tom-3.mp3 differ diff --git a/Games/Drum_kit/sounds/tom-4.mp3 b/Games/Drum_kit/sounds/tom-4.mp3 new file mode 100644 index 0000000000..58b04bebbd Binary files /dev/null and b/Games/Drum_kit/sounds/tom-4.mp3 differ diff --git a/Games/Drum_kit/styles.css b/Games/Drum_kit/styles.css new file mode 100644 index 0000000000..454e127f5f --- /dev/null +++ b/Games/Drum_kit/styles.css @@ -0,0 +1,86 @@ +body { + text-align: center; + background-color: #283149; + } + + h1 { + font-size: 5rem; + color: #DBEDF3; + font-family: "Arvo", cursive; + text-shadow: 3px 0 #DA0463; + + } + + footer { + color: #DBEDF3; + font-family: sans-serif; + } + + .w { + background-image: url("images/tom1.png"); + } + + .a { + background-image: url("images/tom2.png"); + } + + .s { + background-image: url("images/tom3.png"); + } + + .d { + background-image: url("images/tom4.png"); + } + + .j { + background-image: url("images/snare.png"); + } + + .k { + background-image: url("images/crash.png"); + } + + .l { + background-image: url("images/kick.png"); + } + + .set { + margin: 10% auto; + } + + .game-over { + background-color: red; + opacity: 0.8; + } + + .pressed { + box-shadow: 0 3px 4px 0 #DBEDF3; + opacity: 0.5; + } + + .red { + color: red; + } + + .drum { + outline: none; + border: 10px solid #404B69; + font-size: 5rem; + font-family: 'Arvo', cursive; + line-height: 2; + font-weight: 900; + color: #DA0463; + text-shadow: 3px 0 #DBEDF3; + border-radius: 15px; + display: inline-block; + width: 150px; + height: 150px; + text-align: center; + margin: 10px; + background-color: white; + } + + .pressed{ + box-shadow: 0px 3px 4px 0 #DBEDF3; + opacity: 0.5; + } \ No newline at end of file diff --git a/Games/Elephant_ant_man/README.md b/Games/Elephant_ant_man/README.md new file mode 100644 index 0000000000..cc4ad72277 --- /dev/null +++ b/Games/Elephant_ant_man/README.md @@ -0,0 +1,34 @@ +# **Elephant_ant_man** + +--- + +
+ +## **Description 📃** + +It is a cuter version of the classic game rock paper scissors. It is inspired by the famous bedtime story the ant and the elephant where the ant despite his small size teaches a lesson to the elephant. +- + +## **Functionalities 🎮** + +->the user can select one of the three choices and a message will display on the screen if the user won or lost. if the user lost the computer gets the point and vice versa. +- +
+ +## **How to play? 🕹️** + +click on any of the three images +the computer will randomly select a choice of his own +score will be updated as you won or lost +its a endless game enjoy playing + +
+ +## **Screenshots 📸** + +
+ +[image](screenshot.png) + + +
diff --git a/Games/Elephant_ant_man/ant.jpg b/Games/Elephant_ant_man/ant.jpg new file mode 100644 index 0000000000..10960981a5 Binary files /dev/null and b/Games/Elephant_ant_man/ant.jpg differ diff --git a/Games/Elephant_ant_man/boyy.jpg b/Games/Elephant_ant_man/boyy.jpg new file mode 100644 index 0000000000..fa149e3051 Binary files /dev/null and b/Games/Elephant_ant_man/boyy.jpg differ diff --git a/Games/Elephant_ant_man/elephant.jpg b/Games/Elephant_ant_man/elephant.jpg new file mode 100644 index 0000000000..732c04f26a Binary files /dev/null and b/Games/Elephant_ant_man/elephant.jpg differ diff --git a/Games/Elephant_ant_man/index.html b/Games/Elephant_ant_man/index.html new file mode 100644 index 0000000000..3aca5aac43 --- /dev/null +++ b/Games/Elephant_ant_man/index.html @@ -0,0 +1,37 @@ + + + + + + ROCK,PAPER and SCISSORS + + + +

Ant, Boy and Elephant

+
+
+ +
+
+ +
+
+ +
+
+
+
+

0

+

You

+
+
+

0

+

Computer

+
+
+
+

Play your move!

+
+ + + \ No newline at end of file diff --git a/Games/Elephant_ant_man/screenshot.png b/Games/Elephant_ant_man/screenshot.png new file mode 100644 index 0000000000..425431d04f Binary files /dev/null and b/Games/Elephant_ant_man/screenshot.png differ diff --git a/Games/Elephant_ant_man/script.js b/Games/Elephant_ant_man/script.js new file mode 100644 index 0000000000..6d49854750 --- /dev/null +++ b/Games/Elephant_ant_man/script.js @@ -0,0 +1,64 @@ +let userScore=0; +let compScore=0; + +const choices = document.querySelectorAll(".choice"); +const msg=document.querySelector("#msg"); +const userScorePara=document.querySelector("#userscore"); +const compScorePara=document.querySelector("#compscore"); + +const genCompChoice = () => { + const options=["Boy","Elephant","Ant"]; + const randIdx=Math.floor(Math.random()*3); + return options[randIdx]; +} +const drawGame=()=>{ + console.log("It's a tie. Play again!") + msg.innerText="It's a tie. Play again!" + msg.style.backgroundColor="rgb(109, 130, 100)" +} +const showWinner=(userWin, userChoice, compChoice)=>{ + if(userWin){ + console.log("Congratulations! You won.") + userScore++; + userScorePara.innerText =userScore; + msg.innerText=`Congratulations! You won. ${userChoice} beats the ${compChoice}` + msg.style.backgroundColor="green"; + } + else{ + console.log("Sorry you lost, better luck next time.") + compScore++; + compScorePara.innerText=compScore; + msg.innerText=`Sorry you lost, better luck next time. ${userChoice} lost to the ${compChoice}` + msg.style.backgroundColor="red"; + } +} + +const playGame= (userChoice)=>{ + console.log("userchoice = ", userChoice); + const compChoice=genCompChoice(); + console.log("compChoice= ", compChoice); + + if (userChoice==compChoice){ + drawGame(); + }else{ + let userWin=true; + if(userChoice=="Boy"){ + userWin=compChoice==="Elephant"? false:true; + } + else if(userChoice=="Elephant"){ + userWin=compChoice==="Ant"? false:true; + } + else{ + userWin=compChoice==="Boy"? false:true; + } + showWinner(userWin, userChoice, compChoice); + + } +}; + +choices.forEach((choice)=>{ + choice.addEventListener("click",()=>{ + const userChoice= choice.getAttribute("id"); + playGame(userChoice); + }); +}); \ No newline at end of file diff --git a/Games/Elephant_ant_man/style.css b/Games/Elephant_ant_man/style.css new file mode 100644 index 0000000000..80aa99d53a --- /dev/null +++ b/Games/Elephant_ant_man/style.css @@ -0,0 +1,64 @@ +*{ + margin:0; + padding:0; + text-align: center; + background-color: rgb(217, 251, 223); +} +h1 { + background-color: rgb(109, 130, 100); + color: azure; + height: 80px; + line-height: 80px; + font: 80px; + +} +.choice:hover{ + opacity: 0.5; + cursor:grab; +} +.choice{ + height: 200px; + width: 200px; + border-radius: 50%; +} +img{ + height:175px; + width:175px; + border-radius: 50%; + object-fit: cover; + +} +.choices{ + display:flex; + justify-content: center; + align-items: center; + gap:50px; + margin-top: 90px; +} + +.scoreboard{ + display:flex; + justify-content: center; + align-items: center; + gap:100px; + margin-top:40px; + font-size:40px; + color:rgb(53, 76, 53) +} +#userscore,#compscore{ + font-size:60px; +} +#msg{ + background-color: rgb(109, 130, 100); + color:azure; + font-size:35px; + font-style:italic; + height:60px; + display:inline; + padding: 20px; + border-radius: 1rem; + +} +.msgcontainer{ + margin-top: 60px; +} diff --git a/Games/Five_Nights_at_Freddys/README.md b/Games/Five_Nights_at_Freddys/README.md new file mode 100644 index 0000000000..19020b10f3 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/README.md @@ -0,0 +1,21 @@ + +## Installation + +First you need to clone this repository + + + +Then start it using npm or yarn + +``` +npm install --legacy-peer-deps +``` + +Then start localhost + +``` +npm start +``` + + + diff --git a/Games/Five_Nights_at_Freddys/package.json b/Games/Five_Nights_at_Freddys/package.json new file mode 100644 index 0000000000..58dd587382 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/package.json @@ -0,0 +1,41 @@ +{ + "name": "fnaf", + "version": "0.1.0", + "private": true, + "dependencies": { + "@testing-library/jest-dom": "^4.2.4", + "@testing-library/react": "^9.3.2", + "@testing-library/user-event": "^7.1.2", + "gh-pages": "^3.2.3", + "global": "^4.4.0", + "react": "^16.14.0", + "react-dom": "^16.14.0", + "react-image-mapper": "^1.0.0", + "react-redux": "^7.2.2", + "react-scripts": "3.4.1", + "redux": "^4.0.5" + }, + "scripts": { + "predeploy": "npm run build", + "deploy": "gh-pages -d build", + "start": "react-scripts --openssl-legacy-provider start", + "build": "react-scripts --openssl-legacy-provider build", + "test": "react-scripts --openssl-legacy-provider test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": "react-app" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/Games/Five_Nights_at_Freddys/public/favicon.ico b/Games/Five_Nights_at_Freddys/public/favicon.ico new file mode 100644 index 0000000000..ff6fe84ae0 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/favicon.ico differ diff --git a/Games/Five_Nights_at_Freddys/public/icon-192x192.png b/Games/Five_Nights_at_Freddys/public/icon-192x192.png new file mode 100644 index 0000000000..e19126b24f Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/icon-192x192.png differ diff --git a/Games/Five_Nights_at_Freddys/public/icon-256x256.png b/Games/Five_Nights_at_Freddys/public/icon-256x256.png new file mode 100644 index 0000000000..09c214af4e Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/icon-256x256.png differ diff --git a/Games/Five_Nights_at_Freddys/public/icon-384x384.png b/Games/Five_Nights_at_Freddys/public/icon-384x384.png new file mode 100644 index 0000000000..66cb397ef3 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/icon-384x384.png differ diff --git a/Games/Five_Nights_at_Freddys/public/icon-512x512.png b/Games/Five_Nights_at_Freddys/public/icon-512x512.png new file mode 100644 index 0000000000..a6fde2166c Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/icon-512x512.png differ diff --git a/Games/Five_Nights_at_Freddys/public/index.html b/Games/Five_Nights_at_Freddys/public/index.html new file mode 100644 index 0000000000..cad6906ddc --- /dev/null +++ b/Games/Five_Nights_at_Freddys/public/index.html @@ -0,0 +1,29 @@ + + + + + + + + + + + + + Five Nights at Freddy's Web + + + + + +
+ + + + diff --git a/Games/Five_Nights_at_Freddys/public/manifest.json b/Games/Five_Nights_at_Freddys/public/manifest.json new file mode 100644 index 0000000000..e7f492cebb --- /dev/null +++ b/Games/Five_Nights_at_Freddys/public/manifest.json @@ -0,0 +1,37 @@ +{ + "theme_color": "#000000", + "background_color": "#000000", + "display": "fullscreen", + + "name": "Five Nights at Freddy's Web", + "short_name": "FNAF Web", + "description": "A web version of the popular game Five Nights at Freddy's", + "orientation": "landscape", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "/icon-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/icon-256x256.png", + "sizes": "256x256", + "type": "image/png" + }, + { + "src": "/icon-384x384.png", + "sizes": "384x384", + "type": "image/png" + }, + { + "src": "/icon-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/Games/Five_Nights_at_Freddys/public/robots.txt b/Games/Five_Nights_at_Freddys/public/robots.txt new file mode 100644 index 0000000000..e9e57dc4d4 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/Games/Five_Nights_at_Freddys/src/Controller.js b/Games/Five_Nights_at_Freddys/src/Controller.js new file mode 100644 index 0000000000..0bf8ac8174 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/Controller.js @@ -0,0 +1,135 @@ +import React, { useState, useEffect } from "react"; +import BlackoutSound from "./media/Sounds/powerdown.mp3"; +import { connect } from "react-redux"; +import Game from "./Game"; + +import StaticImage from "./media/Textures/Static-Cam.webp"; +import StaticSound from "./media/Sounds/Dead.mp3"; +import VictoryGIF from "./media/Textures/Victory.gif"; +import VictorySound from "./media/Sounds/Clock.mp3"; + +///89000 +const TIME_TO_CHANGE_HOUR = 89000; + +let gameOverAudio = new Audio(StaticSound); +let hourInterval = null; + +function Controller({ + isPlaying, + hour, + time, + energy, + jumpscare, + setStart, + dispatch, + stages, +}) { + const [gameOver, setGameOver] = useState(false); + const [victory, setVictory] = useState(false); + + + useEffect(() => { + dispatch({ type: "CLEAR_DATA" }); + changeEnergy(); + + return () => { + // clearInterval(hourInterval); + dispatch({ type: "CLEAR_DATA" }); + gameOverAudio.pause(); + }; + }, []); + + useEffect(() => { + setTimeout(() => { + if (hour === 5 && !gameOver) endGame(true); + else changeHour(hour); + }, TIME_TO_CHANGE_HOUR); + }, [hour]) + + useEffect(() => { + if (energy <= 0) { + setBlackout(); + } else changeEnergy(energy); + }, [energy]); + + async function changeHour(h) { + if (isPlaying && !jumpscare && !gameOver && h < 6) { + dispatch({ type: "CHANGE_HOUR" }); + } + } + + async function changeEnergy(e) { + if (isPlaying && !gameOver && e > 0) { + setTimeout(() => { + dispatch({ type: "CHANGE_ENERGY" }); + }, time); + } + } + + const setBlackout = () => { + new Audio(BlackoutSound).play(); + + dispatch({ type: "FORCE_CAMERA_CLOSE" }); + dispatch({ type: "CHANGE_CAMERA_BUTTON" }); + }; + + const endGame = (hasWon) => { + if (hasWon) { + setVictory(true); + let VictoryMusic = new Audio(VictorySound); + VictoryMusic.play(); + + const victories = JSON.parse(localStorage.getItem("victories")) || {}; + if(stages.mode !== "CUSTOM") victories[stages.mode] = "★" + + localStorage.setItem("victories", JSON.stringify(victories)); + } else { + setGameOver(true); + gameOverAudio.currentTime = 0; + gameOverAudio.play(); + } + dispatch({ type: "SET_GAME_OVER" }); + setTimeout(() => { + setStart(false); + }, 10000); + }; + + return ( + <> + {gameOver ? ( + static + ) : null} + {victory ? ( +
+ victory +
+ ) : null} + + + ); +} + +const mapStateToProps = (state) => { + return { + time: state.configReducer.time, + hour: state.configReducer.hour, + isPlaying: state.configReducer.isPlaying, + jumpscare: state.configReducer.jumpscare, + energy: state.configReducer.energy, + animatronics: state.animatronicsReducer, + }; +}; + +export default connect(mapStateToProps)(Controller); diff --git a/Games/Five_Nights_at_Freddys/src/CustomNight.js b/Games/Five_Nights_at_Freddys/src/CustomNight.js new file mode 100644 index 0000000000..40c2a6be12 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/CustomNight.js @@ -0,0 +1,161 @@ +import React from 'react'; +import styles from "./css/CustomNight.module.css" + +import Freddy from "./media/Textures/CustomNight/freddy.png"; +import Bonnie from "./media/Textures/CustomNight/bonnie.png"; +import Chica from "./media/Textures/CustomNight/chica.png"; +import Foxy from "./media/Textures/CustomNight/foxy.png"; + +import goldenFreddyJumpscare from "./media/Sounds/golden_freddy.ogg"; + +const images = { + Freddy, + Bonnie, + Chica, + Foxy +} + +const AnimatronicContainer = (props) => { + const {range, changeRange, character} = props; + + return ( +
+ Five Nights At Freddy's + +
+ + {range} + +
+
+ ) +}; + +const CustomNight = ({state, setStart}) => { + const [goldenFreddy, setGoldenFreddy] = React.useState(false); + const changeMode = (value) => { + + let animatronics = {}; + + switch(value) { + case "EASY": + animatronics = {Bonnie: 2, Freddy: 2, Chica: 2, Foxy: 2}; + break; + case "NORMAL": + animatronics = {Bonnie: 10, Freddy: 10, Chica: 10, Foxy: 10}; + break; + case "HARD": + animatronics = {Bonnie: 15, Freddy: 15, Chica: 15, Foxy: 15}; + break; + case "IMPOSSIBLE": + animatronics = {Bonnie: 20, Freddy: 20, Chica: 20, Foxy: 20}; + break; + default: + return; + } + + state.setStages((stages) => ({...animatronics, mode: value})); + }; + + const changeRange = (value, character) => { + const handleValue = (state, value) => + (state === 0 && value < 0) || (state === 20 && value > 0) ? state : state + value + + + state.setStages((stages) => ({...stages, mode: "CUSTOM", [character]: handleValue(stages[character], value)})); + } + + const hasWon = (mode) => { + const victories = JSON.parse(localStorage.getItem("victories")) || {}; + + return victories[mode] || " "; + } + + const handleStart = () => { + if ( + state.ranges.Freddy === 1 && + state.ranges.Bonnie === 9 && + state.ranges.Chica === 8 && + state.ranges.Foxy === 7 + ) { + const golden = new Audio(goldenFreddyJumpscare); + golden.play(); + return setGoldenFreddy(true); + } + setStart(true); + } + + if(goldenFreddy) return ; + + return ( +
+ + + + + +

{"Five Nights at Freddy's Web"}

+ +
+ + + + +
+ + +
+ +
+ +
+ + + + +
+ +
+

Made by Wendell de Sousa | 2021

+ {/*

Five Nights at Freddy's © Scott Cawthon

*/} +
+
+ ) +}; + +export default CustomNight; + +function GoldenFreddy({setGoldenFreddy}) { + React.useEffect(() => { + setTimeout(() => { + window.open("about:blank", "_self"); + window.close(); + setGoldenFreddy(false); + }, 5000); + }, []) + + return
+} \ No newline at end of file diff --git a/Games/Five_Nights_at_Freddys/src/Game.js b/Games/Five_Nights_at_Freddys/src/Game.js new file mode 100644 index 0000000000..10d80d2a5c --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/Game.js @@ -0,0 +1,125 @@ +import React, { useEffect } from "react"; +import { connect } from "react-redux"; + +import Animatronic from "./components/Animatronic"; +import Office from "./components/Office"; +import Camera from "./components/Camera"; +import Hud from "./components/Hud"; +import Media from "./components/Media"; + +let isBlackout = false; + +let { Ambience } = Media.Sounds; +Ambience.loop = true; + +let officeProps = { leftDoor: false, rightDoor: false }; + +const Game = ({ + office, + isCameraOpen, + energy, + gameOver, + stages, + endGame, + dispatch, +}) => { + useEffect(() => { + Ambience.currentTime = 0; + Ambience.play(); + isBlackout = false; + officeProps = { leftDoor: false, rightDoor: false }; + }, []); + + useEffect(() => { + if (gameOver) Ambience.pause(); + }, [gameOver]); + + useEffect(() => { + if (energy <= 0) { + isBlackout = true; + Ambience.pause(); + } + }, [energy]); + + useEffect(() => { + let newTime = 6300; + if (office.leftDoor) newTime -= 1100; + if (office.rightDoor) newTime -= 1100; + if (office.leftLight) newTime -= 500; + if (office.rightLight) newTime -= 500; + if (isCameraOpen) newTime -= 1100; + + dispatch({ type: "CHANGE_TIME", content: newTime }); + officeProps = { + leftDoor: office.leftDoor, + rightDoor: office.rightDoor, + }; + }, [ + office.leftDoor, + office.rightDoor, + office.leftLight, + office.rightLight, + isCameraOpen, + ]); + + const handleJumpscare = (character) => { + if (isBlackout || gameOver) return; + dispatch({ + type: "CHANGE_ANIMATRONIC", + animatronic: character, + animatronicState: { + door: null, + camera: null, + jumpscare: true, + }, + }); + + dispatch({ type: "CHANGE_JUMPSCARE", animatronic: character }); + if (character === "Foxy" || character === "Freddy") + dispatch({ type: "FORCE_CAMERA_CLOSE" }); + setTimeout(() => { + if (!isCameraOpen) dispatch({ type: "FORCE_CAMERA_CLOSE" }); + }, 10000); + }; + + async function isThisDoorOpen(door) { + const isDoorOpen = await officeProps[door]; + return isDoorOpen; + } + + return ( + <> + + + {!gameOver ? ( + <> + {energy <= 0 ? null : } + + {isCameraOpen ? null : ( + + )} + + ) : null} + + ); +}; + +const mapStateToProps = (state) => { + return { + animatronics: state.animatronicsReducer, + time: state.configReducer.time, + hour: state.configReducer.hour, + energy: state.configReducer.energy, + office: state.officeReducer, + camera: state.cameraReducer.camera, + isCameraOpen: state.cameraReducer.isCameraOpen, + }; +}; + +export default connect(mapStateToProps)(Game); diff --git a/Games/Five_Nights_at_Freddys/src/components/Animatronic.js b/Games/Five_Nights_at_Freddys/src/components/Animatronic.js new file mode 100644 index 0000000000..60378f43cb --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/Animatronic.js @@ -0,0 +1,229 @@ +import React, { useState, useEffect } from "react"; +import Functions from "./Functions"; +import Media from "./Media"; +import { connect } from "react-redux"; + +let FreddyIterator = Functions.Freddy(); +let BonnieIterator = Functions.Bonnie(); +let ChicaIterator = Functions.Chica(); +let FoxyIterator = Functions.Foxy(); + +FreddyIterator.next(); + +let FreddyTime = 10000; +let BonnieTime = 5000; +let ChicaTime = 7300; +let FoxyTime = 13000; + +const ranges = { + Freddy: 1, + Bonnie: 1, + Chica: 2, + Foxy: 1, +} + +let isBlackout = false; +let isGameOver = false; + +function Animatronic({ + animatronics, + config, + handleJumpscare, + isThisDoorOpen, + dispatch, + stages +}) { + const { hour, gameOver, blackout } = config; + + useEffect(() => { + ranges["Freddy"] = stages.Freddy; + ranges["Bonnie"] = stages.Bonnie; + ranges["Chica"] = stages.Chica; + ranges["Foxy"] = stages.Foxy; + + if(stages.Bonnie) willMove("Bonnie", BonnieIterator, BonnieTime); + if(stages.Chica) willMove("Chica", ChicaIterator, ChicaTime); + if(stages.Foxy) willMove("Foxy", FoxyIterator, FoxyTime, true); + if(stages.Freddy && stages.Chica && stages.Bonnie)willMove("Freddy", FreddyIterator, FreddyTime, true); + + return () => { + FreddyIterator = Functions.Freddy(); + BonnieIterator = Functions.Bonnie(); + ChicaIterator = Functions.Chica(); + FoxyIterator = Functions.Foxy(); + + FreddyIterator.next(); + + FreddyTime = 10000; + BonnieTime = 5000; + ChicaTime = 7300; + FoxyTime = 13000; + ranges["Freddy"] = stages.Freddy; + ranges["Bonnie"] = stages.Bonnie; + ranges["Chica"] = stages.Chica; + ranges["Foxy"] = stages.Foxy; + + isBlackout = false; + isGameOver = false; + }; + }, []); + + useEffect(() => { + if (hour === 2) { + FreddyTime = 9500; + BonnieTime = 4700; + ChicaTime = 6800; + FoxyTime = 10000; + + + ranges["Bonnie"] = ranges["Bonnie"] + 1; + ranges["Chica"] = ranges["Chica"] + 1; + } else if (hour === 4) { + ranges["Bonnie"] = ranges["Bonnie"] + 2; + ranges["Chica"] = ranges["Chica"] + 2; + ranges["Freddy"] = ranges["Freddy"] + 1; + ranges["Foxy"] = ranges["Foxy"] + 1; + } else if (hour === 5) { + ranges["Bonnie"] = ranges["Bonnie"] + 2; + ranges["Chica"] = ranges["Chica"] + 2; + ranges["Freddy"] = ranges["Freddy"] + 2; + ranges["Foxy"] = ranges["Foxy"] + 2; + } + }, [hour]); + + useEffect(() => { + if (gameOver) isGameOver = gameOver; + }, [gameOver]); + + const changeAnimatronic = (func) => { + dispatch({ type: "CHANGE_ANIMATRONICS_MOVING", content: true }); + + func(); + + setTimeout(() => { + dispatch({ + type: "CHANGE_ANIMATRONICS_MOVING", + content: false, + }); + }, 1500); + }; + + const animatronicFailed = (character) => { + changeAnimatronic(() => { + dispatch({ + type: "CHANGE_ANIMATRONIC", + animatronic: character, + animatronicState: { + door: false, + camera: + character === "Freddy" + ? "Stage" + : character === "Foxy" + ? "" + : "Dinning Area", + jumpscare: false, + }, + }); + + if (character === "Bonnie") { + BonnieIterator = Functions.Bonnie(); + willMove("Bonnie", BonnieIterator, BonnieTime); + } else if (character === "Chica") { + ChicaIterator = Functions.Chica(); + willMove("Chica", ChicaIterator, ChicaTime); + } else if (character === "Foxy") { + FoxyIterator = Functions.Foxy(); + Media.Sounds.FoxyPunch.play(); + willMove("Foxy", FoxyIterator, FoxyTime, true); + } else if (character === "Freddy") { + FreddyIterator = Functions.Freddy(); + FreddyIterator.next(); + willMove("Freddy", FreddyIterator, FreddyTime, true); + } + }); + }; + + const freddyLaugh = () => { + if (isBlackout) return; + let FreddyNumber = Math.floor(Math.random() * 2); + if (FreddyNumber == 0) { + Media.Sounds.FreddyLaugh1.play(); + } else { + Media.Sounds.FreddyLaugh2.play(); + } + }; + useEffect(() => { + if (blackout) isBlackout = true; + }, [blackout]); + + function willMove (character, iterator, animaTime) { + const thisInterval = setInterval(() => { + const max = character === "Bonnie" || character === "Chica" ? 22 : 30; + let luckyNumber = Math.floor(Math.random() * max); + + let condition = luckyNumber < ranges[character] && !animatronics[character].door; + + let newPlace; + if (condition) { + changeAnimatronic(() => { + newPlace = iterator.next().value; + + const newState = { + door: newPlace === "Door" || newPlace === "_3", + jumpscare: false, + camera: newPlace, + }; + dispatch({ + type: "CHANGE_ANIMATRONIC", + animatronic: character, + animatronicState: newState, + }); + }); + + if (character === "Freddy") freddyLaugh(); + } + + if (isBlackout || isGameOver) clearInterval(thisInterval); + + if (newPlace === "Door" || newPlace === "_3") { + if (!isBlackout) checkDoors(character); + clearInterval(thisInterval); + } + }, animaTime); + }; + + async function checkDoors(character) { + const door = + character === "Bonnie" || character === "Foxy" ? "leftDoor" : "rightDoor"; + + setTimeout(async () => { + const isDoorOpen = await isThisDoorOpen(door); + if (!isDoorOpen) { + setTimeout(async () => { + const isDoorOpen = await isThisDoorOpen(door); + if (!isDoorOpen) { + setTimeout(async () => { + const isDoorOpen = await isThisDoorOpen(door); + if (!isDoorOpen) { + handleJumpscare(character); + } else animatronicFailed(character); + }, 3000); + } else animatronicFailed(character); + }, 5000); + } else animatronicFailed(character); + }, 10000); + } + + return <>; +} + +const mapStateToProps = (state) => { + return { + leftDoor: state.officeReducer.leftDoor, + rightDoor: state.officeReducer.rightDoor, + animatronics: state.animatronicsReducer, + config: state.configReducer, + }; +}; + +export default connect(mapStateToProps)(Animatronic); diff --git a/Games/Five_Nights_at_Freddys/src/components/Camera.js b/Games/Five_Nights_at_Freddys/src/components/Camera.js new file mode 100644 index 0000000000..2e2b36457d --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/Camera.js @@ -0,0 +1,175 @@ +import React, { useState, useEffect, useRef } from "react"; +import { connect } from "react-redux"; +import getCam from "./Images"; + +import AnimatronicsMoving from "../media/Sounds/garble1.mp3"; +import AnimatronicsMoving2 from "../media/Sounds/garble2.mp3"; +import Static from "../media/Textures/Static-Cam.webp"; +import Black from "../media/Textures/black.jpg"; +import Media from "./Media"; + +import CameraMap from "../components/CameraMap"; +import CameraButton from "../components/CameraButton"; + +function Camera({ + animatronics, + areAnimatronicsMoving, + isCameraOpen, + office, + camera, + cameraButtonDisappear, + dispatch, +}) { + const [Image, setImage] = useState(Media.Images.Stage); + + const closeCameraRef = useRef(null); + const cameraDivRef = useRef(null); + + const handleCameraButton = () => { + dispatch({ type: "SET_IS_OPEN" }); + }; + + const handleCameraChange = (e) => { + e.preventDefault(); + Media.Sounds.CameraChange.play(); + dispatch({ type: "CHANGE_CAMERA", content: e.target.title }); + }; + + useEffect(() => { + if (cameraDivRef.current) { + if (isCameraOpen) + setTimeout(() => { + cameraDivRef.current.style.display = "flex"; + }, 350); + else + setTimeout(() => { + cameraDivRef.current.style.display = "none"; + }, 100); + } + }, [isCameraOpen]); + + useEffect(() => { + const { Bonnie, Chica, Freddy, Foxy } = animatronics; + let result = ""; + if (Bonnie.camera === camera) result += "_b"; + if (Chica.camera === camera) result += "_c"; + if (Freddy.camera === camera) result += "_f"; + + const newCamera = getCam(result, camera, Foxy.camera); + setImage(newCamera); + }, [camera, animatronics, areAnimatronicsMoving, animatronics.Foxy.camera]); + + useEffect(() => { + if (areAnimatronicsMoving && isCameraOpen) { + let MusicNumber = Math.floor(Math.random() * 2); + let Sound; + if (MusicNumber == 1 || MusicNumber == 2) { + Sound = new Audio(AnimatronicsMoving); + } else { + Sound = new Audio(AnimatronicsMoving2); + } + Sound.play(); + } + }, [areAnimatronicsMoving]); + + return ( +
+ {cameraButtonDisappear ? null : ( + + )} + {isCameraOpen ? ( + <> + Opening camera +
+ + {areAnimatronicsMoving ? ( + Animatronics are moving + ) : ( + Camera + )} + Static +
+ + ) : ( + Closing camera + )} +
+ ); +} + +const mapStateToProps = (state) => { + return { + animatronics: state.animatronicsReducer, + camera: state.cameraReducer.camera, + office: state.officeReducer, + isCameraOpen: state.cameraReducer.isCameraOpen, + areAnimatronicsMoving: state.cameraReducer.areAnimatronicsMoving, + jumpscare: state.configReducer.jumpscare, + cameraButtonDisappear: state.configReducer.cameraButtonDisappear, + }; +}; + +export default connect(mapStateToProps)(Camera); diff --git a/Games/Five_Nights_at_Freddys/src/components/CameraButton.js b/Games/Five_Nights_at_Freddys/src/components/CameraButton.js new file mode 100644 index 0000000000..2de25148ab --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/CameraButton.js @@ -0,0 +1,33 @@ +import React from "react"; +import Media from "./Media"; + +function CameraButton(props) { + const { handleCameraButton } = props; + + const handleCamera = ({ target }) => { + if (target.dataset.disabled == "true") { + target.dataset.disabled = "false"; + Media.Sounds.OpenCamera.play(); + handleCameraButton(); + setTimeout(() => { + target.dataset.disabled = "true"; + }, 700); + } + }; + return ( +
+ Botão da camera +
+ ); +} + +export default CameraButton; diff --git a/Games/Five_Nights_at_Freddys/src/components/CameraMap.js b/Games/Five_Nights_at_Freddys/src/components/CameraMap.js new file mode 100644 index 0000000000..15f33d9743 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/CameraMap.js @@ -0,0 +1,162 @@ +import React from "react"; +import Media from "./Media"; + +function CameraMap(props) { + const { handleCameraChange } = props; + return ( +
+ Mapa da câmera + + + + + + + + + + + +
+ ); +} + +export default CameraMap; diff --git a/Games/Five_Nights_at_Freddys/src/components/Functions.js b/Games/Five_Nights_at_Freddys/src/components/Functions.js new file mode 100644 index 0000000000..b10a0eb874 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/Functions.js @@ -0,0 +1,73 @@ +function* Bonnie() { + yield* [ + "Dinning Area", + "Backstage", + "Supply Closet", + "West Hall", + "W. Hall Corner", + "Door", + ]; +} + +function* Chica() { + yield* [ + "Dinning Area", + "Restrooms", + "Kitchen", + "East Hall", + "E. Hall Corner", + "Door", + ]; +} + +function* Freddy() { + yield* [ + "Stage", + "Dinning Area", + "Restrooms", + "Kitchen", + "East Hall", + "E. Hall Corner", + "Door", + ]; +} + +function* Foxy() { + yield* ["_1", "_2", "_3"]; +} + +const changeAnimatronic = (Localization, iterator, setAnimatronics, change) => { + Localization = iterator.next().value; + setAnimatronics(change); +}; + +const checkAnimatronicsPosition = ( + BonnieLocal, + ChicaLocal, + FreddyLocal, + search +) => { + let res = ""; + if (BonnieLocal == search) { + res += "-b"; + } + if (ChicaLocal == search) { + res += "-c"; + } + if (FreddyLocal == search) { + res += "-f"; + } + + return res; +}; + +const Functions = { + Freddy, + Chica, + Bonnie, + Foxy, + changeAnimatronic, + checkAnimatronicsPosition, +}; + +export default Functions; diff --git a/Games/Five_Nights_at_Freddys/src/components/Hud.js b/Games/Five_Nights_at_Freddys/src/components/Hud.js new file mode 100644 index 0000000000..3ae83a0b3b --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/Hud.js @@ -0,0 +1,20 @@ +import React from "react"; +import { connect } from "react-redux"; + +function Hud({ hour, energy }) { + return ( +
+

{hour === 0 ? "12AM" : `${hour}AM`}

+

{energy}%

+
+ ); +} + +const mapStateToProps = (state) => { + return { + hour: state.configReducer.hour, + energy: state.configReducer.energy, + }; +}; + +export default connect(mapStateToProps)(Hud); diff --git a/Games/Five_Nights_at_Freddys/src/components/Images.js b/Games/Five_Nights_at_Freddys/src/components/Images.js new file mode 100644 index 0000000000..883a63fd4a --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/Images.js @@ -0,0 +1,116 @@ +///SHOW STAGE +import Stage from "../media/Textures/Cams/Stage.webp"; +import Stage_b_c_f from "../media/Textures/Cams/Stage-b-c-f.webp"; +import Stage_b_f from "../media/Textures/Cams/Stage-b-f.webp"; +import Stage_c_f from "../media/Textures/Cams/Stage-c-f.webp"; +import Stage_f from "../media/Textures/Cams/Stage-f.webp"; + +///DINNING AREA +import DinningArea from "../media/Textures/Cams/DinningArea.webp"; +import DinningArea_b from "../media/Textures/Cams/DinningArea-b.webp"; +import DinningArea_c from "../media/Textures/Cams/DinningArea-c.webp"; +import DinningArea_f from "../media/Textures/Cams/DinningArea-f.webp"; +import DinningArea_b_c from "../media/Textures/Cams/DinningArea-b-c.webp"; +import DinningArea_c_f from "../media/Textures/Cams/DinningArea-c-f.webp"; +import DinningArea_b_f from "../media/Textures/Cams/DinningArea-b-f.webp"; +import DinningArea_b_c_f from "../media/Textures/Cams/DinningArea-b-c-f.webp"; + +///BACKSTAGE +import Backstage from "../media/Textures/Cams/Backstage.webp"; +import Backstage_b from "../media/Textures/Cams/Backstage-b.webp"; + +///PIRATE COVE +import PirateCove from "../media/Textures/Cams/Pirate_Cove.webp"; +import PirateCove_1 from "../media/Textures/Cams/Pirate_Cove-1.webp"; +import PirateCove_2 from "../media/Textures/Cams/Pirate_Cove-2.webp"; +import PirateCove_3 from "../media/Textures/Cams/Pirate_Cove-3.webp"; + +///SUPPLY ROOM +import SupplyCloset from "../media/Textures/Cams/SupplyRoom.webp"; +import SupplyCloset_b from "../media/Textures/Cams/SupplyRoom-b.webp"; + +///WEST HALL +import WestHall from "../media/Textures/Cams/West_Hall.webp"; +import WestHall_b from "../media/Textures/Cams/West_Hall-b.webp"; +import FoxyHallway from "../media/Textures/Foxy-Hallway.webp"; + +///WEST HALL CORNER +import WHallCorner from "../media/Textures/Cams/WHallCorner.webp"; +import WHallCorner_b from "../media/Textures/Cams/WHallCorner-b.webp"; + +///RESTROOMS +import Restrooms from "../media/Textures/Cams/Restrooms.webp"; +import Restrooms_c from "../media/Textures/Cams/Restrooms-c.webp"; +import Restrooms_f from "../media/Textures/Cams/Restrooms-f.webp"; +import Restrooms_c_f from "../media/Textures/Cams/Restrooms-c-f.webp"; + +///EAST HALL +import EastHall from "../media/Textures/Cams/East_Hall.webp"; +import EastHall_c from "../media/Textures/Cams/East_Hall-c.webp"; +import EastHall_f from "../media/Textures/Cams/East_Hall-f.webp"; +import EastHall_c_f from "../media/Textures/Cams/East_Hall-c-f.webp"; + +///EAST HALL CORNER +import EHallCorner from "../media/Textures/Cams/EHallCorner.webp"; +import EHallCorner_c from "../media/Textures/Cams/EHallCorner-c.webp"; +import EHallCorner_f from "../media/Textures/Cams/EHallCorner-f.webp"; + +import Kitchen from "../media/Textures/black.jpg"; +import Kitchen_c from "../media/Textures/black.jpg"; +import Kitchen_f from "../media/Textures/black.jpg"; +import Kitchen_c_f from "../media/Textures/black.jpg"; + +const cameraImages = { + Stage, + Stage_b_c_f, + Stage_b_f, + Stage_c_f, + Stage_f, + DinningArea, + DinningArea_b_c_f, + DinningArea_c_f, + DinningArea_b_f, + DinningArea_b_c, + DinningArea_b, + DinningArea_c, + DinningArea_f, + Backstage, + Backstage_b, + SupplyCloset, + SupplyCloset_b, + WestHall, + WestHall_b, + WHallCorner, + WHallCorner_b, + Restrooms, + Restrooms_c, + Restrooms_c_f, + Restrooms_f, + EastHall, + EastHall_c, + EastHall_c_f, + EastHall_f, + EHallCorner, + EHallCorner_c, + EHallCorner_f, + EHallCorner_c_f: EHallCorner_f, + PirateCove, + PirateCove_1, + PirateCove_2, + PirateCove_3, + Kitchen, + Kitchen_c, + Kitchen_f, + Kitchen_c_f, +}; + +export default function getCam(animatronics, camera, foxy = "") { + let location = camera.trim().replaceAll(" ", ""); + + if (location === "W.HallCorner") location = "WHallCorner"; + if (location === "E.HallCorner") location = "EHallCorner"; + + return cameraImages[ + `${location}${animatronics}${location === "PirateCove" ? foxy : ""}` + ]; +} diff --git a/Games/Five_Nights_at_Freddys/src/components/Media.js b/Games/Five_Nights_at_Freddys/src/components/Media.js new file mode 100644 index 0000000000..8a6f970a9d --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/Media.js @@ -0,0 +1,45 @@ +/// AUDIO +import CameraSound from "../media/Sounds/put down.mp3"; +import CameraChange from "../media/Sounds/blip3.mp3"; +import Ambience from "../media/Sounds/MainAmbience.mp3"; +import FreddyLaugh1 from "../media/Sounds/FreddyLaugh1.mp3"; +import FreddyLaugh2 from "../media/Sounds/FreddyLaugh2.mp3"; +import Door from "../media/Sounds/Door.mp3"; +import FoxyPunch from "../media/Sounds/knock2.mp3"; +import Surprise from "../media/Sounds/windowscare.mp3"; +import Jumpscare from "../media/Sounds/jumpscare.mp3"; + +/// IMAGES +import CameraButton from "../media/Textures/CameraButton.png"; +import Up from "../media/Textures/Up.webp"; +import Down from "../media/Textures/Down.webp"; +import Map from "../media/Textures/Cams/Complete_Map.png"; +import Stage from "../media/Textures/Cams/Stage-b-c-f.webp"; + +const Sounds = { + OpenCamera: new Audio(CameraSound), + CameraChange: new Audio(CameraChange), + Ambience: new Audio(Ambience), + FreddyLaugh1: new Audio(FreddyLaugh1), + FreddyLaugh2: new Audio(FreddyLaugh2), + Door: new Audio(Door), + FoxyPunch: new Audio(FoxyPunch), + Surprise: new Audio(Surprise), + Jumpscare: new Audio(Jumpscare), +}; + +const Images = { + CameraButton, + Up, + Down, + Map, + Stage, + Ambience, +}; + +const Media = { + Sounds, + Images, +}; + +export default Media; diff --git a/Games/Five_Nights_at_Freddys/src/components/Office.js b/Games/Five_Nights_at_Freddys/src/components/Office.js new file mode 100644 index 0000000000..9b1d3c9ee1 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/components/Office.js @@ -0,0 +1,383 @@ +import React, { useState, useEffect } from "react"; +import { connect } from "react-redux"; + +import Default from "../media/Textures/Office/Default.webp"; +import Media from "./Media"; + +import Blackout from "../media/Textures/Office/304.webp"; +import MusicBox from "../media/Sounds/music box.mp3"; +import FreddyBlackout from "../media/Textures/Freddy.webp"; + +import JumpscareMP3 from "../media/Sounds/jumpscare.mp3"; +import BonnieJumpscare from "../media/Textures/Bonnie-Jumpscare.webp"; +import ChicaJumpscare from "../media/Textures/Chica-Jumpscare.webp"; +import FreddyJumpscare1 from "../media/Textures/Freddy-Jumpscare1.gif"; +import FreddyJumpscare2 from "../media/Textures/Freddy-Jumpscare.webp"; +import FoxyJumpscare from "../media/Textures/Foxy-Jumpscare.gif"; + +import LD from "../media/Textures/Office/LD.webp"; +import RD from "../media/Textures/Office/RD.webp"; +import RD_LD from "../media/Textures/Office/RD_LD.webp"; +import LD_RL from "../media/Textures/Office/LD_RL.webp"; +import RD_LL from "../media/Textures/Office/RD_LL.webp"; + +import RD_LL_BONNIE from "../media/Textures/Office/RD_LL_BONNIE.webp"; +import LD_RL_CHICA from "../media/Textures/Office/LD_RL_CHICA.webp"; +import RL from "../media/Textures/Office/RL.webp"; + +import RL_LL_BONNIE from "../media/Textures/Office/RL_LL_BONNIE.webp"; +import LL from "../media/Textures/Office/LL.webp"; +import LL_BONNIE from "../media/Textures/Office/LL_BONNIE.webp"; +import RL_LL from "../media/Textures/Office/RL_LL.webp"; +import RL_CHICA from "../media/Textures/Office/RL_CHICA.webp"; +import RL_LL_CHICA from "../media/Textures/Office/RL_LL_CHICA.webp"; +import RL_LL_BONNIE_CHICA from "../media/Textures/Office/RL_LL_BONNIE_CHICA.webp"; + +let canJumpscare = true; + +const officeImages = { + LD, + RD, + RD_LD, + LD_RL, + RD_LL, + RD_LL_BONNIE, + LD_RL_CHICA, + RL, + RL_LL_BONNIE, + LL, + LL_BONNIE, + RL_CHICA, + RL_LL, + RL_LL_CHICA, + RL_LL_BONNIE_CHICA, +}; + +let musicBox = new Audio(MusicBox); +let jumpscareSound = new Audio(JumpscareMP3); +musicBox.loop = "true"; + +function Office({ + blackout, + animatronics, + officeConfig, + jumpscare, + isCameraOpen, + endGame, + dispatch, +}) { + const [isJumpscare, setIsJumpscare] = useState(null); + const [background, setBackground] = useState(Default); + const [blackoutBackground, setBlackoutBackground] = useState(Blackout); + + useEffect(() => { + checkBackground(); + }, [ + officeConfig.leftDoor, + officeConfig.leftLight, + officeConfig.rightDoor, + officeConfig.rightLight, + ]); + + useEffect(() => { + if (isCameraOpen) return; + checkBackground(); + + if (jumpscare) { + dispatch({ type: "CHANGE_CAMERA_BUTTON" }); + setIsJumpscare(jumpscare); + jumpscareSound.play(); + setTimeout(() => { + endGame(false); + }, 5000); + } + }, [isCameraOpen]); + + useEffect(() => { + if (animatronics.Foxy.jumpscare) { + dispatch({ type: "CHANGE_CAMERA_BUTTON" }); + setIsJumpscare("Foxy"); + jumpscareSound.play(); + setTimeout(() => { + endGame(false); + }, 5000); + } + }, [animatronics.Foxy.jumpscare]); + + useEffect(() => { + if (animatronics.Freddy.jumpscare) { + dispatch({ type: "CHANGE_CAMERA_BUTTON" }); + setIsJumpscare("Freddy"); + jumpscareSound.play(); + setTimeout(() => { + endGame(false); + }, 5000); + } + }, [animatronics.Freddy.jumpscare]); + + async function checkBackground() { + const { leftDoor, rightDoor, leftLight, rightLight } = officeConfig; + const { Bonnie, Chica } = animatronics; + + function getBackground() { + const result = []; + + if (rightDoor) result.push("RD"); + if (leftDoor) result.push("LD"); + + if (rightLight && !rightDoor) result.push("RL"); + if (leftLight && !leftDoor) result.push("LL"); + if (Bonnie.door && leftLight) result.push("BONNIE"); + if (Chica.door && rightLight) result.push("CHICA"); + + return result; + } + + const result = await getBackground(); + if (result.length === 0) setBackground(Default); + else setBackground(officeImages[result.join("_")]); + } + + const checkDoorSounds = (light) => { + const { leftDoor, rightDoor } = officeConfig; + const { Bonnie, Chica } = animatronics; + + let condition1 = light === "leftLight" && !leftDoor && Bonnie.door; + let condition2 = light === "rightLight" && !rightDoor && Chica.door; + + if (condition1 || condition2) Media.Sounds.Surprise.play(); + }; + + useEffect(() => { + if (blackout) FreddyJumpscare(); + }, [blackout]); + + useEffect(() => { + canJumpscare = true; + return () => { + canJumpscare = false; + musicBox.pause(); + }; + }, []); + + const FreddyJumpscare = () => { + const musicBoxInterval = setInterval(() => { + let musicBoxNumber = Math.floor(Math.random() * 9); + if (!canJumpscare) clearInterval(musicBoxInterval); + if (musicBoxNumber < 3 && canJumpscare) { + musicBox.currentTime = 0; + musicBox.play(); + setBlackoutBackground(FreddyBlackout); + clearInterval(musicBoxInterval); + + const pauseMusicInterval = setInterval(() => { + let pauseNumber = Math.floor(Math.random() * 3); + if (!canJumpscare) clearInterval(pauseMusicInterval); + if (pauseNumber == 0 && canJumpscare) { + setBlackoutBackground(null); + musicBox.pause(); + clearInterval(pauseMusicInterval); + + const freddyInterval = setInterval(() => { + let freddyNumber = Math.floor(Math.random() * 9); + if (!canJumpscare) clearInterval(freddyInterval); + if (freddyNumber == 0 && canJumpscare) { + const JumpscareImage = FreddyJumpscare1; + setBlackoutBackground(JumpscareImage); + jumpscareSound.play(); + dispatch({ + type: "CHANGE_JUMPSCARE", + animatronic: true, + }); + clearInterval(freddyInterval); + setTimeout(() => { + endGame(false); + setBlackoutBackground(Blackout); + }, 5000); + } + }, 3000); + } + }, 5000); + } + }, 3000); + }; + + if (isJumpscare === "Bonnie" && !isCameraOpen) + return ( +
+ Office +
+ ); + else if (isJumpscare === "Foxy") + return ( +
+ Office +
+ ); + else if (isJumpscare === "Freddy") + return ( +
+ Office +
+ ); + else if (isJumpscare === "Chica" && !isCameraOpen) + return ( +
+ Office +
+ ); + + return ( + <> + {!blackout ? ( + + ) : ( +
+ Office +
+ )} + + ); +} + +const mapStateToProps = (state) => { + return { + officeConfig: state.officeReducer, + animatronics: state.animatronicsReducer, + isCameraOpen: state.cameraReducer.isCameraOpen, + jumpscare: state.configReducer.jumpscare, + }; +}; + +export default connect(mapStateToProps)(Office); diff --git a/Games/Five_Nights_at_Freddys/src/css/CustomNight.module.css b/Games/Five_Nights_at_Freddys/src/css/CustomNight.module.css new file mode 100644 index 0000000000..33660b0897 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/css/CustomNight.module.css @@ -0,0 +1,208 @@ +.golden_freddy { + width: 100vw; + height: 100vh; + background-image: url("../media/Textures/golden_freddy.webp"); + background-color: #000; + background-size: contain; + background-position: center; + background-repeat: no-repeat; +} + +.custom_night_container { + overflow: auto; + font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; + color: white; + backdrop-filter: blur(7px) brightness(0.5); + + display: flex; + flex-direction: column; + justify-content: space-evenly; + height: 100vh; +} + +.github_icon { + width: fit-content; + height: fit-content; + position: absolute; + bottom: 2%; + right: 2%; + cursor: pointer; + transition: transform 200ms 50ms; +} + +.github_icon a { + width: fit-content; + height: fit-content; +} + +.github_icon:hover { + transform: scale(1.2); + transition: transform 200ms 50ms; +} + +.custom_night_container h1 { + font-weight: 400; + margin-left: 30px; + opacity: 0.8; +} + +.animatronics_container { + display: flex; + justify-content: space-evenly; +} + +.animatronic { + display: flex; + flex-direction: column; + align-items: center; +} + +.animatronic img { + max-width: 200px; + width: 20vw; +} + +.animatronic > span { + font-size: 20pt; + margin-bottom: 15px; +} + +.range_buttons { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 25px; + font-size: 1.5rem; + font-family: "Consolas"; + width: 100%; +} + +.range_buttons button { + border-radius: 5px; + width: 50px; + outline: none; + background-color: var(--button-color); + color: inherit; + font-weight: bolder; + border: none; + font-size: inherit; + cursor: pointer; + transition: transform 200ms 50ms; +} + +.range_buttons button:not(:disabled):hover, +.range_buttons button:not(:disabled):focus-within { + transform: scale(1.15); + transition: transform 200ms 50ms; +} + +.range_buttons button:disabled { + cursor: default; + opacity: 0.8; +} + +.start_screen { + font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; + /* height: 100vh; */ + display: flex; + align-self: center; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; +} + +.start_screen span { + flex: 100%; + margin-bottom: 15px; + font-size: 12.5pt; +} + +.ready_button { + font-weight: 800; + padding: auto 10px; + + font-size: 17pt; +} + +.start_screen button:not(.ready_button) { + font-size: 15pt; +} + +.start_screen button:not(.ready_button)[data-selected="false"] { + opacity: 0.6; +} + +.start_screen button:not(.ready_button)[data-selected="true"]:before { + content: "▶ "; +} + +.start_screen button { + border-radius: 6.5px; + /* width: 100px; */ + cursor: pointer; + height: 100%; + outline: none; + color: white; + background-color: var(--button-color); + border: none; +} + +.footer { + opacity: 0.8; + height: 50px; + text-align: center; +} + +.footer p { + margin-top: 0; +} + +@media screen and (min-width: 750px) { + .custom_night_container h1 { + margin-bottom: 30px; + } + .start_screen { + width: 50%; + } + .start_screen button { + margin-top: 10px; + height: 50px; + } + + .range_buttons button { + height: 50px; + } + + .footer { + margin-top: 50px; + } +} + +@media screen and (max-width: 750px) { + .custom_night_container h1 { + /* margin-bottom: 2%; */ + margin-top: 2%; + font-size: 15pt; + } + + .start_screen { + width: 90%; + } + .ready_button { + margin: 1.2% auto 1% auto; + } + + .start_screen button { + font-size: 10pt !important; + height: 35px; + } + + .range_buttons { + margin-top: 15px; + max-height: 30px; + } + + .footer { + margin: 1% 0px 1% 0px; + } +} diff --git a/Games/Five_Nights_at_Freddys/src/css/Game.css b/Games/Five_Nights_at_Freddys/src/css/Game.css new file mode 100644 index 0000000000..59a0766776 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/css/Game.css @@ -0,0 +1,227 @@ +* { + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */ +} + +:root { + --background-color: black; + --button-color: rgba(255, 255, 255, 0.2); +} + +body { + width: 100vw; + height: 100vh; +} + +.custom-night { + background-image: url("../media/FNAF.webp"); + background-size: cover; + background-position: center; + background-repeat: no-repeat; +} + +.animation { + background-size: 100vw; + background-repeat: no-repeat; + background-position: center; +} + +.animation[data-right-door="false"][data-left-door="false"] { + background-image: url("../media/Textures/Office/Default.webp"); +} +.animation[data-right-door="true"][data-left-door="false"] { + background-image: url("../media/Textures/Office/RD.webp"); +} +.animation[data-right-door="false"][data-left-door="true"] { + background-image: url("../media/Textures/Office/LD.webp"); +} +.animation[data-right-door="true"][data-left-door="true"] { + background-image: url("../media/Textures/Office/RD_LD.webp"); +} + +@keyframes up { + 0% { + background-position: 0px; + } + 85% { + background-position: -9500px; + opacity: 1; + } + 100% { + opacity: 0; + } +} +@keyframes down { + 0% { + background-position: -9500px; + opacity: 1; + } + 100% { + background-position: 0px; + } +} + +@keyframes disappear { + from { + display: unset !important; + z-index: 1; + opacity: 1; + } + to { + display: none !important; + opacity: 0; + z-index: -10; + } +} + +body { + margin: 0; + overflow: hidden; + background-color: var(--background-color); +} + +.camera-button { + pointer-events: all !important; + margin-left: 26vw; + bottom: 0; + opacity: 0.5; +} + +.true, +.false { + transform: scale(1.3); + animation: up 0.6s steps(8) forwards; +} + +.map { + bottom: 0; + right: 0; + width: fit-content; +} +@media only screen and (max-width: 750px) { + .map img { + width: 250px !important; + opacity: 0.7; + } + .map { + margin-bottom: 30px; + } + .camera-button { + width: 100vh !important; + } +} + +area { + outline: none; +} + +area.hover { + cursor: pointer; +} + +.true, +.false, +.animatronics-true, +.static { + width: 100vw; + height: 100vh; +} +.animatronics-true { + background-color: var(--background-color); +} + +.static { + opacity: 0.9; + animation: noise 0.12s infinite alternate-reverse; +} + +.hour, +.energy { + font-weight: lighter; + opacity: 0.4; + z-index: 1; + font-family: "Consolas"; + color: white; + position: "absolute"; +} +.hour { + position: absolute; + margin-right: 0; + margin-left: 90vw; +} +.energy { + position: absolute; + bottom: 0; + margin-left: 3vw; + font-size: 15pt; +} + +.opening { + z-index: 1; + animation: disappear 0.5s steps(1) forwards; +} + +@keyframes opening { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.open { + animation: opening 0.5s steps(1) forwards; +} + +img[data-disabled="false"] { + opacity: 0.3; +} + +@media screen and (max-width: 700px) { + .camera-img { + width: 100vw; + height: 90vh; + } + + .hour { + font-size: 17pt; + } + .camera-button { + margin-left: 22vw; + } +} +.office-img { + margin: auto; + width: 100vw; +} + +.office-container { + width: 100vw; + height: 100vh; + display: flex; + justify-content: center; + align-items: center; +} + +img { + pointer-events: none; +} + +* { + -moz-user-select: none; + -webkit-user-select: none; + user-select: none; +} + +.camera-container { + width: 100vw; + height: 100vh; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/Games/Five_Nights_at_Freddys/src/index.js b/Games/Five_Nights_at_Freddys/src/index.js new file mode 100644 index 0000000000..37e3b1dc06 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/index.js @@ -0,0 +1,55 @@ +import React, { useState, useEffect } from "react"; +import ReactDOM from "react-dom"; +import Controller from "./Controller"; +import "./css/Game.css"; +import * as serviceWorker from "./serviceWorker"; +import { Provider } from "react-redux"; +import store from "./store/store"; +import CustomNight from "./CustomNight"; + +const initialState = { + mode: "NORMAL", + Freddy: 10, + Bonnie: 10, + Chica: 10, + Foxy: 10, +}; + +const Start = () => { + const [Start, setStart] = useState(false); + const [stages, setStages] = useState(initialState); + + useEffect(() => { + console.log(window.innerHeight > window.innerWidth); + if (window.innerHeight > window.innerWidth) { + window.alert( + `Para uma melhor experiência, vire seu celular para o modo de paisagem (modo deitado) + ~ For a better experience, please rotate your phone to landscape mode` + ); + } + }, []); + + return ( + <> + {!Start ? ( +
+ +
+ ) : ( + + )} + + ); +}; + +ReactDOM.render( + + + , + document.getElementById("root") +); + +serviceWorker.register(); diff --git a/Games/Five_Nights_at_Freddys/src/media/FNAF.webp b/Games/Five_Nights_at_Freddys/src/media/FNAF.webp new file mode 100644 index 0000000000..483ddb8f96 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/FNAF.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/Ambience.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/Ambience.mp3 new file mode 100644 index 0000000000..1404ef982f Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/Ambience.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/CameraIdle 2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/CameraIdle 2.mp3 new file mode 100644 index 0000000000..2bbcc2473b Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/CameraIdle 2.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/Clock.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/Clock.mp3 new file mode 100644 index 0000000000..712af92409 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/Clock.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/Dead.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/Dead.mp3 new file mode 100644 index 0000000000..0a36517541 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/Dead.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/Door.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/Door.mp3 new file mode 100644 index 0000000000..ef4a82a526 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/Door.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh1.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh1.mp3 new file mode 100644 index 0000000000..4a6ec336f7 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh1.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh2.mp3 new file mode 100644 index 0000000000..c0688cabfb Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh2.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh3.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh3.mp3 new file mode 100644 index 0000000000..9cae715883 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh3.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/MainAmbience.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/MainAmbience.mp3 new file mode 100644 index 0000000000..00f0402b8a Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/MainAmbience.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/blip3.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/blip3.mp3 new file mode 100644 index 0000000000..c6e85da460 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/blip3.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/garble1.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/garble1.mp3 new file mode 100644 index 0000000000..29706fa8c5 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/garble1.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/garble2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/garble2.mp3 new file mode 100644 index 0000000000..6829647a0f Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/garble2.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/golden_freddy.ogg b/Games/Five_Nights_at_Freddys/src/media/Sounds/golden_freddy.ogg new file mode 100644 index 0000000000..35ef673b20 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/golden_freddy.ogg differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/jumpscare.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/jumpscare.mp3 new file mode 100644 index 0000000000..f993866c75 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/jumpscare.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/knock2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/knock2.mp3 new file mode 100644 index 0000000000..6ea586a887 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/knock2.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/music box.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/music box.mp3 new file mode 100644 index 0000000000..abdca5342f Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/music box.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown.mp3 new file mode 100644 index 0000000000..0b4db73b12 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown2.mp3 new file mode 100644 index 0000000000..354625f7a1 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown2.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/put down.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/put down.mp3 new file mode 100644 index 0000000000..9c4b6f65c1 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/put down.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/windowscare.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/windowscare.mp3 new file mode 100644 index 0000000000..7a4ac4b9a6 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/windowscare.mp3 differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Bonnie-Jumpscare.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Bonnie-Jumpscare.webp new file mode 100644 index 0000000000..06cae0ba00 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Bonnie-Jumpscare.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CameraButton.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CameraButton.png new file mode 100644 index 0000000000..7dda7ff099 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CameraButton.png differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage-b.webp new file mode 100644 index 0000000000..441a2dd198 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage-b.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage.webp new file mode 100644 index 0000000000..77e87c2e00 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Complete_Map.png b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Complete_Map.png new file mode 100644 index 0000000000..a6f078049e Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Complete_Map.png differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c-f.webp new file mode 100644 index 0000000000..5575a87290 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c.webp new file mode 100644 index 0000000000..c7f18aa098 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-f.webp new file mode 100644 index 0000000000..c53bda41ef Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b.webp new file mode 100644 index 0000000000..28f3782045 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c-f.webp new file mode 100644 index 0000000000..cbd7de18ef Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c.webp new file mode 100644 index 0000000000..03e2aa4537 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-f.webp new file mode 100644 index 0000000000..241653b33e Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea.webp new file mode 100644 index 0000000000..84d236bb9f Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-c.webp new file mode 100644 index 0000000000..673bcbbc10 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-c.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-f.webp new file mode 100644 index 0000000000..0e774eef5a Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner.webp new file mode 100644 index 0000000000..153fb57f2a Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c-f.webp new file mode 100644 index 0000000000..62add29396 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c.webp new file mode 100644 index 0000000000..7c2d237bf0 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-f.webp new file mode 100644 index 0000000000..c63eac5dbf Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall.webp new file mode 100644 index 0000000000..f9e7d26bc3 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-1.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-1.webp new file mode 100644 index 0000000000..1453c1c966 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-1.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-2.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-2.webp new file mode 100644 index 0000000000..82ece70e02 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-2.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-3.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-3.webp new file mode 100644 index 0000000000..ce9c01f29b Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-3.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove.webp new file mode 100644 index 0000000000..ab10b60d82 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c-f.webp new file mode 100644 index 0000000000..c01a454e07 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c.webp new file mode 100644 index 0000000000..3a87cbe6a6 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-f.webp new file mode 100644 index 0000000000..8884eebc63 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms.webp new file mode 100644 index 0000000000..fe2d08cf23 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-c-f.webp new file mode 100644 index 0000000000..c3ef89ede5 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-c-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-f.webp new file mode 100644 index 0000000000..7641c80ad2 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-c-f.webp new file mode 100644 index 0000000000..81875cdfaa Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-c-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-f.webp new file mode 100644 index 0000000000..15e0385866 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-f.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage.webp new file mode 100644 index 0000000000..4f6dab81ef Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom-b.webp new file mode 100644 index 0000000000..69c559d86b Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom-b.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom.webp new file mode 100644 index 0000000000..9c07c416fe Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner-b.webp new file mode 100644 index 0000000000..180a346aa5 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner-b.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner.webp new file mode 100644 index 0000000000..28c55946d7 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall-b.webp new file mode 100644 index 0000000000..ef1026afc3 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall-b.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall.webp new file mode 100644 index 0000000000..6c374e6221 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall-b.webp new file mode 100644 index 0000000000..aa3a69bd83 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall-b.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall.webp new file mode 100644 index 0000000000..4d43d1bbd5 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Chica-Jumpscare.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Chica-Jumpscare.webp new file mode 100644 index 0000000000..7e41b75600 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Chica-Jumpscare.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/bonnie.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/bonnie.png new file mode 100644 index 0000000000..b9c1ebfe8b Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/bonnie.png differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/chica.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/chica.png new file mode 100644 index 0000000000..33b343da86 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/chica.png differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/foxy.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/foxy.png new file mode 100644 index 0000000000..87414945a6 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/foxy.png differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/freddy.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/freddy.png new file mode 100644 index 0000000000..8043ec851c Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/freddy.png differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Down.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Down.webp new file mode 100644 index 0000000000..e583aa3049 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Down.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Hallway.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Hallway.webp new file mode 100644 index 0000000000..86e1fb1e88 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Hallway.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Jumpscare.gif b/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Jumpscare.gif new file mode 100644 index 0000000000..fb41af0621 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Jumpscare.gif differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare.webp new file mode 100644 index 0000000000..2d30bc9ba2 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare1.gif b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare1.gif new file mode 100644 index 0000000000..94adaf7cef Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare1.gif differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy.webp new file mode 100644 index 0000000000..aaec85e93e Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/304.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/304.webp new file mode 100644 index 0000000000..32c19a8bce Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/304.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/305.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/305.webp new file mode 100644 index 0000000000..041be5eb6f Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/305.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/Default.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/Default.webp new file mode 100644 index 0000000000..a6f9532c46 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/Default.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD.webp new file mode 100644 index 0000000000..4de9fe1afb Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL.webp new file mode 100644 index 0000000000..6a78ed16f6 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL_CHICA.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL_CHICA.webp new file mode 100644 index 0000000000..06e6e23d01 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL_CHICA.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL.webp new file mode 100644 index 0000000000..9b6777773d Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL_BONNIE.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL_BONNIE.webp new file mode 100644 index 0000000000..7a8df6a2a6 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL_BONNIE.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD.webp new file mode 100644 index 0000000000..c2a5a09233 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LD.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LD.webp new file mode 100644 index 0000000000..c9b0cd98df Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LD.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL.webp new file mode 100644 index 0000000000..58a9b18946 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL_BONNIE.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL_BONNIE.webp new file mode 100644 index 0000000000..c76db4fa01 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL_BONNIE.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL.webp new file mode 100644 index 0000000000..baa661a62a Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_CHICA.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_CHICA.webp new file mode 100644 index 0000000000..77e4cdf83b Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_CHICA.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL.webp new file mode 100644 index 0000000000..5482ad7375 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE.webp new file mode 100644 index 0000000000..358a6a4956 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE_CHICA.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE_CHICA.webp new file mode 100644 index 0000000000..c1b6f2d965 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE_CHICA.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_CHICA.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_CHICA.webp new file mode 100644 index 0000000000..ccb252e9aa Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_CHICA.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Static-Cam.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Static-Cam.webp new file mode 100644 index 0000000000..4d451726eb Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Static-Cam.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Up.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Up.webp new file mode 100644 index 0000000000..6813603362 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Up.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.gif b/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.gif new file mode 100644 index 0000000000..3fe570d929 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.gif differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.webp new file mode 100644 index 0000000000..49721ccf65 Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/black.jpg b/Games/Five_Nights_at_Freddys/src/media/Textures/black.jpg new file mode 100644 index 0000000000..3320e95c1d Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/black.jpg differ diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/golden_freddy.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/golden_freddy.webp new file mode 100644 index 0000000000..dd6704065e Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/golden_freddy.webp differ diff --git a/Games/Five_Nights_at_Freddys/src/reducers/animatronicsReducer.js b/Games/Five_Nights_at_Freddys/src/reducers/animatronicsReducer.js new file mode 100644 index 0000000000..581dc73ff2 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/reducers/animatronicsReducer.js @@ -0,0 +1,48 @@ +const originalState = { + Freddy: { + camera: "Stage", + door: false, + jumpscare: false, + }, + Bonnie: { + camera: "Stage", + door: false, + jumpscare: false, + }, + Chica: { + camera: "Stage", + door: false, + jumpscare: false, + }, + Foxy: { + camera: "", + door: false, + jumpscare: false, + }, +}; + +export default function animatronics(state = originalState, action) { + switch (action.type) { + // case "CHANGE_FREDDY_CAMERA": + // return { ...state, Freddy: { ...state.Freddy, camera: action.content } }; + // case "CHANGE_BONNIE_CAMERA": + // return { ...state, Bonnie: { ...state.Bonnie, camera: action.content } }; + // case "CHANGE_CHICA_CAMERA": + // return { ...state, Chica: { ...state.Chica, camera: action.content } }; + // case "CHANGE_FOXY_CAMERA": + // return { ...state, Foxy: { ...state.Foxy, camera: action.content } }; + + case "CHANGE_ANIMATRONIC": + let animatronicProps = state[action.animatronic]; + + animatronicProps = { ...action.animatronicState }; + state[action.animatronic] = animatronicProps; + return state; + case "SET_FOXY_NULL": + return { ...state, Foxy: { ...state.Foxy, camera: null } }; + case "CLEAR_DATA": + return { ...originalState }; + default: + return state; + } +} diff --git a/Games/Five_Nights_at_Freddys/src/reducers/cameraReducer.js b/Games/Five_Nights_at_Freddys/src/reducers/cameraReducer.js new file mode 100644 index 0000000000..e0dd588c59 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/reducers/cameraReducer.js @@ -0,0 +1,24 @@ +const originalState = { + camera: "Stage", + isCameraOpen: false, + areAnimatronicsMoving: false, +}; + +export default function camera(state = originalState, action) { + switch (action.type) { + case "CHANGE_CAMERA": + return { ...state, camera: action.content }; + case "SET_IS_OPEN": + return { + ...state, + isCameraOpen: state.isCameraOpen ? false : true, + }; + case "FORCE_CAMERA_CLOSE": + return { ...state, isCameraOpen: false }; + case "CHANGE_ANIMATRONICS_MOVING": + return { ...state, areAnimatronicsMoving: action.content }; + + default: + return state; + } +} diff --git a/Games/Five_Nights_at_Freddys/src/reducers/configReducer.js b/Games/Five_Nights_at_Freddys/src/reducers/configReducer.js new file mode 100644 index 0000000000..fe6de65a37 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/reducers/configReducer.js @@ -0,0 +1,35 @@ +const originalState = { + hour: 0, + isPlaying: true, + energy: 100, + time: 7000, + blackout: false, + jumpscare: false, + gameOver: false, + cameraButtonDisappear: false, +}; + +export default function config(state = originalState, action) { + switch (action.type) { + case "CHANGE_HOUR": + if (state.jumpscare || state.gameOver) return state; + return { ...state, hour: state.hour + 1 }; + case "CHANGE_ENERGY": + if (state.hour === 6) return state; + return { ...state, energy: state.energy - 1 }; + case "CHANGE_TIME": + return { ...state, time: action.content }; + case "CHANGE_BLACKOUT": + return { ...state, blackout: true }; + case "CHANGE_IS_PLAYING": + return { ...state, isPlaying: action.content }; + case "CHANGE_JUMPSCARE": + return { ...state, jumpscare: action.animatronic }; + case "CHANGE_CAMERA_BUTTON": + return { ...state, cameraButtonDisappear: true }; + case "SET_GAME_OVER": + return { ...state, gameOver: true }; + default: + return state; + } +} diff --git a/Games/Five_Nights_at_Freddys/src/reducers/index.js b/Games/Five_Nights_at_Freddys/src/reducers/index.js new file mode 100644 index 0000000000..93b06e6e4e --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/reducers/index.js @@ -0,0 +1,20 @@ +import { combineReducers } from "redux"; +import cameraReducer from "./cameraReducer"; +import configReducer from "./configReducer"; +import officeReducer from "./officeReducer"; +import animatronicsReducer from "./animatronicsReducer"; + +const appReducer = combineReducers({ + cameraReducer, + configReducer, + officeReducer, + animatronicsReducer, +}); + +export default function rootReducer(state, action) { + if (action.type === "CLEAR_DATA") { + state = undefined; + } + + return appReducer(state, action); +} diff --git a/Games/Five_Nights_at_Freddys/src/reducers/officeReducer.js b/Games/Five_Nights_at_Freddys/src/reducers/officeReducer.js new file mode 100644 index 0000000000..abe1f06e1c --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/reducers/officeReducer.js @@ -0,0 +1,31 @@ +const originalState = { + leftDoor: false, + rightDoor: false, + leftLight: false, + rightLight: false, +}; + +export default function office(state = originalState, action) { + switch (action.type) { + case "CHANGE_OFFICE_CONFIG": + if (action.obj === "leftLight" && state.leftDoor) return state; + if (action.obj === "rightLight" && state.rightDoor) return state; + + if (action.obj === "leftDoor" && !state.leftDoor && state.leftLight) + return { ...state, leftLight: false, leftDoor: true }; + if ( + action.obj === "rightDoor" && + !state.rightDoor && + state.rightLight + ) + return { ...state, rightLight: false, rightDoor: true }; + state[action.obj] = !state[action.obj]; + return state; + + case "CLEAR_DATA": + return { ...originalState }; + + default: + return state; + } +} diff --git a/Games/Five_Nights_at_Freddys/src/service-worker.js b/Games/Five_Nights_at_Freddys/src/service-worker.js new file mode 100644 index 0000000000..93d538ad5a --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/service-worker.js @@ -0,0 +1,116 @@ +/* eslint-disable no-restricted-globals */ + +// This service worker can be customized! +// See https://developers.google.com/web/tools/workbox/modules +// for the list of available Workbox modules, or add any other +// code you'd like. +// You can also remove this file if you'd prefer not to use a +// service worker, and the Workbox build step will be skipped. + +import { clientsClaim } from "workbox-core"; +import { ExpirationPlugin } from "workbox-expiration"; +import { precacheAndRoute, createHandlerBoundToURL } from "workbox-precaching"; +import { registerRoute } from "workbox-routing"; +import { + StaleWhileRevalidate, + NetworkFirst, + CacheFirst, +} from "workbox-strategies"; +// import { googleFontsCache } from "workbox-recipes"; + +// googleFontsCache(); + +clientsClaim(); + +// Precache all of the assets generated by your build process. +// Their URLs are injected into the manifest variable below. +// This variable must be present somewhere in your service worker file, +// even if you decide not to use precaching. See https://cra.link/PWA +precacheAndRoute(self.__WB_MANIFEST); + +// Set up App Shell-style routing, so that all navigation requests +// are fulfilled with your index.html shell. Learn more at +// https://developers.google.com/web/fundamentals/architecture/app-shell +const fileExtensionRegexp = new RegExp("/[^/?]+\\.[^/]+$"); +registerRoute( + // Return false to exempt requests from being fulfilled by index.html. + ({ request, url }) => { + // If this isn't a navigation, skip. + if (request.mode !== "navigate") { + return false; + } // If this is a URL that starts with /_, skip. + + if (url.pathname.startsWith("/_")) { + return false; + } // If this looks like a URL for a resource, because it contains // a file extension, skip. + + if (url.pathname.match(fileExtensionRegexp)) { + return false; + } // Return true to signal that we want to use the handler. + + return true; + }, + createHandlerBoundToURL(process.env.PUBLIC_URL + "/index.html") +); + +// An example runtime caching route for requests that aren't handled by the +// precache, in this case same-origin .png requests like those from in public/ +registerRoute( + // Add in any other file extensions or routing criteria as needed. + ({ url }) => + url.origin === self.location.origin && + (url.pathname.endsWith(".webp") || url.pathname.endsWith(".png")), // Customize this strategy as needed, e.g., by changing to CacheFirst. + new CacheFirst({ + cacheName: "images", + plugins: [ + // Ensure that once this runtime cache reaches a maximum size the + // least-recently used images are removed. + new ExpirationPlugin({ + maxAgeSeconds: 24 * 60 * 60, + }), + ], + }) +); + +registerRoute( + // Add in any other file extensions or routing criteria as needed. + ({ url }) => + url.origin === self.location.origin && url.pathname.endsWith(".mp3"), // Customize this strategy as needed, e.g., by changing to CacheFirst. + new CacheFirst({ + cacheName: "audios", + plugins: [ + // Ensure that once this runtime cache reaches a maximum size the + // least-recently used images are removed. + new ExpirationPlugin({ + maxAgeSeconds: 24 * 60 * 60, + }), + ], + }) +); + +registerRoute( + ({ request }) => request.destination === "style", + new StaleWhileRevalidate({ + cacheName: "static", + plugins: [new ExpirationPlugin({ maxEntries: 50 })], + }) +); + +registerRoute( + ({ request }) => + request.destination === "script" || request.destination === "worker", + new NetworkFirst({ + cacheName: "static-script", + plugins: [new ExpirationPlugin({ maxEntries: 50 })], + }) +); + +// This allows the web app to trigger skipWaiting via +// registration.waiting.postMessage({type: 'SKIP_WAITING'}) +self.addEventListener("message", (event) => { + if (event.data && event.data.type === "SKIP_WAITING") { + self.skipWaiting(); + } +}); + +// Any other custom service worker logic can go here. diff --git a/Games/Five_Nights_at_Freddys/src/serviceWorker.js b/Games/Five_Nights_at_Freddys/src/serviceWorker.js new file mode 100644 index 0000000000..3eade513cb --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/serviceWorker.js @@ -0,0 +1,141 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://cra.link/PWA + +const isLocalhost = Boolean( + window.location.hostname === "localhost" || + // [::1] is the IPv6 localhost address. + window.location.hostname === "[::1]" || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +export function register(config) { + if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + + return; + } + + window.addEventListener("load", () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + "This web app is being served cache-first by a service " + + "worker. To learn more, visit https://cra.link/PWA" + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + +function registerValidSW(swUrl, config) { + navigator.serviceWorker + .register(swUrl) + .then((registration) => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === "installed") { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + "New content is available and will be used when all " + + "tabs for this page are closed. See https://cra.link/PWA." + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log("Content is cached for offline use."); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch((error) => { + console.error("Error during service worker registration:", error); + }); +} + +function checkValidServiceWorker(swUrl, config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { "Service-Worker": "script" }, + }) + .then((response) => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get("content-type"); + if ( + response.status === 404 || + (contentType != null && contentType.indexOf("javascript") === -1) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then((registration) => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log( + "No internet connection found. App is running in offline mode." + ); + }); +} + +export function unregister() { + if ("serviceWorker" in navigator) { + navigator.serviceWorker.ready + .then((registration) => { + registration.unregister(); + }) + .catch((error) => { + console.error(error.message); + }); + } +} diff --git a/Games/Five_Nights_at_Freddys/src/store/store.js b/Games/Five_Nights_at_Freddys/src/store/store.js new file mode 100644 index 0000000000..bdae8ded07 --- /dev/null +++ b/Games/Five_Nights_at_Freddys/src/store/store.js @@ -0,0 +1,6 @@ +import { createStore } from "redux"; +import reducers from "../reducers/index"; + +const store = createStore(reducers); + +export default store; diff --git a/Games/Four_In_Row/README.md b/Games/Four_In_Row/README.md new file mode 100644 index 0000000000..836dd6597e --- /dev/null +++ b/Games/Four_In_Row/README.md @@ -0,0 +1,30 @@ +# **Four_In_Row** + +## **Description 📃** + +- Four in a Row is a two-player strategy game where players take turns dropping colored discs into a vertical grid. The objective is to connect four of their own discs in a row—either horizontally, vertically, or diagonally—before the opponent does. + +## **Functionalities 🎮** + +- Two-Player Mode: Designed for two players, either competitively or cooperatively. +- Vertical Grid: Features a vertical grid with slots where discs are dropped. +- Disc Colors: Players use different colored discs to differentiate between their moves. +- Winning Condition: The goal is to connect four discs in a row, either horizontally, vertically, or diagonally. +- Turn-Based Play: Players take turns dropping discs into the grid. +- Game Over Detection: The game ends when a player achieves four in a row or when the grid is full. +
+ +## **How to play? 🕹️** + +- Players take turns dropping colored discs into a vertical grid. +- The objective is to connect four of your discs in a row horizontally, vertically, or diagonally. +- The game ends when a player connects four in a row or the grid is full. + +
+ +## **Screenshots 📸** +![image](https://github.com/user-attachments/assets/613f20e4-153f-4c1c-ba84-7fb04a95b293) + +![image](https://github.com/user-attachments/assets/08d88616-d097-4f5e-ac36-cd93f3f97ac2) + +

Happy Coding 🧑‍💻

\ No newline at end of file diff --git a/Games/Four_In_Row/index.html b/Games/Four_In_Row/index.html new file mode 100644 index 0000000000..4f2f6aee2e --- /dev/null +++ b/Games/Four_In_Row/index.html @@ -0,0 +1,313 @@ + + + + + + Four In Row + + + + + + + + + + + +
+ +
+ +

Player - 1

+ +
+ +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+ + + +
+ + + + + \ No newline at end of file diff --git a/Games/Four_In_Row/script.js b/Games/Four_In_Row/script.js new file mode 100644 index 0000000000..bf0a39008c --- /dev/null +++ b/Games/Four_In_Row/script.js @@ -0,0 +1,242 @@ +// DOM Variables + +var buttons = document.getElementsByClassName("btn"); +var reset = document.getElementById("reset-btn"); +var playerType = document.getElementById("player-type"); + +// Game Flow Variables + +var playerNumber = 1; // Initially player - 1 gets to start his/her turn + +var filledGrid = []; // Player board + +var filledCells = 0; // No. of cells that has been filled + +for(var i = 0; i < 6; i++) { + + var arr = [-1 , -1 , -1 , -1 , -1 , -1 , -1]; // Board is initialised with -1 + filledGrid.push(arr); + +} + + +// Event Listener for Buttons + +reset.addEventListener("click" , function() { + + resetBoard(); + +}); + +for(var i = 0; i < buttons.length; i++) { + + // Handing the Event when button was clicked + + buttons[i].addEventListener("click" , function() { + + // Make move and disable the button to avoid furthur clicking it again + + var buttonNo = this.classList[1]; + makeMove(this , buttonNo.slice(4)); + + }); + +} + + +// Function to Make Move on the passed button and disable it +function makeMove(button , buttonNo) { + + var row = buttonNo % 7 === 0 ? Math.floor(buttonNo / 7) - 1 : Math.floor(buttonNo / 7); + var col = buttonNo % 7 === 0 ? 6: (buttonNo % 7) - 1; + + if(playerNumber === 1) { + + button.classList.add("btn-player-1"); + + + filledGrid[row][col] = 1; + filledCells++; + + + if(playerWon(row , col , 1) === true) { + setTimeout(function() { + alert("Game Over: Green Wins"); + resetBoard(); + } , 200); + } + + // Update the player + playerNumber = 2; + playerType.textContent = "Player - 2"; + + } else { + + button.classList.add("btn-player-2"); + + + filledGrid[row][col] = 2; + filledCells++; + + if(playerWon(row , col , 2) === true) { + setTimeout(function() { + alert("Game Over : Red Wins"); + resetBoard(); + } , 200); + } + + // Update the player + playerNumber = 1; + playerType.textContent = "Player - 1"; + + } + + // If all the cells has been filled + + if(filledCells === 42) { + setTimeout(function() { + alert("Game Draw"); + resetBoard(); + } , 200); + return; + } + + // Disable the button is the move is made + setTimeout(function () { + button.disabled = true; + },10); + +} + +function playerWon(row , col , player) { + + var count = 0; + + // Check for columns + + for(var i = 0; i < 7; i++) { + if(filledGrid[row][i] === player) { + count++; + if(count === 4) return true; + } else { + count = 0; + } + + } + + count = 0; + + // Check for Rows + + for(var i = 0; i < 6; i++) { + if(filledGrid[i][col] === player) { + count++; + if(count === 4) return true; + } else { + count = 0; + } + } + + + count = 0; + + // Check for primary diagonal + + if(row >= col) { + + var i = row - col; + var j = 0; + + for(; i <= 5; i++ , j++) { + if(filledGrid[i][j] === player) { + count++; + if(count == 4) return true; + } else { + count = 0; + } + } + } else { + + var i = 0; + var j = col - row; + + for(; j <= 6; i++ , j++) { + if(filledGrid[i][j] === player) { + count++; + if(count == 4) return true; + } else { + count = 0; + } + } + + } + + count = 0; + + // Check for secondary diagonal + + if(row + col <= 5) { + + var i = row + col; + var j = 0; + + for(; i >= 0 && j <= row + col; i-- , j++) { + if(filledGrid[i][j] === player) { + count++; + if(count == 4) return true; + } else { + count = 0; + } + } + + } else { + + var i = 5; + var j = row + col - 5; + + for(; j <= 6; j++ , i--) { + if(filledGrid[i][j] === player) { + count++; + if(count == 4) return true; + } else { + count = 0; + } + } + + } + return false; + +} + +// Function to reset the Board completely +function resetBoard() { + + // Remove all the disabled buttons and the styles + + for(var i = 0; i < buttons.length; i++) { + buttons[i].disabled = false; + buttons[i].classList.remove("btn-player-1"); + buttons[i].classList.remove("btn-player-2"); + } + + + // Player Number is changed to 1 + + playerNumber = 1; + playerType.textContent = "Player - 1"; + + + // Filled Cells is changed to 0 + + filledCells = 0; + + + // Filling the Board with -1 + + for(var i = 0; i < 6; i++) { + for(var j = 0; j < 7; j++) { + filledGrid[i][j] = -1; + } + } + +} \ No newline at end of file diff --git a/Games/Four_In_Row/style.css b/Games/Four_In_Row/style.css new file mode 100644 index 0000000000..fb4657d54c --- /dev/null +++ b/Games/Four_In_Row/style.css @@ -0,0 +1,238 @@ +body { + background-color: #e9e7fd; +} + +/* Main Container */ + +#main-container { + + align-items: center; + display: flex; + flex-direction: column; + justify-content: center; + min-height: 100vh; +} + +/* Player Details */ + +#player { + + background-color: #d5deff; + border: 8px solid #4f3ff0; + border-radius: 10px; + margin-top: 50px; + padding: 20px; + width: 400px; + +} + +#player-type { + + color: #4f3ff0; + font-family: "Poppins"; + letter-spacing: 5px; + text-align: center; + text-transform: uppercase; + +} + +/* Grid */ + +#grid { + + background-color: #4f3ff0; + border: 3.5px solid #d5deff; + border-radius: 8px; + box-shadow: 2px 3px 7px grey; + margin-top: 50px; + max-width: 600px; + padding: 3px; + +} + +/* Grid Row */ + +.row { + + display: flex; + +} + +/* Grid Column */ + +.col { + + align-items: center; + background-color: #d5deff; + border: 1px solid #4f3ff0; + border-radius: 5px; + display: flex; + justify-content: center; + height: 75px; + margin: 5px; + width: 75px; + +} + +/* Buttons */ + +.btn { + + background-color: transparent; + border: none; + color: transparent; + height: 100%; + padding: 0; + width: 100%; + +} + +#reset-btn { + + background-color: transparent; + border: 2px solid #4f3ff0; + border-radius: 5px; + color: #4f3ff0; + font-family: "Poppins"; + font-size: 1.5rem; + margin: 50px 0; + padding: 10px 40px; + text-transform: uppercase; + transition: 0.7s; + +} + +#reset-btn:hover { + + background-color: #4f3ff0; + color: #d5deff; + cursor: pointer; + transition: 0.7s; + +} + +/* Player - 1 Buttons */ + +.btn-player-1 { + + background-color: #34c471; + border: 2px solid #34c471; + border-radius: 50%; + color: red; + height: 50px; + width: 50px; + +} + +/* Player - 2 Buttons */ + +.btn-player-2 { + + background-color: #df3670; + border: 2px solid #df3670; + border-radius: 50%; + color: red; + height: 50px; + width: 50px; + +} + +/* Media Queries */ + +@media (max-width: 800px) { + #grid { + width: 500px; + } + + .col { + height: 62px; + margin: 4px; + width: 62px; + } + + #player { + width: 450px; + } + + #reset-btn { + font-size: 1.2rem; + } + + .btn-player-1 { + height: 40px; + width: 40px; + } + + .btn-player-2 { + height: 40px; + width: 40px; + } +} + +@media (max-width: 550px) { + #grid { + width: 400px; + } + + .col { + height: 50px; + margin: 3px; + width: 50px; + } + + #player { + width: 350px; + } + + #reset-btn { + font-size: 1rem; + } + + .btn-player-1 { + height: 30px; + width: 30px; + } + + .btn-player-2 { + height: 30px; + width: 30px; + } +} + +@media (max-width: 450px) { + #grid { + width: 90%; + } + + .col { + height: 40px; + margin: 2px; + } + + #player { + align-items: center; + display: flex; + border-width: 5px; + justify-content: center; + height: 30px; + width: 78%; + } + + #player-type { + font-size: 1.2rem; + } + + #reset-btn { + font-size: 0.8rem; + } + + .btn-player-1 { + height: 20px; + width: 20px; + } + + .btn-player-2 { + height: 20px; + width: 20px; + } +} \ No newline at end of file diff --git a/Games/Fruity_Fortune/README.md b/Games/Fruity_Fortune/README.md new file mode 100644 index 0000000000..87e1422f52 --- /dev/null +++ b/Games/Fruity_Fortune/README.md @@ -0,0 +1,50 @@ +# 🍒 Fruity Fortune Slot Machine 🍇 + +## Description 📃 + +Fruity Fortune is an engaging web-based slot machine game that brings the excitement of casino-style gambling to your browser. With its colorful fruit symbols and simple gameplay, it's perfect for a quick game or extended play sessions. + +## Features 🎮 + +- 🎰 Three-reel slot machine with fruit symbols +- 💰 Starting balance of $100 +- 💸 Each spin costs $10 +- 🏆 Win $50 for matching all three symbols +- 🔄 Reset game feature +- ℹ️ View rules option +- 💻 Responsive design for various screen sizes +- 🌈 Vibrant, animated user interface + +## How to play? 🕹️ + +1. **Start the game**: Open the `index.html` file in your web browser to launch the game. + +2. **Understand the rules**: + - You start with a balance of $100. + - Each spin costs $10. + - If you match all three symbols, you win $50. + - The game ends when your balance reaches $0. + +3. **Spin the reels**: Click the "Spin" button to play. The cost of $10 will be deducted from your balance. + +4. **Watch the results**: The reels will spin and stop, revealing three symbols. + +5. **Check for a win**: If all three symbols match, you win $50, which is added to your balance. + +6. **Continue playing**: Keep spinning as long as you have sufficient balance. + +7. **Reset the game**: Click the "Reset Game" button at any time to start over with a fresh balance of $100. + +8. **View rules**: Click the "View Rules" button to see a reminder of the game rules. + +## Screenshots + +![image](https://github.com/ayush-848/GameZone/assets/126975547/5a802935-bd71-4f1a-b951-165cc141389f) + +![image](https://github.com/ayush-848/GameZone/assets/126975547/478c8e4c-3701-4a18-917b-3b62ee1a5d04) + +![image](https://github.com/ayush-848/GameZone/assets/126975547/bba75390-1019-4228-92ea-3619aeaee1e2) + +Remember, gamble responsibly! This is a simulation game for entertainment purposes only. + +Enjoy playing Fruity Fortune Slot Machine! 🍓🍊🍋 diff --git a/Games/Fruity_Fortune/index.html b/Games/Fruity_Fortune/index.html new file mode 100644 index 0000000000..58bf6b4045 --- /dev/null +++ b/Games/Fruity_Fortune/index.html @@ -0,0 +1,30 @@ + + + + + + Fruity Fortune Slot Machine + + + + +
+

Fruity Fortune

+
+
🍎
+
🍊
+
🍇
+
+
+ + + +
+
+

Balance: $100

+

+
+
+ + + \ No newline at end of file diff --git a/Games/Fruity_Fortune/script.js b/Games/Fruity_Fortune/script.js new file mode 100644 index 0000000000..738dfe8f03 --- /dev/null +++ b/Games/Fruity_Fortune/script.js @@ -0,0 +1,84 @@ +const symbols = ['🍎', '🍊', '🍋', '🍇', '🍉', '🍒']; +let balance = 100; + +const reel1 = document.getElementById('reel1'); +const reel2 = document.getElementById('reel2'); +const reel3 = document.getElementById('reel3'); +const spinButton = document.getElementById('spinButton'); +const resetButton = document.getElementById('resetButton'); +const rulesButton = document.getElementById('rulesButton'); +const balanceDisplay = document.getElementById('balance'); +const messageDisplay = document.getElementById('message'); + +function updateBalance() { + balanceDisplay.textContent = balance; +} + +function spin() { + if (balance < 10) { + messageDisplay.textContent = "Not enough balance to spin!"; + messageDisplay.style.color = "#f44336"; + return; + } + + balance -= 10; + updateBalance(); + + spinButton.disabled = true; + messageDisplay.textContent = ""; + + // Add spin animation + reel1.classList.add('spin'); + reel2.classList.add('spin'); + reel3.classList.add('spin'); + + setTimeout(() => { + const result1 = symbols[Math.floor(Math.random() * symbols.length)]; + const result2 = symbols[Math.floor(Math.random() * symbols.length)]; + const result3 = symbols[Math.floor(Math.random() * symbols.length)]; + + reel1.textContent = result1; + reel2.textContent = result2; + reel3.textContent = result3; + + // Remove spin animation + reel1.classList.remove('spin'); + reel2.classList.remove('spin'); + reel3.classList.remove('spin'); + + if (result1 === result2 && result2 === result3) { + balance += 50; + messageDisplay.textContent = "Congratulations! You won $50!"; + messageDisplay.style.color = "#4CAF50"; + } else { + messageDisplay.textContent = "Try again!"; + messageDisplay.style.color = "#2196F3"; + } + + updateBalance(); + spinButton.disabled = false; + }, 1000); +} + +function resetGame() { + balance = 100; + updateBalance(); + reel1.textContent = '🍎'; + reel2.textContent = '🍊'; + reel3.textContent = '🍇'; + messageDisplay.textContent = ""; +} + +function showRules() { + alert("Fruity Fortune Slot Machine Rules:\n\n" + + "1. Each spin costs $10\n" + + "2. Match all three symbols to win $50\n" + + "3. Starting balance is $100\n" + + "4. Game over when balance reaches $0"); +} + +spinButton.addEventListener('click', spin); +resetButton.addEventListener('click', resetGame); +rulesButton.addEventListener('click', showRules); + +updateBalance(); \ No newline at end of file diff --git a/Games/Fruity_Fortune/style.css b/Games/Fruity_Fortune/style.css new file mode 100644 index 0000000000..d016b5cdde --- /dev/null +++ b/Games/Fruity_Fortune/style.css @@ -0,0 +1,133 @@ +body { + font-family: 'Fredoka One', cursive; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + background: linear-gradient(135deg, #ff9d6c, #ff5e62); + color: #333; +} + +.game-container { + text-align: center; + background-color: rgba(255, 255, 255, 0.9); + padding: 30px; + border-radius: 20px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); + max-width: 500px; + width: 90%; +} + +h1 { + font-size: 3em; + margin-bottom: 20px; + color: #ff5e62; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.slot-machine { + display: flex; + justify-content: center; + margin: 30px 0; + perspective: 1000px; +} + +.reel { + font-size: 60px; + background-color: #f8f8f8; + border: 3px solid #ff9d6c; + border-radius: 15px; + padding: 20px; + margin: 0 10px; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); + transition: transform 0.5s; +} + +.reel.spin { + animation: spin 0.5s linear infinite; +} + +@keyframes spin { + 0% { transform: rotateX(0deg); } + 100% { transform: rotateX(360deg); } +} + +.controls { + display: flex; + justify-content: center; + margin-bottom: 20px; +} + +.btn { + font-family: 'Fredoka One', cursive; + font-size: 18px; + padding: 12px 24px; + margin: 0 10px; + cursor: pointer; + border: none; + border-radius: 50px; + transition: all 0.3s ease; + text-transform: uppercase; +} + +.spin-btn { + background-color: #4CAF50; + color: white; +} + +.reset-btn { + background-color: #f44336; + color: white; +} + +.rules-btn { + background-color: #2196F3; + color: white; +} + +.btn:hover { + transform: translateY(-3px); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); +} + +.btn:active { + transform: translateY(-1px); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} + +.info { + margin-top: 20px; +} + +.balance { + font-size: 24px; + color: #4CAF50; +} + +.message { + font-size: 20px; + font-weight: bold; + min-height: 30px; + margin-top: 10px; +} + +@media (max-width: 500px) { + .game-container { + padding: 20px; + } + + h1 { + font-size: 2em; + } + + .reel { + font-size: 40px; + padding: 15px; + } + + .btn { + font-size: 16px; + padding: 10px 20px; + } +} \ No newline at end of file diff --git a/Games/Gita_Shloka_Generator/README.md b/Games/Gita_Shloka_Generator/README.md new file mode 100644 index 0000000000..43da50d651 --- /dev/null +++ b/Games/Gita_Shloka_Generator/README.md @@ -0,0 +1,56 @@ +# Gita Shlok Generator + +## Overview +Bhagavad-gītā is also known as Gītopaniṣad. It is the essence of Vedic knowledge and one of the most important Upaniṣads in Vedic literature.The speaker of Bhagavad-gītā is Lord Śrī Kṛṣṇa. Lets dive into the spritual world with the help of shloka generator +The Gita Shlok Generator is an interactive web application that displays random shlokas (verses) from the Bhagavad Gita. Each shloka includes its original Sanskrit text, transliteration, translation, and an explanation to help users understand the profound teachings of the Gita. + +## Features + +- Generate random shlokas from the Bhagavad Gita +- Display shlokas with Sanskrit text, transliteration, translation, and explanation +- Light and modern UI for a pleasant user experience +- Responsive design that works on various devices + +## Technologies Used + +- HTML5 +- CSS3 + - Bootstrap 5 + - TailwindCSS +- JavaScript +- jQuery + +## Getting Started + +### Prerequisites + +To run this project locally, you need to have: + +- A web browser (e.g., Chrome, Firefox, Safari) +- Internet connection (for Bootstrap and TailwindCSS CDN links) + +### Installation + +1. Clone the repository to your local machine: + ```sh + git clone https://github.com/your-username/gita-shlok-generator.git + ``` +2. Navigate to the project directory: + ```sh + cd gita-shlok-generator + ``` + +### Usage + +1. Open `index.html` in your web browser: + ```sh + open index.html + ``` +2. Click on the "Generate Random Shlok" button to display a new shloka. + + OR +1.Copy this project in your local system +2.go to the directory +Example D:\New folder (3)\GameZone\Games> cd Gita_Shloka_Generator +4. Type http-server +5. Click the link and run the project diff --git a/Games/Gita_Shloka_Generator/app.js b/Games/Gita_Shloka_Generator/app.js new file mode 100644 index 0000000000..cee05d5e5c --- /dev/null +++ b/Games/Gita_Shloka_Generator/app.js @@ -0,0 +1,25 @@ +document.getElementById('generate-btn').addEventListener('click', generateRandomShlok); + +async function generateRandomShlok() { + try { + const response = await fetch('shloks.json'); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + const shloks = await response.json(); + console.log('Shloks fetched successfully:', shloks); // Debugging log + + const randomIndex = Math.floor(Math.random() * shloks.length); + const shlok = shloks[randomIndex]; + console.log('Random Shlok selected:', shlok); // Debugging log + + document.getElementById('sanskrit').textContent = shlok.sanskrit; + document.getElementById('transliteration').textContent = shlok.transliteration; + document.getElementById('translation').textContent = shlok.translation; + document.getElementById('explanation').textContent = shlok.explanation; + + document.getElementById('shlok-container').style.display = 'block'; + } catch (error) { + console.error('Error fetching shlok data:', error); + } +} diff --git a/Games/Gita_Shloka_Generator/image.jpg b/Games/Gita_Shloka_Generator/image.jpg new file mode 100644 index 0000000000..4977727199 Binary files /dev/null and b/Games/Gita_Shloka_Generator/image.jpg differ diff --git a/Games/Gita_Shloka_Generator/images/krishna.jpg b/Games/Gita_Shloka_Generator/images/krishna.jpg new file mode 100644 index 0000000000..4977727199 Binary files /dev/null and b/Games/Gita_Shloka_Generator/images/krishna.jpg differ diff --git a/Games/Gita_Shloka_Generator/index.html b/Games/Gita_Shloka_Generator/index.html new file mode 100644 index 0000000000..8e6d3a185d --- /dev/null +++ b/Games/Gita_Shloka_Generator/index.html @@ -0,0 +1,25 @@ + + + + + + Gita Shlok Generator + + + + + +
+
+

Gita Shloka Generator

+ +
+

+

+

+

+
+
+ + + diff --git a/Games/Gita_Shloka_Generator/shloks.json b/Games/Gita_Shloka_Generator/shloks.json new file mode 100644 index 0000000000..5e65d5d13e --- /dev/null +++ b/Games/Gita_Shloka_Generator/shloks.json @@ -0,0 +1,131 @@ +[ + { + "chapter": 2, + "verse": 20, + "sanskrit": "न जायते म्रियते वा कदाचि, नायं भूत्वा भविता वा न भूय: |अजो नित्य: शाश्वतोऽयं पुराणो न हन्यते हन्यमाने शरीरे", + "transliteration": "na jāyate mriyate vā kadāchin nāyaṁ bhūtvā bhavitā vā na bhūyaḥ ajo nityaḥ śhāśhvato ’yaṁ purāṇo na hanyate hanyamāne śharīre", + "translation": "The soul is neither born, nor does it ever die; nor having once existed, does it ever cease to be. The soul is without birth, eternal, immortal, and ageless. It is not destroyed when the body is destroyed.", + "explanation": "This verse explains the soul is not something that comes into being at one point in time and then ceases to exist. It is eternal and does not undergo creation or destruction." + }, + { + "chapter": 2, + "verse": 47, + "sanskrit": "कर्मण्येवाधिकारस्ते मा फलेषु कदाचन मा कर्मफलहेतुर्भूर्मा ते सङ्गोऽस्त्वकर्मणि", + "transliteration": "karmanye vadhikaraste ma phaleshu kadachana mā karma-phala-hetur bhūr mā te saṅgo ’stvakarmaṇi", + "translation": "You have a right to perform your prescribed duties, but you are not entitled to the fruits of your actions...", + "explanation": "This verse emphasizes the importance of performing one's duties without attachment to results." + }, + { + "chapter": 2, + "verse": 70, + "sanskrit": "आपूर्यमाणमचलप्रतिष्ठं, समुद्रमाप: प्रविशन्ति यद्वत् |तद्वत्कामा यं प्रविशन्ति सर्वे, स शान्तिमाप्नोति न कामकामी ||", + "transliteration": "āpūryamāṇam achala-pratiṣhṭhaṁ ,samudram āpaḥ praviśhanti yadvat ,tadvat kāmā yaṁ praviśhanti sarve ,sa śhāntim āpnoti na kāma-kāmī", + "translation": "One who is not disturbed by the incessant flow of desires that enter like rivers into the ocean, which is being filled but is always being still, can alone achieve peace.", + "explanation": "This verse describes the state of equanimity and peace achieved by one who remains unaffected by desires, similar to an ocean that remains calm despite the constant influx of water." + }, + { + "chapter": 3, + "verse": 16, + "sanskrit": "एवं प्रवर्तितं चक्रं नानुवर्तयतीह य: |अघायुरिन्द्रियारामो मोघं पार्थ स जीवति", + "transliteration": "evaṁ pravartitaṁ chakraṁ nānuvartayatiha yaḥ,aghāyur indriyārāmo moghaṁ pārtha sa jīvati", + "translation": "He who does not follow the wheel of creation set of going in this world, sinful and sensual, lives in pain.", + "explanation": "This verse emphasizes the importance of following the divine order and participating in the cycle of creation to avoid suffering." + }, + { + "chapter": 3, + "verse": 19, + "sanskrit": "तस्मादसक्त: सततं कार्यं कर्म समाचर | असक्तो ह्याचरन्कर्म परमाप्नोति पूरुष: ", + "transliteration": "tasmād asaktaḥ satataṁ kāryaṁ karma samāchara ,asakto hyācharan karma param āpnoti pūruṣhaḥ", + "translation": "Therefore, perform your duties and work for Me. By doing so, you will be freed from the bonds of karma and attain liberation.", + "explanation": "Lord Krishna advises to perform all duties as an offering to Him to transcend the cycle of karma and attain liberation." + }, + { + "chapter": 4, + "verse": 7, + "sanskrit": "यदा यदा हि धर्मस्य ग्लानिर्भवति भारत | अभ्युत्थानमधर्मस्य तदात्मानं सृजाम्यहम्", + "transliteration": "yadā yadā hi dharmasya glānir bhavati bhārata, abhyutthānam adharmasya tadātmānaṁ sṛijāmyaham", + "translation": "Whenever there is a decline in righteousness and an increase in unrighteousness, O Arjuna, at that time I manifest myself on earth.", + "explanation": "Lord Krishna assures that He incarnates in various forms to protect the good, destroy the wicked, and establish righteousness." + }, + { + "chapter": 5, + "verse": 10, + "sanskrit": "ब्रह्मण्याधाय कर्माणि सङ्गं त्यक्त्वा करोति य: | लिप्यते न स पापेन पद्मपत्रमिवाम्भसा", + "transliteration": "brahmaṇyādhāya karmāṇi saṅgaṁ tyaktvā karoti yaḥ, lipyate na sa pāpena padma-patram ivāmbhasā", + "translation": "He who performs his duties without attachment, surrendering the fruits to the Supreme, is not affected by sin and is always in union with Brahman.", + "explanation": "This verse describes the path of selfless action and its benefits in attaining spiritual union with the Supreme." + }, + { + "chapter": 6, + "verse": 5, + "sanskrit": "उद्धरेदात्मनात्मानं नात्मानमवसादयेत् | आत्मैव ह्यात्मनो बन्धुरात्मैव रिपुरात्मन: ", + "transliteration": "uddhared ātmanātmānaṁ nātmānam avasādayet, ātmaiva hyātmano bandhur ātmaiva ripur ātmanaḥ", + "translation": "One must elevate, and not degrade, oneself by one's own mind. The mind is the friend of the conditioned soul, and its enemy as well.", + "explanation": "This verse emphasizes the role of the mind in one's spiritual progress and the need to master it to elevate oneself." + }, + { + "chapter": 7, + "verse": 14, + "sanskrit": "दैवी ह्येषा गुणमयी मम माया दुरत्यया | मामेव ये प्रपद्यन्ते मायामेतां तरन्ति ते", + "transliteration": "daivī hyeṣhā guṇa-mayī mama māyā duratyayā mām eva ye prapadyante māyām etāṁ taranti te", + "translation": "This divine energy of Mine, consisting of the three modes of material nature, is difficult to overcome. But those who have surrendered unto Me can easily cross beyond it.", + "explanation": "Krishna explains that His divine energy, though difficult to transcend, can be overcome by those who surrender to Him." + }, + { + "chapter": 8, + "verse": 7, + "sanskrit": "तस्मात्सर्वेषु कालेषु मामनुस्मर युध्य च | मय्यर्पितमनोबुद्धिर्मामेवैष्यस्यसंशयम् ", + "transliteration": "tasmāt sarveṣhu kāleṣhu mām anusmara yudhya cha, mayyarpita-mano-buddhir mām evaiṣhyasyasanśhayam", + "translation": "Therefore, always remember Me and perform your duties. With your mind and intellect fixed on Me, you will surely come to Me.", + "explanation": "Krishna instructs Arjuna to remember Him at all times and focus his mind and intellect on Him to attain spiritual realization." + }, + { + "chapter": 9, + "verse": 10, + "sanskrit": "मयाध्यक्षेण प्रकृति: सूयते सचराचरम् | हेतुनानेन कौन्तेय जगद्विपरिवर्तते", + "transliteration": "mayādhyakṣheṇa prakṛitiḥ sūyate sa-charācharam, hetunānena kaunteya jagad viparivartate", + "translation": "This divine operation of the material world is governed by Me. I am the source of the entire creation.", + "explanation": "Krishna declares His supreme role in the creation and operation of the universe, reinforcing His divine nature." + }, + { + "chapter": 9, + "verse": 22, + "sanskrit": "अनन्याश्चिन्तयन्तो मां ये जनाः पर्युपासते | तेषां नित्याभियुक्तानां योगक्षेमं वहाम्यहम्", + "transliteration": "ananyāś cintayanto māṁ ye janāḥ paryupāsate, teṣhāṁ nityābhiyuktānāṁ yoga-kṣhemaṁ vahāmyaham", + "translation": "To those who are constantly devoted and who worship Me with love, I give the understanding by which they can come to Me.", + "explanation": "Krishna promises to take care of the devotees who are devoted to Him, providing them with everything they need." + }, + { + "chapter": 10, + "verse": 8, + "sanskrit": "अहं सर्वस्य प्रभवो मत्तः सर्वं प्रवर्तते | इति मत्वा भजन्ते मां बुधा भावसमन्विता:", + "transliteration": "ahaṁ sarvasya prabhavo mattaḥ sarvaṁ pravartate, iti matvā bhajante māṁ budhā bhāva-samanvitāḥ ", + "translation": "I am the source of all spiritual and material worlds. Everything emanates from Me.", + "explanation": "This verse signifies that Lord Krishna is the ultimate source and cause of all creation, maintenance, and destruction in the universe." + }, + { + "chapter": 12, + "verse": 15, + "sanskrit": "यस्मान्नोद्विजते लोको लोकान्नोद्विजते च य: | हर्षामर्षभयोद्वेगैर्मुक्तो य: स च मे प्रिय:", + "transliteration": "yasmān nodvijate loko lokān nodvijate cha yaḥ, harṣhāmarṣha-bhayodvegair mukto yaḥ sa cha me priyaḥ", + "translation": "One who is not disturbed by the incessant flow of desires that enter like rivers into the ocean, which is being filled but is always being still, can alone achieve peace.", + "explanation": "This verse describes the nature of a peaceful person who remains unaffected by desires and remains calm like an ocean." + }, + { + "chapter": 13, + "verse": 27, + "sanskrit": "यावत्सञ्जायते किञ्चित्सत्वं स्थावरजङ्गमम् | क्षेत्रक्षेत्रज्ञसंयोगात्तद्विद्धि भरतर्षभ", + "transliteration": "yāvat sañjāyate kiñchit sattvaṁ sthāvara-jaṅgamam, kṣhetra-kṣhetrajña-sanyogāt tad viddhi bharatarṣhabha", + "translation": "The knowledge of the field and the knower of the field, the knowledge of the Supreme Self, is revealed to those who are pure in heart and devoted to truth.", + "explanation": "This verse highlights the importance of purity of heart and devotion in understanding the Supreme Self and the nature of existence." + + }, + { + "chapter": 18, + "verse": 66, + "sanskrit": "सर्वधर्मान्परित्यज्य मामेकं शरणं व्रज | अहं त्वां सर्वपापेभ्यो मोक्षयिष्यामि मा शुच:", + "transliteration": "sarva-dharmān parityajya mām ekaṁ śaraṇaṁ vraja, ahaṁ tvāṁ sarva-pāpebhyo mokṣhayiṣhyāmi mā śhuchaḥ", + "translation": "Abandon all varieties of religion and just surrender unto Me. I shall deliver you from all sinful reactions. Do not fear.", + "explanation": "Krishna advises Arjuna to abandon all forms of dharma and surrender only to Him, promising liberation from all sins and fears." + } +] diff --git a/Games/Gita_Shloka_Generator/styles.css b/Games/Gita_Shloka_Generator/styles.css new file mode 100644 index 0000000000..6464e8f492 --- /dev/null +++ b/Games/Gita_Shloka_Generator/styles.css @@ -0,0 +1,39 @@ +body { + font-family: 'Arial', sans-serif; + margin: 0; + padding: 0; +} + +#shlok-container { + display: none; + max-width: 90%; +} + +.btn-primary { + background-color: #012246; + border-color: #000b17; + padding: 10px 20px; + font-size: 18px; + border-radius: 5px; + transition: background-color 0.3s, border-color 0.3s; +} + +.btn-primary:hover { + background-color: #519cec; + border-color: #01244a; +} + +.overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1; + background: rgba(0, 0, 0, 0.3); /* Lighter overlay with lower opacity */ + +} + +.relative { + z-index: 2; +} diff --git a/Games/Guess_That_Pokemon/README.md b/Games/Guess_That_Pokemon/README.md new file mode 100644 index 0000000000..3f33a9858b --- /dev/null +++ b/Games/Guess_That_Pokemon/README.md @@ -0,0 +1,35 @@ +# **Game_Name** +Guess That Pokemon + +
+ +## **Description 📃** + +- A black outline of the pokemon will be displayed on the screen and the player has to guess which pokemon it is. + + +## **functionalities 🎮** + +- There will be options for guess, quit and hint. +
+ +## **How to play? 🕹️** + +- If the player guesses the pokemon without using a hint they are rewarded 100 points. +- If the player guesses the pokemon after taking a hint they are rewarded 50 points. +- If the player incorrectly guesses the pokemon they get 0 points. +- If the player quits they get 0 points. + +
+ +## **Screenshots 📸** + + + +![Guess That Pokemon](./assests/pokemon1.png) + +
+ +## **Working video 📹** + +![Guess That Pokemon](./assests/pokemon3.png) \ No newline at end of file diff --git a/Games/Guess_That_Pokemon/allPokemons.js b/Games/Guess_That_Pokemon/allPokemons.js new file mode 100644 index 0000000000..20c4d1d86b --- /dev/null +++ b/Games/Guess_That_Pokemon/allPokemons.js @@ -0,0 +1,200 @@ +var abra = { + name: "abra", + source: "https://archives.bulbagarden.net/media/upload/9/9e/PCP063.png", + hint:"A small, timid Psychic-type Pokémon with exceptional telekinetic abilities. It's powers manifest most strongly during sleep." +} + +var alakazam = { + name: "alakazam", + source: "https://archives.bulbagarden.net/media/upload/a/a6/PCP065.png", + hint:"The highly intelligent evolution of Abra, boasting immense psychic power. Known for its telepathy and spoon-bending abilities" +} + +var arcanine ={ + name:"arcanine", + source:"https://archives.bulbagarden.net/media/upload/thumb/4/42/0059Arcanine.png/375px-0059Arcanine.png", + hint:"A Fire-type Pokémon and it evolves from Growlithe when exposed to a Fire Stone." +} + +var arbok = { + name: "arbok", + source: "https://archives.bulbagarden.net/media/upload/9/9d/PCP024.png", + hint:"A large, intimidating Poison-type snake Pokémon with a venomous bite." +} + +var articuno = { + name: "articuno", + source: "https://archives.bulbagarden.net/media/upload/d/db/PCP144.png", + hint:"A legendary Ice/Flying-type bird Pokémon with the power to freeze its surroundings." +} + +var beedrill = { + name: "beedrill", + source: "https://archives.bulbagarden.net/media/upload/a/ac/PCP015.png", + hint:"A fierce Bug/Poison-type with venomous stingers." +} + +var bulbasaur = { + name: "bulbasaur", + source: "https://archives.bulbagarden.net/media/upload/thumb/f/fb/0001Bulbasaur.png/375px-0001Bulbasaur.png", + hint:"Along with Charmander and Squirtle, this is one of the three first partner Pokémon of Ash available at the beginning of Pokémon Red, " +} + +var charmander = { + name: "charmander", + source: "https://archives.bulbagarden.net/media/upload/6/6f/PCP004.png", + hint:"A small, lizard-like Fire-type with a burning tail. Its flame grows stronger with its emotions." +} + +var charmeleon = { + name: "charmeleon", + source: "https://archives.bulbagarden.net/media/upload/f/f5/PCP005.png", + hint:"The fiery evolution of Charmander, known for its aggressive nature and powerful flame attacks." +} + +var charizard = { + name: "charizard", + source: "https://archives.bulbagarden.net/media/upload/5/5e/PCP006.png", + hint:"A formidable Fire/Flying-type, it is capable of unleashing devastating fire-based attacks." +} + +var chimecho = { + name: "chimecho", + source: "https://archives.bulbagarden.net/media/upload/7/7e/PCP358.png", + hint:"A floating, bell-shaped Psychic-type with a calming aura. Its melodious chimes can soothe or confuse opponents." +} + +var crobat = { + name: "crobat", + source: "https://archives.bulbagarden.net/media/upload/e/e3/PCP169.png", + hint:"A fast and agile Poison/Flying-type with keen eyesight." +} + +var dragonair = { + name: "dragonair", + source: "https://archives.bulbagarden.net/media/upload/9/95/PCP148.png", + hint:"A serpentine Dragon-type Pokémon with the ability to control weather." +} + +var eevee = { + name: "eevee", + source: "https://archives.bulbagarden.net/media/upload/9/98/PCP133.png", + hint:"A small, fox-like Normal-type with the unique ability to evolve into different forms based on various conditions." +} + +var ekans = { + name: "ekans", + source: "https://archives.bulbagarden.net/media/upload/thumb/d/d2/0023Ekans.png/375px-0023Ekans.png", + hint:"It is a Poison-type Pokémon.It evolves into Arbok" +} + +var espeon = { + name: "espeon", + source: "https://archives.bulbagarden.net/media/upload/5/5f/PCP196.png", + hint:"An evolution of Eevee, it is a Psychic-type with heightened senses and the ability to predict opponents' moves." +} + +var flareon = { + name: "flareon", + source: "https://archives.bulbagarden.net/media/upload/2/2d/PCP136.png", + hint:"An evolution of Eevee, it is a Fire-type with an intense, fiery coat." +} + +var glaceon = { + name: "glaceon", + source: "https://archives.bulbagarden.net/media/upload/d/d0/PCP471.png", + hint:" An Ice-type evolution of Eevee, it possesses the ability to freeze nearby water." +} + +var golbat = { + name: "golbat", + source: "https://archives.bulbagarden.net/media/upload/e/ea/PCP042.png", + hint:"A larger, more powerful evolution of Zubat, this Poison/Flying-type is known for its sharp teeth and high speed." +} + +var gyarados = { + name: "gyarados", + source: "https://archives.bulbagarden.net/media/upload/9/9d/PCP130.png", + hint:"A monstrous Water/Flying-type with a violent temper. Once a Magikarp, it undergoes a dramatic transformation." +} + +var haunter = { + name: "haunter", + source: "https://archives.bulbagarden.net/media/upload/8/84/PCP093.png", + hint:"A mischievous Ghost/Poison-type with the ability to possess others." +} + +var horsea = { + name: "horsea", + source: "https://archives.bulbagarden.net/media/upload/thumb/1/14/0116Horsea.png/375px-0116Horsea.png", + hint:"It is a Water-type Pokémon.It evolves into Seadra which evolves into Kingdra when traded while holding a Dragon Scale." +} + +var igglybuff = { + name: "igglybuff", + source: "https://archives.bulbagarden.net/media/upload/9/9f/PCP174.png", + hint:"A pink, round Normal-type known for its sweet singing voice." +} + +var jigglypuff = { + name: "jigglypuff", + source: "https://archives.bulbagarden.net/media/upload/b/b4/PCP039.png", + hint:"The evolved form of Igglybuff, still adorable but with a powerful singing voice that can induce sleep." +} + +var jolteon = { + name: "jolteon", + source: "https://archives.bulbagarden.net/media/upload/5/58/PCP135.png", + hint:"An Electric-type evolution of Eevee known for its incredible speed and powerful electric attacks." +} + +var kadabra = { + name: "kadabra", + source: "https://archives.bulbagarden.net/media/upload/4/4b/PCP064.png", + hint:"The intermediate stage between Abra and Alakazam, possessing increased psychic prowess." +} + +var magikarp = { + name: "magikarp", + source: "https://archives.bulbagarden.net/media/upload/thumb/d/d1/0129Magikarp.png/375px-0129Magikarp.png", + hint:" A weak, water-type Pokémon known for its inability to battle effectively. Despite its unimpressive appearance and abilities, it evolves into the powerful Gyarados." +} + +var magneton = { + name: "magneton", + source: "https://archives.bulbagarden.net/media/upload/thumb/d/d9/0082Magneton.png/375px-0082Magneton.png", + hint:"An Electric/Steel-type Pokémon formed by three Magnemite linked together. Known for its strong magnetic force and ability to generate powerful electric attacks." +} + +var meowth = { + name: "meowth", + source: "https://archives.bulbagarden.net/media/upload/thumb/d/d6/0052Meowth.png/375px-0052Meowth.png", + hint:"A Normal-type Team Rocket Pokémon known for its cunning and ambition. Often seen carrying coins, it dreams of becoming rich." +} + +var pichu = { + name: "pichu", + source: "https://archives.bulbagarden.net/media/upload/thumb/f/f3/0172Pichu.png/375px-0172Pichu.png", + hint:"A small, Electric-type baby Pokémon with a playful and curious nature. Known for its unpredictable electric shocks caused by excitement or surprise." +} + +var pidgey = { + name: "pidgey", + source: "https://archives.bulbagarden.net/media/upload/thumb/0/0c/0016Pidgey.png/375px-0016Pidgey.png", + hint:"A common Normal/Flying-type Pokémon known for its docile nature. Often found in grassy areas, it prefers to flee from danger rather than fight." +} + +var pikachu = { + name: "pikachu", + source: "https://archives.bulbagarden.net/media/upload/thumb/4/4a/0025Pikachu.png/375px-0025Pikachu.png", + hint:"An iconic Electric-type Pokémon known for its cheerful personality and electric attacks. It stores electricity in its cheeks, which it can release in powerful bolts." +} + +var psyduck = { + name: "psyduck", + source: "https://archives.bulbagarden.net/media/upload/thumb/3/3f/0054Psyduck.png/375px-0054Psyduck.png", + hint:"A Water-type Pokémon known for its constant headaches. Despite its dazed appearance, it possesses hidden psychic powers that are often unleashed unintentionally due to the pain." +} + + + diff --git a/Games/Guess_That_Pokemon/assests/pokemon.jpg b/Games/Guess_That_Pokemon/assests/pokemon.jpg new file mode 100644 index 0000000000..c7894e7c16 Binary files /dev/null and b/Games/Guess_That_Pokemon/assests/pokemon.jpg differ diff --git a/Games/Guess_That_Pokemon/assests/pokemon1.png b/Games/Guess_That_Pokemon/assests/pokemon1.png new file mode 100644 index 0000000000..1f256f374b Binary files /dev/null and b/Games/Guess_That_Pokemon/assests/pokemon1.png differ diff --git a/Games/Guess_That_Pokemon/assests/pokemon2.png b/Games/Guess_That_Pokemon/assests/pokemon2.png new file mode 100644 index 0000000000..320e5c9c77 Binary files /dev/null and b/Games/Guess_That_Pokemon/assests/pokemon2.png differ diff --git a/Games/Guess_That_Pokemon/assests/pokemon3.png b/Games/Guess_That_Pokemon/assests/pokemon3.png new file mode 100644 index 0000000000..72e5386d83 Binary files /dev/null and b/Games/Guess_That_Pokemon/assests/pokemon3.png differ diff --git a/Games/Guess_That_Pokemon/index.html b/Games/Guess_That_Pokemon/index.html new file mode 100644 index 0000000000..8f3d95ee44 --- /dev/null +++ b/Games/Guess_That_Pokemon/index.html @@ -0,0 +1,56 @@ + + + + + + + + Who's that Pokemon? + + + + + + + + + + + + + +
+

Who's that Pokemon?

+
+ +
+ +
+ some image +
+ + +
+ + + +
+ +
+ + + +
+ +
+ + + + + + \ No newline at end of file diff --git a/Games/Guess_That_Pokemon/script.js b/Games/Guess_That_Pokemon/script.js new file mode 100644 index 0000000000..283e543787 --- /dev/null +++ b/Games/Guess_That_Pokemon/script.js @@ -0,0 +1,86 @@ +/* As soon as you initialize the page, choose a random image */ +window.onload = choosePic; +let index; +let points = 0; +let hintTaken = false; + +/* Array that receives all Pokemons in the game. You can greatly improve this array */ +const allPokemons = new Array(abra, alakazam, arcanine, arbok, articuno, beedrill, bulbasaur, charmander, + charmeleon, charizard, chimecho, crobat, dragonair, eevee, ekans, espeon, flareon, glaceon, golbat, + gyarados, haunter, horsea, igglybuff, jigglypuff, jolteon, kadabra, magikarp, magneton, + meowth, pichu, pidgey, pikachu, psyduck); + +function randomNumber() { + return Math.floor(Math.random() * allPokemons.length) + 1; +} + +/* Choose a random Pokemon */ +function choosePic() { + index = randomNumber(); + document.getElementById("canvas").src = allPokemons[index].source; + hintTaken = false; +} + +function clearInput() { + document.getElementById("guessInput").value = ""; +} + +function showAlert(num) { + if (num == 1) { + if (!hintTaken) { + points += 100; + } else { + points += 50; + } + document.getElementById("modal-message").innerText="Congratulations, You did it! It's " + allPokemons[index].name + "!"+"You earned " + (hintTaken ? 50 : 100) + " points!" +"\n Total Points are :" + points; + document.getElementById("modal").style.display = "block"; + } else { + document.getElementById("modal-message").innerText = "Oops, Thats' not correct. It was " + allPokemons[index].name + "!"; + document.getElementById("modal").style.display = "block"; + points += 0; + } + // Add event listener to the cancel button + var closeButton = document.querySelector(".close"); + closeButton.addEventListener("click", function() { + document.getElementById("modal").style.display = "none"; + }); +} + +function tryGuess() { + if (document.getElementById("guessInput").value.trim().toLowerCase() === allPokemons[index].name) { + + showAlert(1); + document.getElementById("canvas").style.filter = "brightness(100%)"; + allPokemons.splice(index, 1); + + if (allPokemons.length >= 1){ + setTimeout(function () { + + document.getElementById("canvas").style.filter = "brightness(0%)"; + choosePic(); + clearInput(); + + }, 500); + } else { + alert("You managed to guess all the Pokemons! You are awesome! Thanks for playing, I hope you had fun ^~^ ") + document.getElementById("title").innerHTML = "You win! Yay!"; + } + + } else { + showAlert(0); + choosePic(); + clearInput(); + } +} + +function giveHint() { + hintTaken = true; + document.getElementById("modal-message").innerText="Hint: " + allPokemons[index].hint; + document.getElementById("modal").style.display = "block"; + + // Add event listener to the cancel button + var closeButton = document.querySelector(".close"); + closeButton.addEventListener("click", function() { + document.getElementById("modal").style.display = "none"; + }); +} \ No newline at end of file diff --git a/Games/Guess_That_Pokemon/style.css b/Games/Guess_That_Pokemon/style.css new file mode 100644 index 0000000000..fa7d51b9fe --- /dev/null +++ b/Games/Guess_That_Pokemon/style.css @@ -0,0 +1,143 @@ +body { + background: url('./assests/pokemon.jpg') no-repeat center center fixed; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + height: 100%; + text-align: center; +} + +img { + width: 100%; + height: 100%; +} + +figure { + border: 10px solid #000000; + background-color: #FFFFFF; + margin-left: auto; + margin-right: auto; + width: 200px; + height: 200px; + text-align: center; + border-radius: 5px; + padding: 15px; +} + +button { + font-family: 'Indie Flower'; + font-weight: bold; + border: none; + border-radius: 15px; + width: 200px; + height: 50px; + margin: 5px; + background-color: #C9CBA3; + color: #59594A; + font-size: 30px; + transition: 0.05s; + padding: 5px;; +} + +button:hover { + cursor: pointer; + background-color: #bf8028; + color: #FFFFFF; +} + +header { + font-family: 'Indie Flower', cursive; + font-size: 20px; +} + +#canvas { + filter: brightness(0%); +} + +.box { + margin: 15px; + padding: 10px; +} + +.main { + display: inline-block; + background-color: #322c2b; + width: 500px; + height: 500px; + background-color: rgba(0, 0, 255, 0.2); /* blue color with 20% opacity */ + backdrop-filter: blur(10px); /* blur the background behind the box */ + -webkit-backdrop-filter: blur(10px); /* for Safari and Chrome */ + padding: 20px; + margin: 40px auto; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); +} + +.main { + background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.3)); + border: 1px solid rgba(255, 255, 255, 0.5); + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2), 0 0 20px rgba(0, 0, 255, 0.2); + } + +.main input { + width: 70%; + height: 30px; + font-size: 300%; + text-align: center; + padding: 10px; + border-radius: 5px; +} + +.modal { + display: none; + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); +} + +.modal-content { + background-color: #f1f1f1; + margin: 15% auto; + padding: 20px; + border: 1px solid #888; + width: 80%; + max-width: 800px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); +} + +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; +} + +.close:hover, +.close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} + +/* Responsive design */ +@media only screen and (max-width: 600px) { + .main { + width: 80%; + height: 80% + } + .main input { + width: 90%; + } + button { + width: 90%; + } + .modal-content { + width: 90%; + } +} \ No newline at end of file diff --git a/Games/Guess_The_Murderer/README.md b/Games/Guess_The_Murderer/README.md new file mode 100644 index 0000000000..c6b2f3a6a9 --- /dev/null +++ b/Games/Guess_The_Murderer/README.md @@ -0,0 +1,21 @@ +# **Guess The Murderer** + +--- +## **Description 📃** +Guess The Murderer is a detective-themed interactive game where players must deduce the identity of the culprit among several suspects. + +## **Functionalities 🎮** +- Select suspects to eliminate based on clues. +- Review suspects' profiles and clues. +- Make an arrest decision based on gathered evidence. + +## **How to play? 🕹️** +To play Guess The Murderer: +1. Examine each suspect's profile and associated clues. +2. Click on suspects to either eliminate or select as the prime suspect. +3. Utilize deductive reasoning to narrow down the true perpetrator. +4. When confident, click the ARREST button to finalize your choice. + +## **Screenshots 📸** +![image](https://github.com/user-attachments/assets/68141aad-b2d9-4c44-a926-7c05d817b130) +![image](https://github.com/user-attachments/assets/791c2af8-673f-49bb-aeab-6e570e67fb21) diff --git a/Games/Guess_The_Murderer/images/Eliminated-Suspect.png b/Games/Guess_The_Murderer/images/Eliminated-Suspect.png new file mode 100644 index 0000000000..6299f0c35b Binary files /dev/null and b/Games/Guess_The_Murderer/images/Eliminated-Suspect.png differ diff --git a/Games/Guess_The_Murderer/images/Suspect1.png b/Games/Guess_The_Murderer/images/Suspect1.png new file mode 100644 index 0000000000..542b465e37 Binary files /dev/null and b/Games/Guess_The_Murderer/images/Suspect1.png differ diff --git a/Games/Guess_The_Murderer/images/Suspect2.png b/Games/Guess_The_Murderer/images/Suspect2.png new file mode 100644 index 0000000000..096a88306d Binary files /dev/null and b/Games/Guess_The_Murderer/images/Suspect2.png differ diff --git a/Games/Guess_The_Murderer/images/Suspect3.png b/Games/Guess_The_Murderer/images/Suspect3.png new file mode 100644 index 0000000000..2ec4f23b66 Binary files /dev/null and b/Games/Guess_The_Murderer/images/Suspect3.png differ diff --git a/Games/Guess_The_Murderer/images/Suspect4.png b/Games/Guess_The_Murderer/images/Suspect4.png new file mode 100644 index 0000000000..6a29882670 Binary files /dev/null and b/Games/Guess_The_Murderer/images/Suspect4.png differ diff --git a/Games/Guess_The_Murderer/images/Suspect5.png b/Games/Guess_The_Murderer/images/Suspect5.png new file mode 100644 index 0000000000..057fc9c54d Binary files /dev/null and b/Games/Guess_The_Murderer/images/Suspect5.png differ diff --git a/Games/Guess_The_Murderer/images/Suspect6.png b/Games/Guess_The_Murderer/images/Suspect6.png new file mode 100644 index 0000000000..6a54f8d040 Binary files /dev/null and b/Games/Guess_The_Murderer/images/Suspect6.png differ diff --git a/Games/Guess_The_Murderer/images/clue1.jpg b/Games/Guess_The_Murderer/images/clue1.jpg new file mode 100644 index 0000000000..489f22259e Binary files /dev/null and b/Games/Guess_The_Murderer/images/clue1.jpg differ diff --git a/Games/Guess_The_Murderer/images/clue2.jpg b/Games/Guess_The_Murderer/images/clue2.jpg new file mode 100644 index 0000000000..3ec6357dd3 Binary files /dev/null and b/Games/Guess_The_Murderer/images/clue2.jpg differ diff --git a/Games/Guess_The_Murderer/images/clue3.jpg b/Games/Guess_The_Murderer/images/clue3.jpg new file mode 100644 index 0000000000..698907dc63 Binary files /dev/null and b/Games/Guess_The_Murderer/images/clue3.jpg differ diff --git a/Games/Guess_The_Murderer/images/clue4.jpg b/Games/Guess_The_Murderer/images/clue4.jpg new file mode 100644 index 0000000000..f5d43cb7f8 Binary files /dev/null and b/Games/Guess_The_Murderer/images/clue4.jpg differ diff --git a/Games/Guess_The_Murderer/images/clue5.jpg b/Games/Guess_The_Murderer/images/clue5.jpg new file mode 100644 index 0000000000..ddb8606e08 Binary files /dev/null and b/Games/Guess_The_Murderer/images/clue5.jpg differ diff --git a/Games/Guess_The_Murderer/images/clue6.jpg b/Games/Guess_The_Murderer/images/clue6.jpg new file mode 100644 index 0000000000..5b1d7310f7 Binary files /dev/null and b/Games/Guess_The_Murderer/images/clue6.jpg differ diff --git a/Games/Guess_The_Murderer/index.html b/Games/Guess_The_Murderer/index.html new file mode 100644 index 0000000000..66bedd518f --- /dev/null +++ b/Games/Guess_The_Murderer/index.html @@ -0,0 +1,77 @@ + + + + Guess Who? + + + + + + + + + + + +
+

Guess The Murderer

+ +

STEP 01: Read the clue cards below to find the culprit.

+ +
+ +
+
+
+
+
+
+
+
+
+
+ +
+ + +

STEP 02: Click on the images to eliminate the suspects

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ SUSPECT 1 SUSPECT 2 SUSPECT 3 +
+ + +
+
+ +
+
+ +
+
+ +
+
+ +
+ SUSPECT 4 SUSPECT 5 SUSPECT 6 +
+
+

+ +
+
+ + \ No newline at end of file diff --git a/Games/Guess_The_Murderer/script.js b/Games/Guess_The_Murderer/script.js new file mode 100644 index 0000000000..48e7def65e --- /dev/null +++ b/Games/Guess_The_Murderer/script.js @@ -0,0 +1,178 @@ +// JavaScript code here +var suspectList = [ "Suspect 1", "Suspect 2", " Suspect 3", "Suspect 4", "Suspect 5", "Suspect 6"]; +var suspectGuilty = [ null, null, null, null, "Suspect 5", null]; +var suspectDeduced = []; +var promptSingleCard = []; + +console.log(suspectDeduced); +console.log(suspectDeduced.length); + +var image1 = document.getElementById("pic_s1"); +var image2 = document.getElementById("pic_s2"); +var image3 = document.getElementById("pic_s3"); +var image4 = document.getElementById("pic_s4"); +var image5 = document.getElementById("pic_s5"); +var image6 = document.getElementById("pic_s6"); + + +var detectiveName = prompt("Reveal your identity, Detective!"); + +var display = function( data ){ + document.getElementById('output').innerText = data; +} + +var alertButton = document.createElement('button'); +alertButton.innerHTML = 'ARREST'; +alertButton.classList.add('arrestButton'); + +alertButton.onclick = function(){ + if (suspectList[4] === suspectGuilty[4]) { + display("Excellent! Elementary, my dear " + detectiveName); + console.log(display); + } else { + display("Try again! Never trust to general impressions, my boy, but concentrate yourself upon details."); + } +}; + +function changeImage(){ + if (image1.src.match("images/Suspect1.png") && promptSingleCard.length === 4) { + image1.src = "images/Eliminated-Suspect.png"; + suspectList[0] = null; + console.log(suspectList); + promptSingleCard.push(1); + console.log(promptSingleCard); + alert("Are you sure this is your final suspect?"); + document.getElementById("deliberation").appendChild(alertButton); + } else if (image1.src.match("images/Suspect1.png")) { + image1.src = "images/Eliminated-Suspect.png"; + suspectList[0] = null; + console.log(suspectList); + promptSingleCard.push(1); + console.log(promptSingleCard); + } else { + alert("This image has already been changed."); + } +} + +function changeImage2(){ + if (image2.src.match("images/Suspect2.png") && promptSingleCard.length === 4) { + image2.src = "images/Eliminated-Suspect.png"; + suspectList[1] = null; + console.log(suspectList); + promptSingleCard.push(2); + console.log(promptSingleCard); + alert("Are you sure this is your final suspect?"); + document.getElementById("deliberation").appendChild(alertButton); + } else if (image2.src.match("images/Suspect2.png")) { + image2.src = "images/Eliminated-Suspect.png"; + suspectList[1] = null; + console.log(suspectList); + promptSingleCard.push(2); + console.log(promptSingleCard); + } else { + alert("This image has already been changed."); + } +} + +function changeImage3(){ + if (image3.src.match("images/Suspect3.png") && promptSingleCard.length === 4) { + image3.src = "images/Eliminated-Suspect.png"; + suspectList[2] = null; + console.log(suspectList); + promptSingleCard.push(3); + console.log(promptSingleCard); + alert("Are you sure this is your final suspect?"); + document.getElementById("deliberation").appendChild(alertButton); + } else if (image3.src.match("images/Suspect3.png")) { + image3.src = "images/Eliminated-Suspect.png"; + suspectList[2] = null; + console.log(suspectList); + promptSingleCard.push(3); + console.log(promptSingleCard); + } else { + alert("This image has already been changed."); + } +} + +function changeImage4(){ + if (image4.src.match("images/Suspect4.png") && promptSingleCard.length === 4) { + image4.src = "images/Eliminated-Suspect.png"; + suspectList[3] = null; + console.log(suspectList); + promptSingleCard.push(4); + console.log(promptSingleCard); + alert("Are you sure this is your final suspect?"); + document.getElementById("deliberation").appendChild(alertButton); + } else if (image4.src.match("images/Suspect4.png")) { + image4.src = "images/Eliminated-Suspect.png"; + suspectList[3] = null; + console.log(suspectList); + promptSingleCard.push(4); + console.log(promptSingleCard); + } else { + alert("This image has already been changed."); + } +} + +function changeImage5(){ + if (image5.src.match("images/Suspect5.png") && promptSingleCard.length === 4) { + image5.src = "images/Eliminated-Suspect.png"; + suspectList[4] = null; + console.log(suspectList); + promptSingleCard.push(5); + console.log(promptSingleCard); + alert("Are you sure this is your final suspect?"); + document.getElementById("deliberation").appendChild(alertButton); + } else if (image5.src.match("images/Suspect5.png")) { + image5.src = "images/Eliminated-Suspect.png"; + suspectList[4] = null; + console.log(suspectList); + promptSingleCard.push(5); + console.log(promptSingleCard); + } else { + alert("This image has already been changed."); + } +} + +function changeImage6(){ + if (image6.src.match("images/Suspect6.png") && promptSingleCard.length === 4) { + image6.src = "images/Eliminated-Suspect.png"; + suspectList[5] = null; + console.log(suspectList); + promptSingleCard.push(6); + console.log(promptSingleCard); + alert("Are you sure this is your final suspect?"); + document.getElementById("deliberation").appendChild(alertButton); + } else if (image6.src.match("images/Suspect6.png")) { + image6.src = "images/Eliminated-Suspect.png"; + suspectList[5] = null; + console.log(suspectList); + promptSingleCard.push(6); + console.log(promptSingleCard); + } else { + alert("This image has already been changed."); + } +} + +let currentSlide = 0; + +function showSlide(index) { + const slides = document.querySelector('.slides'); + const totalSlides = document.querySelectorAll('.slide').length; + if (index >= totalSlides) { + currentSlide = 0; + } else if (index < 0) { + currentSlide = totalSlides - 1; + } else { + currentSlide = index; + } + slides.style.transform = `translateX(-${currentSlide * 100}%)`; +} + +function nextSlide() { + showSlide(currentSlide + 1); +} + +function prevSlide() { + showSlide(currentSlide - 1); +} diff --git a/Games/Guess_The_Murderer/style.css b/Games/Guess_The_Murderer/style.css new file mode 100644 index 0000000000..b7c42d89ab --- /dev/null +++ b/Games/Guess_The_Murderer/style.css @@ -0,0 +1,178 @@ +body { + margin: 0; + padding: 0; + font-family: 'Arial', sans-serif; + } + + header { + background-color: #222; + color: #fff; + text-align: center; + padding: 20px 0; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + } + + header h1 { + font-family: 'Gloock', serif; + font-size: 3em; + margin: 0; + letter-spacing: 2px; + text-transform: uppercase; + } + + .container { + text-align: center; + margin: 50px; + background-color: #000; + color: #fff; + } + + .step1 { + font-size: 19px; + margin: 20px; + } + + .step2 { + font-size: 19px; + margin: 20px; + } + + .step3 { + font-size: 20px; + margin: 40px; + } + + + .mainSlide { + display: flex; + align-items: center; + justify-content: center; + margin: 0 0 10px 30px; + } + + .slider { + width: 800px; + height: 400px; + overflow: hidden; + position: relative; + display: flex; + align-items: center; + } + + .slides { + display: flex; + transition: transform 0.5s ease; + } + + .slide { + min-width: 100%; + transition: transform 0.5s ease; + } + + .slide img { + width: 100%; + height: 100%; + object-fit: cover; + } + + .arrow { + background-color: #C75052; + border: none; + color: white; + padding: 10px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 24px; + font-family: Avenir; + font-weight: bold; + cursor: pointer; + user-select: none; + -webkit-user-select: none; + position: absolute; + top: 50%; + transform: translateY(-50%); + z-index: 1; + } + + .arrow.left { + top: 53%; + left: 23%; + } + + .arrow.right { + top: 55%; + right: 21%; + } + + .starter{ + font-size:30px; + padding:5px; + display:block; + margin:0px; + background-color: #B0D9D9; + text-align: center; + display: inline-block; + } + + #output{ + background-color: black; + color: white; + font-family: 'Avenir', Arial; + font-size: 30px; + width: 800px; + margin: 30px; + } + + .suspectImageSetOne { + width: 800px; + display: inline-block + } + + .column { + float: left; + width: 33.33%; + padding: 5px; + margin-top: 10px; + + } + + .row::after { + content: ""; + clear: both; + display: table; + } + + .suspectImageSetTwo { + width: 800px; + display: inline-block + } + + .suspectNumber1 { + align-content: center; + margin: 10px; + font-size: 20px; + font-weight: bold; + color: white; + + } + span.number { + text-align: center; + margin: 80px; + + } + + .suspectNumber2 { + align-content: center; + margin: 10px; + font-size: 20px; + font-weight: bold; + color: white; + } + + .arrestButton { + background-color: red; + color: white; + font-size: 24px; + padding: 20px; + } \ No newline at end of file diff --git a/Games/Guess_the_friends_name/Readme.md b/Games/Guess_the_friends_name/Readme.md new file mode 100644 index 0000000000..5da38736ad --- /dev/null +++ b/Games/Guess_the_friends_name/Readme.md @@ -0,0 +1,39 @@ +# **Guess_the_friends_name** + +--- + +
+ +## **Description 📃** +- Gameplay Overview: In “Guess the Friend's Name” players embark on a journey of memory and luck. player enters the names of four close friends into the game. The game then generates a random name from the list, and the player must use their intuition and knowledge about their friends to guess which name has been chosen. + +## **functionalities 🎮** +- random name generation +- fully responsive design +- user friendly +- assessment availability +
+ +## **How to play? 🕹️** + +How to Play: + +-Enter Names: Start by typing in the names of four friends you know well. + +-Make Your Guess: Your task is to select the name you believe the game randomly chose. + +-Reveal & Score: After making your selection,If your guess was right, you score points; if not, better luck next time! + +
+ +## **Screenshots 📸** + +
+ +![image](images/guess_name.png) + +![image](images/Name.png) + +
+ +## **Working video 📹** \ No newline at end of file diff --git a/Games/Guess_the_friends_name/images/Name.png b/Games/Guess_the_friends_name/images/Name.png new file mode 100644 index 0000000000..ccf0ddae39 Binary files /dev/null and b/Games/Guess_the_friends_name/images/Name.png differ diff --git a/Games/Guess_the_friends_name/images/guess_name.png b/Games/Guess_the_friends_name/images/guess_name.png new file mode 100644 index 0000000000..8e5d2e8908 Binary files /dev/null and b/Games/Guess_the_friends_name/images/guess_name.png differ diff --git a/Games/Guess_the_friends_name/index.html b/Games/Guess_the_friends_name/index.html new file mode 100644 index 0000000000..458b960734 --- /dev/null +++ b/Games/Guess_the_friends_name/index.html @@ -0,0 +1,40 @@ + + + + + + + Guess the Friend Game + + + + +
+

Guess the Friend's Name

+
+
+
+ + + + +
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/Games/Guess_the_friends_name/script.js b/Games/Guess_the_friends_name/script.js new file mode 100644 index 0000000000..80ba81cc6e --- /dev/null +++ b/Games/Guess_the_friends_name/script.js @@ -0,0 +1,37 @@ +let friends = []; + +function startGame() { + friends = [ + document.getElementById('friend1').value, + document.getElementById('friend2').value, + document.getElementById('friend3').value, + document.getElementById('friend4').value + ]; + + if (friends.some(name => name === '')) { + alert('Please enter all four friend names.'); + return; + } + + document.querySelector('.input-section').style.display = 'none'; + document.querySelector('.game-section').style.display = 'block'; +} + +function makeGuess() { + const guess = document.getElementById('guess').value; + const randomFriend = friends[Math.floor(Math.random() * friends.length)]; + + if (guess === randomFriend) { + document.getElementById('result').textContent = `You guessed right! The name was ${randomFriend}.`; + } else { + document.getElementById('result').textContent = 'Try again!'; + } +} + +function exitGame() { + document.querySelector('.game-section').style.display = 'none'; + document.querySelector('.input-section').style.display = 'block'; + document.getElementById('result').textContent = ''; + document.getElementById('guess').value = ''; + friends = []; +} diff --git a/Games/Guess_the_friends_name/styles.css b/Games/Guess_the_friends_name/styles.css new file mode 100644 index 0000000000..87bbd59a00 --- /dev/null +++ b/Games/Guess_the_friends_name/styles.css @@ -0,0 +1,93 @@ +body { + font-family: Arial, sans-serif; + background-color: #f4f4f4; + text-align: center; + padding: 50px; +} + +.container { + background-color: #fff; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + display: inline-block; +} + + +button { + margin-top: 10px; + padding: 10px 20px; + background-color: #28a745; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; +} + +button:hover { + background-color: #218838; +} + +#result { + margin-top: 20px; + font-size: 1.2em; +} + +#guess{ + width:100%; +} + +.box-input { + position: relative; + } + + .border { + background-image: linear-gradient(to right bottom, #e300ff, #ff00aa, #ff5956, #ffb900, #fffe00); + box-shadow: -25px -10px 30px -5px rgba(225, 0, 255, 0.5), + 25px -10px 30px -5px rgba(255, 0, 212, 0.5), + 25px 10px 30px -5px rgba(255, 174, 0, 0.5), + -25px 10px 30px -5px rgba(255, 230, 0, 0.5); + padding: 4px; + } + + .input { + background-color: #212121; + max-width: 250px; + height: 40px; + padding: 0 19px 0 10px; + font-size: 1.1em; + position: relative; + border: none; + color: white; + outline: 0; + overflow: hidden; + } + + .box-input::after, + .box-input::before { + content: ""; + width: 0px; + height: 30px; + position: absolute; + z-index: -1; + } + + .box-input::after { + bottom: 0; + right: 0; + } + + .box-input::before { + top: 0; + left: 0; + } + + .input::placeholder { + transition: all 0.5s ease-in, transform 0.2s ease-in 0.6s; + } + + .input:focus::placeholder { + padding-left: 165px; + transform: translateY(-50px); + } + \ No newline at end of file diff --git a/Games/Hangman_Game/README.md b/Games/Hangman_Game/README.md new file mode 100644 index 0000000000..3f104604e2 --- /dev/null +++ b/Games/Hangman_Game/README.md @@ -0,0 +1,37 @@ +# **Game_Name** + +Hangman Game + +
+ +## **Description 📃** + +- **Hangman Game** is an interactive game where you have to guess the word in six chances. + +## **functionalities 🎮** + +- You have to select one category ,on the basis of that category you have to guess the word. +- You have six chances in which you have guess,when you choose wrong letter then one by one the part of the man form. +- If you not able to guess till the man form then the game ends. +
+ +## **How to play? 🕹️** + +- First choose the option whose word you want to guess. +- Guess the word within six chances. +- If the guess is correct you win else lose. +- Then play again . + +
+ +## **Screenshots 📸** + +
+ +![image](../../assets/images/Hangman_Game.png) + + +
+ + + \ No newline at end of file diff --git a/Games/Hangman_Game/index.html b/Games/Hangman_Game/index.html new file mode 100644 index 0000000000..b728f07431 --- /dev/null +++ b/Games/Hangman_Game/index.html @@ -0,0 +1,29 @@ + + + + + + Hangman Game + + + + + + +
+
+
+
+ +
+
+ +
+
+ + + + diff --git a/Games/Hangman_Game/script.js b/Games/Hangman_Game/script.js new file mode 100644 index 0000000000..e83049e983 --- /dev/null +++ b/Games/Hangman_Game/script.js @@ -0,0 +1,248 @@ +//Initial References +const letterContainer = document.getElementById("letter-container"); +const optionsContainer = document.getElementById("options-container"); +const userInputSection = document.getElementById("user-input-section"); +const newGameContainer = document.getElementById("new-game-container"); +const newGameButton = document.getElementById("new-game-button"); +const canvas = document.getElementById("canvas"); +const resultText = document.getElementById("result-text"); + +//Options values for buttons +let options = { + fruits: [ + "Apple", + "Blueberry", + "Mandarin", + "Pineapple", + "Pomegranate", + "Watermelon", + "Banana", + "Cherry", + "Avocado", + "Peach", + ], + animals: ["Elephant", "Rhinoceros", "Squirrel", "Panther", "Tiger", "Zebra","Monkey","Horse","Goat","Eagle"], + countries: [ + "India", + "Hungary", + "Kyrgyzstan", + "Switzerland", + "Zimbabwe", + "Dominica", + "Spain", + "Tibet", + "Algeria", + "Cyprus", + ], + colors: ["Turquoise","Beige","Azure","lavender","Yellow","Ivory","Coral","Indigo","Maroon","Emerald"], +}; + +//count +let winCount = 0; +let count = 0; + +let chosenWord = ""; + +//Display option buttons +const displayOptions = () => { + optionsContainer.innerHTML += `

Please Select An Option

`; + let buttonCon = document.createElement("div"); + for (let value in options) { + buttonCon.innerHTML += ``; + } + optionsContainer.appendChild(buttonCon); +}; + +//Block all the Buttons +const blocker = () => { + let optionsButtons = document.querySelectorAll(".options"); + let letterButtons = document.querySelectorAll(".letters"); + //disable all options + optionsButtons.forEach((button) => { + button.disabled = true; + }); + + //disable all letters + letterButtons.forEach((button) => { + button.disabled.true; + }); + newGameContainer.classList.remove("hide"); +}; + +//Word Generator +const generateWord = (optionValue) => { + let optionsButtons = document.querySelectorAll(".options"); + //If optionValur matches the button innerText then highlight the button + optionsButtons.forEach((button) => { + if (button.innerText.toLowerCase() === optionValue) { + button.classList.add("active"); + } + button.disabled = true; + }); + + //initially hide letters, clear previous word + letterContainer.classList.remove("hide"); + userInputSection.innerText = ""; + + let optionArray = options[optionValue]; + //choose random word + chosenWord = optionArray[Math.floor(Math.random() * optionArray.length)]; + chosenWord = chosenWord.toUpperCase(); + + //replace every letter with span containing dash + let displayItem = chosenWord.replace(/./g, '_'); + + //Display each element as span + userInputSection.innerHTML = displayItem; +}; + +//Initial Function (Called when page loads/user presses new game) +const initializer = () => { + winCount = 0; + count = 0; + + //Initially erase all content and hide letteres and new game button + userInputSection.innerHTML = ""; + optionsContainer.innerHTML = ""; + letterContainer.classList.add("hide"); + newGameContainer.classList.add("hide"); + letterContainer.innerHTML = ""; + + //For creating letter buttons + for (let i = 65; i < 91; i++) { + let button = document.createElement("button"); + button.classList.add("letters"); + //Number to ASCII[A-Z] + button.innerText = String.fromCharCode(i); + //character button click + button.addEventListener("click", () => { + let charArray = chosenWord.split(""); + let dashes = document.getElementsByClassName("dashes"); + //if array contains clciked value replace the matched dash with letter else dram on canvas + if (charArray.includes(button.innerText)) { + charArray.forEach((char, index) => { + //if character in array is same as clicked button + if (char === button.innerText) { + //replace dash with letter + dashes[index].innerText = char; + //increment counter + winCount += 1; + //if winCount equals word lenfth + if (winCount == charArray.length) { + resultText.innerHTML = `

You Win :)

The word was ${chosenWord}

`; + //block all buttons + blocker(); + } + } + }); + } else { + //lose count + count += 1; + //for drawing man + drawMan(count); + //Count==6 because head,body,left arm, right arm,left leg,right leg + if (count == 6) { + resultText.innerHTML = `

You Lose :(

The word was ${chosenWord}

`; + blocker(); + } + } + //disable clicked button + button.disabled = true; + }); + letterContainer.append(button); + } + + displayOptions(); + //Call to canvasCreator (for clearing previous canvas and creating initial canvas) + let { initialDrawing } = canvasCreator(); + //initialDrawing would draw the frame + initialDrawing(); +}; + +//Canvas +const canvasCreator = () => { + let context = canvas.getContext("2d"); + context.beginPath(); + context.strokeStyle = "#000"; + context.lineWidth = 2; + + //For drawing lines + const drawLine = (fromX, fromY, toX, toY) => { + context.moveTo(fromX, fromY); + context.lineTo(toX, toY); + context.stroke(); + }; + + const head = () => { + context.beginPath(); + context.arc(70, 30, 10, 0, Math.PI * 2, true); + context.stroke(); + }; + + const body = () => { + drawLine(70, 40, 70, 80); + }; + + const leftArm = () => { + drawLine(70, 50, 50, 70); + }; + + const rightArm = () => { + drawLine(70, 50, 90, 70); + }; + + const leftLeg = () => { + drawLine(70, 80, 50, 110); + }; + + const rightLeg = () => { + drawLine(70, 80, 90, 110); + }; + + //initial frame + const initialDrawing = () => { + //clear canvas + context.clearRect(0, 0, context.canvas.width, context.canvas.height); + //bottom line + drawLine(10, 130, 130, 130); + //left line + drawLine(10, 10, 10, 131); + //top line + drawLine(10, 10, 70, 10); + //small top line + drawLine(70, 10, 70, 20); + }; + + return { initialDrawing, head, body, leftArm, rightArm, leftLeg, rightLeg }; +}; + +//draw the man +const drawMan = (count) => { + let { head, body, leftArm, rightArm, leftLeg, rightLeg } = canvasCreator(); + switch (count) { + case 1: + head(); + break; + case 2: + body(); + break; + case 3: + leftArm(); + break; + case 4: + rightArm(); + break; + case 5: + leftLeg(); + break; + case 6: + rightLeg(); + break; + default: + break; + } +}; + +//New Game +newGameButton.addEventListener("click", initializer); +window.onload = initializer; \ No newline at end of file diff --git a/Games/Hangman_Game/style.css b/Games/Hangman_Game/style.css new file mode 100644 index 0000000000..eb4726f270 --- /dev/null +++ b/Games/Hangman_Game/style.css @@ -0,0 +1,121 @@ + +* { + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: "Poppins", sans-serif; + } + body { + background-color: #0f8d20; + } + .container { + font-size: 16px; + background-color: #ffffff; + width: 90vw; + max-width: 34em; + position: absolute; + transform: translate(-50%, -50%); + top: 50%; + left: 50%; + padding: 3em; + border-radius: 0.6em; + box-shadow: 0 1.2em 2.4em rgba(111, 85, 0, 0.25); + } + #options-container { + text-align: center; + } + #options-container div { + width: 100%; + display: flex; + justify-content: space-between; + margin: 1.2em 0 2.4em 0; + } + #options-container button { + padding: 0.6em 1.2em; + border: 3px solid #000000; + background-color: #ffffff; + color: #000000; + border-radius: 0.3em; + text-transform: capitalize; + cursor: pointer; + } + #options-container button:disabled { + border: 3px solid #808080; + color: #808080; + background-color: #efefef; + } + #options-container button.active { + background-color: #486823; + border: 3px solid #000000; + color: #fff; + } + .letter-container { + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.6em; + } + #letter-container button { + height: 2.4em; + width: 2.4em; + border-radius: 0.3em; + background-color: #ffffff; + cursor: pointer; + } + .new-game-popup { + background-color: #ffffff; + position: absolute; + left: 0; + top: 0; + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + border-radius: 0.6em; + } + + #user-input-section { + display: flex; + justify-content: center; + font-size: 1.8em; + margin: 0.6em 0 1.2em 0; + } + canvas { + display: block; + margin: auto; + border: 10px solid #246346; + border-radius: 10px; + } + .hide { + display: none; + } + #result-text h2 { + font-size: 1.8em; + text-align: center; + } + #result-text p { + font-size: 1.25em; + margin: 1em 0 2em 0; + } + #result-text span { + font-weight: 600; + } + #new-game-button { + font-size: 1.25em; + padding: 0.5em 1em; + background-color: #3a990a; + border: 3px solid #000000; + color: #fff; + border-radius: 0.2em; + cursor: pointer; + } + .win-msg { + color: #088349; + } + .lose-msg { + color: #a52525; + } + \ No newline at end of file diff --git a/Games/Hedgehog_Havoc/Hedgehog.png b/Games/Hedgehog_Havoc/Hedgehog.png new file mode 100644 index 0000000000..c3ffb8b61f Binary files /dev/null and b/Games/Hedgehog_Havoc/Hedgehog.png differ diff --git a/Games/Hedgehog_Havoc/index.html b/Games/Hedgehog_Havoc/index.html new file mode 100644 index 0000000000..e5c6fd573c --- /dev/null +++ b/Games/Hedgehog_Havoc/index.html @@ -0,0 +1,29 @@ + + + + + HEDGEHOG HAVOC + + + + + + +
+
+ Game Over +
+
+
distance
+
000
+
+ +
Click to jump — Grab the carrots / avoid the hedgehogs
+ + + + + + + + diff --git a/Games/Hedgehog_Havoc/script.js b/Games/Hedgehog_Havoc/script.js new file mode 100644 index 0000000000..23783a8a4b --- /dev/null +++ b/Games/Hedgehog_Havoc/script.js @@ -0,0 +1,1374 @@ +//THREEJS RELATED VARIABLES + +var scene, + camera, fieldOfView, aspectRatio, nearPlane, farPlane, + gobalLight, shadowLight, backLight, + renderer, + container, + controls, + clock; +var delta = 0; +var floorRadius = 200; +var speed = 6; +var distance = 0; +var level = 1; +var levelInterval; +var levelUpdateFreq = 3000; +var initSpeed = 5; +var maxSpeed = 48; +var monsterPos = .65; +var monsterPosTarget = .65; +var floorRotation = 0; +var collisionObstacle = 10; +var collisionBonus = 20; +var gameStatus = "play"; +var cameraPosGame = 160; +var cameraPosGameOver = 260; +var monsterAcceleration = 0.004; +var malusClearColor = 0xb44b39; +var malusClearAlpha = 0; +var audio = new Audio('https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Antonio-Vivaldi-Summer_01.mp3'); + +var fieldGameOver, fieldDistance; + +//SCREEN & MOUSE VARIABLES + +var HEIGHT, WIDTH, windowHalfX, windowHalfY, + mousePos = { + x: 0, + y: 0 + }; + +//3D OBJECTS VARIABLES + +var hero; + + +// Materials +var blackMat = new THREE.MeshPhongMaterial({ + color: 0x100707, + shading:THREE.FlatShading, + }); + +var brownMat = new THREE.MeshPhongMaterial({ + color: 0xb44b39, + shininess:0, + shading:THREE.FlatShading, + }); + +var greenMat = new THREE.MeshPhongMaterial({ + color: 0x7abf8e, + shininess:0, + shading:THREE.FlatShading, + }); + + var pinkMat = new THREE.MeshPhongMaterial({ + color: 0xdc5f45,//0xb43b29,//0xff5b49, + shininess:0, + shading:THREE.FlatShading, + }); + + var lightBrownMat = new THREE.MeshPhongMaterial({ + color: 0xe07a57, + shading:THREE.FlatShading, + }); + + var whiteMat = new THREE.MeshPhongMaterial({ + color: 0xa49789, + shading:THREE.FlatShading, + }); + var skinMat = new THREE.MeshPhongMaterial({ + color: 0xff9ea5, + shading:THREE.FlatShading + }); + + +// OTHER VARIABLES + +var PI = Math.PI; + +//INIT THREE JS, SCREEN AND MOUSE EVENTS + +function initScreenAnd3D() { + + HEIGHT = window.innerHeight; + WIDTH = window.innerWidth; + windowHalfX = WIDTH / 2; + windowHalfY = HEIGHT / 2; + + scene = new THREE.Scene(); + + scene.fog = new THREE.Fog(0xd6eae6, 160,350); + + aspectRatio = WIDTH / HEIGHT; + fieldOfView = 50; + nearPlane = 1; + farPlane = 2000; + camera = new THREE.PerspectiveCamera( + fieldOfView, + aspectRatio, + nearPlane, + farPlane + ); + camera.position.x = 0; + camera.position.z = cameraPosGame; + camera.position.y = 30; + camera.lookAt(new THREE.Vector3(0, 30, 0)); + + renderer = new THREE.WebGLRenderer({ + alpha: true, + antialias: true + }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setClearColor( malusClearColor, malusClearAlpha); + + renderer.setSize(WIDTH, HEIGHT); + renderer.shadowMap.enabled = true; + + container = document.getElementById('world'); + container.appendChild(renderer.domElement); + + window.addEventListener('resize', handleWindowResize, false); + document.addEventListener('mousedown', handleMouseDown, false); + document.addEventListener("touchend", handleMouseDown, false); + + /* + controls = new THREE.OrbitControls(camera, renderer.domElement); + //controls.minPolarAngle = -Math.PI / 2; + //controls.maxPolarAngle = Math.PI / 2; + //controls.noZoom = true; + controls.noPan = true; + //*/ + + clock = new THREE.Clock(); + +} + +function handleWindowResize() { + HEIGHT = window.innerHeight; + WIDTH = window.innerWidth; + windowHalfX = WIDTH / 2; + windowHalfY = HEIGHT / 2; + renderer.setSize(WIDTH, HEIGHT); + camera.aspect = WIDTH / HEIGHT; + camera.updateProjectionMatrix(); +} + + +function handleMouseDown(event){ + if (gameStatus == "play") hero.jump(); + else if (gameStatus == "readyToReplay"){ + replay(); + } +} + +function createLights() { + globalLight = new THREE.AmbientLight(0xffffff, .9); + + shadowLight = new THREE.DirectionalLight(0xffffff, 1); + shadowLight.position.set(-30, 40, 20); + shadowLight.castShadow = true; + shadowLight.shadow.camera.left = -400; + shadowLight.shadow.camera.right = 400; + shadowLight.shadow.camera.top = 400; + shadowLight.shadow.camera.bottom = -400; + shadowLight.shadow.camera.near = 1; + shadowLight.shadow.camera.far = 2000; + shadowLight.shadow.mapSize.width = shadowLight.shadow.mapSize.height = 2048; + + scene.add(globalLight); + scene.add(shadowLight); + +} + +function createFloor() { + + floorShadow = new THREE.Mesh(new THREE.SphereGeometry(floorRadius, 50, 50), new THREE.MeshPhongMaterial({ + color: 0x7abf8e, + specular:0x000000, + shininess:1, + transparent:true, + opacity:.5 + })); + //floorShadow.rotation.x = -Math.PI / 2; + floorShadow.receiveShadow = true; + + floorGrass = new THREE.Mesh(new THREE.SphereGeometry(floorRadius-.5, 50, 50), new THREE.MeshBasicMaterial({ + color: 0x7abf8e + })); + //floor.rotation.x = -Math.PI / 2; + floorGrass.receiveShadow = false; + + floor = new THREE.Group(); + floor.position.y = -floorRadius; + + floor.add(floorShadow); + floor.add(floorGrass); + scene.add(floor); + +} + +Hero = function() { + this.status = "running"; + this.runningCycle = 0; + this.mesh = new THREE.Group(); + this.body = new THREE.Group(); + this.mesh.add(this.body); + + var torsoGeom = new THREE.CubeGeometry(7, 7, 10, 1); + + this.torso = new THREE.Mesh(torsoGeom, brownMat); + this.torso.position.z = 0; + this.torso.position.y = 7; + this.torso.castShadow = true; + this.body.add(this.torso); + + var pantsGeom = new THREE.CubeGeometry(9, 9, 5, 1); + this.pants = new THREE.Mesh(pantsGeom, whiteMat); + this.pants.position.z = -3; + this.pants.position.y = 0; + this.pants.castShadow = true; + this.torso.add(this.pants); + + var tailGeom = new THREE.CubeGeometry(3, 3, 3, 1); + tailGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,-2)); + this.tail = new THREE.Mesh(tailGeom, lightBrownMat); + this.tail.position.z = -4; + this.tail.position.y = 5; + this.tail.castShadow = true; + this.torso.add(this.tail); + + this.torso.rotation.x = -Math.PI/8; + + var headGeom = new THREE.CubeGeometry(10, 10, 13, 1); + + headGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,7.5)); + this.head = new THREE.Mesh(headGeom, brownMat); + this.head.position.z = 2; + this.head.position.y = 11; + this.head.castShadow = true; + this.body.add(this.head); + + var cheekGeom = new THREE.CubeGeometry(1, 4, 4, 1); + this.cheekR = new THREE.Mesh(cheekGeom, pinkMat); + this.cheekR.position.x = -5; + this.cheekR.position.z = 7; + this.cheekR.position.y = -2.5; + this.cheekR.castShadow = true; + this.head.add(this.cheekR); + + this.cheekL = this.cheekR.clone(); + this.cheekL.position.x = - this.cheekR.position.x; + this.head.add(this.cheekL); + + + var noseGeom = new THREE.CubeGeometry(6, 6, 3, 1); + this.nose = new THREE.Mesh(noseGeom, lightBrownMat); + this.nose.position.z = 13.5; + this.nose.position.y = 2.6; + this.nose.castShadow = true; + this.head.add(this.nose); + + var mouthGeom = new THREE.CubeGeometry(4, 2, 4, 1); + mouthGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,3)); + mouthGeom.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/12)); + this.mouth = new THREE.Mesh(mouthGeom, brownMat); + this.mouth.position.z = 8; + this.mouth.position.y = -4; + this.mouth.castShadow = true; + this.head.add(this.mouth); + + + var pawFGeom = new THREE.CubeGeometry(3,3,3, 1); + this.pawFR = new THREE.Mesh(pawFGeom, lightBrownMat); + this.pawFR.position.x = -2; + this.pawFR.position.z = 6; + this.pawFR.position.y = 1.5; + this.pawFR.castShadow = true; + this.body.add(this.pawFR); + + this.pawFL = this.pawFR.clone(); + this.pawFL.position.x = - this.pawFR.position.x; + this.pawFL.castShadow = true; + this.body.add(this.pawFL); + + var pawBGeom = new THREE.CubeGeometry(3,3,6, 1); + this.pawBL = new THREE.Mesh(pawBGeom, lightBrownMat); + this.pawBL.position.y = 1.5; + this.pawBL.position.z = 0; + this.pawBL.position.x = 5; + this.pawBL.castShadow = true; + this.body.add(this.pawBL); + + this.pawBR = this.pawBL.clone(); + this.pawBR.position.x = - this.pawBL.position.x; + this.pawBR.castShadow = true; + this.body.add(this.pawBR); + + var earGeom = new THREE.CubeGeometry(7, 18, 2, 1); + earGeom.vertices[6].x+=2; + earGeom.vertices[6].z+=.5; + + earGeom.vertices[7].x+=2; + earGeom.vertices[7].z-=.5; + + earGeom.vertices[2].x-=2; + earGeom.vertices[2].z-=.5; + + earGeom.vertices[3].x-=2; + earGeom.vertices[3].z+=.5; + earGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,9,0)); + + this.earL = new THREE.Mesh(earGeom, brownMat); + this.earL.position.x = 2; + this.earL.position.z = 2.5; + this.earL.position.y = 5; + this.earL.rotation.z = -Math.PI/12; + this.earL.castShadow = true; + this.head.add(this.earL); + + this.earR = this.earL.clone(); + this.earR.position.x = -this.earL.position.x; + this.earR.rotation.z = -this.earL.rotation.z; + this.earR.castShadow = true; + this.head.add(this.earR); + + var eyeGeom = new THREE.CubeGeometry(2,4,4); + + this.eyeL = new THREE.Mesh(eyeGeom, whiteMat); + this.eyeL.position.x = 5; + this.eyeL.position.z = 5.5; + this.eyeL.position.y = 2.9; + this.eyeL.castShadow = true; + this.head.add(this.eyeL); + + var irisGeom = new THREE.CubeGeometry(.6,2,2); + + this.iris = new THREE.Mesh(irisGeom, blackMat); + this.iris.position.x = 1.2; + this.iris.position.y = 1; + this.iris.position.z = 1; + this.eyeL.add(this.iris); + + this.eyeR = this.eyeL.clone(); + this.eyeR.children[0].position.x = -this.iris.position.x; + + + this.eyeR.position.x = -this.eyeL.position.x; + this.head.add(this.eyeR); + + this.body.traverse(function(object) { + if (object instanceof THREE.Mesh) { + object.castShadow = true; + object.receiveShadow = true; + } + }); +} + +BonusParticles = function(){ + this.mesh = new THREE.Group(); + var bigParticleGeom = new THREE.CubeGeometry(10,10,10,1); + var smallParticleGeom = new THREE.CubeGeometry(5,5,5,1); + this.parts = []; + for (var i=0; i<10; i++){ + var partPink = new THREE.Mesh(bigParticleGeom, pinkMat); + var partGreen = new THREE.Mesh(smallParticleGeom, greenMat); + partGreen.scale.set(.5,.5,.5); + this.parts.push(partPink); + this.parts.push(partGreen); + this.mesh.add(partPink); + this.mesh.add(partGreen); + } +} + +BonusParticles.prototype.explose = function(){ + var _this = this; + var explosionSpeed = .5; + for(var i=0; i.2) TweenMax.to([this.eyeR.scale, this.eyeL.scale], sp/8, {y:0, ease:Power1.easeInOut, yoyo:true, repeat:1}); + +} + +Hero.prototype.hang = function(){ + var _this = this; + var sp = 1; + var ease = Power4.easeOut; + + TweenMax.killTweensOf(this.eyeL.scale); + TweenMax.killTweensOf(this.eyeR.scale); + + this.body.rotation.x = 0; + this.torso.rotation.x = 0; + this.body.position.y = 0; + this.torso.position.y = 7; + + TweenMax.to(this.mesh.rotation, sp, {y:0, ease:ease}); + TweenMax.to(this.mesh.position, sp, {y:-7, z:6, ease:ease}); + TweenMax.to(this.head.rotation, sp, {x:Math.PI/6, ease:ease, onComplete:function(){_this.nod();}}); + + TweenMax.to(this.earL.rotation, sp, {x:Math.PI/3, ease:ease}); + TweenMax.to(this.earR.rotation, sp, {x:Math.PI/3, ease:ease}); + + TweenMax.to(this.pawFL.position, sp, {y:-1, z:3, ease:ease}); + TweenMax.to(this.pawFR.position, sp, {y:-1, z:3, ease:ease}); + TweenMax.to(this.pawBL.position, sp, {y:-2, z:-3, ease:ease}); + TweenMax.to(this.pawBR.position, sp, {y:-2, z:-3, ease:ease}); + + TweenMax.to(this.eyeL.scale, sp, {y:1, ease:ease}); + TweenMax.to(this.eyeR.scale, sp, {y:1, ease:ease}); +} + +Monster.prototype.nod = function(){ + var _this = this; + var sp = 1 + Math.random()*2; + + // HEAD + var tHeadRotY = -Math.PI/3 + Math.random()*.5; + var tHeadRotX = Math.PI/3 - .2 + Math.random()*.4; + TweenMax.to(this.head.rotation, sp, {x:tHeadRotX, y:tHeadRotY, ease:Power4.easeInOut, onComplete:function(){_this.nod()}}); + + // TAIL + + var tTailRotY = -Math.PI/4; + TweenMax.to(this.tail.rotation, sp/8, {y:tTailRotY, ease:Power1.easeInOut, yoyo:true, repeat:8}); + + // EYES + + TweenMax.to([this.eyeR.scale, this.eyeL.scale], sp/20, {y:0, ease:Power1.easeInOut, yoyo:true, repeat:1}); +} + +Monster.prototype.sit = function(){ + var sp = 1.2; + var ease = Power4.easeOut; + var _this = this; + TweenMax.to(this.torso.rotation, sp, {x:-1.3, ease:ease}); + TweenMax.to(this.torso.position, sp, {y:-5, ease:ease, onComplete:function(){ + _this.nod(); + gameStatus = "readyToReplay"; + }}); + + TweenMax.to(this.head.rotation, sp, {x:Math.PI/3, y :-Math.PI/3, ease:ease}); + TweenMax.to(this.tail.rotation, sp, {x:2, y:Math.PI/4, ease:ease}); + TweenMax.to(this.pawBL.rotation, sp, {x:-.1, ease:ease}); + TweenMax.to(this.pawBR.rotation, sp, {x:-.1, ease:ease}); + TweenMax.to(this.pawFL.rotation, sp, {x:1, ease:ease}); + TweenMax.to(this.pawFR.rotation, sp, {x:1, ease:ease}); + TweenMax.to(this.mouth.rotation, sp, {x:.3, ease:ease}); + TweenMax.to(this.eyeL.scale, sp, {y:1, ease:ease}); + TweenMax.to(this.eyeR.scale, sp, {y:1, ease:ease}); + + //TweenMax.to(this.body.rotation, sp, {y:Math.PI/4}); + +} + + +Carrot = function() { + this.angle = 0; + this.mesh = new THREE.Group(); + + var bodyGeom = new THREE.CylinderGeometry(5,3, 10, 4,1); + bodyGeom.vertices[8].y+=2; + bodyGeom.vertices[9].y-=3; + + this.body = new THREE.Mesh(bodyGeom, pinkMat); + + var leafGeom = new THREE.CubeGeometry(5,10,1,1); + leafGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,5,0)); + leafGeom.vertices[2].x-=1; + leafGeom.vertices[3].x-=1; + leafGeom.vertices[6].x+=1; + leafGeom.vertices[7].x+=1; + + this.leaf1 = new THREE.Mesh(leafGeom,greenMat); + this.leaf1.position.y = 7; + this.leaf1.rotation.z = .3; + this.leaf1.rotation.x = .2; + + this.leaf2 = this.leaf1.clone(); + this.leaf2.scale.set(1,1.3,1); + this.leaf2.position.y = 7; + this.leaf2.rotation.z = -.3; + this.leaf2.rotation.x = -.2; + + this.mesh.add(this.body); + this.mesh.add(this.leaf1); + this.mesh.add(this.leaf2); + + this.body.traverse(function(object) { + if (object instanceof THREE.Mesh) { + object.castShadow = true; + object.receiveShadow = true; + } + }); +} + +Hedgehog = function() { + this.angle = 0; + this.status="ready"; + this.mesh = new THREE.Group(); + var bodyGeom = new THREE.CubeGeometry(6,6,6,1); + this.body = new THREE.Mesh(bodyGeom, blackMat); + + var headGeom = new THREE.CubeGeometry(5,5,7,1); + this.head= new THREE.Mesh(headGeom, lightBrownMat); + this.head.position.z = 6; + this.head.position.y = -.5; + + var noseGeom = new THREE.CubeGeometry(1.5,1.5,1.5,1); + this.nose = new THREE.Mesh(noseGeom, blackMat); + this.nose.position.z = 4; + this.nose.position.y = 2; + + var eyeGeom = new THREE.CubeGeometry(1,3,3); + + this.eyeL = new THREE.Mesh(eyeGeom, whiteMat); + this.eyeL.position.x = 2.2; + this.eyeL.position.z = -.5; + this.eyeL.position.y = .8; + this.eyeL.castShadow = true; + this.head.add(this.eyeL); + + var irisGeom = new THREE.CubeGeometry(.5,1,1); + + this.iris = new THREE.Mesh(irisGeom, blackMat); + this.iris.position.x = .5; + this.iris.position.y = .8; + this.iris.position.z = .8; + this.eyeL.add(this.iris); + + this.eyeR = this.eyeL.clone(); + this.eyeR.children[0].position.x = -this.iris.position.x; + this.eyeR.position.x = -this.eyeL.position.x; + + var spikeGeom = new THREE.CubeGeometry(.5,2,.5,1); + spikeGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,1,0)); + + for (var i=0; i<9; i++){ + var row = (i%3); + var col = Math.floor(i/3); + var sb = new THREE.Mesh(spikeGeom, blackMat); + sb.rotation.x =-Math.PI/2 + (Math.PI/12*row) -.5 + Math.random(); + sb.position.z = -3; + sb.position.y = -2 + row*2; + sb.position.x = -2 + col*2; + this.body.add(sb); + var st = new THREE.Mesh(spikeGeom, blackMat); + st.position.y = 3; + st.position.x = -2 + row*2; + st.position.z = -2 + col*2; + st.rotation.z = Math.PI/6 - (Math.PI/6*row) -.5 + Math.random(); + this.body.add(st); + + var sr = new THREE.Mesh(spikeGeom, blackMat); + sr.position.x = 3; + sr.position.y = -2 + row*2; + sr.position.z = -2 + col*2; + sr.rotation.z = -Math.PI/2 + (Math.PI/12*row) -.5 + Math.random(); + this.body.add(sr); + + var sl = new THREE.Mesh(spikeGeom, blackMat); + sl.position.x = -3; + sl.position.y = -2 + row*2; + sl.position.z = -2 + col*2; + sl.rotation.z = Math.PI/2 - (Math.PI/12*row) -.5 + Math.random();; + this.body.add(sl); + } + + this.head.add(this.eyeR); + var earGeom = new THREE.CubeGeometry(2, 2, .5, 1); + this.earL = new THREE.Mesh(earGeom, lightBrownMat); + this.earL.position.x = 2.5; + this.earL.position.z = -2.5; + this.earL.position.y = 2.5; + this.earL.rotation.z = -Math.PI/12; + this.earL.castShadow = true; + this.head.add(this.earL); + + this.earR = this.earL.clone(); + this.earR.position.x = -this.earL.position.x; + this.earR.rotation.z = -this.earL.rotation.z; + this.earR.castShadow = true; + this.head.add(this.earR); + + var mouthGeom = new THREE.CubeGeometry( 1, 1,.5, 1); + this.mouth = new THREE.Mesh(mouthGeom, blackMat); + this.mouth.position.z = 3.5; + this.mouth.position.y = -1.5; + this.head.add(this.mouth); + + + this.mesh.add(this.body); + this.body.add(this.head); + this.head.add(this.nose); + + this.mesh.traverse(function(object) { + if (object instanceof THREE.Mesh) { + object.castShadow = true; + object.receiveShadow = true; + } + }); +} + +Hedgehog.prototype.nod = function(){ + var _this = this; + var speed = .1 + Math.random()*.5; + var angle = -Math.PI/4 + Math.random()*Math.PI/2; + TweenMax.to(this.head.rotation, speed, {y:angle, onComplete:function(){ + _this.nod(); + }}); +} + + +function createHero() { + hero = new Hero(); + hero.mesh.rotation.y = Math.PI/2; + scene.add(hero.mesh); + hero.nod(); +} + +function createMonster() { + + monster = new Monster(); + monster.mesh.position.z = 20; + //monster.mesh.scale.set(1.2,1.2,1.2); + scene.add(monster.mesh); + updateMonsterPosition(); + +} + +function updateMonsterPosition(){ + monster.run(); + monsterPosTarget -= delta*monsterAcceleration; + monsterPos += (monsterPosTarget-monsterPos) *delta; + if (monsterPos < .56){ + gameOver(); + } + + var angle = Math.PI*monsterPos; + monster.mesh.position.y = - floorRadius + Math.sin(angle)*(floorRadius + 12); + monster.mesh.position.x = Math.cos(angle)*(floorRadius+15); + monster.mesh.rotation.z = -Math.PI/2 + angle; +} + +function gameOver(){ + fieldGameOver.className = "show"; + gameStatus = "gameOver"; + monster.sit(); + hero.hang(); + monster.heroHolder.add(hero.mesh); + TweenMax.to(this, 1, {speed:0}); + TweenMax.to(camera.position, 3, {z:cameraPosGameOver, y: 60, x:-30}); + carrot.mesh.visible = false; + obstacle.mesh.visible = false; + clearInterval(levelInterval); +} + +function replay(){ + + gameStatus = "preparingToReplay" + + fieldGameOver.className = ""; + + TweenMax.killTweensOf(monster.pawFL.position); + TweenMax.killTweensOf(monster.pawFR.position); + TweenMax.killTweensOf(monster.pawBL.position); + TweenMax.killTweensOf(monster.pawBR.position); + + TweenMax.killTweensOf(monster.pawFL.rotation); + TweenMax.killTweensOf(monster.pawFR.rotation); + TweenMax.killTweensOf(monster.pawBL.rotation); + TweenMax.killTweensOf(monster.pawBR.rotation); + + TweenMax.killTweensOf(monster.tail.rotation); + TweenMax.killTweensOf(monster.head.rotation); + TweenMax.killTweensOf(monster.eyeL.scale); + TweenMax.killTweensOf(monster.eyeR.scale); + + //TweenMax.killTweensOf(hero.head.rotation); + + monster.tail.rotation.y = 0; + + TweenMax.to(camera.position, 3, {z:cameraPosGame, x:0, y:30, ease:Power4.easeInOut}); + TweenMax.to(monster.torso.rotation,2, {x:0, ease:Power4.easeInOut}); + TweenMax.to(monster.torso.position,2, {y:0, ease:Power4.easeInOut}); + TweenMax.to(monster.pawFL.rotation,2, {x:0, ease:Power4.easeInOut}); + TweenMax.to(monster.pawFR.rotation,2, {x:0, ease:Power4.easeInOut}); + TweenMax.to(monster.mouth.rotation,2, {x:.5, ease:Power4.easeInOut}); + + + TweenMax.to(monster.head.rotation,2, {y:0, x:-.3, ease:Power4.easeInOut}); + + TweenMax.to(hero.mesh.position, 2, { x:20, ease:Power4.easeInOut}); + TweenMax.to(hero.head.rotation, 2, { x:0, y:0, ease:Power4.easeInOut}); + TweenMax.to(monster.mouth.rotation, 2, {x:.2, ease:Power4.easeInOut}); + TweenMax.to(monster.mouth.rotation, 1, {x:.4, ease:Power4.easeIn, delay: 1, onComplete:function(){ + + resetGame(); + }}); + +} + +Fir = function() { + var height = 200; + var truncGeom = new THREE.CylinderGeometry(2,2,height, 6,1); + truncGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,height/2,0)); + this.mesh = new THREE.Mesh(truncGeom, greenMat); + this.mesh.castShadow = true; +} + +var firs = new THREE.Group(); + +function createFirs(){ + + var nTrees = 100; + for(var i=0; i< nTrees; i++){ + var phi = i*(Math.PI*2)/nTrees; + var theta = Math.PI/2; + //theta += .25 + Math.random()*.3; + theta += (Math.random()>.05)? .25 + Math.random()*.3 : - .35 - Math.random()*.1; + + var fir = new Tree(); + fir.mesh.position.x = Math.sin(theta)*Math.cos(phi)*floorRadius; + fir.mesh.position.y = Math.sin(theta)*Math.sin(phi)*(floorRadius-10); + fir.mesh.position.z = Math.cos(theta)*floorRadius; + + var vec = fir.mesh.position.clone(); + var axis = new THREE.Vector3(0,1,0); + fir.mesh.quaternion.setFromUnitVectors(axis, vec.clone().normalize()); + floor.add(fir.mesh); + } +} + +function createCarrot(){ + carrot = new Carrot(); + scene.add(carrot.mesh); +} + +function updateCarrotPosition(){ + carrot.mesh.rotation.y += delta * 6; + carrot.mesh.rotation.z = Math.PI/2 - (floorRotation+carrot.angle); + carrot.mesh.position.y = -floorRadius + Math.sin(floorRotation+carrot.angle) * (floorRadius+50); + carrot.mesh.position.x = Math.cos(floorRotation+carrot.angle) * (floorRadius+50); + +} + +function updateObstaclePosition(){ + if (obstacle.status=="flying")return; + + // TODO fix this, + if (floorRotation+obstacle.angle > 2.5 ){ + obstacle.angle = -floorRotation + Math.random()*.3; + obstacle.body.rotation.y = Math.random() * Math.PI*2; + } + + obstacle.mesh.rotation.z = floorRotation + obstacle.angle - Math.PI/2; + obstacle.mesh.position.y = -floorRadius + Math.sin(floorRotation+obstacle.angle) * (floorRadius+3); + obstacle.mesh.position.x = Math.cos(floorRotation+obstacle.angle) * (floorRadius+3); + +} + +function updateFloorRotation(){ + floorRotation += delta*.03 * speed; + floorRotation = floorRotation%(Math.PI*2); + floor.rotation.z = floorRotation; +} + +function createObstacle(){ + obstacle = new Hedgehog(); + obstacle.body.rotation.y = -Math.PI/2; + obstacle.mesh.scale.set(1.1,1.1,1.1); + obstacle.mesh.position.y = floorRadius+4; + obstacle.nod(); + scene.add(obstacle.mesh); +} + +function createBonusParticles(){ + bonusParticles = new BonusParticles(); + bonusParticles.mesh.visible = false; + scene.add(bonusParticles.mesh); + +} + + + +function checkCollision(){ + var db = hero.mesh.position.clone().sub(carrot.mesh.position.clone()); + var dm = hero.mesh.position.clone().sub(obstacle.mesh.position.clone()); + + if(db.length() < collisionBonus){ + getBonus(); + } + + if(dm.length() < collisionObstacle && obstacle.status != "flying"){ + getMalus(); + } +} + +function getBonus(){ + bonusParticles.mesh.position.copy(carrot.mesh.position); + bonusParticles.mesh.visible = true; + bonusParticles.explose(); + carrot.angle += Math.PI/2; + //speed*=.95; + monsterPosTarget += .025; + +} + +function getMalus(){ + obstacle.status="flying"; + var tx = (Math.random()>.5)? -20-Math.random()*10 : 20+Math.random()*5; + TweenMax.to(obstacle.mesh.position, 4, {x:tx, y:Math.random()*50, z:350, ease:Power4.easeOut}); + TweenMax.to(obstacle.mesh.rotation, 4, {x:Math.PI*3, z:Math.PI*3, y:Math.PI*6, ease:Power4.easeOut, onComplete:function(){ + obstacle.status = "ready"; + obstacle.body.rotation.y = Math.random() * Math.PI*2; + obstacle.angle = -floorRotation - Math.random()*.4; + + obstacle.angle = obstacle.angle%(Math.PI*2); + obstacle.mesh.rotation.x = 0; + obstacle.mesh.rotation.y = 0; + obstacle.mesh.rotation.z = 0; + obstacle.mesh.position.z = 0; + + }}); + // + monsterPosTarget -= .04; + TweenMax.from(this, .5, {malusClearAlpha:.5, onUpdate:function(){ + renderer.setClearColor(malusClearColor, malusClearAlpha ); + }}) +} + +function updateDistance(){ + distance += delta*speed; + var d = distance/2; + fieldDistance.innerHTML = Math.floor(d); +} + +function updateLevel(){ + if (speed >= maxSpeed) return; + level++; + speed += 2; +} + +function loop(){ + delta = clock.getDelta(); + updateFloorRotation(); + + if (gameStatus == "play"){ + + if (hero.status == "running"){ + hero.run(); + } + updateDistance(); + updateMonsterPosition(); + updateCarrotPosition(); + updateObstaclePosition(); + checkCollision(); + } + + render(); + requestAnimationFrame(loop); +} + +function render(){ + renderer.render(scene, camera); +} + +window.addEventListener('load', init, false); + +function init(event){ + initScreenAnd3D(); + createLights(); + createFloor() + createHero(); + createMonster(); + createFirs(); + createCarrot(); + createBonusParticles(); + createObstacle(); + initUI(); + resetGame(); + loop(); + + //setInterval(hero.blink.bind(hero), 3000); +} + +function resetGame(){ + scene.add(hero.mesh); + hero.mesh.rotation.y = Math.PI/2; + hero.mesh.position.y = 0; + hero.mesh.position.z = 0; + hero.mesh.position.x = 0; + + monsterPos = .56; + monsterPosTarget = .65; + speed = initSpeed; + level = 0; + distance = 0; + carrot.mesh.visible = true; + obstacle.mesh.visible = true; + gameStatus = "play"; + hero.status = "running"; + hero.nod(); + audio.play(); + updateLevel(); + levelInterval = setInterval(updateLevel, levelUpdateFreq); +} + +function initUI(){ + fieldDistance = document.getElementById("distValue"); + fieldGameOver = document.getElementById("gameoverInstructions"); + +} + + + +//////////////////////////////////////////////// +// MODELS +//////////////////////////////////////////////// + +// TREE + +Tree = function(){ + this.mesh = new THREE.Object3D(); + this.trunc = new Trunc(); + this.mesh.add(this.trunc.mesh); +} + + +Trunc = function(){ + var truncHeight = 50 + Math.random()*150; + var topRadius = 1+Math.random()*5; + var bottomRadius = 5+Math.random()*5; + var mats = [blackMat, brownMat, pinkMat, whiteMat, greenMat, lightBrownMat, pinkMat]; + var matTrunc = blackMat;//mats[Math.floor(Math.random()*mats.length)]; + var nhSegments = 3;//Math.ceil(2 + Math.random()*6); + var nvSegments = 3;//Math.ceil(2 + Math.random()*6); + var geom = new THREE.CylinderGeometry(topRadius,bottomRadius,truncHeight, nhSegments, nvSegments); + geom.applyMatrix(new THREE.Matrix4().makeTranslation(0,truncHeight/2,0)); + + this.mesh = new THREE.Mesh(geom, matTrunc); + + for (var i=0; i.7){ + var size = Math.random()*3; + var fruitGeometry = new THREE.CubeGeometry(size,size,size,1); + var matFruit = mats[Math.floor(Math.random()*mats.length)]; + var fruit = new THREE.Mesh(fruitGeometry, matFruit); + fruit.position.x = v.x; + fruit.position.y = v.y+3; + fruit.position.z = v.z; + fruit.rotation.x = Math.random()*Math.PI; + fruit.rotation.y = Math.random()*Math.PI; + + this.mesh.add(fruit); + } + + // BRANCHES + + if (Math.random()>.5 && v.y > 10 && v.y < truncHeight - 10){ + var h = 3 + Math.random()*5; + var thickness = .2 + Math.random(); + + var branchGeometry = new THREE.CylinderGeometry(thickness/2, thickness, h, 3, 1); + branchGeometry.applyMatrix(new THREE.Matrix4().makeTranslation(0,h/2,0)); + var branch = new THREE.Mesh(branchGeometry, matTrunc); + branch.position.x = v.x; + branch.position.y = v.y; + branch.position.z = v.z; + + var vec = new THREE.Vector3(v.x, 2, v.z); + var axis = new THREE.Vector3(0,1,0); + branch.quaternion.setFromUnitVectors(axis, vec.clone().normalize()); + + + this.mesh.add(branch); + } + + } + + + this.mesh.castShadow = true; +} \ No newline at end of file diff --git a/Games/Hedgehog_Havoc/style.css b/Games/Hedgehog_Havoc/style.css new file mode 100644 index 0000000000..d14dc281fb --- /dev/null +++ b/Games/Hedgehog_Havoc/style.css @@ -0,0 +1,86 @@ +@import url("https://fonts.googleapis.com/css?family=Voltaire"); +#world { + position: absolute; + width: 100%; + height: 100%; + background-color: #dbe6e6; + overflow: hidden; +} + +#gameoverInstructions { + position: absolute; + font-family: "Voltaire", sans-serif; + font-weight: bold; + text-transform: uppercase; + font-size: 120px; + text-align: center; + color: #ffc5a2; + opacity: 0; + left: 50%; + top: 50%; + width: 100%; + transform: translate(-50%, -100%); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + transition: all 500ms ease-in-out; +} +#gameoverInstructions.show { + opacity: 1; + transform: translate(-50%, -50%); + transition: all 500ms ease-in-out; +} + +#dist { + position: absolute; + left: 50%; + top: 50px; + transform: translate(-50%, 0%); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.label { + position: relative; + font-family: "Voltaire", sans-serif; + text-transform: uppercase; + color: #ffa873; + font-size: 12px; + letter-spacing: 2px; + text-align: center; + margin-bottom: 5px; +} + +#distValue { + position: relative; + text-transform: uppercase; + color: #dc5f45; + font-size: 40px; + font-family: "Voltaire"; + text-align: center; +} + +#instructions { + position: absolute; + width: 100%; + bottom: 0; + margin: auto; + margin-bottom: 50px; + font-family: "Voltaire", sans-serif; + color: #dc5f45; + font-size: 16px; + letter-spacing: 1px; + text-transform: uppercase; + text-align: center; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.lightInstructions { + color: #5f9042; +} \ No newline at end of file diff --git a/Games/Hexsweep-Game/README.md b/Games/Hexsweep-Game/README.md new file mode 100644 index 0000000000..8c01867272 --- /dev/null +++ b/Games/Hexsweep-Game/README.md @@ -0,0 +1,31 @@ +# 🎮 Hex Sweep Game + +Welcome to Hex Sweep, a fun and challenging Minesweeper-inspired game! 🕹️ + +## 🎯 Game Description + +Hex Sweep is a twist on the classic Minesweeper game. Instead of a rectangular grid, you'll navigate through a hexagonal grid, searching for hidden mines. Your goal is to uncover all the hexagons that don't contain mines without triggering any of the mines. Can you sweep the board clean without detonating a mine? 💥 + +## 🚀 How to Play + +1. **Objective:** Uncover all hexagons without hitting a mine. +2. **Controls:** + - **Left-click:** Uncover a hexagon. + - **Right-click:** Place a flag on a hexagon to mark it as a suspected mine. +3. **Rules:** + - If you uncover a hexagon with a mine, the game is over. 💣 + - If you uncover all hexagons without mines, you win the game. 🏆 + - Use the numbers on uncovered hexagons to help you figure out where the mines are. Each number indicates how many mines are adjacent to that hexagon. + +## 🌟 Features + +- **Hexagonal Grid:** Navigate through a unique hexagonal grid layout. +- **Dynamic Gameplay:** Each game generates a new board with random mine placements. +- **Timer:** Track how long it takes you to complete the game. ⏱️ +- **Flagging:** Mark suspected mines with flags to help keep track of dangerous spots. 🚩 +- **Responsive Design:** Play comfortably on any device, thanks to a responsive and colorful design. +- **Game Over Popup:** Receive a popup message with the option to play again when the game is over. 📢 + +## 🎨 Colorful Design + +Hex Sweep features a vibrant and colorful design, making the game visually appealing and fun to play. 🌈 diff --git a/Games/Hexsweep-Game/index.html b/Games/Hexsweep-Game/index.html new file mode 100644 index 0000000000..da4acf59dd --- /dev/null +++ b/Games/Hexsweep-Game/index.html @@ -0,0 +1,27 @@ + + + + + + Hex Sweep Game + + + +
+

Hex Sweep

+
+
+

Flags: 0

+

Mines: 10

+

Time: 0 seconds

+
+
+ + + + diff --git a/Games/Hexsweep-Game/script.js b/Games/Hexsweep-Game/script.js new file mode 100644 index 0000000000..95c559cbb5 --- /dev/null +++ b/Games/Hexsweep-Game/script.js @@ -0,0 +1,171 @@ +const gameContainer = document.getElementById('game'); +const flagCountDisplay = document.getElementById('flag-count'); +const mineCountDisplay = document.getElementById('mine-count'); +const timerDisplay = document.getElementById('timer'); +const popup = document.getElementById('popup'); +const popupMessage = document.getElementById('popup-message'); +const popupButton = document.getElementById('popup-button'); + +const gridSize = 10; +const mineCount = 10; +let flagCount = 0; +let grid = []; +let minePositions = []; +let timer; +let secondsElapsed = 0; +let isGameOver = false; + +function initializeGame() { + grid = []; + minePositions = []; + flagCount = 0; + secondsElapsed = 0; + isGameOver = false; + clearInterval(timer); + timerDisplay.textContent = secondsElapsed; + flagCountDisplay.textContent = flagCount; + mineCountDisplay.textContent = mineCount; + + for (let i = 0; i < gridSize; i++) { + grid[i] = []; + for (let j = 0; j < gridSize; j++) { + grid[i][j] = { isMine: false, isFlagged: false, isOpen: false, adjacentMines: 0 }; + } + } + + placeMines(); + calculateAdjacentMines(); + renderGrid(); + startTimer(); +} + +function startTimer() { + timer = setInterval(() => { + secondsElapsed++; + timerDisplay.textContent = secondsElapsed; + }, 1000); +} + +function placeMines() { + while (minePositions.length < mineCount) { + const pos = Math.floor(Math.random() * gridSize * gridSize); + const row = Math.floor(pos / gridSize); + const col = pos % gridSize; + + if (!grid[row][col].isMine) { + grid[row][col].isMine = true; + minePositions.push([row, col]); + } + } +} + +function calculateAdjacentMines() { + const directions = [ + [-1, 0], [1, 0], [0, -1], [0, 1], + [-1, -1], [-1, 1], [1, -1], [1, 1] + ]; + + minePositions.forEach(([row, col]) => { + directions.forEach(([dRow, dCol]) => { + const newRow = row + dRow; + const newCol = col + dCol; + + if (newRow >= 0 && newRow < gridSize && newCol >= 0 && newCol < gridSize) { + grid[newRow][newCol].adjacentMines += 1; + } + }); + }); +} + +function renderGrid() { + gameContainer.innerHTML = ''; + grid.forEach((row, rowIndex) => { + row.forEach((cell, colIndex) => { + const hex = document.createElement('div'); + hex.className = 'hex'; + hex.addEventListener('click', () => openCell(rowIndex, colIndex)); + hex.addEventListener('contextmenu', (e) => { + e.preventDefault(); + flagCell(rowIndex, colIndex); + }); + gameContainer.appendChild(hex); + }); + }); +} + +function openCell(row, col) { + if (isGameOver || grid[row][col].isOpen || grid[row][col].isFlagged) return; + + grid[row][col].isOpen = true; + const hex = gameContainer.children[row * gridSize + col]; + + if (grid[row][col].isMine) { + hex.classList.add('mine'); + showPopup('Game Over! You hit a mine.'); + } else { + hex.textContent = grid[row][col].adjacentMines || ''; + hex.style.backgroundColor = '#bbb'; + if (grid[row][col].adjacentMines === 0) { + openAdjacentCells(row, col); + } + checkWinCondition(); + } +} + +function openAdjacentCells(row, col) { + const directions = [ + [-1, 0], [1, 0], [0, -1], [0, 1], + [-1, -1], [-1, 1], [1, -1], [1, 1] + ]; + + directions.forEach(([dRow, dCol]) => { + const newRow = row + dRow; + const newCol = col + dCol; + + if (newRow >= 0 && newRow < gridSize && newCol >= 0 && newCol < gridSize) { + openCell(newRow, newCol); + } + }); +} + +function flagCell(row, col) { + if (isGameOver || grid[row][col].isOpen) return; + + grid[row][col].isFlagged = !grid[row][col].isFlagged; + const hex = gameContainer.children[row * gridSize + col]; + hex.classList.toggle('flagged'); + flagCount += grid[row][col].isFlagged ? 1 : -1; + flagCountDisplay.textContent = flagCount; +} + +function checkWinCondition() { + let isWin = true; + for (let i = 0; i < gridSize; i++) { + for (let j = 0; j < gridSize; j++) { + if (grid[i][j].isMine && !grid[i][j].isFlagged) { + isWin = false; + } + if (!grid[i][j].isMine && !grid[i][j].isOpen) { + isWin = false; + } + } + } + + if (isWin) { + showPopup('Congratulations! You win!'); + } +} + +function showPopup(message) { + popupMessage.textContent = message; + popup.style.display = 'flex'; + isGameOver = true; + clearInterval(timer); +} + +popupButton.addEventListener('click', () => { + popup.style.display = 'none'; + initializeGame(); +}); + +initializeGame(); diff --git a/Games/Hexsweep-Game/styles.css b/Games/Hexsweep-Game/styles.css new file mode 100644 index 0000000000..63aba84525 --- /dev/null +++ b/Games/Hexsweep-Game/styles.css @@ -0,0 +1,162 @@ +body { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background-color: #f5f5f5; + overflow: hidden; +} + +.container { + text-align: center; + background-color: #fff; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + padding: 20px; + width: 80%; + max-width: 600px; +} + +h1 { + color: #333; + margin-bottom: 20px; +} + +#game { + display: grid; + grid-template-columns: repeat(10, 40px); + grid-gap: 2px; + margin: 0 auto 20px; + justify-content: center; +} + +.hex { + width: 40px; + height: 46.4px; + background-color: #ddd; + position: relative; + cursor: pointer; + clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%); + transition: background-color 0.2s, transform 0.2s; + display: flex; + justify-content: center; + align-items: center; + font-weight: bold; + font-size: 0.8rem; + color: #333; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.hex:before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.5); + clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%); + transition: background-color 0.2s; + z-index: 1; +} + +.hex.flagged:before { + background-color: rgba(255, 140, 0, 0.8); +} + +.hex.mine:before { + background-color: rgba(255, 76, 76, 0.8); +} + +.hex:hover:before { + background-color: rgba(0, 0, 0, 0.05); +} + +.hex:active { + transform: scale(0.95); +} + +.hex:nth-child(odd) { + background-color: #b3cde0; +} + +.hex:nth-child(even) { + background-color: #6497b1; +} + +.info { + margin: 20px 0; + display: flex; + justify-content: space-around; + align-items: center; + flex-wrap: wrap; +} + +.info p { + margin: 10px; +} + +button { + padding: 10px 20px; + font-size: 1rem; + cursor: pointer; + background-color: #4CAF50; + color: #fff; + border: none; + border-radius: 4px; + transition: background-color 0.3s; + margin: 20px auto; +} + +button:hover { + background-color: #45a049; +} + +.popup { + display: none; + position: fixed; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + background-color: rgba(0, 0, 0, 0.7); + color: white; + padding: 20px; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + z-index: 1000; +} + +.popup-content { + background-color: #fff; + color: #333; + padding: 20px; + border-radius: 8px; + text-align: center; +} + +.popup-content p { + margin-bottom: 20px; +} + +.popup-content button { + padding: 10px 20px; + font-size: 1rem; + cursor: pointer; + background-color: #4CAF50; + color: #fff; + border: none; + border-radius: 4px; + transition: background-color 0.3s; +} + +.popup-content button:hover { + background-color: #45a049; +} + +@media (max-width: 500px) { + #game { + grid-template-columns: repeat(5, 40px); + } +} diff --git a/Games/Hide_And_Seek/README.md b/Games/Hide_And_Seek/README.md new file mode 100644 index 0000000000..a5bd7ff566 --- /dev/null +++ b/Games/Hide_And_Seek/README.md @@ -0,0 +1,38 @@ +# Hide and Seek + +## Description 📌 + +Hide and Seek is a Memorising flipping-Card Game that features a beautiful and attractive interference where players test their memory skills in order to find out the correct pair of cards. The objective of this game is to test the memory power of player. The player has to flip two cards at a time and find out the matching pair of it, if the player succesfully finds out all the matched pairs, it will be a win otherwise defeat. + +## Functionalities 🔎 + +1. It consists a play area of 4x4 square tiles. +2. Added Gradient effect to make it beautiful. +3. A Reset Button to restart the gameplay. +4. Flipping of tiles to match the pair. +5. A Win! alert, on successfully matching all pairs. + +## How to Play 🕹️ + +- Start by flipping a tile and remember the symbol behind it. +- Here, the game begins now. As you start searching for other tiles and initial tile will hide. +- Now, search for the tile until the pair matches. +- If the pair matches, the tiles will remain open. +- Continuing play in this manner, till all pairs are matched. +- Once all pairs get matched, you'll win the game 🏆. + +## Screenshots 📸 + +Here are some screenshots of the game: + +**At the Starting of Game:** + +![Starting](./assets/image1.png) + +**During Playing:** + +![Playing](./assets/image2.png) + +**At the End of Game:** + +![End](./assets/image3.png) diff --git a/Games/Hide_And_Seek/assets/image1.png b/Games/Hide_And_Seek/assets/image1.png new file mode 100644 index 0000000000..cc321f9a85 Binary files /dev/null and b/Games/Hide_And_Seek/assets/image1.png differ diff --git a/Games/Hide_And_Seek/assets/image2.png b/Games/Hide_And_Seek/assets/image2.png new file mode 100644 index 0000000000..f29529b4e3 Binary files /dev/null and b/Games/Hide_And_Seek/assets/image2.png differ diff --git a/Games/Hide_And_Seek/assets/image3.png b/Games/Hide_And_Seek/assets/image3.png new file mode 100644 index 0000000000..b738a11639 Binary files /dev/null and b/Games/Hide_And_Seek/assets/image3.png differ diff --git a/Games/Hide_And_Seek/index.html b/Games/Hide_And_Seek/index.html new file mode 100644 index 0000000000..47e5afef5d --- /dev/null +++ b/Games/Hide_And_Seek/index.html @@ -0,0 +1,17 @@ + + + + + + Hide and Seek + + + +
+

Hide and Seek

+
+ +
+ + + \ No newline at end of file diff --git a/Games/Hide_And_Seek/script.js b/Games/Hide_And_Seek/script.js new file mode 100644 index 0000000000..c5d2d6d61f --- /dev/null +++ b/Games/Hide_And_Seek/script.js @@ -0,0 +1,35 @@ +const generateGame = () => { + const emojis = ["🍄", "🍄", "🎄", "🎄", "🌵", "🌵", "🍀", "🍀", "🍁", "🍁", "🌴", "🌴", "🌻", "🌻", "🌹", "🌹"]; + var shuffle_emojis = emojis.sort(() => Math.random() > .5 ? 2 : -1); + for (var i = 0; i < emojis.length; i++) { + let box = document.createElement('div') + box.className = 'item'; + box.innerHTML = shuffle_emojis[i] + box.onclick = function() { + this.classList.add('boxOpen') + setTimeout(function() { + if (document.querySelectorAll('.boxOpen').length > 1) { + if (document.querySelectorAll('.boxOpen')[0].innerHTML == document.querySelectorAll('.boxOpen')[1].innerHTML) { + document.querySelectorAll('.boxOpen')[0].classList.add('boxMatch') + document.querySelectorAll('.boxOpen')[1].classList.add('boxMatch') + + document.querySelectorAll('.boxOpen')[1].classList.remove('boxOpen') + document.querySelectorAll('.boxOpen')[0].classList.remove('boxOpen') + + if (document.querySelectorAll('.boxMatch').length == emojis.length) { + alert("Winner!") + window.location.reload() + } + } else { + document.querySelectorAll('.boxOpen')[1].classList.remove('boxOpen') + document.querySelectorAll('.boxOpen')[0].classList.remove('boxOpen') + } + } + },500) + } + + document.querySelector('.game').appendChild(box); + } +} + +generateGame(); \ No newline at end of file diff --git a/Games/Hide_And_Seek/style.css b/Games/Hide_And_Seek/style.css new file mode 100644 index 0000000000..2ed1ad631b --- /dev/null +++ b/Games/Hide_And_Seek/style.css @@ -0,0 +1,105 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +body { + display: flex; + justify-content: center; + align-items: center; + background: linear-gradient(-45deg, #7d0d56, #37128c, #861169, #3b128e); + background-size: 400% 400%; + animation: gradient 10s ease infinite; + min-height: 100vh; +} + +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + + +.container { + position: relative; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 30px; + background: linear-gradient(to right, rgba(46, 0, 59, 0.603), rgba(46, 0, 59, 0.603), rgba(46, 0, 59, 0.603)); + padding: 40px 60px; +} + +h2 { + font-size: 2em; + color: rgba(255, 255, 255, 0.74); + text-transform: uppercase; + letter-spacing: 0.1em; +} + +.reset { + padding: 15px 20px; + background-color: rgba(255, 20, 251, 0.379); + color: aliceblue; + border: none; + font-size: 0.8em; + text-transform: uppercase; + cursor: pointer; + font-weight: 600; +} + +.reset:focus { + color: #fff; + background: #3700ff69; +} + +.game { + width: 430px; + height: 430px; + display: flex; + flex-wrap: wrap; + gap: 10px; + transform-style: preserve-3d; + perspective: 500px; +} + +.item { + position: relative; + width: 100px; + height: 100px; + display: flex; + justify-content: center; + align-items: center; + font-size: 3em; + background: #ffffff2f; + transform: rotateY(180deg); + transition: 0.25s; +} + +.item.boxOpen { + transform: rotateY(0deg); +} + +.item::after { + content: ''; + position: absolute; + inset: 0; + background: #7a00b3; + transition: 0.25s; + transform: rotate(0.25deg); + backface-visibility: hidden; +} + +.boxOpen:after, .boxMatch:after +{ + transform: rotateY(180deg); +} diff --git a/Games/Idle_miner/README.md b/Games/Idle_miner/README.md new file mode 100644 index 0000000000..e7198f6002 --- /dev/null +++ b/Games/Idle_miner/README.md @@ -0,0 +1,59 @@ +# Idle Miner + +--- + +## **Description 📃** + +- Gather resources and upgrade your production by clicking on different items. +- Automate your resource gathering and expand your mining empire. + +
+ +## **functionalities 🎮** + +- Clicking to gather resources. +- Upgrading items to increase resources per click. +- Automating resource gathering for passive income. +- Managing and optimizing resource production to grow your mining business. + +
+ +## **How to play? 🕹️** + +Gather Resources: + +- Click on items such as Vadapav, Kulfi, Shawarma, Fish, and Biryani to gather resources. + +Upgrade Items: + +- Spend resources to upgrade your items, increasing the resources gathered per click. + +Automate Gathering: + +- Purchase automation upgrades to gather resources passively without clicking. + +Optimize and Expand: + +- Manage your resources efficiently to maximize production and expand your mining empire. + +
+ +## **Screenshots 📸** + +![image](./images/game.png) + +
+ +## **Working video 📹** +![image](./images/2024-07-10%2017-14-05.mp4) + +
+ +## **Project Done By 👦** + +[Manas Deshpande](https://github.com/manasdeshpande) + +
+ +### Happy Coding! + diff --git a/Games/Idle_miner/idle miner.css b/Games/Idle_miner/idle miner.css new file mode 100644 index 0000000000..cf1db13ea7 --- /dev/null +++ b/Games/Idle_miner/idle miner.css @@ -0,0 +1,73 @@ +body { + font-family: Arial, sans-serif; + background-color: #f4f4f4; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin:0px; +} +.hello{ + margin-top: 150px; +} +#game { + display: flex; + flex-direction: column; + gap: 10px; +} + +.center { + display: flex; + align-items: center; + background-color: #e0e0e0; + padding: 10px; + width:300px; + border-radius: 10px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} + +.icon { + font-size: 40px; + margin-right: 10px; +} + +.info { + display: flex; + flex-direction: column; + gap: 5px; +} + +.production-rate { + align-items: center; + justify-content: center; + font-size: 16px; + font-weight: bold; +} + +.buy-info { + display: flex; + align-items: center; + margin-top: 5px; +} + +.buy-btn { + background-color: #ffcc00; + border: none; + padding: 5px 10px; + cursor: pointer; + border-radius: 5px; + margin-right: 10px; +} + +.buy-btn:hover { + background-color: #ffbb00; +} + +.cost { + font-size: 14px; +} + +.timer { + font-size: 14px; + margin-top: 5px; +} diff --git a/Games/Idle_miner/idle miner.html b/Games/Idle_miner/idle miner.html new file mode 100644 index 0000000000..2f204e50b6 --- /dev/null +++ b/Games/Idle_miner/idle miner.html @@ -0,0 +1,93 @@ + + + + + + Idle Miner Clicker Game + + + +
+
RS:00/sec
+
+
+
+
1 /click 0/sec
+
+ +
10
+
+
+ +
100
+
+ +
+
+
+
+
+
1 /click 0/sec
+
+ +
10
+
+
+ +
100
+
+ +
+
+
+
+
+
1 /click 0/sec
+
+ +
10
+
+
+ +
100
+
+ +
+
+
+
+
+
1 /click 0/sec
+
+ +
10
+
+
+ +
100
+
+ +
+
+
+
+
+
1 /click 0/sec
+
+ +
10
+
+
+ +
100
+
+ +
+
+
+ +
+ + + + diff --git a/Games/Idle_miner/idle miner.js b/Games/Idle_miner/idle miner.js new file mode 100644 index 0000000000..b621ab538c --- /dev/null +++ b/Games/Idle_miner/idle miner.js @@ -0,0 +1,243 @@ + +let resources = 0; +let Cost = { + "upgrade": { + "vadapav": 10, + "kulfi": 100, + "shawrma": 1000, + "Fish": 10000, + "Biryani": 100000, + }, + automation: { + "vadapav": 100, + "kulfi": 1000, + "shawrma": 10000, + "Fish": 100000, + "Biryani": 1000000, + }, + resourcesPerClick: { + "vadapav": 1, + "kulfi": 0, + "shawrma": 0, + "Fish": 0, + "Biryani": 0, + }, + AutomationPerSec: { + "vadapav": 0, + "kulfi": 0, + "shawrma": 0, + "Fish": 0, + "Biryani": 0, + }, + Value: { + "vadapav": 1, + "kulfi": 5, + "shawrma": 15, + "Fish": 50, + "Biryani": 100, + } +}; +let resourcesPerSecond = 0; + +//clicking on product +{ + document.getElementById('vadapav').addEventListener('click', () => { + resources += Cost.resourcesPerClick.vadapav; + updateResources(); + } + ); + document.getElementById('kulfi').addEventListener('click', () => { + resources += Cost.resourcesPerClick.kulfi; + updateResources(); + } + ); + document.getElementById('shawrma').addEventListener('click', () => { + resources += Cost.resourcesPerClick.shawrma; + updateResources(); + } + ); + document.getElementById('fish').addEventListener('click', () => { + resources += Cost.resourcesPerClick.Fish; + updateResources(); + } + ); + document.getElementById('biryani').addEventListener('click', () => { + resources += Cost.resourcesPerClick.Biryani; + updateResources(); + } + ); +} +//buying single product +{ + document.getElementById('buy-vadapav').addEventListener('click', () => { + console.log(resources, Cost.upgrade.vadapav, Cost.resourcesPerClick.vadapav); + if (resources >= Cost.upgrade.vadapav) { + resources -= Cost.upgrade.vadapav; + Cost.resourcesPerClick.vadapav += 1; + Cost.upgrade.vadapav *= 2; + updateResourcesPerClick() + updateResources(); + updateUpgradeCost(); + } + } + ); + document.getElementById('buy-kulfi').addEventListener('click', () => { + console.log(resources, Cost.upgrade.kulfi, Cost.resourcesPerClick.kulfi); + if (resources >= Cost.upgrade.kulfi) { + resources -= Cost.upgrade.kulfi; + Cost.resourcesPerClick.kulfi += 5; + Cost.upgrade.kulfi *= 2; + updateResourcesPerClick() + updateResources(); + updateUpgradeCost(); + } + } + ); + document.getElementById('buy-shawrma').addEventListener('click', () => { + if (resources >= Cost.upgrade.shawrma) { + resources -= Cost.upgrade.shawrma; + Cost.resourcesPerClick.shawrma += 10; + Cost.upgrade.shawrma *= 2; + updateResourcesPerClick() + updateResources(); + updateUpgradeCost(); + } + } + ); + document.getElementById('buy-fish').addEventListener('click', () => { + if (resources >= Cost.upgrade.Fish) { + resources -= Cost.upgrade.Fish; + Cost.resourcesPerClick.Fish += 50; + Cost.upgrade.Fish *= 2; + updateResourcesPerClick() + updateResources(); + updateUpgradeCost(); + } + } + ); + document.getElementById('buy-biryani').addEventListener('click', () => { + if (resources >= Cost.upgrade.Biryani) { + resources -= Cost.upgrade.Biryani; + Cost.resourcesPerClick.Biryani += 100; + Cost.upgrade.Biryani *= 2; + updateResourcesPerClick() + updateResources(); + updateUpgradeCost(); + } + } + ); +} + +//buying single automation +{ + document.getElementById('auto-vadapav').addEventListener('click', () => { + console.log(resources, Cost.upgrade.vadapav, Cost.resourcesPerClick.vadapav); + if (resources >= Cost.automation.vadapav) { + resources -= Cost.automation.vadapav; + resourcesPerSecond += Cost.Value.vadapav; + Cost.automation.vadapav *= 2; + Cost.AutomationPerSec.vadapav += Cost.Value.vadapav; + updateAutomationPerSec(); + updateResources(); + updateAutomationCost(); + } + } + ); + document.getElementById('auto-kulfi').addEventListener('click', () => { + if (resources >= Cost.automation.kulfi) { + resources -= Cost.automation.kulfi; + resourcesPerSecond += Cost.Value.kulfi; + Cost.automation.kulfi *= 2; + Cost.AutomationPerSec.kulfi += Cost.Value.kulfi; + updateAutomationPerSec(); + updateResources(); + updateAutomationCost(); + } + } + ); + document.getElementById('auto-shawrma').addEventListener('click', () => { + if (resources >= Cost.automation.shawrma) { + resources -= Cost.automation.shawrma; + resourcesPerSecond += Cost.Value.shawrma; + Cost.automation.shawrma *= 2; + Cost.AutomationPerSec.shawrma += Cost.Value.shawrma; + updateAutomationPerSec(); + updateResources(); + updateAutomationCost(); + } + } + ); + document.getElementById('auto-fish').addEventListener('click', () => { + if (resources >= Cost.automation.Fish) { + resources -= Cost.automation.Fish; + resourcesPerSecond += Cost.Value.Fish; + Cost.automation.Fish *= 2; + Cost.AutomationPerSec.Fish += Cost.Value.Fish; + updateAutomationPerSec(); + updateResources(); + updateAutomationCost(); + } + } + ); + document.getElementById('auto-biryani').addEventListener('click', () => { + if (resources >= Cost.automation.Biryani) { + resources -= Cost.automation.Biryani; + resourcesPerSecond += Cost.Value.Biryani; + Cost.automation.Biryani *= 2; + Cost.AutomationPerSec.Biryani += Cost.Value.Biryani; + updateAutomationPerSec(); + updateResources(); + updateAutomationCost(); + } + } + ); +} +function updateResources() { + document.getElementById('resource').textContent = resources; + document.getElementById('automation-').textContent = " "+resourcesPerSecond; +} + +function updateUpgradeCost() { + document.getElementById('vadapav-cost').textContent = Cost.upgrade.vadapav; + document.getElementById('kulfi-cost').textContent = Cost.upgrade.kulfi; + document.getElementById('shawrma-cost').textContent = Cost.upgrade.shawrma; + document.getElementById('fish-cost').textContent = Cost.upgrade.Fish; + document.getElementById('biryani-cost').textContent = Cost.upgrade.Biryani; +} + +function updateAutomationCost() { + document.getElementById('vadapav-auto').textContent = Cost.automation.vadapav; + document.getElementById('kulfi-auto').textContent = Cost.automation.kulfi; + document.getElementById('shawrma-auto').textContent = Cost.automation.shawrma; + document.getElementById('fish-auto').textContent = Cost.automation.Fish; + document.getElementById('biryani-auto').textContent = Cost.automation.Biryani; +} + +function updateResourcesPerClick() { + document.getElementById('vadapav-click').textContent = Cost.resourcesPerClick.vadapav; + document.getElementById('kulfi-click').textContent = Cost.resourcesPerClick.kulfi; + document.getElementById('shawrma-click').textContent = Cost.resourcesPerClick.shawrma; + document.getElementById('fish-click').textContent = Cost.resourcesPerClick.Fish; + document.getElementById('biryani-click').textContent = Cost.resourcesPerClick.Biryani; +} + +function updateAutomationPerSec() { + document.getElementById('vadapav-autom').textContent = Cost.AutomationPerSec.vadapav; + document.getElementById('kulfi-autom').textContent = Cost.AutomationPerSec.kulfi; + document.getElementById('shawrma-autom').textContent = Cost.AutomationPerSec.shawrma; + document.getElementById('fish-autom').textContent = Cost.AutomationPerSec.Fish; + document.getElementById('biryani-autom').textContent = Cost.AutomationPerSec.Biryani; +} + +setInterval(() => { + resources += resourcesPerSecond; + updateResources(); +}, 1000); + +document.addEventListener("DOMContentLoaded", function() { + updateResources(); + updateUpgradeCost(); + updateAutomationCost(); + updateResourcesPerClick(); + updateAutomationPerSec(); +}); diff --git a/Games/Idle_miner/images/2024-07-10 17-14-05.mp4 b/Games/Idle_miner/images/2024-07-10 17-14-05.mp4 new file mode 100644 index 0000000000..146f49b359 Binary files /dev/null and b/Games/Idle_miner/images/2024-07-10 17-14-05.mp4 differ diff --git a/Games/Idle_miner/images/biryani.png b/Games/Idle_miner/images/biryani.png new file mode 100644 index 0000000000..0705ce9e2b Binary files /dev/null and b/Games/Idle_miner/images/biryani.png differ diff --git a/Games/Idle_miner/images/fish.png b/Games/Idle_miner/images/fish.png new file mode 100644 index 0000000000..b14479c43d Binary files /dev/null and b/Games/Idle_miner/images/fish.png differ diff --git a/Games/Idle_miner/images/game.png b/Games/Idle_miner/images/game.png new file mode 100644 index 0000000000..3a8f5c1179 Binary files /dev/null and b/Games/Idle_miner/images/game.png differ diff --git a/Games/Idle_miner/images/kulfi.png b/Games/Idle_miner/images/kulfi.png new file mode 100644 index 0000000000..ac287733ed Binary files /dev/null and b/Games/Idle_miner/images/kulfi.png differ diff --git a/Games/Idle_miner/images/shawrma.png b/Games/Idle_miner/images/shawrma.png new file mode 100644 index 0000000000..21a833d582 Binary files /dev/null and b/Games/Idle_miner/images/shawrma.png differ diff --git a/Games/Idle_miner/images/vadapav.png b/Games/Idle_miner/images/vadapav.png new file mode 100644 index 0000000000..a728ad60ec Binary files /dev/null and b/Games/Idle_miner/images/vadapav.png differ diff --git a/Games/Jigsaw_Puzzle/Readme.md b/Games/Jigsaw_Puzzle/Readme.md new file mode 100644 index 0000000000..315381d415 --- /dev/null +++ b/Games/Jigsaw_Puzzle/Readme.md @@ -0,0 +1,35 @@ +# Classic Jigsaw Puzzle Game + +Welcome to the Classic Jigsaw Puzzle Game! This game allows you to upload any image and transform it into a jigsaw puzzle with varying difficulty levels. Whether you're looking for a quick challenge or a more intricate puzzle to solve, this game provides an enjoyable and interactive experience. + +## Game Features + +- **Image Upload:** Upload your own images to create personalized puzzles. +- **Piece Selection:** Choose from 12, 25, 50, 100, or 200 pieces for different difficulty levels. +- **Interactive Gameplay:** Drag and drop pieces to solve the puzzle. +- **User-Friendly Interface:** Designed for a smooth and enjoyable user experience. +- **Responsive Design:** Compatible with different devices, ensuring a great experience on both desktop and mobile. + +## Rules + +1. **Objective:** The goal is to assemble the puzzle pieces to form the complete image. +2. **Piece Selection:** Select the number of pieces you want for your puzzle. The more pieces, the more challenging the puzzle. +3. **Gameplay:** Drag and drop the pieces to their correct positions. Pieces will snap into place when they are correctly aligned. + +## How to Play + +1. **Upload Image:** Click on the "Upload Image" button to select an image from your device. +2. **Select Pieces:** Choose the number of pieces for your puzzle (12, 25, 50, 100, 200). +3. **Start Puzzle:** The image will be broken into pieces, and you can start solving the puzzle by dragging and dropping the pieces. +4. **Solving:** Arrange the pieces to form the complete image. Pieces will snap into place when correctly positioned. +5. **Complete Puzzle:** Once all pieces are correctly placed, the puzzle is complete, and you can admire your work! + +## Screenshot + +![image](/assets/images/Jigsaw_Puzzle_SS.png) + +## Enjoy the Game! + +We hope you have fun playing the Classic Jigsaw Puzzle Game. If you have any feedback or suggestions, feel free to share them with us. Happy puzzling! + + diff --git a/Games/Jigsaw_Puzzle/index.html b/Games/Jigsaw_Puzzle/index.html new file mode 100644 index 0000000000..bc5092d432 --- /dev/null +++ b/Games/Jigsaw_Puzzle/index.html @@ -0,0 +1,29 @@ + + + + + + Document + + + +
+ + + + \ No newline at end of file diff --git a/Games/Jigsaw_Puzzle/script.js b/Games/Jigsaw_Puzzle/script.js new file mode 100644 index 0000000000..41d1fe3abb --- /dev/null +++ b/Games/Jigsaw_Puzzle/script.js @@ -0,0 +1,1259 @@ +"use strict"; + +let puzzle, autoStart; + +const mhypot = Math.hypot, + mrandom = Math.random, + mmax = Math.max, + mmin = Math.min, + mround = Math.round, + mfloor = Math.floor, + msqrt = Math.sqrt, + mabs = Math.abs; + +function isMiniature() { + return location.pathname.includes('/fullcpgrid/'); +} + + +function alea(min, max) { + if (typeof max == 'undefined') return min * mrandom(); + return min + (max - min) * mrandom(); +} + + +function intAlea(min, max) { + if (typeof max == 'undefined') { + max = min; min = 0; + } + return mfloor(min + (max - min) * mrandom()); +} + + + +function arrayShuffle(array) { + let k1, temp; + for (let k = array.length - 1; k >= 1; --k) { + k1 = intAlea(0, k + 1); + temp = array[k]; + array[k] = array[k1]; + array[k1] = temp; + } + return array +} + +class Point { + constructor(x, y) { + this.x = Number(x); + this.y = Number(y); + } + copy() { + return new Point(this.x, this.y); + } + + distance(otherPoint) { + return mhypot(this.x - otherPoint.x, this.y - otherPoint.y); + } +} + +class Segment { + constructor(p1, p2) { + this.p1 = new Point(p1.x, p1.y); + this.p2 = new Point(p2.x, p2.y); + } + dx() { + return this.p2.x - this.p1.x; + } + dy() { + return this.p2.y - this.p1.y; + } + length() { + return mhypot(this.dx(), this.dy()); + } + + pointOnRelative(coeff) { + let dx = this.dx(); + let dy = this.dy(); + return new Point(this.p1.x + coeff * dx, this.p1.y + coeff * dy); + } +} + +class Side { + constructor() { + this.type = ""; + this.points = []; + } + + reversed() { + const ns = new Side(); + ns.type = this.type; + ns.points = this.points.slice().reverse(); + return ns; + } + + + scale(puzzle) { + + const coefx = puzzle.scalex; + const coefy = puzzle.scaley; + this.scaledPoints = this.points.map(p => new Point(p.x * coefx, p.y * coefy)); + + } + + drawPath(ctx, shiftx, shifty, withoutMoveTo) { + + if (!withoutMoveTo) { + ctx.moveTo(this.scaledPoints[0].x + shiftx, this.scaledPoints[0].y + shifty); + } + if (this.type == "d") { + ctx.lineTo(this.scaledPoints[1].x + shiftx, this.scaledPoints[1].y + shifty); + } else { + for (let k = 1; k < this.scaledPoints.length - 1; k += 3) { + ctx.bezierCurveTo(this.scaledPoints[k].x + shiftx, this.scaledPoints[k].y + shifty, + this.scaledPoints[k + 1].x + shiftx, this.scaledPoints[k + 1].y + shifty, + this.scaledPoints[k + 2].x + shiftx, this.scaledPoints[k + 2].y + shifty); + } + } + + } +} + + +function twist0(side, ca, cb) { + + const seg0 = new Segment(side.points[0], side.points[1]); + const dxh = seg0.dx(); + const dyh = seg0.dy(); + + const seg1 = new Segment(ca, cb); + const mid0 = seg0.pointOnRelative(0.5); + const mid1 = seg1.pointOnRelative(0.5); + + const segMid = new Segment(mid0, mid1); + const dxv = segMid.dx(); + const dyv = segMid.dy(); + + const scalex = alea(0.8, 1); + const scaley = alea(0.9, 1); + const mid = alea(0.45, 0.55); + + const pa = pointAt(mid - 1 / 12 * scalex, 1 / 12 * scaley); + const pb = pointAt(mid - 2 / 12 * scalex, 3 / 12 * scaley); + const pc = pointAt(mid, 4 / 12 * scaley); + const pd = pointAt(mid + 2 / 12 * scalex, 3 / 12 * scaley); + const pe = pointAt(mid + 1 / 12 * scalex, 1 / 12 * scaley); + + side.points = [seg0.p1, + new Point(seg0.p1.x + 5 / 12 * dxh * 0.52, + seg0.p1.y + 5 / 12 * dyh * 0.52), + new Point(pa.x - 1 / 12 * dxv * 0.72, + pa.y - 1 / 12 * dyv * 0.72), + pa, + new Point(pa.x + 1 / 12 * dxv * 0.72, + pa.y + 1 / 12 * dyv * 0.72), + + new Point(pb.x - 1 / 12 * dxv * 0.92, + pb.y - 1 / 12 * dyv * 0.92), + pb, + new Point(pb.x + 1 / 12 * dxv * 0.52, + pb.y + 1 / 12 * dyv * 0.52), + new Point(pc.x - 2 / 12 * dxh * 0.40, + pc.y - 2 / 12 * dyh * 0.40), + pc, + new Point(pc.x + 2 / 12 * dxh * 0.40, + pc.y + 2 / 12 * dyh * 0.40), + new Point(pd.x + 1 / 12 * dxv * 0.52, + pd.y + 1 / 12 * dyv * 0.52), + pd, + new Point(pd.x - 1 / 12 * dxv * 0.92, + pd.y - 1 / 12 * dyv * 0.92), + new Point(pe.x + 1 / 12 * dxv * 0.72, + pe.y + 1 / 12 * dyv * 0.72), + pe, + new Point(pe.x - 1 / 12 * dxv * 0.72, + pe.y - 1 / 12 * dyv * 0.72), + new Point(seg0.p2.x - 5 / 12 * dxh * 0.52, + seg0.p2.y - 5 / 12 * dyh * 0.52), + seg0.p2]; + side.type = "z"; + + function pointAt(coeffh, coeffv) { + return new Point(seg0.p1.x + coeffh * dxh + coeffv * dxv, + seg0.p1.y + coeffh * dyh + coeffv * dyv) + } + +} + + + +function twist1(side, ca, cb) { + + const seg0 = new Segment(side.points[0], side.points[1]); + const dxh = seg0.dx(); + const dyh = seg0.dy(); + + const seg1 = new Segment(ca, cb); + const mid0 = seg0.pointOnRelative(0.5); + const mid1 = seg1.pointOnRelative(0.5); + + const segMid = new Segment(mid0, mid1); + const dxv = segMid.dx(); + const dyv = segMid.dy(); + + const pa = pointAt(alea(0.3, 0.35), alea(-0.05, 0.05)); + const pb = pointAt(alea(0.45, 0.55), alea(0.2, 0.3)); + const pc = pointAt(alea(0.65, 0.78), alea(-0.05, 0.05)); + + side.points = [seg0.p1, + seg0.p1, pa, pa, + pa, pb, pb, + pb, pc, pc, + pc, seg0.p2, seg0.p2]; + side.type = "z"; + + function pointAt(coeffh, coeffv) { + return new Point(seg0.p1.x + coeffh * dxh + coeffv * dxv, + seg0.p1.y + coeffh * dyh + coeffv * dyv) + } + +} + + + +function twist2(side, ca, cb) { + + const seg0 = new Segment(side.points[0], side.points[1]); + const dxh = seg0.dx(); + const dyh = seg0.dy(); + + const seg1 = new Segment(ca, cb); + const mid0 = seg0.pointOnRelative(0.5); + const mid1 = seg1.pointOnRelative(0.5); + + const segMid = new Segment(mid0, mid1); + const dxv = segMid.dx(); + const dyv = segMid.dy(); + + const hmid = alea(0.45, 0.55); + const vmid = alea(0.4, 0.5) + const pc = pointAt(hmid, vmid); + let sega = new Segment(seg0.p1, pc); + + const pb = sega.pointOnRelative(2 / 3); + sega = new Segment(seg0.p2, pc); + const pd = sega.pointOnRelative(2 / 3); + + side.points = [seg0.p1, pb, pd, seg0.p2]; + side.type = "z"; + + function pointAt(coeffh, coeffv) { + return new Point(seg0.p1.x + coeffh * dxh + coeffv * dxv, + seg0.p1.y + coeffh * dyh + coeffv * dyv) + } + +} + + +function twist3(side, ca, cb) { + + side.points = [side.points[0], side.points[1]]; + +} + +class Piece { + constructor(kx, ky) { + this.ts = new Side(); + this.rs = new Side(); + this.bs = new Side(); + this.ls = new Side(); + this.kx = kx; + this.ky = ky; + } + + scale(puzzle) { + this.ts.scale(puzzle); + this.rs.scale(puzzle); + this.bs.scale(puzzle); + this.ls.scale(puzzle); + } +} + +class PolyPiece { + + constructor(initialPiece, puzzle) { + this.pckxmin = initialPiece.kx; + this.pckxmax = initialPiece.kx + 1; + this.pckymin = initialPiece.ky; + this.pckymax = initialPiece.ky + 1; + this.pieces = [initialPiece]; + this.puzzle = puzzle; + this.listLoops(); + + this.canvas = document.createElement('CANVAS'); + puzzle.container.appendChild(this.canvas); + this.canvas.classList.add('polypiece'); + this.ctx = this.canvas.getContext("2d"); + } + + + merge(otherPoly) { + + const orgpckxmin = this.pckxmin; + const orgpckymin = this.pckymin; + + const kOther = this.puzzle.polyPieces.indexOf(otherPoly); + this.puzzle.polyPieces.splice(kOther, 1); + + this.puzzle.container.removeChild(otherPoly.canvas); + + for (let k = 0; k < otherPoly.pieces.length; ++k) { + this.pieces.push(otherPoly.pieces[k]); + + if (otherPoly.pieces[k].kx < this.pckxmin) this.pckxmin = otherPoly.pieces[k].kx; + if (otherPoly.pieces[k].kx + 1 > this.pckxmax) this.pckxmax = otherPoly.pieces[k].kx + 1; + if (otherPoly.pieces[k].ky < this.pckymin) this.pckymin = otherPoly.pieces[k].ky; + if (otherPoly.pieces[k].ky + 1 > this.pckymax) this.pckymax = otherPoly.pieces[k].ky + 1; + } + + + this.pieces.sort(function (p1, p2) { + if (p1.ky < p2.ky) return -1; + if (p1.ky > p2.ky) return 1; + if (p1.kx < p2.kx) return -1; + if (p1.kx > p2.kx) return 1; + return 0; + }); + + + this.listLoops(); + + this.drawImage(); + this.moveTo(this.x + this.puzzle.scalex * (this.pckxmin - orgpckxmin), + this.y + this.puzzle.scaley * (this.pckymin - orgpckymin)); + + this.puzzle.evaluateZIndex(); + } + + + ifNear(otherPoly) { + + let p1, p2; + let puzzle = this.puzzle; + + + let x = this.x - puzzle.scalex * this.pckxmin; + let y = this.y - puzzle.scaley * this.pckymin; + + let ppx = otherPoly.x - puzzle.scalex * otherPoly.pckxmin; + let ppy = otherPoly.y - puzzle.scaley * otherPoly.pckymin; + if (mhypot(x - ppx, y - ppy) >= puzzle.dConnect) return false; + + + for (let k = this.pieces.length - 1; k >= 0; --k) { + p1 = this.pieces[k]; + for (let ko = otherPoly.pieces.length - 1; ko >= 0; --ko) { + p2 = otherPoly.pieces[ko]; + if (p1.kx == p2.kx && mabs(p1.ky - p2.ky) == 1) return true; + if (p1.ky == p2.ky && mabs(p1.kx - p2.kx) == 1) return true; + } + } + + + + return false; + + } + + + listLoops() { + + const that = this; + function edgeIsCommon(kx, ky, edge) { + let k; + switch (edge) { + case 0: ky--; break; + case 1: kx++; break; + case 2: ky++; break; + case 3: kx--; break; + } + for (k = 0; k < that.pieces.length; k++) { + if (kx == that.pieces[k].kx && ky == that.pieces[k].ky) return true; + } + return false; + } + + + function edgeIsInTbEdges(kx, ky, edge) { + let k; + for (k = 0; k < tbEdges.length; k++) { + if (kx == tbEdges[k].kx && ky == tbEdges[k].ky && edge == tbEdges[k].edge) return k; // found it + } + return false; + } + + + let tbLoops = []; + let tbEdges = []; + let k; + let kEdge; + let lp; + let currEdge; + let tries; + let edgeNumber; + let potNext; + + + let tbTries = [ + [ + { dkx: 0, dky: 0, edge: 1 }, + { dkx: 1, dky: 0, edge: 0 }, + { dkx: 1, dky: -1, edge: 3 } + ], + [ + { dkx: 0, dky: 0, edge: 2 }, + { dkx: 0, dky: 1, edge: 1 }, + { dkx: 1, dky: 1, edge: 0 } + ], + [ + { dkx: 0, dky: 0, edge: 3 }, + { dkx: - 1, dky: 0, edge: 2 }, + { dkx: - 1, dky: 1, edge: 1 } + ], + [ + { dkx: 0, dky: 0, edge: 0 }, + { dkx: 0, dky: - 1, edge: 3 }, + { dkx: - 1, dky: - 1, edge: 2 } + ], + ]; + + + for (k = 0; k < this.pieces.length; k++) { + for (kEdge = 0; kEdge < 4; kEdge++) { + if (!edgeIsCommon(this.pieces[k].kx, this.pieces[k].ky, kEdge)) + tbEdges.push({ kx: this.pieces[k].kx, ky: this.pieces[k].ky, edge: kEdge, kp: k }) + } + } + + while (tbEdges.length > 0) { + lp = []; + currEdge = tbEdges[0]; + lp.push(currEdge); + tbEdges.splice(0, 1); + do { + for (tries = 0; tries < 3; tries++) { + potNext = tbTries[currEdge.edge][tries]; + edgeNumber = edgeIsInTbEdges(currEdge.kx + potNext.dkx, currEdge.ky + potNext.dky, potNext.edge); + if (edgeNumber === false) continue; + currEdge = tbEdges[edgeNumber]; + lp.push(currEdge); + tbEdges.splice(edgeNumber, 1); + break; + } + if (edgeNumber === false) break; + } while (1); + tbLoops.push(lp); + } + + + this.tbLoops = tbLoops.map(loop => loop.map(edge => { + let cell = this.pieces[edge.kp]; + if (edge.edge == 0) return cell.ts; + if (edge.edge == 1) return cell.rs; + if (edge.edge == 2) return cell.bs; + return cell.ls; + })); + } + + + drawPath(ctx, shiftx, shifty) { + + + this.tbLoops.forEach(loop => { + let without = false; + loop.forEach(side => { + side.drawPath(ctx, shiftx, shifty, without); + without = true; + }); + ctx.closePath(); + }); + + } + + + drawImage() { + + puzzle = this.puzzle; + this.nx = this.pckxmax - this.pckxmin + 1; + this.ny = this.pckymax - this.pckymin + 1; + this.canvas.width = this.nx * puzzle.scalex; + this.canvas.height = this.ny * puzzle.scaley; + + this.offsx = (this.pckxmin - 0.5) * puzzle.scalex; + this.offsy = (this.pckymin - 0.5) * puzzle.scaley; + + this.path = new Path2D(); + this.drawPath(this.path, -this.offsx, -this.offsy); + + + this.ctx.fillStyle = 'none'; + this.ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'; + this.ctx.shadowBlur = 4; + this.ctx.shadowOffsetX = 4; + this.ctx.shadowOffsetY = 4; + this.ctx.fill(this.path); + this.ctx.shadowColor = 'rgba(0, 0, 0, 0)'; + + this.pieces.forEach((pp, kk) => { + + this.ctx.save(); + + const path = new Path2D(); + const shiftx = -this.offsx; + const shifty = -this.offsy; + pp.ts.drawPath(path, shiftx, shifty, false); + pp.rs.drawPath(path, shiftx, shifty, true); + pp.bs.drawPath(path, shiftx, shifty, true); + pp.ls.drawPath(path, shiftx, shifty, true); + path.closePath(); + + this.ctx.clip(path); + + const srcx = pp.kx ? ((pp.kx - 0.5) * puzzle.scalex) : 0; + const srcy = pp.ky ? ((pp.ky - 0.5) * puzzle.scaley) : 0; + + const destx = (pp.kx ? 0 : puzzle.scalex / 2) + (pp.kx - this.pckxmin) * puzzle.scalex; + const desty = (pp.ky ? 0 : puzzle.scaley / 2) + (pp.ky - this.pckymin) * puzzle.scaley; + + let w = 2 * puzzle.scalex; + let h = 2 * puzzle.scaley; + if (srcx + w > puzzle.gameCanvas.width) w = puzzle.gameCanvas.width - srcx; + if (srcy + h > puzzle.gameCanvas.height) h = puzzle.gameCanvas.height - srcy; + + this.ctx.drawImage(puzzle.gameCanvas, srcx, srcy, w, h, + destx, desty, w, h); + + this.ctx.translate(puzzle.embossThickness / 2, -puzzle.embossThickness / 2); + this.ctx.lineWidth = puzzle.embossThickness; + this.ctx.strokeStyle = "rgba(0, 0, 0, 0.35)"; + this.ctx.stroke(path); + + this.ctx.translate(-puzzle.embossThickness, puzzle.embossThickness); + this.ctx.strokeStyle = "rgba(255, 255, 255, 0.35)"; + this.ctx.stroke(path); + this.ctx.restore(); + }); + + } + + moveTo(x, y) { + + this.x = x; + this.y = y; + this.canvas.style.left = x + 'px'; + this.canvas.style.top = y + 'px'; + } + + moveToInitialPlace() { + const puzzle = this.puzzle; + this.moveTo(puzzle.offsx + (this.pckxmin - 0.5) * puzzle.scalex, + puzzle.offsy + (this.pckymin - 0.5) * puzzle.scaley); + } + +} + +class Puzzle { + + + constructor(params) { + + this.autoStart = false; + + this.container = (typeof params.container == "string") ? + document.getElementById(params.container) : + params.container; + + + this.container.addEventListener("mousedown", event => { + event.preventDefault(); + events.push({ event: 'touch', position: this.relativeMouseCoordinates(event) }); + }); + this.container.addEventListener("touchstart", event => { + event.preventDefault(); + if (event.touches.length != 1) return; + let ev = event.touches[0]; + events.push({ event: 'touch', position: this.relativeMouseCoordinates(ev) }); + }, { passive: false }); + + this.container.addEventListener("mouseup", event => { + event.preventDefault(); + handleLeave(); + }); + this.container.addEventListener("touchend", handleLeave); + this.container.addEventListener("touchleave", handleLeave); + this.container.addEventListener("touchcancel", handleLeave); + + this.container.addEventListener("mousemove", event => { + event.preventDefault(); + + if (events.length && events[events.length - 1].event == "move") events.pop(); + events.push({ event: 'move', position: this.relativeMouseCoordinates(event) }) + }); + this.container.addEventListener("touchmove", event => { + event.preventDefault(); + if (event.touches.length != 1) return; + let ev = event.touches[0]; + if (events.length && events[events.length - 1].event == "move") events.pop(); + events.push({ event: 'move', position: this.relativeMouseCoordinates(ev) }); + }, { passive: false }); + + + this.gameCanvas = document.createElement('CANVAS'); + this.container.appendChild(this.gameCanvas) + + this.srcImage = new Image(); + this.imageLoaded = false; + this.srcImage.addEventListener("load", () => imageLoaded(this)); + + function handleLeave() { + events.push({ event: 'leave' }); // + } + + } + + getContainerSize() { + let styl = window.getComputedStyle(this.container); + + this.contWidth = parseFloat(styl.width); + this.contHeight = parseFloat(styl.height); + } + + create() { + + this.container.innerHTML = ""; + + this.getContainerSize(); + this.computenxAndny(); + + this.relativeHeight = (this.srcImage.naturalHeight / this.ny) / (this.srcImage.naturalWidth / this.nx); + + this.defineShapes({ coeffDecentr: 0.12, twistf: [twist0, twist1, twist2, twist3][document.getElementById("shape").value - 1] }); + + this.polyPieces = []; + this.pieces.forEach(row => row.forEach(piece => { + this.polyPieces.push(new PolyPiece(piece, this)); + })); + + arrayShuffle(this.polyPieces); + this.evaluateZIndex(); + + } + + + + computenxAndny() { + + let kx, ky, width = this.srcImage.naturalWidth, height = this.srcImage.naturalHeight, npieces = this.nbPieces; + let err, errmin = 1e9; + let ncv, nch; + + let nHPieces = mround(msqrt(npieces * width / height)); + let nVPieces = mround(npieces / nHPieces); + + + for (ky = 0; ky < 5; ky++) { + ncv = nVPieces + ky - 2; + for (kx = 0; kx < 5; kx++) { + nch = nHPieces + kx - 2; + err = nch * height / ncv / width; + err = (err + 1 / err) - 2; + err += mabs(1 - nch * ncv / npieces); + + if (err < errmin) { + errmin = err; + this.nx = nch; + this.ny = ncv; + } + } + } + + } + + + defineShapes(shapeDesc) { + + + let { coeffDecentr, twistf } = shapeDesc; + + const corners = []; + const nx = this.nx, ny = this.ny; + let np; + + for (let ky = 0; ky <= ny; ++ky) { + corners[ky] = []; + for (let kx = 0; kx <= nx; ++kx) { + corners[ky][kx] = new Point(kx + alea(-coeffDecentr, coeffDecentr), + ky + alea(-coeffDecentr, coeffDecentr)); + if (kx == 0) corners[ky][kx].x = 0; + if (kx == nx) corners[ky][kx].x = nx; + if (ky == 0) corners[ky][kx].y = 0; + if (ky == ny) corners[ky][kx].y = ny; + } + } + + this.pieces = []; + for (let ky = 0; ky < ny; ++ky) { + this.pieces[ky] = []; + for (let kx = 0; kx < nx; ++kx) { + this.pieces[ky][kx] = np = new Piece(kx, ky); + if (ky == 0) { + np.ts.points = [corners[ky][kx], corners[ky][kx + 1]]; + np.ts.type = "d"; + } else { + np.ts = this.pieces[ky - 1][kx].bs.reversed(); + } + np.rs.points = [corners[ky][kx + 1], corners[ky + 1][kx + 1]]; + np.rs.type = "d"; + if (kx < nx - 1) { + if (intAlea(2)) + twistf(np.rs, corners[ky][kx], corners[ky + 1][kx]); + else + twistf(np.rs, corners[ky][kx + 2], corners[ky + 1][kx + 2]); + } + if (kx == 0) { + np.ls.points = [corners[ky + 1][kx], corners[ky][kx]]; + np.ls.type = "d"; + } else { + np.ls = this.pieces[ky][kx - 1].rs.reversed() + } + np.bs.points = [corners[ky + 1][kx + 1], corners[ky + 1][kx]]; + np.bs.type = "d"; + if (ky < ny - 1) { + if (intAlea(2)) + twistf(np.bs, corners[ky][kx + 1], corners[ky][kx]); + else + twistf(np.bs, corners[ky + 2][kx + 1], corners[ky + 2][kx]); + } + } + } + + } + + + scale() { + + + const maxWidth = 0.95 * this.contWidth; + const maxHeight = 0.95 * this.contHeight; + + this.gameHeight = maxHeight; + this.gameWidth = this.gameHeight * this.srcImage.naturalWidth / this.srcImage.naturalHeight; + + if (this.gameWidth > maxWidth) { + this.gameWidth = maxWidth; + this.gameHeight = this.gameWidth * this.srcImage.naturalHeight / this.srcImage.naturalWidth; + } + + this.gameCanvas.width = this.gameWidth; + this.gameCanvas.height = this.gameHeight; + this.gameCtx = this.gameCanvas.getContext("2d"); + this.gameCtx.drawImage(this.srcImage, 0, 0, this.gameWidth, this.gameHeight); + + this.gameCanvas.classList.add("gameCanvas"); + this.gameCanvas.style.zIndex = 500; + + this.scalex = this.gameWidth / this.nx; + this.scaley = this.gameHeight / this.ny; + + this.pieces.forEach(row => { + row.forEach(piece => piece.scale(this)); + }); + + this.offsx = (this.contWidth - this.gameWidth) / 2; + this.offsy = (this.contHeight - this.gameHeight) / 2; + + + this.dConnect = mmax(10, mmin(this.scalex, this.scaley) / 10); + + this.embossThickness = mmin(2 + this.scalex / 200 * (5 - 2), 5); + + } + + relativeMouseCoordinates(event) { + + + const br = this.container.getBoundingClientRect(); + return { + x: event.clientX - br.x, + y: event.clientY - br.y + }; + } + + limitRectangle(rect) { + + + rect.x0 = mmin(mmax(rect.x0, -this.scalex / 2), this.contWidth - 1.5 * this.scalex); + rect.x1 = mmin(mmax(rect.x1, -this.scalex / 2), this.contWidth - 1.5 * this.scalex); + rect.y0 = mmin(mmax(rect.y0, -this.scaley / 2), this.contHeight - 1.5 * this.scaley); + rect.y1 = mmin(mmax(rect.y1, -this.scaley / 2), this.contHeight - 1.5 * this.scaley); + } + + spreadInRectangle(rect) { + this.limitRectangle(rect); + this.polyPieces.forEach(pp => + pp.moveTo(alea(rect.x0, rect.x1), alea(rect.y0, rect.y1)) + ); + } + + spreadSetInRectangle(set, rect) { + this.limitRectangle(rect); + set.forEach(pp => + pp.moveTo(alea(rect.x0, rect.x1), alea(rect.y0, rect.y1)) + ); + } + + optimInitial() { + + const minx = -this.scalex / 2; + const miny = -this.scaley / 2; + const maxx = this.contWidth - 1.5 * this.scalex; + const maxy = this.contHeight - 1.5 * this.scaley; + + let freex = this.contWidth - this.gameWidth; + let freey = this.contHeight - this.gameHeight; + + let where = [0, 0, 0, 0]; + let rects = []; + if (freex > 1.5 * this.scalex) { + where[1] = 1; + rects[1] = { + x0: this.gameWidth - 0.5 * this.scalex, + x1: maxx, + y0: miny, y1: maxy + }; + } + if (freex > 3 * this.scalex) { + where[3] = 1; + rects[3] = { + x0: minx, + x1: freex / 2 - 1.5 * this.scalex, + y0: miny, y1: maxy + }; + rects[1].x0 = this.contWidth - freex / 2 - 0.5 * this.scalex; + } + if (freey > 1.5 * this.scaley) { + where[2] = 1; + rects[2] = { + x0: minx, x1: maxx, + y0: this.gameHeight - 0.5 * this.scaley, + y1: this.contHeight - 1.5 * this.scaley + }; + } + if (freey > 3 * this.scaley) { + where[0] = 1; + rects[0] = { + x0: minx, x1: maxx, + y0: miny, + y1: freey / 2 - 1.5 * this.scaley + }; + rects[2].y0 = this.contHeight - freey / 2 - 0.5 * this.scaley; + } + if (where.reduce((sum, a) => sum + a) < 2) { + + if (freex - freey > 0.2 * this.scalex || where[1]) { + + this.spreadInRectangle({ + x0: this.gameWidth - this.scalex / 2, + x1: maxx, + y0: miny, + y1: maxy + }); + } else if (freey - freex > 0.2 * this.scalex || where[2]) { + + this.spreadInRectangle({ + x0: minx, + x1: maxx, + y0: this.gameHeight - this.scaley / 2, + y1: maxy + }); + } else { + if (this.gameWidth > this.gameHeight) { + + this.spreadInRectangle({ + x0: minx, + x1: maxx, + y0: this.gameHeight - this.scaley / 2, + y1: maxy + }); + + } else { + this.spreadInRectangle({ + x0: this.gameWidth - this.scalex / 2, + x1: maxx, + y0: miny, + y1: maxy + }); + } + } + return; + } + + let nrects = []; + rects.forEach(rect => { + nrects.push(rect); + }); + let k0 = 0 + const npTot = this.nx * this.ny; + for (let k = 0; k < nrects.length; ++k) { + let k1 = mround((k + 1) / nrects.length * npTot); + this.spreadSetInRectangle(this.polyPieces.slice(k0, k1), nrects[k]); + k0 = k1; + } + arrayShuffle(this.polyPieces); + this.evaluateZIndex(); + + } + + evaluateZIndex() { + + + for (let k = this.polyPieces.length - 1; k > 0; --k) { + if (this.polyPieces[k].pieces.length > this.polyPieces[k - 1].pieces.length) { + + [this.polyPieces[k], this.polyPieces[k - 1]] = [this.polyPieces[k - 1], this.polyPieces[k]]; + } + } + + this.polyPieces.forEach((pp, k) => { + pp.canvas.style.zIndex = k + 10; + }); + this.zIndexSup = this.polyPieces.length + 10; + } +} + + +let loadFile; +{ + + let options; + + let elFile = document.createElement('input'); + elFile.setAttribute('type', 'file'); + elFile.style.display = 'none'; + elFile.addEventListener("change", getFile); + + function getFile() { + + if (this.files.length == 0) { + + return; + } + let file = this.files[0]; + let reader = new FileReader(); + + reader.addEventListener('load', () => { + puzzle.srcImage.src = reader.result; + }); + reader.readAsDataURL(this.files[0]); + + } + + loadFile = function (ooptions) { + elFile.setAttribute("accept", "image/*"); + elFile.value = null; + elFile.click(); + + } +} + +function loadInitialFile() { + puzzle.srcImage.src = "/assets/images/JigsawPuzzle.jpg"; +} + +function imageLoaded(puzzle) { + events.push({ event: "srcImageLoaded" }); + puzzle.imageLoaded = true; + +} + +function fitImage(img, width, height) { + + + let wn = img.naturalWidth; + let hn = img.naturalHeight; + let w = width; + let h = w * hn / wn; + if (h > height) { + h = height; + w = h * wn / hn; + } + img.style.position = "absolute"; + img.style.width = w + "px"; + img.style.height = h + "px"; + img.style.top = "50%"; + img.style.left = "50%"; + img.style.transform = "translate(-50%,-50%)"; +} + +let animate; +let events = []; + +{ + let state = 0; + let moving; + let tmpImage; + + animate = function () { + requestAnimationFrame(animate); + + let event; + if (events.length) event = events.shift(); + if (event && event.event == "reset") state = 0; + if (event && event.event == "srcImageLoaded") state = 0; + + if (event && event.event == "resize") { + + puzzle.prevWidth = puzzle.contWidth; + puzzle.prevHeight = puzzle.contHeight; + puzzle.getContainerSize(); + if (state == 15 || state > 60) { + puzzle.getContainerSize(); + fitImage(tmpImage, puzzle.contWidth * 0.95, puzzle.contHeight * 0.95); + } + else if (state >= 25) { + puzzle.prevGameWidth = puzzle.gameWidth; + puzzle.prevGameHeight = puzzle.gameHeight; + puzzle.scale(); + let reScale = puzzle.contWidth / puzzle.prevWidth; + puzzle.polyPieces.forEach(pp => { + + let nx = puzzle.contWidth / 2 - (puzzle.prevWidth / 2 - pp.x) * reScale; + let ny = puzzle.contHeight / 2 - (puzzle.prevHeight / 2 - pp.y) * reScale; + + nx = mmin(mmax(nx, -puzzle.scalex / 2), puzzle.contWidth - 1.5 * puzzle.scalex); + ny = mmin(mmax(ny, -puzzle.scaley / 2), puzzle.contHeight - 1.5 * puzzle.scaley); + + pp.moveTo(nx, ny); + pp.drawImage(); + + }); + } + + return; + } + + switch (state) { + + case 0: + state = 10; + break; + + case 10: + if (!puzzle.imageLoaded) return; + + puzzle.container.innerHTML = ""; + tmpImage = document.createElement("img"); + tmpImage.src = puzzle.srcImage.src; + puzzle.getContainerSize(); + fitImage(tmpImage, puzzle.contWidth * 0.95, puzzle.contHeight * 0.95); + tmpImage.style.boxShadow = "4px 4px 4px rgba(0, 0, 0, 0.5)"; + puzzle.container.appendChild(tmpImage); + state = 15; + break; + + + case 15: + if (autoStart) event = { event: "nbpieces", nbpieces: 12 }; + autoStart = false; + if (!event) return; + if (event.event == "nbpieces") { + puzzle.nbPieces = event.nbpieces; + state = 20; + } else if (event.event == "srcImageLoaded") { + state = 10; + return; + } else return; + + case 20: + menu.close(); + puzzle.create(); + puzzle.scale(); + puzzle.polyPieces.forEach(pp => { + pp.drawImage(); + pp.moveToInitialPlace(); + }); + puzzle.gameCanvas.style.top = puzzle.offsy + "px"; + puzzle.gameCanvas.style.left = puzzle.offsx + "px"; + puzzle.gameCanvas.style.display = "block"; + state = 25; + break; + + case 25: + puzzle.gameCanvas.style.display = "none"; + puzzle.polyPieces.forEach(pp => { + pp.canvas.classList.add("moving"); + }); + state = 30; + break; + + case 30: + puzzle.optimInitial(); + + + setTimeout(() => events.push({ event: "finished" }), 1200); + state = 35; + break; + + case 35: + if (!event || event.event != "finished") return; + puzzle.polyPieces.forEach(pp => { + pp.canvas.classList.remove("moving"); + }); + + state = 50; + + break; + + case 50: + if (!event) return; + if (event.event == "nbpieces") { + puzzle.nbPieces = event.nbpieces; + state = 20; + return; + } + if (event.event != "touch") return; + moving = { + xMouseInit: event.position.x, + yMouseInit: event.position.y + } + + + for (let k = puzzle.polyPieces.length - 1; k >= 0; --k) { + let pp = puzzle.polyPieces[k]; + if (pp.ctx.isPointInPath(pp.path, event.position.x - pp.x, event.position.y - pp.y)) { + moving.pp = pp; + moving.ppXInit = pp.x; + moving.ppYInit = pp.y; + + puzzle.polyPieces.splice(k, 1); + puzzle.polyPieces.push(pp); + pp.canvas.style.zIndex = puzzle.zIndexSup; + state = 55; + return; + } + + } + break; + + case 55: + if (!event) return; + switch (event.event) { + case "move": + moving.pp.moveTo(event.position.x - moving.xMouseInit + moving.ppXInit, + event.position.y - moving.yMouseInit + moving.ppYInit); + break; + case "leave": + + let doneSomething; + do { + doneSomething = false; + for (let k = puzzle.polyPieces.length - 1; k >= 0; --k) { + let pp = puzzle.polyPieces[k]; + if (pp == moving.pp) continue; + if (moving.pp.ifNear(pp)) { + + if (pp.pieces.length > moving.pp.pieces.length) { + pp.merge(moving.pp); + moving.pp = pp; + } else { + moving.pp.merge(pp); + } + doneSomething = true; + break; + } + } + + } while (doneSomething); + + puzzle.evaluateZIndex(); + state = 50; + if (puzzle.polyPieces.length == 1) state = 60; // won! + return; + } + + break; + + case 60: + puzzle.container.innerHTML = ""; + puzzle.getContainerSize(); + fitImage(tmpImage, puzzle.contWidth * 0.95, puzzle.contHeight * 0.95); + tmpImage.style.boxShadow = "4px 4px 4px rgba(0, 0, 0, 0.5)"; + + tmpImage.style.left = (puzzle.polyPieces[0].x + puzzle.scalex / 2 + puzzle.gameWidth / 2) / puzzle.contWidth * 100 + "%"; + tmpImage.style.top = (puzzle.polyPieces[0].y + puzzle.scaley / 2 + puzzle.gameHeight / 2) / puzzle.contHeight * 100 + "%"; + + tmpImage.classList.add("moving"); + setTimeout(() => tmpImage.style.top = tmpImage.style.left = "50%", 0); + puzzle.container.appendChild(tmpImage); + state = 65; + menu.open(); + + case 65: + if (event && event.event == "nbpieces") { + puzzle.nbPieces = event.nbpieces; + state = 20; + return; + } + break; + + case 9999: break; + default: + let st = state; + state = 9999; + throw ("oops, unknown state " + st); + } + } +} + +let menu = (function () { + let menu = { items: [] }; + document.querySelectorAll("#menu li").forEach(menuEl => { + let kItem = menu.items.length; + let item = { element: menuEl, kItem: kItem }; + menu.items[kItem] = item; + + }); + + menu.open = function () { + menu.items.forEach(item => item.element.style.display = "block"); + menu.opened = true; + } + menu.close = function () { + menu.items.forEach((item, k) => { + if (k > 0) item.element.style.display = "none"; + }); + menu.opened = false; + } + menu.items[0].element.addEventListener("click", () => { + if (menu.opened) menu.close(); else menu.open() + }); + menu.items[1].element.addEventListener("click", loadInitialFile); + menu.items[2].element.addEventListener("click", loadFile); + menu.items[3].element.addEventListener("click", () => { }); + for (let k = 4; k < menu.items.length; ++k) { + menu.items[k].element.addEventListener("click", () => events.push({ event: "nbpieces", nbpieces: [12, 25, 50, 100, 200][k - 4] })); + } + return menu; +})(); + +menu.close(); + +window.addEventListener("resize", event => { + if (events.length && events[events.length - 1].event == "resize") return;; + events.push({ event: "resize" }); +}); + +puzzle = new Puzzle({ container: "forPuzzle" }); +autoStart = isMiniature(); + +loadInitialFile(); +requestAnimationFrame(animate); diff --git a/Games/Jigsaw_Puzzle/style.css b/Games/Jigsaw_Puzzle/style.css new file mode 100644 index 0000000000..a385c165d0 --- /dev/null +++ b/Games/Jigsaw_Puzzle/style.css @@ -0,0 +1,58 @@ +body { + font-family: Arial, Helvetica, "Liberation Sans", FreeSans, sans-serif; + background-color: #fff; + margin: 0; + padding: 0; + border-width: 0; + cursor: pointer; + } + + #menu { + position: relative; + list-style-type: none; + padding-left: 5px; + z-index: 1000; + /* 1 */ + display: inline-block; + text-align: center; + } + + #menu li { + margin: 2px; + padding: 4px 10px; + border-radius: 5px; + background-color: #ffd580; + } + + #menu li:hover { + background-color: #ffDD60; + } + + #forPuzzle { + position: absolute; + width: 95vw; + height: 95vh; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #ffffdd; + overflow: hidden; + } + + .polypiece { + display: block; + overflow: hidden; + position: absolute; + } + + .moving { + transition-property: top, left; + transition-duration: 1s; + transition-timing-function: linear; + } + + .gameCanvas { + display: none; + overflow: hidden; + position: absolute; + } diff --git a/Games/King_Of_Pirates_Quiz/README.md b/Games/King_Of_Pirates_Quiz/README.md new file mode 100644 index 0000000000..e239f34954 --- /dev/null +++ b/Games/King_Of_Pirates_Quiz/README.md @@ -0,0 +1,48 @@ +# One Piece Quiz + +This is a simple quiz application based on the popular anime and manga series, One Piece. The quiz tests your knowledge of the series with a set of questions. The application is built using HTML, CSS, and JavaScript. + +## Table of Contents + +- [Project Overview](#project-overview) +- [Features](#features) +- [Technologies Used](#technologies-used) +- [Usage](#usage) +- [Contributing](#contributing) + + +## Project Overview + +The One Piece Quiz is a web application that presents the user with a series of questions related to One Piece. Each question has multiple choice answers, and the user can select the correct answer to proceed to the next question. At the end of the quiz, the user receives a score based on their answers. + +## Features + +- A series of multiple choice questions related to One Piece +- Next question button to proceed through the quiz +- Score calculation and display at the end of the quiz +- Responsive design for various screen sizes + +## Technologies Used + +- HTML +- CSS +- JavaScript +- Google Fonts + + + +## Usage + +1. Open the `index.html` file in your web browser. +2. Click the "Next Question" button to proceed through the quiz. +3. Select the correct answer for each question. +4. At the end of the quiz, view your score. + + + +## Contributing + +Contributions are welcome! If you would like to contribute to this project, please fork the repository and submit a pull request with your changes. Ensure that your code follows the existing code style and includes tests where applicable. + + + diff --git a/Games/King_Of_Pirates_Quiz/background.jpg b/Games/King_Of_Pirates_Quiz/background.jpg new file mode 100644 index 0000000000..d02228d699 Binary files /dev/null and b/Games/King_Of_Pirates_Quiz/background.jpg differ diff --git a/Games/King_Of_Pirates_Quiz/index.html b/Games/King_Of_Pirates_Quiz/index.html new file mode 100644 index 0000000000..f1a00d71dd --- /dev/null +++ b/Games/King_Of_Pirates_Quiz/index.html @@ -0,0 +1,26 @@ + + + + + +One Piece Quiz + + + + + + +
+

One Piece Quiz

+ +
+ +
+ +
+ +
+
+ + + diff --git a/Games/King_Of_Pirates_Quiz/script.js b/Games/King_Of_Pirates_Quiz/script.js new file mode 100644 index 0000000000..790d14e68f --- /dev/null +++ b/Games/King_Of_Pirates_Quiz/script.js @@ -0,0 +1,206 @@ +const questions = [ + { + question: "Who is the captain of the Straw Hat Pirates?", + answers: ["Luffy", "Zoro", "Sanji", "Nami"], + correctAnswer: "Luffy" + }, + { + question: "What is the name of Luffy's signature attack?", + answers: ["Gum-Gum Pistol", "Gum-Gum Bazooka", "Gum-Gum Gatling", "Gum-Gum Red Hawk"], + correctAnswer: "Gum-Gum Gatling" + }, + { + question: "Who is known as the 'Pirate Hunter'?", + answers: ["Luffy", "Zoro", "Sanji", "Nami"], + correctAnswer: "Zoro" + }, + { + question: "Who is known as the 'King of the Pirates'?", + answers: ["Shanks", "Whitebeard", "Roger", "Kaido"], + correctAnswer: "Roger" + + }, + { + question: "What is the name of the Devil Fruit that Luffy eats?", + answers: ["Gum-Gum Fruit", "Fire-Fire Fruit", "Ice-Ice Fruit", "Dark-Dark Fruit"], + correctAnswer: "Gum-Gum Fruit" + + }, + { + question: "Who is Luffy's adoptive brother?", + answers: ["Zoro", "Ace", "Sanji", "Law"], + correctAnswer: "Ace" + + }, + + + { + question: "What is the name of Luffy's ship?", + answers: ["Polar Tang", "Going Merry", "Moby Dick", "Red Force"], + correctAnswer: "Going Merry" + + }, + { + question: "What is Zoro's dream?", + answers: ["To become the greatest swordsman", "To find the One Piece", "To become a famous chef", "To become a doctor"], + correctAnswer: "To become the greatest swordsman" + + }, + { + question: "Who is the creator of the One Piece manga and anime series?", + answers: ["Eiichiro Oda", "Akira Toriyama", "Masashi Kishimoto", "Tite Kubo"], + correctAnswer: "Eiichiro Oda" + + }, + { + question: "Who is the doctor of the Straw Hat Pirates?", + answers: ["Chopper", "Law", "Franky", "Brook"], + correctAnswer: "Chopper" + }, + { + question: "What is the name of the island where Luffy first meets the Warlord Dracule Mihawk?", + answers: ["Water 7", "Loguetown", "Sabaody Archipelago", "Baratie"], + correctAnswer: "Baratie" + + }, + + { + question: "Which character has the highest known bounty in the One Piece series?", + answers: ["Monkey D. Luffy", "Charlotte Katakuri", "Edward Newgate (Whitebeard)", "Marshall D. Teach (Blackbeard)"], + correctAnswer: "Edward Newgate (Whitebeard)" + + }, + + { + question: "Who is the original owner of the Straw Hat that Luffy wears?", + answers: ["Gol D. Roger", "Shanks", "Rayleigh", "Whitebeard"], + correctAnswer: "Gol D. Roger" + }, + { + question: "What is the name of the island where the One Piece treasure is said to be located?", + answers: ["Skypiea", "Raftel", "Wano", "Elbaf"], + correctAnswer: "Raftel" + }, + { + question: "Which character can transform into a dragon?", + answers: ["Marco", "Kaido", "Law", "Kin'emon"], + correctAnswer: "Kaido" + }, + { + question: "What is the name of Luffy's first bounty poster?", + answers: ["30,000,000 Berries", "100,000,000 Berries", "1,000,000 Berries", "10,000,000 Berries"], + correctAnswer: "30,000,000 Berries" + }, + { + question: "Who is the captain of the Heart Pirates?", + answers: ["Trafalgar Law", "Eustass Kid", "X Drake", "Killer"], + correctAnswer: "Trafalgar Law" + }, + { + question: "What is the name of the special technique used by Zoro, where he creates multiple sword illusions?", + answers: ["Oni Giri", "Tatsumaki", "Santoryu Ogi: Sanzen Sekai", "Asura"], + correctAnswer: "Santoryu Ogi: Sanzen Sekai" + }, + { + question: "Who was the first character to defeat Luffy in a one-on-one fight?", + answers: ["Crocodile", "Arlong", "Enel", "Mihawk"], + correctAnswer: "Crocodile" + }, + { + question: "What is the name of Sanji's family of assassins?", + answers: ["Baroque Works", "Big Mom Pirates", "Germa 66", "Beasts Pirates"], + correctAnswer: "Germa 66" + }, + { + question: "Which character is known as the 'Magician'?", + answers: ["Buggy", "Blackbeard", "Kizaru", "Magellan"], + correctAnswer: "Magellan" + }, + { + question: "Who is the current Fleet Admiral of the Marines?", + answers: ["Sengoku", "Aokiji", "Akainu", "Kizaru"], + correctAnswer: "Akainu" + }, + { + question: "What is the name of the Devil Fruit eaten by Trafalgar Law?", + answers: ["Op-Op Fruit", "Soul-Soul Fruit", "Room-Room Fruit", "Ope-Ope Fruit"], + correctAnswer: "Ope-Ope Fruit" + }, + { + question: "Who is the captain of the Blackbeard Pirates?", + answers: ["Blackbeard", "Shiryu", "Burgess", "Van Augur"], + correctAnswer: "Blackbeard" + }, + { + question: "What is the name of the weapon used by Franky after the timeskip?", + answers: ["Coup de Vent", "General Cannon", "Iron Pirate General Franky", "Franky Radical Beam"], + correctAnswer: "Iron Pirate General Franky" + } + +]; +let currentQuestion = 0; +let score = 0; +let wrongAnswers = []; + +const questionContainer = document.getElementById('question-container'); +const nextButton = document.getElementById('next-btn'); +const resultContainer = document.getElementById('result'); + +function displayQuestion() { + const currentQ = questions[currentQuestion]; + questionContainer.innerHTML = ` +

${currentQ.question}

+
    + ${currentQ.answers.map(answer => `
  • ${answer}
  • `).join('')} +
+ `; +} + +function checkAnswer() { + const selectedAnswer = document.querySelector('input[name="answer"]:checked'); + if (!selectedAnswer) return; + + if (selectedAnswer.value === questions[currentQuestion].correctAnswer) { + score++; + } else { + wrongAnswers.push({ + question: questions[currentQuestion].question, + correctAnswer: questions[currentQuestion].correctAnswer, + userAnswer: selectedAnswer.value + }); + } + + currentQuestion++; + selectedAnswer.checked = false; + + if (currentQuestion < questions.length) { + displayQuestion(); + } else { + showResult(); + } +} + +function showResult() { + questionContainer.innerHTML = ''; + nextButton.style.display = 'none'; + + resultContainer.innerHTML = `

Your Score: ${score}/${questions.length}

`; + if (wrongAnswers.length > 0) { + resultContainer.innerHTML += '

Incorrect Answers:

'; + wrongAnswers.forEach(wrong => { + resultContainer.innerHTML += ` +

Question: ${wrong.question}

+

Your Answer: ${wrong.userAnswer}

+

Correct Answer: ${wrong.correctAnswer}

+ `; + }); + } +} + +displayQuestion(); + +nextButton.addEventListener('click', function() { + this.classList.add('button-clicked'); + checkAnswer(); +}); + \ No newline at end of file diff --git a/Games/King_Of_Pirates_Quiz/styles.css b/Games/King_Of_Pirates_Quiz/styles.css new file mode 100644 index 0000000000..a60606197d --- /dev/null +++ b/Games/King_Of_Pirates_Quiz/styles.css @@ -0,0 +1,43 @@ +body { + font-family: Arial, sans-serif; + + } + .heading-container{ + font-family: "Press Start 2P", system-ui; + font-weight: 400; + font-style: normal; + align-self: center; + margin-left: 27%; + font-size: 30px; + + } + + .quiz-container { + max-width: 600px; + margin: 20px auto; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + background-color: rgba(255, 255, 255, 0.7); + margin-top: 225px; + align-items: center; + font-family: "Press Start 2P", system-ui; + font-weight: 400; + font-style: normal; + } + + button { + padding: 10px 20px; + margin-top: 10px; + cursor: pointer; + font-family: "Press Start 2P", system-ui; + font-weight: 400; + font-style: normal; + background-color: #23407b;; + } + + button:hover { + background-color: #e48d30; + color: #080808; + } + \ No newline at end of file diff --git a/Games/Madlibs/README.md b/Games/Madlibs/README.md new file mode 100644 index 0000000000..39ee6b0c79 --- /dev/null +++ b/Games/Madlibs/README.md @@ -0,0 +1,39 @@ +# **Madlibs** + +--- + +
+ +## **Description 📃** + +- Welcome to the Mad Libs Game, a fun and interactive word game that lets you create hilarious and unique stories by filling in the blanks! Simply enter a series of words—nouns, verbs, adjectives, and adverbs—and watch as your chosen words are placed into a pre-written story template. The result is a whimsical and often absurd tale that is sure to make you laugh. Perfect for parties, family gatherings, or just a bit of creative fun on your own, this game is a great way to enjoy some light-hearted entertainment. Get ready to unleash your imagination and see where the story takes you! + + + +## **Functionalities 🎮** + +- Multiple input fields for various parts of speech (nouns, verbs, adjectives, adverbs) to fill in the blanks for the story. +- A simple and intuitive form interface for entering words. +- Generates a unique story based on the user's input words. +- A button to submit the form and generate the story dynamically. +- A section to display the generated story, which only appears after the story is created. +- Easily customizable story template to create different versions or extend the game with additional input fields. + +
+ +## **How to play? 🕹️** + +1. Fill in each input field with the requested type of word (noun, verb, adjective, adverb, etc.). Be creative and have fun with your choices! +2. Once you have filled in all the fields, click the "Generate Mad Lib" button. +3. After clicking the button, your custom Mad Libs story will appear below the form. Enjoy reading the hilarious and unique story that you created! +4. Want to create another story? Simply change the words in the input fields and click the "Generate Mad Lib" button again to see a new story. + + +
+ +## **Screenshots 📸** + +![image](https://github.com/AaryanManghnani/GameZone/blob/New-Game-Madlibs/assets/images/Madlibs.png) + + +
diff --git a/Games/Madlibs/index.html b/Games/Madlibs/index.html new file mode 100644 index 0000000000..39df14ba41 --- /dev/null +++ b/Games/Madlibs/index.html @@ -0,0 +1,47 @@ + + + + + + Mad Libs Game + + + +
+

Mad Libs Game

+
+ +

+ + +

+ + +

+ + +

+ + +

+ + +

+ + +

+ + +

+ + +
+ + +
+ + + diff --git a/Games/Madlibs/script.js b/Games/Madlibs/script.js new file mode 100644 index 0000000000..50e28845c5 --- /dev/null +++ b/Games/Madlibs/script.js @@ -0,0 +1,22 @@ +function generateMadLib() { + // Get the values from the form + const noun1 = document.getElementById('noun1').value; + const verb1 = document.getElementById('verb1').value; + const adjective1 = document.getElementById('adjective1').value; + const adverb1 = document.getElementById('adverb1').value; + const noun2 = document.getElementById('noun2').value; + const verb2 = document.getElementById('verb2').value; + const adjective2 = document.getElementById('adjective2').value; + const adverb2 = document.getElementById('adverb2').value; + + // Create the story + const story = `Once upon a time, there was a ${adjective1} ${noun1} that loved to ${verb1} ${adverb1}. + Every morning, it would wake up and ${verb2} with its ${adjective2} ${noun2}. + One day, they decided to go on an adventure together. They ${verb1} through the forest and ${verb2} over the mountains, + always ${adverb1} and ${adverb2}. + By the end of the day, they were tired but happy, knowing they had experienced something truly ${adjective1}.`; + + // Display the story + document.getElementById('madLibStory').textContent = story; + document.getElementById('story').classList.remove('hidden'); +} diff --git a/Games/Madlibs/style.css b/Games/Madlibs/style.css new file mode 100644 index 0000000000..e5354fde7f --- /dev/null +++ b/Games/Madlibs/style.css @@ -0,0 +1,63 @@ +body { + font-family: Arial, sans-serif; + background-color: #f4f4f4; + margin: 0; + padding: 20px; + display: flex; + justify-content: center; + align-items: flex-start; + min-height: 100vh; + box-sizing: border-box; +} + +.container { + background-color: white; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + text-align: center; + max-width: 400px; + width: 100%; +} + +.hidden { + display: none; +} + +h1 { + margin-bottom: 20px; +} + +form { + margin-bottom: 20px; +} + +label { + display: block; + margin-bottom: 5px; +} + +input { + width: calc(100% - 20px); + padding: 10px; + margin-bottom: 15px; + border: 1px solid #ccc; + border-radius: 5px; +} + +button { + padding: 10px 20px; + border: none; + background-color: #28a745; + color: white; + border-radius: 5px; + cursor: pointer; +} + +button:hover { + background-color: #218838; +} + +#story { + margin-top: 20px; +} \ No newline at end of file diff --git a/Games/Magic_8_ball/Readme.md b/Games/Magic_8_ball/Readme.md new file mode 100644 index 0000000000..29fcadfc46 --- /dev/null +++ b/Games/Magic_8_ball/Readme.md @@ -0,0 +1,25 @@ +![alt preview image](./asset/Magic_8_ball.png) + +# **MAGIC 8 BALL** + +## **Description 📃** + +Ask the Magical 8 Ball fortune teller yes or no questions for accurate predictions about your future! + +## **functionalities 🎮** +- Ask your Questions +- Get predicted Answer + +## **How to play? 🕹️** + +- Enter your question in the input textarea +- Press on the ASK button +- View Magic ball prediction +- Press CLEAR button to clear the textarea and ask another question! + + + + + + + diff --git a/Games/Magic_8_ball/asset/Magic_8_ball.mp4 b/Games/Magic_8_ball/asset/Magic_8_ball.mp4 new file mode 100644 index 0000000000..7eaa3cea23 Binary files /dev/null and b/Games/Magic_8_ball/asset/Magic_8_ball.mp4 differ diff --git a/Games/Magic_8_ball/asset/Magic_8_ball.png b/Games/Magic_8_ball/asset/Magic_8_ball.png new file mode 100644 index 0000000000..5834d94fe6 Binary files /dev/null and b/Games/Magic_8_ball/asset/Magic_8_ball.png differ diff --git a/Games/Magic_8_ball/asset/readme.md b/Games/Magic_8_ball/asset/readme.md new file mode 100644 index 0000000000..ef237787d8 --- /dev/null +++ b/Games/Magic_8_ball/asset/readme.md @@ -0,0 +1 @@ +Containes asset used on readme page page of this game repository! diff --git a/Games/Magic_8_ball/index.html b/Games/Magic_8_ball/index.html new file mode 100644 index 0000000000..0a1b374e34 --- /dev/null +++ b/Games/Magic_8_ball/index.html @@ -0,0 +1,52 @@ + + + + + + Document + + + + + +

MAGIC 8 BALL🔮

+
+
+
💤
+
+
+ +

+
+
+ +
+
+ +
+
+
+
+ +
+

+ 🪄Created By + Monika with 💜 + View on + Github + 🟠 GSSOC'24 , + GameZoneProject 🎮 +

+
+ + diff --git a/Games/Magic_8_ball/script.js b/Games/Magic_8_ball/script.js new file mode 100644 index 0000000000..09cc5892e9 --- /dev/null +++ b/Games/Magic_8_ball/script.js @@ -0,0 +1,59 @@ +function clearMagicBall() { + document.querySelector("#response").innerHTML = "💤"; +} + +function clearText() { + document.querySelector("textarea").value = ""; +} + +function ToggleAnimation() { + var magic_ball_class = document.querySelector(".magic-ball"); + magic_ball_class.classList.contains("animate_ball") + ? magic_ball_class.classList.remove("animate_ball") + : magic_ball_class.classList.add("animate_ball"); +} + +function showAnswer() { + var answers = [ + "It is certain", + "It is decidedly so", + "Without a doubt", + "Yes definitely", + "You may rely on it", + "As I see it, yes", + "Most likely", + "Outlook good", + "Yes", + "Signs point to yes", + "Ask again later", + "Don't count on it", + "My reply is no", + "My sources say no", + "Outlook not so good", + "Very doubtful", + ]; + + var magic_n = Math.floor(Math.random() * answers.length); + // alert(magic_n); + setTimeout(() => { + ToggleAnimation(); + document.querySelector("#response").innerHTML = "" + answers[magic_n]; + }, 3000); +} + +function AskMagicBall(event) { + var user_text = document.querySelector("#user-text").value; + // alert(user_text); + if (user_text == "" || user_text == " " || user_text.length <= 3) { + alert("invalid input💭...ask question with more than 3 word!"); + } else { + clearMagicBall(); + ToggleAnimation(); + showAnswer(); + } +} +document.querySelector("#ask").addEventListener("click", AskMagicBall); +document.querySelector("#clear").addEventListener("click", () => { + clearMagicBall(); + clearText(); +}); diff --git a/Games/Magic_8_ball/style.css b/Games/Magic_8_ball/style.css new file mode 100644 index 0000000000..583d3dd762 --- /dev/null +++ b/Games/Magic_8_ball/style.css @@ -0,0 +1,163 @@ +html { + width: 100%; + height: 100%; + margin: 0; + padding: 0; +} + +h1 { + font-size: 45px; +} + +body { + background: linear-gradient(rgb(115, 182, 254), rgb(198, 255, 198)); + text-align: center; + font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; +} + +a { + text-decoration: none; + color: blueviolet; +} + +a:hover { + text-decoration: underline; +} + +.container { + display: flex; + justify-content: center; + column-gap: 5%; + padding: 30px 0; + align-items: center; +} + +.magic-ball { + width: 200px; + height: 200px; + font-size: 21px; + font-weight: 700; + color: rgb(56, 25, 56); + background-color: rgb(255, 247, 190); + display: flex; + align-items: center; + justify-content: center; + border: 70px solid rgb(56, 25, 56); + border-radius: 50%; +} + +.animate_ball { + background: conic-gradient(from var(--a), + rgb(121, 83, 130) 20%, + rgb(3, 69, 66) 70%, + rgb(118, 55, 150) 100%); + + animation: animate 1s linear infinite; +} + +.buttons { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px; +} + +button, +textarea { + transition: transform 1s ease, opacity 1s ease !important; + padding: 10px 20px; + border-radius: 10px; + border: none; + background: whitesmoke; + color: turquoise; + font-weight: 700; + font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; +} + +button:hover { + color: rgb(162, 232, 0); + font-weight: 700; +} + +textarea { + border: 4px solid rgb(3, 206, 148); + width: 300px; + height: 100px; +} + +textarea:focus { + outline: none; + border: 4px solid rgb(172, 70, 255); +} + +.question { + width: fit-content; + box-shadow: 0 0 3px rgb(132, 132, 132); + border-radius: 8px; + padding: 3%; +} + +.multi-color-border { + width: fit-content; + margin: 0 auto; + padding: 3px; + border-radius: 8px; + background: conic-gradient(from var(--a), + rgb(219, 208, 2) 20%, + rgb(0, 178, 249) 70%, + rgb(219, 208, 2) 100%); + animation: animate 5s linear infinite; +} + +.multi-color-border:hover { + transform: scale(1.1); + box-shadow: 0px 0px 5px rgb(234, 231, 255); + +} + +footer { + margin: 20px auto; + border-radius: 8px; + padding: 5px 10px; + max-width: fit-content; + box-shadow: 0 0 3px rgb(132, 132, 132); +} + +@media (max-width:780px) { + .container { + width: 100%; + display: flex; + row-gap: 30px; + align-items: center; + justify-content: center; + flex-direction: column; + } + + .magic-ball { + width: 200px; + height: 200px; + border: 40px solid rgb(56, 25, 56); + } + + textarea { + border: 4px solid rgb(3, 206, 148); + width: 250px; + height: 50px; + } +} + +@property --a { + syntax: ""; + inherits: false; + initial-value: 0deg; +} + +@keyframes animate { + 0% { + --a: 0deg; + } + + 100% { + --a: 360deg; + } +} \ No newline at end of file diff --git a/Games/Makeover_Game/README.md b/Games/Makeover_Game/README.md new file mode 100644 index 0000000000..a31a560e9a --- /dev/null +++ b/Games/Makeover_Game/README.md @@ -0,0 +1,26 @@ +# **Makeover Game** +--- + +## **Description 📃** + +The Makeover Game is a fun and interactive browser-based game where players can design and customize outfits for a virtual character. Players can mix and match different clothing items, accessories, and hairstyles to create their perfect look. + +## **Functionalities 🎮** + +1. Choose from a variety of clothing items including tops, bottoms, dresses, and shoes. +2. Customize hairstyles and hair colors. +3. Save and download your customized outfit. +4. Share your design with friends on social media. + +## **How to play? 🕹️** + +1. Start the Game: Open the game in your browser and wait for it to load. +2. Select an Item: Click on the clothing categories to browse through available items. +3. Mix and Match: You can change the brightness, hue and saturation. +4. Customize Further: Use the options to change the character's hairstyle and skin colour. +5. Save Your Design: Once you're happy with the outfit, click the "Capture" button to save an image of your design. +6. Download and Share: Download the image to your device and share it with your friends. + +## **Screenshots 📸** +![image](https://github.com/abckhush/GameZone/assets/127378920/b155d557-eff1-4731-b3ac-1e89080be0cf) +![image](https://github.com/abckhush/GameZone/assets/127378920/b9ec77b4-1eb8-451e-b390-c626cd6b93d5) diff --git a/Games/Makeover_Game/img/base/base_1.png b/Games/Makeover_Game/img/base/base_1.png new file mode 100644 index 0000000000..c2afa7bf91 Binary files /dev/null and b/Games/Makeover_Game/img/base/base_1.png differ diff --git a/Games/Makeover_Game/img/base/base_10.png b/Games/Makeover_Game/img/base/base_10.png new file mode 100644 index 0000000000..f54f50227a Binary files /dev/null and b/Games/Makeover_Game/img/base/base_10.png differ diff --git a/Games/Makeover_Game/img/base/base_2.png b/Games/Makeover_Game/img/base/base_2.png new file mode 100644 index 0000000000..bbb81ae8dc Binary files /dev/null and b/Games/Makeover_Game/img/base/base_2.png differ diff --git a/Games/Makeover_Game/img/base/base_3.png b/Games/Makeover_Game/img/base/base_3.png new file mode 100644 index 0000000000..c50c7113a1 Binary files /dev/null and b/Games/Makeover_Game/img/base/base_3.png differ diff --git a/Games/Makeover_Game/img/base/base_4.png b/Games/Makeover_Game/img/base/base_4.png new file mode 100644 index 0000000000..41fedc704c Binary files /dev/null and b/Games/Makeover_Game/img/base/base_4.png differ diff --git a/Games/Makeover_Game/img/base/base_5.png b/Games/Makeover_Game/img/base/base_5.png new file mode 100644 index 0000000000..96da9c5ca4 Binary files /dev/null and b/Games/Makeover_Game/img/base/base_5.png differ diff --git a/Games/Makeover_Game/img/base/base_6.png b/Games/Makeover_Game/img/base/base_6.png new file mode 100644 index 0000000000..c72d0c3af8 Binary files /dev/null and b/Games/Makeover_Game/img/base/base_6.png differ diff --git a/Games/Makeover_Game/img/base/base_7.png b/Games/Makeover_Game/img/base/base_7.png new file mode 100644 index 0000000000..908889e1de Binary files /dev/null and b/Games/Makeover_Game/img/base/base_7.png differ diff --git a/Games/Makeover_Game/img/base/base_8.png b/Games/Makeover_Game/img/base/base_8.png new file mode 100644 index 0000000000..76a1ff456c Binary files /dev/null and b/Games/Makeover_Game/img/base/base_8.png differ diff --git a/Games/Makeover_Game/img/base/base_9.png b/Games/Makeover_Game/img/base/base_9.png new file mode 100644 index 0000000000..4232e4d542 Binary files /dev/null and b/Games/Makeover_Game/img/base/base_9.png differ diff --git a/Games/Makeover_Game/img/bg.png b/Games/Makeover_Game/img/bg.png new file mode 100644 index 0000000000..0435810674 Binary files /dev/null and b/Games/Makeover_Game/img/bg.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_1.png b/Games/Makeover_Game/img/bottom/bottom_1.png new file mode 100644 index 0000000000..dc55017050 Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_1.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_10.png b/Games/Makeover_Game/img/bottom/bottom_10.png new file mode 100644 index 0000000000..be18696e2b Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_10.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_2.png b/Games/Makeover_Game/img/bottom/bottom_2.png new file mode 100644 index 0000000000..7418048d2d Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_2.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_3.png b/Games/Makeover_Game/img/bottom/bottom_3.png new file mode 100644 index 0000000000..c3ed98109f Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_3.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_4.png b/Games/Makeover_Game/img/bottom/bottom_4.png new file mode 100644 index 0000000000..61b0c89c09 Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_4.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_5.png b/Games/Makeover_Game/img/bottom/bottom_5.png new file mode 100644 index 0000000000..a5b4d2f0a3 Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_5.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_6.png b/Games/Makeover_Game/img/bottom/bottom_6.png new file mode 100644 index 0000000000..e68a8b7457 Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_6.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_7.png b/Games/Makeover_Game/img/bottom/bottom_7.png new file mode 100644 index 0000000000..2865d9df95 Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_7.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_8.png b/Games/Makeover_Game/img/bottom/bottom_8.png new file mode 100644 index 0000000000..85344c479f Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_8.png differ diff --git a/Games/Makeover_Game/img/bottom/bottom_9.png b/Games/Makeover_Game/img/bottom/bottom_9.png new file mode 100644 index 0000000000..23a43c1fa6 Binary files /dev/null and b/Games/Makeover_Game/img/bottom/bottom_9.png differ diff --git a/Games/Makeover_Game/img/camera-icon.png b/Games/Makeover_Game/img/camera-icon.png new file mode 100644 index 0000000000..b71c142541 Binary files /dev/null and b/Games/Makeover_Game/img/camera-icon.png differ diff --git a/Games/Makeover_Game/img/hair/hair_1.png b/Games/Makeover_Game/img/hair/hair_1.png new file mode 100644 index 0000000000..b37fcfcd9d Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_1.png differ diff --git a/Games/Makeover_Game/img/hair/hair_10.png b/Games/Makeover_Game/img/hair/hair_10.png new file mode 100644 index 0000000000..e4d58e032d Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_10.png differ diff --git a/Games/Makeover_Game/img/hair/hair_2.png b/Games/Makeover_Game/img/hair/hair_2.png new file mode 100644 index 0000000000..2a2f2bc366 Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_2.png differ diff --git a/Games/Makeover_Game/img/hair/hair_3.png b/Games/Makeover_Game/img/hair/hair_3.png new file mode 100644 index 0000000000..f6e209ea73 Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_3.png differ diff --git a/Games/Makeover_Game/img/hair/hair_4.png b/Games/Makeover_Game/img/hair/hair_4.png new file mode 100644 index 0000000000..6b44e05336 Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_4.png differ diff --git a/Games/Makeover_Game/img/hair/hair_5.png b/Games/Makeover_Game/img/hair/hair_5.png new file mode 100644 index 0000000000..632ee19491 Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_5.png differ diff --git a/Games/Makeover_Game/img/hair/hair_6.png b/Games/Makeover_Game/img/hair/hair_6.png new file mode 100644 index 0000000000..79cada3de4 Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_6.png differ diff --git a/Games/Makeover_Game/img/hair/hair_7.png b/Games/Makeover_Game/img/hair/hair_7.png new file mode 100644 index 0000000000..5c460c9b20 Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_7.png differ diff --git a/Games/Makeover_Game/img/hair/hair_8.png b/Games/Makeover_Game/img/hair/hair_8.png new file mode 100644 index 0000000000..1d98465d40 Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_8.png differ diff --git a/Games/Makeover_Game/img/hair/hair_9.png b/Games/Makeover_Game/img/hair/hair_9.png new file mode 100644 index 0000000000..33e492c0b1 Binary files /dev/null and b/Games/Makeover_Game/img/hair/hair_9.png differ diff --git a/Games/Makeover_Game/img/shoes/shoes_1.png b/Games/Makeover_Game/img/shoes/shoes_1.png new file mode 100644 index 0000000000..23a3f2f1c5 Binary files /dev/null and b/Games/Makeover_Game/img/shoes/shoes_1.png differ diff --git a/Games/Makeover_Game/img/shoes/shoes_2.png b/Games/Makeover_Game/img/shoes/shoes_2.png new file mode 100644 index 0000000000..ac3db481b5 Binary files /dev/null and b/Games/Makeover_Game/img/shoes/shoes_2.png differ diff --git a/Games/Makeover_Game/img/shoes/shoes_3.png b/Games/Makeover_Game/img/shoes/shoes_3.png new file mode 100644 index 0000000000..10dc16aae6 Binary files /dev/null and b/Games/Makeover_Game/img/shoes/shoes_3.png differ diff --git a/Games/Makeover_Game/img/shoes/shoes_4.png b/Games/Makeover_Game/img/shoes/shoes_4.png new file mode 100644 index 0000000000..cbc5ed4eef Binary files /dev/null and b/Games/Makeover_Game/img/shoes/shoes_4.png differ diff --git a/Games/Makeover_Game/img/shoes/shoes_5.png b/Games/Makeover_Game/img/shoes/shoes_5.png new file mode 100644 index 0000000000..07f151d793 Binary files /dev/null and b/Games/Makeover_Game/img/shoes/shoes_5.png differ diff --git a/Games/Makeover_Game/img/test/next-btn.png b/Games/Makeover_Game/img/test/next-btn.png new file mode 100644 index 0000000000..32e1d64f55 Binary files /dev/null and b/Games/Makeover_Game/img/test/next-btn.png differ diff --git a/Games/Makeover_Game/img/test/next-btn.psd b/Games/Makeover_Game/img/test/next-btn.psd new file mode 100644 index 0000000000..250c6e1137 Binary files /dev/null and b/Games/Makeover_Game/img/test/next-btn.psd differ diff --git a/Games/Makeover_Game/img/test/prev-btn.png b/Games/Makeover_Game/img/test/prev-btn.png new file mode 100644 index 0000000000..987c39e5bf Binary files /dev/null and b/Games/Makeover_Game/img/test/prev-btn.png differ diff --git a/Games/Makeover_Game/img/test/test-layout-bg.png b/Games/Makeover_Game/img/test/test-layout-bg.png new file mode 100644 index 0000000000..31797201bb Binary files /dev/null and b/Games/Makeover_Game/img/test/test-layout-bg.png differ diff --git a/Games/Makeover_Game/img/test/test-layout.psd b/Games/Makeover_Game/img/test/test-layout.psd new file mode 100644 index 0000000000..3870cb3cb5 Binary files /dev/null and b/Games/Makeover_Game/img/test/test-layout.psd differ diff --git a/Games/Makeover_Game/img/top/top_1.png b/Games/Makeover_Game/img/top/top_1.png new file mode 100644 index 0000000000..c082103b7b Binary files /dev/null and b/Games/Makeover_Game/img/top/top_1.png differ diff --git a/Games/Makeover_Game/img/top/top_10.png b/Games/Makeover_Game/img/top/top_10.png new file mode 100644 index 0000000000..07c51fc656 Binary files /dev/null and b/Games/Makeover_Game/img/top/top_10.png differ diff --git a/Games/Makeover_Game/img/top/top_2.png b/Games/Makeover_Game/img/top/top_2.png new file mode 100644 index 0000000000..77bfe70a32 Binary files /dev/null and b/Games/Makeover_Game/img/top/top_2.png differ diff --git a/Games/Makeover_Game/img/top/top_3.png b/Games/Makeover_Game/img/top/top_3.png new file mode 100644 index 0000000000..aeea9003df Binary files /dev/null and b/Games/Makeover_Game/img/top/top_3.png differ diff --git a/Games/Makeover_Game/img/top/top_4.png b/Games/Makeover_Game/img/top/top_4.png new file mode 100644 index 0000000000..2c7260e505 Binary files /dev/null and b/Games/Makeover_Game/img/top/top_4.png differ diff --git a/Games/Makeover_Game/img/top/top_5.png b/Games/Makeover_Game/img/top/top_5.png new file mode 100644 index 0000000000..f1fbb7fc88 Binary files /dev/null and b/Games/Makeover_Game/img/top/top_5.png differ diff --git a/Games/Makeover_Game/img/top/top_6.png b/Games/Makeover_Game/img/top/top_6.png new file mode 100644 index 0000000000..7b71674f2c Binary files /dev/null and b/Games/Makeover_Game/img/top/top_6.png differ diff --git a/Games/Makeover_Game/img/top/top_7.png b/Games/Makeover_Game/img/top/top_7.png new file mode 100644 index 0000000000..f30d0d0f1e Binary files /dev/null and b/Games/Makeover_Game/img/top/top_7.png differ diff --git a/Games/Makeover_Game/img/top/top_8.png b/Games/Makeover_Game/img/top/top_8.png new file mode 100644 index 0000000000..83a97c05f2 Binary files /dev/null and b/Games/Makeover_Game/img/top/top_8.png differ diff --git a/Games/Makeover_Game/img/top/top_9.png b/Games/Makeover_Game/img/top/top_9.png new file mode 100644 index 0000000000..c19384df0b Binary files /dev/null and b/Games/Makeover_Game/img/top/top_9.png differ diff --git a/Games/Makeover_Game/index.html b/Games/Makeover_Game/index.html new file mode 100644 index 0000000000..c890b3844e --- /dev/null +++ b/Games/Makeover_Game/index.html @@ -0,0 +1,179 @@ + + + + + + + + + Dress Up + + + +
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+

+ No item type selected to change filters of! Select + circle below. +

+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + diff --git a/Games/Makeover_Game/script.js b/Games/Makeover_Game/script.js new file mode 100644 index 0000000000..2d16874358 --- /dev/null +++ b/Games/Makeover_Game/script.js @@ -0,0 +1,277 @@ +const hueSlider = document.getElementById('hue'); +const brightnessSlider = document.getElementById('brightness'); +const satSlider = document.getElementById('saturate'); + +const warnText = document.querySelector('.text'); + +let hueValue = hueSlider.value; +let brightnessValue = brightnessSlider.value; +let satValue = satSlider.value; + +// VARIABLE TO RESPRESENT ITEM IN ARRAY THAT IS SELECTED +let currentItem = 0; +let itemtoColor; +let colorItem; + +const character = { + base: 0, + hair: 0, + top: 0, + bottom: 0, + shoes: 0, +}; + +// ALL ITEMS IN EACH ITEM TYPE +const allBases = [ + 'base_1', + 'base_2', + 'base_3', + 'base_4', + 'base_5', + 'base_6', + 'base_7', + 'base_8', + 'base_9', + 'base_10', +]; +const allHairs = [ + 'hair_1', + 'hair_2', + 'hair_3', + 'hair_4', + 'hair_5', + 'hair_6', + 'hair_7', + 'hair_8', + 'hair_9', + 'hair_10', +]; +const allTops = [ + 'top_1', + 'top_2', + 'top_3', + 'top_4', + 'top_5', + 'top_6', + 'top_7', + 'top_8', + 'top_9', + 'top_10', +]; +const allBottoms = [ + 'bottom_1', + 'bottom_2', + 'bottom_3', + 'bottom_4', + 'bottom_5', + 'bottom_6', + 'bottom_7', + 'bottom_8', + 'bottom_9', + 'bottom_10', +]; +const allShoes = ['shoes_1', 'shoes_2', 'shoes_3', 'shoes_4', 'shoes_5']; + +const itemType = ['base', 'hair', 'top', 'bottom', 'shoes']; + +const itemTypetoColor = (radio) => { + warnText.classList.remove('warn'); + let tempItem = radio.id; + itemtoColor = tempItem.replace('-color', ''); + console.log(itemtoColor); +}; + +hueSlider.addEventListener('input', (e) => { + if (itemtoColor === undefined) { + warnText.classList.add('warn'); + return; + } + hueValue = e.currentTarget.value; + item = document.getElementById(itemtoColor); + item.style.filter = `hue-rotate(${hueValue}deg) brightness(${brightnessValue}%) saturate(${satValue}%)`; +}); +satSlider.addEventListener('input', (e) => { + if (itemtoColor === undefined) { + warnText.classList.add('warn'); + return; + } + satValue = e.currentTarget.value; + item = document.getElementById(itemtoColor); + item.style.filter = `hue-rotate(${hueValue}deg) brightness(${brightnessValue}%) saturate(${satValue}%)`; +}); +brightnessSlider.addEventListener('input', (e) => { + if (itemtoColor === undefined) { + warnText.classList.add('warn'); + return; + } + item = document.getElementById(itemtoColor); + brightnessValue = e.currentTarget.value; + item.style.filter = `hue-rotate(${hueValue}deg) brightness(${brightnessValue}%) saturate(${satValue}%)`; +}); + +const itemSelector = (button) => { + // SETTING UP THE VARIABLES TO USE LATER + const url = 'url(img/'; + let itemList; + //THIS IS TO HAVE A SEPERATE INDEX FOR EACH ITEM TYPE CHANGE TO PREVENT BUG FROM LOGIC METHOD 1 + let itemTypeIndex; + + // SELECTING WHICH TYPE OF ITEM NEEDS TO BE CHANGED + //FOR BASES + if (button.id.includes('base')) { + // AUTOMATICALLY SETTING TO CHANGE THE COLOR OF THE CHANGED ITEM + colorItem = document.getElementById('base-color'); + console.log(colorItem); + colorItem.checked = true; + itemTypetoColor(colorItem); + + document.getElementById('base-color').checked = true; + console.log('Pressed Hair'); + itemTypeIndex = itemType.indexOf('base'); + itemList = allBases; + // CHECKING DIRECTION TO SWITCH ITEMS + if (button.id.includes('next')) { + console.log('+1 to base'); + character.base++; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.base === itemList.length + ? (character.base = 0) + : (character.base = character.base); + console.log(character.base); + } else { + character.base--; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.base === -1 + ? (character.base = itemList.length - 1) + : (character.base = character.base); + } + } + //FOR HEADS + if (button.id.includes('hair')) { + // AUTOMATICALLY SETTING TO CHANGE THE COLOR OF THE CHANGED ITEM + colorItem = document.getElementById('hair-color'); + console.log(colorItem); + colorItem.checked = true; + itemTypetoColor(colorItem); + + document.getElementById('hair-color').checked = true; + console.log('Pressed Hair'); + itemTypeIndex = itemType.indexOf('hair'); + itemList = allHairs; + // CHECKING DIRECTION TO SWITCH ITEMS + if (button.id.includes('next')) { + console.log('+1 to Hair'); + character.hair++; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.hair === itemList.length + ? (character.hair = 0) + : (character.hair = character.hair); + console.log(character.hair); + } else { + character.hair--; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.hair === -1 + ? (character.hair = itemList.length - 1) + : (character.hair = character.hair); + } + + //FOR TOPS + } + if (button.id.includes('top')) { + // AUTOMATICALLY SETTING TO CHANGE THE COLOR OF THE CHANGED ITEM + colorItem = document.getElementById('top-color'); + console.log(colorItem); + colorItem.checked = true; + itemTypetoColor(colorItem); + + document.getElementById('top-color').checked = true; + itemTypeIndex = itemType.indexOf('top'); + itemList = allTops; + // CHECKING DIRECTION TO SWITCH ITEMS + if (button.id.includes('next')) { + character.top++; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.top === itemList.length + ? (character.top = 0) + : (character.top = character.top); + } else { + character.top--; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.top === -1 + ? (character.top = itemList.length - 1) + : (character.top = character.top); + } + } + + //FOR BOTTOMS + if (button.id.includes('bottom')) { + // AUTOMATICALLY SETTING TO CHANGE THE COLOR OF THE CHANGED ITEM + colorItem = document.getElementById('bottom-color'); + console.log(colorItem); + colorItem.checked = true; + itemTypetoColor(colorItem); + + itemTypeIndex = itemType.indexOf('bottom'); + itemList = allBottoms; + // CHECKING DIRECTION TO SWITCH ITEMS + if (button.id.includes('next')) { + character.bottom++; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.bottom === itemList.length + ? (character.bottom = 0) + : (character.bottom = character.bottom); + } else { + character.bottom--; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.bottom === -1 + ? (character.bottom = itemList.length - 1) + : (character.bottom = character.bottom); + } + } + + //FOR SHOES + if (button.id.includes('shoe')) { + // AUTOMATICALLY SET TO CHANGE THE COLOR OF THE CHANGED ITEM + colorItem = document.getElementById('shoes-color'); + console.log(colorItem); + colorItem.checked = true; + itemTypetoColor(colorItem); + + itemTypeIndex = itemType.indexOf('shoes'); + itemList = allShoes; + // CHECKING DIRECTION TO SWITCH ITEMS + if (button.id.includes('next')) { + character.shoes++; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.shoes === itemList.length + ? (character.shoes = 0) + : (character.shoes = character.shoes); + } else { + character.shoes--; + //MAKING SURE INDEX DOES NOT PASS THE ARRAY LENGTH + character.shoes === -1 + ? (character.shoes = itemList.length - 1) + : (character.shoes = character.shoes); + } + } + + const charaItem = itemType[itemTypeIndex]; + console.log(charaItem); + // USING ALL VARIABLES TO SET THE IMAGE OF THE CHARACTER (yes it's a mouthful this line here) + document.getElementById(charaItem).style.background = + url + charaItem + '/' + itemList[character[charaItem]] + '.png)'; + console.table(character); +}; + +document.getElementById('capture-btn').addEventListener('click', () => { + domtoimage.toPng(document.querySelector('#game-bg')) + .then((dataUrl) => { + const link = document.createElement('a'); + link.href = dataUrl; + link.download = 'Makeover_Outfit.png'; + link.click(); + }) + .catch((error) => { + console.error('Error capturing page:', error); + }); +}); \ No newline at end of file diff --git a/Games/Makeover_Game/styles.css b/Games/Makeover_Game/styles.css new file mode 100644 index 0000000000..f5b6e71d30 --- /dev/null +++ b/Games/Makeover_Game/styles.css @@ -0,0 +1,298 @@ +* { + font-family: Arial, Helvetica, sans-serif; +} + +html { + margin: 0; + padding: 0; + height: 100%; +} + +body { + margin: 0; + padding: 0; + background-color: antiquewhite; + width: 100%; + height: 100%; + display: grid; + place-items: center; +} + +footer { + position: absolute; + bottom: 0; +} +footer p { + font-weight: 600; +} +footer p a:hover { + color: #a892e4; +} + +.game-container { + position: absolute; + background-color: rgb(195, 170, 140); + width: 700px; + height: 500px; + display: grid; + box-shadow: 0px 0px 10px rgba(55, 55, 55, 0.7); +} + +#game-bg { + position: absolute; + width: 100%; + height: 100%; + background: url("../img/test/test-layout-bg.png"); +} + +/* Button Styles */ +#next-base, +#next-hair, +#next-top, +#next-bottom, +#next-shoe { + position: relative; + left: 7em; + width: 6em; + height: 25px; + padding: 0 2em 0 0.7em; + text-align: left; + color: white; + background: url("../img/test/next-btn.png"); + background-position: center; + background-size: 100%; + background-repeat: no-repeat; + border: 0; + border-radius: 25%; + border: 1px solid rgb(14, 46, 115); + box-shadow: 3px 3px 5px rgba(55, 55, 55, 0.7); +} + +#prev-base, +#prev-hair, +#prev-top, +#prev-bottom, +#prev-shoe { + position: relative; + width: 6em; + height: 25px; + padding: 0 0.7em 0 2em; + text-align: right; + color: white; + background: url("../img/test/prev-btn.png"); + background-position: center; + background-size: 100%; + background-repeat: no-repeat; + border: 0; + border-radius: 25%; + border: 1px solid rgb(14, 46, 115); + box-shadow: 3px 3px 5px rgba(55, 55, 55, 0.7); +} + +/* When hovering over the buttons! */ +#next-base:hover, +#prev-base:hover, +#next-hair:hover, +#prev-hair:hover, +#next-top:hover, +#prev-top:hover, +#next-bottom:hover, +#prev-bottom:hover, +#next-shoe:hover, +#prev-shoe:hover { + box-shadow: inset 0 0 100px 100px rgba(255, 255, 255, 0.3); +} + +/* The clothes to overite the character */ +#game-bg { + background: url("../img/bg.png"); + width: 100%; + height: 100%; + position: absolute; +} + +#base { + background: url("../img/base/base_1.png"); + width: 100%; + height: 100%; + position: absolute; +} + +#hair { + background: url("../img/hair/hair_1.png"); + width: 100%; + height: 100%; + position: absolute; +} + +#top { + background: url("../img/top/top_1.png"); + width: 100%; + height: 100%; + position: absolute; +} + +#bottom { + background: url("../img/bottom/bottom_1.png"); + width: 100%; + height: 100%; + position: absolute; +} + +#shoes { + background: url("../img/shoes/shoes_1.png"); + width: 100%; + height: 100%; + position: absolute; +} + +/* Button Position Set Up */ +form { + position: absolute; + display: grid; + width: 100%; + height: 100%; + grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: repeat(7, 1fr); + grid-template-areas: "logo-left logo base-right" "base-left base base-right" "head-left head head-right" "top-left top top-right" "blank-left blank blank-right" "bottom-left bottom bottom-right" "feet-left feet feet-right"; +} + +/* Positions of the buttons on the grid */ +.color-section { + display: flex; + flex-direction: column; + font-size: 12px; + grid-area: base-right; + align-self: center; + width: full; + color: white; + text-align: center; + margin: 0 2em; +} + +input[type=range] { + margin: 0.5em; +} + +#warning { + grid-area: head-right; +} +#warning .text { + margin-top: 0; + font-size: 12px; + text-align: center; + color: red; + opacity: 0; + transition: opacity 0.5s; +} +#warning .warn { + opacity: 100%; + transition: opacity 0.5s; +} + +#next-base { + grid-area: blank-right; + align-self: center; + margin-left: 3em; +} + +#next-hair { + grid-area: head-right; + align-self: end; + margin-left: 3em; +} + +#next-top { + grid-area: top-right; + align-self: end; + margin-left: 3em; +} + +#next-bottom { + grid-area: bottom-right; + margin-left: 3em; +} + +#next-shoe { + grid-area: feet-right; + margin-left: 3em; +} + +#prev-base { + grid-area: blank-right; + align-self: center; + margin-left: 2em; +} + +#prev-hair { + grid-area: head-right; + align-self: end; + margin-left: 2em; +} + +#prev-top { + grid-area: top-right; + align-self: end; + margin-left: 2em; +} + +#prev-bottom { + grid-area: bottom-right; + margin-left: 2em; +} + +#prev-shoe { + grid-area: feet-right; + margin-left: 2em; +} + +/* RADIO BUTTONS TO SELECT WHICH ITEM TO COLOR */ +#base-color { + grid-area: blank-right; + align-self: center; + margin: 0.35em 0 0 0.5em; +} + +#hair-color { + grid-area: head-right; + align-self: flex-end; + margin: 0 0 0.35em 0.5em; +} + +#top-color { + grid-area: top-right; + align-self: flex-end; + margin: 0 0 0.35em 0.5em; +} + +#bottom-color { + grid-area: bottom-right; + align-self: flex-start; + margin: 0.35em 0 0 0.5em; +} + +#shoes-color { + grid-area: feet-right; + align-self: flex-start; + margin: 0.35em 0 0 0.5em; +} + +#capture-btn { + position: absolute; + padding-bottom: -80px; + top: 0px; + left: 0px; + background: transparent; + border: none; + cursor: pointer; + z-index: 2; +} + +#capture-btn img { + width: 80px; + height: 80px; +} + +.warn { + color: red; +} diff --git a/Games/Mario Matching Game/01.jpg b/Games/Mario Matching Game/01.jpg deleted file mode 100644 index 51c56edd3d..0000000000 Binary files a/Games/Mario Matching Game/01.jpg and /dev/null differ diff --git a/Games/Mario Matching Game/02.jpg b/Games/Mario Matching Game/02.jpg deleted file mode 100644 index db8ce9cc8e..0000000000 Binary files a/Games/Mario Matching Game/02.jpg and /dev/null differ diff --git a/Games/Mario Matching Game/03.jpg b/Games/Mario Matching Game/03.jpg deleted file mode 100644 index 97cd791cf2..0000000000 Binary files a/Games/Mario Matching Game/03.jpg and /dev/null differ diff --git a/Games/Mario Matching Game/Readme.md b/Games/Mario Matching Game/Readme.md deleted file mode 100644 index 3c80472ede..0000000000 --- a/Games/Mario Matching Game/Readme.md +++ /dev/null @@ -1,23 +0,0 @@ -# Mario Matching Game - -Welcome to the Mario Matching Game! This game challenges players to match three identical images within a specified time limit. - -## Image - -![image](https://github.com/dpvasani/Mario-Matching-Game/assets/109815626/fde14fbe-05fc-4231-9d26-ec8e975a633d) - - -## Gameplay - -- The game board consists of multiple tiles, each containing an image. - -## Features - -- Reset Button: Start a new game round by resetting the board and timer. - -## Technologies Used - -- HTML -- CSS -- JavaScript - diff --git a/Games/Mario Matching Game/index.html b/Games/Mario Matching Game/index.html deleted file mode 100644 index 5ab2a96528..0000000000 --- a/Games/Mario Matching Game/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - Game - - -

Mario Matching Game

-
- - - -
- - - - diff --git a/Games/Mario Matching Game/script.js b/Games/Mario Matching Game/script.js deleted file mode 100644 index 6ebc1da48d..0000000000 --- a/Games/Mario Matching Game/script.js +++ /dev/null @@ -1,30 +0,0 @@ -let chk1 = document.querySelector('#chk1'); -let chk2 = document.querySelector('#chk2'); -let chk3 = document.querySelector('#chk3'); -let reset = document.querySelector('.reset'); -chk1.onclick = function(){ - if(chk1.checked === true){ - chk1.disabled = 'true' - } -} -chk2.onclick = function(){ - if(chk2.checked === true){ - chk2.disabled = 'true' - } -} -chk3.onclick = function(){ - if(chk3.checked === true){ - chk3.disabled = 'true' - } -} - -reset.onclick = function(){ - chk1.disabled = false - chk1.checked = false - - chk2.disabled = false - chk2.checked = false - - chk3.disabled = false - chk3.checked = false -} \ No newline at end of file diff --git a/Games/Mario Matching Game/style.css b/Games/Mario Matching Game/style.css deleted file mode 100644 index 6edfd681d5..0000000000 --- a/Games/Mario Matching Game/style.css +++ /dev/null @@ -1,119 +0,0 @@ -@font-face { - font-family: 'New Super Mario Font U', sans-serif; - src: url(https://fonts.cdnfonts.com/css/new-super-mario-font-u); -} - -* { - margin: 0; - padding: 0; - font-family: 'New Super Mario Font U', sans-serif; - box-sizing: border-box; -} - -body -{ - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - min-height: 100vh; - -} -h2 -{ - padding: 1rem; - text-align: center ; - margin-bottom: 3rem; - font-size: 2.5em; -} -.box -{ - position: relative; - width: 600px; - height: 200px; - border: 1px solid #888888; - box-shadow: 5px 10px #888888; - display: flex; - flex-wrap: wrap; - flex-direction: column; - align-items: center; - justify-content: center; -} -.box label -{ - position: relative; - width: 100%; - height: 33.333%; - border: 1px solid black; - border-bottom: none; -} - -.box label input { - position: relative; - appearance: none; - z-index: 10; -} - -.box label i{ - position:absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-size: 600px; -} - -.box label:nth-child(1) i { - background-image: url(01.jpg); - animation: animate 0.5s steps(3) infinite; -} -.box label:nth-child(2) i { - background-image: url(02.jpg); - animation: animate 0.4s steps(3) infinite; -} -.box label:nth-child(3) i { - background-image: url(03.jpg); - animation: animate 0.7s steps(3) infinite; -} - -@keyframes animate{ - 0% - { - background-position: 0px; - } - 100% - { - background-position: 600px; - } -} - -.box label input:checked ~ i { - animation-play-state: paused; -} - -.reset{ - margin-top: 3rem; - padding: 1rem; - font-size: large; - letter-spacing: 5px; - background-color: rgba(44, 40, 40, 0.897); - color: rgb(255, 255, 255); - border: none; - font-weight: 700; -} - -.reset:active -{ - background: rgba(250, 112, 102, 0.89); - transform: scale(0.95); -} - -@media screen and (max-width:600px) { - .box { - width: 300px; - height: 100px; - } - .box label i{ - background-size: 300px; - } -} \ No newline at end of file diff --git a/Games/Master_Typing/index.html b/Games/Master_Typing/index.html index 6a13c49bcb..e8a433eefd 100644 --- a/Games/Master_Typing/index.html +++ b/Games/Master_Typing/index.html @@ -12,8 +12,8 @@
-
- +
+

MASTER TYPING

diff --git a/Games/Matching_pair/Contact-us.html b/Games/Matching_pair/Contact-us.html new file mode 100644 index 0000000000..f1994b4319 --- /dev/null +++ b/Games/Matching_pair/Contact-us.html @@ -0,0 +1,42 @@ + + + + + + Contact-Me + + + + +
+

Contact-Us

+ +
+
+ + + + + + + + +
+ +
+ +
+

+
+ + + diff --git a/Games/Matching_pair/Contact.css b/Games/Matching_pair/Contact.css new file mode 100644 index 0000000000..f9332e6578 --- /dev/null +++ b/Games/Matching_pair/Contact.css @@ -0,0 +1,163 @@ +body { + font-family: 'Arial', sans-serif; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + margin: 0; + background: linear-gradient(45deg, #0d0812, #0a1a37,rgb(43, 5, 94),rgb(79, 3, 79),rgb(4, 4, 134),rgb(86, 86, 248) + ); + background-size: 400% 400%; + animation: gradientAnimation 5s ease infinite; + color: #fff; + cursor: pointer; + } + #custom-cursor{ + + width: 20px; + height: 20px; + border: 2px solid #e8dce4; + border-radius: 50%; + position: absolute; + pointer-events: none; + transition: transform 0.1s ease-out, background-color 0.2s ease; + z-index: 10000; + animation: cursorAnimation 0.3s infinite alternate; +} +@keyframes cursorAnimation { + 0% { transform: scale(1); background-color: black,; } + 100% { transform: scale(1.5); background-color: white; } +} + +@keyframes gradientAnimation { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} +@keyframes backgroundAnimation { + 0% { background-color: #f44336; } + 20% { background-color: #e91e63; } + 40% { background-color: #9c27b0; } + 60% { background-color: #673ab7; } + 80% { background-color: #3f51b5; } + 100% { background-color: #2196f3; } +} +@keyframes cursorAnimation { + 0% { transform: scale(1); background-color: black,; } + 100% { transform: scale(1.5); background-color: white; } + } + h1 { + margin-top: 20px; + text-align: center; + text-transform: uppercase; + letter-spacing: 2px; + animation: titleAnimation 1s ease-out infinite alternate; + } +.submit{ + text-align: center; + margin-left:100px; + margin-top: 14px; +} +/* Navbar styles */ +.navbar { + width: 100%; + background-color: #09000d; + padding: 1px ; + position: fixed; + top: 0; + z-index: 1000; + } + + .navbar-container { + width: 90%; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; + } + + .navbar-brand { + color: #fff; + text-decoration: none; + font-size: 24px; + font-weight: bold; + } + + .navbar-menu { + list-style: none; + display: flex; + gap: 15px; + } + + .navbar-menu li { + display: inline; + } + + .navbar-menu a { + color: #fff; + text-decoration: none; + font-size: 18px; + } + + .navbar-menu a:hover { + text-decoration: underline; + } + + +.contact-container { + background: #fff; + padding: 20px; + border-radius: 5px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + max-width: 500px; + width: 100%; +} + +h1 { + margin-bottom: 20px; + color: #673ab7; +} + +label { + display: block; + margin-top: 10px; +} + +input, textarea { + width: 100%; + padding: 10px; + margin-top: 5px; + margin-bottom: 10px; + border: 1px solid #ddd; + border-radius: 5px; +} +.form-group{ + display:flex; + + margin-left: 90px; +} + +button { + background-color: #007BFF; + color: #fff; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.3s; + margin-top: 20px; + + + +} + +button:hover { + background-color: #0056b3; +} + +#formMessage { + margin-top: 20px; + color: red; + text-align: center; +} diff --git a/Games/Matching_pair/README.md b/Games/Matching_pair/README.md new file mode 100644 index 0000000000..13282e3b13 --- /dev/null +++ b/Games/Matching_pair/README.md @@ -0,0 +1,89 @@ +# Matching Pairs Game +## Description + +The Matching Pairs Game is a fun and engaging memory game developed using HTML, CSS, and JavaScript. The game challenges players to match pairs of cards with identical images within a limited time. It offers a simple yet addictive gameplay experience, a countdown timer, and a helpful chatbot for hints. + +## Features + +- **Interactive Gameplay:** Flip cards to reveal their images and try to find matching pairs. +- **Scoring System:** Earn points for each successful match. +- **Countdown Timer:** Complete the game within the allotted time to win.(FutureScope) +- **Responsive Design:** The game is optimized for both desktop and mobile devices. +- **Dark Theme:** The game features a modern dark theme for a comfortable playing experience. + +### Objective + +Match all pairs of cards . + +### How to Play + +1. **Starting the Game:** + - All cards are placed face down on the game board. + - The score and timer are displayed at the top of the game area. + +2. **Flipping Cards:** + - Click on any card to flip it over and reveal the image on the front. + - Click on a second card to flip it over as well. + +3. **Matching Pairs:** + - If the images on the two flipped cards match, they will remain face up. + - If the images do not match, both cards will flip back face down after a short delay. + + +5. **Timer:** + - The timer is displayed at the top of the game area. + . + + + +7. **Winning and Losing:** + - The game is won when all pairs of cards have been matched before the timer runs out. + + +8. **Restarting the Game:** + - Refresh the page to start a new game. + +### Tips + +- Remember the positions of the cards you have already flipped. +- Use hints strategically to maximize your chances of finding pairs quickly. + +## ScreeShots +![Matching_Pair_Game](https://github.com/user-attachments/assets/0fc1bf7f-81b4-4124-97a2-9fa135479b66) +## workingVideo: + + +https://github.com/user-attachments/assets/cc6e7ac3-4057-47ad-b859-2aae2d4e31b9 + + + +## Technologies Used + +- **HTML:** Structure of the game. +- **CSS:** Styling and layout. +- **JavaScript:** Game logic and interactivity. + +## Getting Started + +1. Clone the repository: + ```bash + git clone https://github.com/yourusername/matching-pairs-game.git + ``` +2. Navigate to the project directory: + ```bash + cd matching-pairs-game + ``` +3. Open `index.html` in your web browser to play the game. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. + +## Acknowledgments + +- Icons by [Favicon](https://favicon.io/) + + +--- + +Replace `"https://github.com/yourusername/matching-pairs-game.git"` with the actual URL of your GitHub repository. This README file provides a detailed description of the game, instructions for playing, and information about the technologies used, making it easy for others to understand and contribute to your project. diff --git a/Games/Matching_pair/about.css b/Games/Matching_pair/about.css new file mode 100644 index 0000000000..f38cf82790 --- /dev/null +++ b/Games/Matching_pair/about.css @@ -0,0 +1,97 @@ +body { + font-family: 'Arial', sans-serif; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + margin: 0; + background: linear-gradient(45deg, #0d0812, #0a1a37,rgb(43, 5, 94),rgb(79, 3, 79),rgb(4, 4, 134),rgb(86, 86, 248) + ); + background-size: 400% 400%; + animation: gradientAnimation 5s ease infinite; + color: #fff; + cursor: pointer; + } + #custom-cursor{ + + width: 20px; + height: 20px; + border: 2px solid #e8dce4; + border-radius: 50%; + position: absolute; + pointer-events: none; + transition: transform 0.1s ease-out, background-color 0.2s ease; + z-index: 10000; + animation: cursorAnimation 0.3s infinite alternate; +} +@keyframes cursorAnimation { + 0% { transform: scale(1); background-color: black,; } + 100% { transform: scale(1.5); background-color: white; } +} + +@keyframes gradientAnimation { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} +@keyframes backgroundAnimation { + 0% { background-color: #f44336; } + 20% { background-color: #e91e63; } + 40% { background-color: #9c27b0; } + 60% { background-color: #673ab7; } + 80% { background-color: #3f51b5; } + 100% { background-color: #2196f3; } +} +@keyframes cursorAnimation { + 0% { transform: scale(1); background-color: black,; } + 100% { transform: scale(1.5); background-color: white; } + } + h1 { + margin-top: 20px; + text-align: center; + text-transform: uppercase; + letter-spacing: 2px; + animation: titleAnimation 1s ease-out infinite alternate; + } + +.content-container { + margin-top: 300px; /* Adjust based on the height of the navbar */ + padding: 20px; + max-width: 800px; + margin-left: auto; + margin-right: auto; + background-color: #1e1e1e; + color: #ffffff; + border-radius: 10px; +} + +header h1 { + font-size: 32px; + margin-bottom: 20px; + margin-top: 20px; + padding-top: 500px; + +} +h1{ + animation: gradientAnimations 0.3 ease infinite; +} +.instructions h2 { + font-size: 24px; + margin-top: 20px; + margin-bottom: 10px; + margin-left: 10px; +} + +.instructions p, .instructions li { + font-size: 18px; + margin-bottom: 10px; + +} +p{ + margin-top: 15px; +} + +.instructions ul, .instructions ol { + margin-left: 20px; +} diff --git a/Games/Matching_pair/about.html b/Games/Matching_pair/about.html new file mode 100644 index 0000000000..5dce15ca4a --- /dev/null +++ b/Games/Matching_pair/about.html @@ -0,0 +1,58 @@ + + + + + + Matching Pairs Game - Instructions + + + + +
+ +

How to Play the Matching Pairs Game

+
+
+

Objective

+

The goal of the game is to match all pairs of cards within the allotted time.

+

How to Play

+
    +
  1. Starting the Game: +

    When the game starts, all the cards will be placed face down on the game board. You will see the score and timer at the top of the game area.

    +
  2. +
  3. Flipping Cards: +

    Click on any card to flip it over and reveal the image on the front. Click on a second card to flip it over as well.

    +
  4. +
  5. Matching Pairs: +

    If the images on the two flipped cards match, they will remain face up, indicating a successful match. If the images do not match, both cards will be flipped back face down after a short delay.

    +
  6. +
  7. Scoring: +

    Each successful match will add 10 points to your score. The score is displayed at the top of the game area.

    +
  8. +
  9. Timer: +

    You have a limited amount of time (60 seconds) to match all the pairs. The timer is displayed at the top of the game area. The game ends when the timer runs out or when all pairs have been matched.

    +
  10. +
  11. Hints: +

    You can ask the chatbot for hints if you are having trouble finding pairs. To ask for a hint, type "hint" in the chat input box and press the send button. The chatbot will suggest which cards to flip.

    +
  12. +
  13. Winning the Game: +

    The game is won when all pairs of cards have been matched before the timer runs out. A message will appear congratulating you on your win.

    +
  14. +
  15. Losing the Game: +

    If the timer runs out before you have matched all the pairs, the game is over, and a message will appear informing you that the time is up.

    +
  16. +
  17. Restarting the Game: +

    Refresh the page to start a new game.

    +
  18. +
+

Tips

+
    +
  • Try to remember the positions of the cards you have already flipped.
  • +
  • Use hints strategically to maximize your chances of finding pairs quickly.
  • +
+
+ +
+ + + diff --git a/Games/Matching_pair/contact.js b/Games/Matching_pair/contact.js new file mode 100644 index 0000000000..67b548a93f --- /dev/null +++ b/Games/Matching_pair/contact.js @@ -0,0 +1,26 @@ +document.getElementById('contactForm').addEventListener('submit', function(event) { + event.preventDefault(); + + const name = document.getElementById('name').value; + const email = document.getElementById('email').value; + const message = document.getElementById('message').value; + const formMessage = document.getElementById('formMessage'); + + if (name === '' || email === '' || message === '') { + formMessage.textContent = 'Please fill in all fields.'; + return; + } + + if (!validateEmail(email)) { + formMessage.textContent = 'Please enter a valid email address.'; + return; + } + + formMessage.textContent = 'Thank you for contacting us, ' + name + '! We will get back to you soon.'; + formMessage.style.color = 'green'; +}); + +function validateEmail(email) { + const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return re.test(email); +} diff --git a/Games/Matching_pair/favicon_io (2)/android-chrome-192x192.png b/Games/Matching_pair/favicon_io (2)/android-chrome-192x192.png new file mode 100644 index 0000000000..f45d588987 Binary files /dev/null and b/Games/Matching_pair/favicon_io (2)/android-chrome-192x192.png differ diff --git a/Games/Matching_pair/favicon_io (2)/android-chrome-512x512.png b/Games/Matching_pair/favicon_io (2)/android-chrome-512x512.png new file mode 100644 index 0000000000..7a67fed540 Binary files /dev/null and b/Games/Matching_pair/favicon_io (2)/android-chrome-512x512.png differ diff --git a/Games/Matching_pair/favicon_io (2)/apple-touch-icon.png b/Games/Matching_pair/favicon_io (2)/apple-touch-icon.png new file mode 100644 index 0000000000..8226a400ae Binary files /dev/null and b/Games/Matching_pair/favicon_io (2)/apple-touch-icon.png differ diff --git a/Games/Matching_pair/favicon_io (2)/favicon-16x16.png b/Games/Matching_pair/favicon_io (2)/favicon-16x16.png new file mode 100644 index 0000000000..2cfa183025 Binary files /dev/null and b/Games/Matching_pair/favicon_io (2)/favicon-16x16.png differ diff --git a/Games/Matching_pair/favicon_io (2)/favicon-32x32.png b/Games/Matching_pair/favicon_io (2)/favicon-32x32.png new file mode 100644 index 0000000000..bff7c9717c Binary files /dev/null and b/Games/Matching_pair/favicon_io (2)/favicon-32x32.png differ diff --git a/Games/Matching_pair/favicon_io (2)/favicon.ico b/Games/Matching_pair/favicon_io (2)/favicon.ico new file mode 100644 index 0000000000..cde73a67fc Binary files /dev/null and b/Games/Matching_pair/favicon_io (2)/favicon.ico differ diff --git a/Games/Matching_pair/favicon_io (2)/site.webmanifest b/Games/Matching_pair/favicon_io (2)/site.webmanifest new file mode 100644 index 0000000000..45dc8a2065 --- /dev/null +++ b/Games/Matching_pair/favicon_io (2)/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/Games/Matching_pair/index.html b/Games/Matching_pair/index.html new file mode 100644 index 0000000000..09262567dd --- /dev/null +++ b/Games/Matching_pair/index.html @@ -0,0 +1,43 @@ + + + + + + Matching Pairs Game + + + + + + + + + +
+

Matching Pairs Game

+
+
+

Moves: 0

+

Time: 0 seconds

+ +
+
+
+
Hello! Need any help?
+
+ + +
+
+ + + diff --git a/Games/Matching_pair/script.js b/Games/Matching_pair/script.js new file mode 100644 index 0000000000..4692b08652 --- /dev/null +++ b/Games/Matching_pair/script.js @@ -0,0 +1,148 @@ +document.addEventListener('mousemove', function(e) { + const customCursor = document.getElementById('custom-cursor'); + customCursor.style.left = e.pageX + 'px'; + customCursor.style.top = e.pageY + 'px'; +}) +document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + e.preventDefault(); + + document.querySelector(this.getAttribute('href')).scrollIntoView({ + behavior: 'smooth' + }); + }); +}); + +document.addEventListener("DOMContentLoaded", () => { + const gameContainer = document.getElementById("game-container"); + let cards = generateCards(); + let flippedCard = null; + let lockBoard = false; + let moves = 0; + let matchedPairs = 0; + let timerInterval; + let seconds = 0; + + function generateCards() { + const symbols = ["😀", "😎", "🥳", "🎉", "🚀", "🌟", "🎈", "🎁"]; + let cards = [...symbols, ...symbols]; + cards.sort(() => Math.random() - 0.5); + return cards; + } + + + function createCard(symbol, index) { + const card = document.createElement("div"); + card.classList.add("card"); + card.dataset.symbol = symbol; + card.addEventListener("click", flipCard); + gameContainer.appendChild(card); + } + + function flipCard() { + if (lockBoard) return; + if (this === flippedCard) return; + this.textContent = this.dataset.symbol; + this.classList.add("flipped"); + + if (!flippedCard) { + flippedCard = this; + } else { + moves++; + document.getElementById("moves").textContent = `Moves: ${moves}`; + if (flippedCard.dataset.symbol !== this.dataset.symbol) { + lockBoard = true; + setTimeout(() => { + flippedCard.classList.remove("flipped"); + this.classList.remove("flipped"); + flippedCard.textContent = ""; + this.textContent = ""; + flippedCard = null; + lockBoard = false; + }, 1000); + } else { + flippedCard = null; + matchedPairs++; + if (matchedPairs === cards.length / 2) { + clearInterval(timerInterval); + setTimeout(() => { + alert(`Congratulations! You completed the game in ${seconds} seconds with ${moves} moves.`); + }, 500); + } + } + } + } + + function initializeGame() { + gameContainer.innerHTML = ""; + cards.forEach((symbol, index) => { + createCard(symbol, index); + }); + moves = 0; + matchedPairs = 0; + seconds = 0; + document.getElementById("moves").textContent = `Moves: ${moves}`; + startTimer(); + } + + function startTimer() { + timerInterval = setInterval(() => { + seconds++; + document.getElementById("timer").textContent = `Time: ${seconds} seconds`; + }, 1000); + } + + initializeGame(); +}); + +///added chat box functionality +const chatBox = document.getElementById('chat-box'); +const chatInput = document.getElementById('chat-input'); +const sendBtn = document.getElementById('send-btn'); +sendBtn.addEventListener('click', sendMessage); +function sendMessage() { + const message = chatInput.value.trim(); + if (!message) return; + + displayMessage(message, 'user'); + chatInput.value = ''; + respondToMessage(message); +} + +function displayMessage(message, sender) { + const messageElement = document.createElement('div'); + messageElement.classList.add('chat-message', sender); + messageElement.textContent = message; + chatBox.appendChild(messageElement); + chatBox.scrollTop = chatBox.scrollHeight; +} + + +function respondToMessage(message) { + let response; + if (message.toLowerCase().includes('hint')) { + response = getHint(); + } else { + response = "I'm here to help! Ask me for a hint or any other question."; + } + setTimeout(() => displayMessage(response, 'bot'), 1000); +} + +function getHint() { + // Check for pairs of cards that are not yet matched + for (let i = 0; i < cards.length; i++) { + for (let j = i + 1; j < cards.length; j++) { + if (!cards[i].classList.contains('flipped') && !cards[j].classList.contains('flipped')) { + if (cards[i].querySelector('.card-front').style.backgroundImage === cards[j].querySelector('.card-front').style.backgroundImage) { + return `Try flipping the cards at positions ${i + 1} and ${j + 1}.`; + } + } + } + } + // If no pairs found, suggest flipping a random unflipped card + for (let i = 0; i < cards.length; i++) { + if (!cards[i].classList.contains('flipped')) { + return `Try flipping the card at position ${i + 1}.`; + } + } + return "No hints available at the moment.";} diff --git a/Games/Matching_pair/styles.css b/Games/Matching_pair/styles.css new file mode 100644 index 0000000000..d522871d39 --- /dev/null +++ b/Games/Matching_pair/styles.css @@ -0,0 +1,251 @@ +body { + font-family: 'Arial', sans-serif; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + margin: 0; + background: linear-gradient(45deg, #0d0812, #0a1a37,rgb(43, 5, 94),rgb(79, 3, 79),rgb(4, 4, 134),rgb(86, 86, 248) + ); + background-size: 400% 400%; + animation: gradientAnimation 5s ease infinite; + color: #fff; + cursor: none; +} +/* Navbar styles */ +.navbar { + width: 100%; + background-color: #29242b; + padding: 1px ; + position: fixed; + top: 0; + z-index: 1000; +} + +.navbar-container { + width: 90%; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; +} + +.navbar-brand { + color: #fff; + text-decoration: none; + font-size: 24px; + font-weight: bold; +} + +.navbar-menu { + list-style: none; + display: flex; + gap: 15px; +} + +.navbar-menu li { + display: inline; +} + +.navbar-menu a { + color: #fff; + text-decoration: none; + font-size: 18px; +} + +.navbar-menu a:hover { + text-decoration: underline; +} + +/* Adjust the game container to accommodate the navbar */ +.game-container { + margin-top: 60px; /* Adjust based on the height of the navbar */ + text-align: center; +} + +#custom-cursor{ + + width: 20px; + height: 20px; + border: 2px solid #e8dce4; + border-radius: 50%; + position: absolute; + pointer-events: none; + transition: transform 0.1s ease-out, background-color 0.2s ease; + z-index: 10000; + animation: cursorAnimation 0.3s infinite alternate; +} +@keyframes cursorAnimation { + 0% { transform: scale(1); background-color: black,; } + 100% { transform: scale(1.5); background-color: white; } +} + +@keyframes gradientAnimation { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} +@keyframes backgroundAnimation { + 0% { background-color: #f44336; } + 20% { background-color: #e91e63; } + 40% { background-color: #9c27b0; } + 60% { background-color: #673ab7; } + 80% { background-color: #3f51b5; } + 100% { background-color: #2196f3; } +} + +h1 { + margin-top: 20px; + text-align: center; + text-transform: uppercase; + letter-spacing: 2px; + animation: titleAnimation 1s ease-out infinite alternate; +} + +@keyframes titleAnimation { + 0% { color: #fff; transform: scale(1); } + 100% { color: #f3f3f3; transform: scale(1.1); } +} + +#game-container { + display: grid; + grid-template-columns: repeat(4, 100px); + grid-template-rows: repeat(4, 100px); + gap: 10px; + margin-top: 20px; + perspective: 1000px; + animation: fadeIn 2s ease-out; +} + +@keyframes fadeIn { + 0% { opacity: 0; transform: translateY(20px); } + 100% { opacity: 1; transform: translateY(0); } +} + +@keyframes backgroundAnimation { + 0% { background-color: #f44336; } + 20% { background-color: #e91e63; } + 40% { background-color: #9c27b0; } + 60% { background-color: #673ab7; } + 80% { background-color: #3f51b5; } + 100% { background-color: #2196f3; } +} + +.card { + width: 100px; + height: 100px; + display: flex; + justify-content: center; + align-items: center; + font-size: 24px; + cursor: pointer; + transform-style: preserve-3d; + transition: transform 0.5s ease, box-shadow 0.3s ease, transform 0.3s ease; + animation: backgroundAnimation 5s infinite alternate, cardEntry 0.5s ease; +} + +@keyframes cardEntry { + 0% { opacity: 0; transform: scale(0.5); } + 100% { opacity: 1; transform: scale(1); } +} + +.card:hover { + transform: scale(1.1) rotateZ(5deg); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); +} + +.card.flipped { + transform: rotateY(180deg); + background-color: #fff; /* Fixed color for flipped cards */ + color: #000; +} + +#game-info { + margin-top: 20px; + display: flex; + justify-content: center; + align-items: center; + font-size: 18px; +} + +#game-info p { + margin-right: 20px; + animation: fadeIn 1.5s ease-out; +} + +button { + padding: 10px 20px; + background-color: #4caf50; + color: #fff; + border: none; + cursor: pointer; + font-size: 16px; + text-transform: uppercase; + letter-spacing: 1px; + transition: background-color 0.3s ease, transform 0.3s ease; + animation: buttonBounce 2s infinite; +} + +button:hover { + background-color: #45a049; + transform: scale(1.1); +} + +@keyframes buttonBounce { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} +.chat-container { + position: fixed; + bottom: 0; + right: 20px; + width: 300px; + background-color: #2c2c2c; + border: 1px solid #444; + border-radius: 10px; + overflow: hidden; +} + +.chat-box { + height: 200px; + overflow-y: auto; + padding: 10px; + color: #fff; +} + +.chat-message { + margin-bottom: 10px; + padding: 5px 10px; + border-radius: 5px; +} + +.chat-message.bot { + background-color: #444; + text-align: left; +} + +.chat-message.user { + background-color: #0084ff; + text-align: right; +} + +#chat-input { + width: 80%; + padding: 10px; + border: none; + border-radius: 0 0 0 10px; + background-color: #333; + color: #fff; +} + +#send-btn { + width: 10%; + padding: 5px; + border: none; + border-radius: 0 0 10px 0; + background-color: #444; + color: #fff; + cursor: pointer; + display: inline-block; +} diff --git a/Games/MathematicsEscapeRoom/MathematicsEscapeRoom.mp4 b/Games/MathematicsEscapeRoom/MathematicsEscapeRoom.mp4 new file mode 100644 index 0000000000..f0fcb4fa7a Binary files /dev/null and b/Games/MathematicsEscapeRoom/MathematicsEscapeRoom.mp4 differ diff --git a/Games/MathematicsEscapeRoom/README.md b/Games/MathematicsEscapeRoom/README.md new file mode 100644 index 0000000000..b1b3846374 --- /dev/null +++ b/Games/MathematicsEscapeRoom/README.md @@ -0,0 +1,44 @@ +# Mathematics Escape Room Game + +Welcome to the Mathematics Escape Room game! Test your math skills and solve puzzles to escape from each room. Each room presents a new mathematical challenge that you must solve to progress to the next room. Are you ready for the challenge? + +## Features + +- **Interactive Puzzles:** Solve math puzzles to find the key and progress to the next room. +- **Engaging Gameplay:** Each room presents a unique mathematical challenge. +- **Dynamic Interface:** Enjoy a visually appealing interface with an animated background and interactive elements. + +## How to Play + +### Starting the Game + +1. Open `index.html` in your web browser. + +### Game Interface + +- You will see the game title and the current room description. +- Enter your answer in the input box provided. +- Click the "Check Answer" button or press Enter to submit your answer. + +### Solving Puzzles + +- Each room presents a math puzzle. +- Enter the correct answer to unlock the next room. +- If the answer is correct, you will proceed to the next room. If not, try again! + +### Game Completion + +- Successfully escape from all rooms to complete the game. +- A congratulatory message will appear when you finish all rooms. + +## Screenshots + +
+![image](../../assets/images/MathematicsEscapeRoom.png) +
+ +## Technologies Used + +- HTML5 +- CSS3 +- JavaScript diff --git a/Games/MathematicsEscapeRoom/index.html b/Games/MathematicsEscapeRoom/index.html new file mode 100644 index 0000000000..3750754f87 --- /dev/null +++ b/Games/MathematicsEscapeRoom/index.html @@ -0,0 +1,33 @@ + + + + + + Mathematics Escape Room + + + + +
+ + + +
+
+

Mathematics Escape Room

+
+

You are in Room 1. Solve the puzzle to find the key to Room 2!

+ + +

+
+
+
+ +
+ + + \ No newline at end of file diff --git a/Games/MathematicsEscapeRoom/script.js b/Games/MathematicsEscapeRoom/script.js new file mode 100644 index 0000000000..c68d5d4c96 --- /dev/null +++ b/Games/MathematicsEscapeRoom/script.js @@ -0,0 +1,71 @@ +const roomDescription = document.querySelector('.room-description'); +const answerInput = document.getElementById('answer'); +const checkBtn = document.getElementById('check-btn'); +const message = document.getElementById('message'); + +// Define puzzles and answers for each room +const puzzles = [ + { room: 1, question: 'What is 2 + 2?', answer: '4' }, + { room: 2, question: 'What is 5 * 3?', answer: '15' }, + { room: 3, question: 'What is 8 - 3?', answer: '5' }, + { room: 4, question: 'What is 10 / 2?', answer: '5' }, + { room: 5, question: 'What is 4 * 6?', answer: '24' }, + { room: 6, question: 'What is 12 + 7?', answer: '19' }, + { room: 7, question: 'What is 15 - 9?', answer: '6' }, + { room: 8, question: 'What is 18 / 3?', answer: '6' }, + { room: 9, question: 'What is 9 * 9?', answer: '81' }, + { room: 10, question: 'What is 25 - 12?', answer: '13' }, + { room: 11, question: 'What is 30 / 5?', answer: '6' }, + { room: 12, question: 'What is 11 * 4?', answer: '44' }, + { room: 13, question: 'What is 45 - 27?', answer: '18' }, + { room: 14, question: 'What is 64 / 8?', answer: '8' }, + { room: 15, question: 'What is 16 * 3?', answer: '48' }, + { room: 16, question: 'What is 72 + 18?', answer: '90' }, + { room: 17, question: 'What is 100 - 85?', answer: '15' }, + { room: 18, question: 'What is 144 / 12?', answer: '12' }, + { room: 19, question: 'What is 25 * 5?', answer: '125' }, + { room: 20, question: 'What is 99 - 64?', answer: '35' }, +]; + +let currentRoom = 0; + +function displayRoom() { + const currentPuzzle = puzzles[currentRoom]; + roomDescription.textContent = `You are in Room ${currentPuzzle.room}. ${currentPuzzle.question}`; + answerInput.value = ''; + answerInput.focus(); +} + +function checkAnswer() { + const userAnswer = answerInput.value.trim().toLowerCase(); + const currentPuzzle = puzzles[currentRoom]; + + if (userAnswer === currentPuzzle.answer.toLowerCase()) { + message.textContent = 'Correct answer! Moving to the next room...'; + message.style.color = '#008000'; // Green color for correct answer message + + // Move to the next room + currentRoom++; + if (currentRoom < puzzles.length) { + setTimeout(displayRoom, 1000); // Display next room after 1 second + } else { + roomDescription.textContent = 'Congratulations! You have escaped from all the rooms!'; + answerInput.style.display = 'none'; + checkBtn.style.display = 'none'; + } + } else { + message.textContent = 'Oops! Wrong answer. Try again!'; + message.style.color = '#ff0000'; // Red color for wrong answer message + } +} + +checkBtn.addEventListener('click', checkAnswer); +answerInput.addEventListener('keydown', function(event) { + if (event.key === 'Enter') { + checkAnswer(); + } +}); + +// Start the game by displaying the first room +displayRoom(); + diff --git a/Games/MathematicsEscapeRoom/style.css b/Games/MathematicsEscapeRoom/style.css new file mode 100644 index 0000000000..0c36fccbc5 --- /dev/null +++ b/Games/MathematicsEscapeRoom/style.css @@ -0,0 +1,154 @@ +@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&display=swap" rel="stylesheet'); + +body { + font-family: Arial, sans-serif; + margin: 0; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + overflow: hidden; + position: relative; + background-color: #000; /* Fallback color in case video doesn't load */ +} + +html, body { + margin: 0; + padding: 0; + height: 100%; +} +.home_btn{ + position: fixed; + top: 20px; + left: 20px; + z-index: 1000; +} +.home_btn i { + font-size: 2em; + } +.container { + text-align: center; + width: 100%; + height: 100%; + z-index: 1; +} + +.game-title { + font-family: 'Press Start 2P', sans-serif; + font-size: 2rem; + font-weight:bolder; + margin:40px 20px; + color: #fd04c7; + transition: color 0.3s ease, transform 0.5s ease; + animation: bounce 1s infinite alternate; +} + +.game-title:hover { + color: #89eef1; + transform: scale(1.1); +} + +@keyframes bounce { + 0% { + transform: scale(1); + } + 100% { + transform: scale(1.05); + } +} + +.room { + background-color: rgba(255, 255, 255, 0.7); + padding: 20px; + border-radius: 8px; + animation: fade-in 0.5s ease; + height: 50vh; + width:80vh; + display: flex; + flex-direction:column; + justify-content: center; + align-items: center; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.room-description { + font-size: 28px; + margin-bottom: 20px; + color: #0c0c0c; + font-weight: bolder; +} + +.answer-input { + margin-bottom: 10px; + padding: 8px; + width: 500px; + box-sizing: border-box; + font-size: 16px; +} + +.check-btn { + font-family: 'Orbitron', sans-serif; + padding: 10px 20px; + background-color: #130831; + color: #eeeeee; + margin-top: 20px; + border: 2px solid #1b1464; + border-radius: 20px; + font-size: 16px; + cursor: pointer; + font-weight: bolder; + transition: background-color 0.3s ease, color 0.3s ease; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.check-btn:hover { + background-color: #9df0d4; + color: #1b1464; + transform: scale(1.05); +} + +.check-btn:active { + transform: translateY(2px); +} + +.message { + margin-top: 20px; + font-weight: bold; + font-size: 14px; + color: #ff0000; +} + +@keyframes fade-in { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +#video-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; + z-index: -1; +} +video { + min-width: 100%; + min-height: 100%; + width: auto; + height: auto; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} \ No newline at end of file diff --git a/Games/Maze_Runner/README.md b/Games/Maze_Runner/README.md new file mode 100644 index 0000000000..94a3e316dc --- /dev/null +++ b/Games/Maze_Runner/README.md @@ -0,0 +1,42 @@ +# Maze_Runner +
+
+
+ +## *Description 📃* +
+
+This Maze Runner game challenges players to navigate through a randomly generated maze to reach the goal. Players control a character using arrow keys and must avoid maze walls to successfully complete each level. +- + +## *functionalities 🎮* +
+
+Navigate the maze using arrow keys (Up, Down, Left, Right). +Reach the goal represented by a green circle. +Avoid colliding with black walls (generated randomly). +Timer starts upon game start and counts down. +Game over if timer reaches zero. +Restart button available after game over to play again. + +
+ +## *How to play? 🕹️* +
+
+Movement: Use arrow keys to move the player character. +Goal: Reach the green circle to win each level. +Timer: A 60-second timer starts upon game start. +Game Over: Timer ends or player reaches goal. Restart button appears. +Restart: Click Restart to play again from the beginning. +- + +
+ +## *Screenshots 📸* + +
+ + ![image](https://github.com/sanayamahajan-23/GameZone/blob/Maze_runner/Games/Maze_Runner/assets/images/Maze_Runner.png) + +
\ No newline at end of file diff --git a/Games/Maze_Runner/index.html b/Games/Maze_Runner/index.html new file mode 100644 index 0000000000..96be2083aa --- /dev/null +++ b/Games/Maze_Runner/index.html @@ -0,0 +1,17 @@ + + + + + + Maze Runner Game + + + +
+ +
Time Left: 30s
+
+ + + + \ No newline at end of file diff --git a/Games/Maze_Runner/script.js b/Games/Maze_Runner/script.js new file mode 100644 index 0000000000..bf3ed0deec --- /dev/null +++ b/Games/Maze_Runner/script.js @@ -0,0 +1,208 @@ +const canvas = document.getElementById('gameCanvas'); +const ctx = canvas.getContext('2d'); + +const canvasWidth = 800; +const canvasHeight = 600; +canvas.width = canvasWidth; +canvas.height = canvasHeight; + +const cellSize = 40; +let level = 1; +let mazeWidth = Math.floor(canvasWidth / cellSize); +let mazeHeight = Math.floor(canvasHeight / cellSize); + +const player = { + x: 0, + y: 0, + size: cellSize / 2, + color: 'red', + speed: 5 +}; + +const goal = { + x: mazeWidth - 1, + y: mazeHeight - 1, + size: cellSize / 2, + color: 'green' +}; + +let maze = generateMaze(mazeWidth, mazeHeight); +let timeLeft = 60; +let timerInterval; + +function generateMaze(width, height) { + const maze = new Array(height).fill(null).map(() => new Array(width).fill(1)); + + function carvePassagesFrom(cx, cy, maze) { + const directions = shuffle([ + [0, -1], // Up + [1, 0], // Right + [0, 1], // Down + [-1, 0] // Left + ]); + + directions.forEach(([dx, dy]) => { + const nx = cx + dx * 2; + const ny = cy + dy * 2; + + if (nx >= 0 && ny >= 0 && nx < width && ny < height && maze[ny][nx] === 1) { + maze[cy + dy][cx + dx] = 0; + maze[ny][nx] = 0; + carvePassagesFrom(nx, ny, maze); + } + }); + } + + maze[0][0] = 0; + carvePassagesFrom(0, 0, maze); + maze[height - 1][width - 1] = 0; + + return maze; +} + +function shuffle(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +} + +function drawMaze(maze) { + ctx.clearRect(0, 0, canvasWidth, canvasHeight); + for (let y = 0; y < mazeHeight; y++) { + for (let x = 0; x < mazeWidth; x++) { + if (maze[y][x] === 1) { + ctx.fillStyle = 'black'; + ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize); + } + } + } +} + +function drawPlayer(player) { + ctx.fillStyle = player.color; + ctx.beginPath(); + ctx.arc( + player.x * cellSize + player.size, + player.y * cellSize + player.size, + player.size, + 0, + Math.PI * 2 + ); + ctx.fill(); +} + +function drawGoal(goal) { + ctx.fillStyle = goal.color; + ctx.beginPath(); + ctx.arc( + goal.x * cellSize + goal.size, + goal.y * cellSize + goal.size, + goal.size, + 0, + Math.PI * 2 + ); + ctx.fill(); +} + +function isCollision(x, y) { + return maze[y][x] === 1; +} + +function movePlayer(dx, dy) { + const newX = player.x + dx; + const newY = player.y + dy; + if (newX >= 0 && newX < mazeWidth && newY >= 0 && newY < mazeHeight && !isCollision(newX, newY)) { + player.x = newX; + player.y = newY; + checkWin(); + } +} + +function checkWin() { + if (player.x === goal.x && player.y === goal.y) { + clearInterval(timerInterval); + // Display win message + ctx.fillStyle = 'black'; + ctx.font = '30px Arial'; + ctx.fillText('You Won!', canvasWidth / 2 - 50, canvasHeight / 2); + + setTimeout(() => { + nextLevel(); + }, 3000); // 3 seconds delay before moving to the next level + } +} + +function nextLevel() { + level++; + mazeWidth = Math.floor(canvasWidth / cellSize) + level; + mazeHeight = Math.floor(canvasHeight / cellSize) + level; + player.x = 0; + player.y = 0; + goal.x = mazeWidth - 1; + goal.y = mazeHeight - 1; + maze = generateMaze(mazeWidth, mazeHeight); + timeLeft = 30; // Reset timer for the new level + startTimer(); + draw(); +} + + + +document.addEventListener('keydown', (event) => { + switch (event.key) { + case 'ArrowUp': + movePlayer(0, -1); + break; + case 'ArrowDown': + movePlayer(0, 1); + break; + case 'ArrowLeft': + movePlayer(-1, 0); + break; + case 'ArrowRight': + movePlayer(1, 0); + break; + } + draw(); +}); + +function draw() { + drawMaze(maze); + drawPlayer(player); + drawGoal(goal); +} + + +function startTimer() { + const timerDisplay = document.getElementById('time'); + clearInterval(timerInterval); + timerInterval = setInterval(() => { + if (timeLeft > 0) { + timeLeft--; + timerDisplay.textContent = timeLeft; + } else { + clearInterval(timerInterval); + alert('Game Over! Time ran out.'); + resetGame(); + } + }, 1000); +} + +function resetGame() { + level = 1; + mazeWidth = Math.floor(canvasWidth / cellSize); + mazeHeight = Math.floor(canvasHeight / cellSize); + player.x = 0; + player.y = 0; + goal.x = mazeWidth - 1; + goal.y = mazeHeight - 1; + maze = generateMaze(mazeWidth, mazeHeight); + timeLeft = 60; + startTimer(); + draw(); +} + +startTimer(); +draw(); \ No newline at end of file diff --git a/Games/Maze_Runner/styles.css b/Games/Maze_Runner/styles.css new file mode 100644 index 0000000000..91fcf5b7a6 --- /dev/null +++ b/Games/Maze_Runner/styles.css @@ -0,0 +1,28 @@ +body, html { + margin: 0; + padding: 0; + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background-color: #f0f0f0; + } + + #gameContainer { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + #gameCanvas { + border: 2px solid #000; + background-color: #fff; + } + + #timer { + margin-top: 10px; + font-size: 20px; + font-weight: bold; + } \ No newline at end of file diff --git a/Games/Memory Flip/README.md b/Games/Memory Flip/README.md new file mode 100644 index 0000000000..8f0e9ee37f --- /dev/null +++ b/Games/Memory Flip/README.md @@ -0,0 +1,50 @@ +# Memory Flip Game + +This is a simple memory flip game created using HTML, CSS, and JavaScript. The objective of the game is to find all matching pairs of cards by flipping them two at a time. + +## Features + +- Simple and intuitive user interface +- Dynamic card generation and shuffling +- Smooth card flipping animations +- Matching pairs detection + +## How to Play + +1. Open the game in a web browser. +2. Click on any card to flip it and reveal its content. +3. Click on another card to try and find its matching pair. +4. If the two flipped cards match, they will remain revealed. +5. If the two flipped cards do not match, they will be flipped back after a short delay. +6. Continue flipping cards to find all matching pairs. + +## Getting Started + +To run the game locally, follow these steps: + +1. Clone the repository or download the source code. +2. Open the `index.html` file in your preferred web browser. + +## Files + +- `index.html`: The main HTML file containing the structure of the game. +- `styles.css`: The CSS file for styling the game board and cards. +- `script.js`: The JavaScript file containing the game logic and functionality. + +## Customization + +You can customize the game by modifying the `cardsArray` in the `script.js` file to include different card values or images. + +## Example + +```javascript +const cardsArray = [ + { name: 'A', img: 'A' }, + { name: 'B', img: 'B' }, + { name: 'C', img: 'C' }, + { name: 'D', img: 'D' }, + { name: 'E', img: 'E' }, + { name: 'F', img: 'F' }, + { name: 'G', img: 'G' }, + { name: 'H', img: 'H' } +]; diff --git a/Games/Memory Flip/index.html b/Games/Memory Flip/index.html new file mode 100644 index 0000000000..70faa676c7 --- /dev/null +++ b/Games/Memory Flip/index.html @@ -0,0 +1,17 @@ + + + + + + Memory Flip Game + + + +
+
+ +
+
+ + + diff --git a/Games/Memory Flip/script.js b/Games/Memory Flip/script.js new file mode 100644 index 0000000000..3a2817e209 --- /dev/null +++ b/Games/Memory Flip/script.js @@ -0,0 +1,87 @@ +// script.js + +const cardsArray = [ + { name: 'A', img: 'A' }, + { name: 'B', img: 'B' }, + { name: 'C', img: 'C' }, + { name: 'D', img: 'D' }, + { name: 'E', img: 'E' }, + { name: 'F', img: 'F' }, + { name: 'G', img: 'G' }, + { name: 'H', img: 'H' } +]; + +// Duplicate the cards array to create pairs +const gameCards = cardsArray.concat(cardsArray); +gameCards.sort(() => 0.5 - Math.random()); // Shuffle the cards + +const gameBoard = document.getElementById('game-board'); + +let firstCard = null; +let secondCard = null; +let lockBoard = false; + +gameCards.forEach(card => { + const cardElement = document.createElement('div'); + cardElement.classList.add('card'); + cardElement.dataset.name = card.name; + + const frontFace = document.createElement('div'); + frontFace.classList.add('front'); + frontFace.textContent = card.img; + + const backFace = document.createElement('div'); + backFace.classList.add('back'); + backFace.textContent = '?'; + + cardElement.appendChild(frontFace); + cardElement.appendChild(backFace); + + cardElement.addEventListener('click', flipCard); + + gameBoard.appendChild(cardElement); +}); + +function flipCard() { + if (lockBoard) return; + if (this === firstCard) return; + + this.classList.add('flip'); + + if (!firstCard) { + firstCard = this; + return; + } + + secondCard = this; + lockBoard = true; + + checkForMatch(); +} + +function checkForMatch() { + const isMatch = firstCard.dataset.name === secondCard.dataset.name; + + isMatch ? disableCards() : unflipCards(); +} + +function disableCards() { + firstCard.removeEventListener('click', flipCard); + secondCard.removeEventListener('click', flipCard); + + resetBoard(); +} + +function unflipCards() { + setTimeout(() => { + firstCard.classList.remove('flip'); + secondCard.classList.remove('flip'); + + resetBoard(); + }, 1000); +} + +function resetBoard() { + [firstCard, secondCard] = [null, null]; + lockBoard = false; +} diff --git a/Games/Memory Flip/styles.css b/Games/Memory Flip/styles.css new file mode 100644 index 0000000000..543963b583 --- /dev/null +++ b/Games/Memory Flip/styles.css @@ -0,0 +1,64 @@ +/* styles.css */ +body { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background-color: #f0f0f0; + margin: 0; + font-family: Arial, sans-serif; +} + +.game-container { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.game-board { + display: grid; + grid-template-columns: repeat(4, 100px); + grid-gap: 10px; +} + +.card { + width: 100px; + height: 100px; + background-color: #333; + color: white; + display: flex; + justify-content: center; + align-items: center; + font-size: 24px; + cursor: pointer; + position: relative; + transform: rotateY(0deg); + transition: transform 0.5s; +} + +.card.flip { + transform: rotateY(180deg); +} + +.card .front, +.card .back { + position: absolute; + width: 100%; + height: 100%; + backface-visibility: hidden; + display: flex; + justify-content: center; + align-items: center; +} + +.card .front { + background-color: #f9f9f9; + color: #333; +} + +.card .back { + background-color: #333; + color: white; + transform: rotateY(180deg); +} diff --git a/Games/Musical_Memory/Musical_Memory.html b/Games/Musical_Memory/index.html similarity index 100% rename from Games/Musical_Memory/Musical_Memory.html rename to Games/Musical_Memory/index.html diff --git a/Games/Ninja_Hattori_Game/.DS_Store b/Games/Ninja_Hattori_Game/.DS_Store new file mode 100644 index 0000000000..6d740ce2da Binary files /dev/null and b/Games/Ninja_Hattori_Game/.DS_Store differ diff --git a/Games/Ninja_Hattori_Game/README.md b/Games/Ninja_Hattori_Game/README.md new file mode 100644 index 0000000000..e80076f104 --- /dev/null +++ b/Games/Ninja_Hattori_Game/README.md @@ -0,0 +1,10 @@ +# NinjaHattori +A very popular cartoon ninja hattori is all here ! +Dont let "kiyo" hurt ninja hattori + +- Save ninja hattori from kiyo till the destination to win +- Jump when kiyo comes your way and move ahead , +- More the number of kiyo you defeat , more will be the points +- As soon as you come in contact with kiyo , game is over + +![alt text](game.png) \ No newline at end of file diff --git a/Games/Ninja_Hattori_Game/game.png b/Games/Ninja_Hattori_Game/game.png new file mode 100644 index 0000000000..346859558f Binary files /dev/null and b/Games/Ninja_Hattori_Game/game.png differ diff --git a/Games/Ninja_Hattori_Game/hattory.png b/Games/Ninja_Hattori_Game/hattory.png new file mode 100644 index 0000000000..f71acc4b82 Binary files /dev/null and b/Games/Ninja_Hattori_Game/hattory.png differ diff --git a/Games/Ninja_Hattori_Game/index.html b/Games/Ninja_Hattori_Game/index.html new file mode 100644 index 0000000000..da699861b7 --- /dev/null +++ b/Games/Ninja_Hattori_Game/index.html @@ -0,0 +1,19 @@ + + + + + + Ninja Hattori + + + +
+
Welcome To Hattori's Game
+
Press Ctr+R To Play Again
Better Luck Next Time
+
+
Your Score: 0
+
+
+ + + \ No newline at end of file diff --git a/Games/Ninja_Hattori_Game/kiyo.png b/Games/Ninja_Hattori_Game/kiyo.png new file mode 100644 index 0000000000..87542b3d90 Binary files /dev/null and b/Games/Ninja_Hattori_Game/kiyo.png differ diff --git a/Games/Ninja_Hattori_Game/manifest.json b/Games/Ninja_Hattori_Game/manifest.json new file mode 100644 index 0000000000..ac8852e4a7 --- /dev/null +++ b/Games/Ninja_Hattori_Game/manifest.json @@ -0,0 +1,18 @@ +{ + { + "manifest_version": 3, + "name": "Ninja Hattori Game", + "version": "1.0", + "description": "Your favourite cartoon character game", + "action": { + "default_popup": "index.html", + "default_icon": "game.png" + }, + "icons": { + "16": "game.png", + "48": "game.png", + "128": "game.png" + }, + "permissions": [] + } +} \ No newline at end of file diff --git a/Games/Ninja_Hattori_Game/nhome.jpg b/Games/Ninja_Hattori_Game/nhome.jpg new file mode 100644 index 0000000000..3dda0147a9 Binary files /dev/null and b/Games/Ninja_Hattori_Game/nhome.jpg differ diff --git a/Games/Ninja_Hattori_Game/ninja.mp3 b/Games/Ninja_Hattori_Game/ninja.mp3 new file mode 100644 index 0000000000..663e9711bd Binary files /dev/null and b/Games/Ninja_Hattori_Game/ninja.mp3 differ diff --git a/Games/Ninja_Hattori_Game/script.js b/Games/Ninja_Hattori_Game/script.js new file mode 100644 index 0000000000..4ce9c49f2e --- /dev/null +++ b/Games/Ninja_Hattori_Game/script.js @@ -0,0 +1,75 @@ +score = 0; +cross = true; +audio = new Audio('ninja.MP3'); +// audio.loop=true; +setTimeout(() => { + audio.play() +}, 10); +document.onkeydown = function (e) { + console.log("Key code is: ", e.keyCode) + if (e.keyCode == 38) { + ninja = document.querySelector('.ninja'); + ninja.classList.add('animateDino'); + setTimeout(() => { + ninja.classList.remove('animateDino') + }, 700); + } + if (e.keyCode == 39) { + ninja = document.querySelector('.ninja'); + ninjaX = parseInt(window.getComputedStyle(ninja, null).getPropertyValue('left')); + ninja.style.left = ninjaX + 112 + "px"; + } + if (e.keyCode == 37) { + ninja = document.querySelector('.ninja'); + ninjaX = parseInt(window.getComputedStyle(ninja, null).getPropertyValue('left')); + ninja.style.left = (ninjaX - 112) + "px"; + } +} + +setInterval(() => { + ninja = document.querySelector('.ninja'); + gameOver = document.querySelector('.gameOver'); + obstacle = document.querySelector('.obstacle'); + + dx = parseInt(window.getComputedStyle(ninja, null).getPropertyValue('left')); + dy = parseInt(window.getComputedStyle(ninja, null).getPropertyValue('top')); + + ox = parseInt(window.getComputedStyle(obstacle, null).getPropertyValue('left')); + oy = parseInt(window.getComputedStyle(obstacle, null).getPropertyValue('top')); + + offsetX = Math.abs(dx - ox); + offsetY = Math.abs(dy - oy); + // console.log(offsetX, offsetY) + if (offsetX < 73 && offsetY < 52) { + gameOver.innerHTML = "Oops! Better Luck Next Time"; + gameOvery = document.querySelector('.gameOvery'); + container = document.querySelector('.gameContainer'); + gameOvery.style.visibility = 'visible'; + container.style.backgroundImage = 'linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5)), url(nhome.jpg)'; + obstacle.classList.remove('obstacleAni'); + setTimeout(() => { + audio.pause(); + // aud.pause(); + }, 1000); + } + else if (offsetX < 145 && cross) { + score += 1; + updateScore(score); + cross = false; + setTimeout(() => { + cross = true; + }, 1000); + setTimeout(() => { + aniDur = parseFloat(window.getComputedStyle(obstacle, null).getPropertyValue('animation-duration')); + newDur = aniDur - 0.1; + obstacle.style.animationDuration = newDur + 's'; + console.log('New animation duration: ', newDur) + }, 500); + + } + +}, 10); + +function updateScore(score) { + scoreCont.innerHTML = "Your Score: " + score +} \ No newline at end of file diff --git a/Games/Ninja_Hattori_Game/style.css b/Games/Ninja_Hattori_Game/style.css new file mode 100644 index 0000000000..d57df1dbb7 --- /dev/null +++ b/Games/Ninja_Hattori_Game/style.css @@ -0,0 +1,124 @@ +@import url('https://fonts.googleapis.com/css2?family=Lobster&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Alata&display=swap'); +*{ + margin: 0; + padding:0; +} +body{ + /*background-color: red;*/ + overflow: hidden; +} +.gameContainer{ + background-image:linear-gradient(rgba(0,0,0,0.2),rgba(0,0,0,0.2)), url(nhome.jpg); + background-repeat: no-repeat; + text-shadow: 2px 2px cyan; + color: red; + letter-spacing: 2px; + word-spacing: 3px; + background-size: 100vw 100vh; + width: 100%; + height: 100vh; +} +.gameOvery{ + visibility: hidden; + text-align: center; + font-family: 'Alata', sans-serif; + background-color: black; + margin-top: 15vw; + font-size: 3rem; + /*box-shadow: 5px 5px 5px 5px red;*/ + /*text-shadow: 2px 2px 5px red;*/ + width: 50vw; + border-radius: 10px; + border:5px dotted brown; + position: absolute; + margin-left: 320px; + color: transparent; + padding: 15px 30px; +} + +.ninja{ + background-image: url(hattory.png); + background-repeat: no-repeat; + background-size: 100% 100%; + width: 250px; + height: 215px; + position: absolute; + /*bottom:0;*/ + margin-top: 29vw; + left: 52px; +} + +.obstacle{ + width: 150px; + height: 115px; + background-image: url(kiyo.png); + background-size: 100% 100%; + position: absolute; + /*bottom: 0;*/ + margin-top: 35vw; + left: 99vw; +} + +.animateDino{ + animation: dino 0.6s ease-out; +} + +.obstacleAni{ + animation: obstacleAni 5s linear infinite; +} + +.gameOver{ + position: relative; + background-color: black; + top:20px; + margin: auto; + opacity: 0.8; + width:55vw; + border-radius: 9px; + border:3px solid white; + padding: 15px 10px; + font-size: 40px; + text-align: center; + /*font-family: 'Ubuntu', sans-serif;*/ + /*font-family: 'Londrina Solid', cursive;*/ + font-family: 'Lobster', cursive; +} + +#scoreCont{ + font-size: 25px; + color: #54212f; + font-weight: bold; + position: absolute; + margin: 25PX 535PX; + border: 2px solid black; + background-color: white; + opacity: 0.6; + padding: 10px; + font-family: 'Ubuntu', sans-serif; + border-radius: 10px; +} + +@keyframes dino{ + 0%{ + bottom: 0; + } + 50%{ + bottom: 422px; + } + 60%{ + bottom: 422px; + } + 100%{ + bottom: 0; + } +} + +@keyframes obstacleAni{ + 0%{ + left: 100vw; + } + 100%{ + left: -10vw; + } +} \ No newline at end of file diff --git a/Games/Number Guessing Game/README.md b/Games/Number Guessing Game/README.md new file mode 100644 index 0000000000..e1ab3b738a --- /dev/null +++ b/Games/Number Guessing Game/README.md @@ -0,0 +1,29 @@ +# Project Title + +Number Guessing Game + +## Features + +- Interactive Game +- One-Player Mode + +## How to Play + +1. Start the Game: + +- Open the game in your web browser. + +2. Make Your Moves: + +- Enter random number between 1 to 100 + +3. Win the Game: + +- Enter number until you guessed right + + +## Technologies Used + +- HTML +- CSS +- JavaScript \ No newline at end of file diff --git a/Games/Number Guessing Game/index.html b/Games/Number Guessing Game/index.html new file mode 100644 index 0000000000..a194fb407d --- /dev/null +++ b/Games/Number Guessing Game/index.html @@ -0,0 +1,23 @@ + + + + + + + Number Guess in Js + + + +
+
Guess a number from 1 to 100
+

+
+ + +
+

You have 10 chances

+
+ + + + \ No newline at end of file diff --git a/Games/Number Guessing Game/script.js b/Games/Number Guessing Game/script.js new file mode 100644 index 0000000000..3739d60197 --- /dev/null +++ b/Games/Number Guessing Game/script.js @@ -0,0 +1,47 @@ +const input = document.querySelector("input"), + guess = document.querySelector(".guess"), + checkButton = document.querySelector("button"), + remainChances = document.querySelector(".chances"); + +input.focus(); + +let randomNum = Math.floor(Math.random() * 100); +chance = 10; + +checkButton.addEventListener("click", () => { + // Decrement the chance variable on every click + chance--; + let inputValue = input.value; + // Check if the input value is equal to the random number + if (inputValue == randomNum) { + // Update guessed number, disable input, check button text and color. + [guess.textContent, input.disabled] = ["Congratulations!!", true]; + [checkButton.textContent, guess.style.color] = ["Replay", "#333"]; + checkButton.addEventListener("click",()=>{ + window.location.reload(); + + }) + //Check if input value is > random number and within 1-99 range. + } else if (inputValue > randomNum && inputValue < 100) { + // Update the guess text and remaining chances + [guess.textContent, remainChances.textContent] = ["Your guess is high", chance]; + guess.style.color = "#333"; + //Check if input value is < random number and within 1-99 range. + } else if (inputValue < randomNum && inputValue > 0) { + // Update the guessed number text and remaining chances + [guess.textContent, remainChances.textContent] = ["Your guess is low", chance]; + } else { + // Update the guessed number text, color and remaining chances + [guess.textContent, remainChances.textContent] = ["Your number is invalid", chance]; + guess.style.color = "#DE0611"; + } + if (chance == 0) { + //Update check button, disable input, and clear input value. + // Update guessed number text and color to indicate user loss. + [checkButton.textContent, input.disabled, inputValue] = ["Replay", true, ""]; + [guess.textContent, guess.style.color] = ["You lost the game", "#DE0611"]; + } + if (chance < 0) { + window.location.reload(); + } +}); \ No newline at end of file diff --git a/Games/Number Guessing Game/style.css b/Games/Number Guessing Game/style.css new file mode 100644 index 0000000000..d66652b350 --- /dev/null +++ b/Games/Number Guessing Game/style.css @@ -0,0 +1,128 @@ +/* Import Google font - Poppins */ +@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap"); +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: "Poppins", sans-serif; +} + +body { + min-height: 100vh; + min-width: 100vh; + display: flex; + align-items: center; + justify-content: center; + background-image: url(bg.jpg); + background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); + background-size: 400% 400%; + animation: gradient 15s ease infinite; +} + +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +.wrapper { + padding: 30px 40px; + width: 50vw; + border-radius: 12px; + background: #f0def5; + text-align: center; + box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.8); +} +.wrapper header { + font-size: 25px; + font-weight: 500; + color: #541d5a; + text-transform: capitalize; + font-family: "Poppins", sans-serif; + font-weight: 400; + font-style: normal; + text-shadow: 1px 1px 0px rgba(0,0,0,0.5); +} +.wrapper p { + font-size: 18px; + color: #2c0533; +} +.wrapper .input-field { + display: flex; + justify-content: center; + gap: 20px; + margin: 25px 0; +} +.input-field input, +.input-field button { + height: 50px; + width: calc(100% / 2 - 20px); + outline: none; + padding: 0 20px; + border-radius: 8px; + font-size: 18px; +} +.input-field input { + text-align: center; + color: #2b272d; + background-color: rgba(228, 199, 227, 0.8); + width: 110px; + border: 1px solid #aaa; + box-shadow: 0.5px 0.5px 1px black; +} + +.input-field input:hover { + text-align: center; + color: #2b272d; + background-color: rgba(228, 199, 227, 0.5); + width: 110px; + box-shadow: 0.5px 0.5px 1px black; + border: 1px solid #000000; +} + +input::-webkit-inner-spin-button, +input::-webkit-outer-spin-button { + display: none; +} +.input-field input:disabled { + cursor: not-allowed; +} +.input-field button { + border: none; + background: #8e26a0; + color: #f0d8f1; + font-size: 20px; + cursor: pointer; + transition: 0.3s; +} + +.input-field button:hover { + border: none; + color: #711c81; + background-color: #e2b9e3; + box-shadow: 1px 1px 1px black; + cursor: pointer; + transition: 0.3s; +} + +.input-field button:active { + transform: scale(0.97); +} + + +@media screen and (max-width:600px) { +.wrapper { + padding: 30px 40px; + width: 60vw; + border-radius: 12px; + background: #f0def5; + text-align: center; + box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.8); + } +} \ No newline at end of file diff --git a/Games/Otherworldly_Odyssey/README.md b/Games/Otherworldly_Odyssey/README.md new file mode 100644 index 0000000000..28a492f6cb --- /dev/null +++ b/Games/Otherworldly_Odyssey/README.md @@ -0,0 +1,38 @@ +# **Otherworldly Odyssey** + +--- + +
+ +## **Description 📃** +It's an adventure role playing game where players will journey through a magical realm full of fantastic creatures, deadly challenges, and hidden surprises. +- + +## **functionalities 🎮** +1. This game has an innovative XP system which would make it more engaging and fun to play. +2. A money system which can be used to buy various products. +3. A shop where the adventurers can buy elixirs to increase or recover their health or weapons ranging from a simple dagger to a legendary magic wand. +4. Player can earn money and farm XP by fighting various monsters to ultimately challenge the greatest threat this realm has ever faced a "Primordial Dragon". +5. An Easter Egg minigame hidden in the main game. +- +
+ +## **How to play? 🕹️** +Simply click on the button of the action you'll like to choose to perform and follow the instructions. +- + +
+ +## **Screenshots 📸** + +
+ + +![ss1](./img/Screenshot%20(2).png) +![ss2](./img/Screenshot%20(3).png) +![ss3](./img/Screenshot%20(4).png) + +
+ +## **Working video 📹** + \ No newline at end of file diff --git a/Games/Otherworldly_Odyssey/img/23.png b/Games/Otherworldly_Odyssey/img/23.png new file mode 100644 index 0000000000..363ee76432 Binary files /dev/null and b/Games/Otherworldly_Odyssey/img/23.png differ diff --git a/Games/Otherworldly_Odyssey/img/Screenshot (2).png b/Games/Otherworldly_Odyssey/img/Screenshot (2).png new file mode 100644 index 0000000000..b9083f0dce Binary files /dev/null and b/Games/Otherworldly_Odyssey/img/Screenshot (2).png differ diff --git a/Games/Otherworldly_Odyssey/img/Screenshot (3).png b/Games/Otherworldly_Odyssey/img/Screenshot (3).png new file mode 100644 index 0000000000..a800e7e6ff Binary files /dev/null and b/Games/Otherworldly_Odyssey/img/Screenshot (3).png differ diff --git a/Games/Otherworldly_Odyssey/img/Screenshot (4).png b/Games/Otherworldly_Odyssey/img/Screenshot (4).png new file mode 100644 index 0000000000..0b9d520df8 Binary files /dev/null and b/Games/Otherworldly_Odyssey/img/Screenshot (4).png differ diff --git a/Games/Otherworldly_Odyssey/index.html b/Games/Otherworldly_Odyssey/index.html new file mode 100644 index 0000000000..d43a47799c --- /dev/null +++ b/Games/Otherworldly_Odyssey/index.html @@ -0,0 +1,38 @@ + + + + + + + Otherworldly Odyssey + + + +

Otherworldly Odyssey

+ +
+ +
+ XP: 0 + Health: 1000 + Gold: 50 +
+ +
+ Monster Name: + Health: +
+ +
+ Welcome to Otherworldly Odyssey. You must defeat the primordial dragon - Tiamut that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons below. +
+ +
+ + + +
+
+ + + \ No newline at end of file diff --git a/Games/Otherworldly_Odyssey/script.js b/Games/Otherworldly_Odyssey/script.js new file mode 100644 index 0000000000..d6ffcc210c --- /dev/null +++ b/Games/Otherworldly_Odyssey/script.js @@ -0,0 +1,308 @@ +// Initialize game variables +let xp = 0; +let health = 1000; +let gold = 50; +let currentWeapon = 0; +let fighting; +let monsterHealth; +let inventory = ["Arondight"]; + +// Select DOM elements +const button1 = document.querySelector('#button1'); +const button2 = document.querySelector("#button2"); +const button3 = document.querySelector("#button3"); +const text = document.querySelector("#text"); +const xpText = document.querySelector("#xpText"); +const healthText = document.querySelector("#healthText"); +const goldText = document.querySelector("#goldText"); +const monsterStats = document.querySelector("#monsterStats"); +const monsterName = document.querySelector("#monsterName"); +const monsterHealthText = document.querySelector("#monsterHealth"); + +// Define weapons +const weapons = [ + { name: 'Arondight', power: 50 }, + { name: 'Excalibur', power: 100 }, + { name: 'Rhongomiant', power: 200 }, + { name: 'Durendal', power: 350 }, + { name: 'Gáe Bulg', power: 550 }, + { name: 'Kusanagi', power: 800 }, + { name: 'Ru Yi Jing Gu Bang', power: 1100 }, + { name: 'Mjölnir', power: 1450 }, + { name: 'The Sword of Surtr', power: 1850 }, + { name: "Gungnir - Odin's spear", power: 2300 }, +]; + +// Define monsters +const monsters = [ + { + name: "Basilisk", + level: 20, + health: 300 + }, + { + name: "Yamata no Orochi", + level: 160, + health: 1200 + }, + { + name: "Tiamat - Primordial Dragon", + level: 800, + health: 9600 + } +] + +// Define game locations +const locations = [ + { + name: "town square", + "button text": ["Go to store", "Go to cave", "Fight Tiamat"], + "button functions": [goStore, goCave, fightTiamat], + text: "You are in the town square. You see a sign that says \"Store\"." + }, + { + name: "store", + "button text": ["Buy 10 health (10 gold)", "Buy weapon (30 gold)", "Go to town square"], + "button functions": [buyHealth, buyWeapon, goTown], + text: "You enter the store." + }, + { + name: "cave", + "button text": ["Fight Basilisk", "Fight Yamata no Orochi", "Go to town square"], + "button functions": [fightBasilisk, fightYamata, goTown], + text: "You enter the cave. You see some monsters." + }, + { + name: "fight", + "button text": ["Attack", "Dodge", "Run"], + "button functions": [attack, dodge, goTown], + text: "You are fighting a monster." + }, + { + name: "kill monster", + "button text": ["Go to town square", "Go to town square", "Go to town square"], + "button functions": [goTown, goTown, easterEgg], + text: 'The monster screams "Arg!" as it dies. You gain experience points and find gold.' + }, + { + name: "lose", + "button text": ["REPLAY?", "REPLAY?", "REPLAY?"], + "button functions": [restart, restart, restart], + text: "You die. ☠" + }, + { + name: "win", + "button text": ["REPLAY?", "REPLAY?", "REPLAY?"], + "button functions": [restart, restart, restart], + text: "You defeat the Great Tiamat! YOU WIN THE GAME! 🎉" + }, + { + name: "easter egg", + "button text": ["2", "8", "Go to town square?"], + "button functions": [pickTwo, pickEight, goTown], + text: "You find a secret game. Pick a number above. Ten numbers will be randomly chosen between 0 and 10. If the number you choose matches one of the random numbers, you win!" + } +]; + +// Initialize button click handlers +button1.onclick = goStore; +button2.onclick = goCave; +button3.onclick = fightTiamat; + +// Function to update game state based on location +function update(location) { + monsterStats.style.display = "none"; + button1.innerText = location["button text"][0]; + button2.innerText = location["button text"][1]; + button3.innerText = location["button text"][2]; + button1.onclick = location["button functions"][0]; + button2.onclick = location["button functions"][1]; + button3.onclick = location["button functions"][2]; + text.innerHTML = location.text; +} + +// Navigation functions +function goTown() { + update(locations[0]); +} + +function goStore() { + update(locations[1]); +} + +function goCave() { + update(locations[2]); +} + +// Store functions +function buyHealth() { + if (gold >= 10) { + gold -= 10; + health += 500; + goldText.innerText = gold; + healthText.innerText = health; + } else { + text.innerText = "You do not have enough gold to buy health."; + } +} + +function buyWeapon() { + if (currentWeapon < weapons.length - 1) { + if (gold >= 30) { + gold -= 30; + currentWeapon++; + goldText.innerText = gold; + let newWeapon = weapons[currentWeapon].name; + text.innerText = "You now have a " + newWeapon + "."; + inventory.push(newWeapon); + text.innerText += " In your inventory you have: " + inventory; + } else { + text.innerText = "You do not have enough gold to buy a weapon."; + } + } else { + text.innerText = "You already have the most powerful weapon!"; + button2.innerText = "Sell weapon for 15 gold"; + button2.onclick = sellWeapon; + } +} + +function sellWeapon() { + if (inventory.length > 1) { + gold += 15; + goldText.innerText = gold; + let currentWeapon = inventory.shift(); + text.innerText = "You sold a " + currentWeapon + "."; + text.innerText += " In your inventory you have: " + inventory; + } else { + text.innerText = "Don't sell your only weapon!"; + } +} + +// Combat functions +function fightBasilisk() { + fighting = 0; + goFight(); +} + +function fightYamata() { + fighting = 1; + goFight(); +} + +function fightTiamat() { + fighting = 2; + goFight(); +} + +function goFight() { + update(locations[3]); + monsterHealth = monsters[fighting].health; + monsterStats.style.display = "block"; + monsterName.innerText = monsters[fighting].name; + monsterHealthText.innerText = monsterHealth; +} + +function attack() { + text.innerText = "The " + monsters[fighting].name + " attacks."; + text.innerText += " You attack it with your " + weapons[currentWeapon].name + "."; + health -= getMonsterAttackValue(monsters[fighting].level); + if (isMonsterHit()) { + monsterHealth -= weapons[currentWeapon].power + Math.floor(Math.random() * xp) + 1; + } else { + text.innerText += " You miss."; + } + healthText.innerText = health; + monsterHealthText.innerText = monsterHealth; + if (health <= 0) { + lose(); + } else if (monsterHealth <= 0) { + if (fighting === 2) { + winGame(); + } else { + defeatMonster(); + } + } + if (Math.random() <= .1 && inventory.length !== 1) { + text.innerText += " Your " + inventory.pop() + " breaks."; + currentWeapon--; + } +} + +function getMonsterAttackValue(level) { + const hit = (level * 5) - (Math.floor(Math.random() * xp)); + console.log(hit); + return hit > 0 ? hit : 0; +} + +function isMonsterHit() { + return Math.random() > .2 || health < 20; +} + +function dodge() { + text.innerText = "You dodge the attack from the " + monsters[fighting].name; +} + +function defeatMonster() { + gold += Math.floor(monsters[fighting].level * 6.7); + xp += monsters[fighting].level; + goldText.innerText = gold; + xpText.innerText = xp; + update(locations[4]); +} + +// Game end states +function lose() { + update(locations[5]); +} + +function winGame() { + update(locations[6]); +} + +function restart() { + xp = 0; + health = 1000; + gold = 50; + currentWeapon = 0; + inventory = ["Arondight"]; + goldText.innerText = gold; + healthText.innerText = health; + xpText.innerText = xp; + goTown(); +} + +// Easter egg mini-game +function easterEgg() { + update(locations[7]); +} + +function pickTwo() { + pick(2); +} + +function pickEight() { + pick(8); +} + +function pick(guess) { + const numbers = []; + while (numbers.length < 10) { + numbers.push(Math.floor(Math.random() * 11)); + } + text.innerText = "You picked " + guess + ". Here are the random numbers:\n"; + for (let i = 0; i < 10; i++) { + text.innerText += numbers[i] + "\n"; + } + if (numbers.includes(guess)) { + text.innerText += "Right! You win 20 gold!"; + gold += 20; + goldText.innerText = gold; + } else { + text.innerText += "Wrong! You lose 10 health!"; + health -= 10; + healthText.innerText = health; + if (health <= 0) { + lose(); + } + } +} \ No newline at end of file diff --git a/Games/Otherworldly_Odyssey/style.css b/Games/Otherworldly_Odyssey/style.css new file mode 100644 index 0000000000..ebc77aa11b --- /dev/null +++ b/Games/Otherworldly_Odyssey/style.css @@ -0,0 +1,157 @@ +/* Global body styles */ +body { + margin: 0; + padding: 0; + min-height: 100vh; + background-color: #0a0a23; + background-image: url('img/23.png'); + background-size: cover; + background-position: center; + background-repeat: no-repeat; + background-attachment: fixed; + font-size: 16px; + } + +/* Game text area styles */ +#text { + background-color: rgba(10, 10, 35, 0.5); + color: #ffffff; + padding: 10px; + } + +/* Main game container styles */ +#game { + max-width: 90%; /* Responsive width */ + max-height: none; /* Remove max-height */ + margin: 20px auto; + padding: 10px; + background-color: rgba(0, 0, 10, 0); + } + +/* Styles for controls and stats sections */ +#controls, +#stats { + border: 1px solid #0a0a23; + padding: 5px; + color: #0a0a23; + background-color: rgba(0, 0, 10, 0.5); + } + +/* Control buttons layout */ +#controls { + display: flex; + justify-content: space-between; + padding: 10px; + flex-direction: column; /* Stack buttons vertically on mobile */ + gap: 10px; /* Add space between buttons */ + } + +/* Monster stats section styles */ +#monsterStats { + display: none; + border: 1px solid #0a0a23; + padding: 5px; + color: #ffffff; + background-color: #c70d0d; + } + +/* Individual stat styling */ +.stat { + padding-right: 10px; + } + +/* Button styles */ +button { + cursor: pointer; + color: #0a0a23; + background-color: #feac32; + background-image: linear-gradient(#fecc4c, #ffac33); + border: 3px solid #feac32; + border-radius: 20px; + cursor: pointer; + transition: box-shadow 0.3s ease-in-out, transform 0.1s ease-in-out; + width: 100%; /* Full width buttons */ + padding: 10px; /* Larger touch target */ + font-size: 1em; /* Relative font size */ + } + +/* Button hover effect */ +button:hover { + box-shadow: 0 0 15px 5px rgba(255, 165, 0, 0.7); /* Glow effect */ + transform: scale(1.05); /* Slightly increase size on hover */ +} + +/* Centering utility class */ +.centered-div { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + +/* Gradient text effect for title */ +.gradient-text { + font-size: 2em; /* Relative font size */ + font-weight: bold; + background: linear-gradient( + to right, + #4285F4, /* Blue */ + #f4009f, /* Pink */ + #DB4437, /* Red */ + #5d0f9d, /* Purple */ + #4285F4 /* Blue again to loop smoothly */ + ); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + background-size: 200% auto; + animation: gradient-animation 10s linear infinite; + text-align: center; + } + +/* Keyframes for gradient animation */ +@keyframes gradient-animation { + 0% { + background-position: 0% center; + } + 100% { + background-position: -200% center; + } + } + +/* XP stat styling */ +.xpStat { + color:#8c00ff; + text-shadow: 0 0 10px #8c00ff, 0 0 20px #8c00ff, 0 0 30px #8c00ff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + +/* Health stat styling */ +.healthStat { + color: #ff0000 ; + text-shadow: 0 0 10px #ff0000, 0 0 20px #ff0000, 0 0 30px #ff0000, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + +/* Gold stat styling */ +.goldStat { + color: #FFD300; + text-shadow: 0 0 10px #FFD300, 0 0 20px #FFD300, 0 0 30px #FFD300, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + +/* Media query for larger screens */ +@media screen and (min-width: 768px) { + #game { + max-width: 500px; + } + + #controls { + flex-direction: row; + } + + button { + width: auto; + } + + .gradient-text { + font-size: 48px; + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/assets/sounds/music/music-0.wav b/Games/OutRun_Offline_Game/assets/sounds/music/music-0.wav new file mode 100644 index 0000000000..905ab756c8 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sounds/music/music-0.wav differ diff --git a/Games/OutRun_Offline_Game/assets/sounds/music/music-1.wav b/Games/OutRun_Offline_Game/assets/sounds/music/music-1.wav new file mode 100644 index 0000000000..cc05e2aabe Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sounds/music/music-1.wav differ diff --git a/Games/OutRun_Offline_Game/assets/sounds/music/music-2.wav b/Games/OutRun_Offline_Game/assets/sounds/music/music-2.wav new file mode 100644 index 0000000000..93a779377c Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sounds/music/music-2.wav differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/background/alps/back.png b/Games/OutRun_Offline_Game/assets/sprites/background/alps/back.png new file mode 100644 index 0000000000..7bb02245f0 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/background/alps/back.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/background/alps/front.png b/Games/OutRun_Offline_Game/assets/sprites/background/alps/front.png new file mode 100644 index 0000000000..7f2582cef5 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/background/alps/front.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/back.png b/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/back.png new file mode 100644 index 0000000000..ee97c15332 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/back.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/front.png b/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/front.png new file mode 100644 index 0000000000..b20d4ec219 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/front.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/0.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/0.png new file mode 100644 index 0000000000..acbeca69b9 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/0.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/1.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/1.png new file mode 100644 index 0000000000..80c2413548 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/1.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/2.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/2.png new file mode 100644 index 0000000000..4a0e3adad5 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/2.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/3.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/3.png new file mode 100644 index 0000000000..9913bef47a Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/3.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/4.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/4.png new file mode 100644 index 0000000000..2da8d7d809 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/4.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/5.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/5.png new file mode 100644 index 0000000000..445370d1a7 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/5.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/6.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/6.png new file mode 100644 index 0000000000..844accdaf9 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/6.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/7.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/7.png new file mode 100644 index 0000000000..ede5dc45f0 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/7.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/8.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/8.png new file mode 100644 index 0000000000..65cf613440 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/8.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/9.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/9.png new file mode 100644 index 0000000000..4cb152cb43 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/9.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/kmh.png b/Games/OutRun_Offline_Game/assets/sprites/hud/kmh.png new file mode 100644 index 0000000000..7f320b8996 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/kmh.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/alps.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/alps.png new file mode 100644 index 0000000000..856e53cedd Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/alps.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/autobahn.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/autobahn.png new file mode 100644 index 0000000000..758ee467f9 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/autobahn.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/cloudy-mountain.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/cloudy-mountain.png new file mode 100644 index 0000000000..e561192919 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/cloudy-mountain.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/coconut-beach.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/coconut-beach.png new file mode 100644 index 0000000000..9e432b2ae3 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/coconut-beach.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/death-valley.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/death-valley.png new file mode 100644 index 0000000000..9eabcc3deb Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/death-valley.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/desert.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/desert.png new file mode 100644 index 0000000000..39f64ffbc6 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/desert.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/desolation-hill.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/desolation-hill.png new file mode 100644 index 0000000000..6574f14a83 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/desolation-hill.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/devils-canyon.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/devils-canyon.png new file mode 100644 index 0000000000..38eedb4da8 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/devils-canyon.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/gateaway.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/gateaway.png new file mode 100644 index 0000000000..c58b5eed53 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/gateaway.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/lakeside.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/lakeside.png new file mode 100644 index 0000000000..5764480695 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/lakeside.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/old-capital.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/old-capital.png new file mode 100644 index 0000000000..e80f8cc595 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/old-capital.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/seaside-town.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/seaside-town.png new file mode 100644 index 0000000000..0695c9c6de Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/seaside-town.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/vineyard.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/vineyard.png new file mode 100644 index 0000000000..392f57d79f Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/vineyard.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/wheat-field.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/wheat-field.png new file mode 100644 index 0000000000..80a2075f99 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/wheat-field.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/wilderness.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/wilderness.png new file mode 100644 index 0000000000..b70e42c114 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/wilderness.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/loading/loading-box.png b/Games/OutRun_Offline_Game/assets/sprites/loading/loading-box.png new file mode 100644 index 0000000000..ed79517a89 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/loading/loading-box.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/loading/loading-text.png b/Games/OutRun_Offline_Game/assets/sprites/loading/loading-text.png new file mode 100644 index 0000000000..f9b54e8eef Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/loading/loading-text.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/menu/logo-bg-5.png b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-bg-5.png new file mode 100644 index 0000000000..55ac44dfd9 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-bg-5.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/menu/logo-car.png b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-car.png new file mode 100644 index 0000000000..572b8af2cd Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-car.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/menu/logo-road.png b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-road.png new file mode 100644 index 0000000000..ee208de922 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-road.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio-car.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-car.png new file mode 100644 index 0000000000..780dadbcf7 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-car.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-green.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-green.png new file mode 100644 index 0000000000..29de76dfeb Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-green.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-red.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-red.png new file mode 100644 index 0000000000..7236d58274 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-red.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio-freq-1.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-freq-1.png new file mode 100644 index 0000000000..dfe907253b Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-freq-1.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio.png new file mode 100644 index 0000000000..d94a6e71ea Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/music-0.png b/Games/OutRun_Offline_Game/assets/sprites/text/music-0.png new file mode 100644 index 0000000000..627e8159a8 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/music-0.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/music-1.png b/Games/OutRun_Offline_Game/assets/sprites/text/music-1.png new file mode 100644 index 0000000000..7ecd846fda Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/music-1.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/music-2.png b/Games/OutRun_Offline_Game/assets/sprites/text/music-2.png new file mode 100644 index 0000000000..31ebaaff1f Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/music-2.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/press-enter.png b/Games/OutRun_Offline_Game/assets/sprites/text/press-enter.png new file mode 100644 index 0000000000..2a6fe34aac Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/press-enter.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/select-music.png b/Games/OutRun_Offline_Game/assets/sprites/text/select-music.png new file mode 100644 index 0000000000..e211e7f55b Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/select-music.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/vehicles/vehicle-0/left-0.png b/Games/OutRun_Offline_Game/assets/sprites/vehicles/vehicle-0/left-0.png new file mode 100644 index 0000000000..4bab6609ff Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/vehicles/vehicle-0/left-0.png differ diff --git a/Games/OutRun_Offline_Game/index.html b/Games/OutRun_Offline_Game/index.html new file mode 100644 index 0000000000..f9ba4f6848 --- /dev/null +++ b/Games/OutRun_Offline_Game/index.html @@ -0,0 +1,30 @@ + + + + Outrun + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Assets.js b/Games/OutRun_Offline_Game/main/Assets.js new file mode 100644 index 0000000000..e5753b6609 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Assets.js @@ -0,0 +1,585 @@ +let sprites = {}; +let sounds = {}; +let colors = {}; +let dimensions = {}; + +var loading = 0; +var maxLoading = 0; + +function loadAssets() { + //\\//\\ LOADING //\\//\\ + sprites['loading-text'] = loadSprite('loading/loading-text'); + sprites['loading-box'] = loadSprite('loading/loading-box'); + Outrun.drawLoading(); + //\\//\\ MENU ASSETS //\\//\\ + // LOADING MENU SPRITES + sprites['logo-bg-0'] = loadSprite('menu/logo-bg-0'); + sprites['logo-bg-1'] = loadSprite('menu/logo-bg-1'); + sprites['logo-bg-2'] = loadSprite('menu/logo-bg-2'); + sprites['logo-bg-3'] = loadSprite('menu/logo-bg-3'); + sprites['logo-bg-4'] = loadSprite('menu/logo-bg-4'); + sprites['logo-bg-5'] = loadSprite('menu/logo-bg-5'); + sprites['logo-road'] = loadSprite('menu/logo-road'); + sprites['logo-car'] = loadSprite('menu/logo-car'); + sprites['logo-tree-0'] = loadSprite('menu/logo-tree-0'); + sprites['logo-tree-1'] = loadSprite('menu/logo-tree-1'); + sprites['logo-tree-2'] = loadSprite('menu/logo-tree-2'); + sprites['logo-text'] = loadSprite('menu/logo-text'); + //\\//\\ RADIO ASSETS //\\//\\ + // LOADING RADIO SPRITES + sprites['radio-car'] = loadSprite('radio/radio-car'); + sprites['radio'] = loadSprite('radio/radio'); + sprites['radio-freq-0'] = loadSprite('radio/radio-freq-0'); + sprites['radio-freq-1'] = loadSprite('radio/radio-freq-1'); + sprites['radio-freq-2'] = loadSprite('radio/radio-freq-2'); + sprites['radio-dot-red'] = loadSprite('radio/radio-dot-red'); + sprites['radio-dot-green'] = loadSprite('radio/radio-dot-green'); + sprites['radio-hand-0'] = loadSprite('radio/radio-hand-0'); + sprites['radio-hand-1'] = loadSprite('radio/radio-hand-1'); + sprites['radio-hand-2'] = loadSprite('radio/radio-hand-2'); + // LOADING RADIO SAMPLES + sounds['wave'] = loadSound('sample/wave'); + sounds['coin'] = loadSound('sample/coin'); + sounds['signal-0'] = loadSound('sample/signal-0'); + sounds['signal-1'] = loadSound('sample/signal-1'); + Outrun.drawLoading(); + //\\//\\ IN-GAME ASSETS //\\//\\ + // LOADING IN-GAME SPRITES + var tunnel = loadSprite('environment/tunnel'); + sprites['coconut-beach'] = { + back: loadSprite('background/coconut-beach/back'), + front: loadSprite('background/coconut-beach/front'), + tunnel: tunnel, + terrain: loadSprite('environment/coconut-beach/terrain'), + left1: loadSprite('environment/coconut-beach/sail-1'), + left2: loadSprite('environment/coconut-beach/sail-2'), + right1: loadSprite('environment/coconut-beach/tree'), + right2: loadSprite('environment/coconut-beach/bush'), + start0: loadSprite('environment/start-flag-0'), + start1: loadSprite('environment/start-flag-1'), + start2: loadSprite('environment/start-flag-2'), + start3: loadSprite('environment/start-flag-3') + }; + dimensions['coconut-beach'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(9760, 320, -9500), + left1: createDimension(765, 1500, -8000), + left2: createDimension(765, 1500, -9000), + right1: createDimension(1170, 2520, 5000), + right2: createDimension(1280, 790, 5000), + start0: createDimension(4720, 1760, -2000), + start1: createDimension(4720, 1760, -2000), + start2: createDimension(4720, 1760, -2000), + start3: createDimension(4720, 1760, -2000), + }; + sprites['gateaway'] = { + back: loadSprite('background/gateaway/back'), + front: loadSprite('background/gateaway/front'), + tunnel: tunnel, + terrain: loadSprite('environment/gateaway/terrain'), + left1: loadSprite('environment/gateaway/arcade-sign'), + left2: loadSprite('environment/gateaway/motorcycle-sign'), + right1: loadSprite('environment/gateaway/castle'), + right2: loadSprite('environment/gateaway/castle') + }; + dimensions['gateaway'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(9760, 320, -9500), + left1: createDimension(1250, 1690, -6000), + left2: createDimension(1080, 1030, -6000), + right1: createDimension(1230, 1830, 5000), + right2: createDimension(1230, 1830, 5000) + }; + sprites['devils-canyon'] = { + back: loadSprite('background/devils-canyon/back'), + front: loadSprite('background/devils-canyon/front'), + tunnel: tunnel, + terrain: loadSprite('environment/devils-canyon/terrain'), + left1: loadSprite('environment/devils-canyon/sega-sign'), + left2: loadSprite('environment/devils-canyon/diving-sign'), + right1: loadSprite('environment/devils-canyon/rock'), + right2: loadSprite('environment/devils-canyon/rock') + }; + dimensions['devils-canyon'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(9760, 320, -9500), + left1: createDimension(1440, 920, -6000), + left2: createDimension(1160, 800, -6000), + right1: createDimension(1720, 1780, 5000), + right2: createDimension(1720, 1780, 5000) + }; + sprites['desert'] = { + back: loadSprite('background/desert/back'), + front: loadSprite('background/desert/front'), + tunnel: tunnel, + left1: loadSprite('environment/desert/dry-tree'), + left2: loadSprite('environment/desert/dry-tree'), + right1: loadSprite('environment/desert/terrain'), + right2: loadSprite('environment/desert/terrain') + }; + dimensions['desert'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(440, 760, -5000), + left2: createDimension(440, 760, 5000), + right1: createDimension(9760, 320, -9500), + right2: createDimension(9760, 320, 9500) + }; + Outrun.drawLoading(); + sprites['alps'] = { + back: loadSprite('background/alps/back'), + front: loadSprite('background/alps/front'), + tunnel: tunnel, + left1: loadSprite('environment/alps/mill-1'), + left2: loadSprite('environment/alps/mill-2'), + right1: loadSprite('environment/alps/terrain-1'), + right2: loadSprite('environment/alps/terrain-2') + }; + dimensions['alps'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(1080, 1400, 6000), + left2: createDimension(1080, 1400, -6000), + right1: createDimension(9760, 320, -9500), + right2: createDimension(9760, 320, 9500) + }; + sprites['cloudy-mountain'] = { + back: loadSprite('background/cloudy-mountain/back'), + front: loadSprite('background/cloudy-mountain/front'), + tunnel: tunnel, + terrain: loadSprite('environment/cloudy-mountain/clouds'), + right1: loadSprite('environment/cloudy-mountain/tree'), + right2: loadSprite('environment/cloudy-mountain/tree') + }; + dimensions['cloudy-mountain'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(19250, 3000, 0), + right1: createDimension(2480, 2480, -6000), + right2: createDimension(2480, 2480, 6000) + }; + sprites['wilderness'] = { + back: loadSprite('background/wilderness/back'), + front: loadSprite('background/wilderness/front'), + tunnel: tunnel, + left1: loadSprite('environment/wilderness/rock-1'), + left2: loadSprite('environment/wilderness/rock-2'), + right1: loadSprite('environment/wilderness/cut-tree'), + right2: loadSprite('environment/wilderness/dry-tree') + }; + dimensions['wilderness'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(1160, 420, 6000), + left2: createDimension(1160, 550, -6000), + right1: createDimension(885, 660, 6000), + right2: createDimension(880, 1530, -5000) + }; + sprites['old-capital'] = { + back: loadSprite('background/old-capital/back'), + front: loadSprite('background/old-capital/front'), + tunnel: tunnel, + left1: loadSprite('environment/old-capital/tower'), + left2: loadSprite('environment/old-capital/hut'), + right1: loadSprite('environment/old-capital/tree-1'), + right2: loadSprite('environment/old-capital/tree-2') + }; + dimensions['old-capital'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(720, 1640, -5000), + left2: createDimension(1200, 860, -6000), + right1: createDimension(945, 2400, 5500), + right2: createDimension(1740, 1980, 6000) + }; + sprites['wheat-field'] = { + back: loadSprite('background/wheat-field/back'), + front: loadSprite('background/wheat-field/front'), + tunnel: tunnel, + left1: loadSprite('environment/wheat-field/motorcycle-sign'), + left2: loadSprite('environment/wheat-field/tree'), + right1: loadSprite('environment/wheat-field/terrain'), + right2: loadSprite('environment/wheat-field/terrain'), + }; + dimensions['wheat-field'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(1080, 1030, -6000), + left2: createDimension(1740, 1980, -6000), + right1: createDimension(9760, 320, 9500), + right2: createDimension(9760, 320, 9500) + }; + Outrun.drawLoading(); + sprites['seaside-town'] = { + back: loadSprite('background/seaside-town/back'), + front: loadSprite('background/seaside-town/front'), + tunnel: tunnel, + terrain: loadSprite('environment/seaside-town/terrain'), + right1: loadSprite('environment/seaside-town/tower'), + right2: loadSprite('environment/seaside-town/hut') + }; + dimensions['seaside-town'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(9760, 320, -9500), + right1: createDimension(720, 1640, 5000), + right2: createDimension(1200, 860, 5500) + }; + sprites['vineyard'] = { + back: loadSprite('background/vineyard/back'), + front: loadSprite('background/vineyard/front'), + tunnel: tunnel, + right1: loadSprite('environment/vineyard/terrain'), + right2: loadSprite('environment/vineyard/terrain'), + goal: loadSprite('environment/goal') + }; + dimensions['vineyard'] = { + tunnel: createDimension(4800, 2000, 0), + right1: createDimension(6600, 650, 7700), + right2: createDimension(6600, 650, -7700), + goal: createDimension(9010, 1760, 0) + }; + sprites['death-valley'] = { + back: loadSprite('background/death-valley/back'), + front: loadSprite('background/death-valley/front'), + tunnel: tunnel, + left1: loadSprite('environment/death-valley/danke-sign'), + left2: loadSprite('environment/death-valley/rock'), + right1: loadSprite('environment/death-valley/pebbles'), + right2: loadSprite('environment/death-valley/pebbles'), + goal: loadSprite('environment/goal') + }; + dimensions['death-valley'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(1120, 730, -6000), + left2: createDimension(440, 970, -5000), + right1: createDimension(2420, 160, 7000), + right2: createDimension(2420, 160, -7000), + goal: createDimension(9010, 1760, 0) + }; + sprites['desolation-hill'] = { + back: loadSprite('background/desolation-hill/back'), + front: loadSprite('background/desolation-hill/front'), + tunnel: tunnel, + right1: loadSprite('environment/desolation-hill/rock-1'), + right2: loadSprite('environment/desolation-hill/rock-2'), + goal: loadSprite('environment/goal') + }; + dimensions['desolation-hill'] = { + tunnel: createDimension(4800, 2000, 0), + right1: createDimension(1160, 420, 6000), + right2: createDimension(1160, 420, -6000), + goal: createDimension(9010, 1760, 0) + }; + sprites['autobahn'] = { + back: loadSprite('background/autobahn/back'), + front: loadSprite('background/autobahn/front'), + tunnel: tunnel, + left1: loadSprite('environment/autobahn/bush-1'), + left2: loadSprite('environment/autobahn/bush-2'), + right1: loadSprite('environment/autobahn/tree'), + right2: loadSprite('environment/autobahn/tree'), + goal: loadSprite('environment/goal') + }; + dimensions['autobahn'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(840, 560, -5000), + left2: createDimension(1260, 530, -5500), + right1: createDimension(2480, 2480, 6000), + right2: createDimension(2480, 2480, 6000), + goal: createDimension(9010, 1760, 0) + }; + sprites['lakeside'] = { + back: loadSprite('background/lakeside/back'), + front: loadSprite('background/lakeside/front'), + tunnel: tunnel, + right1: loadSprite('environment/lakeside/tree'), + right2: loadSprite('environment/lakeside/tree'), + goal: loadSprite('environment/goal') + }; + dimensions['lakeside'] = { + tunnel: createDimension(4800, 2000, 0), + right1: createDimension(1800, 1890, 6000), + right2: createDimension(1800, 1890, -6000), + goal: createDimension(9010, 1760, 0) + }; + Outrun.drawLoading(); + // LOADING FERRARI SPRITES + for (var i = 0; i < 2; i++) { + sprites['down-hardleft-' + i] = loadSprite('ferrari/down-hardleft-' + i); + sprites['down-hardright-' + i] = loadSprite('ferrari/down-hardright-' + i); + sprites['down-left-' + i] = loadSprite('ferrari/down-left-' + i); + sprites['down-right-' + i] = loadSprite('ferrari/down-right-' + i); + sprites['down-straight-' + i] = loadSprite('ferrari/down-straight-' + i); + + sprites['hardleft-' + i] = loadSprite('ferrari/hardleft-' + i); + sprites['hardright-' + i] = loadSprite('ferrari/hardright-' + i); + sprites['left-' + i] = loadSprite('ferrari/left-' + i); + sprites['right-' + i] = loadSprite('ferrari/right-' + i); + sprites['straight-' + i] = loadSprite('ferrari/straight-' + i); + + sprites['up-hardleft-' + i] = loadSprite('ferrari/up-hardleft-' + i); + sprites['up-hardright-' + i] = loadSprite('ferrari/up-hardright-' + i); + sprites['up-left-' + i] = loadSprite('ferrari/up-left-' + i); + sprites['up-right-' + i] = loadSprite('ferrari/up-right-' + i); + sprites['up-straight-' + i] = loadSprite('ferrari/up-straight-' + i); + + + sprites['down-hardleft-brake-' + i] = loadSprite('ferrari/down-hardleft-brake-' + i); + sprites['down-hardright-brake-' + i] = loadSprite('ferrari/down-hardright-brake-' + i); + sprites['down-left-brake-' + i] = loadSprite('ferrari/down-left-brake-' + i); + sprites['down-right-brake-' + i] = loadSprite('ferrari/down-right-brake-' + i); + sprites['down-straight-brake-' + i] = loadSprite('ferrari/down-straight-brake-' + i); + + sprites['hardleft-brake-' + i] = loadSprite('ferrari/hardleft-brake-' + i); + sprites['hardright-brake-' + i] = loadSprite('ferrari/hardright-brake-' + i); + sprites['left-brake-' + i] = loadSprite('ferrari/left-brake-' + i); + sprites['right-brake-' + i] = loadSprite('ferrari/right-brake-' + i); + sprites['straight-brake-' + i] = loadSprite('ferrari/straight-brake-' + i); + + sprites['up-hardleft-brake-' + i] = loadSprite('ferrari/up-hardleft-brake-' + i); + sprites['up-hardright-brake-' + i] = loadSprite('ferrari/up-hardright-brake-' + i); + sprites['up-left-brake-' + i] = loadSprite('ferrari/up-left-brake-' + i); + sprites['up-right-brake-' + i] = loadSprite('ferrari/up-right-brake-' + i); + sprites['up-straight-brake-' + i] = loadSprite('ferrari/up-straight-brake-' + i); + } + Outrun.drawLoading(); + // LOADING IN-GAME MUSIC + sounds['music-0'] = loadSound('music/music-0'); + sounds['music-1'] = loadSound('music/music-1'); + sounds['music-2'] = loadSound('music/music-2'); + //\\//\\ TEXT ASSETS //\\//\\ + sprites['press-enter'] = loadSprite('text/press-enter'); + sprites['select-music'] = loadSprite('text/select-music'); + sprites['music-0'] = loadSprite('text/music-0'); + sprites['music-1'] = loadSprite('text/music-1'); + sprites['music-2'] = loadSprite('text/music-2'); + //\\//\\ VEHICLES //\\//\\ + for (var i = 0; i < 11; i++) { + sprites['vehicle-' + i] = { + right0: loadSprite('vehicles/vehicle-' + i + '/right-0'), + right1: loadSprite('vehicles/vehicle-' + i + '/right-1'), + left0: loadSprite('vehicles/vehicle-' + i + '/left-0'), + left1: loadSprite('vehicles/vehicle-' + i + '/left-1') + }; + } + dimensions['vehicle-0'] = createDimension(945, 525); + dimensions['vehicle-1'] = dimensions['vehicle-0']; + dimensions['vehicle-2'] = dimensions['vehicle-0']; + dimensions['vehicle-3'] = createDimension(1420, 620); + dimensions['vehicle-4'] = dimensions['vehicle-3']; + dimensions['vehicle-5'] = createDimension(570, 600); + dimensions['vehicle-6'] = createDimension(1460, 1100); + dimensions['vehicle-7'] = dimensions['vehicle-6']; + dimensions['vehicle-8'] = dimensions['vehicle-6']; + dimensions['vehicle-9'] = createDimension(920, 450); + dimensions['vehicle-10'] = dimensions['vehicle-9']; + Outrun.drawLoading(); + //\\//\\ HUD //\\//\\ + for(var i = 0; i < 10; i++){ + sprites['hud-'+i] = loadSprite('hud/digits/'+i); + } + sprites['hud-kmh'] = loadSprite('hud/kmh'); + sprites['hud-coconut-beach'] = loadSprite('hud/map/coconut-beach'); + sprites['hud-gateaway'] = loadSprite('hud/map/gateaway'); + sprites['hud-devils-canyon'] = loadSprite('hud/map/devils-canyon'); + sprites['hud-desert'] = loadSprite('hud/map/desert'); + sprites['hud-alps'] = loadSprite('hud/map/alps'); + sprites['hud-cloudy-mountain'] = loadSprite('hud/map/cloudy-mountain'); + sprites['hud-wilderness'] = loadSprite('hud/map/wilderness'); + sprites['hud-old-capital'] = loadSprite('hud/map/old-capital'); + sprites['hud-wheat-field'] = loadSprite('hud/map/wheat-field'); + sprites['hud-seaside-town'] = loadSprite('hud/map/seaside-town'); + sprites['hud-vineyard'] = loadSprite('hud/map/vineyard'); + sprites['hud-death-valley'] = loadSprite('hud/map/death-valley'); + sprites['hud-desolation-hill'] = loadSprite('hud/map/desolation-hill'); + sprites['hud-autobahn'] = loadSprite('hud/map/autobahn'); + sprites['hud-lakeside'] = loadSprite('hud/map/lakeside'); + //\\//\\ COLORS //\\//\\ + colors['coconut-beach'] = { + skyColor: '#008BFF', + darkOffroadColor: '#D3C0B2', + lightOffroadColor: '#E1CDBF', + darkAsphaltColor: '#7F7D7D', + lightAsphaltColor: '#8B898A', + darkSideColor: '#7F7D7D', + lightSideColor: '#E5DCDD', + darkLineColor: '#7F7D7D', + lightLineColor: '#E5DCDD' + }; + colors['gateaway'] = { + skyColor: '#00BEDA', + darkOffroadColor: '#959E6B', + lightOffroadColor: '#A2AA75', + darkAsphaltColor: '#767475', + lightAsphaltColor: '#838081', + darkSideColor: '#767475', + lightSideColor: '#CECACD', + darkLineColor: '#767475', + lightLineColor: '#CECACD' + }; + colors['devils-canyon'] = { + skyColor: '#FFC25E', + darkOffroadColor: '#809473', + lightOffroadColor: '#8CA17F', + darkAsphaltColor: '#89857A', + lightAsphaltColor: '#9A958D', + darkSideColor: '#8E0C00', + lightSideColor: '#CAC6C7', + darkLineColor: '#89857A', + lightLineColor: '#CAC6C7' + }; + colors['desert'] = { + skyColor: '#000FFF', + darkOffroadColor: '#CEBCA2', + lightOffroadColor: '#DAC9AE', + darkAsphaltColor: '#AB9C8F', + lightAsphaltColor: '#B8A89B', + darkSideColor: '#AB9C8F', + lightSideColor: '#B8A89B', + darkLineColor: '#AB9C8F', + lightLineColor: '#B8A89B' + }; + colors['alps'] = { + skyColor: '#005AFF', + darkOffroadColor: '#8BA17D', + lightOffroadColor: '#95AC87', + darkAsphaltColor: '#7E7C7E', + lightAsphaltColor: '#8A878A', + darkSideColor: '#7E7C7E', + lightSideColor: '#C9C9C3', + darkLineColor: '#7E7C7E', + lightLineColor: '#C9C9C3' + }; + colors['cloudy-mountain'] = { + skyColor: '#938BFA', + darkOffroadColor: '#959D6C', + lightOffroadColor: '#A2AA75', + darkAsphaltColor: '#777576', + lightAsphaltColor: '#817F80', + darkSideColor: '#777576', + lightSideColor: '#C4C2C5', + darkLineColor: '#777576', + lightLineColor: '#C4C2C5' + }; + colors['wilderness'] = { + skyColor: '#D8C2A3', + darkOffroadColor: '#B18F73', + lightOffroadColor: '#BE9C7E', + darkAsphaltColor: '#B8987B', + lightAsphaltColor: '#C7A687', + darkSideColor: '#B8987B', + lightSideColor: '#C7A687', + darkLineColor: '#B8987B', + lightLineColor: '#C7A687' + }; + colors['old-capital'] = { + skyColor: '#7642FD', + darkOffroadColor: '#523627', + lightOffroadColor: '#5B3F2F', + darkAsphaltColor: '#4E3F3F', + lightAsphaltColor: '#574848', + darkSideColor: '#4E3F3F', + lightSideColor: '#C29E82', + darkLineColor: '#4E3F3F', + lightLineColor: '#C29E82' + }; + colors['wheat-field'] = { + skyColor: '#FFC25E', + darkOffroadColor: '#825E00', + lightOffroadColor: '#866404', + darkAsphaltColor: '#646365', + lightAsphaltColor: '#6F6E70', + darkSideColor: '#646365', + lightSideColor: '#C2C0C2', + darkLineColor: '#646365', + lightLineColor: '#C2C0C2' + }; + colors['seaside-town'] = { + skyColor: '#3C74FE', + darkOffroadColor: '#D2A479', + lightOffroadColor: '#DAAF82', + darkAsphaltColor: '#868277', + lightAsphaltColor: '#979288', + darkSideColor: '#868277', + lightSideColor: '#CDC9CE', + darkLineColor: '#868277', + lightLineColor: '#CDC9CE' + }; + colors['vineyard'] = { + skyColor: '#0BA1FF', + darkOffroadColor: '#A3A95C', + lightOffroadColor: '#B0B566', + darkAsphaltColor: '#7F7D7E', + lightAsphaltColor: '#898687', + darkSideColor: '#7F7D7E', + lightSideColor: '#ACAAAC', + darkLineColor: '#7F7D7E', + lightLineColor: '#ACAAAC' + }; + colors['death-valley'] = { + skyColor: '#6255FE', + darkOffroadColor: '#AA7B5D', + lightOffroadColor: '#AD7E5E', + darkAsphaltColor: '#6C5D5D', + lightAsphaltColor: '#776868', + darkSideColor: '#6C5D5D', + lightSideColor: '#C6C0C4', + darkLineColor: '#6C5D5D', + lightLineColor: '#C6C0C4' + }; + colors['desolation-hill'] = { + skyColor: '#EFECDC', + darkOffroadColor: '#CEBEB1', + lightOffroadColor: '#D9CABE', + darkAsphaltColor: '#848284', + lightAsphaltColor: '#908D90', + darkSideColor: '#848284', + lightSideColor: '#CFCCCF', + darkLineColor: '#848284', + lightLineColor: '#CFCCCF' + }; + colors['autobahn'] = { + skyColor: '#7642FD', + darkOffroadColor: '#839876', + lightOffroadColor: '#8EA481', + darkAsphaltColor: '#696B86', + lightAsphaltColor: '#747592', + darkSideColor: '#8C0C00', + lightSideColor: '#C5C4C5', + darkLineColor: '#696B86', + lightLineColor: '#C5C4C5' + }; + colors['lakeside'] = { + skyColor: '#FEAAA4', + darkOffroadColor: '#B8A79B', + lightOffroadColor: '#C6B4A8', + darkAsphaltColor: '#7D7569', + lightAsphaltColor: '#877F72', + darkSideColor: '#7D7569', + lightSideColor: '#C8C1C2', + darkLineColor: '#7D7569', + lightLineColor: '#C8C1C2' + }; +} + +function loadSprite(fileName) { + maxLoading++; + var sprite = new Image(); + sprite.onload = function () { + loading++; + } + sprite.src = "./assets/sprites/" + fileName + ".png"; + return sprite; +} + +function loadSound(fileName) { + maxLoading++; + var sample = new Audio(); + sample.isLoaded = false; + sample.oncanplay = function () { + if (!this.isLoaded) { + this.isLoaded = true; + loading++; + } + } + sample.src = "./assets/sounds/" + fileName + ".wav"; + return sample; +} + +function createDimension(width, height, offset) { + return { width: width, height: height, offset: offset }; +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/AudioManager.js b/Games/OutRun_Offline_Game/main/AudioManager.js new file mode 100644 index 0000000000..680776678e --- /dev/null +++ b/Games/OutRun_Offline_Game/main/AudioManager.js @@ -0,0 +1,62 @@ +function AudioManager() { + this.delay = 0; + this.music = 1; + this.dots = 3; + this.background = 0; + this.tree = 0; + this.flash = 0; +} + +const radioDelay = 6; + +AudioManager.prototype.update = function () { + if (Outrun.scene == MENU_SCENE | Outrun.scene == RADIO_SCENE) { + this.delay = (this.delay + 1) % radioDelay; + if (!this.delay) { + this.dots--; + if (this.dots < 0) { + this.dots = 3 + Math.random() * 4; + } + this.background = (this.background + 1) % 6; + this.tree = (this.tree + 1) % 3; + this.flash = (this.flash + 1) % 10; + } + if (sounds['wave'].paused) + sounds['wave'].play(); + } else if (Outrun.scene == IN_GAME_SCENE) { + if (sounds['music-' + this.music].paused) + sounds['music-' + this.music].play(); + } +} + +AudioManager.prototype.draw = function () { + Canvas.fill('#008BFF'); + Canvas.drawStaticImage(sprites['radio-car'], 0, 0, Canvas.width, Canvas.height); + Canvas.drawStaticImage(sprites['radio'], 127, 166, 126, 30); + Canvas.drawStaticImage(sprites['radio-freq-' + this.music], 143, 173, 24, 7); + for (var i = 0; i < this.dots; i++) { + Canvas.drawStaticImage(sprites['radio-dot-' + (i < 4 ? 'green' : 'red')], 156 + i * 3, 187, 2, 2); + Canvas.drawStaticImage(sprites['radio-dot-' + (i < 4 ? 'green' : 'red')], 156 + i * 3, 190, 2, 2); + } + Canvas.drawStaticImage(sprites['radio-hand-' + this.music], 117, 165, 133, 59); + if (Outrun.scene == MENU_SCENE) { + Canvas.drawStaticImage(sprites['logo-bg-' + this.background], 72, 18, 176, 88); + Canvas.drawStaticImage(sprites['logo-road'], 81, 80, 95, 25); + Canvas.drawStaticImage(sprites['logo-car'], 127, 66, 64, 39); + Canvas.drawStaticImage(sprites['logo-tree-' + this.tree], 75, 30, 46, 57); + Canvas.drawStaticImage(sprites['logo-text'], 109, 33, 135, 36); + if (this.flash < 5) + Canvas.drawStaticImage(sprites['press-enter'], 111, 123, 97, 8); + } else { + Canvas.drawStaticImage(sprites['select-music'], 65, 67, 191, 14); + if (this.music == 0) { + Canvas.drawStaticImage(sprites['music-0'], 72, 88, 175, 16); + } else if (this.music == 1) { + Canvas.drawStaticImage(sprites['music-1'], 96, 88, 127, 16); + } else { + Canvas.drawStaticImage(sprites['music-2'], 108, 88, 103, 16); + } + } +} + +let Radio = new AudioManager(); \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Camera.js b/Games/OutRun_Offline_Game/main/Camera.js new file mode 100644 index 0000000000..c801b78eed --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Camera.js @@ -0,0 +1,9 @@ +function Camera(width, height, altitude, fov) { + this.width = width; + this.height = height; + this.altitude = altitude; + this.fov = fov; + this.gap = this.width / (2 * Math.tan(this.fov * Math.PI / 360)); + this.rotation = 0; + this.position = new Vector3(-1.5 * (laneWidth + lineWidth), this.altitude + this.height / 2, 0); +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Canvas.js b/Games/OutRun_Offline_Game/main/Canvas.js new file mode 100644 index 0000000000..6990a423e4 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Canvas.js @@ -0,0 +1,97 @@ +function Canvas2D() { + this.canvas = document.getElementById('screen'); + this.canvasContext = this.canvas.getContext('2d'); + this.canvas.width = 320; + this.canvas.height = 224; + if (window.innerWidth / window.innerHeight <= canvasRatio) { + this.canvas.width = window.innerWidth; + this.canvas.height = window.innerWidth / canvasRatio; + } else { + this.canvas.width = window.innerHeight * canvasRatio; + this.canvas.height = window.innerHeight; + } + this.width = 320; + this.height = 224; + this.gradient = this.canvasContext.createLinearGradient(0, 0, 0, 200); + this.gradient.addColorStop(1, "white"); +} + +const canvasRatio = 1.42857142857; + +Canvas2D.prototype.clear = function () { + this.canvasContext.clearRect(0, 0, this.width, this.height); +} + +Canvas2D.prototype.fill = function (color) { + this.canvasContext.fillStyle = color; + this.canvasContext.fillRect(0, 0, this.width, this.height); +} + +Canvas2D.prototype.fillGradient = function (color) { + this.gradient.addColorStop(0, color); + this.canvasContext.fillStyle = this.gradient; + this.canvasContext.fillRect(0, 0, this.width, this.height); +} + +Canvas2D.prototype.drawImage = function (image, center, width, height) { + this.canvasContext.drawImage(image, center.xScreen - width / 2, center.yScreen - height, width, height); +} + +Canvas2D.prototype.drawStaticImage = function (image, x, y, width, height) { + this.canvasContext.drawImage(image, x, y, width, height); +} + +Canvas2D.prototype.drawShape = function (point1, point2, point3, point4, color) { + this.canvasContext.beginPath(); + this.canvasContext.moveTo(point1.xScreen, point1.yScreen); + this.canvasContext.lineTo(point2.xScreen, point2.yScreen); + this.canvasContext.lineTo(point3.xScreen, point3.yScreen); + this.canvasContext.lineTo(point4.xScreen, point4.yScreen); + this.canvasContext.fillStyle = color; + this.canvasContext.fill(); + this.canvasContext.strokeStyle = color; + this.canvasContext.stroke(); +} + +Canvas2D.prototype.drawText = function (text) { + for (var i = 0; i < text.length; i++) { + console.log(text.charAt(text.length - i - 1)); + this.drawStaticImage(sprites['hud-' + text.charAt(text.length - i - 1)], 19 - i * 8, 209, 7, 12); + } + +} + +/* + PROBABLY NOT GOING TO BE USED IN THE FUTURE +Canvas2D.prototype.pixelize = function (pixelSize) { + this.canvasContext.drawImage(this.canvas, 0, 0, this.width, this.height, 0, 0, this.width / pixelSize, this.height / pixelSize); + this.canvasContext.mozImageSmoothingEnabled = false; + this.canvasContext.imageSmoothingEnabled = false; + this.canvasContext.drawImage(this.canvas, 0, 0, this.width / pixelSize, this.height / pixelSize, 0, 0, this.width, this.height); +} +*/ + +Canvas2D.prototype.fix = function () { + this.canvasContext.mozImageSmoothingEnabled = false; + this.canvasContext.imageSmoothingEnabled = false; + this.canvasContext.drawImage(this.canvas, 0, 0, this.width, this.height, 0, 0, this.canvas.width, this.canvas.height); +} + +Canvas2D.prototype.mix = function (base, target, step) { + if (base == target) + return base; + var resHex = '#'; + for (var i = 1; i <= 5; i += 2) { + var diff = parseInt(target.substring(i, i + 2), 16) - parseInt(base.substring(i, i + 2), 16); + var add = null; + if (Math.abs(diff) >= step) { + add = (parseInt(base.substring(i, i + 2), 16) + step * Math.sign(diff)).toString(16).toUpperCase(); + } else { + add = target.substring(i, i + 2); + } + resHex += (add.length == 1 ? '0' : '') + add; + } + return resHex; +} + +let Canvas = new Canvas2D(); \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/EventListener.js b/Games/OutRun_Offline_Game/main/EventListener.js new file mode 100644 index 0000000000..5433b052f4 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/EventListener.js @@ -0,0 +1,62 @@ +function EventListener() { + document.onkeydown = keyDown; + document.onkeyup = keyUp; +} + +let KEY_W = 87; +let KEY_A = 65; +let KEY_S = 83; +let KEY_D = 68; +let KEY_ENTER = 13; +let KEY_SPACE = 32; +let KEY_UP = 38; +let KEY_LEFT = 37; +let KEY_DOWN = 40; +let KEY_RIGHT = 39; + +function keyDown(event) { + if (loading == maxLoading) { + if (Outrun.scene == MENU_SCENE) { + if (event.which == KEY_ENTER) { + Outrun.scene = RADIO_SCENE; + sounds['coin'].play(); + } + } else if (Outrun.scene == RADIO_SCENE) { + if (event.which == KEY_A | event.which == KEY_LEFT) { + if (Radio.music != 0) + Radio.music--; + } else if (event.which == KEY_D | event.which == KEY_RIGHT) { + if (Radio.music != 2) + Radio.music++; + } else if (event.which == KEY_ENTER) { + sounds['wave'].pause(); + Outrun.newGame(); + Outrun.scene = IN_GAME_SCENE; + } + } else if (Outrun.scene == IN_GAME_SCENE) { + if (event.which == KEY_W | event.which == KEY_UP) { + Driver.accelerate = true; + } else if (event.which == KEY_S | event.which == KEY_DOWN) { + Driver.decelerate = true; + } else if (event.which == KEY_A | event.which == KEY_LEFT) { + Driver.steerLeft = true; + } else if (event.which == KEY_D | event.which == KEY_RIGHT) { + Driver.steerRight = true; + } + } + } +} + +function keyUp(event) { + if (Outrun.scene == IN_GAME_SCENE) { + if (event.which == KEY_W | event.which == KEY_UP) { + Driver.accelerate = false; + } else if (event.which == KEY_S | event.which == KEY_DOWN) { + Driver.decelerate = false; + } else if (event.which == KEY_A | event.which == KEY_LEFT) { + Driver.steerLeft = false; + } else if (event.which == KEY_D | event.which == KEY_RIGHT) { + Driver.steerRight = false; + } + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Game.js b/Games/OutRun_Offline_Game/main/Game.js new file mode 100644 index 0000000000..a43af468f8 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Game.js @@ -0,0 +1,72 @@ +function Game() { + this.scene = MENU_SCENE; + this.renderSize = 300; + this.playable = false; + this.startDelay = 0; +} + +var controlCount = 0; + +const MENU_SCENE = 'menu'; +const RADIO_SCENE = 'radio'; +const IN_GAME_SCENE = 'drive'; + +const FPS = 60; + +var time = null; +var currentTime = null; + +Game.prototype.init = function () { + time = new Date().getTime(); + loadAssets(); + this.eventListener = new EventListener(); +} + +Game.prototype.newGame = function () { + this.gameWorld = new GameWorld(); +} + +Game.prototype.start = function () { + Outrun.init(); + Outrun.mainLoop(); +} + +Game.prototype.mainLoop = function () { + currentTime = new Date().getTime(); + var milliseconds = currentTime - time; + if (milliseconds >= 1000 / FPS) { + time = currentTime; + if (loading < maxLoading) { + Outrun.drawLoading(); + } else { + Radio.update(); + if (Outrun.scene == MENU_SCENE | Outrun.scene == RADIO_SCENE) { + Radio.draw(); + } else if (Outrun.scene == IN_GAME_SCENE) { + if(!Outrun.playable){ + Outrun.startDelay = (Outrun.startDelay + 1) % FPS; + if(!Outrun.startDelay) + Outrun.gameWorld.road.nextLight(); + } + Outrun.gameWorld.play(); + Outrun.gameWorld.update(); + Outrun.gameWorld.draw(); + } + } + Canvas.fix(); + } + + requestAnimationFrame(Outrun.mainLoop); +} + +Game.prototype.drawLoading = function () { + Canvas.fill('#008BFF'); + Canvas.canvasContext.fillStyle = "#000000"; + Canvas.canvasContext.fillRect(99, 126, 121, 12); + Canvas.canvasContext.fillStyle = "#F7F700"; + Canvas.canvasContext.fillRect(99, 126, 121 * (loading / maxLoading), 12); + Canvas.drawStaticImage(sprites['loading-box'], 98, 125, 124, 15); + Canvas.drawStaticImage(sprites['loading-text'], 106, 84, 109, 28); +} + +let Outrun = new Game(); diff --git a/Games/OutRun_Offline_Game/main/GameWorld.js b/Games/OutRun_Offline_Game/main/GameWorld.js new file mode 100644 index 0000000000..06c74b84b2 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/GameWorld.js @@ -0,0 +1,134 @@ +function GameWorld() { + this.road = new Road(new Vector3(0, 0, 0), 0, 0, trackNumLanes); + this.route = 'coconut-beach'; + this.currentColor = colors['coconut-beach']; + this.backParallax = 0; + this.frontParallax = 0; +} + +const backSpeed = 0.000001; +const frontSpeed = 0.000002; +const backWidth = 1536; +const frontWidth = 2048; +const backgroundHeight = 256; +const backgroundOffset = -135; + +GameWorld.prototype.play = function () { + if (this.road.endSegment != null && this.road.findIndex(this.road.endSegment.highCenter.z) < this.road.findIndex(Driver.camera.position.z)) + Outrun.playable = false; + if (Outrun.playable) + Driver.play(); + for (var i = 0; i < this.road.vehicles.length; i++) { + this.road.vehicles[i].play(); + } +} + +GameWorld.prototype.update = function () { + var currentIndex = this.road.findIndex(Driver.camera.position.z); + for (var i = currentIndex, size = Math.min(this.road.segments.length, currentIndex + Outrun.renderSize); i < size; i++) { + this.road.segments[i].project(); + } + Driver.project(); + for (var i = 0; i < this.road.vehicles.length; i++) { + this.road.vehicles[i].project(); + } + this.route = this.road.findRoute(); + for (var i = 0; i < 9; i++) { + var key = Object.keys(this.currentColor)[i]; + this.currentColor[key] = Canvas.mix(this.currentColor[key], colors[this.route][key], 1); + } + var parallaxAmount = Driver.speed * Math.sign(Driver.curveDirection); + this.backParallax -= backSpeed * parallaxAmount; + this.frontParallax -= frontSpeed * parallaxAmount; + if (Math.abs(this.backParallax) > 1) { + this.backParallax = 0; + } + if (Math.abs(this.frontParallax) > 1) { + this.frontParallax = 0; + } +} + +GameWorld.prototype.draw = function () { + Canvas.fillGradient(this.currentColor.skyColor); + Canvas.drawStaticImage(sprites[this.route].back, backWidth * (this.backParallax - 1), backgroundOffset, backWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].back, backWidth * (this.backParallax), backgroundOffset, backWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].back, backWidth * (this.backParallax + 1), backgroundOffset, backWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].front, frontWidth * (this.frontParallax - 1), backgroundOffset, frontWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].front, frontWidth * (this.frontParallax), backgroundOffset, frontWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].front, frontWidth * (this.frontParallax + 1), backgroundOffset, frontWidth, backgroundHeight); + var currentIndex = this.road.findIndex(Driver.camera.position.z); + var maxRendered = Math.min(this.road.segments.length, currentIndex + Outrun.renderSize) - 1; + for (var i = maxRendered; i >= currentIndex; i--) { + var segment = this.road.segments[i]; + var color = segment.isDark ? this.currentColor.darkOffroadColor : this.currentColor.lightOffroadColor; + if (segment instanceof Segment) { + Canvas.drawShape(segment.offroad.upLeft, segment.offroad.upRight, segment.offroad.downRight, segment.offroad.downLeft, color); + } else { + var subSegment = segment.leftJunction; + Canvas.drawShape(subSegment.offroad.upLeft, subSegment.offroad.upRight, subSegment.offroad.downRight, subSegment.offroad.downLeft, color); + subSegment = segment.rightJunction; + Canvas.drawShape(subSegment.offroad.upLeft, subSegment.offroad.upRight, subSegment.offroad.downRight, subSegment.offroad.downLeft, color); + } + } + for (var i = maxRendered; i >= currentIndex; i--) { + var segment = this.road.segments[i]; + var asphaltColor = segment.isDark ? this.currentColor.darkAsphaltColor : this.currentColor.lightAsphaltColor; + var sideColor = segment.isDark ? this.currentColor.darkSideColor : this.currentColor.lightSideColor; + var lineColor = segment.isDark ? this.currentColor.darkLineColor : this.currentColor.lightLineColor; + if (segment instanceof Segment) { + Canvas.drawShape(segment.asphalt.upLeft, segment.asphalt.upRight, segment.asphalt.downRight, segment.asphalt.downLeft, asphaltColor); + Canvas.drawShape(segment.leftSide.upLeft, segment.leftSide.upRight, segment.leftSide.downRight, segment.leftSide.downLeft, sideColor); + Canvas.drawShape(segment.rightSide.upLeft, segment.rightSide.upRight, segment.rightSide.downRight, segment.rightSide.downLeft, sideColor); + for (var j = 0; j < segment.numLanes - 1; j++) { + Canvas.drawShape(segment.lines[j].upLeft, segment.lines[j].upRight, segment.lines[j].downRight, segment.lines[j].downLeft, lineColor); + } + for (var j = 0; j < segment.objects.length; j++) { + var object = segment.objects[j]; + if (sprites[this.route][object.fileName] != undefined) + Canvas.drawImage(sprites[this.route][object.fileName], object.center, object.relWidth, object.relHeight); + } + } else { + var subSegment = segment.leftJunction; + Canvas.drawShape(subSegment.asphalt.upLeft, subSegment.asphalt.upRight, subSegment.asphalt.downRight, subSegment.asphalt.downLeft, asphaltColor); + Canvas.drawShape(subSegment.leftSide.upLeft, subSegment.leftSide.upRight, subSegment.leftSide.downRight, subSegment.leftSide.downLeft, sideColor); + Canvas.drawShape(subSegment.rightSide.upLeft, subSegment.rightSide.upRight, subSegment.rightSide.downRight, subSegment.rightSide.downLeft, sideColor); + for (var j = 0; j < subSegment.numLanes - 1; j++) { + Canvas.drawShape(subSegment.lines[j].upLeft, subSegment.lines[j].upRight, subSegment.lines[j].downRight, subSegment.lines[j].downLeft, lineColor); + } + for (var j = 0; j < subSegment.objects.length; j++) { + var object = subSegment.objects[j]; + if (sprites[this.route][object.fileName] != undefined) + Canvas.drawImage(sprites[this.route][object.fileName], object.center, object.relWidth, object.relHeight); + } + subSegment = segment.rightJunction; + Canvas.drawShape(subSegment.asphalt.upLeft, subSegment.asphalt.upRight, subSegment.asphalt.downRight, subSegment.asphalt.downLeft, asphaltColor); + Canvas.drawShape(subSegment.leftSide.upLeft, subSegment.leftSide.upRight, subSegment.leftSide.downRight, subSegment.leftSide.downLeft, sideColor); + Canvas.drawShape(subSegment.rightSide.upLeft, subSegment.rightSide.upRight, subSegment.rightSide.downRight, subSegment.rightSide.downLeft, sideColor); + for (var j = 0; j < subSegment.numLanes - 1; j++) { + Canvas.drawShape(subSegment.lines[j].upLeft, subSegment.lines[j].upRight, subSegment.lines[j].downRight, subSegment.lines[j].downLeft, lineColor); + } + for (var j = 0; j < subSegment.objects.length; j++) { + var object = subSegment.objects[j]; + if (sprites[this.route][object.fileName] != undefined) + Canvas.drawImage(sprites[this.route][object.fileName], object.center, object.relWidth, object.relHeight); + } + } + } + for (var i = this.road.vehicles.length - 1; i >= 0; i--) { + var vehicle = this.road.vehicles[i]; + var position = this.road.findIndex(vehicle.car.center.z); + if (position > currentIndex & position < maxRendered) + Canvas.drawImage(sprites[vehicle.vehicleType][vehicle.car.fileName], vehicle.car.center, vehicle.car.relWidth, vehicle.car.relHeight); + } + Canvas.drawImage(sprites[Driver.car.fileName], Driver.car.center, Driver.car.relWidth, Driver.car.relHeight); + + Canvas.drawStaticImage(sprites['hud-' + this.route], 301, 210, 16, 11); + Canvas.drawStaticImage(sprites['hud-kmh'], 27, 210, 18, 13); + Canvas.drawText(Math.floor(Driver.speed / 3).toString()); + + if (this.road.segments.length - currentIndex < Outrun.renderSize) { + this.road.addSegments(true); + } +} + +let Driver = new Player(); \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Junction.js b/Games/OutRun_Offline_Game/main/Junction.js new file mode 100644 index 0000000000..1e28df37af --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Junction.js @@ -0,0 +1,12 @@ +function Junction(prevJunction, curve, hill, index, isInitial) { + this.numLanes = prevJunction.numLanes; + this.isDark = index % (2 * invisSegment) < invisSegment; + this.leftJunction = new Segment(prevJunction.leftJunction, -curve, hill, index, isInitial, true); + this.rightJunction = new Segment(prevJunction.rightJunction, curve, hill, index, isInitial, true); + this.isInitial = isInitial; +} + +Junction.prototype.project = function () { + this.leftJunction.project(); + this.rightJunction.project(); +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Player.js b/Games/OutRun_Offline_Game/main/Player.js new file mode 100644 index 0000000000..83b838e6ca --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Player.js @@ -0,0 +1,131 @@ +function Player() { + this.camera = new Camera(window.innerWidth, window.innerHeight, 300, 120); + this.car = new WorldObject(new Vector3(0, 0, carDistance), 'straight'); + this.car.width = 810; + this.car.height = 460; + this.car.project = function (measure2) { + this.center.project(); + this.relWidth = Vector3.calculate(this.width, Driver.camera.gap, measure2); + this.relHeight = Vector3.calculate(this.height, Driver.camera.gap, measure2); + } + this.lastSegment = null; + this.curve = 0; + this.hill = 0; + this.curveDirection = 0; + this.hillDirection = 0; + this.speed = 0; + this.accelerate = false; + this.decelerate = false; + this.steerLeft = false; + this.steerRight = false; +} + +const maxSpeed = 900; + +const carDistance = 5000; + +const curveSense = 0.2; +const hillSense = 10; +const speedSense = 250; + +Player.prototype.play = function () { + if (this.accelerate) { + this.speed += 4; + } else if (this.decelerate) { + this.speed -= 16; + } else { + this.speed -= 2; + } + this.speed = this.speed < 0 ? 0 : this.speed > maxSpeed ? maxSpeed : this.speed; + + var carIndex = Outrun.gameWorld.road.findIndex(this.car.center.z); + var segment = Outrun.gameWorld.road.segments[carIndex]; + if (segment instanceof Segment) { + this.lastSegment = segment; + this.curve = segment.curve; + this.hill = segment.hill; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Segment) { + this.curveDirection = this.curve - Outrun.gameWorld.road.segments[carIndex - 1].curve; + this.hillDirection = this.hill - Outrun.gameWorld.road.segments[carIndex - 1].hill; + } else { + this.curveDirection = 0; + this.hillDirection = 0; + } + } else { + if (Outrun.gameWorld.road.trackCount > Outrun.gameWorld.road.chosenPath.length) { + Outrun.gameWorld.road.chosenPath.push(this.car.center.x >= this.lastSegment.highCenter.x); + } + if (Outrun.gameWorld.road.chosenPath[Outrun.gameWorld.road.chosenPath.length - 1]) { + this.curve = segment.rightJunction.curve; + this.hill = segment.rightJunction.hill; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Junction) { + this.curveDirection = this.curve - Outrun.gameWorld.road.segments[carIndex - 1].rightJunction.curve; + this.hillDirection = this.hill - Outrun.gameWorld.road.segments[carIndex - 1].rightJunction.hill; + } else { + this.curveDirection = 0; + this.hillDirection = 0; + } + } else { + this.curve = segment.leftJunction.curve; + this.hill = segment.leftJunction.hill; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Junction) { + this.curveDirection = this.curve - Outrun.gameWorld.road.segments[carIndex - 1].leftJunction.curve; + this.hillDirection = this.hill - Outrun.gameWorld.road.segments[carIndex - 1].leftJunction.hill; + } else { + this.curveDirection = 0; + this.hillDirection = 0; + } + } + } + + zMove = this.speed * (this.steerLeft | this.steerRight ? 0.99 : 1); + xMove = this.speed * ((this.steerLeft ? -0.08 : this.steerRight ? 0.08 : 0) - this.curveDirection / 25); + + this.camera.position.z += zMove; + this.camera.position.x += xMove; + this.camera.position.y = this.hill + this.camera.altitude + this.camera.height / 2; +} + +Player.prototype.project = function () { + this.car.center.x = this.camera.position.x; + this.car.center.z = this.camera.position.z + carDistance; + this.car.center.y = this.hill; + this.car.project(this.car.center.z - this.camera.position.z); + + this.car.fileName = ''; + if (this.hillDirection > hillSense) { + this.car.fileName = 'up-'; + } else if (this.hillDirection < -hillSense) { + this.car.fileName = 'down-'; + } + if (this.curveDirection < -curveSense) { + if (this.steerLeft & this.speed != 0) + this.car.fileName += 'hardleft-'; + else if (this.steerRight & this.speed != 0) + this.car.fileName += 'straight-'; + else + this.car.fileName += 'left-'; + } else if (this.curveDirection > curveSense) { + if (this.steerLeft & this.speed != 0) + this.car.fileName += 'straight-'; + else if (this.steerRight & this.speed != 0) + this.car.fileName += 'hardright-'; + else + this.car.fileName += 'right-'; + } else { + if (this.steerLeft & this.speed != 0) + this.car.fileName += 'left-'; + else if (this.steerRight & this.speed != 0) + this.car.fileName += 'right-'; + else + this.car.fileName += 'straight-'; + } + if (this.decelerate) { + this.car.fileName += 'brake-'; + } + if (this.speed > speedSense) { + this.car.fileName += Math.floor(Math.random() * 2); + } else { + this.car.fileName += '0'; + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Road.js b/Games/OutRun_Offline_Game/main/Road.js new file mode 100644 index 0000000000..40fa36ff0b --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Road.js @@ -0,0 +1,274 @@ +function Road(center, curve, hill, numLanes) { + this.trackRemain = trackLength - 1; + this.chosenPath = []; + this.vehicles = []; + this.trackCount = 0; + this.segments = [new Segment(Road.prepareInitial(center, curve, hill, numLanes), curve, hill, 0, true)]; + this.addSegments(false); + this.segments[0].offroad.downLeft.project(); + this.segments[0].offroad.downRight.project(); + this.segments[0].asphalt.downLeft.project(); + this.segments[0].asphalt.downRight.project(); + this.segments[0].leftSide.downLeft.project(); + this.segments[0].leftSide.downRight.project(); + this.segments[0].rightSide.downLeft.project(); + this.segments[0].rightSide.downRight.project(); + for (var i = 0; i < numLanes - 1; i++) { + this.segments[0].lines[i].downLeft.project(); + this.segments[0].lines[i].downRight.project(); + } + this.startSegment = this.segments[13]; + this.endSegment = null; + this.startSegment.objects.push(new WorldObject(new Vector3(this.startSegment.highCenter.x, this.startSegment.highCenter.y, this.startSegment.highCenter.z), 'start0')); +} + +const trackLength = 2000; +const junctionLength = 400; + +const trackNumLanes = 6; +const junctNumLanes = 3; + +const vehicleSpawn = 5; + +const MAX_CURVE = 1; +const MAX_HILL = 10; + +Road.prototype.addSegments = function (canCurve) { + var curved = canCurve & Math.random() < 0.4; + if (this.segments[this.segments.length - 1] instanceof Segment) { + if (curved & this.trackRemain > 400 + Outrun.renderSize) { + var curveLength = Math.random() < 0.5 ? 200 : 400; + if (Math.random() < 0.7) { + this.addCurves(curveLength); + } else { + this.addHills(curveLength); + } + this.trackRemain -= curveLength; + } else if (this.trackRemain != 0) { + var length = Math.min(this.trackRemain, Outrun.renderSize); + this.addStraights(length); + this.trackRemain -= length; + } else { + if (this.chosenPath.length < 4) { + this.addJunctions(junctionLength); + this.trackRemain = trackLength; + } else { + Outrun.finished = true; + this.endSegment = this.segments[this.segments.length - 1]; + this.endSegment.objects.push(new WorldObject(new Vector3(this.endSegment.highCenter.x, this.endSegment.highCenter.y, this.endSegment.highCenter.z), 'goal')); + this.addStraights(Outrun.renderSize * 2); + } + } + } else { + var lastJunction = null; + if (this.chosenPath[this.chosenPath.length - 1]) { + lastJunction = this.segments[this.segments.length - 1].rightJunction; + var newCenter = new Vector3(lastJunction.highCenter.x + (laneWidth * 1.5 + sideLineWidth / 2 + lineWidth / 2), lastJunction.highCenter.y, lastJunction.highCenter.z); + this.segments.push(new Segment(Road.prepareInitial(newCenter, lastJunction.curve, lastJunction.hill, trackNumLanes), 0, 0, this.segments.length, true)); + } else { + lastJunction = this.segments[this.segments.length - 1].leftJunction; + var newCenter = new Vector3(lastJunction.highCenter.x - (laneWidth * 1.5 + sideLineWidth / 2 + lineWidth / 2), lastJunction.highCenter.y, lastJunction.highCenter.z); + this.segments.push(new Segment(Road.prepareInitial(newCenter, lastJunction.curve, lastJunction.hill, trackNumLanes), 0, 0, this.segments.length, true)); + } + this.addStraights(Outrun.renderSize); + } +} + +Road.prototype.addCurves = function (length) { + var direction = Math.random() < 0.5 ? -1 : 1; + var part = length / 3; + var vehicle = 0; + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], MAX_CURVE * (i / part) * direction, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], MAX_CURVE * direction, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], MAX_CURVE * (1 - i / part) * direction, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } +} + +Road.prototype.addHills = function (length) { + var part = length / 3; + var vehicle = 0; + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], 0, MAX_HILL * (Math.cos((2 * i / part - 1) * Math.PI) + 1), this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], 0, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], 0, MAX_HILL * (-Math.cos((2 * i / part - 1) * Math.PI) - 1), this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } +} + +Road.prototype.addStraights = function (length) { + var vehicle = 0; + for (var i = 0; i < length; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], 0, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } +} + +Road.prototype.addJunctions = function (length) { + this.trackCount++; + var lastSegment = this.segments[this.segments.length - 1]; + var initial = { + numLanes: junctNumLanes, + leftJunction: Road.prepareInitial(new Vector3(lastSegment.highCenter.x - (lastSegment.asphalt.width / 4 - sideLineWidth / 2 + lineWidth / 4), lastSegment.highCenter.y, lastSegment.highCenter.z), lastSegment.curve, lastSegment.hill, junctNumLanes), + rightJunction: Road.prepareInitial(new Vector3(lastSegment.highCenter.x + (lastSegment.asphalt.width / 4 - sideLineWidth / 2 + lineWidth / 4), lastSegment.highCenter.y, lastSegment.highCenter.z), lastSegment.curve, lastSegment.hill, junctNumLanes) + }; + this.segments.push(new Junction(initial, 0, 0, this.segments.length, true)); + var part = (length - 1) / 3; + for (var i = 0; i < part; i++) { + this.segments.push(new Junction(this.segments[this.segments.length - 1], MAX_CURVE * (i / part), 0, this.segments.length, false)); + } + for (var i = 0; i < part; i++) { + this.segments.push(new Junction(this.segments[this.segments.length - 1], MAX_CURVE, 0, this.segments.length, false)); + } + for (var i = 0; i < part; i++) { + this.segments.push(new Junction(this.segments[this.segments.length - 1], MAX_CURVE * (1 - i / part), 0, this.segments.length, false)); + } + for (var i = 0; i < Outrun.renderSize; i++) { + this.segments.push(new Junction(this.segments[this.segments.length - 1], 0, 0, this.segments.length, false)); + } +} + +Road.prototype.addVehicles = function (segment) { + var shift = (Math.floor(Math.random() * (segment.numLanes / 2)) + 0.5) * (Math.random() < 0.5 ? 1 : -1); + this.vehicles.push(new Vehicle(new Vector3(segment.highCenter.x, segment.highCenter.y, segment.highCenter.z), shift, 'vehicle-' + Math.floor(Math.random() * 11))); +} + +Road.prototype.nextLight = function () { + var currentFile = this.startSegment.objects[this.startSegment.objects.length - 1].fileName; + if (currentFile == 'start0') + this.startSegment.objects[this.startSegment.objects.length - 1].fileName = 'start1'; + else if (currentFile == 'start1') + this.startSegment.objects[this.startSegment.objects.length - 1].fileName = 'start2'; + else if (currentFile == 'start2') + this.startSegment.objects[this.startSegment.objects.length - 1].fileName = 'start3'; + if (currentFile == 'start2') { + sounds['signal-1'].play(); + Outrun.playable = true; + } + else + sounds['signal-0'].play(); +} + +Road.prototype.findIndex = function (position) { + return Math.floor(position / segmentDepth) % this.segments.length; +} + +Road.prepareInitial = function (center, curve, hill, numLanes) { + var asphaltWidth = laneWidth * numLanes + lineWidth * (numLanes - 1) + sideLineWidth * 2; + var initial = { + numLanes: numLanes, + curve: curve, + hill: hill, + highCenter: center, + offroad: { + upLeft: new Vector3(center.x - offroadWidth / 2, center.y, center.z), + upRight: new Vector3(center.x + offroadWidth / 2, center.y, center.z), + highCenter: center, + space: 0, + width: offroadWidth + }, + asphalt: { + upLeft: new Vector3(center.x - asphaltWidth / 2, center.y, center.z), + upRight: new Vector3(center.x + asphaltWidth / 2, center.y, center.z), + highCenter: center, + space: 0, + width: asphaltWidth + }, + leftSide: { + upLeft: new Vector3(center.x - asphaltWidth / 2, center.y, center.z), + upRight: new Vector3(center.x - asphaltWidth / 2 + sideLineWidth, center.y, center.z), + highCenter: center, + space: (sideLineWidth - asphaltWidth) / 2, + width: sideLineWidth + }, + rightSide: { + upLeft: new Vector3(center.x + asphaltWidth / 2 - sideLineWidth, center.y, center.z), + upRight: new Vector3(center.x + asphaltWidth / 2, center.y, center.z), + highCenter: center, + space: (asphaltWidth - sideLineWidth) / 2, + width: sideLineWidth + }, + lines: [] + }; + var leftSide = initial.leftSide; + for (var i = 0; i < numLanes - 1; i++) { + initial.lines.push( + { + upLeft: new Vector3(leftSide.upRight.x + laneWidth + (laneWidth + lineWidth) * i, center.y, center.z), + upRight: new Vector3(leftSide.upRight.x + (laneWidth + lineWidth) * (i + 1), center.y, center.z), + highCenter: center, + space: leftSide.space + (sideLineWidth + lineWidth) / 2 + laneWidth + (laneWidth + lineWidth) * i, + width: lineWidth + } + ); + } + return initial; +} + +Road.prototype.findRoute = function () { + var length = this.chosenPath.length; + var sum = this.chosenPath.reduce((a, b) => a + b, 0); + switch (length) { + case 0: return 'coconut-beach'; + case 1: + switch (sum) { + case 0: return 'gateaway'; + case 1: return 'devils-canyon'; + } + case 2: + switch (sum) { + case 0: return 'desert'; + case 1: return 'alps'; + case 2: return 'cloudy-mountain'; + } + case 3: + switch (sum) { + case 0: return 'wilderness'; + case 1: return 'old-capital'; + case 2: return 'wheat-field'; + case 3: return 'seaside-town'; + } + case 4: + switch (sum) { + case 0: return 'vineyard'; + case 1: return 'death-valley'; + case 2: return 'desolation-hill'; + case 3: return 'autobahn'; + case 4: return 'lakeside'; + } + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Segment.js b/Games/OutRun_Offline_Game/main/Segment.js new file mode 100644 index 0000000000..99c7195d20 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Segment.js @@ -0,0 +1,79 @@ +function Segment(prevSegment, curve, hill, index, isInitial, isTunnel) { + this.numLanes = prevSegment.numLanes; + this.isInitial = isInitial; + this.curve = prevSegment.curve + curve; + this.hill = prevSegment.hill + hill; + this.lowCenter = prevSegment.highCenter; + this.highCenter = new Vector3(this.lowCenter.x + curve, this.lowCenter.y + hill, this.lowCenter.z + segmentDepth); + this.isDark = index % (2 * invisSegment) < invisSegment; + this.offroad = new Tile(prevSegment.offroad, this.highCenter); + this.asphalt = new Tile(prevSegment.asphalt, this.highCenter); + this.leftSide = new Tile(prevSegment.leftSide, this.highCenter); + this.rightSide = new Tile(prevSegment.rightSide, this.highCenter); + this.lines = []; + for (var i = 0; i < this.numLanes - 1; i++) { + this.lines.push(new Tile(prevSegment.lines[i], this.highCenter)); + } + this.objects = []; + if (!isTunnel) { + if (!(index % (objectDistance / 4))) { + this.objects.push(new WorldObject(new Vector3(this.highCenter.x, this.highCenter.y, this.highCenter.z), 'terrain')); + if (Math.random() < 0.1) { + this.objects.push(new WorldObject(new Vector3(this.highCenter.x, this.highCenter.y, this.highCenter.z), 'left' + (Math.random() < 0.5 ? '1' : '2'))); + } + } + if (!(index % objectDistance)) { + this.objects.push(new WorldObject(new Vector3(this.highCenter.x, this.highCenter.y, this.highCenter.z), 'right' + (Math.random() < 0.5 ? '1' : '2'))); + } + } else if (!(index % tunnelDistance)) { + this.objects.push(new WorldObject(new Vector3(this.highCenter.x, this.highCenter.y, this.highCenter.z), 'tunnel')); + } +} + +const invisSegment = 5; +const sideLineWidth = 300; +const lineWidth = 150; +const laneWidth = 1200; +const offroadWidth = 70000; +const segmentDepth = 600; +const objectDistance = 20; +const tunnelDistance = 6; + +Segment.prototype.project = function () { + if (this.isInitial & this.lowCenter.z > Driver.camera.position.z) { + this.offroad.downLeft.project(); + this.offroad.downRight.project(); + this.asphalt.downLeft.project(); + this.asphalt.downRight.project(); + this.leftSide.downLeft.project(); + this.leftSide.downRight.project(); + this.rightSide.downLeft.project(); + this.rightSide.downRight.project(); + for (var i = 0; i < this.numLanes - 1; i++) { + this.lines[i].downLeft.project(); + this.lines[i].downRight.project(); + } + } + this.highCenter.x = this.lowCenter.x + (this.curve - Driver.curve); + this.highCenter.project(); + var measure2 = this.highCenter.z - Driver.camera.position.z; + this.offroad.project(measure2); + this.asphalt.project(measure2); + this.leftSide.project(measure2); + this.rightSide.project(measure2); + for (var i = 0, size = this.numLanes / 2; i < size; i++) { + var relSpace = Vector3.calculate(this.lines[i].space, Driver.camera.gap, measure2); + var relWidth = Vector3.calculate(this.lines[i].width, Driver.camera.gap, measure2); + this.lines[i].calculate(relSpace, relWidth); + this.lines[this.numLanes - 2 - i].calculate(-relSpace, relWidth); + } + if (this.numLanes % 2 == 0) { + this.lines[this.numLanes / 2 + 1].project(measure2); + } + for (var i = 0; i < this.objects.length; i++) { + if (dimensions[Outrun.gameWorld.route][this.objects[i].fileName] != undefined) { + this.objects[i].center.x = this.highCenter.x + dimensions[Outrun.gameWorld.route][this.objects[i].fileName].offset; + this.objects[i].project(measure2); + } + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Tile.js b/Games/OutRun_Offline_Game/main/Tile.js new file mode 100644 index 0000000000..d750d8cec2 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Tile.js @@ -0,0 +1,26 @@ +function Tile(prevTile, highCenter) { + this.lowCenter = prevTile.highCenter; + this.highCenter = highCenter; + this.space = prevTile.space; + this.width = prevTile.width; + this.downLeft = prevTile.upLeft; + this.downRight = prevTile.upRight; + this.upLeft = new Vector3(); + this.upRight = new Vector3(); +} + +Tile.prototype.project = function (measure2) { + var relSpace = Vector3.calculate(this.space, Driver.camera.gap, measure2); + var relWidth = Vector3.calculate(this.width, Driver.camera.gap, measure2); + this.upLeft.xScreen = this.highCenter.xScreen + relSpace - relWidth / 2; + this.upLeft.yScreen = this.highCenter.yScreen; + this.upRight.xScreen = this.highCenter.xScreen + relSpace + relWidth / 2; + this.upRight.yScreen = this.highCenter.yScreen; +} + +Tile.prototype.calculate = function (relSpace, relWidth) { + this.upLeft.xScreen = this.highCenter.xScreen + relSpace - relWidth / 2; + this.upLeft.yScreen = this.highCenter.yScreen; + this.upRight.xScreen = this.highCenter.xScreen + relSpace + relWidth / 2; + this.upRight.yScreen = this.highCenter.yScreen; +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Vector3.js b/Games/OutRun_Offline_Game/main/Vector3.js new file mode 100644 index 0000000000..20629928de --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Vector3.js @@ -0,0 +1,17 @@ +function Vector3(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + this.xScreen = 0; + this.yScreen = 0; +} + +Vector3.prototype.project = function () { + zDiff = this.z - Driver.camera.position.z; + this.xScreen = Canvas.width / 2 + Driver.camera.gap * (this.x - Driver.camera.position.x) / zDiff; + this.yScreen = Canvas.height / 2 + Driver.camera.gap * (Driver.camera.position.y - this.y) / zDiff; +} + +Vector3.calculate = function (length, measure1, measure2) { + return length * measure1 / measure2; +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Vehicle.js b/Games/OutRun_Offline_Game/main/Vehicle.js new file mode 100644 index 0000000000..037d5a91d0 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Vehicle.js @@ -0,0 +1,85 @@ +function Vehicle(center, shift, vehicleType) { + this.vehicleType = vehicleType; + this.shift = shift; + this.car = new WorldObject(center, 'right0'); + this.car.width = 810; + this.car.height = 460; + this.car.project = function (measure2, dimension) { + this.center.project(); + this.relWidth = Vector3.calculate(dimension.width, Driver.camera.gap, measure2); + this.relHeight = Vector3.calculate(dimension.height, Driver.camera.gap, measure2); + } + this.lastSegment = null; + this.chosenPath = []; + this.curveDirection = 0; + this.hasStopped = false; +} + +const speed = 400; + +Vehicle.prototype.play = function () { + if (!this.hasStopped) { + this.car.center.z += speed; + } + + var carIndex = Outrun.gameWorld.road.findIndex(this.car.center.z); + var segment = Outrun.gameWorld.road.segments[carIndex]; + if (segment instanceof Segment) { + this.hasStopped = false; + this.lastSegment = segment; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Segment) { + this.curveDirection = segment.curve - Outrun.gameWorld.road.segments[carIndex - 1].curve; + } else { + this.curveDirection = 0; + this.shift += 1.5 * (this.chosenPath[this.chosenPath.length - 1] ? -1 : 1); + } + } else if (segment instanceof Junction) { + this.hasStopped = false; + if (Outrun.gameWorld.road.trackCount > this.chosenPath.length) { + this.chosenPath.push(this.car.center.x >= this.lastSegment.highCenter.x); + this.shift += 1.5 * (this.chosenPath[this.chosenPath.length - 1] ? -1 : 1); + } + if (this.chosenPath[this.chosenPath.length - 1]) { + segment = segment.rightJunction; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Junction) { + this.curveDirection = segment.curve - Outrun.gameWorld.road.segments[carIndex - 1].rightJunction.curve; + } else { + this.curveDirection = 0; + } + } else { + segment = segment.leftJunction; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Junction) { + this.curveDirection = segment.curve - Outrun.gameWorld.road.segments[carIndex - 1].leftJunction.curve; + } else { + this.curveDirection = 0; + } + } + } else { + this.hasStopped = true; + } + + this.car.center.x = segment.highCenter.x + this.shift * (laneWidth + lineWidth); + this.car.center.y = segment.highCenter.y; +} + +Vehicle.prototype.project = function () { + this.car.project(this.car.center.z - Driver.camera.position.z, dimensions[this.vehicleType]); + + if (this.curveDirection < 0) { + if (this.car.center.x < Driver.car.center.x) + this.car.fileName = 'left1'; + else + this.car.fileName = 'left0'; + } else if (this.curveDirection > 0) { + if (this.car.center.x > Driver.car.center.x) + this.car.fileName = 'right1'; + else + this.car.fileName = 'right0'; + } else { + if (this.car.center.x < Driver.car.center.x) { + this.car.fileName = 'right0'; + } else { + this.car.fileName = 'left0'; + } + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/WorldObject.js b/Games/OutRun_Offline_Game/main/WorldObject.js new file mode 100644 index 0000000000..ca9cdee988 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/WorldObject.js @@ -0,0 +1,12 @@ +function WorldObject(center, fileName) { + this.center = center; + this.fileName = fileName; + this.relHeight = 0; + this.relWidth = 0; +} + +WorldObject.prototype.project = function (measure2) { + this.center.project(); + this.relWidth = Vector3.calculate(dimensions[Outrun.gameWorld.route][this.fileName].width, Driver.camera.gap, measure2); + this.relHeight = Vector3.calculate(dimensions[Outrun.gameWorld.route][this.fileName].height, Driver.camera.gap, measure2); +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/style.css b/Games/OutRun_Offline_Game/style.css new file mode 100644 index 0000000000..8f3d69218f --- /dev/null +++ b/Games/OutRun_Offline_Game/style.css @@ -0,0 +1,17 @@ +html, body { + width: 100%; + height: 100%; + margin: 0; + background-color: #3d3d3d; +} + +canvas { + padding: 0; + margin: auto; + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} \ No newline at end of file diff --git a/Games/Pattern_Creation_Game/Readme.md b/Games/Pattern_Creation_Game/Readme.md new file mode 100644 index 0000000000..ebddeccbc4 --- /dev/null +++ b/Games/Pattern_Creation_Game/Readme.md @@ -0,0 +1,25 @@ +

Pattern Creation Game

+ +A web-based game that allows users to create, save, load, and share patterns using a customizable grid. Users can select colors, change brush sizes, use an eraser, and apply a fill tool to create intricate designs. +
+

Features

+ +1- Color Picker: Select any color using an HTML color input.
+2- Brush Size Tool: Change the size of the brush to color multiple cells at once.
+3- Eraser Tool: Erase colors from the grid cells.
+4- Fill Tool: Fill the entire grid with the selected color.
+5- Undo/Redo: Revert or reapply the last few actions.
+6- Save Pattern: Save the current pattern as a JSON string.
+7- Load Pattern: Load a pattern from a JSON string.
+8- Clear Grid: Reset the entire grid to white. +
+

How to Play

+ +1- Select a Color: Use the color picker to choose a color, or click the "Eraser" to select the eraser tool.
+2- Change Brush Size: Select the desired brush size from the dropdown menu.
+3- Color the Grid: Click on grid cells to color them with the selected brush size and color.
+4- Fill Grid: Click the "Fill Grid" button to fill the entire grid with the selected color.
+5- Clear Grid: Click the "Clear Grid" button to reset the grid to white.
+6- Undo/Redo: Use the "Undo" and "Redo" buttons to revert or reapply the last few actions.
+7- Save Pattern: Click the "Save Pattern" button to save the current pattern as a JSON string in the textarea.
+8- Load Pattern: Enter a JSON string in the textarea and click the "Load Pattern" button to load the pattern. diff --git a/Games/Pattern_Creation_Game/index.html b/Games/Pattern_Creation_Game/index.html new file mode 100644 index 0000000000..394fec1a90 --- /dev/null +++ b/Games/Pattern_Creation_Game/index.html @@ -0,0 +1,35 @@ + + + + + + Pattern Creation Game + + + +
+
+ +
Eraser
+
+
+ + + + + + + + +
+
+ +
+ + + + diff --git a/Games/Pattern_Creation_Game/script.js b/Games/Pattern_Creation_Game/script.js new file mode 100644 index 0000000000..ec585da0e0 --- /dev/null +++ b/Games/Pattern_Creation_Game/script.js @@ -0,0 +1,110 @@ +const gridContainer = document.getElementById('grid-container'); +const patternCode = document.getElementById('pattern-code'); +let selectedColor = 'black'; +let brushSize = 1; +let grid = []; +let history = []; +let redoStack = []; + +function createGrid() { + gridContainer.innerHTML = ''; + for (let i = 0; i < 10; i++) { + grid[i] = []; + for (let j = 0; j < 10; j++) { + const cell = document.createElement('div'); + cell.classList.add('grid-cell'); + cell.addEventListener('click', () => colorCell(i, j)); + grid[i][j] = { element: cell, color: 'white' }; + gridContainer.appendChild(cell); + } + } +} + +function colorCell(row, col) { + for (let i = 0; i < brushSize; i++) { + for (let j = 0; j < brushSize; j++) { + if (grid[row + i] && grid[row + i][col + j]) { + const cell = grid[row + i][col + j]; + if (cell.color !== selectedColor) { + history.push({ row: row + i, col: col + j, color: cell.color }); + redoStack = []; + cell.color = selectedColor; + cell.element.style.backgroundColor = selectedColor; + } + } + } + } +} + +function selectColor(color) { + selectedColor = color; +} + +function savePattern() { + const pattern = grid.map(row => row.map(cell => cell.color)); + patternCode.value = JSON.stringify(pattern); +} + +function loadPattern() { + try { + const pattern = JSON.parse(patternCode.value); + pattern.forEach((row, i) => { + row.forEach((color, j) => { + grid[i][j].color = color; + grid[i][j].element.style.backgroundColor = color; + }); + }); + history = []; + redoStack = []; + } catch (error) { + alert('Invalid pattern code'); + } +} + +function undo() { + const lastAction = history.pop(); + if (lastAction) { + redoStack.push({ ...lastAction, color: grid[lastAction.row][lastAction.col].color }); + grid[lastAction.row][lastAction.col].color = lastAction.color; + grid[lastAction.row][lastAction.col].element.style.backgroundColor = lastAction.color; + } +} + +function redo() { + const lastUndo = redoStack.pop(); + if (lastUndo) { + history.push({ ...lastUndo, color: grid[lastUndo.row][lastUndo.col].color }); + grid[lastUndo.row][lastUndo.col].color = lastUndo.color; + grid[lastUndo.row][lastUndo.col].element.style.backgroundColor = lastUndo.color; + } +} + +function clearGrid() { + for (let row of grid) { + for (let cell of row) { + cell.color = 'white'; + cell.element.style.backgroundColor = 'white'; + } + } + history = []; + redoStack = []; +} + +function fillGrid() { + for (let row of grid) { + for (let cell of row) { + if (cell.color !== selectedColor) { + history.push({ row: grid.indexOf(row), col: row.indexOf(cell), color: cell.color }); + cell.color = selectedColor; + cell.element.style.backgroundColor = selectedColor; + } + } + } + redoStack = []; +} + +function changeBrushSize(size) { + brushSize = parseInt(size); +} + +createGrid(); diff --git a/Games/Pattern_Creation_Game/styles.css b/Games/Pattern_Creation_Game/styles.css new file mode 100644 index 0000000000..262ffb9e4a --- /dev/null +++ b/Games/Pattern_Creation_Game/styles.css @@ -0,0 +1,78 @@ +body { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + font-family: Arial, sans-serif; + background-color: #f0f0f0; +} + +#game-container { + display: flex; + flex-direction: column; + align-items: center; +} + +#color-palette { + display: flex; + margin-bottom: 20px; +} + +#color-picker { + width: 40px; + height: 40px; + margin-right: 10px; +} + +.color { + width: 30px; + height: 30px; + margin: 0 5px; + border: 1px solid #000; + cursor: pointer; +} + +.eraser { + display: flex; + align-items: center; + justify-content: center; + width: auto; + padding: 0 10px; + background-color: white; + border: 1px solid #000; + font-size: 14px; +} + +#controls { + margin-bottom: 20px; +} + +button { + margin: 0 5px; + padding: 10px; + font-size: 14px; + cursor: pointer; +} + +#grid-container { + display: grid; + grid-template-columns: repeat(10, 30px); + grid-template-rows: repeat(10, 30px); + gap: 2px; +} + +.grid-cell { + width: 30px; + height: 30px; + background-color: white; + border: 1px solid #ddd; + cursor: pointer; +} + +#pattern-code { + margin-top: 20px; + width: 300px; + height: 100px; + resize: none; +} diff --git a/Games/Penalty_Shootout_Game/README.md b/Games/Penalty_Shootout_Game/README.md new file mode 100644 index 0000000000..2be841f97a --- /dev/null +++ b/Games/Penalty_Shootout_Game/README.md @@ -0,0 +1,3 @@ +# Penalty Shootout Game +An HTML canvas based game, that can be played using mouse click. +HTML canvas has been used for the animation of the character and animation of the ball has been achieved by making the ball move through an SVG curve. \ No newline at end of file diff --git a/Games/Penalty_Shootout_Game/css/main.css b/Games/Penalty_Shootout_Game/css/main.css new file mode 100644 index 0000000000..0fcbf3d1cc --- /dev/null +++ b/Games/Penalty_Shootout_Game/css/main.css @@ -0,0 +1,529 @@ +/*! HTML5 Boilerplate v4.3.0 | MIT License | http://h5bp.com/ */ + +html, +button, +input, +select, +textarea { + color: #222; +} + +html { + font-size: 1em; + line-height: 1.4; +} + +::-moz-selection { + background: #b3d4fc; + text-shadow: none; +} + +::selection { + background: #b3d4fc; + text-shadow: none; +} + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0; +} + +audio, +canvas, +img, +video { + vertical-align: middle; +} + +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +textarea { + resize: vertical; +} + +.browsehappy { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} + + +/* ========================================================================== + Author's custom styles + ========================================================================== */ + +html { + height: 100%; +} + +body { + background: #000; + height: 100%; +} + +#zee-ball { + position: absolute; top: 440px; left: 390px; + -webkit-transition: width 0.5s linear, height 0.5s linear; + -moz-transition: width 0.5s linear, height 0.5s linear; + -ms-transition: width 0.5s linear, height 0.5s linear; + -o-transition: width 0.5s linear, height 0.5s linear; + transition: width 0.5s linear, height 0.5s linear; +} + +#kickAnimation { + position: absolute; + top: 250px; + left: 280px; +} + +#zee-game { + margin: 0 auto 0 auto; + width: 810px; + height: 525px; + position: relative; + background: url('../img/background.jpg') no-repeat top center transparent; + cursor: pointer; + overflow: hidden; + + /* center vertically on the screen */ + top: 50%; + margin-top: -262.5px; +} + +#vertical-direction { + position: absolute; + top: 342px; + left: 60px; + width: 17px; + height: 130px; + background: url('../img/direction-vertical.png') no-repeat 0 0 transparent; +} + +#horizontal-direction { + position: absolute; + top: 500px; + left: 60px; + width: 132px; + height: 18px; + background: url('../img/direction-horizontal.png') no-repeat 0 0 transparent; +} + +#power-level { + position: absolute; + top: 500px; + right: 70px; + width: 134px; + height: 11px; + background: url('../img/power.png') no-repeat 0 0 transparent; +} + +.small-ball { + position: absolute; + width: 13px; + height: 13px; + background: url('../img/small-ball.png') no-repeat 0 0 transparent; +} + +#horizontal-direction-indicator { + top: 480px; + -webkit-transition: left 0.32s ease-out; + -moz-transition: left 0.32s ease-out; + -ms-transition: left 0.32s ease-out; + -o-transition: left 0.32s ease-out; + transition: left 0.32s ease-out; +} + +#horizontal-direction-indicator.one-end { + left: 60px; +} + +#horizontal-direction-indicator.other-end { + left: 179px; +} + +#vertical-direction-indicator { + left: 82px; + -webkit-transition: top 0.32s ease-out; + -moz-transition: top 0.32s ease-out; + -ms-transition: top 0.32s ease-out; + -o-transition: top 0.32s ease-out; + transition: top 0.32s ease-out; +} + +#vertical-direction-indicator.one-end { + top: 342px; +} + +#vertical-direction-indicator.other-end { + top: 459px; +} + +#power-level-indicator { + top: 477px; + -webkit-transition: right 0.32s ease-out; + -moz-transition: right 0.32s ease-out; + -ms-transition: right 0.32s ease-out; + -o-transition: right 0.32s ease-out; + transition: right 0.32s ease-out; +} + +#power-level-indicator.one-end { + right: 70px; +} + +#power-level-indicator.other-end { + right: 191px; +} + +/* goal keeper */ +.goal-keeper { + position: absolute; + height: 194px; + width: 596px; + top: 98px; + left: 114px; +} + +.goal-keeper.standing { + background: url('../img/keeper-standing.png') no-repeat 0 0 transparent; +} + +.goal-keeper.right-jump { + background: url('../img/keeper-right-jump.png') no-repeat 0 0 transparent; + display: none; +} + +.goal-keeper.left-jump { + background: url('../img/keeper-left-jump.png') no-repeat 0 0 transparent; + display: none; +} + +/* modals */ + +.modal { + position: absolute; + top: -475px; + left: 239px; + width: 288px; + min-height: 41px; + padding: 30px; + -webkit-transition: top 0.26s ease-out; + -moz-transition: top 0.26s ease-out; + -ms-transition: top 0.26s ease-out; + -o-transition: top 0.26s ease-out; + transition: top 0.26s ease-out; + text-align: center; + /* default fallback */ + background: rgb(255, 255, 255) transparent; + /* nice browsers */ + background: rgba(255, 255, 255, 0.8); + /* IE 6/7 */ + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#CCFFFFFF, endColorstr=#CCFFFFFF); + /* IE8 */ + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#CCFFFFFF, endColorstr=#CCFFFFFF)"; + /* border radius */ + -webkit-border-radius: 10px 10px 10px 10px; + -moz-border-radius: 10px 10px 10px 10px; + border-radius: 10px 10px 10px 10px; + + /* font styles */ + font: 25px sans-serif; +} + +.modal.active { + top: 232px; +} + +#score-board { + list-style: none; + padding: 6px 0 0 64px; + margin: 0; +} + +#score-board li { + float: left; + margin-right: 6px; + zoom: 1; + filter: alpha(opacity=56); + opacity: 0.56; +} + +#score-board li.scored { + zoom: 1; + filter: alpha(opacity=100); + opacity: 1; +} + +/* splash screen */ +#splash-screen { + position: absolute; + top: 0; left: 5px; + width: 800px; height: 800px; + background: url('../img/splash-screen.jpg') no-repeat 0 0 #fff; + -webkit-transition: top 0.38s ease-out; + -moz-transition: top 0.38s ease-out; + -ms-transition: top 0.38s ease-out; + -o-transition: top 0.38s ease-out; + transition: top 0.38s ease-out; +} + +#splash-screen.out { + top: -800px; +} + +/* form */ +#form-thing .labels { + font: 16px sans-serif; + line-height: 1; +} + +#form-thing input[type="text"] { + border: 1px solid #CCC; + border-radius: 8px; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + padding: 9px 13px; + margin: 9px 0 9px 18px; + font: 16px sans-serif; + color: #666; + line-height: 1; + width: 212px; +} + +#form-thing button { + border: none; + background: #CFCFCF; + font: 16px sans-serif; + line-height: 1; + padding: 12px 18px; + border-radius: 8px; + margin-top: 14px; + width: 309px; +} + +#form-thing button:hover { + background: #dfdfdf; +} + +#form-thing button.submitted { + background: #dfdfdf; +} + +#form-thing form { + padding: 102px 0 0 254px; + zoom: 1; + filter: alpha(opacity=90); + opacity: 0.9; +} + +#form-thing form label { + color: #eee; +} + +#form-thing { + position: absolute; + width: 800px; height: 800px; + top: 0; left: 5px; + background: #fff; + -webkit-transition: top 0.38s ease-out; + -moz-transition: top 0.38s ease-out; + -ms-transition: top 0.38s ease-out; + -o-transition: top 0.38s ease-out; + transition: top 0.38s ease-out; + background: url('../img/form.jpg') no-repeat 0 0 #fff; +} + +#form-thing.out { + top: -800px; +} + +#zee-button { + position: absolute; + top: 497px; + left: 318px; + width: 177px; + height: 49px; + cursor: pointer; +} + +#form-message { + text-align: center; + color: #ddd; +} + +/* instructions */ +#instructions { + position: absolute; + width: 800px; height: 800px; + top: 0; left: 5px; + background: url('../img/instructions.jpg') no-repeat 0 0 #fff; + -webkit-transition: top 0.38s ease-out; + -moz-transition: top 0.38s ease-out; + -ms-transition: top 0.38s ease-out; + -o-transition: top 0.38s ease-out; + transition: top 0.38s ease-out; +} + +#instructions.out { + top: -800px; +} + +#like-gate { + position: absolute; + width: 800px; height: 800px; + top: 0; left: 5px; + background: url('../img/like-gate.jpg') no-repeat 0 0 #fff; +} + +/* ========================================================================== + Media Queries + ========================================================================== */ + +@media only screen and (min-width: 35em) { + +} + +@media print, + (-o-min-device-pixel-ratio: 5/4), + (-webkit-min-device-pixel-ratio: 1.25), + (min-resolution: 120dpi) { + +} + +/* ========================================================================== + Helper classes + ========================================================================== */ + +.ir { + background-color: transparent; + border: 0; + overflow: hidden; + *text-indent: -9999px; +} + +.ir:before { + content: ""; + display: block; + width: 0; + height: 150%; +} + +.hidden { + display: none !important; + visibility: hidden; +} + +.visuallyhidden { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +.visuallyhidden.focusable:active, +.visuallyhidden.focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; +} + +.invisible { + visibility: hidden; +} + +.clearfix:before, +.clearfix:after { + content: " "; + display: table; +} + +.clearfix:after { + clear: both; +} + +.clearfix { + *zoom: 1; +} + +/* ========================================================================== + Print styles + ========================================================================== */ + +@media print { + * { + background: transparent !important; + color: #000 !important; + box-shadow: none !important; + text-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + thead { + display: table-header-group; + } + + tr, + img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + @page { + margin: 0.5cm; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } +} diff --git a/Games/Penalty_Shootout_Game/css/normalize.css b/Games/Penalty_Shootout_Game/css/normalize.css new file mode 100644 index 0000000000..42e24d6880 --- /dev/null +++ b/Games/Penalty_Shootout_Game/css/normalize.css @@ -0,0 +1,527 @@ +/*! normalize.css v1.1.3 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +/** + * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. + */ + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4. + * Known issue: no IE 6 support. + */ + +[hidden] { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/** + * 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using + * `em` units. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-size: 100%; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Address `font-family` inconsistency between `textarea` and other form + * elements. + */ + +html, +button, +input, +select, +textarea { + font-family: sans-serif; +} + +/** + * Address margins handled incorrectly in IE 6/7. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/** + * Address `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/** + * Address font sizes and margins set differently in IE 6/7. + * Address font sizes within `section` and `article` in Firefox 4+, Safari 5, + * and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +h2 { + font-size: 1.5em; + margin: 0.83em 0; +} + +h3 { + font-size: 1.17em; + margin: 1em 0; +} + +h4 { + font-size: 1em; + margin: 1.33em 0; +} + +h5 { + font-size: 0.83em; + margin: 1.67em 0; +} + +h6 { + font-size: 0.67em; + margin: 2.33em 0; +} + +/** + * Address styling not present in IE 7/8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +blockquote { + margin: 1em 40px; +} + +/** + * Address styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address differences between Firefox and other browsers. + * Known issue: no IE 6/7 normalization. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Address styling not present in IE 6/7/8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address margins set differently in IE 6/7. + */ + +p, +pre { + margin: 1em 0; +} + +/** + * Correct font family set oddly in IE 6, Safari 4/5, and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; +} + +/** + * Improve readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/** + * Address CSS quotes not supported in IE 6/7. + */ + +q { + quotes: none; +} + +/** + * Address `quotes` property not supported in Safari 4. + */ + +q:before, +q:after { + content: ''; + content: none; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Lists + ========================================================================== */ + +/** + * Address margins set differently in IE 6/7. + */ + +dl, +menu, +ol, +ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +/** + * Address paddings set differently in IE 6/7. + */ + +menu, +ol, +ul { + padding: 0 0 0 40px; +} + +/** + * Correct list images handled incorrectly in IE 7. + */ + +nav ul, +nav ol { + list-style: none; + list-style-image: none; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/** + * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3. + * 2. Improve image quality when scaled in IE 7. + */ + +img { + border: 0; /* 1 */ + -ms-interpolation-mode: bicubic; /* 2 */ +} + +/** + * Correct overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/** + * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/** + * Correct margin displayed oddly in IE 6/7. + */ + +form { + margin: 0; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct color not being inherited in IE 6/7/8/9. + * 2. Correct text not wrapping in Firefox 3. + * 3. Correct alignment displayed oddly in IE 6/7. + */ + +legend { + border: 0; /* 1 */ + padding: 0; + white-space: normal; /* 2 */ + *margin-left: -7px; /* 3 */ +} + +/** + * 1. Correct font size not being inherited in all browsers. + * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5, + * and Chrome. + * 3. Improve appearance and consistency in all browsers. + */ + +button, +input, +select, +textarea { + font-size: 100%; /* 1 */ + margin: 0; /* 2 */ + vertical-align: baseline; /* 3 */ + *vertical-align: middle; /* 3 */ +} + +/** + * Address Firefox 3+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+. + * Correct `select` style inheritance in Firefox 4+ and Opera. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + * 4. Remove inner spacing in IE 7 without affecting normal text inputs. + * Known issue: inner spacing remains in IE 6. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ + *overflow: visible; /* 4 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * 1. Address box sizing set to content-box in IE 8/9. + * 2. Remove excess padding in IE 8/9. + * 3. Remove excess padding in IE 7. + * Known issue: excess padding remains in IE 6. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ + *height: 13px; /* 3 */ + *width: 13px; /* 3 */ +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Remove inner padding and border in Firefox 3+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * 1. Remove default vertical scrollbar in IE 6/7/8/9. + * 2. Improve readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/Games/Penalty_Shootout_Game/css/normalize.min.css b/Games/Penalty_Shootout_Game/css/normalize.min.css new file mode 100644 index 0000000000..f33b6e9858 --- /dev/null +++ b/Games/Penalty_Shootout_Game/css/normalize.min.css @@ -0,0 +1 @@ +/*! normalize.css v1.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0} \ No newline at end of file diff --git a/Games/Penalty_Shootout_Game/img/background.jpg b/Games/Penalty_Shootout_Game/img/background.jpg new file mode 100644 index 0000000000..f19ac2a1c6 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/background.jpg differ diff --git a/Games/Penalty_Shootout_Game/img/direction-horizontal.png b/Games/Penalty_Shootout_Game/img/direction-horizontal.png new file mode 100644 index 0000000000..e7b3b33441 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/direction-horizontal.png differ diff --git a/Games/Penalty_Shootout_Game/img/direction-vertical.png b/Games/Penalty_Shootout_Game/img/direction-vertical.png new file mode 100644 index 0000000000..a141646698 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/direction-vertical.png differ diff --git a/Games/Penalty_Shootout_Game/img/favicons/zee-ball-16x16.png b/Games/Penalty_Shootout_Game/img/favicons/zee-ball-16x16.png new file mode 100644 index 0000000000..872787087b Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/favicons/zee-ball-16x16.png differ diff --git a/Games/Penalty_Shootout_Game/img/favicons/zee-ball-43x43.png b/Games/Penalty_Shootout_Game/img/favicons/zee-ball-43x43.png new file mode 100644 index 0000000000..c5710515a2 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/favicons/zee-ball-43x43.png differ diff --git a/Games/Penalty_Shootout_Game/img/form.jpg b/Games/Penalty_Shootout_Game/img/form.jpg new file mode 100644 index 0000000000..82adf9035d Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/form.jpg differ diff --git a/Games/Penalty_Shootout_Game/img/instructions.jpg b/Games/Penalty_Shootout_Game/img/instructions.jpg new file mode 100644 index 0000000000..a87718ac44 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/instructions.jpg differ diff --git a/Games/Penalty_Shootout_Game/img/keeper-left-jump.png b/Games/Penalty_Shootout_Game/img/keeper-left-jump.png new file mode 100644 index 0000000000..569dd1cc15 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/keeper-left-jump.png differ diff --git a/Games/Penalty_Shootout_Game/img/keeper-right-jump.png b/Games/Penalty_Shootout_Game/img/keeper-right-jump.png new file mode 100644 index 0000000000..1596c05713 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/keeper-right-jump.png differ diff --git a/Games/Penalty_Shootout_Game/img/keeper-standing.png b/Games/Penalty_Shootout_Game/img/keeper-standing.png new file mode 100644 index 0000000000..5136b916b8 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/keeper-standing.png differ diff --git a/Games/Penalty_Shootout_Game/img/like-gate.jpg b/Games/Penalty_Shootout_Game/img/like-gate.jpg new file mode 100644 index 0000000000..4df49f4bab Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/like-gate.jpg differ diff --git a/Games/Penalty_Shootout_Game/img/power.png b/Games/Penalty_Shootout_Game/img/power.png new file mode 100644 index 0000000000..d9c55a9ff9 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/power.png differ diff --git a/Games/Penalty_Shootout_Game/img/slow-kick-right.png b/Games/Penalty_Shootout_Game/img/slow-kick-right.png new file mode 100644 index 0000000000..303796d8d4 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/slow-kick-right.png differ diff --git a/Games/Penalty_Shootout_Game/img/small-ball.png b/Games/Penalty_Shootout_Game/img/small-ball.png new file mode 100644 index 0000000000..d5d1e087df Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/small-ball.png differ diff --git a/Games/Penalty_Shootout_Game/img/splash-screen.jpg b/Games/Penalty_Shootout_Game/img/splash-screen.jpg new file mode 100644 index 0000000000..1964fbcf71 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/splash-screen.jpg differ diff --git a/Games/Penalty_Shootout_Game/img/zee-ball.png b/Games/Penalty_Shootout_Game/img/zee-ball.png new file mode 100644 index 0000000000..c5710515a2 Binary files /dev/null and b/Games/Penalty_Shootout_Game/img/zee-ball.png differ diff --git a/Games/Penalty_Shootout_Game/index.html b/Games/Penalty_Shootout_Game/index.html new file mode 100644 index 0000000000..854a327cca --- /dev/null +++ b/Games/Penalty_Shootout_Game/index.html @@ -0,0 +1,81 @@ + + + + + + + + + Penalty Shootout + + + + + + + + + + + + + + + + +
+ + +
+
+
+ + + + + + + + + + + + + +
+
+
+
+
+
+ + +
    +
  • +
  • +
  • +
  • +
  • +
+ +
+ + + + + + + + + diff --git a/Games/Penalty_Shootout_Game/js/.main.js.swp b/Games/Penalty_Shootout_Game/js/.main.js.swp new file mode 100644 index 0000000000..002a94ea81 Binary files /dev/null and b/Games/Penalty_Shootout_Game/js/.main.js.swp differ diff --git a/Games/Penalty_Shootout_Game/js/main.js b/Games/Penalty_Shootout_Game/js/main.js new file mode 100644 index 0000000000..d8b5467d9b --- /dev/null +++ b/Games/Penalty_Shootout_Game/js/main.js @@ -0,0 +1,439 @@ +// kick animation using William Malone's code +// http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/ + +// Copyright 2013 William Malone (www.williammalone.com) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +(function() { + // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel + // MIT license + + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] + || window[vendors[x]+'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) + window.requestAnimationFrame = function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function() { callback(currTime + timeToCall); }, + timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + + if (!window.cancelAnimationFrame) + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; +}()); + + + +// stopping the oscillating indicators, recording values of indicators and keeping track of goals +var verticalBallStopped = false; +var horizontalBallStopped = false; +var powerBallStopped = false; +var x1, x2, x3; +var chanceCount = 0; +// recording the direction of the jump by the player, goal or not and the end co-ordinates of the ball +var direction; +var endTop = 440; +var endLeft = 390; +var score = 0; +// variables to store user information +var thisName; +var thisTel; +var thisEmail; +var thisCity; + +function kick(el, et) { + + var player, + playerImage, + canvas, + isItOver; + + isItOver = false; + + function gameLoop () { + if (isItOver == false) { + window.requestAnimationFrame(gameLoop); + + player.update(); + player.render(); + } + } + + function sprite (options) { + + var that = {}, + frameIndex = 0, + tickCount = 0, + ticksPerFrame = options.ticksPerFrame || 0, + numberOfFrames = options.numberOfFrames || 1; + + that.context = options.context; + that.width = options.width; + that.height = options.height; + that.image = options.image; + + that.update = function () { + + tickCount += 1; + + if (tickCount > ticksPerFrame) { + + tickCount = 0; + + // If the current frame index is in range + if (frameIndex < numberOfFrames - 2) { + // Go to the next frame + frameIndex += 1; + } + else if (frameIndex == numberOfFrames - 2) { + frameIndex += 1; + // start moving the ball + moveBall(el, et); + // make the goal keeper jump + keeperJump(); + } + else if (frameIndex < numberOfFrames - 1) { + frameIndex += 1; + } + else { + // frameIndex = 0; // don't repeat the animation + isItOver = true; + } + } + }; + + that.render = function () { + + // Clear the canvas + that.context.clearRect(0, 0, that.width, that.height); + + // Draw the animation + that.context.drawImage( + that.image, + frameIndex * that.width / numberOfFrames, + 0, + that.width / numberOfFrames, + that.height, + 0, + 0, + that.width / numberOfFrames, + that.height); + }; + + return that; + } + + // Get canvas + canvas = document.getElementById("kickAnimation"); + canvas.width = 150; + canvas.height = 270; + + // Create sprite sheet + playerImage = new Image(); + + // Create sprite + player = sprite({ + context: canvas.getContext("2d"), + width: 300, + height: 270, + image: playerImage, + numberOfFrames: 2, + ticksPerFrame: 20 + }); + + // Load sprite sheet + playerImage.addEventListener("load", gameLoop); + playerImage.src = "img/slow-kick-right.png"; + +} + +function keeperJump() { + var randomBinary = Math.floor(Math.random()*2); + var someTimeAfter = window.setTimeout(function() { + if ((randomBinary == 0) && (x3 >= 0.55)) { + document.getElementById('goal-keeper-state-1').style.display = "none"; + document.getElementById('goal-keeper-state-2').style.display = "block"; + direction = "left"; + } + else if ((randomBinary == 1) && (x3 >= 0.55)) { + document.getElementById('goal-keeper-state-1').style.display = "none"; + document.getElementById('goal-keeper-state-3').style.display = "block"; + direction = "right"; + } + }, 0); +} + +function moveBall(el, et) { + var path = "M " + "390" + "," + "440" + " "+ el + "," + et; // Ml Mt Ql Qt El Et " Q " + "460" + "," + "340" + + pathAnimator = new PathAnimator( path ), // initiate a new pathAnimator object + objToAnimate = document.getElementById('zee-ball'), // The object that will move along the path + speed = 0.5, // seconds that will take going through the whole path + reverse = false, // go back of forward along the path + startOffset = 0 // between 0% to 100% + + // start animating the ball + pathAnimator.start( speed, step, reverse, startOffset, finish); + + // make the ball smaller in size with respect to the distance from the eye please! + + function step( point, angle ){ + // do something every "frame" with: point.x, point.y & angle + objToAnimate.style.cssText = "top:" + point.y + "px;" + + "left:" + point.x + "px;" + + "transform:rotate("+ angle +"deg);" + + "-webkit-transform:rotate("+ angle +"deg);"; + } + + function finish(){ + // see if the ball has reached the goal + if ((endTop >= 98)&&(endTop <= 292)&&(endLeft >= 114)&&(endLeft <= 710)) { + if ((direction == "right")&&(endLeft < 362)) { + // increase the score and indicate it on the score board + incrementScore(); + if (chanceCount < 4) {modalElem5.setAttribute("class","modal active");} + else { + if (score > 4) {modalElem7.setAttribute("class","modal active");} + else {modalElem6.innerHTML = "You scored " + score + " goal(s) out of 5. Click to try again"; + modalElem6.setAttribute("class","modal active");} + } + } + else if ((direction == "left")&&(endLeft >= 362)) { + // increase the score and indicate it on the score board + incrementScore(); + if (chanceCount < 4) {modalElem5.setAttribute("class","modal active");} + else { + if (score > 4) {modalElem7.setAttribute("class","modal active");} + else {modalElem6.innerHTML = "You scored " + score + " goal(s) out of 5. Click to try again"; + modalElem6.setAttribute("class","modal active");} + } + } + else { + if (chanceCount < 4) {modalElem4.setAttribute("class","modal active");} + else { + modalElem6.innerHTML = "You scored " + score + " goal(s) out of 5. Click to try again"; + modalElem6.setAttribute("class","modal active"); + } + } + } + else { + if (chanceCount < 4) {modalElem4.setAttribute("class","modal active");} + else { + modalElem6.innerHTML = "You scored " + score + " goal(s) out of 5. Click to try again"; + modalElem6.setAttribute("class","modal active"); + } + } + } +} + +// to osciallte the vertical direction indicator +function moveVerticalSmallBall() { + var thing = document.getElementById('vertical-direction-indicator'); + if (thing.getAttribute('class') == "small-ball one-end") { + thing.setAttribute('class','small-ball other-end'); + } + else if (thing.getAttribute('class') == "small-ball other-end") { + thing.setAttribute('class','small-ball one-end'); + } +} + +var verticalIndicatorOscillate = window.setInterval(moveVerticalSmallBall, 320); + +// to osciallte the horizontal direction indicator +function moveHorizontalSmallBall() { + var thing = document.getElementById('horizontal-direction-indicator'); + if (thing.getAttribute('class') == "small-ball one-end") { + thing.setAttribute('class','small-ball other-end'); + } + else if (thing.getAttribute('class') == "small-ball other-end") { + thing.setAttribute('class','small-ball one-end'); + } +} + +var verticalIndicatorOscillate = window.setInterval(moveHorizontalSmallBall, 320); + +// to osciallte the vertical direction indicator +function movePowerSmallBall() { + var thing = document.getElementById('power-level-indicator'); + if (thing.getAttribute('class') == "small-ball one-end") { + thing.setAttribute('class','small-ball other-end'); + } + else if (thing.getAttribute('class') == "small-ball other-end") { + thing.setAttribute('class','small-ball one-end'); + } +} + +var powerLevelOscillate = window.setInterval(movePowerSmallBall, 320); + +function refreshScene() { + // stop the meters + document.getElementById('vertical-direction-indicator').setAttribute('style','') + document.getElementById('vertical-direction-indicator').setAttribute('class','small-ball one-end'); + document.getElementById('horizontal-direction-indicator').setAttribute('style','') + document.getElementById('horizontal-direction-indicator').setAttribute('class','small-ball one-end'); + document.getElementById('power-level-indicator').setAttribute('style','') + document.getElementById('power-level-indicator').setAttribute('class','small-ball one-end'); + verticalBallStopped = false; + horizontalBallStopped = false; + powerBallStopped = false; + + // stop the ball + document.getElementById('zee-ball').setAttribute('style','') + document.getElementById('zee-ball').setAttribute('class',''); + + // clear the canvas or in other words, make the player vanish + var contextForNow = document.getElementById('kickAnimation').getContext('2d'); + contextForNow.clearRect(0,0,150,270); + + // reset position of the goal keeper + document.getElementById('goal-keeper-state-2').style.display = "none"; + document.getElementById('goal-keeper-state-3').style.display = "none"; + document.getElementById('goal-keeper-state-1').style.display = "block"; +} + +function stopVerticalBall() { + var element = document.getElementById('vertical-direction-indicator'), + style = window.getComputedStyle(element), + top = style.getPropertyValue('top'); + x1 = parseInt(top.substring(0,3), 10); + x1 = (459-x1)/117; + console.log(x1); + // fix the position of the small ball to wherever it is + element.setAttribute("class", "small-ball"); + element.style.top = top; + verticalBallStopped = true; +} + +function stopHorizontalBall() { + var element = document.getElementById('horizontal-direction-indicator'), + style = window.getComputedStyle(element), + left = style.getPropertyValue('left'); + x2 = parseInt(left.substring(0,3), 10); + x2 = (x2-60)/119; + console.log(x2); + // fix the position of the small ball to wherever it is + element.setAttribute("class", "small-ball"); + element.style.left = left; + horizontalBallStopped = true; +} + +function stopPowerBallAndKick() { + // get position of the small ball + var element = document.getElementById('power-level-indicator'), + style = window.getComputedStyle(element), + right = style.getPropertyValue('right'); + x3 = parseInt(right.substring(0,3), 10); + x3 = (191-x3)/121; + console.log(x3); + + // fix the position of the small ball to wherever it is + element.setAttribute("class", "small-ball"); + element.style.right = right; + powerBallStopped = true; + + // Calculate the ending position of the ball + var Et, El, Qt, Ql; + Et = 440 - ((0.8 + x1)/1.8)*x3*440 + 0.3*x3*((Math.abs(0.5-x2))/0.5)*440; + var stringEt = Et.toString(10); + El = 405 + x3*(x2-0.5)*810 + var stringEl = El.toString(10); + + // ending co-ordinates of the ball + endTop = Et; + endLeft = El; + + // let the player kick the ball now! + console.log(stringEl + " " + stringEt); + kick(stringEl, stringEt) +} + +function kickingProcess() { + if ((verticalBallStopped == false) && (horizontalBallStopped == false) && (powerBallStopped == false)) { + stopVerticalBall(); + } + else if ((verticalBallStopped == true) && (horizontalBallStopped == false) && (powerBallStopped == false)) { + stopHorizontalBall(); + } + else if ((verticalBallStopped == true) && (horizontalBallStopped == true) && (powerBallStopped == false)) { + stopPowerBallAndKick(); + } + else if ((verticalBallStopped == true) && (horizontalBallStopped == true) && (powerBallStopped == true)) { + if (chanceCount < 4) { + chanceCount += 1; + } + else { + chanceCount = 0; + score = 0; + document.getElementById('score-board').getElementsByTagName('li')[0].setAttribute('class', ''); + document.getElementById('score-board').getElementsByTagName('li')[1].setAttribute('class', ''); + document.getElementById('score-board').getElementsByTagName('li')[2].setAttribute('class', ''); + document.getElementById('score-board').getElementsByTagName('li')[3].setAttribute('class', ''); + document.getElementById('score-board').getElementsByTagName('li')[4].setAttribute('class', ''); + } + modalElem4.setAttribute("class","modal"); + modalElem5.setAttribute("class","modal"); + modalElem6.setAttribute('class','modal'); + modalElem7.setAttribute('class','modal'); + refreshScene(); + } +} + +function incrementScore() { + if ((chanceCount == 0)) { + document.getElementById('score-board').getElementsByTagName('li')[0].setAttribute('class', 'scored'); + score += 1; + } + else if ((chanceCount == 1)) { + document.getElementById('score-board').getElementsByTagName('li')[1].setAttribute('class', 'scored'); + score += 1; + } + else if ((chanceCount == 2)) { + document.getElementById('score-board').getElementsByTagName('li')[2].setAttribute('class', 'scored'); + score += 1; + } + else if ((chanceCount == 3)) { + document.getElementById('score-board').getElementsByTagName('li')[3].setAttribute('class', 'scored'); + score += 1; + } + else if ((chanceCount == 4)) { + document.getElementById('score-board').getElementsByTagName('li')[4].setAttribute('class', 'scored'); + score += 1; + } +} + +// ======================================================================================================= + +window.onclick = function() { + kickingProcess(); +} + +// all the modals to be displayed +modalElem1 = document.getElementById('modal-1'); +modalElem2 = document.getElementById('modal-2'); +modalElem3 = document.getElementById('modal-3'); +modalElem4 = document.getElementById('modal-4'); +modalElem5 = document.getElementById('modal-5'); +modalElem6 = document.getElementById('modal-6'); +modalElem7 = document.getElementById('modal-7'); diff --git a/Games/Penalty_Shootout_Game/js/plugins.js b/Games/Penalty_Shootout_Game/js/plugins.js new file mode 100644 index 0000000000..728680b08d --- /dev/null +++ b/Games/Penalty_Shootout_Game/js/plugins.js @@ -0,0 +1,24 @@ +// Avoid `console` errors in browsers that lack a console. +(function() { + var method; + var noop = function () {}; + var methods = [ + 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', + 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', + 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', + 'timeStamp', 'trace', 'warn' + ]; + var length = methods.length; + var console = (window.console = window.console || {}); + + while (length--) { + method = methods[length]; + + // Only stub undefined methods. + if (!console[method]) { + console[method] = noop; + } + } +}()); + +// Place any jQuery/helper plugins in here. diff --git a/Games/Penalty_Shootout_Game/js/vendor/jquery-1.11.0.min.js b/Games/Penalty_Shootout_Game/js/vendor/jquery-1.11.0.min.js new file mode 100644 index 0000000000..73f33fb3aa --- /dev/null +++ b/Games/Penalty_Shootout_Game/js/vendor/jquery-1.11.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="
a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("