diff --git a/.github/workflows/update-index.yml b/.github/workflows/update-index.yml index 94e8ed2..c5fc7bf 100644 --- a/.github/workflows/update-index.yml +++ b/.github/workflows/update-index.yml @@ -1,4 +1,5 @@ name: Update Game Index + on: push: branches: [ main, master ] @@ -8,28 +9,32 @@ on: jobs: update-index: runs-on: ubuntu-latest + steps: - - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v3 with: token: ${{ secrets.GITHUB_TOKEN }} - + fetch-depth: 0 # Important for pushing commits back + - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.x' - + - name: Update INDEX.md run: | python update_index.py - - - name: Commit changes + + - name: Commit and push changes run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git add INDEX.md + if [[ -n "$(git status --porcelain INDEX.md)" ]]; then git commit -m "Auto-update INDEX.md with new games [skip ci]" - git push + git push origin HEAD:${GITHUB_REF#refs/heads/} else echo "No changes to INDEX.md" fi diff --git a/INDEX.md b/INDEX.md index 42e7341..c079aad 100644 --- a/INDEX.md +++ b/INDEX.md @@ -2,9 +2,7 @@ Welcome to Game_Scripts — an open-source collection of mini games! This index automatically tracks all games across different programming languages. -Last updated: Fri Oct 17 14:33:32 UTC 2025 -Tracked 26 games across 3 languages. ## 📚 Table of Contents - [Java](#java-games) @@ -16,6 +14,9 @@ Tracked 26 games across 3 languages. ### đŸŽ¯ [BrickBreakingGame](./Java/BrickBreakingGame/) A fun game built with core programming concepts +### đŸŽ¯ [FlappyBird](./Java/FlappyBird/) +FlappyBird Game + ### đŸŽ¯ [Hangman](./Java/Hangman/) 🎮 Hangman GUI Game @@ -58,7 +59,6 @@ A fun game built with core programming concepts A simple yet elegant web-based stopwatch application with start, stop, and reset functionality. ### đŸŽ¯ [Typing Speed Game](./Javascript/Typing Speed Game/) -A fast-paced browser game built with HTML, CSS, and JavaScript. Words fall from the top of the screen — type them before they hit the bottom! Designed to improve typing speed, accuracy, and reflexes. ### đŸŽ¯ [Weather Site](./Javascript/Weather Site/) A fun game built with core programming concepts diff --git a/Java/FlappyBird/App.java b/Java/FlappyBird/App.java new file mode 100644 index 0000000..948f0b0 --- /dev/null +++ b/Java/FlappyBird/App.java @@ -0,0 +1,21 @@ +import javax.swing.*; + +public class App { + public static void main(String[] args) throws Exception { + int boardWidth = 360; + int boardHeight = 640; + + JFrame frame = new JFrame("Flappy Bird"); + // frame.setVisible(true); + frame.setSize(boardWidth, boardHeight); + frame.setLocationRelativeTo(null); + frame.setResizable(false); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + FlappyBird flappyBird = new FlappyBird(); + frame.add(flappyBird); + frame.pack(); + flappyBird.requestFocus(); + frame.setVisible(true); + } +} diff --git a/Java/FlappyBird/FlappyBird.java b/Java/FlappyBird/FlappyBird.java new file mode 100644 index 0000000..a7a6439 --- /dev/null +++ b/Java/FlappyBird/FlappyBird.java @@ -0,0 +1,215 @@ +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; +import java.util.Random; +import javax.swing.*; + +public class FlappyBird extends JPanel implements ActionListener, KeyListener { + int boardWidth = 360; + int boardHeight = 640; + + // images + Image backgroundImg; + Image birdImg; + Image topPipeImg; + Image bottomPipeImg; + + // bird class + int birdX = boardWidth / 8; + int birdY = boardHeight / 2; + int birdWidth = 34; + int birdHeight = 24; + + class Bird { + int x = birdX; + int y = birdY; + int width = birdWidth; + int height = birdHeight; + Image img; + + Bird(Image img) { + this.img = img; + } + } + + // pipe class + int pipeX = boardWidth; + int pipeY = 0; + int pipeWidth = 64; // scaled by 1/6 + int pipeHeight = 512; + + class Pipe { + int x = pipeX; + int y = pipeY; + int width = pipeWidth; + int height = pipeHeight; + Image img; + boolean passed = false; + + Pipe(Image img) { + this.img = img; + } + } + + // game logic + Bird bird; + int velocityX = -4; // move pipes to the left speed (simulates bird moving right) + int velocityY = 0; // move bird up/down speed. + int gravity = 1; + + ArrayList pipes; + Random random = new Random(); + + Timer gameLoop; + Timer placePipeTimer; + boolean gameOver = false; + double score = 0; + + FlappyBird() { + setPreferredSize(new Dimension(boardWidth, boardHeight)); + // setBackground(Color.blue); + setFocusable(true); + addKeyListener(this); + + // load images + backgroundImg = new ImageIcon(getClass().getResource("./flappybirdbg.png")).getImage(); + birdImg = new ImageIcon(getClass().getResource("./flappybird.png")).getImage(); + topPipeImg = new ImageIcon(getClass().getResource("./toppipe.png")).getImage(); + bottomPipeImg = new ImageIcon(getClass().getResource("./bottompipe.png")).getImage(); + + // bird + bird = new Bird(birdImg); + pipes = new ArrayList(); + + // place pipes timer + placePipeTimer = new Timer(1500, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // Code to be executed + placePipes(); + } + }); + placePipeTimer.start(); + + // game timer + gameLoop = new Timer(1000 / 60, this); // how long it takes to start timer, milliseconds gone between frames + gameLoop.start(); + } + + void placePipes() { + // (0-1) * pipeHeight/2. + // 0 -> -128 (pipeHeight/4) + // 1 -> -128 - 256 (pipeHeight/4 - pipeHeight/2) = -3/4 pipeHeight + int randomPipeY = (int) (pipeY - pipeHeight / 4 - Math.random() * (pipeHeight / 2)); + int openingSpace = boardHeight / 4; + + Pipe topPipe = new Pipe(topPipeImg); + topPipe.y = randomPipeY; + pipes.add(topPipe); + + Pipe bottomPipe = new Pipe(bottomPipeImg); + bottomPipe.y = topPipe.y + pipeHeight + openingSpace; + pipes.add(bottomPipe); + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + draw(g); + } + + public void draw(Graphics g) { + // background + g.drawImage(backgroundImg, 0, 0, this.boardWidth, this.boardHeight, null); + + // bird + g.drawImage(birdImg, bird.x, bird.y, bird.width, bird.height, null); + + // pipes + for (int i = 0; i < pipes.size(); i++) { + Pipe pipe = pipes.get(i); + g.drawImage(pipe.img, pipe.x, pipe.y, pipe.width, pipe.height, null); + } + + // score + g.setColor(Color.white); + + g.setFont(new Font("Arial", Font.PLAIN, 32)); + if (gameOver) { + g.drawString("Game Over: " + String.valueOf((int) score), 10, 35); + } else { + g.drawString(String.valueOf((int) score), 10, 35); + } + + } + + public void move() { + // bird + velocityY += gravity; + bird.y += velocityY; + bird.y = Math.max(bird.y, 0); // apply gravity to current bird.y, limit the bird.y to top of the canvas + + // pipes + for (int i = 0; i < pipes.size(); i++) { + Pipe pipe = pipes.get(i); + pipe.x += velocityX; + + if (!pipe.passed && bird.x > pipe.x + pipe.width) { + score += 0.5; // 0.5 because there are 2 pipes! so 0.5*2 = 1, 1 for each set of pipes + pipe.passed = true; + } + + if (collision(bird, pipe)) { + gameOver = true; + } + } + + if (bird.y > boardHeight) { + gameOver = true; + } + } + + boolean collision(Bird a, Pipe b) { + return a.x < b.x + b.width && // a's top left corner doesn't reach b's top right corner + a.x + a.width > b.x && // a's top right corner passes b's top left corner + a.y < b.y + b.height && // a's top left corner doesn't reach b's bottom left corner + a.y + a.height > b.y; // a's bottom left corner passes b's top left corner + } + + @Override + public void actionPerformed(ActionEvent e) { // called every x milliseconds by gameLoop timer + move(); + repaint(); + if (gameOver) { + placePipeTimer.stop(); + gameLoop.stop(); + } + } + + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_SPACE) { + // System.out.println("JUMP!"); + velocityY = -10; + + if (gameOver) { + // restart game by resetting conditions + bird.y = birdY; + velocityY = 0; + pipes.clear(); + gameOver = false; + score = 0; + gameLoop.start(); + placePipeTimer.start(); + } + } + } + + // not needed + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyReleased(KeyEvent e) { + } +} diff --git a/Java/FlappyBird/README.md b/Java/FlappyBird/README.md new file mode 100644 index 0000000..d72cccb --- /dev/null +++ b/Java/FlappyBird/README.md @@ -0,0 +1,2 @@ +# FlappyBird +FlappyBird Game diff --git a/Java/FlappyBird/bottompipe.png b/Java/FlappyBird/bottompipe.png new file mode 100644 index 0000000..2c57b32 Binary files /dev/null and b/Java/FlappyBird/bottompipe.png differ diff --git a/Java/FlappyBird/flappybird.png b/Java/FlappyBird/flappybird.png new file mode 100644 index 0000000..7f14459 Binary files /dev/null and b/Java/FlappyBird/flappybird.png differ diff --git a/Java/FlappyBird/flappybirdbg.png b/Java/FlappyBird/flappybirdbg.png new file mode 100644 index 0000000..885ee71 Binary files /dev/null and b/Java/FlappyBird/flappybirdbg.png differ diff --git a/Java/FlappyBird/toppipe.png b/Java/FlappyBird/toppipe.png new file mode 100644 index 0000000..8b0a967 Binary files /dev/null and b/Java/FlappyBird/toppipe.png differ diff --git a/Javascript/Typing Speed Game/README.md b/Javascript/Typing Speed Game/README.md index a01c123..14929e8 100644 --- a/Javascript/Typing Speed Game/README.md +++ b/Javascript/Typing Speed Game/README.md @@ -1,42 +1,41 @@ -# đŸ•šī¸ Typing Speed Game +đŸ•šī¸ Typing Speed Game A fast-paced browser game built with HTML, CSS, and JavaScript. Words fall from the top of the screen — type them before they hit the bottom! Designed to improve typing speed, accuracy, and reflexes. ---- +🚀 Features -## 🚀 Features +🎮 Welcome screen with instructions and Start button -- 🎮 Welcome screen with instructions and Start button -- âŒ¨ī¸ Real-time typing input and word matching -- 🧠 Score tracking and game-over detection -- â¸ī¸ Pause and resume functionality -- 🔄 Restart button to replay instantly -- 🧱 Responsive layout for desktop and mobile +âŒ¨ī¸ Real-time typing input and word matching ---- +🧠 Score tracking and game-over detection -## đŸ“Ļ Tech Stack +â¸ī¸ Pause and resume functionality -- **HTML**: Structure and layout -- **CSS**: Styling and responsive design -- **JavaScript**: Game logic, animation, and input handling +🔄 Restart button to replay instantly ---- +🧱 Responsive layout for desktop and mobile -## 📸 Gameplay Preview +⚡ Difficulty Settings: Easy, Medium, Hard -> Words fall from the top. Type them quickly to score points. -> If a word reaches the bottom, the game ends. -> You can pause and restart anytime. +Easy: slower words, +1 point per correct word ---- +Medium: medium speed, +2 points per correct word -## đŸ› ī¸ How to Run +Hard: faster words, +3 points per correct word -1. Clone the repository: - ```bash - git clone https://github.com/devmalik7/Game_Scripts.git - cd Javascript - cd "Typing Speed Game" - ``` -2. Run **index.md** in your browser. +đŸ“Ļ Tech Stack + +HTML: Structure and layout + +CSS: Styling and responsive design + +JavaScript: Game logic, animation, input handling, and difficulty levels + +📸 Gameplay Preview + +Words fall from the top. Type them quickly to score points. +If a word reaches the bottom, the game ends. +You can pause, restart, and select difficulty anytime. + +Select a difficulty (Easy, Medium, Hard) and start typing! diff --git a/Javascript/Typing Speed Game/index.html b/Javascript/Typing Speed Game/index.html index e84a22b..ec05296 100644 --- a/Javascript/Typing Speed Game/index.html +++ b/Javascript/Typing Speed Game/index.html @@ -7,8 +7,21 @@ + +

