🏇 Horse Race Game
Copy the code below to use this horse racing mini-game
import React, { useRef, useEffect, useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
export default function HorseRaceGame({ horses, onWinner }) {
const canvasRef = useRef(null);
const [winner, setWinner] = useState(null);
const gameRef = useRef({
horses: [],
isRacing: false,
finishLine: 0
});
const horseColors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E2'];
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
const game = gameRef.current;
game.finishLine = canvas.width - 100;
// Initialize horses
game.horses = horses.map((horse, i) => ({
name: horse.kick_username,
data: horse,
x: 50,
y: 80 + (i * 70),
speed: 0,
color: horseColors[i % horseColors.length],
finished: false
}));
const drawTrack = () => {
// Background
ctx.fillStyle = '#2c5f2d';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw lanes
game.horses.forEach((_, i) => {
const y = 50 + (i * 70);
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 2;
ctx.setLineDash([10, 10]);
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(canvas.width, y);
ctx.stroke();
});
// Finish line
ctx.setLineDash([]);
ctx.strokeStyle = '#000000';
ctx.lineWidth = 8;
ctx.beginPath();
ctx.moveTo(game.finishLine, 0);
ctx.lineTo(game.finishLine, canvas.height);
ctx.stroke();
// Checkered pattern on finish line
const squareSize = 20;
for (let i = 0; i < canvas.height / squareSize; i++) {
ctx.fillStyle = i % 2 === 0 ? '#000000' : '#ffffff';
ctx.fillRect(game.finishLine - 4, i * squareSize, 8, squareSize);
}
};
const drawHorse = (horse) => {
ctx.save();
ctx.translate(horse.x, horse.y);
// Horse body
ctx.fillStyle = horse.color;
ctx.fillRect(0, 0, 40, 30);
// Horse head
ctx.fillRect(35, -10, 20, 20);
// Legs
ctx.fillRect(5, 30, 5, 15);
ctx.fillRect(15, 30, 5, 15);
ctx.fillRect(25, 30, 5, 15);
ctx.fillRect(35, 30, 5, 15);
// Name label
ctx.fillStyle = '#000000';
ctx.font = 'bold 12px Arial';
ctx.fillText(horse.name, -10, -15);
ctx.restore();
};
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawTrack();
game.horses.forEach(horse => {
if (!horse.finished) {
// Random speed variation for realism
horse.speed = 2 + Math.random() * 3;
horse.x += horse.speed;
// Check if finished
if (horse.x >= game.finishLine) {
horse.x = game.finishLine;
horse.finished = true;
if (!game.isRacing) {
game.isRacing = true;
setWinner(horse);
if (onWinner) onWinner(horse.data);
}
}
}
drawHorse(horse);
});
if (!game.horses.every(h => h.finished)) {
requestAnimationFrame(animate);
}
};
// Start race after 2 seconds
setTimeout(() => {
animate();
}, 2000);
}, [horses, onWinner]);
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/90">
<div className="bg-gradient-to-b from-green-800 to-green-900 p-6 rounded-2xl border-4 border-yellow-400 shadow-2xl max-w-6xl w-full mx-4">
<h2 className="text-3xl font-bold text-center text-yellow-400 mb-4">🏇 HORSE RACE 🏇</h2>
<canvas
ref={canvasRef}
width={1000}
height={horses.length * 70 + 50}
className="w-full rounded-lg border-2 border-yellow-600"
/>
<AnimatePresence>
{winner && (
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
className="mt-6 text-center bg-gradient-to-r from-yellow-500 to-orange-500 p-6 rounded-lg"
>
<h3 className="text-4xl font-bold text-white mb-2">🏆 WINNER! 🏆</h3>
<p className="text-3xl text-white font-bold">{winner.name}</p>
</motion.div>
)}
</AnimatePresence>
</div>
</div>
);
}How to Use:
- • This component creates a visual horse race game
- • Pass in an array of participant objects as the
horsesprop - • The
onWinnercallback fires when a horse crosses the finish line - • Each horse moves at a random speed for realistic racing
- • The game automatically starts 2 seconds after mounting
Example Usage:
import HorseRaceGame from './HorseRaceGame';
const participants = [
{ kick_username: 'Player1', tier: 'vip' },
{ kick_username: 'Player2', tier: 'supporter' },
// ... more participants
];
<HorseRaceGame
horses={participants}
onWinner={(winner) => {
console.log('Winner:', winner);
}}
/>