pig / index.html
Pnkj01's picture
Add 3 files
cbc430d verified
Raw
History Blame Contribute Delete
28.9 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Free Fire Headshot Trainer</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@keyframes targetPulse {
0% { transform: scale(1); opacity: 0.8; }
50% { transform: scale(1.1); opacity: 1; }
100% { transform: scale(1); opacity: 0.8; }
}
.target {
animation: targetPulse 2s infinite;
transition: all 0.3s ease;
}
.hit-effect {
position: absolute;
width: 100px;
height: 100px;
background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,0,0,0) 70%);
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
opacity: 0;
}
.headshot {
background: radial-gradient(circle, rgba(255,215,0,0.7) 0%, rgba(255,215,0,0) 70%);
}
.body-shot {
background: radial-gradient(circle, rgba(255,0,0,0.7) 0%, rgba(255,0,0,0) 70%);
}
#game-area {
touch-action: manipulation;
}
.damage-indicator {
position: absolute;
color: white;
font-weight: bold;
text-shadow: 1px 1px 2px black;
pointer-events: none;
transform: translate(-50%, -50%);
animation: floatUp 1s forwards;
}
@keyframes floatUp {
0% { transform: translate(-50%, -50%); opacity: 1; }
100% { transform: translate(-50%, -150%); opacity: 0; }
}
.crosshair {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 30px;
height: 30px;
pointer-events: none;
z-index: 1000;
}
</style>
</head>
<body class="bg-gray-900 text-white overflow-hidden">
<div class="crosshair">
<div class="relative w-full h-full">
<div class="absolute top-0 left-1/2 w-0.5 h-3 bg-red-500 transform -translate-x-1/2"></div>
<div class="absolute bottom-0 left-1/2 w-0.5 h-3 bg-red-500 transform -translate-x-1/2"></div>
<div class="absolute left-0 top-1/2 w-3 h-0.5 bg-red-500 transform -translate-y-1/2"></div>
<div class="absolute right-0 top-1/2 w-3 h-0.5 bg-red-500 transform -translate-y-1/2"></div>
<div class="absolute top-1/2 left-1/2 w-1.5 h-1.5 bg-red-500 rounded-full transform -translate-x-1/2 -translate-y-1/2"></div>
</div>
</div>
<div class="container mx-auto px-4 py-6">
<div class="flex justify-between items-center mb-4">
<h1 class="text-2xl font-bold text-yellow-400">
<i class="fas fa-crosshairs mr-2"></i> Free Fire Headshot Trainer
</h1>
<div class="flex items-center space-x-4">
<div class="bg-gray-800 px-3 py-1 rounded-lg">
<span class="text-yellow-400 font-bold" id="score">0</span>
<span class="text-gray-400">/</span>
<span class="text-gray-300" id="shots">0</span>
</div>
<div class="bg-gray-800 px-3 py-1 rounded-lg">
<span class="text-green-400 font-bold" id="accuracy">0%</span>
</div>
</div>
</div>
<div class="flex mb-4 space-x-2">
<button id="start-btn" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded-lg font-bold">
<i class="fas fa-play mr-2"></i> Start
</button>
<button id="reset-btn" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg font-bold">
<i class="fas fa-redo mr-2"></i> Reset
</button>
<button id="settings-btn" class="bg-gray-600 hover:bg-gray-700 px-4 py-2 rounded-lg font-bold">
<i class="fas fa-cog mr-2"></i> Settings
</button>
</div>
<div class="bg-gray-800 p-4 rounded-lg mb-4">
<h2 class="text-lg font-bold mb-2 text-yellow-400">
<i class="fas fa-info-circle mr-2"></i> Headshot Tips
</h2>
<ul class="list-disc pl-5 text-sm space-y-1">
<li>Aim slightly above the head to account for recoil</li>
<li>Use single shots or short bursts for better accuracy</li>
<li>Practice controlling weapon recoil patterns</li>
<li>Headshots deal 2.5x more damage than body shots</li>
<li>Move your crosshair in straight lines between targets</li>
</ul>
</div>
<div id="game-area" class="relative bg-gray-800 border-2 border-gray-700 rounded-lg overflow-hidden" style="height: 60vh;">
<div id="targets-container" class="relative w-full h-full"></div>
<div id="results" class="absolute inset-0 bg-black bg-opacity-80 flex flex-col items-center justify-center hidden">
<h2 class="text-3xl font-bold mb-4 text-yellow-400">Training Results</h2>
<div class="grid grid-cols-2 gap-4 mb-6">
<div class="bg-gray-700 p-4 rounded-lg">
<p class="text-gray-400">Total Shots</p>
<p class="text-2xl font-bold" id="final-shots">0</p>
</div>
<div class="bg-gray-700 p-4 rounded-lg">
<p class="text-gray-400">Headshots</p>
<p class="text-2xl font-bold text-yellow-400" id="final-headshots">0</p>
</div>
<div class="bg-gray-700 p-4 rounded-lg">
<p class="text-gray-400">Accuracy</p>
<p class="text-2xl font-bold text-green-400" id="final-accuracy">0%</p>
</div>
<div class="bg-gray-700 p-4 rounded-lg">
<p class="text-gray-400">Score</p>
<p class="text-2xl font-bold" id="final-score">0</p>
</div>
</div>
<button id="close-results" class="bg-blue-600 hover:bg-blue-700 px-6 py-3 rounded-lg font-bold text-lg">
<i class="fas fa-redo mr-2"></i> Try Again
</button>
</div>
</div>
<div class="mt-4 bg-gray-800 p-4 rounded-lg">
<h2 class="text-lg font-bold mb-2 text-yellow-400">
<i class="fas fa-trophy mr-2"></i> Progress
</h2>
<div class="flex items-center space-x-2 mb-2">
<div class="w-full bg-gray-700 rounded-full h-4">
<div id="progress-bar" class="bg-yellow-500 h-4 rounded-full" style="width: 0%"></div>
</div>
<span id="progress-text" class="text-sm font-bold">0%</span>
</div>
<p class="text-sm text-gray-400">Complete training sessions to improve your headshot ratio in Free Fire.</p>
</div>
</div>
<!-- Settings Modal -->
<div id="settings-modal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center hidden z-50">
<div class="bg-gray-800 rounded-lg p-6 w-full max-w-md">
<h2 class="text-2xl font-bold mb-4 text-yellow-400">
<i class="fas fa-cog mr-2"></i> Training Settings
</h2>
<div class="space-y-4">
<div>
<label class="block text-gray-300 mb-2">Target Count</label>
<input type="range" id="target-count" min="5" max="30" value="15" class="w-full">
<div class="flex justify-between text-sm text-gray-400">
<span>5</span>
<span id="target-count-value">15</span>
<span>30</span>
</div>
</div>
<div>
<label class="block text-gray-300 mb-2">Target Speed</label>
<input type="range" id="target-speed" min="1" max="5" value="3" class="w-full">
<div class="flex justify-between text-sm text-gray-400">
<span>Slow</span>
<span id="target-speed-value">Medium</span>
<span>Fast</span>
</div>
</div>
<div>
<label class="block text-gray-300 mb-2">Target Size</label>
<input type="range" id="target-size" min="1" max="3" value="2" class="w-full">
<div class="flex justify-between text-sm text-gray-400">
<span>Small</span>
<span id="target-size-value">Medium</span>
<span>Large</span>
</div>
</div>
<div class="flex items-center">
<input type="checkbox" id="headshot-only" class="mr-2">
<label for="headshot-only" class="text-gray-300">Headshots Only Mode</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="moving-targets" class="mr-2" checked>
<label for="moving-targets" class="text-gray-300">Moving Targets</label>
</div>
</div>
<div class="mt-6 flex justify-end space-x-3">
<button id="cancel-settings" class="bg-gray-600 hover:bg-gray-700 px-4 py-2 rounded-lg">
Cancel
</button>
<button id="save-settings" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded-lg font-bold">
Save Settings
</button>
</div>
</div>
</div>
<script>
// Game state
const state = {
score: 0,
shots: 0,
headshots: 0,
gameActive: false,
targets: [],
settings: {
targetCount: 15,
targetSpeed: 3,
targetSize: 2,
headshotOnly: false,
movingTargets: true
}
};
// DOM elements
const gameArea = document.getElementById('game-area');
const targetsContainer = document.getElementById('targets-container');
const startBtn = document.getElementById('start-btn');
const resetBtn = document.getElementById('reset-btn');
const settingsBtn = document.getElementById('settings-btn');
const scoreDisplay = document.getElementById('score');
const shotsDisplay = document.getElementById('shots');
const accuracyDisplay = document.getElementById('accuracy');
const progressBar = document.getElementById('progress-bar');
const progressText = document.getElementById('progress-text');
const resultsScreen = document.getElementById('results');
const finalShots = document.getElementById('final-shots');
const finalHeadshots = document.getElementById('final-headshots');
const finalAccuracy = document.getElementById('final-accuracy');
const finalScore = document.getElementById('final-score');
const closeResults = document.getElementById('close-results');
const settingsModal = document.getElementById('settings-modal');
const targetCountInput = document.getElementById('target-count');
const targetSpeedInput = document.getElementById('target-speed');
const targetSizeInput = document.getElementById('target-size');
const headshotOnlyInput = document.getElementById('headshot-only');
const movingTargetsInput = document.getElementById('moving-targets');
const targetCountValue = document.getElementById('target-count-value');
const targetSpeedValue = document.getElementById('target-speed-value');
const targetSizeValue = document.getElementById('target-size-value');
const saveSettingsBtn = document.getElementById('save-settings');
const cancelSettingsBtn = document.getElementById('cancel-settings');
// Initialize
function init() {
startBtn.addEventListener('click', startGame);
resetBtn.addEventListener('click', resetGame);
settingsBtn.addEventListener('click', showSettings);
closeResults.addEventListener('click', resetGame);
gameArea.addEventListener('click', handleShot);
// Settings controls
targetCountInput.addEventListener('input', updateSettingsDisplay);
targetSpeedInput.addEventListener('input', updateSettingsDisplay);
targetSizeInput.addEventListener('input', updateSettingsDisplay);
saveSettingsBtn.addEventListener('click', saveSettings);
cancelSettingsBtn.addEventListener('click', hideSettings);
updateSettingsDisplay();
}
// Update settings display
function updateSettingsDisplay() {
targetCountValue.textContent = targetCountInput.value;
const speedValue = parseInt(targetSpeedInput.value);
targetSpeedValue.textContent =
speedValue === 1 ? 'Slow' :
speedValue === 2 ? 'Medium Slow' :
speedValue === 3 ? 'Medium' :
speedValue === 4 ? 'Fast' : 'Very Fast';
const sizeValue = parseInt(targetSizeInput.value);
targetSizeValue.textContent =
sizeValue === 1 ? 'Small' :
sizeValue === 2 ? 'Medium' : 'Large';
}
// Show settings modal
function showSettings() {
targetCountInput.value = state.settings.targetCount;
targetSpeedInput.value = state.settings.targetSpeed;
targetSizeInput.value = state.settings.targetSize;
headshotOnlyInput.checked = state.settings.headshotOnly;
movingTargetsInput.checked = state.settings.movingTargets;
updateSettingsDisplay();
settingsModal.classList.remove('hidden');
}
// Hide settings modal
function hideSettings() {
settingsModal.classList.add('hidden');
}
// Save settings
function saveSettings() {
state.settings = {
targetCount: parseInt(targetCountInput.value),
targetSpeed: parseInt(targetSpeedInput.value),
targetSize: parseInt(targetSizeInput.value),
headshotOnly: headshotOnlyInput.checked,
movingTargets: movingTargetsInput.checked
};
hideSettings();
}
// Start game
function startGame() {
if (state.gameActive) return;
state.gameActive = true;
state.score = 0;
state.shots = 0;
state.headshots = 0;
updateUI();
createTargets();
startBtn.innerHTML = '<i class="fas fa-pause mr-2"></i> Pause';
startBtn.classList.remove('bg-green-600', 'hover:bg-green-700');
startBtn.classList.add('bg-yellow-600', 'hover:bg-yellow-700');
startBtn.removeEventListener('click', startGame);
startBtn.addEventListener('click', pauseGame);
}
// Pause game
function pauseGame() {
state.gameActive = false;
clearAllTargets();
startBtn.innerHTML = '<i class="fas fa-play mr-2"></i> Resume';
startBtn.classList.remove('bg-yellow-600', 'hover:bg-yellow-700');
startBtn.classList.add('bg-green-600', 'hover:bg-green-700');
startBtn.removeEventListener('click', pauseGame);
startBtn.addEventListener('click', startGame);
}
// Reset game
function resetGame() {
state.gameActive = false;
state.score = 0;
state.shots = 0;
state.headshots = 0;
clearAllTargets();
resultsScreen.classList.add('hidden');
updateUI();
startBtn.innerHTML = '<i class="fas fa-play mr-2"></i> Start';
startBtn.classList.remove('bg-yellow-600', 'hover:bg-yellow-700');
startBtn.classList.add('bg-green-600', 'hover:bg-green-700');
startBtn.removeEventListener('click', pauseGame);
startBtn.addEventListener('click', startGame);
}
// Create targets
function createTargets() {
if (!state.gameActive) return;
targetsContainer.innerHTML = '';
state.targets = [];
const targetCount = state.settings.targetCount;
const gameAreaRect = gameArea.getBoundingClientRect();
for (let i = 0; i < targetCount; i++) {
createTarget(gameAreaRect);
}
}
// Create a single target
function createTarget(gameAreaRect) {
const target = document.createElement('div');
target.className = 'target absolute cursor-pointer rounded-full bg-red-600 flex items-center justify-center';
// Set size based on settings
const size = state.settings.targetSize;
const targetSize = size === 1 ? 40 : size === 2 ? 60 : 80;
const headSize = size === 1 ? 12 : size === 2 ? 16 : 20;
target.style.width = `${targetSize}px`;
target.style.height = `${targetSize}px`;
// Create head (for headshot area)
const head = document.createElement('div');
head.className = 'absolute bg-blue-700 rounded-full';
head.style.width = `${headSize}px`;
head.style.height = `${headSize}px`;
head.style.top = '15%';
head.style.left = '50%';
head.style.transform = 'translateX(-50%)';
target.appendChild(head);
// Random position within game area (with padding)
const padding = 30;
const maxX = gameAreaRect.width - targetSize - padding;
const maxY = gameAreaRect.height - targetSize - padding;
let x = padding + Math.random() * maxX;
let y = padding + Math.random() * maxY;
target.style.left = `${x}px`;
target.style.top = `${y}px`;
// Add movement if enabled
if (state.settings.movingTargets) {
const speed = state.settings.targetSpeed * 0.5;
let xDirection = Math.random() > 0.5 ? 1 : -1;
let yDirection = Math.random() > 0.5 ? 1 : -1;
const moveTarget = () => {
if (!state.gameActive) return;
x += xDirection * speed;
y += yDirection * speed;
// Bounce off edges
if (x <= padding || x >= maxX) {
xDirection *= -1;
x = Math.max(padding, Math.min(x, maxX));
}
if (y <= padding || y >= maxY) {
yDirection *= -1;
y = Math.max(padding, Math.min(y, maxY));
}
target.style.left = `${x}px`;
target.style.top = `${y}px`;
requestAnimationFrame(moveTarget);
};
moveTarget();
}
// Add click handler
target.addEventListener('click', (e) => {
if (!state.gameActive) return;
e.stopPropagation();
handleTargetClick(target, e);
});
targetsContainer.appendChild(target);
state.targets.push(target);
}
// Handle target click
function handleTargetClick(target, e) {
if (!state.gameActive) return;
const rect = target.getBoundingClientRect();
const head = target.querySelector('div');
const headRect = head.getBoundingClientRect();
// Calculate click position relative to target
const clickX = e.clientX - rect.left;
const clickY = e.clientY - rect.top;
// Check if headshot (click within head area)
const isHeadshot =
clickX >= headRect.left - rect.left &&
clickX <= headRect.right - rect.left &&
clickY >= headRect.top - rect.top &&
clickY <= headRect.bottom - rect.top;
if (state.settings.headshotOnly && !isHeadshot) {
showMissFeedback(e.clientX, e.clientY);
return;
}
// Remove target
target.remove();
state.targets = state.targets.filter(t => t !== target);
// Update stats
state.shots++;
if (isHeadshot) {
state.headshots++;
state.score += 100;
} else {
state.score += 40;
}
// Show hit effect
showHitFeedback(e.clientX, e.clientY, isHeadshot);
// Create new target if game is still active
if (state.gameActive) {
const gameAreaRect = gameArea.getBoundingClientRect();
createTarget(gameAreaRect);
}
// Check if training session is complete
if (state.shots >= state.settings.targetCount) {
endGame();
}
updateUI();
}
// Handle missed shot (clicked outside target)
function handleShot(e) {
if (!state.gameActive || e.target === targetsContainer) {
if (state.gameActive) {
state.shots++;
showMissFeedback(e.clientX, e.clientY);
updateUI();
// Check if training session is complete
if (state.shots >= state.settings.targetCount) {
endGame();
}
}
return;
}
}
// Show hit feedback
function showHitFeedback(x, y, isHeadshot) {
const effect = document.createElement('div');
effect.className = `hit-effect ${isHeadshot ? 'headshot' : 'body-shot'}`;
effect.style.left = `${x}px`;
effect.style.top = `${y}px`;
// Damage indicator
const damage = document.createElement('div');
damage.className = 'damage-indicator';
damage.textContent = isHeadshot ? 'HEADSHOT! +100' : 'HIT! +40';
damage.style.left = `${x}px`;
damage.style.top = `${y}px`;
damage.style.color = isHeadshot ? 'gold' : 'red';
damage.style.fontSize = isHeadshot ? '18px' : '16px';
document.body.appendChild(effect);
document.body.appendChild(damage);
// Animate
effect.style.opacity = '1';
effect.style.transform = 'scale(1)';
setTimeout(() => {
effect.style.opacity = '0';
effect.style.transform = 'scale(1.5)';
setTimeout(() => {
effect.remove();
damage.remove();
}, 300);
}, 300);
}
// Show miss feedback
function showMissFeedback(x, y) {
const effect = document.createElement('div');
effect.className = 'hit-effect';
effect.style.left = `${x}px`;
effect.style.top = `${y}px`;
effect.style.background = 'radial-gradient(circle, rgba(255,255,255,0.3) 0%, rgba(255,255,255,0) 70%)';
// Miss text
const missText = document.createElement('div');
missText.className = 'damage-indicator';
missText.textContent = 'MISS!';
missText.style.left = `${x}px`;
missText.style.top = `${y}px`;
missText.style.color = 'white';
document.body.appendChild(effect);
document.body.appendChild(missText);
// Animate
effect.style.opacity = '1';
effect.style.transform = 'scale(1)';
setTimeout(() => {
effect.style.opacity = '0';
effect.style.transform = 'scale(1.5)';
setTimeout(() => {
effect.remove();
missText.remove();
}, 300);
}, 300);
}
// Clear all targets
function clearAllTargets() {
targetsContainer.innerHTML = '';
state.targets = [];
}
// End game
function endGame() {
state.gameActive = false;
clearAllTargets();
// Show results
finalShots.textContent = state.shots;
finalHeadshots.textContent = state.headshots;
finalScore.textContent = state.score;
const accuracy = state.shots > 0 ? Math.round((state.headshots / state.shots) * 100) : 0;
finalAccuracy.textContent = `${accuracy}%`;
resultsScreen.classList.remove('hidden');
// Update progress
updateProgress(accuracy);
}
// Update progress
function updateProgress(accuracy) {
// Simple progress calculation based on accuracy
const progress = Math.min(100, Math.floor(accuracy * 1.2));
progressBar.style.width = `${progress}%`;
progressText.textContent = `${progress}%`;
// Change color based on progress
if (progress < 30) {
progressBar.className = 'bg-red-500 h-4 rounded-full';
} else if (progress < 70) {
progressBar.className = 'bg-yellow-500 h-4 rounded-full';
} else {
progressBar.className = 'bg-green-500 h-4 rounded-full';
}
}
// Update UI
function updateUI() {
scoreDisplay.textContent = state.score;
shotsDisplay.textContent = state.shots;
const accuracy = state.shots > 0 ? Math.round((state.headshots / state.shots) * 100) : 0;
accuracyDisplay.textContent = `${accuracy}%`;
// Update progress during game
if (state.gameActive) {
const progress = Math.floor((state.shots / state.settings.targetCount) * 100);
progressBar.style.width = `${progress}%`;
progressText.textContent = `${progress}%`;
}
}
// Initialize the game
init();
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Pnkj01/pig" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>