diff --git a/Games/Alphabet-and-Vowels/README.md b/Games/Alphabet-and-Vowels/README.md new file mode 100644 index 0000000000..7e19c63d8d --- /dev/null +++ b/Games/Alphabet-and-Vowels/README.md @@ -0,0 +1,38 @@ +# **Alphabet and Vowel Game** + +--- + +
+ +## **Description 📃** + +- The Alphabet and Vowel Game is an interactive web-based game designed to help players identify vowels and consonants. This game is ideal for educational purposes, providing a fun way to enhance letter recognition and differentiate between vowels and consonants. It offers a seamless and enjoyable experience for players of all ages. + +## **Functionalities 🎮** + +- Displays a grid of alphabet letters. +- Prompts players to click on vowels first, followed by consonants. +- Provides immediate feedback on the correctness of the selected letter. +- Tracks player progress and updates instructions dynamically. +- Features a reset button to start a new game session. +- Boasts a modern, user-friendly interface for an engaging experience. + +
+ +## **How to play? 🕹️** + +1. Launch the Alphabet and Vowel Game in your browser. +2. Read the instructions to know whether to click on vowels or consonants. +3. Click on the letters displayed in the grid according to the instructions. +4. Receive instant feedback indicating if your choice was correct or incorrect. +5. Complete the first task (clicking all vowels), then move on to the next task (clicking all consonants). +6. Use the "Reset Game" button to restart the game at any time. + +
+ +## **Screenshots 📸** + +![image](https://github.com/kunjgit/GameZone/assets/97523900/03b0a814-d6f5-4aea-8ca9-7995947677e0) + + +
diff --git a/Games/Alphabet-and-Vowels/app.js b/Games/Alphabet-and-Vowels/app.js new file mode 100644 index 0000000000..4b7164453c --- /dev/null +++ b/Games/Alphabet-and-Vowels/app.js @@ -0,0 +1,56 @@ +const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); +const vowels = 'AEIOU'; +let score = 0; +let target = 'vowel'; + +document.addEventListener('DOMContentLoaded', () => { + const alphabetGrid = document.getElementById('alphabetGrid'); + const feedback = document.getElementById('feedback'); + const instruction = document.getElementById('instruction'); + const resetButton = document.getElementById('resetButton'); + + const shuffleArray = array => array.sort(() => Math.random() - 0.5); + + const generateButtons = () => { + shuffleArray(alphabet).forEach(letter => { + const button = document.createElement('button'); + button.textContent = letter; + button.addEventListener('click', () => checkLetter(letter, button)); + alphabetGrid.appendChild(button); + }); + }; + + const checkLetter = (letter, button) => { + if ((target === 'vowel' && vowels.includes(letter)) || + (target === 'consonant' && !vowels.includes(letter))) { + button.classList.add('correct'); + score++; + feedback.textContent = 'Correct!'; + } else { + button.classList.add('wrong'); + feedback.textContent = 'Try again!'; + } + + button.disabled = true; + + if (score === 5) { + target = 'consonant'; + instruction.textContent = 'Now click on all the consonants!'; + score = 0; + feedback.textContent = ''; + } + }; + + const resetGame = () => { + alphabetGrid.innerHTML = ''; + feedback.textContent = ''; + instruction.textContent = 'Click on all the vowels!'; + score = 0; + target = 'vowel'; + generateButtons(); + }; + + resetButton.addEventListener('click', resetGame); + + generateButtons(); +}); diff --git a/Games/Alphabet-and-Vowels/index.html b/Games/Alphabet-and-Vowels/index.html new file mode 100644 index 0000000000..c8867851b4 --- /dev/null +++ b/Games/Alphabet-and-Vowels/index.html @@ -0,0 +1,19 @@ + + + + + + Alphabet and Vowel Game + + + +
+

Alphabet and Vowel Game

+

Click on all the vowels!

+
+