+ 🧠 TYPING GAME 🎮 +

+
-

Typing Speed Game

+

Typing Speed Game

Type the falling words before they reach the bottom.

Each correct word increases your score.

If a word hits the bottom, the game ends.

@@ -30,6 +43,9 @@

Typing Speed Game

+ + +
diff --git a/Javascript/Typing Speed Game/script.js b/Javascript/Typing Speed Game/script.js index 24f6fe9..bf0406e 100644 --- a/Javascript/Typing Speed Game/script.js +++ b/Javascript/Typing Speed Game/script.js @@ -27,12 +27,71 @@ const startBtn = document.getElementById("startbtn"); const pauseBtn = document.getElementById("pausebtn"); const restartBtn = document.getElementById("restartbtn"); +const easyBtn = document.getElementById("easyBtn"); +const mediumBtn = document.getElementById("mediumBtn"); +const hardBtn = document.getElementById("hardBtn"); + let score = 0; let activeWords = []; let gameInterval; let spawnInterval; let paused = false; let running = false; +let difficulty = "medium"; +let moveSpeed = 50; +let spawnRate = 2000; +let scorePerWord = 2; // default for medium + +// Difficulty setup (speed + spawn rate + points) +function setDifficulty(level) { + difficulty = level; + + switch (level) { + case "easy": + moveSpeed = 75; // slower falling + spawnRate = 2500; // fewer words + scorePerWord = 1; + break; + case "medium": + moveSpeed = 50; + spawnRate = 2000; + scorePerWord = 2; + break; + case "hard": + moveSpeed = 25; // faster falling + spawnRate = 1200; // more words + scorePerWord = 3; + break; + } + + statusElement.textContent = `Difficulty: ${level.toUpperCase()}`; + + // ✅ Restart intervals if game already running + if (running && !paused) { + clearInterval(gameInterval); + clearInterval(spawnInterval); + gameInterval = setInterval(moveWords, moveSpeed); + spawnInterval = setInterval(generateWord, spawnRate); + } + + // ✅ Highlight selected button + highlightDifficulty(level); +} + +// Highlight active difficulty button +function highlightDifficulty(level) { + [easyBtn, mediumBtn, hardBtn].forEach((btn) => + btn.classList.remove("active") + ); + if (level === "easy") easyBtn.classList.add("active"); + if (level === "medium") mediumBtn.classList.add("active"); + if (level === "hard") hardBtn.classList.add("active"); +} + +// Difficulty buttons +easyBtn.addEventListener("click", () => setDifficulty("easy")); +mediumBtn.addEventListener("click", () => setDifficulty("medium")); +hardBtn.addEventListener("click", () => setDifficulty("hard")); function generateWord() { if (!running || paused) return; @@ -75,7 +134,7 @@ input.addEventListener("input", () => { const data = input.value.trim(); activeWords.forEach((word, i) => { if (word.textContent === data) { - score++; + score += scorePerWord; // ✅ Add points based on difficulty scoreElement.textContent = score; wordsContainer.removeChild(word); activeWords.splice(i, 1); @@ -102,8 +161,9 @@ function startGame() { paused = false; pauseBtn.textContent = "Pause"; - gameInterval = setInterval(moveWords, 50); - spawnInterval = setInterval(generateWord, 2000); + // ✅ Use current difficulty settings + gameInterval = setInterval(moveWords, moveSpeed); + spawnInterval = setInterval(generateWord, spawnRate); } function pause() { @@ -133,3 +193,5 @@ startBtn.addEventListener("click", () => { pauseBtn.addEventListener("click", pause); restartBtn.addEventListener("click", restart); + +highlightDifficulty("medium"); diff --git a/Javascript/Typing Speed Game/style.css b/Javascript/Typing Speed Game/style.css index a25f161..e0170a2 100644 --- a/Javascript/Typing Speed Game/style.css +++ b/Javascript/Typing Speed Game/style.css @@ -1,9 +1,12 @@ body { font-family: Arial, sans-serif; text-align: center; - background: #f0f0f0; margin: 0; padding: 20px; + background: url("image.jp"); + background-size: contain; + background-color: rgb(122, 235, 255); + color: #fff; } .hidden { @@ -11,55 +14,148 @@ body { } #welcomescreen { - margin-top: 100px; + background: #ffffffcc; + padding: 40px 60px; + border-radius: 20px; + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(8px); + transition: all 0.3s ease; +} + +#welcomescreen h1 { + font-size: 2em; + color: #333; + margin-bottom: 20px; } #gamescreen { max-width: 600px; margin: 0 auto; - background: #fff; - border: 2px solid #333; - border-radius: 8px; - padding: 20px; + background: #ffffffcc; + border-radius: 16px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25); + padding: 25px; + backdrop-filter: blur(8px); } #gamecontainer { width: 100%; height: 300px; - border: 1px solid #ccc; + border: 2px solid #ddd; position: relative; overflow: hidden; - background: #fafafa; + background: linear-gradient(180deg, #f9f9f9, #f0f0f0); + border-radius: 12px; + margin-bottom: 15px; } .word { position: absolute; - font-size: 20px; - font-weight: bold; - color: #333; + font-size: 22px; + font-weight: 700; + color: #4a4a4a; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15); + animation: float 1.5s ease-in-out infinite alternate; +} + +@keyframes float { + from { + transform: translateY(0); + } + to { + transform: translateY(-4px); + } } #input { - width: 80%; - padding: 10px; + width: 85%; + padding: 12px 14px; font-size: 18px; + border-radius: 8px; + border: 2px solid #764ba2; + outline: none; margin-top: 15px; + transition: all 0.3s ease; +} + +#input:focus { + border-color: #667eea; + box-shadow: 0 0 8px rgba(102, 126, 234, 0.4); } #scoreboard { - margin-top: 10px; + margin-top: 15px; display: flex; justify-content: space-between; font-size: 18px; + color: #333; + font-weight: 600; } #buttons { - margin-top: 10px; + margin-top: 15px; } button { - padding: 8px 16px; - margin: 5px; + padding: 10px 18px; + margin: 6px; font-size: 16px; + border: none; + border-radius: 8px; cursor: pointer; + transition: all 0.3s ease; + font-weight: 600; +} + +#startbtn { + background: #28a745; + color: white; +} +#pausebtn { + background: #ffc107; + color: #222; +} +#restartbtn { + background: #17a2b8; + color: white; +} + +#easyBtn, +#mediumBtn, +#hardBtn { + background: #e0e0e0; + color: #333; + border: 2px solid transparent; +} + +#easyBtn:hover, +#mediumBtn:hover, +#hardBtn:hover { + background: #ddd; +} + +.active { + background: #764ba2 !important; + color: white !important; + border-color: #667eea; +} + +#msg { + margin-top: 10px; + font-weight: 600; + color: #333; + text-shadow: 0 0 1px rgba(0, 0, 0, 0.2); +} + +@media (max-width: 600px) { + #gamescreen { + padding: 15px; + } + #input { + width: 95%; + } + button { + font-size: 14px; + padding: 8px 14px; + } }