Skip to content
This repository was archived by the owner on Apr 23, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ A browser-based space race game where players navigate a spaceship through space
- Progressive difficulty that increases over time
- Particle effects for collisions and explosions
- Local storage for high score tracking
- Theme toggle between light and dark modes

## Game Mechanics

Expand All @@ -27,6 +28,7 @@ A browser-based space race game where players navigate a spaceship through space
### Getting Started
1. Open `index.html` in a web browser
2. Click the "Start Game" button on the welcome screen
3. Use the theme toggle button in the top-right corner to switch between light and dark modes

### Controls
- **Keyboard Controls:**
Expand Down
48 changes: 47 additions & 1 deletion game.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ const GAME_CONFIG = {
DIFFICULTY_INCREASE_RATE: 0.0001, // Per frame
};

// Theme configuration
const THEME_CONFIG = {
STORAGE_KEY: 'spaceRaceTheme',
DEFAULT_THEME: 'dark',
};

// Game state
let gameState = {
isRunning: false,
Expand All @@ -35,6 +41,11 @@ const restartBtn = document.getElementById('restartBtn');
const startModal = document.getElementById('startModal');
const startBtn = document.getElementById('startBtn');

// Theme toggle elements
const themeToggle = document.getElementById('themeToggle');
const sunIcon = document.getElementById('sunIcon');
const moonIcon = document.getElementById('moonIcon');

// Mobile controls
const leftBtn = document.getElementById('leftBtn');
const rightBtn = document.getElementById('rightBtn');
Expand All @@ -53,11 +64,46 @@ function resizeCanvas() {
}
}

// Theme functions
function initTheme() {
// Get saved theme or use default
const savedTheme = localStorage.getItem(THEME_CONFIG.STORAGE_KEY) || THEME_CONFIG.DEFAULT_THEME;
setTheme(savedTheme);

// Set up theme toggle event listener
themeToggle.addEventListener('click', toggleTheme);
}

function setTheme(theme) {
// Apply theme to document
if (theme === 'light') {
document.documentElement.setAttribute('data-theme', 'light');
sunIcon.classList.add('hidden');
moonIcon.classList.remove('hidden');
} else {
document.documentElement.removeAttribute('data-theme');
moonIcon.classList.add('hidden');
sunIcon.classList.remove('hidden');
}

// Save theme preference
localStorage.setItem(THEME_CONFIG.STORAGE_KEY, theme);
}

function toggleTheme() {
const currentTheme = localStorage.getItem(THEME_CONFIG.STORAGE_KEY) || THEME_CONFIG.DEFAULT_THEME;
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
setTheme(newTheme);
}