+ +
+ + + diff --git a/Games/Alphabet-and-Vowels/style.css b/Games/Alphabet-and-Vowels/style.css new file mode 100644 index 0000000000..ae806620eb --- /dev/null +++ b/Games/Alphabet-and-Vowels/style.css @@ -0,0 +1,69 @@ +body { + font-family: 'Arial', sans-serif; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + background-color: #16d1e2; +} + +.container { + text-align: center; + background: #fff; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +h1 { + color: #333; +} + +.alphabet-grid { + display: grid; + grid-template-columns: repeat(6, 50px); + gap: 10px; + justify-content: center; + margin: 20px 0; +} + +.alphabet-grid button { + background-color: #008cba; + color: white; + border: none; + border-radius: 5px; + width: 50px; + height: 50px; + font-size: 18px; + cursor: pointer; + transition: background-color 0.3s; +} + +.alphabet-grid button.correct { + background-color: #4caf50; +} + +.alphabet-grid button.wrong { + background-color: #f44336; +} + +#feedback { + margin-top: 20px; + font-size: 20px; +} + +#resetButton { + background-color: #ff9800; + color: white; + border: none; + border-radius: 5px; + padding: 10px 20px; + font-size: 18px; + cursor: pointer; + transition: background-color 0.3s; +} + +#resetButton:hover { + background-color: #e68900; +} diff --git a/Games/Block_Ninja/README.md b/Games/Block_Ninja/README.md new file mode 100644 index 0000000000..cee18fdbb6 --- /dev/null +++ b/Games/Block_Ninja/README.md @@ -0,0 +1,59 @@ +# **Block Ninja** + +--- + +## **Description 📃** +Block Ninja is an engaging and addictive game where players must slash through blocks that appear on the screen while avoiding dangerous obstacles. The game tests your reflexes and precision as you aim to score the highest points by slicing through as many blocks as possible. The challenge increases with each level, making it an exciting experience for players of all ages. + +## **Functionalities 🎮** +- **Start Game:** Begin a new game session. +- **Slash Blocks:** Use swipe gestures or mouse movements to slash through blocks. +- **Avoid Obstacles:** Dodge dangerous obstacles to prevent losing points or ending the game. +- **Score Tracking:** Keep track of your highest scores and aim to beat them. +- **Multiple Levels:** Progress through various levels of increasing difficulty. +- **Sound Effects:** Enjoy immersive sound effects that enhance the gaming experience. +- **Pause/Resume:** Pause the game anytime and resume from where you left off. + +## **How to Play? 🕹️** +1. **Launch the Game:** + - Open the Block Ninja game application on your device. + +2. **Start a New Game:** + - Click on the "Start Game" button to begin. + +3. **Slash Blocks:** + - Use your finger (on touch screens) or mouse (on computers) to swipe across the screen. + - Slash through the blocks that appear to score points. + +4. **Avoid Obstacles:** + - Be cautious of obstacles that appear among the blocks. + - Avoid slashing through these obstacles as they can end the game or reduce your points. + +5. **Score Points:** + - Successfully slashing blocks will earn you points. + - Try to slash multiple blocks in one swipe for combo points. + +6. **Advance Through Levels:** + - As you score points, you'll advance through levels of increasing difficulty. + - Each level presents new challenges and faster-moving blocks. + +7. **Pause/Resume:** + - You can pause the game at any time by clicking the "Pause" button. + - Resume the game from the same point by clicking "Resume." + +8. **End of Game:** + - The game ends when you hit a dangerous obstacle or miss too many blocks. + - Your final score will be displayed, and you can choose to start a new game. + +--- + +Enjoy slicing through blocks and mastering the art of the Block Ninja! Can you achieve the highest score and become the ultimate ninja? + + +## **Screenshots 📸** + + +![image](../../assets/images/Block_Ninja.png) + +
+ diff --git a/Games/Block_Ninja/index.html b/Games/Block_Ninja/index.html new file mode 100644 index 0000000000..0c93eb7494 --- /dev/null +++ b/Games/Block_Ninja/index.html @@ -0,0 +1,48 @@ + + + + + + Document + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/Games/Block_Ninja/script.js b/Games/Block_Ninja/script.js new file mode 100644 index 0000000000..60fa9b177c --- /dev/null +++ b/Games/Block_Ninja/script.js @@ -0,0 +1,2185 @@ +// globalConfig.js +// ============================================================================ +// ============================================================================ + +// Provides global variables used by the entire program. +// Most of this should be configuration. + +// Timing multiplier for entire game engine. +let gameSpeed = 1; + +// Colors +const BLUE = { r: 0x67, g: 0xd7, b: 0xf0 }; +const GREEN = { r: 0xa6, g: 0xe0, b: 0x2c }; +const PINK = { r: 0xfa, g: 0x24, b: 0x73 }; +const ORANGE = { r: 0xfe, g: 0x95, b: 0x22 }; +const allColors = [BLUE, GREEN, PINK, ORANGE]; + +// Gameplay +const getSpawnDelay = () => { + const spawnDelayMax = 1400; + const spawnDelayMin = 550; + const spawnDelay = spawnDelayMax - state.game.cubeCount * 3.1; + return Math.max(spawnDelay, spawnDelayMin); +} +const doubleStrongEnableScore = 2000; +// Number of cubes that must be smashed before activating a feature. +const slowmoThreshold = 10; +const strongThreshold = 25; +const spinnerThreshold = 25; + +// Interaction state +let pointerIsDown = false; +// The last known position of the primary pointer in screen coordinates.` +let pointerScreen = { x: 0, y: 0 }; +// Same as `pointerScreen`, but converted to scene coordinates in rAF. +let pointerScene = { x: 0, y: 0 }; +// Minimum speed of pointer before "hits" are counted. +const minPointerSpeed = 50; +// The hit speed affects the direction the target post-hit. This number dampens that force. +const hitDampening = 0.1; +// Backboard receives shadows and is the farthest negative Z position of entities. +const backboardZ = -400; +const shadowColor = '#262e36'; +// How much air drag is applied to standard objects +const airDrag = 0.022; +const gravity = 0.3; +// Spark config +const sparkColor = 'rgba(170,221,255,.9)'; +const sparkThickness = 2.2; +const airDragSpark = 0.1; +// Track pointer positions to show trail +const touchTrailColor = 'rgba(170,221,255,.62)'; +const touchTrailThickness = 7; +const touchPointLife = 120; +const touchPoints = []; +// Size of in-game targets. This affects rendered size and hit area. +const targetRadius = 40; +const targetHitRadius = 50; +const makeTargetGlueColor = target => { + // const alpha = (target.health - 1) / (target.maxHealth - 1); + // return `rgba(170,221,255,${alpha.toFixed(3)})`; + return 'rgb(170,221,255)'; +}; +// Size of target fragments +const fragRadius = targetRadius / 3; + + + +// Game canvas element needed in setup.js and interaction.js +const canvas = document.querySelector('#c'); + +// 3D camera config +// Affects perspective +const cameraDistance = 900; +// Does not affect perspective +const sceneScale = 1; +// Objects that get too close to the camera will be faded out to transparent over this range. +// const cameraFadeStartZ = 0.8*cameraDistance - 6*targetRadius; +const cameraFadeStartZ = 0.45*cameraDistance; +const cameraFadeEndZ = 0.65*cameraDistance; +const cameraFadeRange = cameraFadeEndZ - cameraFadeStartZ; + +// Globals used to accumlate all vertices/polygons in each frame +const allVertices = []; +const allPolys = []; +const allShadowVertices = []; +const allShadowPolys = []; + + + + +// state.js +// ============================================================================ +// ============================================================================ + +/////////// +// Enums // +/////////// + +// Game Modes +const GAME_MODE_RANKED = Symbol('GAME_MODE_RANKED'); +const GAME_MODE_CASUAL = Symbol('GAME_MODE_CASUAL'); + +// Available Menus +const MENU_MAIN = Symbol('MENU_MAIN'); +const MENU_PAUSE = Symbol('MENU_PAUSE'); +const MENU_SCORE = Symbol('MENU_SCORE'); + + + +////////////////// +// Global State // +////////////////// + +const state = { + game: { + mode: GAME_MODE_RANKED, + // Run time of current game. + time: 0, + // Player score. + score: 0, + // Total number of cubes smashed in game. + cubeCount: 0 + }, + menus: { + // Set to `null` to hide all menus + active: MENU_MAIN + } +}; + + +//////////////////////////// +// Global State Selectors // +//////////////////////////// + +const isInGame = () => !state.menus.active; +const isMenuVisible = () => !!state.menus.active; +const isCasualGame = () => state.game.mode === GAME_MODE_CASUAL; +const isPaused = () => state.menus.active === MENU_PAUSE; + + +/////////////////// +// Local Storage // +/////////////////// + +const highScoreKey = '__menja__highScore'; +const getHighScore = () => { + const raw = localStorage.getItem(highScoreKey); + return raw ? parseInt(raw, 10) : 0; +}; + +let _lastHighscore = getHighScore(); +const setHighScore = score => { + _lastHighscore = getHighScore(); + localStorage.setItem(highScoreKey, String(score)); +}; + +const isNewHighScore = () => state.game.score > _lastHighscore; + + + + +// utils.js +// ============================================================================ +// ============================================================================ + + +const invariant = (condition, message) => { + if (!condition) throw new Error(message); +}; + + +///////// +// DOM // +///////// + +const $ = selector => document.querySelector(selector); +const handleClick = (element, handler) => element.addEventListener('click', handler); +const handlePointerDown = (element, handler) => { + element.addEventListener('touchstart', handler); + element.addEventListener('mousedown', handler); +}; + + + +//////////////////////// +// Formatting Helpers // +//////////////////////// + +// Converts a number into a formatted string with thousand separators. +const formatNumber = num => num.toLocaleString(); + + + +//////////////////// +// Math Constants // +//////////////////// + +const PI = Math.PI; +const TAU = Math.PI * 2; +const ETA = Math.PI * 0.5; + + + +////////////////// +// Math Helpers // +////////////////// + +// Clamps a number between min and max values (inclusive) +const clamp = (num, min, max) => Math.min(Math.max(num, min), max); + +// Linearly interpolate between numbers a and b by a specific amount. +// mix >= 0 && mix <= 1 +const lerp = (a, b, mix) => (b - a) * mix + a; + + + + +//////////////////// +// Random Helpers // +//////////////////// + +// Generates a random number between min (inclusive) and max (exclusive) +const random = (min, max) => Math.random() * (max - min) + min; + +// Generates a random integer between and possibly including min and max values +const randomInt = (min, max) => ((Math.random() * (max - min + 1)) | 0) + min; + +// Returns a random element from an array +const pickOne = arr => arr[Math.random() * arr.length | 0]; + + + + +/////////////////// +// Color Helpers // +/////////////////// + +// Converts an { r, g, b } color object to a 6-digit hex code. +const colorToHex = color => { + return '#' + + (color.r | 0).toString(16).padStart(2, '0') + + (color.g | 0).toString(16).padStart(2, '0') + + (color.b | 0).toString(16).padStart(2, '0'); +}; + +// Operates on an { r, g, b } color object. +// Returns string hex code. +// `lightness` must range from 0 to 1. 0 is pure black, 1 is pure white. +const shadeColor = (color, lightness) => { + let other, mix; + if (lightness < 0.5) { + other = 0; + mix = 1 - (lightness * 2); + } else { + other = 255; + mix = lightness * 2 - 1; + } + return '#' + + (lerp(color.r, other, mix) | 0).toString(16).padStart(2, '0') + + (lerp(color.g, other, mix) | 0).toString(16).padStart(2, '0') + + (lerp(color.b, other, mix) | 0).toString(16).padStart(2, '0'); +}; + + + + + +//////////////////// +// Timing Helpers // +//////////////////// + +const _allCooldowns = []; + +const makeCooldown = (rechargeTime, units=1) => { + let timeRemaining = 0; + let lastTime = 0; + + const initialOptions = { rechargeTime, units }; + + const updateTime = () => { + const now = state.game.time; + // Reset time remaining if time goes backwards. + if (now < lastTime) { + timeRemaining = 0; + } else { + // update... + timeRemaining -= now-lastTime; + if (timeRemaining < 0) timeRemaining = 0; + } + lastTime = now; + }; + + const canUse = () => { + updateTime(); + return timeRemaining <= (rechargeTime * (units-1)); + }; + + const cooldown = { + canUse, + useIfAble() { + const usable = canUse(); + if (usable) timeRemaining += rechargeTime; + return usable; + }, + mutate(options) { + if (options.rechargeTime) { + // Apply recharge time delta so change takes effect immediately. + timeRemaining -= rechargeTime-options.rechargeTime; + if (timeRemaining < 0) timeRemaining = 0; + rechargeTime = options.rechargeTime; + } + if (options.units) units = options.units; + }, + reset() { + timeRemaining = 0; + lastTime = 0; + this.mutate(initialOptions); + } + }; + + _allCooldowns.push(cooldown); + + return cooldown; +}; + +const resetAllCooldowns = () => _allCooldowns.forEach(cooldown => cooldown.reset()); + +const makeSpawner = ({ chance, cooldownPerSpawn, maxSpawns }) => { + const cooldown = makeCooldown(cooldownPerSpawn, maxSpawns); + return { + shouldSpawn() { + return Math.random() <= chance && cooldown.useIfAble(); + }, + mutate(options) { + if (options.chance) chance = options.chance; + cooldown.mutate({ + rechargeTime: options.cooldownPerSpawn, + units: options.maxSpawns + }); + } + }; +}; + + + + +//////////////////// +// Vector Helpers // +//////////////////// + +const normalize = v => { + const mag = Math.hypot(v.x, v.y, v.z); + return { + x: v.x / mag, + y: v.y / mag, + z: v.z / mag + }; +} + +// Curried math helpers +const add = a => b => a + b; +// Curried vector helpers +const scaleVector = scale => vector => { + vector.x *= scale; + vector.y *= scale; + vector.z *= scale; +}; + + + + + + + + +//////////////// +// 3D Helpers // +//////////////// + +// Clone array and all vertices. +function cloneVertices(vertices) { + return vertices.map(v => ({ x: v.x, y: v.y, z: v.z })); +} + +// Copy vertex data from one array into another. +// Arrays must be the same length. +function copyVerticesTo(arr1, arr2) { + const len = arr1.length; + for (let i=0; i { + const targetVertex = target[i]; + // X axis rotation + const x1 = v.x; + const y1 = v.z*sinX + v.y*cosX; + const z1 = v.z*cosX - v.y*sinX; + // Y axis rotation + const x2 = x1*cosY - z1*sinY; + const y2 = y1; + const z2 = x1*sinY + z1*cosY; + // Z axis rotation + const x3 = x2*cosZ - y2*sinZ; + const y3 = x2*sinZ + y2*cosZ; + const z3 = z2; + + // Scale, Translate, and set the transform. + targetVertex.x = x3 * sX + tX; + targetVertex.y = y3 * sY + tY; + targetVertex.z = z3 * sZ + tZ; + }); +} + +// 3D projection on a single vertex. +// Directly mutates the vertex. +const projectVertex = v => { + const focalLength = cameraDistance * sceneScale; + const depth = focalLength / (cameraDistance - v.z); + v.x = v.x * depth; + v.y = v.y * depth; +}; + +// 3D projection on a single vertex. +// Mutates a secondary target vertex. +const projectVertexTo = (v, target) => { + const focalLength = cameraDistance * sceneScale; + const depth = focalLength / (cameraDistance - v.z); + target.x = v.x * depth; + target.y = v.y * depth; +}; + + + + + +// PERF.js +// ============================================================================ +// ============================================================================ + +// Dummy no-op functions. +// I use these in a special build for custom performance profiling. +const PERF_START = () => {}; +const PERF_END = () => {}; +const PERF_UPDATE = () => {}; + + + + +// 3dModels.js +// ============================================================================ +// ============================================================================ + +// Define models once. The origin is the center of the model. + +// A simple cube, 8 vertices, 6 quads. +// Defaults to an edge length of 2 units, can be influenced with `scale`. +function makeCubeModel({ scale=1 }) { + return { + vertices: [ + // top + { x: -scale, y: -scale, z: scale }, + { x: scale, y: -scale, z: scale }, + { x: scale, y: scale, z: scale }, + { x: -scale, y: scale, z: scale }, + // bottom + { x: -scale, y: -scale, z: -scale }, + { x: scale, y: -scale, z: -scale }, + { x: scale, y: scale, z: -scale }, + { x: -scale, y: scale, z: -scale } + ], + polys: [ + // z = 1 + { vIndexes: [0, 1, 2, 3] }, + // z = -1 + { vIndexes: [7, 6, 5, 4] }, + // y = 1 + { vIndexes: [3, 2, 6, 7] }, + // y = -1 + { vIndexes: [4, 5, 1, 0] }, + // x = 1 + { vIndexes: [5, 6, 2, 1] }, + // x = -1 + { vIndexes: [0, 3, 7, 4] } + ] + }; +} + +// Not very optimized - lots of duplicate vertices are generated. +function makeRecursiveCubeModel({ recursionLevel, splitFn, color, scale=1 }) { + const getScaleAtLevel = level => 1 / (3 ** level); + + // We can model level 0 manually. It's just a single, centered, cube. + let cubeOrigins = [{ x: 0, y: 0, z: 0 }]; + + // Recursively replace cubes with smaller cubes. + for (let i=1; i<=recursionLevel; i++) { + const scale = getScaleAtLevel(i) * 2; + const cubeOrigins2 = []; + cubeOrigins.forEach(origin => { + cubeOrigins2.push(...splitFn(origin, scale)); + }); + cubeOrigins = cubeOrigins2; + } + + const finalModel = { vertices: [], polys: [] }; + + // Generate single cube model and scale it. + const cubeModel = makeCubeModel({ scale: 1 }); + cubeModel.vertices.forEach(scaleVector(getScaleAtLevel(recursionLevel))); + + // Compute the max distance x, y, or z origin values will be. + // Same result as `Math.max(...cubeOrigins.map(o => o.x))`, but much faster. + const maxComponent = getScaleAtLevel(recursionLevel) * (3 ** recursionLevel - 1); + + // Place cube geometry at each origin. + cubeOrigins.forEach((origin, cubeIndex) => { + // To compute occlusion (shading), find origin component with greatest + // magnitude and normalize it relative to `maxComponent`. + const occlusion = Math.max( + Math.abs(origin.x), + Math.abs(origin.y), + Math.abs(origin.z) + ) / maxComponent; + // At lower iterations, occlusion looks better lightened up a bit. + const occlusionLighter = recursionLevel > 2 + ? occlusion + : (occlusion + 0.8) / 1.8; + // Clone, translate vertices to origin, and apply scale + finalModel.vertices.push( + ...cubeModel.vertices.map(v => ({ + x: (v.x + origin.x) * scale, + y: (v.y + origin.y) * scale, + z: (v.z + origin.z) * scale + })) + ); + // Clone polys, shift referenced vertex indexes, and compute color. + finalModel.polys.push( + ...cubeModel.polys.map(poly => ({ + vIndexes: poly.vIndexes.map(add(cubeIndex * 8)) + })) + ); + }); + + return finalModel; +} + + +// o: Vector3D - Position of cube's origin (center). +// s: Vector3D - Determines size of menger sponge. +function mengerSpongeSplit(o, s) { + return [ + // Top + { x: o.x + s, y: o.y - s, z: o.z + s }, + { x: o.x + s, y: o.y - s, z: o.z + 0 }, + { x: o.x + s, y: o.y - s, z: o.z - s }, + { x: o.x + 0, y: o.y - s, z: o.z + s }, + { x: o.x + 0, y: o.y - s, z: o.z - s }, + { x: o.x - s, y: o.y - s, z: o.z + s }, + { x: o.x - s, y: o.y - s, z: o.z + 0 }, + { x: o.x - s, y: o.y - s, z: o.z - s }, + // Bottom + { x: o.x + s, y: o.y + s, z: o.z + s }, + { x: o.x + s, y: o.y + s, z: o.z + 0 }, + { x: o.x + s, y: o.y + s, z: o.z - s }, + { x: o.x + 0, y: o.y + s, z: o.z + s }, + { x: o.x + 0, y: o.y + s, z: o.z - s }, + { x: o.x - s, y: o.y + s, z: o.z + s }, + { x: o.x - s, y: o.y + s, z: o.z + 0 }, + { x: o.x - s, y: o.y + s, z: o.z - s }, + // Middle + { x: o.x + s, y: o.y + 0, z: o.z + s }, + { x: o.x + s, y: o.y + 0, z: o.z - s }, + { x: o.x - s, y: o.y + 0, z: o.z + s }, + { x: o.x - s, y: o.y + 0, z: o.z - s } + ]; +} + + + +// Helper to optimize models by merging duplicate vertices within a threshold, +// and removing all polys that share the same vertices. +// Directly mutates the model. +function optimizeModel(model, threshold=0.0001) { + const { vertices, polys } = model; + + const compareVertices = (v1, v2) => ( + Math.abs(v1.x - v2.x) < threshold && + Math.abs(v1.y - v2.y) < threshold && + Math.abs(v1.z - v2.z) < threshold + ); + + const comparePolys = (p1, p2) => { + const v1 = p1.vIndexes; + const v2 = p2.vIndexes; + return ( + ( + v1[0] === v2[0] || + v1[0] === v2[1] || + v1[0] === v2[2] || + v1[0] === v2[3] + ) && ( + v1[1] === v2[0] || + v1[1] === v2[1] || + v1[1] === v2[2] || + v1[1] === v2[3] + ) && ( + v1[2] === v2[0] || + v1[2] === v2[1] || + v1[2] === v2[2] || + v1[2] === v2[3] + ) && ( + v1[3] === v2[0] || + v1[3] === v2[1] || + v1[3] === v2[2] || + v1[3] === v2[3] + ) + ); + }; + + + vertices.forEach((v, i) => { + v.originalIndexes = [i]; + }); + + for (let i=vertices.length-1; i>=0; i--) { + for (let ii=i-1; ii>=0; ii--) { + const v1 = vertices[i]; + const v2 = vertices[ii]; + if (compareVertices(v1, v2)) { + vertices.splice(i, 1); + v2.originalIndexes.push(...v1.originalIndexes); + break; + } + } + } + + vertices.forEach((v, i) => { + polys.forEach(p => { + p.vIndexes.forEach((vi, ii, arr) => { + const vo = v.originalIndexes; + if (vo.includes(vi)) { + arr[ii] = i; + } + }); + }); + }); + + polys.forEach(p => { + const vi = p.vIndexes; + p.sum = vi[0] + vi[1] + vi[2] + vi[3]; + }); + polys.sort((a, b) => b.sum - a.sum); + + // Assumptions: + // 1. Each poly will either have no duplicates or 1 duplicate. + // 2. If two polys are equal, they are both hidden (two cubes touching), + // therefore both can be removed. + for (let i=polys.length-1; i>=0; i--) { + for (let ii=i-1; ii>=0; ii--) { + const p1 = polys[i]; + const p2 = polys[ii]; + if (p1.sum !== p2.sum) break; + if (comparePolys(p1, p2)) { + polys.splice(i, 1); + polys.splice(ii, 1); + i--; + break; + } + } + } + + return model; +} + + + + + +// Entity.js +// ============================================================================ +// ============================================================================ + +class Entity { + constructor({ model, color, wireframe=false }) { + const vertices = cloneVertices(model.vertices); + const shadowVertices = cloneVertices(model.vertices); + const colorHex = colorToHex(color); + const darkColorHex = shadeColor(color, 0.4); + + const polys = model.polys.map(p => ({ + vertices: p.vIndexes.map(vIndex => vertices[vIndex]), + color: color, // custom rgb color object + wireframe: wireframe, + strokeWidth: wireframe ? 2 : 0, // Set to non-zero value to draw stroke + strokeColor: colorHex, // must be a CSS color string + strokeColorDark: darkColorHex, // must be a CSS color string + depth: 0, + middle: { x: 0, y: 0, z: 0 }, + normalWorld: { x: 0, y: 0, z: 0 }, + normalCamera: { x: 0, y: 0, z: 0 } + })); + + const shadowPolys = model.polys.map(p => ({ + vertices: p.vIndexes.map(vIndex => shadowVertices[vIndex]), + wireframe: wireframe, + normalWorld: { x: 0, y: 0, z: 0 } + })); + + this.projected = {}; // Will store 2D projected data + this.model = model; + this.vertices = vertices; + this.polys = polys; + this.shadowVertices = shadowVertices; + this.shadowPolys = shadowPolys; + this.reset(); + } + + // Better names: resetEntity, resetTransform, resetEntityTransform + reset() { + this.x = 0; + this.y = 0; + this.z = 0; + this.xD = 0; + this.yD = 0; + this.zD = 0; + + this.rotateX = 0; + this.rotateY = 0; + this.rotateZ = 0; + this.rotateXD = 0; + this.rotateYD = 0; + this.rotateZD = 0; + + this.scaleX = 1; + this.scaleY = 1; + this.scaleZ = 1; + + this.projected.x = 0; + this.projected.y = 0; + } + + transform() { + transformVertices( + this.model.vertices, + this.vertices, + this.x, + this.y, + this.z, + this.rotateX, + this.rotateY, + this.rotateZ, + this.scaleX, + this.scaleY, + this.scaleZ + ); + + copyVerticesTo(this.vertices, this.shadowVertices); + } + + // Projects origin point, stored as `projected` property. + project() { + projectVertexTo(this, this.projected); + } +} + + + + + +// getTarget.js +// ============================================================================ +// ============================================================================ + +// All active targets +const targets = []; + +// Pool target instances by color, using a Map. +// keys are color objects, and values are arrays of targets. +// Also pool wireframe instances separately. +const targetPool = new Map(allColors.map(c=>([c, []]))); +const targetWireframePool = new Map(allColors.map(c=>([c, []]))); + + + +const getTarget = (() => { + + const slowmoSpawner = makeSpawner({ + chance: 0.5, + cooldownPerSpawn: 10000, + maxSpawns: 1 + }); + + let doubleStrong = false; + const strongSpawner = makeSpawner({ + chance: 0.3, + cooldownPerSpawn: 12000, + maxSpawns: 1 + }); + + const spinnerSpawner = makeSpawner({ + chance: 0.1, + cooldownPerSpawn: 10000, + maxSpawns: 1 + }); + + // Cached array instances, no need to allocate every time. + const axisOptions = [ + ['x', 'y'], + ['y', 'z'], + ['z', 'x'] + ]; + + function getTargetOfStyle(color, wireframe) { + const pool = wireframe ? targetWireframePool : targetPool; + let target = pool.get(color).pop(); + if (!target) { + target = new Entity({ + model: optimizeModel(makeRecursiveCubeModel({ + recursionLevel: 1, + splitFn: mengerSpongeSplit, + scale: targetRadius + })), + color: color, + wireframe: wireframe + }); + + // Init any properties that will be used. + // These will not be automatically reset when recycled. + target.color = color; + target.wireframe = wireframe; + // Some properties don't have their final value yet. + // Initialize with any value of the right type. + target.hit = false; + target.maxHealth = 0; + target.health = 0; + } + return target; + } + + return function getTarget() { + if (doubleStrong && state.game.score <= doubleStrongEnableScore) { + doubleStrong = false; + // Spawner is reset automatically when game resets. + } else if (!doubleStrong && state.game.score > doubleStrongEnableScore) { + doubleStrong = true; + strongSpawner.mutate({ maxSpawns: 2 }); + } + + // Target Parameters + // -------------------------------- + let color = pickOne([BLUE, GREEN, ORANGE]); + let wireframe = false; + let health = 1; + let maxHealth = 3; + const spinner = state.game.cubeCount >= spinnerThreshold && isInGame() && spinnerSpawner.shouldSpawn(); + + // Target Parameter Overrides + // -------------------------------- + if (state.game.cubeCount >= slowmoThreshold && slowmoSpawner.shouldSpawn()) { + color = BLUE; + wireframe = true; + } + else if (state.game.cubeCount >= strongThreshold && strongSpawner.shouldSpawn()) { + color = PINK; + health = 3; + } + + // Target Creation + // -------------------------------- + const target = getTargetOfStyle(color, wireframe); + target.hit = false; + target.maxHealth = maxHealth; + target.health = health; + updateTargetHealth(target, 0); + + const spinSpeeds = [ + Math.random() * 0.1 - 0.05, + Math.random() * 0.1 - 0.05 + ]; + + if (spinner) { + // Ends up spinning a random axis + spinSpeeds[0] = -0.25; + spinSpeeds[1] = 0; + target.rotateZ = random(0, TAU); + } + + const axes = pickOne(axisOptions); + + spinSpeeds.forEach((spinSpeed, i) => { + switch (axes[i]) { + case 'x': + target.rotateXD = spinSpeed; + break; + case 'y': + target.rotateYD = spinSpeed; + break; + case 'z': + target.rotateZD = spinSpeed; + break; + } + }); + + return target; + } +})(); + + +const updateTargetHealth = (target, healthDelta) => { + target.health += healthDelta; + // Only update stroke on non-wireframe targets. + // Showing "glue" is a temporary attempt to display health. For now, there's + // no reason to have wireframe targets with high health, so we're fine. + if (!target.wireframe) { + const strokeWidth = target.health - 1; + const strokeColor = makeTargetGlueColor(target); + for (let p of target.polys) { + p.strokeWidth = strokeWidth; + p.strokeColor = strokeColor; + } + } +}; + + +const returnTarget = target => { + target.reset(); + const pool = target.wireframe ? targetWireframePool : targetPool; + pool.get(target.color).push(target); +}; + + +function resetAllTargets() { + while(targets.length) { + returnTarget(targets.pop()); + } +} + + + + + +// createBurst.js +// ============================================================================ +// ============================================================================ + +// Track all active fragments +const frags = []; +// Pool inactive fragments by color, using a Map. +// keys are color objects, and values are arrays of fragments. +// // Also pool wireframe instances separately. +const fragPool = new Map(allColors.map(c=>([c, []]))); +const fragWireframePool = new Map(allColors.map(c=>([c, []]))); + + +const createBurst = (() => { + // Precompute some private data to be reused for all bursts. + const basePositions = mengerSpongeSplit({ x:0, y:0, z:0 }, fragRadius*2); + const positions = cloneVertices(basePositions); + const prevPositions = cloneVertices(basePositions); + const velocities = cloneVertices(basePositions); + + const basePositionNormals = basePositions.map(normalize); + const positionNormals = cloneVertices(basePositionNormals); + + + const fragCount = basePositions.length; + + function getFragForTarget(target) { + const pool = target.wireframe ? fragWireframePool : fragPool; + let frag = pool.get(target.color).pop(); + if (!frag) { + frag = new Entity({ + model: makeCubeModel({ scale: fragRadius }), + color: target.color, + wireframe: target.wireframe + }); + frag.color = target.color; + frag.wireframe = target.wireframe; + } + return frag; + } + + return (target, force=1) => { + // Calculate fragment positions, and what would have been the previous positions + // when still a part of the larger target. + transformVertices( + basePositions, positions, + target.x, target.y, target.z, + target.rotateX, target.rotateY, target.rotateZ, + 1, 1, 1 + ); + transformVertices( + basePositions, prevPositions, + target.x - target.xD, target.y - target.yD, target.z - target.zD, + target.rotateX - target.rotateXD, target.rotateY - target.rotateYD, target.rotateZ - target.rotateZD, + 1, 1, 1 + ); + + // Compute velocity of each fragment, based on previous positions. + // Will write to `velocities` array. + for (let i=0; i { + frag.reset(); + const pool = frag.wireframe ? fragWireframePool : fragPool; + pool.get(frag.color).push(frag); +}; + + + + + +// sparks.js +// ============================================================================ +// ============================================================================ + +const sparks = []; +const sparkPool = []; + + +function addSpark(x, y, xD, yD) { + const spark = sparkPool.pop() || {}; + + spark.x = x + xD * 0.5; + spark.y = y + yD * 0.5; + spark.xD = xD; + spark.yD = yD; + spark.life = random(200, 300); + spark.maxLife = spark.life; + + sparks.push(spark); + + return spark; +} + + +// Spherical spark burst +function sparkBurst(x, y, count, maxSpeed) { + const angleInc = TAU / count; + for (let i=0; i { + if (Math.random() < 0.4) { + projectVertex(v); + addSpark( + v.x, + v.y, + random(-12, 12), + random(-12, 12) + ); + } + }); +} + +function returnSpark(spark) { + sparkPool.push(spark); +} + + + + + +// hud.js +// ============================================================================ +// ============================================================================ + +const hudContainerNode = $('.hud'); + +function setHudVisibility(visible) { + if (visible) { + hudContainerNode.style.display = 'block'; + } else { + hudContainerNode.style.display = 'none'; + } +} + + +/////////// +// Score // +/////////// +const scoreNode = $('.score-lbl'); +const cubeCountNode = $('.cube-count-lbl'); + +function renderScoreHud() { + if (isCasualGame()) { + scoreNode.style.display = 'none'; + cubeCountNode.style.opacity = 1; + } else { + scoreNode.innerText = `SCORE: ${state.game.score}`; + scoreNode.style.display = 'block'; + cubeCountNode.style.opacity = 0.65 ; + } + cubeCountNode.innerText = `CUBES SMASHED: ${state.game.cubeCount}`; +} + +renderScoreHud(); + + +////////////////// +// Pause Button // +////////////////// + +handlePointerDown($('.pause-btn'), () => pauseGame()); + + +//////////////////// +// Slow-Mo Status // +//////////////////// + +const slowmoNode = $('.slowmo'); +const slowmoBarNode = $('.slowmo__bar'); + +function renderSlowmoStatus(percentRemaining) { + slowmoNode.style.opacity = percentRemaining === 0 ? 0 : 1; + slowmoBarNode.style.transform = `scaleX(${percentRemaining.toFixed(3)})`; +} + + + + + +// menus.js +// ============================================================================ +// ============================================================================ + +// Top-level menu containers +const menuContainerNode = $('.menus'); +const menuMainNode = $('.menu--main'); +const menuPauseNode = $('.menu--pause'); +const menuScoreNode = $('.menu--score'); + +const finalScoreLblNode = $('.final-score-lbl'); +const highScoreLblNode = $('.high-score-lbl'); + + + +function showMenu(node) { + node.classList.add('active'); +} + +function hideMenu(node) { + node.classList.remove('active'); +} + +function renderMenus() { + hideMenu(menuMainNode); + hideMenu(menuPauseNode); + hideMenu(menuScoreNode); + + switch (state.menus.active) { + case MENU_MAIN: + showMenu(menuMainNode); + break; + case MENU_PAUSE: + showMenu(menuPauseNode); + break; + case MENU_SCORE: + finalScoreLblNode.textContent = formatNumber(state.game.score); + if (isNewHighScore()) { + highScoreLblNode.textContent = 'New High Score!'; + } else { + highScoreLblNode.textContent = `High Score: ${formatNumber(getHighScore())}`; + } + showMenu(menuScoreNode); + break; + } + + setHudVisibility(!isMenuVisible()); + menuContainerNode.classList.toggle('has-active', isMenuVisible()); + menuContainerNode.classList.toggle('interactive-mode', isMenuVisible() && pointerIsDown); +} + +renderMenus(); + + + +//////////////////// +// Button Actions // +//////////////////// + +// Main Menu +handleClick($('.play-normal-btn'), () => { + setGameMode(GAME_MODE_RANKED); + setActiveMenu(null); + resetGame(); +}); + +handleClick($('.play-casual-btn'), () => { + setGameMode(GAME_MODE_CASUAL); + setActiveMenu(null); + resetGame(); +}); + +// Pause Menu +handleClick($('.resume-btn'), () => resumeGame()); +handleClick($('.menu-btn--pause'), () => setActiveMenu(MENU_MAIN)); + +// Score Menu +handleClick($('.play-again-btn'), () => { + setActiveMenu(null); + resetGame(); +}); + +handleClick($('.menu-btn--score'), () => setActiveMenu(MENU_MAIN)); + + + + +//////////////////// +// Button Actions // +//////////////////// + +// Main Menu +handleClick($('.play-normal-btn'), () => { + setGameMode(GAME_MODE_RANKED); + setActiveMenu(null); + resetGame(); +}); + +handleClick($('.play-casual-btn'), () => { + setGameMode(GAME_MODE_CASUAL); + setActiveMenu(null); + resetGame(); +}); + +// Pause Menu +handleClick($('.resume-btn'), () => resumeGame()); +handleClick($('.menu-btn--pause'), () => setActiveMenu(MENU_MAIN)); + +// Score Menu +handleClick($('.play-again-btn'), () => { + setActiveMenu(null); + resetGame(); +}); + +handleClick($('.menu-btn--score'), () => setActiveMenu(MENU_MAIN)); + + + + + +// actions.js +// ============================================================================ +// ============================================================================ + +////////////////// +// MENU ACTIONS // +////////////////// + +function setActiveMenu(menu) { + state.menus.active = menu; + renderMenus(); +} + + +///////////////// +// HUD ACTIONS // +///////////////// + +function setScore(score) { + state.game.score = score; + renderScoreHud(); +} + +function incrementScore(inc) { + if (isInGame()) { + state.game.score += inc; + if (state.game.score < 0) { + state.game.score = 0; + } + renderScoreHud(); + } +} + +function setCubeCount(count) { + state.game.cubeCount = count; + renderScoreHud(); +} + +function incrementCubeCount(inc) { + if (isInGame()) { + state.game.cubeCount += inc; + renderScoreHud(); + } +} + + +////////////////// +// GAME ACTIONS // +////////////////// + +function setGameMode(mode) { + state.game.mode = mode; +} + +function resetGame() { + resetAllTargets(); + state.game.time = 0; + resetAllCooldowns(); + setScore(0); + setCubeCount(0); + spawnTime = getSpawnDelay(); +} + +function pauseGame() { + isInGame() && setActiveMenu(MENU_PAUSE); +} + +function resumeGame() { + isPaused() && setActiveMenu(null); +} + +function endGame() { + handleCanvasPointerUp(); + if (isNewHighScore()) { + setHighScore(state.game.score); + } + setActiveMenu(MENU_SCORE); +} + + + +//////////////////////// +// KEYBOARD SHORTCUTS // +//////////////////////// + +window.addEventListener('keydown', event => { + if (event.key === 'p') { + isPaused() ? resumeGame() : pauseGame(); + } +}); + + + + + + +// tick.js +// ============================================================================ +// ============================================================================ + + +let spawnTime = 0; +const maxSpawnX = 450; +const pointerDelta = { x: 0, y: 0 }; +const pointerDeltaScaled = { x: 0, y: 0 }; + +// Temp slowmo state. Should be relocated once this stabilizes. +const slowmoDuration = 1500; +let slowmoRemaining = 0; +let spawnExtra = 0; +const spawnExtraDelay = 300; +let targetSpeed = 1; + + +function tick(width, height, simTime, simSpeed, lag) { + PERF_START('frame'); + PERF_START('tick'); + + state.game.time += simTime; + + if (slowmoRemaining > 0) { + slowmoRemaining -= simTime; + if (slowmoRemaining < 0) { + slowmoRemaining = 0; + } + targetSpeed = pointerIsDown ? 0.075 : 0.3; + } else { + const menuPointerDown = isMenuVisible() && pointerIsDown; + targetSpeed = menuPointerDown ? 0.025 : 1; + } + + renderSlowmoStatus(slowmoRemaining / slowmoDuration); + + gameSpeed += (targetSpeed - gameSpeed) / 22 * lag; + gameSpeed = clamp(gameSpeed, 0, 1); + + const centerX = width / 2; + const centerY = height / 2; + + const simAirDrag = 1 - (airDrag * simSpeed); + const simAirDragSpark = 1 - (airDragSpark * simSpeed); + + // Pointer Tracking + // ------------------- + + // Compute speed and x/y deltas. + // There is also a "scaled" variant taking game speed into account. This serves two purposes: + // - Lag won't create large spikes in speed/deltas + // - In slow mo, speed is increased proportionately to match "reality". Without this boost, + // it feels like your actions are dampened in slow mo. + const forceMultiplier = 1 / (simSpeed * 0.75 + 0.25); + pointerDelta.x = 0; + pointerDelta.y = 0; + pointerDeltaScaled.x = 0; + pointerDeltaScaled.y = 0; + const lastPointer = touchPoints[touchPoints.length - 1]; + + if (pointerIsDown && lastPointer && !lastPointer.touchBreak) { + pointerDelta.x = (pointerScene.x - lastPointer.x); + pointerDelta.y = (pointerScene.y - lastPointer.y); + pointerDeltaScaled.x = pointerDelta.x * forceMultiplier; + pointerDeltaScaled.y = pointerDelta.y * forceMultiplier; + } + const pointerSpeed = Math.hypot(pointerDelta.x, pointerDelta.y); + const pointerSpeedScaled = pointerSpeed * forceMultiplier; + + // Track points for later calculations, including drawing trail. + touchPoints.forEach(p => p.life -= simTime); + + if (pointerIsDown) { + touchPoints.push({ + x: pointerScene.x, + y: pointerScene.y, + life: touchPointLife + }); + } + + while (touchPoints[0] && touchPoints[0].life <= 0) { + touchPoints.shift(); + } + + + // Entity Manipulation + // -------------------- + PERF_START('entities'); + + // Spawn targets + spawnTime -= simTime; + if (spawnTime <= 0) { + if (spawnExtra > 0) { + spawnExtra--; + spawnTime = spawnExtraDelay; + } else { + spawnTime = getSpawnDelay(); + } + const target = getTarget(); + const spawnRadius = Math.min(centerX * 0.8, maxSpawnX); + target.x = (Math.random() * spawnRadius * 2 - spawnRadius); + target.y = centerY + targetHitRadius * 2; + target.z = (Math.random() * targetRadius*2 - targetRadius); + target.xD = Math.random() * (target.x * -2 / 120); + target.yD = -20; + targets.push(target); + } + + // Animate targets and remove when offscreen + const leftBound = -centerX + targetRadius; + const rightBound = centerX - targetRadius; + const ceiling = -centerY - 120; + const boundDamping = 0.4; + + targetLoop: + for (let i = targets.length - 1; i >= 0; i--) { + const target = targets[i]; + target.x += target.xD * simSpeed; + target.y += target.yD * simSpeed; + + if (target.y < ceiling) { + target.y = ceiling; + target.yD = 0; + } + + if (target.x < leftBound) { + target.x = leftBound; + target.xD *= -boundDamping; + } else if (target.x > rightBound) { + target.x = rightBound; + target.xD *= -boundDamping; + } + + if (target.z < backboardZ) { + target.z = backboardZ; + target.zD *= -boundDamping; + } + + target.yD += gravity * simSpeed; + target.rotateX += target.rotateXD * simSpeed; + target.rotateY += target.rotateYD * simSpeed; + target.rotateZ += target.rotateZD * simSpeed; + target.transform(); + target.project(); + + // Remove if offscreen + if (target.y > centerY + targetHitRadius * 2) { + targets.splice(i, 1); + returnTarget(target); + if (isInGame()) { + if (isCasualGame()) { + incrementScore(-25); + } else { + endGame(); + } + } + continue; + } + + + // If pointer is moving really fast, we want to hittest multiple points along the path. + // We can't use scaled pointer speed to determine this, since we care about actual screen + // distance covered. + const hitTestCount = Math.ceil(pointerSpeed / targetRadius * 2); + // Start loop at `1` and use `<=` check, so we skip 0% and end up at 100%. + // This omits the previous point position, and includes the most recent. + for (let ii=1; ii<=hitTestCount; ii++) { + const percent = 1 - (ii / hitTestCount); + const hitX = pointerScene.x - pointerDelta.x * percent; + const hitY = pointerScene.y - pointerDelta.y * percent; + const distance = Math.hypot( + hitX - target.projected.x, + hitY - target.projected.y + ); + + if (distance <= targetHitRadius) { + // Hit! (though we don't want to allow hits on multiple sequential frames) + if (!target.hit) { + target.hit = true; + + target.xD += pointerDeltaScaled.x * hitDampening; + target.yD += pointerDeltaScaled.y * hitDampening; + target.rotateXD += pointerDeltaScaled.y * 0.001; + target.rotateYD += pointerDeltaScaled.x * 0.001; + + const sparkSpeed = 7 + pointerSpeedScaled * 0.125; + + if (pointerSpeedScaled > minPointerSpeed) { + target.health--; + incrementScore(10); + + if (target.health <= 0) { + incrementCubeCount(1); + createBurst(target, forceMultiplier); + sparkBurst(hitX, hitY, 8, sparkSpeed); + if (target.wireframe) { + slowmoRemaining = slowmoDuration; + spawnTime = 0; + spawnExtra = 2; + } + targets.splice(i, 1); + returnTarget(target); + } else { + sparkBurst(hitX, hitY, 8, sparkSpeed); + glueShedSparks(target); + updateTargetHealth(target, 0); + } + } else { + incrementScore(5); + sparkBurst(hitX, hitY, 3, sparkSpeed); + } + } + // Break the current loop and continue the outer loop. + // This skips to processing the next target. + continue targetLoop; + } + } + + // This code will only run if target hasn't been "hit". + target.hit = false; + } + + // Animate fragments and remove when offscreen. + const fragBackboardZ = backboardZ + fragRadius; + // Allow fragments to move off-screen to sides for a while, since shadows are still visible. + const fragLeftBound = -width; + const fragRightBound = width; + + for (let i = frags.length - 1; i >= 0; i--) { + const frag = frags[i]; + frag.x += frag.xD * simSpeed; + frag.y += frag.yD * simSpeed; + frag.z += frag.zD * simSpeed; + + frag.xD *= simAirDrag; + frag.yD *= simAirDrag; + frag.zD *= simAirDrag; + + if (frag.y < ceiling) { + frag.y = ceiling; + frag.yD = 0; + } + + if (frag.z < fragBackboardZ) { + frag.z = fragBackboardZ; + frag.zD *= -boundDamping; + } + + frag.yD += gravity * simSpeed; + frag.rotateX += frag.rotateXD * simSpeed; + frag.rotateY += frag.rotateYD * simSpeed; + frag.rotateZ += frag.rotateZD * simSpeed; + frag.transform(); + frag.project(); + + // Removal conditions + if ( + // Bottom of screen + frag.projected.y > centerY + targetHitRadius || + // Sides of screen + frag.projected.x < fragLeftBound || + frag.projected.x > fragRightBound || + // Too close to camera + frag.z > cameraFadeEndZ + ) { + frags.splice(i, 1); + returnFrag(frag); + continue; + } + } + + // 2D sparks + for (let i = sparks.length - 1; i >= 0; i--) { + const spark = sparks[i]; + spark.life -= simTime; + if (spark.life <= 0) { + sparks.splice(i, 1); + returnSpark(spark); + continue; + } + spark.x += spark.xD * simSpeed; + spark.y += spark.yD * simSpeed; + spark.xD *= simAirDragSpark; + spark.yD *= simAirDragSpark; + spark.yD += gravity * simSpeed; + } + + PERF_END('entities'); + + // 3D transforms + // ------------------- + + PERF_START('3D'); + + // Aggregate all scene vertices/polys + allVertices.length = 0; + allPolys.length = 0; + allShadowVertices.length = 0; + allShadowPolys.length = 0; + targets.forEach(entity => { + allVertices.push(...entity.vertices); + allPolys.push(...entity.polys); + allShadowVertices.push(...entity.shadowVertices); + allShadowPolys.push(...entity.shadowPolys); + }); + + frags.forEach(entity => { + allVertices.push(...entity.vertices); + allPolys.push(...entity.polys); + allShadowVertices.push(...entity.shadowVertices); + allShadowPolys.push(...entity.shadowPolys); + }); + + // Scene calculations/transformations + allPolys.forEach(p => computePolyNormal(p, 'normalWorld')); + allPolys.forEach(computePolyDepth); + allPolys.sort((a, b) => b.depth - a.depth); + + // Perspective projection + allVertices.forEach(projectVertex); + + allPolys.forEach(p => computePolyNormal(p, 'normalCamera')); + + PERF_END('3D'); + + PERF_START('shadows'); + + // Rotate shadow vertices to light source perspective + transformVertices( + allShadowVertices, + allShadowVertices, + 0, 0, 0, + TAU/8, 0, 0, + 1, 1, 1 + ); + + allShadowPolys.forEach(p => computePolyNormal(p, 'normalWorld')); + + const shadowDistanceMult = Math.hypot(1, 1); + const shadowVerticesLength = allShadowVertices.length; + for (let i=0; i { + if (p.wireframe) { + ctx.lineWidth = 2; + ctx.beginPath(); + const { vertices } = p; + const vCount = vertices.length; + const firstV = vertices[0]; + ctx.moveTo(firstV.x, firstV.y); + for (let i=1; i { + if (!p.wireframe && p.normalCamera.z < 0) return; + + if (p.strokeWidth !== 0) { + ctx.lineWidth = p.normalCamera.z < 0 ? p.strokeWidth * 0.5 : p.strokeWidth; + ctx.strokeStyle = p.normalCamera.z < 0 ? p.strokeColorDark : p.strokeColor; + } + + const { vertices } = p; + const lastV = vertices[vertices.length - 1]; + const fadeOut = p.middle.z > cameraFadeStartZ; + + if (!p.wireframe) { + const normalLight = p.normalWorld.y * 0.5 + p.normalWorld.z * -0.5; + const lightness = normalLight > 0 + ? 0.1 + : ((normalLight ** 32 - normalLight) / 2) * 0.9 + 0.1; + ctx.fillStyle = shadeColor(p.color, lightness); + } + + // Fade out polys close to camera. `globalAlpha` must be reset later. + if (fadeOut) { + // If polygon gets really close to camera (outside `cameraFadeRange`) the alpha + // can go negative, which has the appearance of alpha = 1. So, we'll clamp it at 0. + ctx.globalAlpha = Math.max(0, 1 - (p.middle.z - cameraFadeStartZ) / cameraFadeRange); + } + + ctx.beginPath(); + ctx.moveTo(lastV.x, lastV.y); + for (let v of vertices) { + ctx.lineTo(v.x, v.y); + } + + if (!p.wireframe) { + ctx.fill(); + } + if (p.strokeWidth !== 0) { + ctx.stroke(); + } + + if (fadeOut) { + ctx.globalAlpha = 1; + } + }); + PERF_END('drawPolys'); + + + PERF_START('draw2D'); + + // 2D Sparks + // --------------- + ctx.strokeStyle = sparkColor; + ctx.lineWidth = sparkThickness; + ctx.beginPath(); + sparks.forEach(spark => { + ctx.moveTo(spark.x, spark.y); + // Shrink sparks to zero length as they die. + // Speed up shrinking as life approaches 0 (root curve). + // Note that sparks already get smaller over time as their speed slows + // down from damping. So this is like a double scale down. To counter this + // a bit and keep the sparks larger for longer, we'll also increase the scale + // a bit after applying the root curve. + const scale = (spark.life / spark.maxLife) ** 0.5 * 1.5; + ctx.lineTo(spark.x - spark.xD*scale, spark.y - spark.yD*scale); + + }); + ctx.stroke(); + + + // Touch Strokes + // --------------- + + ctx.strokeStyle = touchTrailColor; + const touchPointCount = touchPoints.length; + for (let i=1; i 68) { + frameTime = 68; + } + + const halfW = width / 2; + const halfH = height / 2; + + // Convert pointer position from screen to scene coords. + pointerScene.x = pointerScreen.x / viewScale - halfW; + pointerScene.y = pointerScreen.y / viewScale - halfH; + + const lag = frameTime / 16.6667; + const simTime = gameSpeed * frameTime; + const simSpeed = gameSpeed * lag; + tick(width, height, simTime, simSpeed, lag); + + // Auto clear canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + // Auto scale drawing for high res displays, and incorporate `viewScale`. + // Also shift canvas so (0, 0) is the middle of the screen. + // This just works with 3D perspective projection. + const drawScale = dpr * viewScale; + ctx.scale(drawScale, drawScale); + ctx.translate(halfW, halfH); + draw(ctx, width, height, viewScale); + ctx.setTransform(1, 0, 0, 1, 0, 0); + } + const raf = () => requestAnimationFrame(frameHandler); + // Start loop + raf(); +} + + + + + +// interaction.js +// ============================================================================ +// ============================================================================ + +// Interaction +// ----------------------------- + +function handleCanvasPointerDown(x, y) { + if (!pointerIsDown) { + pointerIsDown = true; + pointerScreen.x = x; + pointerScreen.y = y; + // On when menus are open, point down/up toggles an interactive mode. + // We just need to rerender the menu system for it to respond. + if (isMenuVisible()) renderMenus(); + } +} + +function handleCanvasPointerUp() { + if (pointerIsDown) { + pointerIsDown = false; + touchPoints.push({ + touchBreak: true, + life: touchPointLife + }); + // On when menus are open, point down/up toggles an interactive mode. + // We just need to rerender the menu system for it to respond. + if (isMenuVisible()) renderMenus(); + } +} + +function handleCanvasPointerMove(x, y) { + if (pointerIsDown) { + pointerScreen.x = x; + pointerScreen.y = y; + } +} + + +// Use pointer events if available, otherwise fallback to touch events (for iOS). +if ('PointerEvent' in window) { + canvas.addEventListener('pointerdown', event => { + event.isPrimary && handleCanvasPointerDown(event.clientX, event.clientY); + }); + + canvas.addEventListener('pointerup', event => { + event.isPrimary && handleCanvasPointerUp(); + }); + + canvas.addEventListener('pointermove', event => { + event.isPrimary && handleCanvasPointerMove(event.clientX, event.clientY); + }); + // We also need to know if the mouse leaves the page. For this game, it's best if that + // cancels a swipe, so essentially acts as a "mouseup" event. + document.body.addEventListener('mouseleave', handleCanvasPointerUp); +} else { + let activeTouchId = null; + canvas.addEventListener('touchstart', event => { + if (!pointerIsDown) { + const touch = event.changedTouches[0]; + activeTouchId = touch.identifier; + handleCanvasPointerDown(touch.clientX, touch.clientY); + + + } + }); + canvas.addEventListener('touchend', event => { + for (let touch of event.changedTouches) { + if (touch.identifier === activeTouchId) { + handleCanvasPointerUp(); + break; + } + } + }); + canvas.addEventListener('touchmove', event => { + for (let touch of event.changedTouches) { + if (touch.identifier === activeTouchId) { + handleCanvasPointerMove(touch.clientX, touch.clientY); + event.preventDefault(); + break; + } + } + }, { passive: false }); +} + + + + + +// index.js +// ============================================================================ +// ============================================================================ + +setupCanvases(); \ No newline at end of file diff --git a/Games/Block_Ninja/style.css b/Games/Block_Ninja/style.css new file mode 100644 index 0000000000..c762c2b1d4 --- /dev/null +++ b/Games/Block_Ninja/style.css @@ -0,0 +1,267 @@ +body { + margin: 0; + background-color: #000; + background-image: radial-gradient(ellipse at top, #335476 0.0%, #31506e 11.1%, #304b67 22.2%, #2f4760 33.3%, #2d4359 44.4%, #2c3f51 55.6%, #2a3a4a 66.7%, #293643 77.8%, #28323d 88.9%, #262e36 100.0%); + height: 100vh; + overflow: hidden; + + font-family: monospace; + font-weight: bold; + letter-spacing: 0.06em; + color: rgba(255, 255, 255, 0.75); +} + +#c { + display: block; + touch-action: none; + transform: translateZ(0); +} + + +/*///////////////////// +// HUD // +/////////////////////*/ + + +.hud__score, +.pause-btn { + position: fixed; + font-size: calc(14px + 2vw + 1vh); +} + +.hud__score { + top: 0.65em; + left: 0.65em; + pointer-events: none; + user-select: none; +} + +.cube-count-lbl { + font-size: 0.46em; +} + +.pause-btn { + position: fixed; + top: 0; + right: 0; + padding: 0.8em 0.65em; +} + +.pause-btn > div { + position: relative; + width: 0.8em; + height: 0.8em; + opacity: 0.75; +} + +.pause-btn > div::before, +.pause-btn > div::after { + content: ''; + display: block; + width: 34%; + height: 100%; + position: absolute; + background-color: #fff; +} + +.pause-btn > div::after { + right: 0; +} + +.slowmo { + position: fixed; + bottom: 0; + width: 100%; + pointer-events: none; + opacity: 0; + transition: opacity 0.4s; + will-change: opacity; +} + +.slowmo::before { + content: 'SLOW-MO'; + display: block; + font-size: calc(8px + 1vw + 0.5vh); + margin-left: 0.5em; + margin-bottom: 8px; +} + +.slowmo::after { + content: ''; + display: block; + position: fixed; + bottom: 0; + width: 100%; + height: 1.5vh; + background-color: rgba(0, 0, 0, 0.25); + z-index: -1; +} + +.slowmo__bar { + height: 1.5vh; + background-color: rgba(255, 255, 255, 0.75); + transform-origin: 0 0; +} + + + +/*///////////////////// +// MENUS // +/////////////////////*/ + +.menus::before { + content: ''; + pointer-events: none; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: #000; + opacity: 0; + transition: opacity 0.2s; + transition-timing-function: ease-in; +} + +.menus.has-active::before { + opacity: 0.08; + transition-duration: 0.4s; + transition-timing-function: ease-out; +} + +.menus.interactive-mode::before { + opacity: 0.02; +} + + + +/* Menu containers */ +.menu { + pointer-events: none; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + user-select: none; + text-align: center; + color: rgba(255, 255, 255, 0.9); + opacity: 0; + visibility: hidden; + transform: translateY(30px); + transition-property: opacity, visibility, transform; + transition-duration: 0.2s; + transition-timing-function: ease-in; +} + +.menu.active { + opacity: 1; + visibility: visible; + transform: translateY(0); + transition-duration: 0.4s; + transition-timing-function: ease-out; +} + +.menus.interactive-mode .menu.active { + opacity: 0.6; +} + +.menus:not(.interactive-mode) .menu.active > * { + pointer-events: auto; +} + + +/* Common menu elements */ + +h1 { + font-size: 4rem; + line-height: 0.95; + text-align: center; + font-weight: bold; + margin: 0 0.65em 1em; +} + +h2 { + font-size: 1.2rem; + line-height: 1; + text-align: center; + font-weight: bold; + margin: -1em 0.65em 1em; +} + +.final-score-lbl { + font-size: 5rem; + margin: -0.2em 0 0; +} + +.high-score-lbl { + font-size: 1.2rem; + margin: 0 0 2.5em; +} + +button { + display: block; + position: relative; + width: 200px; + padding: 12px 20px; + background: transparent; + border: none; + outline: none; + user-select: none; + font-family: monospace; + font-weight: bold; + font-size: 1.4rem; + color: #fff; + opacity: 0.75; + transition: opacity 0.3s; +} + +button::before { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgba(255, 255, 255, 0.15); + transform: scale(0, 0); + opacity: 0; + transition: opacity 0.3s, transform 0.3s; +} + +/* No `:focus` styles because this is a mouse/touch game! */ +button:active { + opacity: 1; +} + +button:active::before { + transform: scale(1, 1); + opacity: 1; +} + +.credits { + position: fixed; + width: 100%; + left: 0; + bottom: 20px; +} + +a { + color: white; +} + +/* Only enable hover state on large screens */ +@media (min-width: 1025px) { + button:hover { + opacity: 1; + } + + button:hover::before { + transform: scale(1, 1); + opacity: 1; + } +} \ No newline at end of file diff --git a/Games/Brick_Breaker/README.md b/Games/Brick_Breaker/README.md index d815790085..9058a3e049 100644 --- a/Games/Brick_Breaker/README.md +++ b/Games/Brick_Breaker/README.md @@ -17,6 +17,10 @@
+## **Scores:** +- +1 for each brick broken till number of bricks is greater than or equal to 60. +- +2 for each brick broken till number of bricks is less than 60 and greater than or equal to 50. +- +5 for each brick broken if number of bricks is less than 50; ## **Screenshots 📸**
diff --git a/Games/Brick_Breaker/index.html b/Games/Brick_Breaker/index.html index 024a1d3f52..7a8bfbed97 100644 --- a/Games/Brick_Breaker/index.html +++ b/Games/Brick_Breaker/index.html @@ -1,25 +1,34 @@ - - - - - Brick Breaker - - - - -
-
- Score: -
-
- -
-
-

Brick Breaker

-
- - + + + + + Brick Breaker + + + + + + + +
+

Brick Breaker

+
+
+ + +
+ Bricks Remaining: 0 +
+
+ Score: 0 +
+ +
+
+ +
+ + diff --git a/Games/Brick_Breaker/script.js b/Games/Brick_Breaker/script.js index 00c32f35a9..54001cefab 100644 --- a/Games/Brick_Breaker/script.js +++ b/Games/Brick_Breaker/script.js @@ -51,6 +51,8 @@ function ballRest() { function brickReset() { brickCount = 0; + initializeBrickColors(); + var i; for (var i = 0; i < 3 * BRICK_COLS; i++) { brickGrid[i] = false; @@ -138,18 +140,54 @@ function ballBrickColl() { } if (brickCount === 0) { brickReset(); - updateScore(0); // Reset the score to 0 when all bricks are destroyed + updateScore(0); + scoredisplay(false); // Reset the score to zero if no bricks are remaining } else { updateScore(brickCount); // Update the score with the remaining brick count + scoredisplay(true); // Increment the score if a brick is hit } + // colorText(ballBrickCol+","+ballBrickRow+": "+brickIndexUnderBall, mouseX, mouseY, 'white'); + + if(brickCount=== 70){ + scoredisplay(0); + } } function updateScore(score) { var scoreElement = document.getElementById("score"); scoreElement.textContent = "Bricks Remaining: " + score; + +} + +var s = 0; // Declare the variable outside the function to store the score +var y=0; +function scoredisplay(hit) { + if (hit) { + s=70-brickCount; + if(s>20){ + y=s-20; + s=s+y*4; + } + else if(s>10){ + y=s-10; + s=s+y; + } + + + } else if(brickCount==70){ + s = 0; // Reset the score to zero if no bricks are hit + } + + + // Update the content of the HTML element with id "s" to display the score + var scoredisplayElement = document.getElementById("s"); + scoredisplayElement.textContent = "Score: " + s; } + + + function paddleMove() { // paddle var paddleTopEdgeY = canvas.height - PADDLE_DIST_FROM_EDGE; @@ -199,7 +237,7 @@ function updateMousePos(evt) { /**********GamePlay Draw functions***********/ function playArea() { // gameCanvas - colorRect(0, 0, canvas.width, canvas.height, "white"); + colorRect(0, 0, canvas.width, canvas.height, "#222"); // ball colorCircle(); // paddle @@ -208,7 +246,7 @@ function playArea() { canvas.height - PADDLE_DIST_FROM_EDGE, PADDLE_WIDTH, PADDLE_THICKNESS, - "black" + "#61dafb" ); drawbricks(); @@ -228,17 +266,39 @@ function rowColToArrayIndex(col, row) { return col + BRICK_COLS * row; } +var brickColors = []; + +// Function to initialize the brick colors +function initializeBrickColors() { + brickColors = []; + for (var i = 0; i < BRICK_ROWS * BRICK_COLS; i++) { + // Add a random color to the array + brickColors.push(getRandomColor()); + } +} + +// Function to get a random color +function getRandomColor() { + var colors = ["#f86257", "#5bb9a9", " #7d5ba6", "#0b5394", "#ec9b00"]; + return colors[Math.floor(Math.random() * colors.length)]; +} + +// Call the function to initialize brick colors once during initialization +initializeBrickColors(); + function drawbricks() { for (var eachRow = 0; eachRow < BRICK_ROWS; eachRow++) { for (var eachCol = 0; eachCol < BRICK_COLS; eachCol++) { var arrayIndex = rowColToArrayIndex(eachCol, eachRow); if (brickGrid[arrayIndex]) { + // Choose a random color from an array of colors + colorRect( BRICK_W * eachCol, BRICK_H * eachRow, BRICK_W - BRICK_GAP, BRICK_H - BRICK_GAP, - "green" + brickColors[arrayIndex] ); } // if brick } // each brick @@ -254,9 +314,9 @@ function colorCircle() { ballY, 10 ); - gradient.addColorStop(0, "blue"); - gradient.addColorStop(0.5, "grey"); - gradient.addColorStop(1, "black"); + gradient.addColorStop(0, "#61dafb"); + gradient.addColorStop(0.5, "#888"); + gradient.addColorStop(1, "#000"); canvasContext.fillStyle = gradient; canvasContext.beginPath(); diff --git a/Games/Brick_Breaker/styles.css b/Games/Brick_Breaker/styles.css index a9b3968c1e..7cbb899ef7 100644 --- a/Games/Brick_Breaker/styles.css +++ b/Games/Brick_Breaker/styles.css @@ -1,19 +1,75 @@ body { - background-color: black; -} -#canvas-container { - margin: 0 auto; - text-align: center; + margin: 20px; + padding: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + /* background-color: #282c34; */ + background: linear-gradient(#282c34, rgb(4, 4, 17)); + color: white; + font-family: 'Arial', sans-serif; } #header-container { text-align: center; - font-size: 40px; - color: white; + margin: 20px; + font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; } -#score-container { - text-align: center; - font-size: 24px; - color: white; - padding: 10px; + +#header-container h1 { + font-size: 2.7em; + color: #61dafb; + margin: 0; +} +.status{ + display: flex; + flex-direction: row; + justify-content: space-between; + width: 800px;; + margin-bottom: 20px; +} +#score-container #score-display { + + font-size: 30px; + margin: 0px; + margin-bottom: 10px; + +} + +#score-display{ + color:rgb(233, 243, 160); +} + +.status span{ + font-size: 20px; + border: 1px solid rgb(103, 101, 101) !important; + padding: 10px; +} + +/* #canvas-container { + display: flex; + justify-content: center; + align-items: center; +} */ + #canvas-container { + display: flex; + justify-content: center; + align-items: flex-start !important; /* Align bricks to the top */ + height: calc(100vh - 100px); + top:0; +} + +#gameCanvas { + border: 2px solid #61dafb; + background-color: #222; +} + +.home-icon { + font-size: 1.5em; + position: absolute; + /* top: 20px; */ + left: 20px; + color: #61dafb; + text-decoration: none; } diff --git a/Games/Computer_Bingo/README.md b/Games/Computer_Bingo/README.md new file mode 100644 index 0000000000..2f89ca6c79 --- /dev/null +++ b/Games/Computer_Bingo/README.md @@ -0,0 +1,16 @@ +# 🏆 Simulador Bingo + +Repository of a simulator of the popular Bingo game where you can compete against the PC + +## 📝 Detalle +Game where 15 numbers from 1 to 100 are randomly distributed between 2 cards (player and PC), the numbers can be repeated between player and machine but not in +oneself. As the ball is drawn, those that came out are marked and below on the screen there is also the history of the numbers drawn. The first to exhaust the +Card numbers win. The score is saved in localStorage based on how quickly it was finished, taking into account the balls that remain in the bowl without coming out + +# Screenshot + +![alt text](image.png) + +# Working Video + + \ No newline at end of file diff --git a/Games/Computer_Bingo/WhatsApp Video 2024-06-07 at 18.53.41_01758a15.mp4 b/Games/Computer_Bingo/WhatsApp Video 2024-06-07 at 18.53.41_01758a15.mp4 new file mode 100644 index 0000000000..99f90d472e Binary files /dev/null and b/Games/Computer_Bingo/WhatsApp Video 2024-06-07 at 18.53.41_01758a15.mp4 differ diff --git a/Games/Computer_Bingo/favicon/image.png b/Games/Computer_Bingo/favicon/image.png new file mode 100644 index 0000000000..3bfaa3daae Binary files /dev/null and b/Games/Computer_Bingo/favicon/image.png differ diff --git a/Games/Computer_Bingo/image.png b/Games/Computer_Bingo/image.png new file mode 100644 index 0000000000..f10c385f06 Binary files /dev/null and b/Games/Computer_Bingo/image.png differ diff --git a/Games/Computer_Bingo/index.html b/Games/Computer_Bingo/index.html new file mode 100644 index 0000000000..bbb13c6190 --- /dev/null +++ b/Games/Computer_Bingo/index.html @@ -0,0 +1,41 @@ + + + + + + + + + + Bingo + + + +
+

maximum score 0 points

+
+
+
+

Player

+
+
+
+

Start

+
+
+

CPU

+
+
+
+ +
+ + +
+ +
+ + + + + \ No newline at end of file diff --git a/Games/Computer_Bingo/script.js b/Games/Computer_Bingo/script.js new file mode 100644 index 0000000000..de894531a4 --- /dev/null +++ b/Games/Computer_Bingo/script.js @@ -0,0 +1,122 @@ +const userboard = document.getElementById('playerBoard') +const cpuBoard = document.getElementById('cpuBoard') +const totalNumbers = document.getElementById('totalNumbers') +const numberDraw = document.getElementById('numberDraw') +const automaticBtn = document.getElementById('automatica') +const stopAutomatic = document.getElementById('stopAutomatica') +const scoreSpan = document.getElementById('score') + +const maxScore = localStorage.getItem('maxScore') || 0 +scoreSpan.innerText = maxScore + +const userNumbers = fifteenRandomNumbers() +const cpuNumbers = fifteenRandomNumbers() + + +let userAcerts = 0 +let cpuAcerts = 0 + +// Creo el array con todos los numeros del 1 al 99, ya que son las bolas que pueden salir +const balls = [] +for (let i = 1; i < 100; i++) { + balls.push(i) +} + +for (let i = 0; i < userNumbers.length; i++) { + userboard.innerHTML += `
${userNumbers[i]}
` +} + +for (let i = 0; i < cpuNumbers.length; i++) { + cpuBoard.innerHTML += `
${cpuNumbers[i]}
` +} + + + +numberDraw.addEventListener('click', randomNumberDraw) +automaticBtn.addEventListener('click', () => automatic(true)) +stopAutomatic.addEventListener('click', () => automatic(false)) + + + +function automatic(value) { + + if (value) { + alert('Automatico activado!') + automaticInterval = setInterval(randomNumberDraw, 300) + } else { + alert('Automatico desactivado!') + clearInterval(automaticInterval) + } + + automaticBtn.classList.toggle('hidden') + stopAutomatic.classList.toggle('hidden') +} + +function randomNumberDraw() { + const randomNumber = balls[Math.floor(Math.random() * balls.length)] + balls.splice(balls.indexOf(randomNumber), 1) + console.log(balls) + + numberDraw.innerText = randomNumber + + totalNumbers.innerHTML += `
${randomNumber}
` + + if (userNumbers.includes(randomNumber)) { + document.getElementById(`userNum${userNumbers.indexOf(randomNumber)}`).style.backgroundColor = 'green' + userAcerts++ + } + + if (cpuNumbers.includes(randomNumber)) { + document.getElementById(`cpuNum${cpuNumbers.indexOf(randomNumber)}`).style.backgroundColor = 'red' + cpuAcerts++ + } + + checkWinner() + + if (balls.length === 0) { + alert('No quedan mas bolas!') + document.getElementById('numberDraw').style.display = 'none' + } +} + +function checkWinner() { + if (userAcerts === 15) { + document.getElementById('numberDraw').style.display = 'none' + alert(`You won! They were left in the closet ${balls.length} balls`) + clearInterval(automaticInterval) + stopAutomatic.classList.toggle('hidden') + document.querySelector('.jugada-automatica').style.minHeight = '30px' + if (balls.length > maxScore) { + localStorage.setItem('maxScore', balls.length) + scoreSpan.innerText = balls.length + } + } else if (cpuAcerts === 15) { + document.getElementById('numberDraw').style.display = 'none' + alert(`You lost, the winner is the CPU! They were left in the closet ${balls.length} balls`) + clearInterval(automaticInterval) + stopAutomatic.classList.toggle('hidden') + document.querySelector('.jugada-automatica').style.minHeight = '30px' + } +} + +function fifteenRandomNumbers() { + + const arr = []; + + for (let i = 0; i < 15; i++) { + const randomNumber = Math.floor(Math.random() * 100) + + isInArray = arr.includes(randomNumber) + + if (randomNumber == 100 || randomNumber == 0) { + i-- // Si bien no lo agrega al array por el continue, con el i-- "vuelvo" un ciclo, ya que si no lo pierdo y quedo con menos de 15 + continue + } else if (!isInArray) { + arr.push(randomNumber) + } else { + i-- + } + } + + return arr +} \ No newline at end of file diff --git a/Games/Computer_Bingo/style.css b/Games/Computer_Bingo/style.css new file mode 100644 index 0000000000..6c7a20014d --- /dev/null +++ b/Games/Computer_Bingo/style.css @@ -0,0 +1,158 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Helvetica, sans-serif, sans-serif; +} + +body { + background-color: #2455c0; +} + +.competidores { + display: flex; + justify-content: space-around; + align-items: center; + margin-top: 3em; +} + +.carton { + background-color: #9e1c23; + color: #fff; + width: calc(65px * 5); + padding: 10px; + border-radius: 5px; +} + +.carton h2 { + text-align: center; + margin: 1em; +} + +.carton__numero-contenedor { + display: flex; + flex-wrap: wrap; + justify-content: space-around; +} + +.numero-contenedor__child { + width: 50px; + height: 50px; + color: #000; + background-color: #fff; + margin: 5px; + display: flex; + justify-content: center; + align-items: center; + font-size: 20px; + font-weight: bold; + border-radius: 5px; +} + +.mezclador { + border: 3px solid #000; + width: 300px; + height: 300px; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + background: radial-gradient(rgb(196, 188, 188), #000); +} + +.mezclador p { + background-color: #fff; + font-size: 50px; + padding: 5px; + border: 5px solid #555; + min-width: 70px; + min-height: 70px; + text-align: center; + cursor: pointer; + user-select: none; +} + +.mezclador p:hover{ + background-color: #000; + color: #fff; + transition: .5s; +} + +.numeros { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin: 0 2em .7em 2em; + border: 2px solid #fff; + padding: 10px; + min-height: 250px; + border-radius: 5px; +} + +.numero-obtenido { + width: 50px; + height: 50px; + background-color: #fff; + margin: 5px; + display: flex; + justify-content: center; + align-items: center; + font-size: 20px; + font-weight: bold; + border-radius: 5px; +} + +.jugada-automatica{ + min-height: 25vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.aut-btn{ + padding: 20px; + border: 2px solid #fff; + border-radius: 5px; + background-color: #fff; + color: #000; + font-size: 20px; + font-weight: bold; + cursor: pointer; +} + +.hidden{ + display: none; +} + +.score p { + color: #000; + font-size: 20px; + font-weight: bold; + margin: 1em auto; + background-color: rgb(184, 170, 170); + display: block; + padding: 10px; + width: 400px; + text-align: center; + border-radius: 5px; + cursor: pointer; +} + +@media screen and (max-width: 970px) { + .competidores { + flex-direction: column; + } + + .mezclador{ + order: -1; + } + + .competidores > *{ + margin: 1em; + } + + .score p{ + width: 40%; + } +} \ No newline at end of file diff --git a/Games/Disney_Trivia/README.md b/Games/Disney_Trivia/README.md new file mode 100644 index 0000000000..8273af6277 --- /dev/null +++ b/Games/Disney_Trivia/README.md @@ -0,0 +1,16 @@ +# **Disney Trivia** + +## **Description 📃** +A fun and engaging trivia game about Disney movies, characters, and history. + +## **How To Play🕹️** +- Click on start button to start and choose the correct option. +- There is time limit of 15 seconds. +- You can restart the game to play again. +- Click on next button for the next question. + +## **Screenshots 📸** + +![Screenshot from 2024-06-06 22-40-36](https://github.com/manmita/GameZone/assets/34617961/6c688ec3-6c67-490f-bd20-da7c419964a7) + + diff --git a/Games/Disney_Trivia/disney_b.jpg b/Games/Disney_Trivia/disney_b.jpg new file mode 100644 index 0000000000..7985e83133 Binary files /dev/null and b/Games/Disney_Trivia/disney_b.jpg differ diff --git a/Games/Disney_Trivia/index.html b/Games/Disney_Trivia/index.html new file mode 100644 index 0000000000..69fec9c32d --- /dev/null +++ b/Games/Disney_Trivia/index.html @@ -0,0 +1,33 @@ + + + + + + Disney Trivia Game + + + +
+

Disney Trivia Game

+
+
Time left: 15 seconds
+
Question text
+
+ + + + +
+
+
+ + +
+
+

Your Score: 0

+
+
+ + + + diff --git a/Games/Disney_Trivia/script.js b/Games/Disney_Trivia/script.js new file mode 100644 index 0000000000..4972bba9bf --- /dev/null +++ b/Games/Disney_Trivia/script.js @@ -0,0 +1,283 @@ +// script.js + +const startButton = document.getElementById('start-btn'); +const nextButton = document.getElementById('next-btn'); +const questionContainerElement = document.getElementById('question-container'); +const questionElement = document.getElementById('question'); +const answerButtonsElement = document.getElementById('answer-buttons'); +const scoreContainer = document.getElementById('score-container'); +const scoreElement = document.getElementById('score'); +const timerElement = document.getElementById('time'); + +let shuffledQuestions, currentQuestionIndex, score, timeLeft, timerInterval; + +// define questions array with question and answer +const questions = [ + { + question: 'What was the first animated feature film released by Disney?', + answers: [ + { text: 'Snow White and the Seven Dwarfs', correct: true }, + { text: 'Cinderella', correct: false }, + { text: 'Sleeping Beauty', correct: false }, + { text: 'Bambi', correct: false } + ] + }, + { + question: 'In "The Lion King," what is the name of Simba\'s father?', + answers: [ + { text: 'Scar', correct: false }, + { text: 'Mufasa', correct: true }, + { text: 'Timon', correct: false }, + { text: 'Pumbaa', correct: false } + ] + }, + { + question: 'What is the name of the toy cowboy in "Toy Story"?', + answers: [ + { text: 'Buzz Lightyear', correct: false }, + { text: 'Jessie', correct: false }, + { text: 'Bullseye', correct: false }, + { text: 'Woody', correct: true }, + ] + }, + { + question: 'Which Disney princess has a pet tiger named Rajah?', + answers: [ + { text: 'Jasmine', correct: true }, + { text: 'Ariel', correct: false }, + { text: 'Belle', correct: false }, + { text: 'Mulan', correct: false } + ] + }, + { + question: 'What does the crocodile swallow in "Peter Pan"?', + answers: [ + { text: 'Captain Hook\'s hook', correct: false }, + { text: 'Peter Pan\'s hat', correct: false }, + { text: 'A clock', correct: true }, + { text: 'A map', correct: false } + ] + }, + { + question: 'What kind of animal is Dumbo?', + answers: [ + { text: 'A mouse', correct: false }, + { text: 'An elephant', correct: true }, + { text: 'A lion', correct: false }, + { text: 'A bear', correct: false } + ] + }, + { + question: 'In "Beauty and the Beast," what is the name of the teapot?', + answers: [ + { text: 'Mrs. Potts', correct: true }, + { text: 'Lumière', correct: false }, + { text: 'Cogsworth', correct: false }, + { text: 'Belle', correct: false } + ] + }, + { + question: 'In which Disney movie do two dogs share a plate of spaghetti?', + answers: [ + { text: '101 Dalmatians', correct: false }, + { text: 'The Fox and the Hound', correct: false }, + { text: 'Lady and the Tramp', correct: true }, + { text: 'Oliver & Company', correct: false } + ] + }, + { + question: 'What is the name of the bear in "The Jungle Book"?', + answers: [ + { text: 'Baloo', correct: true }, + { text: 'Bagheera', correct: false }, + { text: 'Shere Khan', correct: false }, + { text: 'Kaa', correct: false } + ] + }, + { + question: 'Which Disney princess sings "Part of Your World"?', + answers: [ + { text: 'Belle', correct: false }, + { text: 'Cinderella', correct: false }, + { text: 'Rapunzel', correct: false }, + { text: 'Ariel', correct: true }, + ] + }, + { + question: 'In "Aladdin," what is the name of Aladdin\'s pet monkey?', + answers: [ + { text: 'Iago', correct: false }, + { text: 'Abu', correct: true }, + { text: 'Rajah', correct: false }, + { text: 'Sultan', correct: false } + ] + }, + { + question: 'In "Finding Nemo," what kind of fish is Nemo?', + answers: [ + { text: 'Clownfish', correct: true }, + { text: 'Goldfish', correct: false }, + { text: 'Betta fish', correct: false }, + { text: 'Angelfish', correct: false } + ] + }, + { + question: 'In "Frozen," which song does Elsa sing as she builds the castle?', + answers: [ + { text: 'Let It Go', correct: true }, + { text: 'Do You Want to Build a Snowman?', correct: false }, + { text: 'For the First Time in Forever', correct: false }, + { text: 'Love Is an Open Door', correct: false } + ] + }, + { + question: 'In "Mulan," what is the name of Mulan\'s dragon guardian?', + answers: [ + { text: 'Shan Yu', correct: false }, + { text: 'Crikee', correct: false }, + { text: 'Mushu', correct: true }, + { text: 'Li Shang', correct: false } + ] + }, + { + question: 'What does Rapunzel use to hit Flynn Ryder over the head?', + answers: [ + { text: 'A book', correct: false }, + { text: 'A frying pan', correct: true }, + { text: 'A chair', correct: false }, + { text: 'A vase', correct: false } + ] + }, + { + question: 'In "Hercules," what are the names of the two little demons that work for Hades?', + answers: [ + { text: 'Famine and Pestilence', correct: false }, + { text: 'Destruction and Chaos', correct: false }, + { text: 'Pain and Panic', correct: true }, + { text: 'Wrath and Fury', correct: false } + ] + }, + { + question: 'In "Cinderella," what are the names of Cinderella\'s stepsisters?', + answers: [ + { text: 'Beatrice and Eugenie', correct: false }, + { text: 'Hilda and Helga', correct: false }, + { text: 'Flora and Fauna', correct: false }, + { text: 'Anastasia and Drizella', correct: true }, + ] + }, + { + question: 'In "The Little Mermaid," what does Ariel call the fork she collects?', + answers: [ + { text: 'Dinglehopper', correct: true }, + { text: 'Snarfblatt', correct: false }, + { text: 'Thingamabob', correct: false }, + { text: 'Gizmo', correct: false } + ] + } +]; + + +startButton.addEventListener('click', startGame); +nextButton.addEventListener('click', () => { + currentQuestionIndex++; + setNextQuestion(); +}); + +skipButton.addEventListener('click', () => { + currentQuestionIndex++; + setNextQuestion(); +}); + +// function to start the game +function startGame() { + startButton.classList.add('hide'); // hide start button + shuffledQuestions = questions.sort(() => Math.random() - 0.5); + currentQuestionIndex = 0; // reset question + score = 0; // reset score + scoreContainer.classList.add('hide'); //hide score container + questionContainerElement.classList.remove('hide'); //show question container + setNextQuestion(); +} + +// function to set next question +function setNextQuestion() { + resetState(); + showQuestion(shuffledQuestions[currentQuestionIndex]); + startTimer(); +} + +// function to display the question and answers +function showQuestion(question) { + questionElement.innerText = question.question; + question.answers.forEach(answer => { + const button = document.createElement('button'); // create a button for each answer + button.innerText = answer.text; + button.classList.add('btn'); + if (answer.correct) { + button.dataset.correct = answer.correct; + } + button.addEventListener('click', selectAnswer); + answerButtonsElement.appendChild(button); + }); +} + +// function to reset +function resetState() { + clearInterval(timerInterval); + timerElement.innerText = '15'; + nextButton.classList.add('hide'); + while (answerButtonsElement.firstChild) { + answerButtonsElement.removeChild(answerButtonsElement.firstChild); + } +} + +// function to select answer +function selectAnswer(e) { + const selectedButton = e.target; + const correct = selectedButton.dataset.correct; + if (correct) { + score++; // if correct answer then increment score + } + Array.from(answerButtonsElement.children).forEach(button => { + setStatusClass(button, button.dataset.correct); + }); + if (shuffledQuestions.length > currentQuestionIndex + 1) { + nextButton.classList.remove('hide'); + } else { + startButton.innerText = 'Restart'; + startButton.classList.remove('hide'); + scoreContainer.classList.remove('hide'); + scoreElement.innerText = `Your Score: ${score}`; + questionContainerElement.classList.add('hide'); + } +} + +function setStatusClass(element, correct) { + clearStatusClass(element); + if (correct) { + element.classList.add('correct'); + } else { + element.classList.add('wrong'); + } +} + +function clearStatusClass(element) { + element.classList.remove('correct'); + element.classList.remove('wrong'); +} + +// function to start timer +function startTimer() { + timeLeft = 15; + timerInterval = setInterval(() => { + timeLeft--; + timerElement.innerText = timeLeft; + if (timeLeft <= 0) { + clearInterval(timerInterval); + currentQuestionIndex++; + setNextQuestion(); + } + }, 1000); +} + diff --git a/Games/Disney_Trivia/style.css b/Games/Disney_Trivia/style.css new file mode 100644 index 0000000000..a62e8cb430 --- /dev/null +++ b/Games/Disney_Trivia/style.css @@ -0,0 +1,78 @@ +/* style.css */ + +body { + background-image: url("https://github.com/manmita/GameZone/blob/Disney_Trivia/Games/Disney_Trivia/disney_b.jpg"); + background-repeat: no-repeat; + background-size: 1920px 1080px; + display: flex; + font-family: 'Arial', sans-serif; + justify-content: center; + align-items: center; + height: 100vh; + +} + +.container { + text-align: center; + width: 80%; + max-width: 600px; + width: 100%; + background-color: white; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(25, 89, 172, 0.1); + text-align: center; +} + +h1 { + margin-bottom: 20px; +} + +.btn { + border: none; + outline: none; + padding: 10px 20px; + margin: 10px; + font-size: 16px; + cursor: pointer; + border-radius: 5px; + transition: background-color 0.3s; +} + +.btn:hover { + background-color: #dcdcdc; +} + +.btn-container { + display: flex; + flex-direction: column; +} + +.next-btn { + margin-top: 20px; +} + +.btn.answer { + background-color: #e0e0e0; +} + +.btn.correct { + background-color: #4CAF50; + color: white; +} + +.btn.wrong { + background-color: #f44336; + color: white; +} + +.hide { + display: none; +} + +#timer { + font-size: 18px; + margin-bottom: 20px; +} + + diff --git a/Games/Harmony_Mixer/Assets/Background.svg b/Games/Harmony_Mixer/Assets/Background.svg new file mode 100644 index 0000000000..eebd0f2b90 --- /dev/null +++ b/Games/Harmony_Mixer/Assets/Background.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Games/Harmony_Mixer/Assets/Pause-button.png b/Games/Harmony_Mixer/Assets/Pause-button.png new file mode 100644 index 0000000000..3c877cc4ee Binary files /dev/null and b/Games/Harmony_Mixer/Assets/Pause-button.png differ diff --git a/Games/Harmony_Mixer/Assets/Play-button.png b/Games/Harmony_Mixer/Assets/Play-button.png new file mode 100644 index 0000000000..8c0c499c38 Binary files /dev/null and b/Games/Harmony_Mixer/Assets/Play-button.png differ diff --git a/Games/Harmony_Mixer/Assets/Reset.png b/Games/Harmony_Mixer/Assets/Reset.png new file mode 100644 index 0000000000..aacd523986 Binary files /dev/null and b/Games/Harmony_Mixer/Assets/Reset.png differ diff --git a/Games/Harmony_Mixer/Assets/Upload-2.png b/Games/Harmony_Mixer/Assets/Upload-2.png new file mode 100644 index 0000000000..6a477e1caf Binary files /dev/null and b/Games/Harmony_Mixer/Assets/Upload-2.png differ diff --git a/Games/Harmony_Mixer/Assets/Upload.png b/Games/Harmony_Mixer/Assets/Upload.png new file mode 100644 index 0000000000..13824e97d2 Binary files /dev/null and b/Games/Harmony_Mixer/Assets/Upload.png differ diff --git a/Games/Harmony_Mixer/Assets/logo.svg b/Games/Harmony_Mixer/Assets/logo.svg new file mode 100644 index 0000000000..6c5394ba76 --- /dev/null +++ b/Games/Harmony_Mixer/Assets/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Games/Harmony_Mixer/README.md b/Games/Harmony_Mixer/README.md new file mode 100644 index 0000000000..3194ae5fc3 --- /dev/null +++ b/Games/Harmony_Mixer/README.md @@ -0,0 +1,51 @@ +# **Game_Name** + +Harmony Mixer + +
+ +## **Description 📃** + + + +- **Harmony Mixer** is an interactive and immersive audio visualizer game that allows you to upload, manipulate, and mix audio tracks. Experience the magic of sound through real-time visualizations and intuitive controls that make mixing both fun and educational. + +## **functionalities 🎮** + + + +- Upload and play audio files. +- Adjust pitch, volume, filter frequency, and balance of the audio. +- Real-time audio visualization on a canvas. +- Interactive seek bar to navigate through the audio track. +- Play, pause, and reset settings for seamless audio control. +- Visual feedback through animated controls and elements. + +
+ +## **How to play? 🕹️** + + + +- Open **Harmony Mixer** in your web browser. +- Click the upload icon to select an audio file from your device. +- Once the audio is uploaded, it will start playing automatically. +- Use the pitch, volume, filter, and balance controls to mix the audio to your preference. +- Watch the audio visualization in real-time on the canvas. +- Use the seek bar to navigate through the track. +- Play and pause the audio using the respective buttons. +- Click the reset button to restore default settings and start mixing afresh. +- Enjoy the dynamic and engaging audio visualizer experience! + +
+ +## **Screenshots 📸** + +
+Screenshot 2024-06-09 at 12 43 43 AM + +
+ +## **Working video 📹** + +[screen-capture.webm](https://github.com/sidharth2829/GameZone/assets/111569459/bd452abf-2952-4553-ae90-4e9db322aebe) diff --git a/Games/Harmony_Mixer/index.html b/Games/Harmony_Mixer/index.html new file mode 100644 index 0000000000..ab52127f16 --- /dev/null +++ b/Games/Harmony_Mixer/index.html @@ -0,0 +1,45 @@ + + + + + + + Harmony Mixer + + + + + + + + + +
+ + + + + + + + + + + + +
+ +
+ + + + +
+ + + diff --git a/Games/Harmony_Mixer/script.js b/Games/Harmony_Mixer/script.js new file mode 100644 index 0000000000..2c4ae8f566 --- /dev/null +++ b/Games/Harmony_Mixer/script.js @@ -0,0 +1,172 @@ +const audioUpload = document.getElementById('audio-upload'); +const canvas = document.getElementById('visualizer'); +const canvasCtx = canvas.getContext('2d'); +const pitchControl = document.getElementById('pitch'); +const volumeControl = document.getElementById('volume'); +const filterControl = document.getElementById('filter'); +const balanceControl = document.getElementById('balance'); +const playButton = document.getElementById('play'); +const pauseButton = document.getElementById('pause'); +const resetSettingsButton = document.getElementById('reset-settings'); +const seekBar = document.getElementById('seek-bar'); +const uploadImage = document.getElementById('upload-image'); +const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); +let analyser, bufferLength, dataArray, source, gainNode, pannerNode, filterNode, buffer, isPlaying = false, startTime = 0, pausedAt = 0; + +audioUpload.addEventListener('change', function() { + const file = this.files[0]; + if (file) { + if (isPlaying) { + pauseAudio(); // Stop the audio when a new file is uploaded + } + const reader = new FileReader(); + reader.onload = function(e) { + audioCtx.decodeAudioData(e.target.result, function(decodedData) { + buffer = decodedData; + initAudio(); + seekBar.max = buffer.duration; + seekBar.value = 0; // Reset seek bar to beginning + pausedAt = 0; // Reset pausedAt to beginning + startAudio(); // Play audio automatically after file is uploaded + }); + }; + reader.readAsArrayBuffer(file); + uploadImage.src = './Assets/Upload-2.png'; + } +}); + +function initAudio() { + gainNode = audioCtx.createGain(); + gainNode.gain.value = volumeControl.value; + + pannerNode = audioCtx.createStereoPanner(); + pannerNode.pan.value = balanceControl.value; + + filterNode = audioCtx.createBiquadFilter(); + filterNode.type = 'lowpass'; + filterNode.frequency.value = filterControl.value; + + analyser = audioCtx.createAnalyser(); + analyser.fftSize = 2048; + bufferLength = analyser.frequencyBinCount; + dataArray = new Uint8Array(bufferLength); + + gainNode.connect(pannerNode); + pannerNode.connect(filterNode); + filterNode.connect(analyser); + analyser.connect(audioCtx.destination); + + pitchControl.addEventListener('input', function() { + if (source) { + source.detune.value = (this.value - 1) * 1000; // detune in cents + } + }); + + volumeControl.addEventListener('input', function() { + if (gainNode) { + gainNode.gain.value = this.value; + } + }); + + filterControl.addEventListener('input', function() { + if (filterNode) { + filterNode.frequency.value = this.value; + } + }); + + balanceControl.addEventListener('input', function() { + if (pannerNode) { + pannerNode.pan.value = this.value; + } + }); + + resetSettingsButton.addEventListener('click', function() { + pitchControl.value = 1; + volumeControl.value = 1; + filterControl.value = 20000; // default value + balanceControl.value = 0; + + if (source) { + source.detune.value = 0; + } + if (gainNode) { + gainNode.gain.value = 1; + } + if (pannerNode) { + pannerNode.pan.value = 0; + } + if (filterNode) { + filterNode.frequency.value = 1000; + } + + }); + + seekBar.addEventListener('input', function() { + if (isPlaying) { + pauseAudio(); + pausedAt = parseFloat(this.value); + startAudio(); + } else { + pausedAt = parseFloat(this.value); + } + }); +} + +function startAudio() { + source = audioCtx.createBufferSource(); + source.buffer = buffer; + source.detune.value = (pitchControl.value - 1) * 1000; + + source.connect(gainNode); + + source.start(0, pausedAt); + startTime = audioCtx.currentTime - pausedAt; + isPlaying = true; + draw(); +} + +function pauseAudio() { + if (source) { + source.stop(); + source.disconnect(); + } + pausedAt = audioCtx.currentTime - startTime; + isPlaying = false; +} + +playButton.addEventListener('click', function() { + if (!isPlaying) { + startAudio(); + } +}); + +pauseButton.addEventListener('click', function() { + if (isPlaying) { + pauseAudio(); + } +}); + +function draw() { + if (!isPlaying) return; + requestAnimationFrame(draw); + analyser.getByteFrequencyData(dataArray); + canvasCtx.clearRect(0, 0, canvas.width, canvas.height); + + const barWidth = (canvas.width / bufferLength) * 2.5; + let barHeight; + let x = 0; + + for (let i = 0; i < bufferLength; i++) { + barHeight = dataArray[i]; + // Calculate color + const shade = 255 - (barHeight * 2); // Reverse the height to get a lighter color + canvasCtx.fillStyle = `rgb(${shade}, ${shade}, 255)`; // Shades of purple + + canvasCtx.fillRect(x, canvas.height - barHeight / 2, barWidth, barHeight / 2); + + x += barWidth + 1; + } + + // Update seek bar + seekBar.value = audioCtx.currentTime - startTime; +} diff --git a/Games/Harmony_Mixer/style.css b/Games/Harmony_Mixer/style.css new file mode 100644 index 0000000000..b6618cfd5d --- /dev/null +++ b/Games/Harmony_Mixer/style.css @@ -0,0 +1,95 @@ +*{ + font-family: "Tenor Sans", cursive; + align-self: center; +} + +body { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + margin: 0; + background-image: url("./Assets/Background.svg"); + color: rgb(0, 0, 0); + background-position: center; /* Center the image */ + background-repeat: no-repeat; /* Do not repeat the image */ + background-size: cover; + +} + +h1 { + margin-bottom: 20px; + text-align: center; + width: 75%; +} + +#audio-upload { + display: none; +} + +.upload-label { + cursor: pointer; + width: 7%; + margin-top: 20px; +} + +.controls { + display: flex; + flex-wrap: wrap; + gap: 20px; + margin-bottom: 20px; + justify-content: space-evenly; +} + +canvas { + width: 70%; + display: flex; + margin: auto; + aspect-ratio: 500 / 150; +} + +button { + background-color: transparent; + color: #282c34; + border: none; + width: 7%; + cursor: pointer; +} +img { + transition: transform .7s ease-in-out; +} +img:hover { + transform: rotate(360deg); +}s + +label { + display: block; + margin-top: 10px; + align-self: center; +} + +#seek-bar { + width: 70%; + margin-top: 20px; +} + +#seek-container +{ + width: 100%; + display: flex; + justify-content: space-evenly; + margin: auto; +} + +#navbar +{ + display: flex; + width: 100%; +} + +#logo +{ + width: 10%; + margin: 1rem; +} \ No newline at end of file diff --git a/Games/Kill_The_Bird/index.html b/Games/Kill_The_Bird/index.html new file mode 100644 index 0000000000..1e44a677b5 --- /dev/null +++ b/Games/Kill_The_Bird/index.html @@ -0,0 +1,33 @@ + + + + + + Kill The Birds + + + +
+
+ +
+
GAME OVER
+

KILL THE BIRDS (shoot the birds)

+

CSS GAME - NO JS!

+ + + + + + + + + + + + + +
SCORE:
+
+ + diff --git a/Games/Kill_The_Bird/styles.css b/Games/Kill_The_Bird/styles.css new file mode 100644 index 0000000000..b0e64e93a7 --- /dev/null +++ b/Games/Kill_The_Bird/styles.css @@ -0,0 +1,317 @@ +body { + counter-reset: birds; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: hidden; +} +/*hide checkbox*/ +input { + position: fixed; + left: -10px; + top: -10px; +} + +h1 { + margin: 0; + text-align: center; +} +h2 { + position: fixed; + right: 20px; + bottom: 0; + font-size: 18px; + color: red; +} + +/*play area*/ +.wrapper { + height: 500px; + background: -webkit-linear-gradient( + top, + hsla(210, 70%, 80%, 1) 0%, + hsla(210, 50%, 100%, 1) 100% + ); + position: relative; + cursor: crosshair; +} +/*count dead birds*/ +.input-circle:checked { + counter-increment: birds; +} + +.sum { + position: fixed; + left: 45%; + top: 60px; + font-size: 24px; + fonot-weight: bold; +} + +/*print to screen dead birds*/ +.sum:after { + content: counter(birds); +} + +.input-circle ~ .pajaro { + opacity: 0; + transition: 0.3s cubic-bezier(0, 0.43, 1, 0); + animation: move 8s infinite alternate; +} +.input-circle1:not(:checked) ~ .pajaro1, +.input-circle2:not(:checked) ~ .pajaro2, +.input-circle3:not(:checked) ~ .pajaro3, +.input-circle4:not(:checked) ~ .pajaro4, +.input-circle5:not(:checked) ~ .pajaro5, +.input-circle6:not(:checked) ~ .pajaro6 { + opacity: 1; +} + +.input-circle1:checked ~ .pajaro1 span, +.input-circle2:checked ~ .pajaro2 span, +.input-circle3:checked ~ .pajaro3 span, +.input-circle4:checked ~ .pajaro4 span, +.input-circle5:checked ~ .pajaro5 span, +.input-circle6:checked ~ .pajaro6 span { + display: block; +} + +.pajaro { + position: absolute; + left: 0; + cursor: crosshair; +} +.pajaro > span { + display: none; + position: absolute; + z-index: 2; + left: -250%; + bottom: -50%; + background-color: white; + border: solid 2px #000; + width: 80px; + height: 30px; + padding: 10px; + border-radius: 50%; +} +.pajaro > span:before { + content: "I'm Dead!"; + color: red; + font-weight: bold; +} + +.pajaro1 { + top: 50px; + animation-delay: -2s !important; + transform: scale(0.9); +} +.pajaro2 { + top: 100px; + animation-delay: -4s !important; + transform: scale(0.5); +} +.pajaro3 { + top: 200px; + animation-delay: -3s !important; + transform: scale(1.4); +} + +.pajaro4 { + top: 50px; + animation-delay: -12s !important; + transform: scale(0.9); +} +.pajaro5 { + top: 100px; + animation-delay: -16s !important; + transform: scale(0.5); +} +.pajaro6 { + top: 200px; + animation-delay: -20s !important; + transform: scale(1.4); +} + +@keyframes move { + 0% { + left: 0%; + } + 20% { + left: 20%; + top: 50%; + } + 40% { + top: 30%; + left: 60%; + } + 60% { + top: 80%; + left: 80%; + } + 80% { + top: 10%; + left: 20%; + } + 100% { + top: 30%; + left: 20%; + } +} + +.timer { + background-color: #333; + width: 300px; + height: 50px; + position: fixed; +} + +.timer span { + display: block; + background: repeating-linear-gradient( + -45deg, + #000, + rgba(0, 0, 0, 0) 25px, + #fff 25px, + #fff 50px + ); + width: 300px; + height: 50px; + animation: timer 20s linear; +} + +.timer span:before { + content: "TIME LEFT"; + display: block; + position: absolute; + z-index: 3; + left: 0; + right: 0; + top: 0; + bottom: 0; + text-align: center; + line-height: 50px; + font-size: 25px; + color: red; +} +@keyframes timer { + 0% { + width: 10px; + } + 100% { + width: 300px; + display: block; + } +} + +.gameover { + position: fixed; + z-index: 100000; + left: 0; + top: 0; + bottom: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.8); + animation: gameover 20s linear forwards; + font-size: 80px; + color: white; + font-weight: bold; + text-align: center; + text-indent: 0; + line-height: 500px; +} + +@keyframes gameover { + 0% { + left: -5000px; + bottom: 100%; + } + 97% { + left: -5000px; + bottom: 100%; + } + 100% { + left: 0px; + } +} + +/*------------------------------------------------------ body of the bird +*/ + +.pajaro { + background: black; + border-radius: 50% 50% 20% 20%; + color: white; + line-height: 20px; + letter-spacing: 2px; + font-size: 0.8em; + text-align: center; + position: absolute; + + margin-top: -20px; + margin-left: -10px; + width: 15px; + height: 15px; + animation: planeo 0.8s linear infinite; + z-index: 999; +} + +.pajaro:after, +.pajaro:before { + content: ""; + position: absolute; + top: 50%; + left: 50%; +} + +/*------------------------------------------------------ bird wings +*/ + +.pajaro:after { + border-radius: 100% 100% 0 0; + box-shadow: inset 0px 5px 0 black; + width: 100px; + height: 100px; + margin-top: -7px; + margin-left: -50px; + transform-origin: 100% 0%; + animation: alas 3s linear infinite; +} + +/*------------------------------------------------------ bird beak +*/ + +.pajaro:before { + background: #ffc37f; + border-radius: 100% 0% 20% 0%; + margin-top: 3px; + margin-left: -4px; + width: 6px; + height: 6px; + transform: rotateZ(45deg); +} + +/*------------------------------------------------------ wings animation +*/ + +@keyframes alas { + 50% { + transform: rotateX(-1440deg); + } +} + +/*------------------------------------------------------ bird animation +*/ + +@keyframes planeo { + 40% { + transform: rotateZ(2deg) translateX(2px) translateY(10px) translateZ(0); + line-height: 16px; + font-size: 0.6em; + } + 80% { + transform: rotateZ(-2deg) translateX(5px) translateY(8px) translateZ(0); + } +} diff --git a/Games/Memory_Game/img1.jpg b/Games/Memory_Game/img1.jpg new file mode 100644 index 0000000000..4308d81d46 Binary files /dev/null and b/Games/Memory_Game/img1.jpg differ diff --git a/Games/Memory_Game/index.html b/Games/Memory_Game/index.html index c67af2d854..ce390456dd 100644 --- a/Games/Memory_Game/index.html +++ b/Games/Memory_Game/index.html @@ -24,10 +24,10 @@

INSTRUCTIONS

-

1.Click on each block to turn it

-

2.Remember the position of each block image

-

3.click on another block and try to remember on which block have you seen the same image

-

4.Your Number of moves are counted

+

1. Click on each block to turn it

+

2. Remember the position of each block image

+

3. Click on another block and try to remember on which block have you seen the same image

+

4. Your Number of moves are counted

diff --git a/Games/Memory_Game/mind.jpeg b/Games/Memory_Game/mind.jpeg new file mode 100644 index 0000000000..479ca8962c Binary files /dev/null and b/Games/Memory_Game/mind.jpeg differ diff --git a/Games/Memory_Game/mind.png b/Games/Memory_Game/mind.png deleted file mode 100644 index cdb2396d78..0000000000 Binary files a/Games/Memory_Game/mind.png and /dev/null differ diff --git a/Games/Memory_Game/mind1.jpg b/Games/Memory_Game/mind1.jpg deleted file mode 100644 index a5c87ab806..0000000000 Binary files a/Games/Memory_Game/mind1.jpg and /dev/null differ diff --git a/Games/Memory_Game/script.js b/Games/Memory_Game/script.js index 346e06c589..32c76941a6 100644 --- a/Games/Memory_Game/script.js +++ b/Games/Memory_Game/script.js @@ -124,8 +124,14 @@ const matrixGenerator = (cardValues, size = 4) => { winCount += 1; //check if winCount ==half of cardValues if (winCount == Math.floor(cardValues.length / 2)) { - result.innerHTML = `

You Won

-

Moves: ${movesCount}

`; + result.innerHTML = `

You Won!!

`; + result.style.fontFamily = 'Arial, sans-serif'; // Change the font family + result.style.fontSize = '24px'; // Change the font size + result.style.fontWeight = 'bold'; // Change the font weight + //result.style.fontStyle = 'italic'; // Change the font style + result.style.color = 'white'; // Change the text color + + `

Moves: ${movesCount}

`; stopGame(); } } else { diff --git a/Games/Memory_Game/style.css b/Games/Memory_Game/style.css index 81687cb580..63bb5d2260 100644 --- a/Games/Memory_Game/style.css +++ b/Games/Memory_Game/style.css @@ -1,7 +1,6 @@ :root { - /* --color-green--light: #00c46a; */ - /* background-image: linear-gradient(135deg, #71FA32, #009DE0) ; */ - + --color-green--light: #00c46a; + background-color: linear-gradient(135deg, #71FA32, #009DE0); } * { @@ -9,18 +8,22 @@ margin: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; + overflow: hidden; } body { - background-image: url("./mind1.jpg"); + background-image:url(img1.jpg); /*changing bg image*/ + background-size: cover; } .wrapper { box-sizing: content-box; width: 26.87em; padding: 2.5em 3em; - - background-color: #0d614b; + /* margin: 0; */ + height: 90vh; + background-color: transparent; + /* background- */ position: absolute; transform: translate(-50%, -50%); left: 50%; @@ -34,7 +37,7 @@ body { width: 100%; display: grid; gap: 0.6em; - + } .stats-container { @@ -56,7 +59,7 @@ body { .card-before, .card-after { position: absolute; - border-radius: 5px; + border-radius: 2px; width: 100%; height: 100%; display: flex; @@ -68,8 +71,11 @@ body { } .card-before { - background-color: var(--color-green--light); - + background: rgba(203, 250, 255, 0.24); + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(2px); + -webkit-backdrop-filter: blur(2px); + border: 1px solid rgba(203, 250, 255, 0.26); font-size: 2.8em; font-weight: 600; } @@ -86,7 +92,7 @@ body { .card-container.flipped .card-after { transform: rotateY(0deg); -} +} .controls-container { position: absolute; @@ -96,7 +102,8 @@ body { flex-direction: column; width: 100%; height: 100%; - background-image: url("./mind.png"); + background-image: url("./mind.jpeg"); + background-size: cover; /* background-color: var(--color-green--light); */ top: 0; @@ -122,7 +129,7 @@ button { font-size: 1.3em; font-family: cursive; box-shadow: 0 0.6em 2em rgba(86, 66, 0, 0.2); - background-color: rgb(162, 162, 93); + background-color: transparent; } @@ -143,18 +150,71 @@ button { font-size: 1.8em; margin: 0.6em 0 1em 0; } -.menu{ +.menu { justify-content: center; } .instructions{ font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; - font-size: 10px; - background-color: aquamarine; - border-radius: 30px; - padding:45px; + font-size: 12px; + /* background-color: #ffffff; */ + box-shadow: 0 0.9em 2.8em rgba(86, 66, 0, 0.2); + /* color:#1479EA; */ + border: 1px solid white; + border-radius: 10px; + padding: 10px; + margin-bottom: 10px; } .instructions p{ - padding:25 25 25 25; + /* padding: 10px; */ + font-size: 12px; font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; +} + +/*adding button animation to start game and stop game buttons*/ +button { + width: 10em; + position: relative; + height: 3.5em; + border: 4px ridge #ffffff; + outline: none; + background-color: transparent; + color: rgb(190, 238, 255); + transition: 1s; + border-radius: 0.3em; + font-size: 16px; + font-weight: bold; + cursor: pointer; +} + +button::after { + content: ""; + position: absolute; + top: -10px; + left: 3%; + width: 95%; + height: 40%; + /* background-color: #212121; */ + transition: tranform ease-in .5s; + transform-origin: center; +} + +button::before { + content: ""; + transform-origin: center; + position: absolute; + top: 80%; + left: 3%; + width: 95%; + height: 40%; + /* background-color: #212121; */ + transition: transform ease-in 0.5s; +} + +button:hover::before, button:hover::after { + transform: scale(1.1); +} + +button:hover { + box-shadow: inset 0px 0px 25px #ffffff; } \ No newline at end of file diff --git a/Games/Tic_tac_toe_responsive/README.md b/Games/Tic_tac_toe_responsive/README.md new file mode 100644 index 0000000000..cee5495f23 --- /dev/null +++ b/Games/Tic_tac_toe_responsive/README.md @@ -0,0 +1,28 @@ +# **Game_Name** + +Tic Tac Toe + +
+ +## **Description 📃** +- Tic Tac Toe is a traditional 2 player game. Where players take turn one by one to mark a cell out of 9 + + +## **functionalities 🎮** +- If a player is able to mark 3 consecutive cells (horizontally/vertically/diagonally) then that player wins the game. +- If no player is able to mark 3 consecutive cells, then the game is a draw + +
+ +## **How to play? 🕹️** +- Firstly player X takes turn and clicks on a cell of their choice +- The cell is filled with an X +- Now player O will mark a cell and fills it by a O + +
+ +## **Screenshots 📸** + +
+[image](/Games/Tic_tac_toe_responsive/assets/images/Tic_tac_toe_responsive.png) + diff --git a/Games/Tic_tac_toe_responsive/assets/images/PointerBody.png b/Games/Tic_tac_toe_responsive/assets/images/PointerBody.png new file mode 100644 index 0000000000..f1ae84d5d5 Binary files /dev/null and b/Games/Tic_tac_toe_responsive/assets/images/PointerBody.png differ diff --git a/Games/Tic_tac_toe_responsive/assets/images/PointerHover.png b/Games/Tic_tac_toe_responsive/assets/images/PointerHover.png new file mode 100644 index 0000000000..0f63672839 Binary files /dev/null and b/Games/Tic_tac_toe_responsive/assets/images/PointerHover.png differ diff --git a/Games/Tic_tac_toe_responsive/assets/images/PointerText.png b/Games/Tic_tac_toe_responsive/assets/images/PointerText.png new file mode 100644 index 0000000000..b6545bf4f0 Binary files /dev/null and b/Games/Tic_tac_toe_responsive/assets/images/PointerText.png differ diff --git a/Games/Tic_tac_toe_responsive/assets/images/Tic_tac_toe_responsive.png b/Games/Tic_tac_toe_responsive/assets/images/Tic_tac_toe_responsive.png new file mode 100644 index 0000000000..c002f0e872 Binary files /dev/null and b/Games/Tic_tac_toe_responsive/assets/images/Tic_tac_toe_responsive.png differ diff --git a/Games/Tic_tac_toe_responsive/index.html b/Games/Tic_tac_toe_responsive/index.html new file mode 100644 index 0000000000..a610682d2d --- /dev/null +++ b/Games/Tic_tac_toe_responsive/index.html @@ -0,0 +1,63 @@ + + + + + + + Tic Tac Toe + + + + + + + +
+ +
+

Tic Tac Toe

+

The easiest one

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

+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/Games/Tic_tac_toe_responsive/script.js b/Games/Tic_tac_toe_responsive/script.js new file mode 100644 index 0000000000..87b81b32c2 --- /dev/null +++ b/Games/Tic_tac_toe_responsive/script.js @@ -0,0 +1,101 @@ +const cells = document.querySelectorAll('.cell'); +const display = document.querySelector('.display'); +let restart = document.querySelector('#restart'); + +display.innerText = "X's turn" +let count = 0; +let xTurn; + +const winCombinations = [ + [0, 1, 2], + [0, 3, 6], + [0, 4, 8], + [1, 4, 7], + [2, 5, 8], + [2, 4, 6], + [3, 4, 5], + [6, 7, 8], +]; + +const handleClick = (cell) => { + let curCell = cell.target; + count++; + + if (xTurn) { + curCell.innerText = 'X'; + display.innerText = "O's turn" + xTurn = false; + } + else { + curCell.innerText = 'O'; + display.innerText = "X's turn" + xTurn = true; + } + + if (count == 9) { + console.log(count); + checkDraw(); + return; + } + getWinner(); +} + +const startGame = () => { + xTurn = true; + + cells.forEach((element) => { + element.removeEventListener('click', handleClick); + element.addEventListener('click', handleClick, { once: true } // so that a cell can be clicked only once + ) + }) +} +startGame(); + + + +const showWinner = (winner) => { + display.innerText = `${winner} won 🍾`; +} + + +const getWinner = () => { + + for (let combinations of winCombinations) { + + const pos1 = cells[combinations[0]].innerText; + const pos2 = cells[combinations[1]].innerText; + const pos3 = cells[combinations[2]].innerText; + + if (pos1 != "", pos2 != "", pos3 != "") { + + if (pos1 === pos2 && pos2 === pos3) { + showWinner(pos1); + return true; + } + } + + } + return false; +} + + +const checkDraw = () => { + cells.forEach(cell => { + if (cell.innerText !== "" && !getWinner()) { + display.innerText = "Draw!🤝"; + } + }) +} + +const restartGame = () => { + cells.forEach(cell => { + cell.innerText = ""; + count = 0; + display.innerText = "X's turn" + startGame(); + + + }) +} + +restart.addEventListener('click', restartGame) \ No newline at end of file diff --git a/Games/Tic_tac_toe_responsive/style.css b/Games/Tic_tac_toe_responsive/style.css new file mode 100644 index 0000000000..ff11ccf393 --- /dev/null +++ b/Games/Tic_tac_toe_responsive/style.css @@ -0,0 +1,241 @@ +*{ + margin: 0; + padding: 0; + box-sizing: border-box; + outline: none; + font-family: 'whyte', Arial, Helvetica, sans-serif; +} + +body{ + background-color: #FFC700; + background-color: #C8B8FF; + display: flex; + flex-wrap: wrap; +} + + + +/* CURSORS */ +html{ + cursor: url('/Games/Tic_tac_toe_responsive/assets/images/PointerBody.png'), auto; +} + + i, .cell, footer a { + cursor: url('/Games/Tic_tac_toe_responsive/assets/images/PointerHover.png'), auto; +} + +.notch p, h3, input { + cursor: url('/Games/Tic_tac_toe_responsive/assets/images/PointerText.png'), auto; + +} + + + +/* PHONE UI */ +.phoneUi{ + border: 4px solid black; + width: 580px; + height: 80%; + border-radius: 30px; + background-color: white; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + text-align: center; +} + +.notch{ + width: 100%; + height: 10%; + color: black; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: 22px; + gap: 8px; +} + +.notch p { + color: grey; + font-size: 12px; +} + +/* SCREEN */ +.screen{ + width: 90%; + height: 80%; + padding: 0px 35px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + background-color: #2DD998; + border: 4px solid black; + color: black; + border-radius: 12px; + font-weight: bold; +} + + +.screenHeader { + display: flex; + justify-content: space-between; + align-items: center; + height: 20%; +} + + +.greenBars{ + width: 40%; + display: flex; + justify-content: start; + gap: 10px; +} + +.greenBars span { + border-radius: 12px; + border: 3px solid black; + width: 50%; + height: 22px; + } + +.circleDiv { + display: flex; + justify-content: space-around; + width: 100px; +} + +.circleDiv span { + width: 20px; + height: 20px; + border-radius: 12px; + border: 3px solid black; +} + +/* Display FIELD */ + +.displayDiv{ + height: 14%; + background-color: #699CF8; + border-radius: 15px; + border: 4px solid black; + display: flex; + justify-content: space-around; + align-items: center; + + +} + +.display{ + color: black; + width: 100%; + height: 100%; + padding: 20px; + font-size: 30px; + display: flex; + justify-content: center; + align-items: center; +} + +.displayDiv i { + position: absolute; + right: 100px; +} + + +/* MAIN CONTENT */ +.content{ + width: 100%; + overflow: auto; + height: 66%; + padding: 0px 10px; +} + +.gameBox{ + width: 100%; + height: 100%; + padding: 10px; + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; + gap: 8px; + +} +.cell{ + width: 30%; + height: 30%; + border: 4px solid black; + background-color: white; + border-radius: 10px; + font-size: 90px; + display: flex; + justify-content: center; + align-items: center; + font-family: cursive ,'whyte', Arial, Helvetica, sans-serif; +} + +footer{ + margin-top: 20px; +} + +footer a { + text-decoration: none; + cursor: pointer; +} + + +/* RESPONSIVE */ + + +@media (max-width: 648px) +{ + .phoneUi{ + width: 440px; + } + .cell{ + width: 80px; + height: 80px; + font-size: 70px; + } + + +} + + +@media (max-width: 475px) +{ + .screen{ + padding: 0px 10px; + } + .phoneUi{ + width: 340px; + } + .notch{ + font-size: 18px; + } + .notch p { + color: grey; + font-size: 10px; + } + .cell{ + width: 70px; + height: 70px; + font-size: 50px; + } + .displayDiv i { + right: 40px; + } + + +} + +@media (max-height: 500px) +{ + .notch h3 { + font-size: 14px; + } +} + diff --git a/Games/Tilting_Maze/index.html b/Games/Tilting_Maze/index.html index deca918994..d721528de9 100644 --- a/Games/Tilting_Maze/index.html +++ b/Games/Tilting_Maze/index.html @@ -8,13 +8,17 @@ Tilting Maze - - -
-
+ + + +
+ + + +
+ + +
@@ -31,6 +35,7 @@

Instructions:

Click the joystick to start!

Move every ball to the center. Ready for hard mode? Press H

+
@@ -38,4 +43,6 @@

Instructions:

How to simulate ball movement in a maze with JavaScript
- \ No newline at end of file + + + \ No newline at end of file diff --git a/Games/Tilting_Maze/script.js b/Games/Tilting_Maze/script.js index 89c9eba2af..f292d19c64 100644 --- a/Games/Tilting_Maze/script.js +++ b/Games/Tilting_Maze/script.js @@ -679,4 +679,10 @@ Math.minmax = (value, limit) => { gameInProgress = false; } else throw error; } - } \ No newline at end of file + } + const restartBtn = document.getElementById("restart-btn"); + + + restartBtn.addEventListener("click", function() { + resetGame(); + }); \ No newline at end of file diff --git a/Games/Tilting_Maze/style.css b/Games/Tilting_Maze/style.css index 918af7e892..626bb8e2e1 100644 --- a/Games/Tilting_Maze/style.css +++ b/Games/Tilting_Maze/style.css @@ -6,9 +6,9 @@ body { --joystick-head-color: #f06449; --ball-color: #f06449; --end-color: #7d82b8; - --text-color: #210124; - - font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; + --text-color: #210124; + font-size:100%; + font-family: "Roboto", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; background-color: var(--background-color); } @@ -265,4 +265,25 @@ a:visited { width: 300px; background-color: white; } -} \ No newline at end of file +} +#restart-btn { + background-color: var(--ball-color); + color: var(--background-color); + border: none; + border-radius: 5px; + padding: 10px 20px; + font-size: 1em; + cursor: pointer; + transition: background-color 0.3s, transform 0.3s; + display: block; +} + +#restart-btn:hover { + background-color: var(--end-color); + transform: scale(1.05); +} + +#restart-btn:active { + background-color: var(--joystick-head-color); + transform: scale(1); +} diff --git a/Games/Tower_Block_Game/README.md b/Games/Tower_Block_Game/README.md new file mode 100644 index 0000000000..d3e8dcc7a9 --- /dev/null +++ b/Games/Tower_Block_Game/README.md @@ -0,0 +1,46 @@ +# **Tower Block Game** + +--- + +
+ +## **Description 📃** + +- The Tower Block Game is an engaging and fun stacking game where players aim to stack blocks as high as possible without missing. The game uses 3D graphics and smooth animations to create an immersive experience. + +## **Functionalities 🎮** + +- Start a new game by clicking the "Start" button or pressing the spacebar. +- Stack blocks by clicking or pressing the spacebar. +- The game ends if a block is missed. +- View your current score during the game. +- Restart the game after it ends by clicking or pressing the spacebar. + +
+ +## **How to play? 🕹️** + +1. Open the game in your web browser. +2. Click the "Start" button or press the spacebar to begin. +3. As the block moves, click or press the spacebar to place it. +4. Try to align the blocks as closely as possible. +5. The game ends if a block is missed. +6. Click or press the spacebar to restart the game. + +
+ +## **Screenshots 📸** +
+ +![Tower_Block_Game](https://github.com/Saipradyumnagoud/GameZone/assets/143107589/955917b4-98e7-43c9-833d-96683546d58a) + + + +
+ +## **Working video 📹** + +https://github.com/Saipradyumnagoud/GameZone/assets/143107589/e0a6612d-2917-42a8-8a10-f1fbeddbf4ea + + + diff --git a/Games/Tower_Block_Game/index.html b/Games/Tower_Block_Game/index.html new file mode 100644 index 0000000000..6d78781f2a --- /dev/null +++ b/Games/Tower_Block_Game/index.html @@ -0,0 +1,28 @@ + + + + + + Tower Block Game + + + +
+
+
0
+
Click (or press the spacebar) to place the block
+
+

Game Over

+

You did great, you're the best.

+

Click or spacebar to start again

+
+
+
Start
+
+
+
+ + + + + diff --git a/Games/Tower_Block_Game/script.js b/Games/Tower_Block_Game/script.js new file mode 100644 index 0000000000..008fcb2986 --- /dev/null +++ b/Games/Tower_Block_Game/script.js @@ -0,0 +1,310 @@ + +console.clear(); +var Stage = /** @class */ (function () { + function Stage() { + // container + var _this = this; + this.render = function () { + this.renderer.render(this.scene, this.camera); + }; + this.add = function (elem) { + this.scene.add(elem); + }; + this.remove = function (elem) { + this.scene.remove(elem); + }; + this.container = document.getElementById('game'); + // renderer + this.renderer = new THREE.WebGLRenderer({ + antialias: true, + alpha: false + }); + this.renderer.setSize(window.innerWidth, window.innerHeight); + this.renderer.setClearColor('#D0CBC7', 1); + this.container.appendChild(this.renderer.domElement); + // scene + this.scene = new THREE.Scene(); + // camera + var aspect = window.innerWidth / window.innerHeight; + var d = 20; + this.camera = new THREE.OrthographicCamera(-d * aspect, d * aspect, d, -d, -100, 1000); + this.camera.position.x = 2; + this.camera.position.y = 2; + this.camera.position.z = 2; + this.camera.lookAt(new THREE.Vector3(0, 0, 0)); + //light + this.light = new THREE.DirectionalLight(0xffffff, 0.5); + this.light.position.set(0, 499, 0); + this.scene.add(this.light); + this.softLight = new THREE.AmbientLight(0xffffff, 0.4); + this.scene.add(this.softLight); + window.addEventListener('resize', function () { return _this.onResize(); }); + this.onResize(); + } + Stage.prototype.setCamera = function (y, speed) { + if (speed === void 0) { speed = 0.3; } + TweenLite.to(this.camera.position, speed, { y: y + 4, ease: Power1.easeInOut }); + TweenLite.to(this.camera.lookAt, speed, { y: y, ease: Power1.easeInOut }); + }; + Stage.prototype.onResize = function () { + var viewSize = 30; + this.renderer.setSize(window.innerWidth, window.innerHeight); + this.camera.left = window.innerWidth / -viewSize; + this.camera.right = window.innerWidth / viewSize; + this.camera.top = window.innerHeight / viewSize; + this.camera.bottom = window.innerHeight / -viewSize; + this.camera.updateProjectionMatrix(); + }; + return Stage; +}()); +var Block = /** @class */ (function () { + function Block(block) { + // set size and position + this.STATES = { ACTIVE: 'active', STOPPED: 'stopped', MISSED: 'missed' }; + this.MOVE_AMOUNT = 12; + this.dimension = { width: 0, height: 0, depth: 0 }; + this.position = { x: 0, y: 0, z: 0 }; + this.targetBlock = block; + this.index = (this.targetBlock ? this.targetBlock.index : 0) + 1; + this.workingPlane = this.index % 2 ? 'x' : 'z'; + this.workingDimension = this.index % 2 ? 'width' : 'depth'; + // set the dimensions from the target block, or defaults. + this.dimension.width = this.targetBlock ? this.targetBlock.dimension.width : 10; + this.dimension.height = this.targetBlock ? this.targetBlock.dimension.height : 2; + this.dimension.depth = this.targetBlock ? this.targetBlock.dimension.depth : 10; + this.position.x = this.targetBlock ? this.targetBlock.position.x : 0; + this.position.y = this.dimension.height * this.index; + this.position.z = this.targetBlock ? this.targetBlock.position.z : 0; + this.colorOffset = this.targetBlock ? this.targetBlock.colorOffset : Math.round(Math.random() * 100); + // set color + if (!this.targetBlock) { + this.color = 0x333344; + } + else { + var offset = this.index + this.colorOffset; + var r = Math.sin(0.3 * offset) * 55 + 200; + var g = Math.sin(0.3 * offset + 2) * 55 + 200; + var b = Math.sin(0.3 * offset + 4) * 55 + 200; + this.color = new THREE.Color(r / 255, g / 255, b / 255); + } + // state + this.state = this.index > 1 ? this.STATES.ACTIVE : this.STATES.STOPPED; + // set direction + this.speed = -0.1 - (this.index * 0.005); + if (this.speed < -4) + this.speed = -4; + this.direction = this.speed; + // create block + var geometry = new THREE.BoxGeometry(this.dimension.width, this.dimension.height, this.dimension.depth); + geometry.applyMatrix(new THREE.Matrix4().makeTranslation(this.dimension.width / 2, this.dimension.height / 2, this.dimension.depth / 2)); + this.material = new THREE.MeshToonMaterial({ color: this.color, shading: THREE.FlatShading }); + this.mesh = new THREE.Mesh(geometry, this.material); + this.mesh.position.set(this.position.x, this.position.y + (this.state == this.STATES.ACTIVE ? 0 : 0), this.position.z); + if (this.state == this.STATES.ACTIVE) { + this.position[this.workingPlane] = Math.random() > 0.5 ? -this.MOVE_AMOUNT : this.MOVE_AMOUNT; + } + } + Block.prototype.reverseDirection = function () { + this.direction = this.direction > 0 ? this.speed : Math.abs(this.speed); + }; + Block.prototype.place = function () { + this.state = this.STATES.STOPPED; + var overlap = this.targetBlock.dimension[this.workingDimension] - Math.abs(this.position[this.workingPlane] - this.targetBlock.position[this.workingPlane]); + var blocksToReturn = { + plane: this.workingPlane, + direction: this.direction + }; + if (this.dimension[this.workingDimension] - overlap < 0.3) { + overlap = this.dimension[this.workingDimension]; + blocksToReturn.bonus = true; + this.position.x = this.targetBlock.position.x; + this.position.z = this.targetBlock.position.z; + this.dimension.width = this.targetBlock.dimension.width; + this.dimension.depth = this.targetBlock.dimension.depth; + } + if (overlap > 0) { + var choppedDimensions = { width: this.dimension.width, height: this.dimension.height, depth: this.dimension.depth }; + choppedDimensions[this.workingDimension] -= overlap; + this.dimension[this.workingDimension] = overlap; + var placedGeometry = new THREE.BoxGeometry(this.dimension.width, this.dimension.height, this.dimension.depth); + placedGeometry.applyMatrix(new THREE.Matrix4().makeTranslation(this.dimension.width / 2, this.dimension.height / 2, this.dimension.depth / 2)); + var placedMesh = new THREE.Mesh(placedGeometry, this.material); + var choppedGeometry = new THREE.BoxGeometry(choppedDimensions.width, choppedDimensions.height, choppedDimensions.depth); + choppedGeometry.applyMatrix(new THREE.Matrix4().makeTranslation(choppedDimensions.width / 2, choppedDimensions.height / 2, choppedDimensions.depth / 2)); + var choppedMesh = new THREE.Mesh(choppedGeometry, this.material); + var choppedPosition = { + x: this.position.x, + y: this.position.y, + z: this.position.z + }; + if (this.position[this.workingPlane] < this.targetBlock.position[this.workingPlane]) { + this.position[this.workingPlane] = this.targetBlock.position[this.workingPlane]; + } + else { + choppedPosition[this.workingPlane] += overlap; + } + placedMesh.position.set(this.position.x, this.position.y, this.position.z); + choppedMesh.position.set(choppedPosition.x, choppedPosition.y, choppedPosition.z); + blocksToReturn.placed = placedMesh; + if (!blocksToReturn.bonus) + blocksToReturn.chopped = choppedMesh; + } + else { + this.state = this.STATES.MISSED; + } + this.dimension[this.workingDimension] = overlap; + return blocksToReturn; + }; + Block.prototype.tick = function () { + if (this.state == this.STATES.ACTIVE) { + var value = this.position[this.workingPlane]; + if (value > this.MOVE_AMOUNT || value < -this.MOVE_AMOUNT) + this.reverseDirection(); + this.position[this.workingPlane] += this.direction; + this.mesh.position[this.workingPlane] = this.position[this.workingPlane]; + } + }; + return Block; +}()); +var Game = /** @class */ (function () { + function Game() { + var _this = this; + this.STATES = { + 'LOADING': 'loading', + 'PLAYING': 'playing', + 'READY': 'ready', + 'ENDED': 'ended', + 'RESETTING': 'resetting' + }; + this.blocks = []; + this.state = this.STATES.LOADING; + this.stage = new Stage(); + this.mainContainer = document.getElementById('container'); + this.scoreContainer = document.getElementById('score'); + this.startButton = document.getElementById('start-button'); + this.instructions = document.getElementById('instructions'); + this.scoreContainer.innerHTML = '0'; + this.newBlocks = new THREE.Group(); + this.placedBlocks = new THREE.Group(); + this.choppedBlocks = new THREE.Group(); + this.stage.add(this.newBlocks); + this.stage.add(this.placedBlocks); + this.stage.add(this.choppedBlocks); + this.addBlock(); + this.tick(); + this.updateState(this.STATES.READY); + document.addEventListener('keydown', function (e) { + if (e.keyCode == 32) + _this.onAction(); + }); + document.addEventListener('click', function (e) { + _this.onAction(); + }); + document.addEventListener('touchstart', function (e) { + e.preventDefault(); + _this.onAction(); + // ?? this triggers after click on android so you + // insta-lose, will figure it out later. + }); + } + Game.prototype.updateState = function (newState) { + for (var key in this.STATES) + this.mainContainer.classList.remove(this.STATES[key]); + this.mainContainer.classList.add(newState); + this.state = newState; + }; + Game.prototype.onAction = function () { + switch (this.state) { + case this.STATES.READY: + this.startGame(); + break; + case this.STATES.PLAYING: + this.placeBlock(); + break; + case this.STATES.ENDED: + this.restartGame(); + break; + } + }; + Game.prototype.startGame = function () { + if (this.state != this.STATES.PLAYING) { + this.scoreContainer.innerHTML = '0'; + this.updateState(this.STATES.PLAYING); + this.addBlock(); + } + }; + Game.prototype.restartGame = function () { + var _this = this; + this.updateState(this.STATES.RESETTING); + var oldBlocks = this.placedBlocks.children; + var removeSpeed = 0.2; + var delayAmount = 0.02; + var _loop_1 = function (i) { + TweenLite.to(oldBlocks[i].scale, removeSpeed, { x: 0, y: 0, z: 0, delay: (oldBlocks.length - i) * delayAmount, ease: Power1.easeIn, onComplete: function () { return _this.placedBlocks.remove(oldBlocks[i]); } }); + TweenLite.to(oldBlocks[i].rotation, removeSpeed, { y: 0.5, delay: (oldBlocks.length - i) * delayAmount, ease: Power1.easeIn }); + }; + for (var i = 0; i < oldBlocks.length; i++) { + _loop_1(i); + } + var cameraMoveSpeed = removeSpeed * 2 + (oldBlocks.length * delayAmount); + this.stage.setCamera(2, cameraMoveSpeed); + var countdown = { value: this.blocks.length - 1 }; + TweenLite.to(countdown, cameraMoveSpeed, { value: 0, onUpdate: function () { _this.scoreContainer.innerHTML = String(Math.round(countdown.value)); } }); + this.blocks = this.blocks.slice(0, 1); + setTimeout(function () { + _this.startGame(); + }, cameraMoveSpeed * 1000); + }; + Game.prototype.placeBlock = function () { + var _this = this; + var currentBlock = this.blocks[this.blocks.length - 1]; + var newBlocks = currentBlock.place(); + this.newBlocks.remove(currentBlock.mesh); + if (newBlocks.placed) + this.placedBlocks.add(newBlocks.placed); + if (newBlocks.chopped) { + this.choppedBlocks.add(newBlocks.chopped); + var positionParams = { y: '-=30', ease: Power1.easeIn, onComplete: function () { return _this.choppedBlocks.remove(newBlocks.chopped); } }; + var rotateRandomness = 10; + var rotationParams = { + delay: 0.05, + x: newBlocks.plane == 'z' ? ((Math.random() * rotateRandomness) - (rotateRandomness / 2)) : 0.1, + z: newBlocks.plane == 'x' ? ((Math.random() * rotateRandomness) - (rotateRandomness / 2)) : 0.1, + y: Math.random() * 0.1 + }; + if (newBlocks.chopped.position[newBlocks.plane] > newBlocks.placed.position[newBlocks.plane]) { + positionParams[newBlocks.plane] = '+=' + (40 * Math.abs(newBlocks.direction)); + } + else { + positionParams[newBlocks.plane] = '-=' + (40 * Math.abs(newBlocks.direction)); + } + TweenLite.to(newBlocks.chopped.position, 1, positionParams); + TweenLite.to(newBlocks.chopped.rotation, 1, rotationParams); + } + this.addBlock(); + }; + Game.prototype.addBlock = function () { + var lastBlock = this.blocks[this.blocks.length - 1]; + if (lastBlock && lastBlock.state == lastBlock.STATES.MISSED) { + return this.endGame(); + } + this.scoreContainer.innerHTML = String(this.blocks.length - 1); + var newKidOnTheBlock = new Block(lastBlock); + this.newBlocks.add(newKidOnTheBlock.mesh); + this.blocks.push(newKidOnTheBlock); + this.stage.setCamera(this.blocks.length * 2); + if (this.blocks.length >= 5) + this.instructions.classList.add('hide'); + }; + Game.prototype.endGame = function () { + this.updateState(this.STATES.ENDED); + }; + Game.prototype.tick = function () { + var _this = this; + this.blocks[this.blocks.length - 1].tick(); + this.stage.render(); + requestAnimationFrame(function () { _this.tick(); }); + }; + return Game; +}()); +var game = new Game(); diff --git a/Games/Tower_Block_Game/styles.css b/Games/Tower_Block_Game/styles.css new file mode 100644 index 0000000000..713a97096d --- /dev/null +++ b/Games/Tower_Block_Game/styles.css @@ -0,0 +1,143 @@ +@import url("https://fonts.googleapis.com/css?family=Comfortaa"); +html, body { + margin: 0; + overflow: hidden; + height: 100%; + width: 100%; + position: relative; + font-family: 'Comfortaa', cursive; +} + +#container { + width: 100%; + height: 100%; +} +#container #score { + position: absolute; + top: 20px; + width: 100%; + text-align: center; + font-size: 10vh; + -webkit-transition: -webkit-transform 0.5s ease; + transition: -webkit-transform 0.5s ease; + transition: transform 0.5s ease; + transition: transform 0.5s ease, -webkit-transform 0.5s ease; + color: #333344; + -webkit-transform: translatey(-200px) scale(1); + transform: translatey(-200px) scale(1); +} +#container #game { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} +#container .game-over { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 85%; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +#container .game-over * { + -webkit-transition: opacity 0.5s ease, -webkit-transform 0.5s ease; + transition: opacity 0.5s ease, -webkit-transform 0.5s ease; + transition: opacity 0.5s ease, transform 0.5s ease; + transition: opacity 0.5s ease, transform 0.5s ease, -webkit-transform 0.5s ease; + opacity: 0; + -webkit-transform: translatey(-50px); + transform: translatey(-50px); + color: #333344; +} +#container .game-over h2 { + margin: 0; + padding: 0; + font-size: 40px; +} +#container .game-ready { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: distribute; + justify-content: space-around; +} +#container .game-ready #start-button { + -webkit-transition: opacity 0.5s ease, -webkit-transform 0.5s ease; + transition: opacity 0.5s ease, -webkit-transform 0.5s ease; + transition: opacity 0.5s ease, transform 0.5s ease; + transition: opacity 0.5s ease, transform 0.5s ease, -webkit-transform 0.5s ease; + opacity: 0; + -webkit-transform: translatey(-50px); + transform: translatey(-50px); + border: 3px solid #333344; + padding: 10px 20px; + background-color: transparent; + color: #333344; + font-size: 30px; +} +#container #instructions { + position: absolute; + width: 100%; + top: 16vh; + left: 0; + text-align: center; + -webkit-transition: opacity 0.5s ease, -webkit-transform 0.5s ease; + transition: opacity 0.5s ease, -webkit-transform 0.5s ease; + transition: opacity 0.5s ease, transform 0.5s ease; + transition: opacity 0.5s ease, transform 0.5s ease, -webkit-transform 0.5s ease; + opacity: 0; +} +#container #instructions.hide { + opacity: 0 !important; +} +#container.playing #score, #container.resetting #score { + -webkit-transform: translatey(0px) scale(1); + transform: translatey(0px) scale(1); +} +#container.playing #instructions { + opacity: 1; +} +#container.ready .game-ready #start-button { + opacity: 1; + -webkit-transform: translatey(0); + transform: translatey(0); +} +#container.ended #score { + -webkit-transform: translatey(6vh) scale(1.5); + transform: translatey(6vh) scale(1.5); +} +#container.ended .game-over * { + opacity: 1; + -webkit-transform: translatey(0); + transform: translatey(0); +} +#container.ended .game-over p { + -webkit-transition-delay: 0.3s; + transition-delay: 0.3s; +} \ No newline at end of file diff --git a/Games/Typing_Speed_Test2/README.md b/Games/Typing_Speed_Test2/README.md new file mode 100644 index 0000000000..94ec705dd4 --- /dev/null +++ b/Games/Typing_Speed_Test2/README.md @@ -0,0 +1,30 @@ +# **Game_Name** + +Typing Speed Test + +
+ +## **Description 📃** +- The game shows a random quote from a famous movie/series that has to be typed in a specified time limit, as fast as possible. A higher typing speed would show a higher WPM value. + + +## **functionalities 🎮** +- Space: jump to next word (if the word is incomplete it will mark it as incorrect) +- Backspace: delete previous letter or jump to previous word +- Start: to generate a new quote and reset the timer to 30 seconds +- WPM: Words Per Minutes +
+ +## **How to play? 🕹️** +- Click the Start button +- A 30 timer will start counting backwards +- A random quote will be generated +- Use your keyboard to enter the quote +- A word will be counted as correct only if it is completely correct +
+ +## **Screenshots 📸** + +
+[image](/Games/Typing_Speed_Test2/assets/images/Typing_Speed_Test2.png) + diff --git a/Games/Typing_Speed_Test2/assets/images/Typing_Speed_Test2.png b/Games/Typing_Speed_Test2/assets/images/Typing_Speed_Test2.png new file mode 100644 index 0000000000..732e39457e Binary files /dev/null and b/Games/Typing_Speed_Test2/assets/images/Typing_Speed_Test2.png differ diff --git a/Games/Typing_Speed_Test2/data.js b/Games/Typing_Speed_Test2/data.js new file mode 100644 index 0000000000..6338444f19 --- /dev/null +++ b/Games/Typing_Speed_Test2/data.js @@ -0,0 +1,22 @@ +const data = [ + "She did not tell them to clean up their lives, or go and sin no more. She did not tell them they were the blessed of the earth, its inheriting meek, or its glory-bound pure. She told them that the only grace they could have is the grace they could imagine. That if they could not see it, they could not have it.", + + + "If there is one thing Voldemort cannot understand, it is love. He didn't realize that love as powerful as your mother's for you leaves its own mark. Not a scar, no visible sign… to have been loved so deeply, even though the person who loved us is gone, will give us some protection forever. It is in your very own skin.", + + "It is a curious thing, Harry, but perhaps those who are best suited to power are those who have never sought it. Those who, like you, have leadership thrust upon them, and take up the mantle because they must, and find to their own surprise that they wear it well.", + + "In this world, everything is governed by balance. There's what you stand to gain and what you stand to lose. And when you think you've got nothing to lose, you become overconfident.", + + "There are moments in life we should just be able to have a damn remote control, so you could pause it. Even if just for five minutes. But sometimes things happen with irreverent obscenity and there's nothing you can do to help it.", + + "The bullet of an M16 shoots out at 2100 miles per hour. Faster than the speed of sound. So if they shot you in the heart, you won't even hear the bullet that killed you.", + + "We've always defined ourselves by the ability to overcome the impossible. And we count these moments. These moments when we dare to aim higher, to break barriers, to reach for the stars, to make the unknown known. We count these moments as our proudest achievements. But we lost all that.", + + "When I was a kid, it seemed like they made something new every day. Some, gadget or idea, like every day was Christmas. But 6 billion people, just imagine that. And every last one of them trying to have it all. This world isn't so bad.", + + "Sometimes, you read a book and it fills you with this weird evangelical zeal, and you become convinced that the shattered world will never be put back together unless and until all living humans read the book.", + + "It's estimated that human beings only use 10% of their brain's capacity. Imagine if we could access 100%. Interesting things begin to happen. With all this knowledge, you could unlock secrets that go beyond out limiters. I'm not even sure that mankind is ready for it." +]; diff --git a/Games/Typing_Speed_Test2/index.html b/Games/Typing_Speed_Test2/index.html new file mode 100644 index 0000000000..8332eda125 --- /dev/null +++ b/Games/Typing_Speed_Test2/index.html @@ -0,0 +1,44 @@ + + + + + + + Typing Speed + + + + + +

Test your Typing Speed

+ +
+
+
+
+ +
+ +
30
+
+
+
+

Rules

+

1) Once game starts you will get 30 seconds to write the given sentence

+
+

2) A word will be counted as correct only if it is completely correct

+
+

3) If you press space, it will skip to the next word (if the word is incomplete it will mark it as incorrect)

+
+

4) Backspace doesn't work on long press, you need to press it for each word

+
+
+ + + + + + + \ No newline at end of file diff --git a/Games/Typing_Speed_Test2/script.js b/Games/Typing_Speed_Test2/script.js new file mode 100644 index 0000000000..c9df860150 --- /dev/null +++ b/Games/Typing_Speed_Test2/script.js @@ -0,0 +1,228 @@ +const wordsDiv = document.querySelector('.words'); +const body = document.querySelector('body'); +const cursor = document.querySelector('.cursor'); +const button = document.querySelector('button'); +const timer = document.querySelector('.timer'); +const result = document.querySelector('.result'); +const gameTime = 30 * 1000; + + +// format each letter of a word +const formatWord = (word) => { + return ` +
${word.split('').join('')}
+ ` +} + +let addClass = (element, className) => { + element.className += ' ' + className; +} + +let removeClass = (element, className) => { + element.className = element.className.replace(className, ''); +} + + +const newGame = () => { + + // get a paragraph from the data + const words = `${data[Math.floor(Math.random() * data.length)]}` + + // to split all the words whenever space comes and return an array + const newWords = words.split(" "); + + wordsDiv.innerHTML = " "; + let counter = 30; + result.innerHTML = ''; + + + + newWords.forEach(element => { + wordsDiv.innerHTML += formatWord(element); + }); + + + const singleWord = document.querySelector('.singleWord'); + const letter = document.querySelector('.letter'); + + addClass(singleWord, 'current'); + addClass(letter, 'current'); + + const firstLetter = document.querySelector('.letter.current'); + cursor.style.top = firstLetter.getBoundingClientRect().top + 'px'; + cursor.style.left = firstLetter.getBoundingClientRect().left + 'px'; + + let countdownTimer = setInterval(() => { + counter--; + timer.textContent = counter; + + if (counter < 0) { + clearInterval(countdownTimer); + timer.textContent = "Time's up!"; + } + }, 1000); + + setTimeout(() => { + gameOver(); + }, gameTime); + + + // to focus on body, because it is focusing on the button + body.focus(); + +} + + +const gameOver = () => { + alert("Time's Up!"); + timer.innerHTML = `GAME OVER!` + result.innerHTML = `Your WPM: ${getWpm()}`; +} + + +const getWpm = () => { + + const words = [...document.querySelectorAll('.singleWord')]; + + const lastTypedWord = document.querySelector('.singleWord.current'); // the current element where game stopped + const lastTypedWordIndex = words.indexOf(lastTypedWord); + + const typedWords = words.slice(0, lastTypedWordIndex); + + + // to get all the words inside the typedWords array + const correctWords = typedWords.filter(word => { + + //get all letters in each word and make an array + const letters = [...word.children]; + const incorrectLetters = letters.filter(curletter => curletter.className.includes('incorrect')); + const correctLetters = letters.filter(curletter => curletter.className.includes('correct')); + + + return incorrectLetters.length === 0 && correctLetters.length === letters.length; + }); + + + return correctWords.length / gameTime * 60000; +} + + +const handleSpace = (expected, currentWord, currentLetter) => { + if (expected !== ' ') { + const lettersToInvalidate = [...document.querySelectorAll('.singleWord.current .letter:not(.correct)')]; + lettersToInvalidate.forEach(letter => { + addClass(letter, 'incorrect'); + }); + } + removeClass(currentWord, 'current'); + addClass(currentWord.nextElementSibling, 'current'); + + if (currentLetter) { + removeClass(currentLetter, 'current'); + } + addClass(currentWord.nextElementSibling.firstChild, 'current') +} + + +const handleBackspace = (currentLetter, isFirstLetter, currentWord) => { + // if backspace at start of next word + if (currentLetter && isFirstLetter) { + // make previous word current + removeClass(currentWord, 'current'); + addClass(currentWord.previousElementSibling, 'current'); + + // make last letter current + removeClass(currentLetter, 'current'); + addClass(currentWord.previousElementSibling.lastChild, 'current'); + + removeClass(currentWord.previousElementSibling.lastChild, 'incorrect'); + removeClass(currentWord.previousElementSibling.lastChild, 'correct'); + } + + // if backspace in middle of a word + if (currentLetter && !isFirstLetter) { + removeClass(currentLetter, 'current'); + addClass(currentLetter.previousElementSibling, 'current'); + + removeClass(currentLetter.previousElementSibling, 'incorrect'); + removeClass(currentLetter.previousElementSibling, 'correct'); + + } + + // if backspace at the end of a word + if (!currentLetter) //therefore expected = space + { + addClass(currentWord.lastChild, 'current'); + removeClass(currentWord.lastChild, 'incorrect'); + removeClass(currentWord.lastChild, 'correct'); + } +} + + +const moveCursor = () => { + const nextLetter = document.querySelector('.letter.current'); + const nextWord = document.querySelector('.singleWord.current'); + + if (nextLetter) { + cursor.style.top = nextLetter.getBoundingClientRect().top + 'px'; + cursor.style.left = nextLetter.getBoundingClientRect().left + 'px'; + } + //if next is space + else { + cursor.style.top = nextWord.getBoundingClientRect().top + 7 + 'px'; + cursor.style.left = nextWord.getBoundingClientRect().right + 'px'; + } +} + + +body.addEventListener('keyup', ev => { + const key = ev.key; + const currentWord = document.querySelector('.singleWord.current'); + const currentLetter = document.querySelector('.letter.current'); + + //if no currentLetter, then expected key will be space + const expected = currentLetter?.innerHTML || ' '; + + + //check whether the input is a letter or not + //if it's length is not equal to 1, it means it is 'Backspace' + //if key is empty ' ' it means it is the space key + const isLetter = key.length === 1 && key !== ' '; + const isSpace = key === ' '; + const isBackSpace = key === 'Backspace'; + const isFirstLetter = currentLetter === currentWord.firstChild; + + + + + if (isLetter) { + if (currentLetter) { + addClass(currentLetter, key === expected ? 'correct' : 'incorrect'); + removeClass(currentLetter, 'current'); + if (currentLetter.nextSibling) { + addClass(currentLetter.nextSibling, 'current'); + } + } + } + + // if key is SPACE + if (isSpace) { + handleSpace(expected, currentWord, currentLetter); + } + + // if key is BACKSPACE + if (isBackSpace) { + handleBackspace(currentLetter, isFirstLetter, currentWord); + } + + + // move cursor + moveCursor(); + + +}) + + +button.addEventListener('click', newGame); + + diff --git a/Games/Typing_Speed_Test2/style.css b/Games/Typing_Speed_Test2/style.css new file mode 100644 index 0000000000..dad53ae1c4 --- /dev/null +++ b/Games/Typing_Speed_Test2/style.css @@ -0,0 +1,112 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Roboto Mono', monospace; + background-color: #111; + color: white; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +h1 { + margin: 30px; +} + +.game { + margin: 30px; + line-height: 35px; + width: 40%; + color: gray; + position: relative; +} + +@keyframes blink { + 0% { + opacity: 1; + } + + 50% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +.cursor { + width: 2px; + height: 1.2rem; + background: white; + position: fixed; + top: 72px; + left: 27px; + animation: blink .7s infinite; +} + +.singleWord { + display: inline-block; +} + +.correct { + color: #fff; +} + +.incorrect { + color: #f55; +} + +.info { + gap: 10px; + display: flex; + justify-content: center; + align-items: center; + display: flex; + flex-direction: column; + +} + +.info button { + height: 40px; + width: 100px; + border-radius: 6px; + background-color: rgb(221, 0, 0); + background-color: orchid; + border: none; + cursor: pointer; +} + +.info button:hover { + background-color: rgb(201, 96, 197); +} + +.timer { + margin: 20px; + font-size: 20px; +} + +.result { + margin: 20px; + font-size: 20px; + color: orchid; + border: 2px solid orchid; + border-radius: 6px; + padding: 10px; +} + +.rules { + margin-top: 200px; + margin-bottom: 20px; + color: gray; + opacity: 0.7; +} + +.rules h3 { + margin-bottom: 30px; +} \ No newline at end of file diff --git a/Games/Virtual_Pet/README.md b/Games/Virtual_Pet/README.md index 39ca46fbc5..e84ae2cb17 100644 --- a/Games/Virtual_Pet/README.md +++ b/Games/Virtual_Pet/README.md @@ -1,4 +1,3 @@ - # Virtual Pet Virtual Pet is a simple and interactive game where players take care of a virtual pet by feeding, playing, and keeping it healthy. It's a fun way to test your virtual pet care skills! diff --git a/Games/Yahtzee/README.md b/Games/Yahtzee/README.md new file mode 100644 index 0000000000..03b49d37ee --- /dev/null +++ b/Games/Yahtzee/README.md @@ -0,0 +1,58 @@ +# **Yahtzee** +
+ +## **Description 📃** + +The object of the game is to roll certain combinations of numbers with five dice. At each turn you throw dice trying to get a good combination of numbers; different combinations give different scores. The game takes thirteen turns. + +## **Functionalities 🎮** + +**Roll the dice:** This is done by clicking `Roll` button on the top right corner. + +**Holding back dice:** The player can choose certain dice to hold their values during a reroll. This is done by clicking on the dice needed. + +**Chosing score:** By clicking on the scoring category label you need to keep. + +**Total score:** It keeps updating the total score, sum and bonus of each player. + +
+ +## **How to play? 🕹️** + +- Each round begins with the rolling of five dice. +- The player can choose certain dice to hold their values during a reroll. +- After the three rolls (or after the first or second roll if you choose to stop) you must find a place among the thirteen boxes in the scorecard to put your score. +- The score you get depends on the box that you choose and the combination that you have rolled. +- If the criterion for the chosen category is not met, a score of zero is recorded for that category. +- After a box is used, you can't use it again, so you have to choose wisely. +- The one with the higher score, at the end, wins. + +**Scoring:** +1. Ones: Sum of the ones displayed at time the score is entered. +2. Twos: Sum of the twos displayed at time the score is entered. +3. Threes: Sum of the threes displayed at time the score is entered. +4. Fours: Sum of the fours displayed at time the score is entered. +5. Fives: Sum of the fives displayed at time the score is entered. +6. Sixes: Sum of the sixes displayed at time the score is entered. +7. Three of a kind: Sum of all of the dice provided three of them are the same; zero otherwise. +8. Four of a kind: Sum of all of the dice provided four of them are the same; zero otherwise. +9. Full house: 25 points provided that one has three-of-a-kind and the other two dice are a pair (are the same). +10. Small straight: 30 points provided four of the dice have consecutive values; zero otherwise. +11. Large straight: 40 points provided all five dice have consecutive values; zero otherwise. +12. Yahtzee: 50 points provided all five dice have the same value; zero otherwise. +13. Chance: Sum of all of the dice. + +
+ +## **Screenshots 📸** + +![Yahtzee](/assets/images/Yahtzee.png) + +
+ +## **Working video 📹** + + +https://github.com/pankhuri92/GSSOC-GameZone/assets/animations/Yahtzee_video.mp4 + + diff --git a/Games/Yahtzee/index.html b/Games/Yahtzee/index.html new file mode 100644 index 0000000000..0ef90e13c9 --- /dev/null +++ b/Games/Yahtzee/index.html @@ -0,0 +1,135 @@ + + + + + + + Yahtzee + + + +

Yahtzee !

+
+ + +
+
+
+
Player 1
+
Player 2
+
+
+
Ones
+
+
+
+
+
Twos
+
+
+
+
+
Threes
+
+
+
+
+
Fours
+
+
+
+
+
Fives
+
+
+
+
+
Sixes
+
+
+
+
+
Sum
+
+
+
+
+
Bonus
+
+
+
+
+
Three of a kind
+
+
+
+
+
Four of a kind
+
+
+
+
+
Full House
+
+
+
+
+
Small straight
+
+
+
+
+
Large straight
+
+
+
+
+
Chance
+
+
+
+
+
Yahtzee
+
+
+
+
+
TOTAL SCORE
+
+
+
+
+ + +
+
+

Player 2

+
+
+
+ +
+
+

Player 1

+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + + \ No newline at end of file diff --git a/Games/Yahtzee/script.js b/Games/Yahtzee/script.js new file mode 100644 index 0000000000..910ad7226f --- /dev/null +++ b/Games/Yahtzee/script.js @@ -0,0 +1,571 @@ +// Initialize player scores and dice arrays +let player1Score=[]; +let player2Score=[]; +let player1Dice=[]; +let player2Dice=[]; +let rollCount=0; +let roundCount=0; +let onlyPossibleRow="blank"; +let jokerCard=false; +let isPlayerOneTurn=true; + +// Transform values for dice animation +let transformValues=[ +[0,30],[-5,40],[0,35],[5,40],[0,30] +]; + +// DOM element references +const player1Container=document.getElementById("player1Container"); +const player2Container=document.getElementById("player2Container"); +const diceElements=document.querySelectorAll(".dice"); +const rollButton = document.getElementById("roll"); +const scoreTableCells=document.querySelectorAll(".cell"); + +// Add event listener to the roll button +rollButton.addEventListener("click",rollDice); + +// Sound effect for rolling dice +let rollSound=new Audio("/assets/audio/Yahtzee_roll.wav"); +function rollDice() { + rollCount++; + let diceArr=[1,2,3,4,5]; + let randomDice=[]; + +// Generate random values for each die + for (let i=0;i0 && scoreTable[12]) { + yahtzeeScore=parseInt(yahtzeeElement.innerHTML)+100; + yahtzeeElement.innerHTML=yahtzeeScore; + } + +// Handle Yahtzee with Joker rule + if(yahtzeeScore>0 && scoreTable[dice[0]-1]!=undefined && scoreTable[12]!==undefined){ + jokerCard=true; + } + if(yahtzeeScore>0 && scoreTable[dice[0]-1]==undefined && scoreTable[12]!==undefined){ + onlyPossibleRow=dice[0]; + writeTempValueOnOnlyPossibleRaw(dice,playerNumber); + return; + } + //------------------------------------------------------------ + if (scoreTable[0] === undefined) { + let onesScore = calculateOnes(dice); + document.getElementById("ones" + playerNumber).innerHTML = onesScore; + } + if (scoreTable[1] === undefined) { + let twosScore = calculateTwos(dice); + document.getElementById("twos" + playerNumber).innerHTML = twosScore; + } + if (scoreTable[2] === undefined) { + let threesScore = calculateThrees(dice); + document.getElementById("threes" + playerNumber).innerHTML = threesScore; + } + if (scoreTable[3] === undefined) { + let foursScore = calculateFours(dice); + document.getElementById("fours" + playerNumber).innerHTML = foursScore; + } + if (scoreTable[4] === undefined) { + let fivesScore = calculateFives(dice); + document.getElementById("fives" + playerNumber).innerHTML = fivesScore; + } + if (scoreTable[5] === undefined) { + let sixesScore = calculateSixes(dice); + document.getElementById("sixes" + playerNumber).innerHTML = sixesScore; + } + if (scoreTable[6] === undefined) { + let threeOfAKindScore = calculateThreeOfAKind(dice); + document.getElementById("threeOfAKind" + playerNumber).innerHTML = + threeOfAKindScore; + } + if (scoreTable[7] === undefined) { + let fourOfAKindScore = calculateFourOfAKind(dice); + document.getElementById("fourOfAKind" + playerNumber).innerHTML = + fourOfAKindScore; + } + if (scoreTable[8] === undefined) { + let fullHouseScore = calculateFullHouse(dice); + document.getElementById("fullHouse" + playerNumber).innerHTML = + fullHouseScore; + } + if (scoreTable[9] === undefined) { + let smallStraightScore = jokerCard ? 30: calculateSmallStraight(dice); + document.getElementById("smallStraight" + playerNumber).innerHTML = + smallStraightScore; + } + if (scoreTable[10] === undefined) { + let largeStraightScore = jokerCard ? 40 : calculateLargeStraight(dice); + document.getElementById("largeStraight" + playerNumber).innerHTML = + largeStraightScore; + } + if (scoreTable[11] === undefined) { + let chanceScore = calculateChance(dice); + document.getElementById("chance" + playerNumber).innerHTML = chanceScore; + } +} + +function writeTempValueOnOnlyPossibleRaw(dice,playerNumber) { + if(dice[0]==1) { + let score=calculateOnes(dice); + document.getElementById("ones"+playerNumber).innerHTML=score; + } + if(dice[0]==2) { + let score=calculateTwos(dice); + document.getElementById("twos"+playerNumber).innerHTML=score; + } + if(dice[0]==3) { + let score=calculateThrees(dice); + document.getElementById("threes"+playerNumber).innerHTML=score; + } + if(dice[0]==4) { + let score=calculateFours(dice); + document.getElementById("fours"+playerNumber).innerHTML=score; + } + if(dice[0]==5) { + let score=calculateFives(dice); + document.getElementById("fives"+playerNumber).innerHTML=score; + } + if(dice[0]==6) { + let score=calculateSixes(dice); + document.getElementById("sixes"+playerNumber).innerHTML=score; + } +} + +scoreTableCells.forEach(function(cell){ + cell.addEventListener("click",onCellClick); +}); +function onCellClick(){ + let row=this.getAttribute("data-row"); + let column=this.getAttribute("data-column"); + if( + rollCount==0 || + row===null ||(onlyPossibleRow!="blank" && row!=onlyPossibleRow) + ) return; + if(isPlayerOneTurn && column==1){ + player1Score[row-1]=parseInt(this.innerHTML); + let upperSectionScore1=calculateUpperSection(player1Score); + let bonusScore1=upperSectionScore1>63 ? 35 : 0; + let lowerSectionScore1=calculateLowerSectionScore(player1Score); + let totalScore1=upperSectionScore1+lowerSectionScore1+bonusScore1; + sum1.innerHTML=upperSectionScore1; + bonus1.innerHTML=bonusScore1; + total1.innerHTML=totalScore1; + this.removeEventListener("click",onCellClick); + this.style.color="white"; + sum1.style.color="white"; + bonus1.style.color="white"; + total1.style.color="white"; + changeTurn(); + } + if(!isPlayerOneTurn && column==2){ + player2Score[row-1]=parseInt(this.innerHTML); + let upperSectionScore2=calculateUpperSection(player2Score); + let bonusScore2=upperSectionScore2>63 ? 35 : 0; + let lowerSectionScore2=calculateLowerSectionScore(player2Score); + let totalScore2=upperSectionScore2+lowerSectionScore2+bonusScore2; + sum2.innerHTML=upperSectionScore2; + bonus2.innerHTML=bonusScore2; + total2.innerHTML=totalScore2; + this.removeEventListener("click",onCellClick); + this.style.color="white"; + sum2.style.color="white"; + bonus2.style.color="white"; + total2.style.color="white"; + changeTurn(); + } +} + +function changeTurn(){ + roundCount++; + updateScoreTable(); + resetDiceFaces(); + isPlayerOneTurn=!isPlayerOneTurn; + rollCount=0; + if(isPlayerOneTurn){ + const player2ContainerDice=player2Container.querySelectorAll(".dice"); + player2ContainerDice.forEach((diceElement)=> { + diceElement.style.transform="none"; + player2Container.removeChild(diceElement); + player1Container.appendChild(diceElement); + }); + }else { + const player1ContainerDice=player1Container.querySelectorAll(".dice"); + player1ContainerDice.forEach((diceElement)=> { + diceElement.style.transform="none"; + player1Container.removeChild(diceElement); + player2Container.appendChild(diceElement); + }); +} + if(roundCount==26) { + calculateEndGameScore(); + return; + } + rollButton.disabled=false; + rollButton.style.opacity=1; +} +function updateScoreTable(){ + let scoreTable=[]; + scoreTable=player1Score.slice(); + let column =1 ; + if(!isPlayerOneTurn) { + scoreTable=[]; + scoreTable=player2Score.slice(); + column=2; + } + let scoreCells=document.querySelectorAll('[data-column="'+column+'"]'); + for (let i=0;iplayer2Total ? "Player 1 Wins" : "Player 2 Wins"; + document.getElementById("endGameMessage").innerHTML=endGameMessage; + rollButton.disabled=true; + rollButton.style.opacity=0.5; + +} + + + + + + +//-------------------------------------------------------------- +function calculateOnes(dice) { + let score=0; + for (let i=0;i=3) { + score=dice.reduce((acc,val)=>acc+val); + break; + } + } + return score; +} +function calculateFourOfAKind(dice) { + let score=0; + for(let i=0;i=4) { + score=dice.reduce((acc,val)=>acc+val); + break; + } + } + return score; +} +function calculateFullHouse(dice) { + let score=0; + let diceCopy=dice.slice(); + diceCopy.sort(); + if( + (diceCopy[0]==diceCopy[1] && + diceCopy[1]==diceCopy[2] && + diceCopy[3]==diceCopy[4] + ) || + (diceCopy[0]==diceCopy[1] && + diceCopy[2]==diceCopy[3] && + diceCopy[3]==diceCopy[4] + ) + ) { + score=25; + return score; + } + return score; +} +function calculateSmallStraight(dice) { + let score=0; + let diceCopy=[...new Set(dice)]; + diceCopy.sort(); + if( + (diceCopy[1]==diceCopy[0]+1 && + diceCopy[2]==diceCopy[1]+1 && + diceCopy[3]==diceCopy[2] +1 + ) || + (diceCopy[2]==diceCopy[1]+1 && + diceCopy[3]==diceCopy[2]+1 && + diceCopy[4]==diceCopy[3] +1 + ) + ) { + score=30; + } + return score; +} +function calculateLargeStraight(dice) { + let score=0; + let diceCopy=[...new Set(dice)]; + diceCopy.sort(); + if( + (diceCopy[1]==diceCopy[0]+1 && + diceCopy[2]==diceCopy[1]+1 && + diceCopy[3]==diceCopy[2] +1 && + diceCopy[4]==diceCopy[3] +1 + ) + ) { + score=40; + } + return score; +} +function calculateUpperSection(playerScore){ + let score=0; + let ones=playerScore[0]==undefined ? 0 : playerScore[0]; + let twos=playerScore[1]==undefined ? 0 : playerScore[1]; + let threes=playerScore[2]==undefined ? 0 : playerScore[2]; + let fours=playerScore[3]==undefined ? 0 : playerScore[3]; + let fives=playerScore[4]==undefined ? 0 : playerScore[4]; + let sixes=playerScore[5]==undefined ? 0 : playerScore[5]; + score=ones+twos+threes+fours+fives+sixes; + return score; +} +function calculateLowerSectionScore(playerScore){ + let lowerSectionScore=0; + let threeOfAKind=playerScore[6]===undefined ? 0 : playerScore[6]; + let fourOfAKind=playerScore[7]===undefined ? 0 : playerScore[7]; + let fullHouse=playerScore[8]===undefined ? 0 : playerScore[8]; + let smallStraight=playerScore[9]===undefined ? 0 : playerScore[9]; + let largeStraight=playerScore[10]===undefined ? 0 : playerScore[10]; + let chance=playerScore[11]===undefined ? 0 : playerScore[11]; + let yahtzee=playerScore[12]===undefined ? 0 : playerScore[12]; + if(yahtzee>0) { + playerNumber=isPlayerOneTurn ? 1 : 2; + yahtzee=parseInt(document.getElementById("yahtzee"+playerNumber).innerHTML); + } + lowerSectionScore=threeOfAKind+fourOfAKind+fullHouse+smallStraight+largeStraight + + chance+yahtzee; + return lowerSectionScore; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Games/Yahtzee/style.css b/Games/Yahtzee/style.css new file mode 100644 index 0000000000..ad82c5ed00 --- /dev/null +++ b/Games/Yahtzee/style.css @@ -0,0 +1,155 @@ +/* Set the background for the entire HTML document to a gradient and set the text color to white */ +html{ + background: linear-gradient(to bottom, #280058, #4d1591, #6834a7,#7d47be ); + color: white; + } + +h2{ + display: flex; + justify-content: center; + font-size: 2.7rem; + margin-bottom: 2vh; + margin-top: 3vh; + font-family:Georgia, 'Times New Roman', Times, serif; +} + +/* Style the main game container */ + #gameContainer{ + display: flex; + width:100%; + height: 100%; + margin-top: 2vh; + align-content: center; + justify-content: center; + } + /* Style the score tables */ + .table { + display: table; + width:30%; + background: linear-gradient(to bottom,rgb(2, 81, 155), rgb(25, 114, 197), rgb(52, 158, 239)); + cursor:pointer; + font-family:'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; + font-size: 2rem; + margin: 30px; + } + .header { + display: table-header-group; + background-color: rgb(2, 81, 155); + } + .header-cell { + display: table-cell; + padding:7px; + text-align: center; + width: 20%; + border-color: white; + border: 4px outset; + font-size: 1.1rem; + } + .row { + display: table-row; + } + + /* Add styles for the last row in the table */ + .row:last-child{ + font-size: 18px; + font-weight: bold; + border-top: 2px outset white; + } + .cell { + display: table-cell; + border: 3px outset; + padding: 7px; + text-align: center; + width:20%; + border-color: rgb(255, 255, 255); + font-size: 1.1rem; + } + + /* Style the first cell in each row */ + .cell:first-child { + width:60%; + text-align: left; + color: rgb(255, 255, 255); + font-weight: bold; + } + #totalCaption { + font-size: 18px; + } + #bonusCaption { + border-bottom: 2px solid rgb(4,83,83); + } + #sumCaption { + border-top: 2px solid rgb(4,83,83); + } + #bonusCaption > *,#sumCaption > * { + font-weight: bold; + } + + #board{ + width:60%; + min-height: 80%; + margin: 20px; + border: 6px ridge #e7e7e7; + background: radial-gradient( rgb(237, 171, 167), rgb(242, 149, 144), rgb(243, 123, 116)); + background-blend-mode: darken; + } + #playArea { + min-height: 80%; + display: flex; + justify-content: flex-end; + border-top: 6px ridge #e7e7e7; + border-bottom: 6px ridge #e7e7e7; + } + .dice-container { + height: 9.4%; + display: flex; + align-items: center; + justify-content: center; + gap:2%; + background: linear-gradient(to bottom, #cd0473, #e655a5); + margin-top: auto; + font-family: Georgia, 'Times New Roman', Times, serif; + font-size: 1.2rem; + } + .dice { + max-width: 40px; + max-height: 40px; + border-radius: 10px; + transition: all 0.4s linear; + z-index: 1000; + } + .face { + width:100%; + height: 100%; + cursor: pointer; + transition: all 0.4s linear; + } + .face:hover { + transform: scale(1.1); + } + #endGameMessage { + align-self: center; + color: white; + font-size: 80px; + width:100%; + text-align: center; + transform: translateX(5%); + font-family: Georgia, 'Times New Roman', Times, serif; + } + #roll { + width:5.7rem; + height:5.7rem; + border-radius: 100%; + border:transparent; + align-self:baseline; + color: whitesmoke; + font-weight: bold; + font-family: Georgia, 'Times New Roman', Times, serif; + background-image: url("/assets/images/Yahtzee_button.png"); + background-size: cover; + cursor: pointer; + background-color: rgb(243, 123, 116); + } + #roll:hover { + transform: scale(1.1); + } \ No newline at end of file diff --git a/Games/snake/README.md b/Games/snake/README.md new file mode 100644 index 0000000000..d691f36bc7 --- /dev/null +++ b/Games/snake/README.md @@ -0,0 +1,23 @@ +# Snake Game + +This is a simple Snake Game implemented in HTML CSS and JavaScript. + +## How to Play + +- Use the arrow keys to control the snake's direction. +- Eat the red food blocks to grow the snake and increase your score. +- Avoid colliding with the walls or the snake itself. + + +## Development + +To run the game locally: + +1. Clone this repository. +2. Open `index.html` in your browser. + +## Acknowledgements + +- The Snake Game logic is inspired by classic snake games. +- CSS styles for the game layout are defined in `styles.css`. + diff --git a/Games/snake/index.html b/Games/snake/index.html new file mode 100644 index 0000000000..fa8181fdc1 --- /dev/null +++ b/Games/snake/index.html @@ -0,0 +1,13 @@ + + + + + + Snake Game + + + + + + + diff --git a/Games/snake/script.js b/Games/snake/script.js new file mode 100644 index 0000000000..c459740d25 --- /dev/null +++ b/Games/snake/script.js @@ -0,0 +1,96 @@ +const canvas = document.getElementById("gameCanvas"); +const ctx = canvas.getContext("2d"); +const gridSize = 20; +let snake = [{x: 10, y: 10}]; +let food = {x: 15, y: 15}; +let dx = 0; +let dy = 0; +let score = 0; +let gameInterval; + +document.addEventListener("keydown", changeDirection); + +function changeDirection(event) { + const keyPressed = event.key; + if (keyPressed === "ArrowUp" && dy === 0) { + dx = 0; + dy = -1; + } else if (keyPressed === "ArrowDown" && dy === 0) { + dx = 0; + dy = 1; + } else if (keyPressed === "ArrowLeft" && dx === 0) { + dx = -1; + dy = 0; + } else if (keyPressed === "ArrowRight" && dx === 0) { + dx = 1; + dy = 0; + } +} + +function drawSnake() { + ctx.fillStyle = "#000"; + snake.forEach((segment) => { + ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize); + }); +} + +function drawFood() { + ctx.fillStyle = "#ff0000"; + ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize); +} + +function moveSnake() { + const head = {x: snake[0].x + dx, y: snake[0].y + dy}; + snake.unshift(head); + if (head.x === food.x && head.y === food.y) { + score++; + createFood(); + } else { + snake.pop(); + } +} + +function createFood() { + food.x = Math.floor(Math.random() * (canvas.width / gridSize)); + food.y = Math.floor(Math.random() * (canvas.height / gridSize)); +} + +function drawScore() { + ctx.fillStyle = "#000"; + ctx.font = "20px Arial"; + ctx.fillText("Score: " + score, 10, 25); +} + +function draw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawSnake(); + drawFood(); + drawScore(); + moveSnake(); + + if (checkCollision()) { + gameOver(); + return; + } +} + +function checkCollision() { + const head = snake[0]; + return ( + head.x < 0 || + head.x >= canvas.width / gridSize || + head.y < 0 || + head.y >= canvas.height / gridSize || + snake.slice(1).some(segment => segment.x === head.x && segment.y === head.y) + ); +} + +function gameOver() { + clearInterval(gameInterval); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "#000"; + ctx.font = "30px Arial"; + ctx.fillText("Game Over!", canvas.width / 2 - 100, canvas.height / 2); +} + +gameInterval = setInterval(draw, 100); diff --git a/Games/snake/style.css b/Games/snake/style.css new file mode 100644 index 0000000000..2228ef5329 --- /dev/null +++ b/Games/snake/style.css @@ -0,0 +1,17 @@ +body { + margin: 0; + padding: 0; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background-color: #f0f0f0; +} + +.game-container { + position: relative; +} + +#gameCanvas { + border: 1px solid #000; +} diff --git a/README.md b/README.md index dda30015af..4085fddcc0 100644 --- a/README.md +++ b/README.md @@ -108,8 +108,8 @@ This repository also provides one such platforms where contributers come over an | Game | Game | Game | Game | Game | -| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | -| [Master Typing](https://github.com/kunjgit/GameZone/tree/main/Games/Master_Typing) | [Treasure Hunt](https://github.com/Antiquely3059/GameZone/tree/main/Games/Treasure%20Hunt) | [Virtual Pet](https://github.com/Antiquely3059/GameZone/tree/main/Games/Virtual_Pet) | [MazeRunner](https://github.com/kunjgit/GameZone/tree/main/Games/MazeRunner) | [Ping_Pong_Singleplayer](https://github.com/kunjgit/GameZone/tree/main/Games/Ping_Pong_Singleplayer) | | +| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | --- | +| [Master Typing](https://github.com/kunjgit/GameZone/tree/main/Games/Master_Typing) | [Treasure Hunt](https://github.com/Antiquely3059/GameZone/tree/main/Games/Treasure%20Hunt) | [Virtual Pet](https://github.com/Antiquely3059/GameZone/tree/main/Games/Virtual_Pet) | [MazeRunner](https://github.com/kunjgit/GameZone/tree/main/Games/MazeRunner) | [Ping_Pong_Singleplayer](https://github.com/kunjgit/GameZone/tree/main/Games/Ping_Pong_Singleplayer) | | | [Tilting Maze](https://github.com/kunjgit/GameZone/tree/main/Games/Tilting_Maze) | [Simon Game Challenge](https://github.com/kunjgit/GameZone/tree/main/Games/Simon_Game_Challenge) | [Snake Game](https://github.com/kunjgit/GameZone/tree/main/Games/Snake_Game) | [Dino Runner Game](https://github.com/kunjgit/GameZone/tree/main/Games/Dino_Runner_Game) | | [Whack a Mole](https://github.com/kunjgit/GameZone/tree/main/Games/Whack_a_Mole) | [Doraemon Jump](https://github.com/kunjgit/GameZone/tree/main/Games/Doraemon_Jump) | [Black Jack](https://github.com/kunjgit/GameZone/tree/main/Games/Black_Jack) | [Memory Game](https://github.com/kunjgit/GameZone/tree/main/Games/Memory_Game) | [Word Guessing Game](https://github.com/kunjgit/GameZone/tree/main/Games/Word_Guessing_Game) | | [Ludo Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ludo_Game) | [Piano Game](https://github.com/kunjgit/GameZone/tree/main/Games/Piano) | [Atari Breakout](https://github.com/kunjgit/GameZone/tree/main/Games/Atari_Breakout) | [Dinosaur Game](https://github.com/kunjgit/GameZone/tree/main/Games/Chrome_Dinosaur_Game) | [Guess The Colour by RGB Game](https://github.com/kunjgit/GameZone/tree/main/Games/Colour_Guessing_Game) | @@ -120,7 +120,7 @@ This repository also provides one such platforms where contributers come over an | [Word Scramble Game](https://github.com/kunjgit/GameZone/tree/main/Games/Word_Scramble_Game) | [Tetris](https://github.com/kunjgit/GameZone/tree/main/Games/Tetris) | [Interactive Quizzing Application](https://github.com/kunjgit/GameZone/tree/main/Games/Interactive_Quizzing) | [Planet Defense Game](https://github.com/kunjgit/GameZone/tree/main/Games/Planet_Defense) | [Rabbit Rush Game](https://github.com/kunjgit/GameZone/tree/main/Games/Rabbit_Rush) | | [Wordle](https://github.com/kunjgit/GameZone/tree/main/Games/Wordle) | [Roll Race Game](https://github.com/kunjgit/GameZone/tree/main/Games/Roll_Race) | [Menja Game](https://github.com/kunjgit/GameZone/tree/main/Games/Menja) | [Typing Speed Test Game](https://github.com/kunjgit/GameZone/tree/main/Games/Typing_Speed_Test_Game) | [Tile Game](https://github.com/kunjgit/GameZone/tree/main/Games/Tile_Game) | | [Stick Hero Game](https://github.com/kunjgit/GameZone/tree/main/Games/Stick_Hero_Game) | [Starwars Character Game](https://github.com/kunjgit/GameZone/tree/main/Games/Starwars_Character_Game) | [Traffic Run](https://github.com/kunjgit/GameZone/tree/main/Games/Traffic_Run) | [Love Result Predictor](https://github.com/kunjgit/GameZone/tree/main/Games/Love_Result_Predictor) | [Tower Defense](https://github.com/kunjgit/GameZone/tree/main/Games/Tower_Defense) | -[Menja_block_breaker](https://github.com/kunjgit/GameZone/tree/main/Games/Menja_block_breaker) | +| [Menja_block_breaker](https://github.com/kunjgit/GameZone/tree/main/Games/Menja_block_breaker) | | [Yahtzee](https://github.com/kunjgit/GameZone/tree/main/Games/Yahtzee) | | [Bird Game](https://github.com/kunjgit/GameZone/tree/main/Games/Bird_game) | [Bubble Blast Game](https://github.com/kunjgit/GameZone/tree/main/Games/Bubble_Blast_Game) | [Emoji Charades](https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_Charades) | [Drum And Kit](https://github.com/kunjgit/GameZone/tree/main/Games/Drum_Kit_Game) | [Rock Paper Scissors](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_Paper_Scissors) | | [Frogger](https://github.com/kunjgit/GameZone/tree/main/Games/Frogger) | [!morethan5 ](https://github.com/kunjgit/GameZone/tree/main/Games/Not_morethan5) | [Unruly Tower](https://github.com/kunjgit/GameZone/tree/main/Games/Unruly_Tower) | [Maze Game](https://github.com/kunjgit/GameZone/tree/main/Games/MazeGame) | [Connect4](https://github.com/kunjgit/GameZone/tree/main/Games/Connect4) | | [Spelling_Bee](https://github.com/kunjgit/GameZone/tree/main/Games/Spelling_Bee) | [2048](https://github.com/kunjgit/GameZone/tree/main/Games/2048) | [Spin the Wheel](https://github.com/kunjgit/GameZone/tree/main/Games/Spin_the_wheel) | [Breakout](https://github.com/kunjgit/GameZone/tree/main/Games/Breakout) | [Tower Blocks](https://github.com/kunjgit/GameZone/tree/main/Games/Tower_Blocks) | @@ -154,6 +154,7 @@ This repository also provides one such platforms where contributers come over an | [Mastermind_Mania](https://github.com/kunjgit/GameZone/tree/main/Games/Mastermind_Mania) | [Ludo_4_Player](https://github.com/kunjgit/GameZone/tree/main/Games/Ludo_4_Player) | [AirBalloon](https://github.com/kunjgit/GameZone/tree/main/Games/AirBalloon) | [Space Invaders](https://github.com/kunjgit/GameZone/tree/main/Games/Space_Invaders) | [Cut the Rope](https://github.com/kunjgit/GameZone/tree/main/Games/Cut_the_rope) | | [Caesar&Cipher](https://github.com/kunjgit/GameZone/tree/main/Games/Caesar_Cipher) | [Monster_Maker](https://github.com/kunjgit/GameZone/tree/main/Games/Monster_Maker) | [Stolen Sword](https://github.com/kunjgit/GameZone/tree/main/Games/Stolen_Sword) | [Mastermind](https://github.com/kunjgit/GameZone/tree/main/Games/Mastermind) | [Highway 404](https://github.com/kunjgit/GameZone/tree/main/Games/Highway_404) | | [BullseyeGame](https://github.com/kunjgit/GameZone/tree/main/Games/BullseyeGame) | [Crossword Game](https://github.com/kunjgit/GameZone/tree/main/Games/Crossword_Game) | [Guess the Correct Logo](https://github.com/shruti-2412/GameZone/tree/main/Games/Guess_The_Correct_Logo) | [Painting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Painting_Game) | [Platform_game_engine](https://github.com/kunjgit/GameZone/tree/main/Games/Platform_game_engine) | +| [Kill_The_Bird](https://github.com/kunjgit/GameZone/tree/main/Games/Kill_The_Bird) | | [Doppelkopf](https://github.com/kunjgit/GameZone/tree/main/Games/Doppelkopf) | [quiz_game](https://github.com/kunjgit/GameZone/tree/main/Games/quiz_game) | [Island Survival](https://github.com/kunjgit/GameZone/tree/main/Games/Island_Survival) | [Linkup Game](https://github.com/kunjgit/GameZone/tree/main/Games/linkup) | [Trivia_Card](https://github.com/kunjgit/GameZone/tree/main/Games/Trivia_Card) | | [Insect Catch Game](https://github.com/kunjgit/GameZone/tree/main/Games/Insect_Catch_Game) | [Carnival_game](https://github.com/kunjgit/GameZone/tree/main/Games/Carnival_game) | [Make Me Laugh](https://github.com/kunjgit/GameZone/tree/main/Games/Make_Me_Laugh) | [Avoider_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Avoider_Game) | [Dungeon_Crawler](https://github.com/kunjgit/GameZone/tree/main/Games/Dungeon_Crawler) | | [snake_water_gun](https://github.com/kunjgit/GameZone/tree/main/Games/snake_water_gun) | [Run and Jump](https://github.com/kunjgit/GameZone/tree/main/Games/Run_and_Jump) | [AI CHESS Game](https://github.com/kunjgit/GameZone/tree/main/Games/AI_CHESS_Game) | [Fruit_Catching](https://github.com/kunjgit/GameZone/tree/main/Games/Fruit_Catching) | [Bulls eye](https://github.com/kunjgit/GameZone/tree/main/Games/Bulls_eye) | @@ -188,11 +189,9 @@ This repository also provides one such platforms where contributers come over an | [CSS Select](https://github.com/kunjgit/GameZone/tree/main/Games/CSS_Select) | [Squid](https://github.com/kunjgit/GameZone/tree/main/Games/Squid_Game) | [Flip Coin](https://github.com/kunjgit/GameZone/tree/main/Games/Flip_Coin) | [Witty Word Quest](https://github.com/kunjgit/GameZone/tree/main/Games/witty_word_quest) | [Typing Game](https://github.com/Ishan-77/GameZone/tree/main/Games/Typing_Game) | | [numeral-whiz](https://github.com/Ishan-77/GameZone/tree/main/Games/numeral-whiz) | [candy_match](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Match_Saga) | [Crossy_Road](https://github.com/tanujbordikar/GameZone/tree/Crossy_Road) | [HueHero](https://github.com/kunjgit/GameZone/tree/main/Games/HueHero) | [Puzzel_Winner](https://github.com/kunjgit/GameZone/tree/main/Games/Puzzel_Winner) | | [Emoji_Intruder](https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_Intruder) | [Guess The Weapon](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Weapon) | [Guess Who](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_Who) | [Pop My Balloon](https://github.com/kunjgit/GameZone/tree/main/Games/Pop_My_Balloon) | [Color_Blast](https://github.com/kunjgit/GameZone/tree/main/Games/Color_Blast) | -| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Coloron](https://github.com/kunjgit/GameZone/tree/main/Games/Coloron). | -| [Black_jackk](https://github.com/kunjgit/GameZone/tree/main/Games/Black_jackk) | [Atlas_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Atlas_Game) | | -| [Emoji_Intruder](https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_Intruder) | [Guess The Weapon](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Weapon) | [Guess Who](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_Who) | | | -| [Emoji_Intruder](https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_Intruder) | [Guess The Weapon](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Weapon) | [Guess Who](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_Who) | [Pop My Balloon](https://github.com/kunjgit/GameZone/tree/main/Games/Pop_My_Balloon) | | -| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Earth_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Earth_Guardian) | [Earth_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Earth_Guardian) | [HTML5_Controller_Tester](https://github.com/kunjgit/GameZone/tree/main/Games/HTML5_Controller_Tester) +| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Coloron](https://github.com/kunjgit/GameZone/tree/main/Games/Coloron). | +| [Black_jackk](https://github.com/kunjgit/GameZone/tree/main/Games/Black_jackk) +| [Earth_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Earth_Guardian) | | [escaperoom](https://github.com/kunjgit/GameZone/tree/main/Games/escaperoom) | [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | [HTML5_Controller_Tester](https://github.com/kunjgit/GameZone/tree/main/Games/HTML5_Controller_Tester) | [numeral-whiz](https://github.com/Ishan-77/GameZone/tree/main/Games/numeral-whiz) | [candy_match](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Match_Saga) | [Crossy_Road](https://github.com/tanujbordikar/GameZone/tree/Crossy_Road) | [HueHero](https://github.com/kunjgit/GameZone/tree/main/Games/HueHero) | [Puzzel_Winner](https://github.com/kunjgit/GameZone/tree/main/Games/Puzzel_Winner) | @@ -201,6 +200,7 @@ This repository also provides one such platforms where contributers come over an | [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | [CatchTheBall](https://github.com/kunjgit/GameZone/tree/main/Games/CatchTheBall) | | [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | [DoraemonRun ](https://github.com/kunjgit/GameZone/tree/main/Games/DoraemonRun) | | [Memory_Cards_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Memory_Cards_Game) | +| [Typing_Speed_Test2](https://github.com/kunjgit/GameZone/tree/main/Games/Typing_Speed_Test2) | [Tic Tac Toe Responsive ](https://github.com/kunjgit/GameZone/tree/main/Games/Tic_tac_toe_responsive) | | [Technical_Mind_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Technical_Mind_Game) | [Slide_Master_Puzzle](https://github.com/kunjgit/GameZone/tree/Main/Games/Slide_Master_Puzz)| | | [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | [Letter_Sleuth](https://github.com/swetha5157/GameZone/tree/main/Games/Letter_Sleuth) @@ -215,138 +215,147 @@ This repository also provides one such platforms where contributers come over an | [Steampunk_FlappyBird](https://github.com/kunjgit/GameZone/tree/main/Games/Steampunk_FlappyBird) | | [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | | [Automated_rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/automated_rock_paper_scissor) | -| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Astronaut_runner](https://github.com/tanishkaa08/GameZone/tree/main/Games/Astronaunt_runner) | -[16_Puzzle](https://github.com/kunjgit/GameZone/tree/main/Games/16_Puzzle) | -| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | -| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | -| [Dice_Roller](https://github.com/kunjgit/GameZone/tree/main/Games/Dice_Roller) | [Bear Hunter Ninja](https://github.com/Niyatizzz/GameZone/tree/main/Games/Bear_Hunter_Ninja) | -| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | -| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | -| [Pokemon_Stats_Card](https://github.com/kunjgit/GameZone/tree/main/Games/Pokemon_Stats_Card) | +| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Astronaut_runner](https://github.com/tanishkaa08/GameZone/tree/main/Games/Astronaunt_runner) | +[16_Puzzle](https://github.com/kunjgit/GameZone/tree/main/Games/16_Puzzle) | +| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | +| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | +| [Dice_Roller](https://github.com/kunjgit/GameZone/tree/main/Games/Dice_Roller) | [Bear Hunter Ninja](https://github.com/Niyatizzz/GameZone/tree/main/Games/Bear_Hunter_Ninja) | +| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | +| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | +| [Pokemon_Stats_Card](https://github.com/kunjgit/GameZone/tree/main/Games/Pokemon_Stats_Card) | | [Steampunk_FlappyBird](https://github.com/kunjgit/GameZone/tree/main/Games/Steampunk_FlappyBird) | -| [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | +| [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | | [Automated_rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/automated_rock_paper_scissor) | -| [Grab_The_Carrot](https://github.com/Aksshay88/GameZone/tree/main/Games/Grab_The_Carrot) | -| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Astronaut_runner](https://github.com/tanishkaa08/GameZone/tree/main/Games/Astronaunt_runner) | -| [16_Puzzle](https://github.com/kunjgit/GameZone/tree/main/Games/16_Puzzle) | -| [Musical_Memory](https://github.com/kunjgit/GameZone/tree/main/Games/Musical_Memory) | -|[Quick_Click](https://github.com/kunjgit/GameZone/tree/main/Games/Quick_Click) | -| [Dragon_Tower](https://github.com/kunjgit/GameZone/tree/main/Games/Dragon_Tower) | -| [Hover_Board_Effect](https://github.com/kunjgit/GameZone/tree/main/Games/Hover_Board_Effect) | -[Mancala_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Mancala_Game) | -| [Dice_Roller](https://github.com/kunjgit/GameZone/tree/main/Games/Dice_Roller) | [Bear Hunter Ninja](https://github.com/Niyatizzz/GameZone/tree/main/Games/Bear_Hunter_Ninja) | -| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | -| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | -| [Chrome_Dino_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Chrome_Dino_Game) | -| [Pokemon_Stats_Card](https://github.com/kunjgit/GameZone/tree/main/Games/Pokemon_Stats_Card) | +| [Grab_The_Carrot](https://github.com/Aksshay88/GameZone/tree/main/Games/Grab_The_Carrot) | +| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Astronaut_runner](https://github.com/tanishkaa08/GameZone/tree/main/Games/Astronaunt_runner) | +| [16_Puzzle](https://github.com/kunjgit/GameZone/tree/main/Games/16_Puzzle) | +| [Musical_Memory](https://github.com/kunjgit/GameZone/tree/main/Games/Musical_Memory) | +|[Quick_Click](https://github.com/kunjgit/GameZone/tree/main/Games/Quick_Click) | +| [Dragon_Tower](https://github.com/kunjgit/GameZone/tree/main/Games/Dragon_Tower) | +| [Hover_Board_Effect](https://github.com/kunjgit/GameZone/tree/main/Games/Hover_Board_Effect) | +[Mancala_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Mancala_Game) | +| [Dice_Roller](https://github.com/kunjgit/GameZone/tree/main/Games/Dice_Roller) | [Bear Hunter Ninja](https://github.com/Niyatizzz/GameZone/tree/main/Games/Bear_Hunter_Ninja) | +| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | +| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | +| [Chrome_Dino_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Chrome_Dino_Game) | +| [Pokemon_Stats_Card](https://github.com/kunjgit/GameZone/tree/main/Games/Pokemon_Stats_Card) | | [Steampunk_FlappyBird](https://github.com/kunjgit/GameZone/tree/main/Games/Steampunk_FlappyBird) | -| [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | +| [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | | [Automated_rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/automated_rock_paper_scissor) | -| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Astronaut_runner](https://github.com/tanishkaa08/GameZone/tree/main/Games/Astronaunt_runner) | -| [16_Puzzle](https://github.com/kunjgit/GameZone/tree/main/Games/16_Puzzle) | -| [Dragon_Tower](https://github.com/kunjgit/GameZone/tree/main/Games/Dragon_Tower) | -| [Hover_Board_Effect](https://github.com/kunjgit/GameZone/tree/main/Games/Hover_Board_Effect) | -| [escaperoom](https://github.com/kunjgit/GameZone/tree/main/Games/escaperoom) | -| [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | [HTML5_Controller_Tester](https://github.com/kunjgit/GameZone/tree/main/Games/HTML5_Controller_Tester) | -| [numeral-whiz](https://github.com/Ishan-77/GameZone/tree/main/Games/numeral-whiz) | [candy_match](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Match_Saga) | -| [Crossy_Road](https://github.com/tanujbordikar/GameZone/tree/Crossy_Road) | [HueHero](https://github.com/kunjgit/GameZone/tree/main/Games/HueHero) | -| [Puzzel_Winner](https://github.com/kunjgit/GameZone/tree/main/Games/Puzzel_Winner) | -| [Emoji_Intruder](https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_Intruder) | [Guess The Weapon](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Weapon) | -| [Guess Who](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_Who) | [Pop My Balloon](https://github.com/kunjgit/GameZone/tree/main/Games/Pop_My_Balloon) | -| [Tower Stack](https://github.com/kunjgit/GameZone/tree/main/Games/Tower_Stack) | [Soccer](https://github.com/kunjgit/GameZone/tree/main/Games/Soccer) | -| [TriHand_Tactics](https://github.com/kunjgit/GameZone/tree/main/Games/TriHand_Tactics) | -| [Earth_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Earth_Guardian) | -| [CatchTheBall](https://github.com/kunjgit/GameZone/tree/main/Games/CatchTheBall) | -| [Candy_Crush_Saga](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Crush_Saga) | -| [numeral-whiz](https://github.com/Ishan-77/GameZone/tree/main/Games/numeral-whiz) | [candy_match](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Match_Saga) | [Crossy_Road](https://github.com/tanujbordikar/GameZone/tree/Crossy_Road) | [HueHero](https://github.com/kunjgit/GameZone/tree/main/Games/HueHero) | [Puzzel_Winner](https://github.com/kunjgit/GameZone/tree/main/Games/Puzzel_Winner) | -| [Emoji_Intruder](https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_Intruder) | [Guess The Weapon](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Weapon) | [Guess Who](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_Who) | [Pop My Balloon](https://github.com/kunjgit/GameZone/tree/main/Games/Pop_My_Balloon) | [Tower Stack](https://github.com/kunjgit/GameZone/tree/main/Games/Tower_Stack) | -| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [TriHand_Tactics](https://github.com/kunjgit/GameZone/tree/main/Games/TriHand_Tactics) | [Earth_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Earth_Guardian) | [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | -| [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | [CatchTheBall](https://github.com/kunjgit/GameZone/tree/main/Games/CatchTheBall) | - [Candy_Crush_Saga](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Crush_Saga) | - [Colour_Generator_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Colour_Generator_Game) | -| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | -| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | -[Mancala_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Mancala_Game) | -|[2048_win](https://github.com/kunjgit/GameZone/tree/main/Games/2048_win) | -| [Dice_Roller](https://github.com/kunjgit/GameZone/tree/main/Games/Dice_Roller) | [Chrome_Dino_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Chrome_Dino_Game) | -| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | -| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | -| [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | -| [Shrek_Vs_Wild](https://github.com/kunjgit/GameZone/tree/main/Games/Shrek_Vs_Wild) | -| [Balloon_Buster](https://github.com/kunjgit/GameZone/tree/main/Games/Balloon_Buster) | -| [Pokemon_Stats_Card](https://github.com/kunjgit/GameZone/tree/main/Games/Pokemon_Stats_Card) | -| [Steampunk_FlappyBird](https://github.com/kunjgit/GameZone/tree/main/Games/Steampunk_FlappyBird) | -| [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | | -| [path_finder](https://github.com/kunjgit/GameZone/tree/main/Games/path_finder) | -| [Shrek_Vs_Wild](https://github.com/kunjgit/GameZone/tree/main/Games/Shrek_Vs_Wild) | -| [Dragon_Tower](https://github.com/kunjgit/GameZone/tree/main/Games/Dragon_Tower) | -| [Guess_num](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_num) | -| [QuickFingers](https://github.com/kunjgit/GameZone/tree/main/Games/QuickFingers) | -| [Physics_Quizz](https://github.com/kunjgit/GameZone/tree/main/Games/Physics_Quizz) | -| [Tiny_Fishing](https://github.com/kunjgit/GameZone/tree/main/Games/Tiny_Fishing) | - -| [Hover_Board_Effect](https://github.com/kunjgit/GameZone/tree/main/Games/Hover_Board_Effect) | - -| [namefate](https://github.com/kunjgit/GameZone/tree/main/Games/namefate) | -| [Fruit_Catching_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Fruit_Catching_Game) | -| [color_matching_application](https://github.com/kunjgit/GameZone/tree/main/Games/color_matching_application) | -| [Pictionary_Game](https://github.com/Jagpreet153/GameZone/tree/main/Games/Pictionary_Game) | -| [Anagram_Checker_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Anagram_Checker_Game) | -| [HitYourFriend](https://github.com/kunjgit/GameZone/tree/main/Games/HitYourFriend) | -| [Random_joke_Generator](https://github.com/Jagpreet153/GameZone/tree/main/Games/Random_joke_Generator) | -| [Arkanoid_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Arkanoid_Game) | -| [Catch_Stars](https://github.com/Kunjgit/GameZone/tree/main/Games/Catch_Stars) | -| [Color Matcher](https://github.com/1911aditi/GameZone/tree/1a4f3847e11bb13b1aca4652a87868c9bc467a93/Games/color%20matcher)                | +| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [Astronaut_runner](https://github.com/tanishkaa08/GameZone/tree/main/Games/Astronaunt_runner) | +| [16_Puzzle](https://github.com/kunjgit/GameZone/tree/main/Games/16_Puzzle) | +| [Dragon_Tower](https://github.com/kunjgit/GameZone/tree/main/Games/Dragon_Tower) | +| [Hover_Board_Effect](https://github.com/kunjgit/GameZone/tree/main/Games/Hover_Board_Effect) | +| [escaperoom](https://github.com/kunjgit/GameZone/tree/main/Games/escaperoom) | +| [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | [HTML5_Controller_Tester](https://github.com/kunjgit/GameZone/tree/main/Games/HTML5_Controller_Tester) | +| [numeral-whiz](https://github.com/Ishan-77/GameZone/tree/main/Games/numeral-whiz) | [candy_match](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Match_Saga) | +| [Crossy_Road](https://github.com/tanujbordikar/GameZone/tree/Crossy_Road) | [HueHero](https://github.com/kunjgit/GameZone/tree/main/Games/HueHero) | +| [Puzzel_Winner](https://github.com/kunjgit/GameZone/tree/main/Games/Puzzel_Winner) | +| [Emoji_Intruder](https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_Intruder) | [Guess The Weapon](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Weapon) | +| [Guess Who](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_Who) | [Pop My Balloon](https://github.com/kunjgit/GameZone/tree/main/Games/Pop_My_Balloon) | +| [Tower Stack](https://github.com/kunjgit/GameZone/tree/main/Games/Tower_Stack) | [Soccer](https://github.com/kunjgit/GameZone/tree/main/Games/Soccer) | +| [TriHand_Tactics](https://github.com/kunjgit/GameZone/tree/main/Games/TriHand_Tactics) | +| [Earth_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Earth_Guardian) | +| [CatchTheBall](https://github.com/kunjgit/GameZone/tree/main/Games/CatchTheBall) | +| [Candy_Crush_Saga](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Crush_Saga) | +| [numeral-whiz](https://github.com/Ishan-77/GameZone/tree/main/Games/numeral-whiz) | [candy_match](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Match_Saga) | [Crossy_Road](https://github.com/tanujbordikar/GameZone/tree/Crossy_Road) | [HueHero](https://github.com/kunjgit/GameZone/tree/main/Games/HueHero) | [Puzzel_Winner](https://github.com/kunjgit/GameZone/tree/main/Games/Puzzel_Winner) | +| [Emoji_Intruder](https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_Intruder) | [Guess The Weapon](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Weapon) | [Guess Who](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_Who) | [Pop My Balloon](https://github.com/kunjgit/GameZone/tree/main/Games/Pop_My_Balloon) | [Tower Stack](https://github.com/kunjgit/GameZone/tree/main/Games/Tower_Stack) | +| [Maze_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Maze_Game) | [TriHand_Tactics](https://github.com/kunjgit/GameZone/tree/main/Games/TriHand_Tactics) | [Earth_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Earth_Guardian) | [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | +| [Ball_Shooting_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball_Shooting_Game) | [CatchTheBall](https://github.com/kunjgit/GameZone/tree/main/Games/CatchTheBall) | +[Candy_Crush_Saga](https://github.com/kunjgit/GameZone/tree/main/Games/Candy_Crush_Saga) | +[Colour_Generator_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Colour_Generator_Game) | +| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | +| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | +[Mancala_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Mancala_Game) | +|[2048_win](https://github.com/kunjgit/GameZone/tree/main/Games/2048_win) | +| [Dice_Roller](https://github.com/kunjgit/GameZone/tree/main/Games/Dice_Roller) | [Chrome_Dino_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Chrome_Dino_Game) | +| [Rock_paper_scissor](https://github.com/kunjgit/GameZone/tree/main/Games/Rock_paper_scissor) | +| [City_Builder_Game](https://github.com/kunjgit/GameZone/tree/main/Games/City_Builder_Game) | +| [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | +| [Shrek_Vs_Wild](https://github.com/kunjgit/GameZone/tree/main/Games/Shrek_Vs_Wild) | +| [Balloon_Buster](https://github.com/kunjgit/GameZone/tree/main/Games/Balloon_Buster) | +| [Pokemon_Stats_Card](https://github.com/kunjgit/GameZone/tree/main/Games/Pokemon_Stats_Card) | +| [Steampunk_FlappyBird](https://github.com/kunjgit/GameZone/tree/main/Games/Steampunk_FlappyBird) | +| [Catch_The_Circle](https://github.com/kunjgit/GameZone/tree/main/Games/Catch_The_Circle) | | +| [path_finder](https://github.com/kunjgit/GameZone/tree/main/Games/path_finder) | +| [Shrek_Vs_Wild](https://github.com/kunjgit/GameZone/tree/main/Games/Shrek_Vs_Wild) | +| [Dragon_Tower](https://github.com/kunjgit/GameZone/tree/main/Games/Dragon_Tower) | +| [Guess_num](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_num) | +| [QuickFingers](https://github.com/kunjgit/GameZone/tree/main/Games/QuickFingers) | +| [Physics_Quizz](https://github.com/kunjgit/GameZone/tree/main/Games/Physics_Quizz) | +| [Tiny_Fishing](https://github.com/kunjgit/GameZone/tree/main/Games/Tiny_Fishing) | + +| [Hover_Board_Effect](https://github.com/kunjgit/GameZone/tree/main/Games/Hover_Board_Effect) | + +| [namefate](https://github.com/kunjgit/GameZone/tree/main/Games/namefate) | +| [Fruit_Catching_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Fruit_Catching_Game) | +| [color_matching_application](https://github.com/kunjgit/GameZone/tree/main/Games/color_matching_application) | +| [Pictionary_Game](https://github.com/Jagpreet153/GameZone/tree/main/Games/Pictionary_Game) | +| [Anagram_Checker_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Anagram_Checker_Game) | +| [HitYourFriend](https://github.com/kunjgit/GameZone/tree/main/Games/HitYourFriend) | +| [Random_joke_Generator](https://github.com/Jagpreet153/GameZone/tree/main/Games/Random_joke_Generator) | +| [Arkanoid_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Arkanoid_Game) | +| [Catch_Stars](https://github.com/Kunjgit/GameZone/tree/main/Games/Catch_Stars) | +| [Color Matcher](https://github.com/1911aditi/GameZone/tree/1a4f3847e11bb13b1aca4652a87868c9bc467a93/Games/color%20matcher)                | | [LaserDarts] (https://github.com/Jagpreet153/GameZone/tree/main/Games/LaserDarts) -| [Block Building](https://github.com/kunjgit/GameZone/tree/main/Games/Block_Building) | +| [Block Building](https://github.com/kunjgit/GameZone/tree/main/Games/Block_Building) | | [Flames Game](https://github.com/kunjgit/GameZone/tree/main/Games/Flames_Game)| -| [NewsJunction](https://github.com/kunjgit/GameZone/tree/main/Games/NewsJunction) | -|[Ping_Pong_Singleplayer](https://github.com/kunjgit/GameZone/tree/main/Games/Ping_Pong_Singleplayer) | -| [MazeRunner](https://github.com/kunjgit/GameZone/tree/main/Games/MazeRunner) | +| [NewsJunction](https://github.com/kunjgit/GameZone/tree/main/Games/NewsJunction) | +|[Ping_Pong_Singleplayer](https://github.com/kunjgit/GameZone/tree/main/Games/Ping_Pong_Singleplayer) | +| [MazeRunner](https://github.com/kunjgit/GameZone/tree/main/Games/MazeRunner) | | [Emoji_slot_machine] (https://github.com/kunjgit/GameZone/tree/main/Games/Emoji_slot_machine) -| [NewsJunction](https://github.com/kunjgit/GameZone/tree/main/Games/NewsJunction) -| [Pixel Painter](https://github.com/kunjgit/GameZone/tree/main/Games/pixel_painter) | -| [Guess_The_Song](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Song) | [Reverse Memory](https://github.com/MuraliDharan7/GameZone/tree/reverse-memory-game/Games/Reverse%20Memory) -| [NewsJunction](https://github.com/kunjgit/GameZone/tree/main/Games/NewsJunction) | -| [Recognizing_Figures](https://github.com/kunjgit/GameZone/tree/main/Games/Recognizing_Figures) | - -| [WordScramble](https://github.com/kunjgit/GameZone/tree/main/Games/wordScramble) - -[Roll_The_Dice](https://github.com/kunjgit/GameZone/tree/main/Games/Roll_The_Dice) | -| [Black_jackk](https://github.com/kunjgit/GameZone/tree/main/Games/Black_jackk) | -| [Recognizing_Figures](https://github.com/kunjgit/GameZone/tree/main/Games/Recognizing_Figures) | [Screen Pet Game](https://github.com/kunjgit/GameZone/tree/main/Games/Screen-Pet-Game) | -| [Sudoku_light_theme](https://github.com/kunjgit/GameZone/tree/main/Games/Sudoku_light_theme) | -| [Find_the_ball](https://github.com/kunjgit/GameZone/tree/main/Games/Find_the_ball) | +| [NewsJunction](https://github.com/kunjgit/GameZone/tree/main/Games/NewsJunction) +| [Pixel Painter](https://github.com/kunjgit/GameZone/tree/main/Games/pixel_painter) | +| [Guess_The_Song](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_The_Song) | [Reverse Memory](https://github.com/MuraliDharan7/GameZone/tree/reverse-memory-game/Games/Reverse%20Memory) +| [NewsJunction](https://github.com/kunjgit/GameZone/tree/main/Games/NewsJunction) | +| [Recognizing_Figures](https://github.com/kunjgit/GameZone/tree/main/Games/Recognizing_Figures) | +| [WordScramble](https://github.com/kunjgit/GameZone/tree/main/Games/wordScramble) +[Roll_The_Dice](https://github.com/kunjgit/GameZone/tree/main/Games/Roll_The_Dice) | +| [Black_jackk](https://github.com/kunjgit/GameZone/tree/main/Games/Black_jackk) | +| [Recognizing_Figures](https://github.com/kunjgit/GameZone/tree/main/Games/Recognizing_Figures) | [Screen Pet Game](https://github.com/kunjgit/GameZone/tree/main/Games/Screen-Pet-Game) | +| [Sudoku_light_theme](https://github.com/kunjgit/GameZone/tree/main/Games/Sudoku_light_theme) | +| [Find_the_ball](https://github.com/kunjgit/GameZone/tree/main/Games/Find_the_ball) | | [Color The Page](https://github.com/kunjgit/GameZone/tree/main/Games/Color_The_Page)| |[Building Blocks Game](https://github.com/kunjgit/GameZone/tree/main/Games/Building_Block_Game)| |[Cartoon character guessing game](https://github.com/kunjgit/GameZone/tree/main/Games/Cartoon_Character_Guessing_Game)| |[Carrom Board Game](https://github.com/kunjgit/GameZone/tree/main/Games/carrom)| -| [Number_Recall_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Number_Recall_Game) | -| [Hit_the_hamster](https://github.com/kunjgit/GameZone/tree/main/Games/Hit_the_hamster) | -| [Forest_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Forst_Guardian) | -| [Sudoku_light_theme](https://github.com/kunjgit/GameZone/tree/main/Games/Sudoku_light_theme) | -| [Find_the_ball](https://github.com/kunjgit/GameZone/tree/main/Games/Find_the_ball) | +| [Number_Recall_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Number_Recall_Game) | +| [Hit_the_hamster](https://github.com/kunjgit/GameZone/tree/main/Games/Hit_the_hamster) | +| [Forest_Guardian](https://github.com/kunjgit/GameZone/tree/main/Games/Forst_Guardian) | +| [Sudoku_light_theme](https://github.com/kunjgit/GameZone/tree/main/Games/Sudoku_light_theme) | +| [Find_the_ball](https://github.com/kunjgit/GameZone/tree/main/Games/Find_the_ball) | |[Color The Page](https://github.com/kunjgit/GameZone/tree/main/Games/Color_The_Page)| -|[AquaSort_Game](https://github.com/kunjgit/GameZone/tree/main/Games/AquaSort_Game) | -|[Chess_Game_computer](https://github.com/kunjgit/GameZone/tree/main/Games/Chess_Game_computer) | -|[Turn_on_the_light](https://github.com/kunjgit/GameZone/tree/main/Games/Turn_on_the_light) | +|[AquaSort_Game](https://github.com/kunjgit/GameZone/tree/main/Games/AquaSort_Game) | +| [Snake](https://github.com/kunjgit/GameZone/tree/main/Games/snake)                | + +|[Chess_Game_computer](https://github.com/kunjgit/GameZone/tree/main/Games/Chess_Game_computer) | + +|[Turn_on_the_light](https://github.com/kunjgit/GameZone/tree/main/Games/Turn_on_the_light) | | [Tic-Tac-Toe Game](https://github.com/kunjgit/GameZone/tree/main/Games/Tic-Tac-Toe) | | [Rapid_click_frenzy](https://github.com/kunjgit/GameZone/tree/main/Games/Rapid_click_frenzy) | | [Dsa_quiz_game](https://github.com/kunjgit/GameZone/tree/main/Games/Dsa_quiz_game) | | [Gravity_Simulation_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Gravity_Simulation_Game) | | [Anagarm-Word-Game](https://github.com/kunjgit/GameZone/tree/main/Games/Anagarm-Word-Game) | +| [Alphabet-and-Vowels](https://github.com/kunjgit/GameZone/tree/main/Games/Alphabet-and-Vowels) | +| [Taash_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Taash_Game)| | [Brick Buster Game](https://github.com/kunjgit/GameZone/tree/main/Games/Brick%20Buster) | | [Rapid_click_frenzy](https://github.com/kunjgit/GameZone/tree/main/Games/Rapid_click_frenzy) | | [Penguins Can't Fly](https://github.com/Will2Jacks/GameZoneForked/tree/Task/Games/Penguins_Can't_Fly) | | [Intellect Quest](https://github.com/Will2Jacks/GameZoneForked/tree/Task/Games/Intellect_Quest) | | [Taash_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Taash_Game) | +| [Intellect Quest](https://github.com/Will2Jacks/GameZoneForked/tree/Task/Games/Intellect_Quest) | +| [Taash_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Taash_Game) | | [Number_Guessing_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Number_Guessing_Game) | +| [Tower_Block_Game](https://github.com/Saipradyumnagoud/GameZone/tree/main/Games/Tower_Block_Game) | | [Modulo_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Modulo_Game) | +| [Block_Ninja] (https://github.com/kunjgit/GameZone/tree/main/Games/Block_Ninja) | +| [Disney_Trivia](https://github.com/manmita/GameZone/tree/Disney_Trivia/Games/Disney_Trivia)| +|[Harmony_Mixer](https://github.com/kunjgit/GameZone/tree/main/Games/Harmony_Mixer)| +
-

Page with Curl Contributing Guideline

@@ -395,7 +404,7 @@ Terms and conditions for use, reproduction and distribution are under the [Apach
- This project thanking all the contributors for having your valuable contribution to our project -- Make sure you show some love by giving ⭐ to our repository +- Make sure you show some love by giving ⭐ to our repository
@@ -405,6 +414,4 @@ Terms and conditions for use, reproduction and distribution are under the [Apach
- -

Back to top

- +

Back to top

diff --git a/assets/animations/Yahtzee_video.mp4 b/assets/animations/Yahtzee_video.mp4 new file mode 100644 index 0000000000..3a722d310c Binary files /dev/null and b/assets/animations/Yahtzee_video.mp4 differ diff --git a/assets/audio/Yahtzee_roll.wav b/assets/audio/Yahtzee_roll.wav new file mode 100644 index 0000000000..6bc5a76ef8 Binary files /dev/null and b/assets/audio/Yahtzee_roll.wav differ diff --git a/assets/css/style.css b/assets/css/style.css index 50ab9b3cca..7587c4c83e 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -4,6 +4,7 @@ width: 100%; height: 100%; margin: 0px; padding: 0px; +transition: background-color 4s ease; overflow-x: hidden;} #about { color: white; diff --git a/assets/images/Alphabet-and-Vowels.jpeg b/assets/images/Alphabet-and-Vowels.jpeg new file mode 100644 index 0000000000..496b9da32b Binary files /dev/null and b/assets/images/Alphabet-and-Vowels.jpeg differ diff --git a/assets/images/Block_Ninja.png b/assets/images/Block_Ninja.png new file mode 100644 index 0000000000..efc5cd8caf Binary files /dev/null and b/assets/images/Block_Ninja.png differ diff --git a/assets/images/Computer_Bingo.png b/assets/images/Computer_Bingo.png new file mode 100644 index 0000000000..f10c385f06 Binary files /dev/null and b/assets/images/Computer_Bingo.png differ diff --git a/assets/images/Disney_Trivia.png b/assets/images/Disney_Trivia.png new file mode 100644 index 0000000000..fbb708cc1a Binary files /dev/null and b/assets/images/Disney_Trivia.png differ diff --git a/assets/images/Harmony_Mixer.png b/assets/images/Harmony_Mixer.png new file mode 100644 index 0000000000..59a6089412 Binary files /dev/null and b/assets/images/Harmony_Mixer.png differ diff --git a/assets/images/Tic_tac_toe_responsive.png b/assets/images/Tic_tac_toe_responsive.png new file mode 100644 index 0000000000..c002f0e872 Binary files /dev/null and b/assets/images/Tic_tac_toe_responsive.png differ diff --git a/assets/images/Tower_Block_Game.png b/assets/images/Tower_Block_Game.png new file mode 100644 index 0000000000..4681a2dd40 Binary files /dev/null and b/assets/images/Tower_Block_Game.png differ diff --git a/assets/images/Typing_Speed_Test2.png b/assets/images/Typing_Speed_Test2.png new file mode 100644 index 0000000000..732e39457e Binary files /dev/null and b/assets/images/Typing_Speed_Test2.png differ diff --git a/assets/images/Yahtzee.png b/assets/images/Yahtzee.png new file mode 100644 index 0000000000..28947d63e4 Binary files /dev/null and b/assets/images/Yahtzee.png differ diff --git a/assets/images/Yahtzee_button.png b/assets/images/Yahtzee_button.png new file mode 100644 index 0000000000..06b615bf09 Binary files /dev/null and b/assets/images/Yahtzee_button.png differ diff --git a/assets/images/Yahtzee_dice1.png b/assets/images/Yahtzee_dice1.png new file mode 100644 index 0000000000..7ce3c94f5d Binary files /dev/null and b/assets/images/Yahtzee_dice1.png differ diff --git a/assets/images/Yahtzee_dice2.png b/assets/images/Yahtzee_dice2.png new file mode 100644 index 0000000000..a28ceb44c2 Binary files /dev/null and b/assets/images/Yahtzee_dice2.png differ diff --git a/assets/images/Yahtzee_dice3.png b/assets/images/Yahtzee_dice3.png new file mode 100644 index 0000000000..1b2955d3d8 Binary files /dev/null and b/assets/images/Yahtzee_dice3.png differ diff --git a/assets/images/Yahtzee_dice4.png b/assets/images/Yahtzee_dice4.png new file mode 100644 index 0000000000..5a499ad410 Binary files /dev/null and b/assets/images/Yahtzee_dice4.png differ diff --git a/assets/images/Yahtzee_dice5.png b/assets/images/Yahtzee_dice5.png new file mode 100644 index 0000000000..70af18e773 Binary files /dev/null and b/assets/images/Yahtzee_dice5.png differ diff --git a/assets/images/Yahtzee_dice6.png b/assets/images/Yahtzee_dice6.png new file mode 100644 index 0000000000..795a34069b Binary files /dev/null and b/assets/images/Yahtzee_dice6.png differ diff --git a/assets/images/grabthecarrot.png b/assets/images/grabthecarrot.png deleted file mode 100644 index 69a5874ced..0000000000 Binary files a/assets/images/grabthecarrot.png and /dev/null differ diff --git a/assets/images/image.png b/assets/images/image.png deleted file mode 100644 index 27158628e7..0000000000 Binary files a/assets/images/image.png and /dev/null differ diff --git a/assets/images/killthebird.jpeg b/assets/images/killthebird.jpeg new file mode 100644 index 0000000000..9995c9c29e Binary files /dev/null and b/assets/images/killthebird.jpeg differ diff --git a/assets/images/memory-game.png b/assets/images/memory-game.png new file mode 100644 index 0000000000..a1a9053ec7 Binary files /dev/null and b/assets/images/memory-game.png differ diff --git a/assets/images/snake.png b/assets/images/snake.png new file mode 100644 index 0000000000..98118e2990 Binary files /dev/null and b/assets/images/snake.png differ diff --git a/assets/js/background.js b/assets/js/background.js new file mode 100644 index 0000000000..0f181a473e --- /dev/null +++ b/assets/js/background.js @@ -0,0 +1,27 @@ +const randomColor = () => { + const hex = '0123456789ABCDEF'; + let color = '#'; + for (let i = 0; i < 6; i++) { + color += hex[Math.floor(Math.random() * 16)]; + } + return color; +}; + +let id; + +const startChanging = () => { + if (!id) { // better practice + id = setInterval(change, 2500); // Set interval to 2000 milliseconds (2 seconds) + } + function change() { + document.body.style.backgroundColor = randomColor(); + } +}; + +const stopChanging = () => { + clearInterval(id); + id = null; // flushes out the value after stop and hence no overriding +}; + +// Start changing colors when the page loads +window.onload = startChanging; diff --git a/assets/js/script.js b/assets/js/script.js index 238469f452..1ab605cb4e 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -198,14 +198,27 @@ for (let i = 0; i < filterBtn.length; i++) { // Code for enabling Light-Dark THEME +function applyTheme() { + var slider = document.getElementById("themeToggle"); + var isDarkTheme = localStorage.getItem("isDarkTheme"); + if (isDarkTheme === "true") { + slider.checked = true; + enableDarkTheme(); + } else { + slider.checked = false; + disableDarkTheme(); + } +} function toggleTheme() { var slider = document.getElementById("themeToggle"); if (slider.checked) { - disableDarkTheme(); - } else { + localStorage.setItem("isDarkTheme", "true"); enableDarkTheme(); + } else { + localStorage.setItem("isDarkTheme", "false"); + disableDarkTheme(); } } @@ -245,6 +258,8 @@ function disableDarkTheme() { } } +document.addEventListener("DOMContentLoaded", applyTheme); + window.onscroll = function() {scrollFunction()}; function scrollFunction() { diff --git a/index.html b/index.html index 62e69f176a..2fa8006e92 100644 --- a/index.html +++ b/index.html @@ -391,7 +391,7 @@

- + @@ -408,7 +408,18 @@

🠕

- + +