Snake Game =========== In this classic arcade game project, we'll create a fully functional Snake game where you control a growing snake that eats apples and tries to avoid hitting itself. This complete game features multiple screens, scoring system, speed increases, and smooth gameplay - just like the original! **Sketch** .. code-block:: java // Snake Game – English version import java.util.*; ArrayList snake; PVector food; PVector direction; int gridSize = 20; int cols, rows; boolean gameOver = false; boolean gameStarted = false; int score = 0; int highScore = 0; void setup() { size(600, 600); cols = width / gridSize; rows = height / gridSize; initGame(); } void draw() { background(20, 50, 20); // deep-green background if (!gameStarted) { drawStartScreen(); } else if (gameOver) { drawGameOverScreen(); } else { updateGame(); drawGrid(); drawFood(); drawSnake(); drawUI(); } } // ------------------------------------------------------------------ // INITIALIZATION // ------------------------------------------------------------------ void initGame() { snake = new ArrayList(); snake.add(new PVector(5, 5)); // head snake.add(new PVector(4, 5)); // body snake.add(new PVector(3, 5)); // tail direction = new PVector(1, 0); // move right generateFood(); gameOver = false; score = 0; } // ------------------------------------------------------------------ // GAME LOOP // ------------------------------------------------------------------ void updateGame() { // speed increases every 50 points int speed = 10 - min(score / 5, 7); if (frameCount % speed == 0) { moveSnake(); checkCollisions(); checkFood(); } } void moveSnake() { PVector head = snake.get(0).copy().add(direction); // wrap around edges head.x = (head.x + cols) % cols; head.y = (head.y + rows) % rows; snake.add(0, head); // new head if (!head.equals(food)) snake.remove(snake.size() - 1); // pop tail } void checkCollisions() { PVector head = snake.get(0); for (int i = 1; i < snake.size(); i++) { if (head.equals(snake.get(i))) { gameOver = true; if (score > highScore) highScore = score; return; } } } void checkFood() { if (snake.get(0).equals(food)) { score += 10; generateFood(); // snake auto-grows because tail is not removed } } // ------------------------------------------------------------------ // DRAWING HELPERS // ------------------------------------------------------------------ void drawGrid() { stroke(40, 80, 40); strokeWeight(1); for (int x = 0; x < width; x += gridSize) line(x, 0, x, height); for (int y = 0; y < height; y += gridSize) line(0, y, width, y); } void drawSnake() { for (int i = 0; i < snake.size(); i++) { PVector p = snake.get(i); // head vs body color if (i == 0) { fill(100, 255, 100); stroke(50, 200, 50); } else { float alpha = map(i, 1, snake.size(), 255, 100); fill(50, 200, 50, alpha); stroke(30, 150, 30); } strokeWeight(2); rect(p.x * gridSize + 1, p.y * gridSize + 1, gridSize - 2, gridSize - 2, 3); // eyes on head if (i == 0) { fill(0); noStroke(); float eye = gridSize * 0.2f; float off = gridSize * 0.25f; if (direction.x == 1) { // right ellipse(p.x * gridSize + gridSize - off, p.y * gridSize + off, eye, eye); ellipse(p.x * gridSize + gridSize - off, p.y * gridSize + gridSize - off, eye, eye); } else if (direction.x == -1) { // left ellipse(p.x * gridSize + off, p.y * gridSize + off, eye, eye); ellipse(p.x * gridSize + off, p.y * gridSize + gridSize - off, eye, eye); } else if (direction.y == -1) { // up ellipse(p.x * gridSize + off, p.y * gridSize + off, eye, eye); ellipse(p.x * gridSize + gridSize - off, p.y * gridSize + off, eye, eye); } else { // down ellipse(p.x * gridSize + off, p.y * gridSize + gridSize - off, eye, eye); ellipse(p.x * gridSize + gridSize - off, p.y * gridSize + gridSize - off, eye, eye); } } } } void drawFood() { // apple body fill(255, 100, 100); stroke(200, 50, 50); strokeWeight(2); ellipse(food.x * gridSize + gridSize / 2, food.y * gridSize + gridSize / 2, gridSize - 4, gridSize - 4); // stem fill(100, 200, 100); noStroke(); rect(food.x * gridSize + gridSize / 2 - 1, food.y * gridSize + 2, 2, 4); // blinking highlight if (frameCount % 30 < 15) { fill(255, 255, 255, 100); noStroke(); ellipse(food.x * gridSize + gridSize / 2, food.y * gridSize + gridSize / 2, gridSize / 2, gridSize / 2); } } void drawUI() { // score panel fill(0, 0, 0, 150); noStroke(); rect(10, 10, 200, 80, 5); fill(255, 255, 100); textAlign(LEFT); textSize(20); text("Score: " + score, 20, 35); text("Best: " + highScore, 20, 60); text("Length: " + snake.size(), 20, 85); textSize(14); fill(255, 200); text("Speed: " + (1 + score / 50), 120, 35); } // ------------------------------------------------------------------ // SCREENS // ------------------------------------------------------------------ void drawStartScreen() { fill(255, 255, 100); textAlign(CENTER); textSize(48); text("🐍 Snake", width / 2, height / 2 - 100); textSize(24); fill(255); text("Use arrow keys or WASD to move.", width / 2, height / 2 - 40); text("Eat red apples to grow.", width / 2, height / 2 - 10); text("Don't hit yourself!", width / 2, height / 2 + 20); textSize(32); fill(100, 255, 100); text("Press any key to start", width / 2, height / 2 + 80); if (highScore > 0) { textSize(18); fill(255, 255, 0); text("High Score: " + highScore, width / 2, height / 2 + 120); } } void drawGameOverScreen() { fill(0, 0, 0, 150); noStroke(); rect(0, 0, width, height); fill(255, 100, 100); textAlign(CENTER); textSize(48); text("Game Over!", width / 2, height / 2 - 60); fill(255, 255, 100); textSize(32); text("Final Score: " + score, width / 2, height / 2 - 10); text("Snake Length: " + snake.size(), width / 2, height / 2 + 30); if (score == highScore && score > 0) { fill(255, 255, 0); textSize(24); text("🎉 New Record! 🎉", width / 2, height / 2 + 70); } fill(100, 255, 100); textSize(20); text("Press R to restart", width / 2, height / 2 + 120); text("Press Q for menu", width / 2, height / 2 + 150); } // ------------------------------------------------------------------ // INPUT // ------------------------------------------------------------------ void keyPressed() { if (!gameStarted) { gameStarted = true; initGame(); } else if (gameOver) { if (key == 'r' || key == 'R') { initGame(); gameStarted = true; } else if (key == 'q' || key == 'Q') { gameStarted = false; } } else { // direction controls if ((key == 'w' || key == 'W' || keyCode == UP) && direction.y != 1) direction = new PVector(0, -1); else if ((key == 's' || key == 'S' || keyCode == DOWN) && direction.y != -1) direction = new PVector(0, 1); else if ((key == 'a' || key == 'A' || keyCode == LEFT) && direction.x != 1) direction = new PVector(-1, 0); else if ((key == 'd' || key == 'D' || keyCode == RIGHT) && direction.x != -1) direction = new PVector( 1, 0); else if (key == 'p' || key == 'P') noLoop(); // pause else if (key == ' ') loop(); // resume } } // ------------------------------------------------------------------ // FOOD GENERATION // ------------------------------------------------------------------ void generateFood() { boolean ok = false; while (!ok) { food = new PVector(int(random(cols)), int(random(rows))); ok = true; for (PVector s : snake) if (s.equals(food)) ok = false; } } **How it works?** This Snake game demonstrates comprehensive game development principles and advanced programming concepts: **Game Architecture:** - **State Management**: Uses game states (start screen, playing, game over) to control different phases - **Game Loop**: Classic update-draw cycle with ``updateGame()`` and drawing functions - **Modular Design**: Well-organized code with separate functions for each game aspect **Snake Mechanics:** - **Dynamic Data Structure**: Uses ``ArrayList`` to represent growing snake body - **Movement System**: Snake head moves based on ``direction`` vector, body follows - **Growth Logic**: When food is eaten, tail is not removed, causing natural growth - **Self-Collision**: Checks if head touches any body segment to trigger game over **Grid-Based Movement:** - **Discrete Positioning**: Snake moves on a grid using ``gridSize = 20`` pixels - **Wrap-Around Edges**: Snake teleports to opposite side when hitting screen boundary - **Coordinate System**: Uses grid coordinates (cols/rows) instead of pixel coordinates **Food System:** - **Smart Generation**: ``generateFood()`` ensures food never spawns on snake body - **Visual Appeal**: Apple design with stem and blinking highlight effect - **Collision Detection**: Precise grid-based food consumption detection **Progressive Difficulty:** - **Speed Increase**: Game speeds up as score increases using ``10 - min(score/5, 7)`` - **Score Tracking**: Points awarded for each apple (10 points) - **High Score Memory**: Persistent best score tracking across game sessions **Professional User Interface:** - **Multiple Screens**: Welcome screen, gameplay, and game over with different layouts - **Real-time HUD**: Score, high score, snake length, and speed display - **Visual Feedback**: Snake head has directional eyes showing movement direction - **Professional Polish**: Semi-transparent panels, color coding, celebration effects **Advanced Graphics:** - **Gradient Effects**: Snake body fades from bright head to dim tail - **Direction-Aware Eyes**: Snake head eyes point in movement direction - **Apple Animation**: Blinking highlight effect using frame-based timing - **Grid Visualization**: Subtle grid lines for clear game area definition **Input System:** - **Multiple Control Schemes**: Arrow keys and WASD for accessibility - **Direction Validation**: Prevents 180-degree turns (instant death prevention) - **Game Controls**: Pause (P), resume (Space), restart (R), menu (Q) - **State-Aware Input**: Different controls for different game states **Collision Systems:** - **Self-Collision**: Precise head-to-body collision detection - **Food Collection**: Exact grid position matching - **Boundary Handling**: Teleportation instead of death (wrap-around) **Game Design Features:** - **Immediate Feedback**: Visual and numerical feedback for all actions - **Difficulty Curve**: Gradual speed increase maintains engagement - **Achievement System**: New record celebration - **Accessibility**: Clear instructions and multiple control options **Programming Concepts Demonstrated:** - **Object-Oriented Thinking**: Game entities as data structures - **Algorithm Design**: Pathfinding, collision detection, random generation - **State Machines**: Game flow control - **Data Management**: Dynamic arrays, coordinate systems - **User Experience**: Interface design, feedback systems This project showcases how to build a complete, polished game with professional features and smooth gameplay! For more please refer to `Processing Reference `_.