<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>1 vs 1 Haxball</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #1e3c72, #2a5298);
color: white;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
padding: 20px;
}
header {
text-align: center;
margin-bottom: 20px;
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.game-container {
background: rgba(0, 0, 0, 0.3);
border-radius: 15px;
padding: 20px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5);
}
#gameCanvas {
background: #2d5a2d;
border: 4px solid #fff;
border-radius: 10px;
display: block;
margin: 0 auto;
}
.controls {
display: flex;
justify-content: center;
gap: 15px;
margin-top: 20px;
}
button {
background: #4CAF50;
color: white;
border: none;
padding: 12px 24px;
font-size: 16px;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
}
button:hover {
background: #45a049;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.3);
}
button:active {
transform: translateY(1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.scoreboard {
display: flex;
justify-content: space-between;
margin-top: 20px;
font-size: 1.5rem;
background: rgba(0, 0, 0, 0.2);
padding: 15px;
border-radius: 10px;
width: 100%;
max-width: 800px;
}
.team {
display: flex;
flex-direction: column;
align-items: center;
}
.team-name {
font-weight: bold;
margin-bottom: 5px;
}
.instructions {
margin-top: 20px;
text-align: center;
background: rgba(0, 0, 0, 0.2);
padding: 15px;
border-radius: 10px;
max-width: 800px;
}
.instructions h3 {
margin-bottom: 10px;
}
.instructions p {
margin-bottom: 5px;
}
.game-message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 2rem;
font-weight: bold;
text-align: center;
background: rgba(0, 0, 0, 0.7);
padding: 20px;
border-radius: 10px;
display: none;
}
</style>
</head>
<body>
<header>
<h1>1 vs 1 Haxball</h1>
<p>Mavi takımı siz, kırmızı takımı bot kontrol ediyor!</p>
</header>
<main class="game-container">
<canvas id="gameCanvas" width="800" height="400"></canvas>
<div class="controls">
<button id="startBtn">Oyunu Başlat</button>
<button id="pauseBtn">Durdur</button>
<button id="resetBtn">Sıfırla</button>
</div>
<div class="scoreboard">
<div class="team">
<div class="team-name" style="color: #3498db;">Mavi Takım (Siz)</div>
<div id="playerScore">0</div>
</div>
<div class="team">
<div class="team-name" style="color: #e74c3c;">Kırmızı Takım (Bot)</div>
<div id="botScore">0</div>
</div>
</div>
</main>
<section class="instructions">
<h3>Oyun Kontrolleri</h3>
<p>W, A, S, D - Mavi oyuncuyu hareket ettirin</p>
<p>Boşluk - Topa vurun</p>
<p>Amacınız: Kırmızı takımın kalesine gol atmak!</p>
</section>
<div id="gameMessage" class="game-message"></div>
<script>
// Oyun değişkenleri
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const startBtn = document.getElementById('startBtn');
const pauseBtn = document.getElementById('pauseBtn');
const resetBtn = document.getElementById('resetBtn');
const playerScoreEl = document.getElementById('playerScore');
const botScoreEl = document.getElementById('botScore');
const gameMessageEl = document.getElementById('gameMessage');
let gameRunning = false;
let animationId;
let lastTime = 0;
let goalCooldown = false; // Gol tekrarını önlemek için
let goalCelebration = 0; // Gol kutlaması süresi
// Oyun nesneleri
const game = {
width: canvas.width,
height: canvas.height,
playerScore: 0,
botScore: 0,
friction: 0.98,
maxSpeed: 5,
goalWidth: 120,
goalDepth: 10
};
// Mavi oyuncu (sizin kontrol ettiğiniz)
const player = {
x: game.width / 4,
y: game.height / 2,
radius: 15,
color: '#3498db',
speed: 0,
dx: 0,
dy: 0,
kickPower: 8,
mass: 1
};
// Kırmızı bot
const bot = {
x: game.width * 3/4,
y: game.height / 2,
radius: 15,
color: '#e74c3c',
speed: 0,
dx: 0,
dy: 0,
kickPower: 7,
mass: 1,
lastKickTime: 0,
state: 'idle', // idle, chasing, defending, kicking
targetX: 0,
targetY: 0,
stuckTimer: 0,
lastPosition: { x: 0, y: 0 }
};
// Top nesnesi
const ball = {
x: game.width / 2,
y: game.height / 2,
radius: 10,
color: '#f1c40f',
dx: 0,
dy: 0,
speed: 0,
mass: 0.5,
stuck: false,
stuckTimer: 0
};
// Kaleler
const goals = {
player: {
x: 0,
y: game.height / 2 - game.goalWidth / 2,
width: game.goalDepth,
height: game.goalWidth
},
bot: {
x: game.width - game.goalDepth,
y: game.height / 2 - game.goalWidth / 2,
width: game.goalDepth,
height: game.goalWidth
}
};
// Klavye kontrolleri
const keys = {};
document.addEventListener('keydown', (e) => {
keys[e.key] = true;
});
document.addEventListener('keyup', (e) => {
keys[e.key] = false;
});
// Oyunu başlatma
startBtn.addEventListener('click', () => {
if (!gameRunning) {
gameRunning = true;
hideMessage();
gameLoop();
}
});
// Oyunu durdurma
pauseBtn.addEventListener('click', () => {
gameRunning = false;
cancelAnimationFrame(animationId);
showMessage("Oyun Durduruldu");
});
// Oyunu sıfırlama
resetBtn.addEventListener('click', () => {
gameRunning = false;
cancelAnimationFrame(animationId);
resetGame();
showMessage("Oyun Sıfırlandı");
setTimeout(hideMessage, 2000);
});
// Mesaj gösterme
function showMessage(message) {
gameMessageEl.textContent = message;
gameMessageEl.style.display = 'block';
}
// Mesaj gizleme
function hideMessage() {
gameMessageEl.style.display = 'none';
}
// Oyunu sıfırlama fonksiyonu
function resetGame() {
// Mavi oyuncuyu sıfırla
player.x = game.width / 4;
player.y = game.height / 2;
player.dx = 0;
player.dy = 0;
player.speed = 0;
// Kırmızı botu sıfırla
bot.x = game.width * 3/4;
bot.y = game.height / 2;
bot.dx = 0;
bot.dy = 0;
bot.speed = 0;
bot.lastKickTime = 0;
bot.state = 'idle';
bot.targetX = 0;
bot.targetY = 0;
bot.stuckTimer = 0;
bot.lastPosition = { x: bot.x, y: bot.y };
// Topu sıfırla
ball.x = game.width / 2;
ball.y = game.height / 2;
ball.dx = 0;
ball.dy = 0;
ball.speed = 0;
ball.stuck = false;
ball.stuckTimer = 0;
// Skoru sıfırla
game.playerScore = 0;
game.botScore = 0;
playerScoreEl.textContent = game.playerScore;
botScoreEl.textContent = game.botScore;
// Durum bayraklarını sıfırla
goalCooldown = false;
goalCelebration = 0;
// Oyun alanını çiz
draw();
}
// Oyun döngüsü
function gameLoop(timestamp) {
if (!gameRunning) return;
const deltaTime = timestamp - lastTime;
lastTime = timestamp;
update(deltaTime);
draw();
animationId = requestAnimationFrame(gameLoop);
}
// Oyun durumunu güncelleme
function update(deltaTime) {
// Gol kutlaması sırasında güncellemeyi atla
if (goalCelebration > 0) {
goalCelebration -= deltaTime;
if (goalCelebration <= 0) {
// Kutlama bitti, pozisyonları sıfırla
resetPositions();
hideMessage();
goalCooldown = false;
}
return;
}
// Mavi oyuncu hareketi (sizin kontrolünüz)
if (keys['w'] || keys['W']) {
player.dy = -game.maxSpeed;
} else if (keys['s'] || keys['S']) {
player.dy = game.maxSpeed;
} else {
player.dy *= game.friction;
}
if (keys['a'] || keys['A']) {
player.dx = -game.maxSpeed;
} else if (keys['d'] || keys['D']) {
player.dx = game.maxSpeed;
} else {
player.dx *= game.friction;
}
// Mavi oyuncu hızını güncelle
player.speed = Math.sqrt(player.dx * player.dx + player.dy * player.dy);
if (player.speed > game.maxSpeed) {
player.dx = (player.dx / player.speed) * game.maxSpeed;
player.dy = (player.dy / player.speed) * game.maxSpeed;
player.speed = game.maxSpeed;
}
// Mavi oyuncu pozisyonunu güncelle
player.x += player.dx;
player.y += player.dy;
// Mavi oyuncuyu sınırla
player.x = Math.max(player.radius, Math.min(game.width - player.radius, player.x));
player.y = Math.max(player.radius, Math.min(game.height - player.radius, player.y));
// Kırmızı bot hareketi (yeniden yazılmış yapay zeka)
updateBot(deltaTime);
// Top hareketi
ball.x += ball.dx;
ball.y += ball.dy;
// Topu sınırla
if (ball.x - ball.radius < 0) {
ball.x = ball.radius;
ball.dx = -ball.dx * 0.8;
} else if (ball.x + ball.radius > game.width) {
ball.x = game.width - ball.radius;
ball.dx = -ball.dx * 0.8;
}
if (ball.y - ball.radius < 0) {
ball.y = ball.radius;
ball.dy = -ball.dy * 0.8;
} else if (ball.y + ball.radius > game.height) {
ball.y = game.height - ball.radius;
ball.dy = -ball.dy * 0.8;
}
// Top sürtünmesi
ball.dx *= game.friction;
ball.dy *= game.friction;
// Çarpışma kontrolleri
checkCollisions();
// Gol kontrolü
checkGoals();
// Top sıkışma kontrolü
checkBallStuck();
}
// Kırmızı bot yapay zeka (tamamen yeniden yazıldı)
function updateBot(deltaTime) {
// Botun takılıp takılmadığını kontrol et
const distMoved = Math.sqrt(Math.pow(bot.x - bot.lastPosition.x, 2) + Math.pow(bot.y - bot.lastPosition.y, 2));
if (distMoved < 1) {
bot.stuckTimer += deltaTime;
if (bot.stuckTimer > 1000) {
// Bot takıldı, rastgele bir yöne hareket et
const randomAngle = Math.random() * Math.PI * 2;
bot.dx = Math.cos(randomAngle) * game.maxSpeed;
bot.dy = Math.sin(randomAngle) * game.maxSpeed;
bot.stuckTimer = 0;
}
} else {
bot.stuckTimer = 0;
bot.lastPosition = { x: bot.x, y: bot.y };
}
// Topa olan mesafe
const distToBall = Math.sqrt(Math.pow(ball.x - bot.x, 2) + Math.pow(ball.y - bot.y, 2));
// Kendi kalesine olan mesafe
const distToOwnGoal = Math.sqrt(Math.pow(goals.bot.x - bot.x, 2) + Math.pow(goals.bot.y + goals.bot.height/2 - bot.y, 2));
// Rakip kaleye olan mesafe
const distToOpponentGoal = Math.sqrt(Math.pow(goals.player.x - bot.x, 2) + Math.pow(goals.player.y + goals.player.height/2 - bot.y, 2));
// Bot durumunu belirle
if (distToBall < bot.radius + ball.radius + 20) {
bot.state = 'kicking';
} else if (ball.x > game.width / 2 && ball.dx > 0 && distToOwnGoal < 200) {
bot.state = 'defending';
} else {
bot.state = 'chasing';
}
// Duruma göre hareket et
switch (bot.state) {
case 'chasing':
// Topa doğru hareket et
const chaseAngle = Math.atan2(ball.y - bot.y, ball.x - bot.x);
bot.dx = Math.cos(chaseAngle) * (game.maxSpeed * 0.8);
bot.dy = Math.sin(chaseAngle) * (game.maxSpeed * 0.8);
break;
case 'defending':
// Topu kes veya kendi kalesini koru
if (distToBall < 100) {
// Topu kes
const interceptAngle = Math.atan2(ball.y - bot.y, ball.x - bot.x);
bot.dx = Math.cos(interceptAngle) * (game.maxSpeed * 0.9);
bot.dy = Math.sin(interceptAngle) * (game.maxSpeed * 0.9);
} else {
// Kaleye doğru geri çekil
const defendAngle = Math.atan2(goals.bot.y + goals.bot.height/2 - bot.y, goals.bot.x - bot.x);
bot.dx = Math.cos(defendAngle) * (game.maxSpeed * 0.7);
bot.dy = Math.sin(defendAngle) * (game.maxSpeed * 0.7);
}
break;
case 'kicking':
// Topa vur
if (Date.now() - bot.lastKickTime > 800) {
// Rakip kaleye doğru vur
const kickAngle = Math.atan2(goals.player.y + goals.player.height/2 - bot.y, goals.player.x - bot.x);
// Vuruş gücünü uygula
const kickPower = bot.kickPower * (1 + Math.random() * 0.3); // Biraz rastgelelik ekle
ball.dx = Math.cos(kickAngle) * kickPower;
ball.dy = Math.sin(kickAngle) * kickPower;
// Botu geri it
bot.dx = -Math.cos(kickAngle) * kickPower * 0.3;
bot.dy = -Math.sin(kickAngle) * kickPower * 0.3;
bot.lastKickTime = Date.now();
}
break;
}
// Bot pozisyonunu güncelle
bot.x += bot.dx;
bot.y += bot.dy;
// Botu sınırla
bot.x = Math.max(bot.radius, Math.min(game.width - bot.radius, bot.x));
bot.y = Math.max(bot.radius, Math.min(game.height - bot.radius, bot.y));
// Botun kendi kalesine çok yaklaştıysa, topu hemen uzaklaştır
if (distToOwnGoal < 80 && distToBall < bot.radius + ball.radius + 30) {
const safeAngle = Math.atan2(bot.y - game.height/2, bot.x - game.width/2);
ball.dx = Math.cos(safeAngle) * bot.kickPower * 1.5;
ball.dy = Math.sin(safeAngle) * bot.kickPower * 1.5;
bot.lastKickTime = Date.now();
}
}
// Top sıkışma kontrolü
function checkBallStuck() {
// Topun hızını kontrol et
ball.speed = Math.sqrt(ball.dx * ball.dx + ball.dy * ball.dy);
// Top çok yavaşsa ve duvarlardaysa, sıkışmış olabilir
if (ball.speed < 0.5) {
ball.stuckTimer += 16; // Yaklaşık 60fps
if (ball.stuckTimer > 1000) { // 1 saniye boyunca yavaşsa
// Topu rastgele bir yöne fırlat
const randomAngle = Math.random() * Math.PI * 2;
ball.dx = Math.cos(randomAngle) * 3;
ball.dy = Math.sin(randomAngle) * 3;
ball.stuckTimer = 0;
}
} else {
ball.stuckTimer = 0;
}
}
// Çarpışma kontrolü (yeniden yazıldı)
function checkCollisions() {
// Mavi oyuncu ve top çarpışması
const playerDist = Math.sqrt(Math.pow(ball.x - player.x, 2) + Math.pow(ball.y - player.y, 2));
if (playerDist < player.radius + ball.radius) {
if (keys[' ']) {
// Boşluk tuşuna basıldığında topa vur
const angle = Math.atan2(ball.y - player.y, ball.x - player.x);
ball.dx = Math.cos(angle) * player.kickPower;
ball.dy = Math.sin(angle) * player.kickPower;
// Oyuncuyu geri it
player.dx = -Math.cos(angle) * player.kickPower * 0.3;
player.dy = -Math.sin(angle) * player.kickPower * 0.3;
} else {
// Normal çarpışma
const angle = Math.atan2(ball.y - player.y, ball.x - player.x);
const overlap = (player.radius + ball.radius) - playerDist;
// Nesneleri ayır
const separateX = Math.cos(angle) * overlap * 0.5;
const separateY = Math.sin(angle) * overlap * 0.5;
ball.x += separateX;
ball.y += separateY;
player.x -= separateX;
player.y -= separateY;
// Hızları ayarla
const relativeVelocity = 0.8;
ball.dx = Math.cos(angle) * relativeVelocity;
ball.dy = Math.sin(angle) * relativeVelocity;
player.dx = -Math.cos(angle) * relativeVelocity * 0.5;
player.dy = -Math.sin(angle) * relativeVelocity * 0.5;
}
}
// Kırmızı bot ve top çarpışması
const botDist = Math.sqrt(Math.pow(ball.x - bot.x, 2) + Math.pow(ball.y - bot.y, 2));
if (botDist < bot.radius + ball.radius) {
// Normal çarpışma
const angle = Math.atan2(ball.y - bot.y, ball.x - bot.x);
const overlap = (bot.radius + ball.radius) - botDist;
// Nesneleri ayır
const separateX = Math.cos(angle) * overlap * 0.5;
const separateY = Math.sin(angle) * overlap * 0.5;
ball.x += separateX;
ball.y += separateY;
bot.x -= separateX;
bot.y -= separateY;
// Eğer bot kicking durumunda değilse, topu it
if (bot.state !== 'kicking') {
const relativeVelocity = 0.6;
ball.dx = Math.cos(angle) * relativeVelocity;
ball.dy = Math.sin(angle) * relativeVelocity;
bot.dx = -Math.cos(angle) * relativeVelocity * 0.5;
bot.dy = -Math.sin(angle) * relativeVelocity * 0.5;
}
}
}
// Gol kontrolü (tamamen yeniden yazıldı)
function checkGoals() {
// Gol cooldown aktifse kontrol etme
if (goalCooldown) return;
// Mavi takımın kalesine gol (bot attı)
if (ball.x - ball.radius < goals.player.x + goals.player.width &&
ball.y > goals.player.y &&
ball.y < goals.player.y + goals.player.height &&
ball.dx < 0) {
// Gol sayısını artır
game.botScore++;
botScoreEl.textContent = game.botScore;
// Gol cooldown aktif et
goalCooldown = true;
// Gol kutlamasını başlat
goalCelebration = 1500; // 1.5 saniye
// Mesaj göster
showMessage("Kırmızı Takım Gol Attı!");
}
// Kırmızı takımın kalesine gol (siz attınız)
if (ball.x + ball.radius > goals.bot.x &&
ball.y > goals.bot.y &&
ball.y < goals.bot.y + goals.bot.height &&
ball.dx > 0) {
// Gol sayısını artır
game.playerScore++;
playerScoreEl.textContent = game.playerScore;
// Gol cooldown aktif et
goalCooldown = true;
// Gol kutlamasını başlat
goalCelebration = 1500; // 1.5 saniye
// Mesaj göster
showMessage("Mavi Takım Gol Attı!");
}
}
// Pozisyonları sıfırlama (gol sonrası)
function resetPositions() {
// Mavi oyuncuyu sıfırla
player.x = game.width / 4;
player.y = game.height / 2;
player.dx = 0;
player.dy = 0;
// Kırmızı botu sıfırla
bot.x = game.width * 3/4;
bot.y = game.height / 2;
bot.dx = 0;
bot.dy = 0;
bot.lastKickTime = 0;
bot.state = 'idle';
bot.targetX = 0;
bot.targetY = 0;
bot.stuckTimer = 0;
bot.lastPosition = { x: bot.x, y: bot.y };
// Topu sıfırla
ball.x = game.width / 2;
ball.y = game.height / 2;
ball.dx = 0;
ball.dy = 0;
ball.stuck = false;
ball.stuckTimer = 0;
}
// Oyun alanını çizme
function draw() {
// Arka planı temizle
ctx.clearRect(0, 0, game.width, game.height);
// Sahayı çiz
ctx.fillStyle = '#2d5a2d';
ctx.fillRect(0, 0, game.width, game.height);
// Orta çizgiyi çiz
ctx.beginPath();
ctx.moveTo(game.width / 2, 0);
ctx.lineTo(game.width / 2, game.height);
ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
ctx.lineWidth = 2;
ctx.stroke();
// Orta daireyi çiz
ctx.beginPath();
ctx.arc(game.width / 2, game.height / 2, 50, 0, Math.PI * 2);
ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
ctx.lineWidth = 2;
ctx.stroke();
// Kaleleri çiz
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.fillRect(goals.player.x, goals.player.y, goals.player.width, goals.player.height);
ctx.fillRect(goals.bot.x, goals.bot.y, goals.bot.width, goals.bot.height);
// Mavi oyuncuyu çiz (sizin kontrol ettiğiniz)
ctx.beginPath();
ctx.arc(player.x, player.y, player.radius, 0, Math.PI * 2);
ctx.fillStyle = player.color;
ctx.fill();
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
ctx.stroke();
// Kırmızı botu çiz
ctx.beginPath();
ctx.arc(bot.x, bot.y, bot.radius, 0, Math.PI * 2);
ctx.fillStyle = bot.color;
ctx.fill();
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
ctx.stroke();
// Topu çiz
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.fillStyle = ball.color;
ctx.fill();
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
ctx.stroke();
}
// İlk çizim
draw();
</script>
</body>
</html>
Selamlar 1v1 bota karşı yenebilen varsa buyursun kodları verdim html de açmanız yeterli skor da sınır yok limit ayarlamadım 5 gol atan kazanır