├── .gitignore
├── .idea
├── .gitignore
├── compiler.xml
├── jarRepositories.xml
├── libraries
│ └── javafx_sdk_23.xml
├── misc.xml
├── uiDesigner.xml
└── vcs.xml
├── HOME.md
├── README.md
├── TeachMeJava.iml
├── snake-game-js
├── game.js
├── index.html
└── styles.css
├── src
└── main
│ └── java
│ ├── com
│ └── github
│ │ └── karabosithole
│ │ ├── Board.java
│ │ ├── Question.java
│ │ ├── QuestionManager.java
│ │ └── Snake.java
│ └── resources
│ ├── apple.png
│ ├── dot.png
│ ├── head.png
│ └── questions.txt
└── target
└── classes
└── com
└── github
└── karabosithole
├── Board$1.class
├── Board$TAdapter.class
├── Board.class
├── Question.class
├── QuestionManager.class
└── Snake.class
/.gitignore:
--------------------------------------------------------------------------------
1 | ### IntelliJ IDEA ###
2 | out/
3 | !**/src/main/**/out/
4 | !**/src/test/**/out/
5 |
6 | ### Eclipse ###
7 | .apt_generated
8 | .classpath
9 | .factorypath
10 | .project
11 | .settings
12 | .springBeans
13 | .sts4-cache
14 | bin/
15 | !**/src/main/**/bin/
16 | !**/src/test/**/bin/
17 |
18 | ### NetBeans ###
19 | /nbproject/private/
20 | /nbbuild/
21 | /dist/
22 | /nbdist/
23 | /.nb-gradle/
24 |
25 | ### VS Code ###
26 | .vscode/
27 |
28 | ### Mac OS ###
29 | .DS_Store
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.idea/libraries/javafx_sdk_23.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HOME.md:
--------------------------------------------------------------------------------
1 | # Snake Game Project Wiki
2 |
3 | ## Overview
4 | The Snake Game is a fun and interactive project developed in Java, where players control a snake to eat apples and answer trivia questions after each successful catch. This project was designed to reinforce my Java skills through hands-on practice while creating an engaging and educational game.
5 |
6 | For more details, you can also check out the project’s [README file](https://github.com/Karabosithole/LearnJavaSnakeGame).
7 | ---
8 |
9 | ## Project Motivation
10 |
11 | ### Why I Did the Project
12 | I created the Snake Game primarily to learn Java by practicing through an actual project. I find that hands-on, interactive learning works best for me, so developing a game allowed me to make the learning process fun and effective. My goal was to deepen my understanding of Java concepts while simultaneously creating an enjoyable experience.
13 |
14 | ### Target Audience
15 | This game is aimed at casual gamers and trivia enthusiasts who enjoy quick, fun games that also challenge their knowledge. It could also be useful for educators seeking innovative ways to engage students with learning through gamification.
16 |
17 | ---
18 | ### Realization: Running Java on the Web
19 |
20 | Initially, I designed the Snake Game in **Java** using the Swing framework. However, I soon realized that Java applications, especially ones built with Swing for a graphical user interface, cannot be run directly on a website due to browser limitations. Modern browsers do not support running Java applets or Swing-based applications natively, meaning users would have to download the game to run it locally.
21 |
22 | #### Pivot to JavaScript
23 |
24 | To offer a more seamless user experience where visitors could play the Snake Game directly on my portfolio site, I decided to recreate the game using **JavaScript**, **HTML**, and **CSS**. By doing this, users can play the game directly in their browser without needing to download anything.
25 |
26 | This transition involved learning how to recreate the core mechanics of the game in a web-friendly format while maintaining the same interactive gameplay. The new browser-based version of the Snake Game ensures ease of access for users and allows it to be embedded directly on my portfolio site.
27 |
28 | ---
29 |
30 | ### Technologies Used
31 |
32 | - **Java**: Original implementation of the Snake Game (downloadable version).
33 | - **JavaScript/HTML/CSS**: Rewritten version for browser playability.
34 |
35 | ---
36 |
37 | ### Future Plans
38 |
39 | - Continue supporting both versions of the Snake Game: one for download (Java) and one for browser play (JavaScript).
40 | - Explore other technologies to potentially expand the game's accessibility to more platforms.
41 |
42 | ## Learning Objectives
43 | In this project, I focused on achieving several learning goals:
44 | - **Object-Oriented Programming (OOP)**: Understanding and applying OOP principles in Java, including classes, inheritance, and polymorphism.
45 | - **GUI Development**: Designing a graphical user interface using Java's Swing library to create an interactive gaming experience.
46 | - **Event Handling**: Managing real-time player input and game events like key presses and game over states.
47 | - **Game Logic**: Implementing the core game mechanics such as movement, apple consumption, score calculation, and trivia integration.
48 |
49 | ---
50 |
51 | ## Development Process
52 |
53 | ### Tools and Technologies
54 | - **Java (JDK 17)**: The main programming language used to develop the Snake Game.
55 | - **Swing**: Java’s built-in GUI toolkit for building the graphical interface.
56 | - **Git**: For version control and collaboration.
57 | - **IDE**: Used IntelliJ IDEA for development.
58 |
59 | ### Key Design Decisions
60 | - **Modular Code Structure**: To make the code more readable and maintainable, I broke down the project into separate classes such as `Snake`, `Apple`, `GameBoard`, and `TriviaQuestion`.
61 | - **Trivia Integration**: After each apple consumption, the player is presented with a trivia question to enhance the gameplay and make it both fun and educational.
62 |
63 | ---
64 |
65 | ## Challenges and Solutions
66 |
67 | ### Challenge: Real-Time Event Handling
68 | One of the challenges I faced was managing the game loop while simultaneously handling real-time player input without slowing down the game.
69 |
70 | **Solution**: I solved this by using `KeyListener` and an efficient game loop structure that checks for input asynchronously, ensuring smooth gameplay.
71 |
72 | ### Challenge: Collision Detection
73 | Detecting when the snake collided with itself or the game boundaries posed a problem due to the continuous movement logic.
74 |
75 | **Solution**: I implemented precise boundary checks and a method that checks for collisions with the snake's own body, ensuring the game ends correctly when necessary.
76 |
77 | ### Challenge: Trivia Question Timing
78 | Integrating trivia questions after the snake eats an apple was tricky in terms of pausing the game and resuming after the answer.
79 |
80 | **Solution**: I added a trivia screen that pops up when the snake eats an apple, which halts the game temporarily and resumes only when the player answers the question.
81 |
82 | ---
83 |
84 | ## Reflections
85 |
86 | This project reaffirmed my love for learning through practice and play. As someone with ADHD, I often find traditional learning methods challenging, but creating something interactive and engaging made the entire process enjoyable. Through this project, I not only strengthened my Java programming skills but also learned how to work on a project that requires real-time interaction and user input.
87 |
88 | This experience reinforced my belief that gamification can be a powerful tool for learning. It also taught me the value of persistence—when facing challenges like handling event-driven programming and implementing complex game logic, I learned how to break problems down and solve them step by step.
89 |
90 | ---
91 |
92 | ## Future Improvements
93 |
94 | While the Snake Game is fully functional, I see a few areas for potential enhancement:
95 | - **Mobile Compatibility**: I plan to adapt the game to work on mobile devices, using frameworks like LibGDX for Java-based game development on Android.
96 | - **Multiplayer Mode**: Adding a multiplayer mode where two players can control different snakes, competing to collect the most apples while answering trivia questions.
97 | - **Question Bank Expansion**: I aim to expand the trivia question bank to cover more categories and difficulty levels, making the game even more educational.
98 |
99 | ---
100 |
101 | ## How to Play
102 |
103 | 1. **Movement**: Use the arrow keys to control the direction of the snake.
104 | 2. **Objective**: Eat apples to score points.
105 | 3. **Trivia**: After each apple is eaten, answer a trivia question to continue the game.
106 | 4. **Game Over**: The game ends if the snake collides with itself or the game boundary.
107 |
108 | ---
109 |
110 | ## Installation
111 |
112 | 1. Clone the repository:
113 | ```bash
114 | git clone https://github.com/karabosithole/snake-game.git
115 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Java Multiple-Choice Quiz Game & Snake Game (Java and JavaScript)
2 |
3 | ## Overview
4 |
5 | This repository contains two projects:
6 | - A **Multiple-Choice Quiz Game** built in Java using the Swing framework.
7 | - A **Snake Game**, originally developed in Java, with a new version that can be played directly in the browser using JavaScript.
8 |
9 | Both projects aim to provide fun and educational experiences for users while showcasing Java programming concepts.
10 |
11 | For detailed documentation and project motivation, visit the [Wiki Home](https://github.com/Karabosithole/LearnJavaSnakeGame).
12 |
13 | ---
14 |
15 | ## Projects in This Repository
16 |
17 | ### 1. Multiple-Choice Quiz Game (Java)
18 |
19 | **Overview**:
20 | This is a simple multiple-choice quiz game built in Java using the Swing framework. The game randomly selects a Java-related question and presents it to the user along with four possible answers.
21 |
22 | - **Features**: Random question selection, immediate feedback, easy to extend with new questions.
23 | - **Technologies Used**: Java, Swing (for GUI).
24 |
25 | **Installation**:
26 | 1. Prerequisites: Java 8+ and a Java IDE or command-line tools.
27 | 2. Clone the repository and compile the code:
28 | ```bash
29 | git clone https://github.com/your-username/java-multiple-choice-quiz.git
30 | javac com/github/karabosithole/Main.java
31 | java com.github.karabosithole.Main
32 |
33 |
34 | # Java Multiple-Choice Quiz Game (Java)
35 |
36 | ## Overview
37 | This is a simple multiple-choice quiz game built in Java using the Swing framework. The game randomly selects a question from a pool of Java-related questions and presents it to the user along with four possible answers. The user must choose the correct answer from the options presented. Immediate feedback is given on whether the answer is correct or incorrect.
38 |
39 | For detailed documentation and project motivation, visit the [Wiki Home](https://github.com/Karabosithole/LearnJavaSnakeGame).
40 |
41 | ## Features
42 | - Multiple-choice questions related to Java programming.
43 | - Random question selection from a pool of predefined questions.
44 | - Interactive GUI using Java Swing for question display and user input.
45 | - Immediate feedback after each answer.
46 | - Easy to extend with additional questions and answers.
47 |
48 | ## Installation
49 |
50 | ### Prerequisites
51 | - Java 8 or higher
52 | - A Java IDE (e.g., IntelliJ IDEA, Eclipse) or simply `javac` for command-line compilation
53 |
54 | ### Steps
55 | 1. Clone this repository or download the source code:
56 | ```bash
57 | git clone https://github.com/your-username/java-multiple-choice-quiz.git
58 | ```
59 | 2. Open the project in your preferred Java IDE or navigate to the folder in the terminal.
60 | 3. Compile and run the `Main` class to start the quiz game.
61 |
62 | Using the terminal:
63 | ```bash
64 | javac com/github/karabosithole/Main.java
65 | java com.github.karabosithole.Main
66 | ```
67 |
68 | ## How to Play
69 | 1. When the game starts, a question will be displayed with four answer choices (A, B, C, D).
70 | 2. Select one of the answers from the dialog box.
71 | 3. You will receive immediate feedback on whether your answer was correct or incorrect.
72 | 4. The game will then ask the next question after a short delay.
73 |
74 | ### Example Flow
75 | 1. **Question**: What does JVM stand for?
76 | - A) Java Virtual Machine
77 | - B) Java Visual Model
78 | - C) Java Version Manager
79 | - D) Java Variable Model
80 |
81 | **Answer**: If the user selects "A) Java Virtual Machine," they receive a message indicating whether they were correct.
82 |
83 | ## Adding More Questions
84 | To add more questions to the game, follow these steps:
85 | 1. Open the `QuestionManager` class.
86 | 2. In the `initQuestions()` method, add a new `Question` object with your custom question, answer choices, and the index of the correct answer.
87 |
88 | ```bash
89 | Questions.add(new Question("Your custom question?",
90 | new String[] {"A) Option1", "B) Option2", "C) Option3", "D) Option4"},
91 | 2)); // Correct answer is the 3rd option (index 2)
92 | ```
93 |
94 | ## Technologies Used
95 | - **Java**: Programming language used to develop the game.
96 | - **Swing**: Java's GUI framework to display dialogs and capture user input.
97 |
98 | ## Credits
99 | Created by Karabo Sithole.
100 |
--------------------------------------------------------------------------------
/TeachMeJava.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/snake-game-js/game.js:
--------------------------------------------------------------------------------
1 | const questions = [
2 | {
3 | question: "What does JVM stand for?",
4 | answers: ["A) Java Virtual Machine", "B) Java Visual Model", "C) Java Version Manager", "D) Java Variable Model"],
5 | correct: 0
6 | },
7 | {
8 | question: "Which of these is not a Java keyword?",
9 | answers: ["A) public", "B) static", "C) void", "D) main"],
10 | correct: 3
11 | },
12 | {
13 | question: "What is the extension of Java files?",
14 | answers: ["A) .jav", "B) .java", "C) .class", "D) .js"],
15 | correct: 1
16 | },
17 | // Add more questions here
18 | ];
19 |
20 | let currentQuestionIndex = 0;
21 | let score = 0;
22 | let snake = [{ x: 10, y: 10 }];
23 | let apple = { x: 15, y: 15 };
24 | let gameCanvas = document.getElementById("gameCanvas");
25 | let ctx = gameCanvas.getContext("2d");
26 | let box = 20;
27 | let d;
28 | let gameSpeed = 200; // Adjust the speed of the game (lower is faster)
29 | let game;
30 |
31 | // Control whether the game is paused
32 | let isPaused = false;
33 |
34 | document.addEventListener("keydown", direction);
35 |
36 | function direction(event) {
37 | if (event.keyCode == 37 && d != "RIGHT") {
38 | d = "LEFT";
39 | } else if (event.keyCode == 38 && d != "DOWN") {
40 | d = "UP";
41 | } else if (event.keyCode == 39 && d != "LEFT") {
42 | d = "RIGHT";
43 | } else if (event.keyCode == 40 && d != "UP") {
44 | d = "DOWN";
45 | }
46 | }
47 |
48 | function draw() {
49 | if (isPaused) return; // Pause the game if isPaused is true
50 |
51 | ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
52 | for (let i = 0; i < snake.length; i++) {
53 | ctx.fillStyle = (i === 0) ? "green" : "white";
54 | ctx.fillRect(snake[i].x * box, snake[i].y * box, box, box);
55 | ctx.strokeStyle = "black";
56 | ctx.strokeRect(snake[i].x * box, snake[i].y * box, box, box);
57 | }
58 |
59 | ctx.fillStyle = "red";
60 | ctx.fillRect(apple.x * box, apple.y * box, box, box);
61 |
62 | let snakeX = snake[0].x;
63 | let snakeY = snake[0].y;
64 |
65 | if (d === "LEFT") snakeX--;
66 | if (d === "UP") snakeY--;
67 | if (d === "RIGHT") snakeX++;
68 | if (d === "DOWN") snakeY++;
69 |
70 | if (snakeX === apple.x && snakeY === apple.y) {
71 | score++;
72 | apple = {
73 | x: Math.floor(Math.random() * (gameCanvas.width / box)),
74 | y: Math.floor(Math.random() * (gameCanvas.height / box))
75 | };
76 | displayQuestion();
77 | } else {
78 | snake.pop();
79 | }
80 |
81 | // Check collision with itself or walls
82 | if (snakeX < 0 || snakeX >= gameCanvas.width / box || snakeY < 0 || snakeY >= gameCanvas.height / box || collision(snakeX, snakeY, snake)) {
83 | clearInterval(game);
84 | alert("Game Over! Score: " + score);
85 | }
86 |
87 | let newHead = { x: snakeX, y: snakeY };
88 | snake.unshift(newHead);
89 | }
90 |
91 | function collision(x, y, snake) {
92 | for (let i = 1; i < snake.length; i++) {
93 | if (snake[i].x === x && snake[i].y === y) {
94 | return true;
95 | }
96 | }
97 | return false;
98 | }
99 |
100 | // Display question when snake eats apple
101 | function displayQuestion() {
102 | isPaused = true; // Pause the game
103 | const questionElement = document.getElementById('question');
104 | const answersElement = document.getElementById('answers');
105 | const feedbackElement = document.getElementById('feedback');
106 | const nextButton = document.getElementById('next');
107 |
108 | feedbackElement.textContent = ''; // Clear feedback
109 | nextButton.style.display = 'none'; // Hide next button
110 |
111 | if (currentQuestionIndex < questions.length) {
112 | questionElement.textContent = questions[currentQuestionIndex].question;
113 | questionElement.style.display = 'block';
114 | answersElement.innerHTML = ''; // Clear previous answers
115 |
116 | questions[currentQuestionIndex].answers.forEach((answer, index) => {
117 | const button = document.createElement('button');
118 | button.textContent = answer;
119 | button.onclick = () => checkAnswer(index);
120 | answersElement.appendChild(button);
121 | });
122 | answersElement.style.display = 'block'; // Show answers
123 | } else {
124 | questionElement.textContent = 'Quiz Completed!';
125 | answersElement.innerHTML = '';
126 | nextButton.style.display = 'none';
127 | }
128 | }
129 |
130 | function checkAnswer(selectedIndex) {
131 | const feedbackElement = document.getElementById('feedback');
132 | const nextButton = document.getElementById('next');
133 | const currentQuestion = questions[currentQuestionIndex];
134 |
135 | if (selectedIndex === currentQuestion.correct) {
136 | feedbackElement.textContent = 'Correct!';
137 | } else {
138 | feedbackElement.textContent = 'Incorrect! The correct answer is: ' + currentQuestion.answers[currentQuestion.correct];
139 | }
140 |
141 | currentQuestionIndex++;
142 | nextButton.style.display = 'block'; // Show next button
143 | }
144 |
145 | document.getElementById('next').onclick = () => {
146 | const questionElement = document.getElementById('question');
147 | const answersElement = document.getElementById('answers');
148 |
149 | questionElement.style.display = 'none';
150 | answersElement.style.display = 'none';
151 | document.getElementById('feedback').textContent = ''; // Clear feedback
152 |
153 | isPaused = false; // Resume the game
154 | };
155 |
156 | // Start the game
157 | game = setInterval(draw, gameSpeed);
158 |
--------------------------------------------------------------------------------
/snake-game-js/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snake Game with Quiz
7 |
8 |
9 |
10 |
11 |
Snake Game with Quiz
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/snake-game-js/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Arial, sans-serif;
3 | background-color: #f4f4f4;
4 | display: flex;
5 | justify-content: center;
6 | align-items: center;
7 | height: 100vh;
8 | margin: 0;
9 | }
10 |
11 | .container {
12 | background: white;
13 | padding: 20px;
14 | border-radius: 10px;
15 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
16 | text-align: center;
17 | }
18 |
19 | canvas {
20 | background: #000;
21 | display: block;
22 | margin: 20px auto;
23 | }
24 |
25 | button {
26 | display: block;
27 | margin: 20px auto;
28 | padding: 10px 20px;
29 | border: none;
30 | background-color: #28a745;
31 | color: white;
32 | border-radius: 5px;
33 | cursor: pointer;
34 | }
35 |
36 | button:hover {
37 | background-color: #218838;
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/github/karabosithole/Board.java:
--------------------------------------------------------------------------------
1 | package com.github.karabosithole;
2 |
3 | import java.awt.Color;
4 | import java.awt.Dimension;
5 | import java.awt.Font;
6 | import java.awt.FontMetrics;
7 | import java.awt.Graphics;
8 | import java.awt.Image;
9 | import java.awt.Toolkit;
10 | import java.awt.event.ActionEvent;
11 | import java.awt.event.ActionListener;
12 | import java.awt.event.KeyAdapter;
13 | import java.awt.event.KeyEvent;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import javax.swing.*;
17 |
18 | /**
19 | * The Board class represents the game board for the Snake game.
20 | * It handles the game logic, rendering, and user input.
21 | */
22 | public class Board extends JPanel implements ActionListener {
23 |
24 | // Dimensions of the game board
25 | private final int B_WIDTH = 300;
26 | private final int B_HEIGHT = 300;
27 | private final int DOT_SIZE = 10;
28 | private final int ALL_DOTS = 900; // Maximum dots on the board
29 | private final int RAND_POS = 29; // Random position for apple
30 | private final int DELAY = 140; // Delay for game speed
31 |
32 | private final int x[] = new int[ALL_DOTS]; // X coordinates of the snake
33 | private final int y[] = new int[ALL_DOTS]; // Y coordinates of the snake
34 |
35 | private int dots; // Current length of the snake
36 | private int apple_x; // X coordinate of the apple
37 | private int apple_y; // Y coordinate of the apple
38 |
39 | // Direction flags for the snake movement
40 | private boolean leftDirection = false;
41 | private boolean rightDirection = true;
42 | private boolean upDirection = false;
43 | private boolean downDirection = false;
44 | private boolean inGame = true; // Game state
45 |
46 | private Timer timer; // Timer to control game speed
47 | private Image ball; // Image for the snake's body
48 | private Image apple; // Image for the apple
49 | private Image head; // Image for the snake's head
50 |
51 | // private List questions; // List of questions to ask
52 | private boolean gamePaused = false; // Pause flag
53 | private QuestionManager questionManager; // Use composition
54 | private Timer delayTimer;
55 |
56 | /**
57 | * Constructor to initialize the Board.
58 | */
59 | public Board() {
60 | initBoard();
61 | }
62 |
63 | /**
64 | * Initializes the game board settings and components.
65 | */
66 | private void initBoard() {
67 | addKeyListener(new TAdapter()); // Add key listener for controls
68 | setBackground(Color.black); // Set background color
69 | setFocusable(true); // Make the panel focusable
70 |
71 | setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT)); // Set preferred size
72 | loadImages(); // Load images for the game
73 | initGame(); // Initialize the game state
74 |
75 | questionManager = new QuestionManager();
76 |
77 | // Initialize questions
78 | // questions = new ArrayList<>();
79 | // questions.add("What does JVM stand for?");
80 | // questions.add("What is the difference between JDK and JRE?");
81 | // questions.add("What is a constructor in Java?");
82 | // questions.add("What is polymorphism?");
83 | // questions.add("What is an interface?");
84 | }
85 |
86 | /**
87 | * Loads images for the game elements.
88 | */
89 | private void loadImages() {
90 | ImageIcon iid = new ImageIcon("src/main/java/resources/dot.png");
91 | ball = iid.getImage();
92 |
93 | ImageIcon iia = new ImageIcon("src/main/java/resources/apple.png");
94 | apple = iia.getImage();
95 |
96 | ImageIcon iih = new ImageIcon("src/main/java/resources/head.png");
97 | head = iih.getImage();
98 | }
99 |
100 | /**
101 | * Initializes the game state and positions.
102 | */
103 | private void initGame() {
104 | dots = 3; // Set initial snake length
105 |
106 | // Initialize snake's starting position
107 | for (int z = 0; z < dots; z++) {
108 | x[z] = 50 - z * 10;
109 | y[z] = 50;
110 | }
111 |
112 | locateApple(); // Locate the first apple
113 |
114 | timer = new Timer(DELAY, this); // Create timer for game updates
115 | timer.start(); // Start the timer
116 | }
117 |
118 | /**
119 | * Paints the game components on the panel.
120 | *
121 | * @param g Graphics object for drawing
122 | */
123 | @Override
124 | public void paintComponent(Graphics g) {
125 | super.paintComponent(g); // Call parent method
126 |
127 | doDrawing(g); // Custom drawing
128 | }
129 |
130 | /**
131 | * Handles the custom drawing of game elements.
132 | *
133 | * @param g Graphics object for drawing
134 | */
135 | private void doDrawing(Graphics g) {
136 | if (inGame) {
137 | // Draw apple
138 | g.drawImage(apple, apple_x, apple_y, this);
139 |
140 | // Draw the snake
141 | for (int z = 0; z < dots; z++) {
142 | if (z == 0) {
143 | g.drawImage(head, x[z], y[z], this); // Draw head
144 | } else {
145 | g.drawImage(ball, x[z], y[z], this); // Draw body
146 | }
147 | }
148 |
149 | Toolkit.getDefaultToolkit().sync(); // Sync graphics
150 |
151 | } else {
152 | gameOver(g); // Show game over message
153 | }
154 | }
155 |
156 | /**
157 | * Displays the game over message.
158 | *
159 | * @param g Graphics object for drawing
160 | */
161 | private void gameOver(Graphics g) {
162 | String msg = "Game Over";
163 | Font small = new Font("Helvetica", Font.BOLD, 14);
164 | FontMetrics metr = getFontMetrics(small);
165 |
166 | //question box shows
167 | g.setColor(Color.white); // Set color for text
168 | g.setFont(small); // Set font for text
169 | g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2, B_HEIGHT / 2); // Center the message
170 | }
171 |
172 | /**
173 | * Checks if the snake has eaten an apple and updates the game state.
174 | */
175 | private void checkApple() {
176 | if ((x[0] == apple_x) && (y[0] == apple_y)) {
177 | dots++; // Increase snake length
178 | locateApple(); // Locate new apple
179 |
180 | // Pause the game before showing the question
181 | pauseGame();
182 |
183 | questionManager.displayQuestion();
184 |
185 | // Start a delay before resuming the game
186 | addResumeDelay();
187 |
188 | // // Show a random question
189 | // int randomIndex = (int) (Math.random() * questions.size());
190 | // String question = questions.get(randomIndex);
191 | // JOptionPane.showMessageDialog(this, question, "Java Question", JOptionPane.INFORMATION_MESSAGE);
192 | }
193 | }
194 |
195 | // Pause the game by stopping the timer
196 | private void pauseGame() {
197 | gamePaused = true;
198 | timer.stop(); // Stop the timer to pause game updates
199 | }
200 |
201 | // Resume the game by restarting the timer
202 | private void resumeGame() {
203 | gamePaused = false;
204 | timer.start(); // Restart the timer to continue game updates
205 | }
206 |
207 | // Add a delay before resuming the game
208 | private void addResumeDelay() {
209 | // Create a new Timer for a 1 second delay (1000ms)
210 | delayTimer = new Timer(1000, new ActionListener() {
211 | @Override
212 | public void actionPerformed(ActionEvent e) {
213 | // After 1 second, resume the game
214 | resumeGame();
215 | delayTimer.stop(); // Stop the delay timer
216 | }
217 | });
218 |
219 | // Start the delay timer
220 | delayTimer.setRepeats(false); // We want this to happen only once
221 | delayTimer.start();
222 | }
223 |
224 | /**
225 | * Moves the snake in the current direction.
226 | */
227 | private void move() {
228 | for (int z = dots; z > 0; z--) {
229 | x[z] = x[(z - 1)]; // Move body segments
230 | y[z] = y[(z - 1)];
231 | }
232 |
233 | // Update head position based on direction
234 | if (leftDirection) {
235 | x[0] -= DOT_SIZE;
236 | }
237 |
238 | if (rightDirection) {
239 | x[0] += DOT_SIZE;
240 | }
241 |
242 | if (upDirection) {
243 | y[0] -= DOT_SIZE;
244 | }
245 |
246 | if (downDirection) {
247 | y[0] += DOT_SIZE;
248 | }
249 | }
250 |
251 | /**
252 | * Checks for collisions with walls or the snake itself.
253 | */
254 | private void checkCollision() {
255 | // Check for collision with body
256 | for (int z = dots; z > 0; z--) {
257 | if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {
258 | inGame = false; // Collision detected
259 | }
260 | }
261 |
262 | // Check for collision with walls
263 | if (y[0] >= B_HEIGHT || y[0] < 0 || x[0] >= B_WIDTH || x[0] < 0) {
264 | inGame = false; // Out of bounds
265 | }
266 |
267 | if (!inGame) {
268 | timer.stop(); // Stop the game timer
269 | }
270 | }
271 |
272 | /**
273 | * Locates the apple at a random position on the board.
274 | */
275 | private void locateApple() {
276 | int r = (int) (Math.random() * RAND_POS);
277 | apple_x = ((r * DOT_SIZE)); // Calculate X position
278 |
279 | r = (int) (Math.random() * RAND_POS);
280 | apple_y = ((r * DOT_SIZE)); // Calculate Y position
281 | }
282 |
283 | /**
284 | * Handles the timer event for updating the game state.
285 | *
286 | * @param e ActionEvent triggered by the timer
287 | */
288 | @Override
289 | public void actionPerformed(ActionEvent e) {
290 | if (inGame) {
291 | checkApple(); // Check for apple consumption
292 | checkCollision(); // Check for collisions
293 | move(); // Move the snake
294 | }
295 |
296 | repaint(); // Refresh the display
297 | }
298 |
299 | /**
300 | * KeyAdapter for handling user input for snake movement.
301 | */
302 | private class TAdapter extends KeyAdapter {
303 | @Override
304 | public void keyPressed(KeyEvent e) {
305 | int key = e.getKeyCode(); // Get the key code
306 |
307 | // Change direction based on key press
308 | if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
309 | leftDirection = true;
310 | upDirection = false;
311 | downDirection = false;
312 | }
313 |
314 | if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
315 | rightDirection = true;
316 | upDirection = false;
317 | downDirection = false;
318 | }
319 |
320 | if ((key == KeyEvent.VK_UP) && (!downDirection)) {
321 | upDirection = true;
322 | rightDirection = false;
323 | leftDirection = false;
324 | }
325 |
326 | if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
327 | downDirection = true;
328 | rightDirection = false;
329 | leftDirection = false;
330 | }
331 | }
332 | }
333 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/karabosithole/Question.java:
--------------------------------------------------------------------------------
1 | package com.github.karabosithole;
2 |
3 | public class Question {
4 | private String questionText;
5 | private String[] choices;
6 | private int correctAnswerIndex;
7 |
8 | public Question(String questionText, String[] choices, int correctAnswerIndex) {
9 | this.questionText = questionText;
10 | this.choices = choices;
11 | this.correctAnswerIndex = correctAnswerIndex;
12 | }
13 |
14 | public String getQuestionText() {
15 | return questionText;
16 | }
17 |
18 | public String[] getChoices() {
19 | return choices;
20 | }
21 |
22 | public int getCorrectAnswerIndex() {
23 | return correctAnswerIndex;
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/src/main/java/com/github/karabosithole/QuestionManager.java:
--------------------------------------------------------------------------------
1 | package com.github.karabosithole;
2 |
3 | import javax.swing.*;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | public class QuestionManager {
8 | private List questions; // List of Question objects
9 |
10 | public QuestionManager() {
11 | initQuestions();
12 | }
13 |
14 | // Initialize questions with multiple choices
15 | public void initQuestions() {
16 | questions = new ArrayList<>();
17 |
18 | // Add a question with its choices and the correct answer
19 | questions.add(new Question("What does JVM stand for?",
20 | new String[] {"A) Java Virtual Machine", "B) Java Visual Model", "C) Java Version Manager", "D) Java Variable Model"},
21 | 0)); // Correct answer is index 0 ("Java Virtual Machine")
22 |
23 | questions.add(new Question("What is the difference between JDK and JRE?",
24 | new String[] {"A) JDK is for development; JRE is for running Java", "B) JDK is faster than JRE", "C) JRE is the latest version of JDK", "D) JDK is for UI, JRE for back-end"},
25 | 0));
26 |
27 | questions.add(new Question("What is a constructor in Java?",
28 | new String[] {"A) A method to create objects", "B) A special method to initialize objects", "C) A class that builds other classes", "D) A template for creating objects"},
29 | 1));
30 |
31 | questions.add(new Question("What is polymorphism?",
32 | new String[] {"A) Ability to take many forms", "B) A type of inheritance", "C) Java method overloading", "D) The ability to create abstract methods"},
33 | 0));
34 |
35 | questions.add(new Question("What is an interface?",
36 | new String[] {"A) A class that extends another class", "B) A blueprint for classes", "C) A method signature", "D) A way to inherit multiple classes"},
37 | 1));
38 | }
39 |
40 | // Retrieve a random question
41 | public Question getRandomQuestion() {
42 | int randomIndex = (int) (Math.random() * questions.size());
43 | return questions.get(randomIndex);
44 | }
45 |
46 | // Display the question and handle the user's answer
47 | public void displayQuestion() {
48 | Question question = getRandomQuestion();
49 |
50 | // Show the question with multiple choices
51 | String selectedAnswer = (String) JOptionPane.showInputDialog(
52 | null,
53 | question.getQuestionText(),
54 | "Multiple Choice Question",
55 | JOptionPane.QUESTION_MESSAGE,
56 | null,
57 | question.getChoices(), // The array of choices (A, B, C, D)
58 | question.getChoices()[0]); // Default selection (optional)
59 |
60 | // Check if the selected answer is correct
61 | int selectedIndex = java.util.Arrays.asList(question.getChoices()).indexOf(selectedAnswer);
62 | if (selectedIndex == question.getCorrectAnswerIndex()) {
63 | JOptionPane.showMessageDialog(null, "Correct!", "Answer", JOptionPane.INFORMATION_MESSAGE);
64 | } else {
65 | JOptionPane.showMessageDialog(null, "Wrong answer. The correct answer is: " + question.getChoices()[question.getCorrectAnswerIndex()], "Answer", JOptionPane.ERROR_MESSAGE);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/github/karabosithole/Snake.java:
--------------------------------------------------------------------------------
1 | package com.github.karabosithole;
2 |
3 | import java.awt.EventQueue;
4 | import javax.swing.JFrame;
5 |
6 |
7 | /**
8 | * The Snake class represents the main window for the Snake game.
9 | * It extends JFrame to create the game UI and manage the game board.
10 | */
11 | public class Snake extends JFrame {
12 |
13 | /**
14 | * Constructor to initialize the Snake game UI.
15 | */
16 |
17 | public Snake() {
18 | initUI(); // Initialize the user interface
19 | }
20 |
21 | /**
22 | * Initializes the user interface components for the game.
23 | */
24 | private void initUI() {
25 | add(new Board()); // Add the game board to the frame
26 |
27 | setResizable(false); // Disable resizing of the window
28 | pack(); // Pack the components within the frame
29 |
30 | setTitle("Snake"); // Set the title of the window
31 | setLocationRelativeTo(null); // Center the window on the screen
32 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Exit the application on close
33 | }
34 |
35 | /**
36 | * The main method to launch the Snake game application.
37 | *
38 | * @param args Command line arguments
39 | */
40 | public static void main(String[] args) {
41 | // Use EventQueue to ensure that the UI is created on the Event Dispatch Thread
42 | EventQueue.invokeLater(() -> {
43 | JFrame ex = new Snake(); // Create an instance of Snake
44 | ex.setVisible(true); // Make the frame visible
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/resources/apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/src/main/java/resources/apple.png
--------------------------------------------------------------------------------
/src/main/java/resources/dot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/src/main/java/resources/dot.png
--------------------------------------------------------------------------------
/src/main/java/resources/head.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/src/main/java/resources/head.png
--------------------------------------------------------------------------------
/src/main/java/resources/questions.txt:
--------------------------------------------------------------------------------
1 | questions:
2 | - id: "start"
3 | text: "What is the keyword to define a class in Java?"
4 | answer: "class"
5 |
6 | - id: "left"
7 | text: "Which method is the entry point of a Java application?"
8 | answer: "main"
9 |
10 | - id: "right"
11 | text: "Which Java keyword is used to create an object?"
12 | answer: "new"
13 |
14 | - id: "swim"
15 | text: "What does 'JVM' stand for?"
16 | answer: "Java Virtual Machine"
17 |
18 | - id: "walk"
19 | text: "What is the parent class of all classes in Java?"
20 | answer: "Object"
21 |
22 | - id: "climb"
23 | text: "What keyword is used to inherit a class in Java?"
24 | answer: "extends"
25 |
26 | - id: "around"
27 | text: "What is the interface keyword used for?"
28 | answer: "interface"
29 |
30 | - id: "left2"
31 | text: "What is polymorphism?"
32 | answer: "The ability of an object to take on many forms"
33 |
34 | - id: "right2"
35 | text: "What is encapsulation?"
36 | answer: "The wrapping of data and methods into a single unit"
37 |
38 | - id: "swim2"
39 | text: "What is inheritance?"
40 | answer: "The mechanism where one class acquires the properties and behaviors of a parent class"
41 |
42 | - id: "walk2"
43 | text: "What is abstraction?"
44 | answer: "The concept of hiding the complex implementation details and showing only the necessary features"
45 |
46 | - id: "climb2"
47 | text: "What is a constructor?"
48 | answer: "A special method used to initialize objects"
49 |
50 | - id: "around2"
51 | text: "What is method overloading?"
52 | answer: "Having multiple methods in the same class with the same name but different parameters"
53 |
--------------------------------------------------------------------------------
/target/classes/com/github/karabosithole/Board$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/target/classes/com/github/karabosithole/Board$1.class
--------------------------------------------------------------------------------
/target/classes/com/github/karabosithole/Board$TAdapter.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/target/classes/com/github/karabosithole/Board$TAdapter.class
--------------------------------------------------------------------------------
/target/classes/com/github/karabosithole/Board.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/target/classes/com/github/karabosithole/Board.class
--------------------------------------------------------------------------------
/target/classes/com/github/karabosithole/Question.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/target/classes/com/github/karabosithole/Question.class
--------------------------------------------------------------------------------
/target/classes/com/github/karabosithole/QuestionManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/target/classes/com/github/karabosithole/QuestionManager.class
--------------------------------------------------------------------------------
/target/classes/com/github/karabosithole/Snake.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Karabosithole/LearnJavaSnakeGame/4cfab7f05c48c0abddeefe36259d49f87de24766/target/classes/com/github/karabosithole/Snake.class
--------------------------------------------------------------------------------