Building the Banana Game: Exploring Software Development Through MERN Stack and API Integration
Ever wondered how a simple idea transforms into an engaging gaming experience through code? Enter The Banana Game, a project I developed using the MERN stack (MongoDB, Express.js, React, Node.js) and the Banana API. This game is more than just a fun way to pass time — it’s a showcase of modern web development, encompassing React for the UI, Node.js for the backend, MongoDB for the database, and CSS for styling.
Hi, I’m Benjamin, and I’m thrilled to introduce you to this project I developed using the MERN stack and the Banana API. This game offers an engaging and competitive experience while showcasing core development practices. Let’s dive into how it works and the technical magic behind it.
How the Banana Game Works
- Login & Registration
- Registration: New users can create a virtual identity with a username, email, and password.
- Login: After registration, users are directed to the login screen. Once logged in, they’re greeted with a simple and intuitive homepage featuring navigation options: Start Game, Leaderboard, Profile, and Logout.
2. Game Mechanics
- Players start with 4 lives. Answering a question incorrectly results in losing a life.
- A countdown timer adds urgency, keeping the gameplay exciting. Correct answers are rewarded by updating the BestTime, which dynamically reflects in the user database.
3. Leaderboard
- The leaderboard ranks the top 9 players by their BestTime, fostering friendly competition and motivation to improve.
4. Profile Section
- Users can track their progress, including games played, games won, games lost, and streaks.
5. Logout
- A secure logout feature redirects players to the login screen, ensuring data protection.
Check out the repository here: [GitHub Link]
Core Themes in Development
- Software Design Principles
The project employs a component-based architecture for scalability and maintainability. Key highlights include:
- Separation of concerns: Each component focuses on a specific task. For example,
StartGame
handles game logic, whileLeaderboard
focuses on player rankings. - State management: A centralized UserContext ensures data consistency, following the Model-View-Controller (MVC) pattern.
Breaking Down the Code
1. Frontend: React and CSS
The game’s frontend is built using React, leveraging its component-based architecture for modularity and scalability. Here’s how React powers the Banana Game:
- Component-Based Design:
- The
StartGame
component handles gameplay logic, including managing user lives and tracking time. - The
Leaderboard
component fetches and displays top players using API calls to the backend. - The
Profile
component renders player-specific stats using state management viaUserContext
.
// Sample React Component for Leaderboard
function Leaderboard() {
const [leaders, setLeaders] = useState([]);
useEffect(() => {
fetch('/api/leaderboard')
.then((res) => res.json())
.then((data) => setLeaders(data))
.catch((error) => console.error("Error fetching leaderboard:", error));
}, []);
return (
<div className="leaderboard">
<h2>Top Players</h2>
<ul>
{leaders.map((player, index) => (
<li key={index}>
{index + 1}. {player.username} - Best Time: {player.bestTime}s
</li>
))}
</ul>
</div>
);
}
- Styling with CSS:
The Banana Game features a clean and simple design, achieved through custom CSS for the login screen, game UI, and leaderboard.
.leaderboard {
text-align: center;
background-color: #f8f9fa;
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.leaderboard ul {
list-style: none;
padding: 0;
}
.leaderboard li {
font-size: 1.2rem;
margin: 5px 0;
}
2. Backend: Node.js and Express.js
The backend is built with Node.js and Express.js, ensuring a robust API layer for communication between the frontend and database.
- Express Routes for API Endpoints:
// Leaderboard API Endpoint
app.get('/api/leaderboard', async (req, res) => {
try {
const topPlayers = await User.find().sort({ bestTime: 1 }).limit(9);
res.json(topPlayers);
} catch (error) {
res.status(500).send("Error fetching leaderboard data");
}
});
- Handling Authentication:
bcrypt is used to hash passwords during registration and verify them during login, ensuring secure user authentication.
const bcrypt = require('bcrypt');
app.post('/api/register', async (req, res) => {
const { username, password, email } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = new User({ username, password: hashedPassword, email });
await newUser.save();
res.status(201).send("User registered successfully");
});
3. Database: MongoDB with Mongoose
User data, including stats and hashed passwords, is stored in a MongoDB Atlas database. The Mongoose library simplifies schema definitions and database queries.
- Schema Definition for Users:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: { type: String, required: true },
password: { type: String, required: true },
email: { type: String, required: true },
gamesPlayed: { type: Number, default: 0 },
gamesWon: { type: Number, default: 0 },
bestTime: { type: Number, default: null },
});
const User = mongoose.model('User', userSchema);
module.exports = User;
4. Gameplay Logic: Event-Driven Programming
The countdown timer and gameplay logic are powered by event-driven programming, creating a dynamic and responsive user experience.
- Countdown Timer in React:
useEffect(() => {
const timer = setInterval(() => {
setTimeLeft((prevTime) => (prevTime > 0 ? prevTime - 1 : 0));
}, 1000);
return () => clearInterval(timer);
}, []);
- Dynamic Gameplay Events:
- Correct answers update the BestTime in the database.
- Incorrect answers reduce user lives, triggering UI updates.
5. Integration with the Banana API
The game leverages the Banana API to fetch questions dynamically, making gameplay more diverse and engaging.
app.get('/api/questions', async (req, res) => {
try {
const questions = await bananaAPI.fetchQuestions();
res.json(questions);
} catch (error) {
res.status(500).send("Error fetching questions from Banana API");
}
});
Reflection on the Development Process
- Frontend Excellence:
React’s component-based design made the UI modular and scalable, while CSS added a polished, user-friendly appearance. - Secure Backend:
Node.js and Express provided a reliable backend structure, while bcrypt ensured secure user authentication. - Database Integration:
MongoDB handled data efficiently, but error handling during database queries could be improved. - API Interoperability:
The Banana API integration added unique value to the game, but better fallback mechanisms for API downtimes are needed.
Conclusion
The Banana Game is a testament to the capabilities of modern web development. Combining React, Node.js, Express, MongoDB, and the Banana API, it delivers an engaging gaming experience while showcasing robust software design principles, event-driven programming, and secure user management.
If you’re inspired by this project or have questions, let’s connect in the comments! Follow my Medium for more exciting content.
Explore More:
- GitHub Repository: Link to Repo
- LinkedIn: My LinkedIn Profile
Let’s build something amazing together.