mirror of
https://github.com/JorySeverijnse/ui-fixer-supreme.git
synced 2025-12-06 13:36:57 +00:00
Compare commits
4 Commits
f0091bbd23
...
d09cda3510
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d09cda3510 | ||
|
|
225b337a27 | ||
|
|
6ff0bbb8ef | ||
|
|
1d011db6f8 |
@ -22,6 +22,7 @@ const MatrixRain = ({ color = '#00FF00' }: MatrixRainProps) => {
|
|||||||
const fontSize = 16;
|
const fontSize = 16;
|
||||||
let columns: number;
|
let columns: number;
|
||||||
let rainDrops: number[] = [];
|
let rainDrops: number[] = [];
|
||||||
|
let animationStarted = false;
|
||||||
|
|
||||||
const katakana = 'アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッン';
|
const katakana = 'アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッン';
|
||||||
const latin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
const latin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
@ -29,18 +30,23 @@ const MatrixRain = ({ color = '#00FF00' }: MatrixRainProps) => {
|
|||||||
const alphabet = katakana + latin + nums;
|
const alphabet = katakana + latin + nums;
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
canvas.width = window.innerWidth;
|
// Use document dimensions for reliability
|
||||||
canvas.height = window.innerHeight;
|
const width = document.documentElement.clientWidth || window.innerWidth;
|
||||||
|
const height = document.documentElement.clientHeight || window.innerHeight;
|
||||||
|
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
columns = Math.floor(canvas.width / fontSize);
|
columns = Math.floor(canvas.width / fontSize);
|
||||||
rainDrops = [];
|
rainDrops = [];
|
||||||
for (let x = 0; x < columns; x++) {
|
for (let x = 0; x < columns; x++) {
|
||||||
rainDrops[x] = Math.random() * canvas.height / fontSize;
|
rainDrops[x] = Math.random() * canvas.height / fontSize;
|
||||||
}
|
}
|
||||||
|
animationStarted = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
const draw = () => {
|
const draw = () => {
|
||||||
|
if (!animationStarted) return;
|
||||||
|
|
||||||
ctx.fillStyle = 'rgba(0, 0, 0, 0.04)';
|
ctx.fillStyle = 'rgba(0, 0, 0, 0.04)';
|
||||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
@ -58,12 +64,19 @@ const MatrixRain = ({ color = '#00FF00' }: MatrixRainProps) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Initialize after a brief delay to ensure DOM is ready
|
||||||
|
const initTimeout = setTimeout(init, 50);
|
||||||
const interval = setInterval(draw, 30);
|
const interval = setInterval(draw, 30);
|
||||||
|
|
||||||
const handleResize = () => init();
|
const handleResize = () => {
|
||||||
|
init();
|
||||||
|
};
|
||||||
|
|
||||||
window.addEventListener('resize', handleResize);
|
window.addEventListener('resize', handleResize);
|
||||||
|
window.addEventListener('orientationchange', () => setTimeout(init, 150));
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
clearTimeout(initTimeout);
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
window.removeEventListener('resize', handleResize);
|
window.removeEventListener('resize', handleResize);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -51,9 +51,10 @@ const Breakout = () => {
|
|||||||
const isMobile = window.innerWidth < 768;
|
const isMobile = window.innerWidth < 768;
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
const maxWidth = window.innerWidth - 32;
|
const maxWidth = window.innerWidth - 32;
|
||||||
const maxHeight = window.innerHeight - 280;
|
// Reserve space for: header(50) + stats(40) + controls(80) + margins(30) = 200
|
||||||
|
const maxHeight = window.innerHeight - 200;
|
||||||
const aspectRatio = 480 / 580;
|
const aspectRatio = 480 / 580;
|
||||||
let width = maxWidth;
|
let width = Math.min(maxWidth, 400);
|
||||||
let height = width / aspectRatio;
|
let height = width / aspectRatio;
|
||||||
if (height > maxHeight) { height = maxHeight; width = height * aspectRatio; }
|
if (height > maxHeight) { height = maxHeight; width = height * aspectRatio; }
|
||||||
return { width: Math.floor(width), height: Math.floor(height) };
|
return { width: Math.floor(width), height: Math.floor(height) };
|
||||||
@ -269,7 +270,7 @@ const Breakout = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<div className="mt-4 flex flex-col items-center gap-2 w-full">
|
<div className="mt-2 flex flex-col items-center gap-1 w-full flex-shrink-0">
|
||||||
<div className="flex gap-4 text-center">
|
<div className="flex gap-4 text-center">
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">SCORE</p><p className="font-minecraft text-sm text-primary">{score.toLocaleString()}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">SCORE</p><p className="font-minecraft text-sm text-primary">{score.toLocaleString()}</p></div>
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">HIGH</p><p className="font-minecraft text-sm text-primary">{highScore.toLocaleString()}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">HIGH</p><p className="font-minecraft text-sm text-primary">{highScore.toLocaleString()}</p></div>
|
||||||
@ -277,10 +278,10 @@ const Breakout = () => {
|
|||||||
<div><p className="font-pixel text-[8px] text-foreground/60">♥</p><p className="font-minecraft text-sm text-primary">{lives}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">♥</p><p className="font-minecraft text-sm text-primary">{lives}</p></div>
|
||||||
</div>
|
</div>
|
||||||
{gameStarted && !gameOver && (
|
{gameStarted && !gameOver && (
|
||||||
<div className="flex gap-4 mt-2">
|
<div className="flex gap-4 mt-1">
|
||||||
<GameTouchButton onAction={moveLeft} className="p-4 px-8 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg" interval={30}>←</GameTouchButton>
|
<GameTouchButton onAction={moveLeft} className="p-3 px-6 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg" interval={30}>←</GameTouchButton>
|
||||||
<button onClick={() => setIsPaused(p => !p)} className="p-4 px-6 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px] select-none">{isPaused ? '▶' : '❚❚'}</button>
|
<button onClick={() => setIsPaused(p => !p)} className="p-3 px-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px] select-none">{isPaused ? '▶' : '❚❚'}</button>
|
||||||
<GameTouchButton onAction={moveRight} className="p-4 px-8 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg" interval={30}>→</GameTouchButton>
|
<GameTouchButton onAction={moveRight} className="p-3 px-6 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg" interval={30}>→</GameTouchButton>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{(!gameStarted || gameOver) && (
|
{(!gameStarted || gameOver) && (
|
||||||
|
|||||||
@ -73,8 +73,9 @@ const Pacman = () => {
|
|||||||
if (typeof window === 'undefined') return 20;
|
if (typeof window === 'undefined') return 20;
|
||||||
const isMobile = window.innerWidth < 768;
|
const isMobile = window.innerWidth < 768;
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
const maxWidth = window.innerWidth - 40;
|
const maxWidth = window.innerWidth - 32;
|
||||||
const maxHeight = window.innerHeight - 300;
|
// Reserve space for: header(50) + stats(40) + controls(120) + margins(30) = 240
|
||||||
|
const maxHeight = window.innerHeight - 240;
|
||||||
return Math.min(Math.floor(maxWidth / GRID_WIDTH), Math.floor(maxHeight / GRID_HEIGHT), 16);
|
return Math.min(Math.floor(maxWidth / GRID_WIDTH), Math.floor(maxHeight / GRID_HEIGHT), 16);
|
||||||
}
|
}
|
||||||
return isFullscreen ? 26 : 20;
|
return isFullscreen ? 26 : 20;
|
||||||
@ -342,22 +343,22 @@ const Pacman = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<div className="mt-4 flex flex-col items-center gap-2 w-full">
|
<div className="mt-2 flex flex-col items-center gap-1 w-full flex-shrink-0">
|
||||||
<div className="flex gap-4 text-center">
|
<div className="flex gap-4 text-center">
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">SCORE</p><p className="font-minecraft text-sm text-primary">{score.toLocaleString()}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">SCORE</p><p className="font-minecraft text-sm text-primary">{score.toLocaleString()}</p></div>
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">HIGH</p><p className="font-minecraft text-sm text-primary">{highScore.toLocaleString()}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">HIGH</p><p className="font-minecraft text-sm text-primary">{highScore.toLocaleString()}</p></div>
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">LVL</p><p className="font-minecraft text-sm text-primary">{level}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">LVL</p><p className="font-minecraft text-sm text-primary">{level}</p></div>
|
||||||
</div>
|
</div>
|
||||||
{gameStarted && !gameOver && !gameComplete && (
|
{gameStarted && !gameOver && !gameComplete && (
|
||||||
<div className="grid grid-cols-3 gap-1 mt-2">
|
<div className="grid grid-cols-3 gap-1 mt-1">
|
||||||
<div />
|
<div />
|
||||||
<GameTouchButton onAction={() => setNextDirection('up')} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↑</GameTouchButton>
|
<GameTouchButton onAction={() => setNextDirection('up')} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↑</GameTouchButton>
|
||||||
<div />
|
<div />
|
||||||
<GameTouchButton onAction={() => setNextDirection('left')} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">←</GameTouchButton>
|
<GameTouchButton onAction={() => setNextDirection('left')} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">←</GameTouchButton>
|
||||||
<button onClick={() => setIsPaused(p => !p)} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px] select-none">{isPaused ? '▶' : '❚❚'}</button>
|
<button onClick={() => setIsPaused(p => !p)} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px] select-none">{isPaused ? '▶' : '❚❚'}</button>
|
||||||
<GameTouchButton onAction={() => setNextDirection('right')} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">→</GameTouchButton>
|
<GameTouchButton onAction={() => setNextDirection('right')} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">→</GameTouchButton>
|
||||||
<div />
|
<div />
|
||||||
<GameTouchButton onAction={() => setNextDirection('down')} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↓</GameTouchButton>
|
<GameTouchButton onAction={() => setNextDirection('down')} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↓</GameTouchButton>
|
||||||
<div />
|
<div />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -39,8 +39,9 @@ const Snake = () => {
|
|||||||
if (typeof window === 'undefined') return 24;
|
if (typeof window === 'undefined') return 24;
|
||||||
const isMobile = window.innerWidth < 768;
|
const isMobile = window.innerWidth < 768;
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
const maxWidth = window.innerWidth - 40;
|
const maxWidth = window.innerWidth - 32;
|
||||||
const maxHeight = window.innerHeight - 300;
|
// Reserve space for: header(50) + stats(40) + controls(120) + margins(30) = 240
|
||||||
|
const maxHeight = window.innerHeight - 240;
|
||||||
return Math.min(Math.floor(maxWidth / GRID_SIZE), Math.floor(maxHeight / GRID_SIZE), 18);
|
return Math.min(Math.floor(maxWidth / GRID_SIZE), Math.floor(maxHeight / GRID_SIZE), 18);
|
||||||
}
|
}
|
||||||
return isFullscreen ? 28 : 24;
|
return isFullscreen ? 28 : 24;
|
||||||
@ -303,22 +304,22 @@ const Snake = () => {
|
|||||||
|
|
||||||
{/* Mobile Controls */}
|
{/* Mobile Controls */}
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<div className="mt-4 flex flex-col items-center gap-2 w-full">
|
<div className="mt-2 flex flex-col items-center gap-1 w-full flex-shrink-0">
|
||||||
<div className="flex gap-4 text-center">
|
<div className="flex gap-4 text-center">
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">SCORE</p><p className="font-minecraft text-sm text-primary">{score.toLocaleString()}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">SCORE</p><p className="font-minecraft text-sm text-primary">{score.toLocaleString()}</p></div>
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">HIGH</p><p className="font-minecraft text-sm text-primary">{highScore.toLocaleString()}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">HIGH</p><p className="font-minecraft text-sm text-primary">{highScore.toLocaleString()}</p></div>
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">LEN</p><p className="font-minecraft text-sm text-primary">{snake.length}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">LEN</p><p className="font-minecraft text-sm text-primary">{snake.length}</p></div>
|
||||||
</div>
|
</div>
|
||||||
{gameStarted && !gameOver && !gameComplete && (
|
{gameStarted && !gameOver && !gameComplete && (
|
||||||
<div className="grid grid-cols-3 gap-1 mt-2">
|
<div className="grid grid-cols-3 gap-1 mt-1">
|
||||||
<div />
|
<div />
|
||||||
<GameTouchButton onAction={() => directionQueueRef.current.push('up')} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↑</GameTouchButton>
|
<GameTouchButton onAction={() => directionQueueRef.current.push('up')} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↑</GameTouchButton>
|
||||||
<div />
|
<div />
|
||||||
<GameTouchButton onAction={() => directionQueueRef.current.push('left')} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">←</GameTouchButton>
|
<GameTouchButton onAction={() => directionQueueRef.current.push('left')} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">←</GameTouchButton>
|
||||||
<button onClick={() => setIsPaused(p => !p)} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px] select-none">{isPaused ? '▶' : '❚❚'}</button>
|
<button onClick={() => setIsPaused(p => !p)} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px] select-none">{isPaused ? '▶' : '❚❚'}</button>
|
||||||
<GameTouchButton onAction={() => directionQueueRef.current.push('right')} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">→</GameTouchButton>
|
<GameTouchButton onAction={() => directionQueueRef.current.push('right')} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">→</GameTouchButton>
|
||||||
<div />
|
<div />
|
||||||
<GameTouchButton onAction={() => directionQueueRef.current.push('down')} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↓</GameTouchButton>
|
<GameTouchButton onAction={() => directionQueueRef.current.push('down')} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↓</GameTouchButton>
|
||||||
<div />
|
<div />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -76,9 +76,10 @@ const Tetris = () => {
|
|||||||
if (typeof window === 'undefined') return 24;
|
if (typeof window === 'undefined') return 24;
|
||||||
const isMobile = window.innerWidth < 768;
|
const isMobile = window.innerWidth < 768;
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
const maxWidth = window.innerWidth - 40;
|
const maxWidth = window.innerWidth - 32;
|
||||||
const maxHeight = window.innerHeight - 320;
|
// Reserve space for: header(50) + stats(40) + controls(120) + margins(30) = 240
|
||||||
return Math.min(Math.floor(maxWidth / BOARD_WIDTH), Math.floor(maxHeight / BOARD_HEIGHT), 22);
|
const maxHeight = window.innerHeight - 240;
|
||||||
|
return Math.min(Math.floor(maxWidth / BOARD_WIDTH), Math.floor(maxHeight / BOARD_HEIGHT), 20);
|
||||||
}
|
}
|
||||||
return isFullscreen ? 30 : 24;
|
return isFullscreen ? 30 : 24;
|
||||||
}, [isFullscreen]);
|
}, [isFullscreen]);
|
||||||
@ -316,22 +317,22 @@ const Tetris = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<div className="mt-4 flex flex-col items-center gap-2 w-full">
|
<div className="mt-2 flex flex-col items-center gap-1 w-full flex-shrink-0">
|
||||||
<div className="flex gap-4 text-center">
|
<div className="flex gap-4 text-center">
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">SCORE</p><p className="font-minecraft text-sm text-primary">{score.toLocaleString()}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">SCORE</p><p className="font-minecraft text-sm text-primary">{score.toLocaleString()}</p></div>
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">HIGH</p><p className="font-minecraft text-sm text-primary">{highScore.toLocaleString()}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">HIGH</p><p className="font-minecraft text-sm text-primary">{highScore.toLocaleString()}</p></div>
|
||||||
<div><p className="font-pixel text-[8px] text-foreground/60">LINES</p><p className="font-minecraft text-sm text-primary">{lines}</p></div>
|
<div><p className="font-pixel text-[8px] text-foreground/60">LINES</p><p className="font-minecraft text-sm text-primary">{lines}</p></div>
|
||||||
</div>
|
</div>
|
||||||
{gameStarted && !gameOver && !gameComplete && (
|
{gameStarted && !gameOver && !gameComplete && (
|
||||||
<div className="grid grid-cols-3 gap-1 mt-2">
|
<div className="grid grid-cols-3 gap-1 mt-1">
|
||||||
<div />
|
<div />
|
||||||
<GameTouchButton onAction={rotatePiece} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg" interval={200}>↑</GameTouchButton>
|
<GameTouchButton onAction={rotatePiece} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg" interval={200}>↑</GameTouchButton>
|
||||||
<div />
|
<div />
|
||||||
<GameTouchButton onAction={moveLeft} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">←</GameTouchButton>
|
<GameTouchButton onAction={moveLeft} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">←</GameTouchButton>
|
||||||
<GameTouchButton onAction={hardDrop} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px]" interval={500}>DROP</GameTouchButton>
|
<GameTouchButton onAction={hardDrop} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px]" interval={500}>DROP</GameTouchButton>
|
||||||
<GameTouchButton onAction={moveRight} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">→</GameTouchButton>
|
<GameTouchButton onAction={moveRight} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">→</GameTouchButton>
|
||||||
<button onClick={togglePause} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px] select-none">{isPaused ? '▶' : '❚❚'}</button>
|
<button onClick={togglePause} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-[10px] select-none">{isPaused ? '▶' : '❚❚'}</button>
|
||||||
<GameTouchButton onAction={moveDown} className="p-4 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↓</GameTouchButton>
|
<GameTouchButton onAction={moveDown} className="p-3 border border-primary/50 active:bg-primary/40 text-primary font-pixel text-lg">↓</GameTouchButton>
|
||||||
<div />
|
<div />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user