<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Platform Macerası</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #87CEEB 0%, #98D8E8 100%);
overflow: hidden;
position: relative;
}
#gameCanvas {
display: block;
position: absolute;
top: 0;
left: 0;
z-index: 0;
}
.game-ui {
position: absolute;
top: 20px;
left: 20px;
color: white;
font-size: 24px;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
z-index: 100;
}
.controls {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 15px 30px;
border-radius: 10px;
text-align: center;
z-index: 100;
}
.controls h3 {
margin-bottom: 10px;
color: #FFD700;
}
.controls p {
margin: 5px 0;
}
.game-over {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 40px;
border-radius: 20px;
text-align: center;
display: none;
z-index: 200;
}
.game-over h2 {
font-size: 48px;
color: #FFD700;
margin-bottom: 20px;
}
.game-over p {
font-size: 24px;
margin-bottom: 30px;
}
.btn {
background: linear-gradient(45deg, #FF6B6B, #4ECDC4);
color: white;
border: none;
padding: 15px 40px;
font-size: 20px;
border-radius: 30px;
cursor: pointer;
transition: transform 0.3s;
}
.btn:hover {
transform: scale(1.1);
}
.loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 32px;
z-index: 300;
text-align: center;
}
.error-message {
background: rgba(255, 0, 0, 0.8);
color: white;
padding: 20px;
border-radius: 10px;
margin-top: 20px;
display: none;
}
.spinner {
border: 4px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top: 4px solid white;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin: 20px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.webgl-error {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 30px;
border-radius: 15px;
text-align: center;
z-index: 400;
display: none;
max-width: 500px;
}
.webgl-error h2 {
color: #ff6b6b;
margin-bottom: 15px;
}
.webgl-error ul {
text-align: left;
margin: 20px 0;
}
.webgl-error li {
margin: 10px 0;
}
.debug-info {
position: absolute;
top: 10px;
right: 10px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
border-radius: 5px;
font-size: 12px;
z-index: 150;
display: none;
}
.position-info {
position: absolute;
top: 80px;
left: 20px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
border-radius: 5px;
font-size: 14px;
z-index: 100;
font-family: monospace;
}
</style>
</head>
<body>
<div class="loading" id="loading">
<div>Yükleniyor...</div>
<div class="spinner"></div>
<div class="error-message" id="errorMessage">
Three.js kütüphanesi yüklenemedi. Lütfen internet bağlantınızı kontrol edin.
</div>
</div>
<div class="webgl-error" id="webglError">
<h2>WebGL Desteklenmiyor!</h2>
<p>Tarayıcınız WebGL desteklemiyor. Lütfen aşağıdaki çözümleri deneyin:</p>
<ul>
<li>Chrome, Firefox, Edge veya Safari gibi modern bir tarayıcı kullanın</li>
<li>Tarayıcınızı güncelleyin</li>
<li>Donanım hızlandırma aktif olsun</li>
<li>GPU sürücülerinizi güncelleyin</li>
</ul>
<button class="btn" onclick="location.reload()">Tekrar Dene</button>
</div>
<div class="debug-info" id="debugInfo">
<div>WebGL: <span id="webglStatus">Kontrol ediliyor...</span></div>
<div>Three.js: <span id="threeStatus">Yükleniyor...</span></div>
<div>Renderer: <span id="rendererStatus">Oluşturulmadı</span></div>
</div>
<div class="game-ui">
<div>🪙 <span id="coins">0</span></div>
<div>❤️ <span id="lives">3</span></div>
</div>
<div class="position-info" id="positionInfo">
<div>Pozisyon: X=<span id="posX">0</span> Y=<span id="posY">0</span> Z=<span id="posZ">0</span></div>
<div>Hız: X=<span id="velX">0</span> Y=<span id="velY">0</span> Z=<span id="velZ">0</span></div>
<div>Zeminde: <span id="onGround">false</span></div>
</div>
<div class="controls">
<h3>Kontroller</h3>
<p>🏃 Hareket: WASD veya Ok Tuşları</p>
<p>🦘 Zıplama: Boşluk Tuşu</p>
<p>🔄 Kamera: Mouse</p>
</div>
<div class="game-over" id="gameOver">
<h2 id="gameOverTitle">Oyun Bitti!</h2>
<p id="gameOverMessage">Topladığınız Coin: <span id="finalCoins">0</span></p>
<button class="btn" onclick="location.reload()">Tekrar Oyna</button>
</div>
<script>
// Debug modu - URL'de ?debug=1 parametresi ile aktifleştirilir
const debugMode = window.location.search.includes('debug=1');
if (debugMode) {
document.getElementById('debugInfo').style.display = 'block';
}
// WebGL desteğini kontrol et
function checkWebGL() {
try {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
if (debugMode) console.log('WebGL context alınamadı');
return false;
}
// Basit bir test
const testProgram = gl.createProgram();
if (!testProgram) {
if (debugMode) console.log('WebGL program oluşturulamadı');
return false;
}
gl.deleteProgram(testProgram);
if (debugMode) console.log('WebGL desteği mevcut');
document.getElementById('webglStatus').textContent = 'Mevcut';
return true;
} catch (e) {
if (debugMode) console.error('WebGL kontrol hatası:', e);
document.getElementById('webglStatus').textContent = 'Hata: ' + e.message;
return false;
}
}
// Three.js yükleme fonksiyonu
function loadScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = () => {
if (debugMode) console.log('Three.js yüklendi:', src);
document.getElementById('threeStatus').textContent = 'Yüklendi';
resolve();
};
script.onerror = (e) => {
if (debugMode) console.error('Three.js yüklenemedi:', src, e);
document.getElementById('threeStatus').textContent = 'Hata';
reject(e);
};
document.head.appendChild(script);
});
}
// Ana başlatma fonksiyonu
async function initializeGame() {
if (!checkWebGL()) {
document.getElementById('loading').style.display = 'none';
document.getElementById('webglError').style.display = 'block';
return;
}
try {
// Three.js'i farklı kaynaklardan dene
await loadScript('https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js')
.catch(() => loadScript('https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js'))
.catch(() => loadScript('https://unpkg.com/three@0.128.0/build/three.min.js'))
.catch(() => loadScript('https://skypack.dev/three@0.128.0'))
.catch(() => {
throw new Error('Tüm Three.js kaynakları başarısız oldu');
});
// Three.js yüklendi, oyunu başlat
document.getElementById('loading').style.display = 'none';
initGame();
} catch (error) {
console.error('Başlatma hatası:', error);
document.getElementById('loading').style.display = 'none';
document.getElementById('webglError').style.display = 'block';
}
}
// Oyun değişkenleri
let scene, camera, renderer;
let mario, marioVelocity = { x: 0, y: 0, z: 0 };
let platforms = [];
let coins = [];
let enemies = [];
let keys = {};
let coinsCollected = 0;
let lives = 3;
let isJumping = false;
let gameRunning = true;
let onGround = false;
let groundY = 0.25; // Ana platformun üst yüzeyi
// Fizik sabitleri
const GRAVITY = -0.02;
const JUMP_FORCE = 0.4;
const MOVE_SPEED = 0.15;
const MAX_FALL_SPEED = -0.5;
const MARIO_HEIGHT = 1.6; // Mario'nun toplam yüksekliği
const MARIO_RADIUS = 0.3; // Mario'nun yarıçapı
// Oyunu başlat
function initGame() {
try {
if (debugMode) console.log('Oyun başlatılıyor...');
// Sahne oluştur
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x87CEEB, 10, 100);
// Kamera oluştur
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 10, 15);
camera.lookAt(0, 0, 0);
// Renderer oluştur
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
preserveDrawingBuffer: true
});
// Renderer ayarları
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setClearColor(0x87CEEB, 1);
renderer.setPixelRatio(window.devicePixelRatio);
// Canvas'ı ekle
renderer.domElement.id = 'gameCanvas';
document.body.appendChild(renderer.domElement);
if (debugMode) {
document.getElementById('rendererStatus').textContent = 'Oluşturuldu';
console.log('Renderer başarıyla oluşturuldu');
}
// Işıklar
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(10, 20, 5);
directionalLight.castShadow = true;
directionalLight.shadow.camera.left = -20;
directionalLight.shadow.camera.right = 20;
directionalLight.shadow.camera.top = 20;
directionalLight.shadow.camera.bottom = -20;
scene.add(directionalLight);
// Mario'yu oluştur
createMario();
// Platformları oluştur
createPlatforms();
// Coinleri oluştur
createCoins();
// Düşmanları oluştur
createEnemies();
// Gökyüzü kutusu
createSkybox();
// Event listeners
window.addEventListener('resize', onWindowResize);
document.addEventListener('keydown', onKeyDown);
document.addEventListener('keyup', onKeyUp);
document.addEventListener('mousemove', onMouseMove);
// Oyun döngüsünü başlat
animate();
if (debugMode) console.log('Oyun başarıyla başlatıldı!');
} catch (error) {
console.error('Oyun başlatılırken hata:', error);
document.getElementById('loading').style.display = 'none';
document.getElementById('webglError').style.display = 'block';
}
}
function createMario() {
// Mario grubu
mario = new THREE.Group();
// Vücut - basit silindir
const bodyGeometry = new THREE.CylinderGeometry(MARIO_RADIUS, MARIO_RADIUS, 0.8, 16);
const bodyMaterial = new THREE.MeshPhongMaterial({ color: 0xFF0000 });
const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
body.position.y = 0.4;
body.castShadow = true;
mario.add(body);
// Baş
const headGeometry = new THREE.SphereGeometry(0.35, 16, 16);
const headMaterial = new THREE.MeshPhongMaterial({ color: 0xFFDBAC });
const head = new THREE.Mesh(headGeometry, headMaterial);
head.position.y = 1.0;
head.castShadow = true;
mario.add(head);
// Şapka
const hatGeometry = new THREE.CylinderGeometry(0.4, 0.4, 0.3, 16);
const hatMaterial = new THREE.MeshPhongMaterial({ color: 0xFF0000 });
const hat = new THREE.Mesh(hatGeometry, hatMaterial);
hat.position.y = 1.25;
hat.castShadow = true;
mario.add(hat);
// Gözler
const eyeGeometry = new THREE.SphereGeometry(0.05, 8, 8);
const eyeMaterial = new THREE.MeshPhongMaterial({ color: 0x000000 });
const leftEye = new THREE.Mesh(eyeGeometry, eyeMaterial);
leftEye.position.set(-0.1, 1.05, 0.3);
mario.add(leftEye);
const rightEye = new THREE.Mesh(eyeGeometry, eyeMaterial);
rightEye.position.set(0.1, 1.05, 0.3);
mario.add(rightEye);
// Sakal
const mustacheGeometry = new THREE.BoxGeometry(0.3, 0.05, 0.05);
const mustacheMaterial = new THREE.MeshPhongMaterial({ color: 0x8B4513 });
const mustache = new THREE.Mesh(mustacheGeometry, mustacheMaterial);
mustache.position.set(0, 0.95, 0.3);
mario.add(mustache);
// Overalls
const overallsGeometry = new THREE.BoxGeometry(0.7, 0.4, 0.4);
const overallsMaterial = new THREE.MeshPhongMaterial({ color: 0x0000FF });
const overalls = new THREE.Mesh(overallsGeometry, overallsMaterial);
overalls.position.y = 0.3;
overalls.castShadow = true;
mario.add(overalls);
// Butonlar
const buttonGeometry = new THREE.SphereGeometry(0.05, 8, 8);
const buttonMaterial = new THREE.MeshPhongMaterial({ color: 0xFFFF00 });
for (let i = 0; i < 2; i++) {
const button = new THREE.Mesh(buttonGeometry, buttonMaterial);
button.position.set(-0.1 + i * 0.2, 0.3, 0.21);
mario.add(button);
}
// Mario'yu zeminin üzerine yerleştir
mario.position.set(0, groundY + MARIO_HEIGHT/2, 0);
marioVelocity.y = 0;
onGround = true;
scene.add(mario);
}
function createPlatforms() {
// Ana platform - Mario'nun başlangıç pozisyonuna uygun
const mainPlatformGeometry = new THREE.BoxGeometry(20, 0.5, 20);
const mainPlatformMaterial = new THREE.MeshPhongMaterial({ color: 0x8B4513 });
const mainPlatform = new THREE.Mesh(mainPlatformGeometry, mainPlatformMaterial);
mainPlatform.position.y = 0;
mainPlatform.receiveShadow = true;
scene.add(mainPlatform);
platforms.push(mainPlatform);
// Yükselen platformlar
const platformPositions = [
{ x: -5, y: 2, z: -5, w: 4, h: 0.5, d: 4 },
{ x: 5, y: 4, z: -5, w: 4, h: 0.5, d: 4 },
{ x: 0, y: 6, z: -10, w: 6, h: 0.5, d: 4 },
{ x: -8, y: 3, z: 5, w: 4, h: 0.5, d: 4 },
{ x: 8, y: 5, z: 5, w: 4, h: 0.5, d: 4 },
{ x: 0, y: 8, z: 0, w: 8, h: 0.5, d: 8 }
];
platformPositions.forEach(pos => {
const geometry = new THREE.BoxGeometry(pos.w, pos.h, pos.d);
const material = new THREE.MeshPhongMaterial({ color: 0x228B22 });
const platform = new THREE.Mesh(geometry, material);
platform.position.set(pos.x, pos.y, pos.z);
platform.receiveShadow = true;
platform.castShadow = true;
scene.add(platform);
platforms.push(platform);
});
}
function createCoins() {
const coinPositions = [
{ x: -5, y: 3, z: -5 },
{ x: 5, y: 5, z: -5 },
{ x: 0, y: 7, z: -10 },
{ x: -8, y: 4, z: 5 },
{ x: 8, y: 6, z: 5 },
{ x: 0, y: 9, z: 0 },
{ x: -3, y: 3, z: 0 },
{ x: 3, y: 3, z: 0 },
{ x: 0, y: 3, z: 3 },
{ x: 0, y: 3, z: -3 }
];
coinPositions.forEach(pos => {
const coinGroup = new THREE.Group();
// Coin
const coinGeometry = new THREE.CylinderGeometry(0.3, 0.3, 0.1, 16);
const coinMaterial = new THREE.MeshPhongMaterial({
color: 0xFFD700,
emissive: 0xFFD700,
emissiveIntensity: 0.2
});
const coin = new THREE.Mesh(coinGeometry, coinMaterial);
coin.rotation.x = Math.PI / 2;
coin.castShadow = true;
coinGroup.add(coin);
coinGroup.position.set(pos.x, pos.y, pos.z);
coinGroup.userData = { isCoin: true, collected: false };
scene.add(coinGroup);
coins.push(coinGroup);
});
}
function createEnemies() {
const enemyPositions = [
{ x: -5, z: -5 },
{ x: 5, z: 5 }
];
enemyPositions.forEach(pos => {
const enemy = new THREE.Group();
// Gövde
const bodyGeometry = new THREE.SphereGeometry(0.4, 16, 16);
const bodyMaterial = new THREE.MeshPhongMaterial({ color: 0x8B0000 });
const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
body.position.y = 0.4;
body.castShadow = true;
enemy.add(body);
// Gözler
const eyeGeometry = new THREE.SphereGeometry(0.08, 8, 8);
const eyeMaterial = new THREE.MeshPhongMaterial({ color: 0xFFFFFF });
const leftEye = new THREE.Mesh(eyeGeometry, eyeMaterial);
leftEye.position.set(-0.15, 0.5, 0.35);
enemy.add(leftEye);
const rightEye = new THREE.Mesh(eyeGeometry, eyeMaterial);
rightEye.position.set(0.15, 0.5, 0.35);
enemy.add(rightEye);
// Pupil
const pupilGeometry = new THREE.SphereGeometry(0.04, 8, 8);
const pupilMaterial = new THREE.MeshPhongMaterial({ color: 0x000000 });
const leftPupil = new THREE.Mesh(pupilGeometry, pupilMaterial);
leftPupil.position.set(-0.15, 0.5, 0.42);
enemy.add(leftPupil);
const rightPupil = new THREE.Mesh(pupilGeometry, pupilMaterial);
rightPupil.position.set(0.15, 0.5, 0.42);
enemy.add(rightPupil);
enemy.position.set(pos.x, 0.8, pos.z); // Zemin üzerinde başlasın
enemy.userData = {
isEnemy: true,
direction: Math.random() > 0.5 ? 1 : -1,
speed: 0.02 + Math.random() * 0.02
};
scene.add(enemy);
enemies.push(enemy);
});
}
function createSkybox() {
const skyGeometry = new THREE.SphereGeometry(100, 32, 32);
const skyMaterial = new THREE.MeshBasicMaterial({
color: 0x87CEEB,
side: THREE.BackSide
});
const skybox = new THREE.Mesh(skyGeometry, skyMaterial);
scene.add(skybox);
// Bulutlar
for (let i = 0; i < 10; i++) {
const cloudGeometry = new THREE.SphereGeometry(3 + Math.random() * 2, 8, 8);
const cloudMaterial = new THREE.MeshBasicMaterial({
color: 0xFFFFFF,
transparent: true,
opacity: 0.8
});
const cloud = new THREE.Mesh(cloudGeometry, cloudMaterial);
cloud.position.set(
(Math.random() - 0.5) * 80,
20 + Math.random() * 20,
(Math.random() - 0.5) * 80
);
cloud.scale.set(1.5, 0.8, 1);
scene.add(cloud);
}
}
function updateMario() {
if (!gameRunning) return;
// Yerçekimi
marioVelocity.y += GRAVITY;
if (marioVelocity.y < MAX_FALL_SPEED) {
marioVelocity.y = MAX_FALL_SPEED;
}
// Hareket
if (keys['ArrowLeft'] || keys['a'] || keys['A']) {
marioVelocity.x = -MOVE_SPEED;
mario.rotation.y = Math.PI / 2;
} else if (keys['ArrowRight'] || keys['d'] || keys['D']) {
marioVelocity.x = MOVE_SPEED;
mario.rotation.y = -Math.PI / 2;
} else {
marioVelocity.x *= 0.8; // Sürtünme
}
if (keys['ArrowUp'] || keys['w'] || keys['W']) {
marioVelocity.z = -MOVE_SPEED;
} else if (keys['ArrowDown'] || keys['s'] || keys['S']) {
marioVelocity.z = MOVE_SPEED;
} else {
marioVelocity.z *= 0.8; // Sürtünme
}
// Zıplama - sadece zemindeyken
if ((keys[' '] || keys['ArrowUp'] || keys['w'] || keys['W']) && onGround) {
marioVelocity.y = JUMP_FORCE;
isJumping = true;
onGround = false;
}
// Pozisyon güncelleme
mario.position.x += marioVelocity.x;
mario.position.y += marioVelocity.y;
mario.position.z += marioVelocity.z;
// Platform çarpışma kontrolü
checkPlatformCollisions();
// Coin toplama kontrolü
checkCoinCollection();
// Düşman çarpışma kontrolü
checkEnemyCollisions();
// Düşme kontrolü
if (mario.position.y < -10) {
loseLife();
}
// Debug bilgilerini güncelle
updateDebugInfo();
// Kamera takibi
camera.position.x = mario.position.x;
camera.position.z = mario.position.z + 15;
camera.lookAt(mario.position);
}
function checkPlatformCollisions() {
onGround = false;
platforms.forEach(platform => {
const platformTop = platform.position.y + platform.geometry.parameters.height / 2;
const marioBottom = mario.position.y - MARIO_HEIGHT/2;
// Yatay mesafe kontrolü
const dx = Math.abs(mario.position.x - platform.position.x);
const dz = Math.abs(mario.position.z - platform.position.z);
const platformHalfWidth = platform.geometry.parameters.width / 2;
const platformHalfDepth = platform.geometry.parameters.depth / 2;
// Mario platformun üzerinde mi ve yeterince yakında mı?
if (dx < platformHalfWidth + MARIO_RADIUS &&
dz < platformHalfDepth + MARIO_RADIUS &&
marioBottom <= platformTop + 0.1 &&
marioVelocity.y <= 0) {
// Mario'yu platformun üzerine yerleştir
mario.position.y = platformTop + MARIO_HEIGHT/2;
marioVelocity.y = 0;
isJumping = false;
onGround = true;
}
});
}
function checkCoinCollection() {
const marioBox = new THREE.Box3().setFromObject(mario);
coins.forEach(coin => {
if (!coin.userData.collected) {
const coinBox = new THREE.Box3().setFromObject(coin);
if (marioBox.intersectsBox(coinBox)) {
coin.userData.collected = true;
scene.remove(coin);
coinsCollected++;
document.getElementById('coins').textContent = coinsCollected;
// Coin toplama efekti
createCoinEffect(coin.position);
}
}
});
}
function checkEnemyCollisions() {
const marioBox = new THREE.Box3().setFromObject(mario);
enemies.forEach(enemy => {
const enemyBox = new THREE.Box3().setFromObject(enemy);
if (marioBox.intersectsBox(enemyBox)) {
// Mario'dan yukarıdaysa, düşmanı yen
if (mario.position.y > enemy.position.y + 0.5 && marioVelocity.y < 0) {
scene.remove(enemy);
enemies = enemies.filter(e => e !== enemy);
marioVelocity.y = JUMP_FORCE * 0.7; // Mini zıplama
} else {
// Can kaybet
loseLife();
}
}
});
}
function createCoinEffect(position) {
const particles = [];
for (let i = 0; i < 10; i++) {
const geometry = new THREE.SphereGeometry(0.1, 8, 8);
const material = new THREE.MeshBasicMaterial({ color: 0xFFD700 });
const particle = new THREE.Mesh(geometry, material);
particle.position.copy(position);
particle.velocity = {
x: (Math.random() - 0.5) * 0.2,
y: Math.random() * 0.2,
z: (Math.random() - 0.5) * 0.2
};
scene.add(particle);
particles.push(particle);
}
// Parçacık animasyonu
function animateParticles() {
particles.forEach((particle, index) => {
particle.position.x += particle.velocity.x;
particle.position.y += particle.velocity.y;
particle.position.z += particle.velocity.z;
particle.velocity.y -= 0.01;
particle.material.opacity -= 0.02;
if (particle.material.opacity <= 0) {
scene.remove(particle);
particles.splice(index, 1);
}
});
if (particles.length > 0) {
requestAnimationFrame(animateParticles);
}
}
animateParticles();
}
function updateEnemies() {
enemies.forEach(enemy => {
// Hareket
enemy.position.x += enemy.userData.direction * enemy.userData.speed;
// Sınırları kontrol et
if (Math.abs(enemy.position.x) > 8) {
enemy.userData.direction *= -1;
}
// Dönme animasyonu
enemy.rotation.y += 0.05;
});
}
function updateCoins() {
coins.forEach(coin => {
if (!coin.userData.collected) {
coin.rotation.y += 0.05;
coin.position.y += Math.sin(Date.now() * 0.003) * 0.01;
}
});
}
function updateDebugInfo() {
document.getElementById('posX').textContent = mario.position.x.toFixed(2);
document.getElementById('posY').textContent = mario.position.y.toFixed(2);
document.getElementById('posZ').textContent = mario.position.z.toFixed(2);
document.getElementById('velX').textContent = marioVelocity.x.toFixed(2);
document.getElementById('velY').textContent = marioVelocity.y.toFixed(2);
document.getElementById('velZ').textContent = marioVelocity.z.toFixed(2);
document.getElementById('onGround').textContent = onGround;
}
function loseLife() {
lives--;
document.getElementById('lives').textContent = lives;
if (lives <= 0) {
gameOver();
} else {
// Mario'yu başlangıç pozisyonuna döndür
mario.position.set(0, groundY + MARIO_HEIGHT/2, 0);
marioVelocity = { x: 0, y: 0, z: 0 };
onGround = true;
}
}
function gameOver() {
gameRunning = false;
document.getElementById('gameOver').style.display = 'block';
document.getElementById('finalCoins').textContent = coinsCollected;
if (coinsCollected >= 8) {
document.getElementById('gameOverTitle').textContent = 'Tebrikler! Kazandınız! 🎉';
} else {
document.getElementById('gameOverTitle').textContent = 'Oyun Bitti! 😢';
}
}
function onKeyDown(event) {
keys[event.key] = true;
}
function onKeyUp(event) {
keys[event.key] = false;
}
function onMouseMove(event) {
if (!gameRunning) return;
const mouseX = (event.clientX / window.innerWidth) * 2 - 1;
const mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
// Kamerayı mouse hareketine göre ayarla
camera.position.x = mario.position.x + mouseX * 5;
camera.position.z = mario.position.z + 15 + mouseY * 5;
camera.lookAt(mario.position);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
updateMario();
updateEnemies();
updateCoins();
renderer.render(scene, camera);
}
// Oyunu başlat
initializeGame();
</script>
</body>
</html>
Selamlar az önce ücretsiz olarak paylaştığım yapay zekanın yaptığı 3d platform oyunu hatalar buglar olabilir ama en iyi yapay zeka bu ücretsiz olması + konumda