// Initialize the game
function initGame() {
resizeCanvas();
window.addEventListener('resize', resizeCanvas);

// Initialize theme
initTheme();

// Set high score display
highScoreDisplay.textContent = gameState.highScore;

Expand Down Expand Up @@ -691,4 +737,4 @@ function gameLoop() {
}

// Initialize the game when the page loads
window.addEventListener('load', initGame);
window.addEventListener('load', initGame);
36 changes: 23 additions & 13 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body class="bg-black text-white flex flex-col items-center justify-center min-h-screen p-4">
<body class="flex flex-col items-center justify-center min-h-screen p-4">
<div class="theme-toggle" id="themeToggle" title="Toggle light/dark theme">
<!-- Sun icon (for dark mode) -->
<svg id="sunIcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 2.25a.75.75 0 01.75.75v2.25a.75.75 0 01-1.5 0V3a.75.75 0 01.75-.75zM7.5 12a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0zM18.894 6.166a.75.75 0 00-1.06-1.06l-1.591 1.59a.75.75 0 101.06 1.061l1.591-1.59zM21.75 12a.75.75 0 01-.75.75h-2.25a.75.75 0 010-1.5H21a.75.75 0 01.75.75zM17.834 18.894a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 10-1.061 1.06l1.59 1.591zM12 18a.75.75 0 01.75.75V21a.75.75 0 01-1.5 0v-2.25A.75.75 0 0112 18zM7.758 17.303a.75.75 0 00-1.061-1.06l-1.591 1.59a.75.75 0 001.06 1.061l1.591-1.59zM6 12a.75.75 0 01-.75.75H3a.75.75 0 010-1.5h2.25A.75.75 0 016 12zM6.697 7.757a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 00-1.061 1.06l1.59 1.591z" />
</svg>
<!-- Moon icon (for light mode) -->
<svg id="moonIcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="hidden">
<path d="M9.528 1.718a.75.75 0 01.162.819A8.97 8.97 0 009 6a9 9 0 009 9 8.97 8.97 0 003.463-.69.75.75 0 01.981.98 10.503 10.503 0 01-9.694 6.46c-5.799 0-10.5-4.701-10.5-10.5 0-4.368 2.667-8.112 6.46-9.694a.75.75 0 01.818.162z" />
</svg>
</div>
<h1 class="text-4xl font-bold mb-4 text-center text-blue-400">Space Race</h1>

<div class="relative w-full max-w-2xl">
Expand All @@ -18,16 +28,16 @@ <h1 class="text-4xl font-bold mb-4 text-center text-blue-400">Space Race</h1>
</div>

<!-- Game canvas -->
<canvas id="gameCanvas" class="border-2 border-blue-500 bg-gray-900 w-full"></canvas>
<canvas id="gameCanvas" class="border-2 w-full"></canvas>

<!-- Game controls for mobile -->
<div class="mt-4 grid grid-cols-3 gap-2 md:hidden">
<button id="leftBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">←</button>
<div class="mt-4 grid grid-cols-3 gap-2 md:hidden">
<button id="leftBtn" class="game-button font-bold py-2 px-4 rounded">←</button>
<div class="grid grid-cols-1 gap-2">
<button id="upBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">↑</button>
<button id="downBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">↓</button>
<button id="upBtn" class="game-button font-bold py-2 px-4 rounded">↑</button>
<button id="downBtn" class="game-button font-bold py-2 px-4 rounded">↓</button>
</div>
<button id="rightBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">→</button>
<button id="rightBtn" class="game-button font-bold py-2 px-4 rounded">→</button>
</div>
</div>

Expand All @@ -39,23 +49,23 @@ <h2 class="text-2xl font-bold mb-2 text-blue-400">How to Play</h2>
</div>

<!-- Game over modal -->
<div id="gameOverModal" class="hidden fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-10">
<div class="bg-gray-800 p-8 rounded-lg max-w-md w-full text-center">
<div id="gameOverModal" class="hidden fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-10">
<div class="modal-content p-8 rounded-lg max-w-md w-full text-center">
<h2 class="text-3xl font-bold mb-4 text-red-500">Game Over</h2>
<p class="text-xl mb-4">Your score: <span id="finalScore">0</span></p>
<button id="restartBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-full text-lg">Play Again</button>
<button id="restartBtn" class="game-button font-bold py-2 px-6 rounded-full text-lg">Play Again</button>
</div>
</div>

<!-- Game start modal -->
<div id="startModal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-10">
<div class="bg-gray-800 p-8 rounded-lg max-w-md w-full text-center">
<div class="modal-content p-8 rounded-lg max-w-md w-full text-center">
<h2 class="text-3xl font-bold mb-4 text-blue-400">Space Race</h2>
<p class="text-xl mb-6">Navigate through space, avoid obstacles, and survive as long as possible!</p>
<button id="startBtn" class="bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-6 rounded-full text-lg">Start Game</button>
<button id="startBtn" class="game-button font-bold py-2 px-6 rounded-full text-lg">Start Game</button>
</div>
</div>

<script src="game.js"></script>
</body>
</html>
</html>
94 changes: 93 additions & 1 deletion styles.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,57 @@
/* Custom styles beyond Tailwind */

/* Theme variables */
:root {
/* Dark theme (default) */
--bg-color: #000000;
--text-color: #ffffff;
--primary-color: #3B82F6; /* blue-500 */
--secondary-color: #1F2937; /* gray-800 */
--canvas-bg: #111827; /* gray-900 */
--border-color: #3B82F6; /* blue-500 */
--button-bg: #2563EB; /* blue-600 */
--button-hover: #1D4ED8; /* blue-700 */
--modal-bg: #1F2937; /* gray-800 */
}

/* Light theme */
[data-theme="light"] {
--bg-color: #f3f4f6; /* gray-100 */
--text-color: #1f2937; /* gray-800 */
--primary-color: #2563EB; /* blue-600 */
--secondary-color: #e5e7eb; /* gray-200 */
--canvas-bg: #e5e7eb; /* gray-200 */
--border-color: #2563EB; /* blue-600 */
--button-bg: #2563EB; /* blue-600 */
--button-hover: #1D4ED8; /* blue-700 */
--modal-bg: #ffffff;
}

/* Apply theme colors */
body {
background-color: var(--bg-color);
color: var(--text-color);
}

#gameCanvas {
background-color: var(--canvas-bg);
border-color: var(--border-color);
}

.game-button {
background-color: var(--button-bg);
color: white;
transition: background-color 0.3s ease;
}

.game-button:hover {
background-color: var(--button-hover);
}

.modal-content {
background-color: var(--modal-bg);
}

/* Canvas sizing */
#gameCanvas {
aspect-ratio: 16/9;
Expand All @@ -23,10 +75,50 @@
pointer-events: none;
}

/* Theme toggle styles */
.theme-toggle {
position: absolute;
top: 1rem;
right: 1rem;
background-color: var(--secondary-color);
border: 2px solid var(--primary-color);
border-radius: 50%;
width: 2.5rem;
height: 2.5rem;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
z-index: 20;
}

.theme-toggle:hover {
transform: scale(1.1);
}

.theme-toggle svg {
width: 1.5rem;
height: 1.5rem;
fill: var(--primary-color);
}

/* Mobile controls improvements */
@media (max-width: 768px) {
#gameCanvas {
aspect-ratio: 3/4;
max-height: 60vh;
}
}

.theme-toggle {
top: 0.5rem;
right: 0.5rem;
width: 2rem;
height: 2rem;
}

.theme-toggle svg {
width: 1.2rem;
height: 1.2rem;
}
}