from random import uniform
from ursina import (
Entity,
Text,
Ursina,
Vec3,
camera,
color,
destroy,
held_keys,
invoke,
time,
window,
)
app = Ursina()
# 1. EKRAN VE GÖKYÜZÜ
window.title = "AirStrike 3D - Aerodinamik Sürüm"
window.borderless = False
window.fullscreen = False
window.color = color.rgb(120, 180, 240) # Mavi Gökyüzü
camera.position = (0, 28, -20)
camera.rotation_x = 55
# 2. HARİTA (Google'dan indirdiğin zemin.jpg kaplaması kullanılıyor)
# Eğer zemin.jpg yoksa beyaz görünür, o yüzden aynı klasörde olmalı!
ground = Entity(
model="plane",
scale=(120, 1, 350),
texture="zemin.jpg", # ZEMİN GÖRSELİ BURADA ENTEGRE EDİLDİ
position=(0, 0, 100)
)
# 3. TAMAMEN YUVARLAK VE AERODİNAMİK HELİKOPTER
player = Entity(position=(0, 3, 0))
# Ana Gövde (Uzun ve pürüzsüz bir küre)
body = Entity(parent=player, model="sphere", color=color.rgb(35, 120, 45), scale=(1.8, 1.2, 3.8))
# Kokpit Camı (Yuvarlak gövdeye gömülü mavi küre)
cockpit = Entity(parent=player, model="sphere", color=color.cyan, scale=(1.4, 0.9, 1.5), position=(0, 0.3, 1.2))
# Kuyruk (İnce uzun silindir, köşesiz)
tail = Entity(parent=player, model="cylinder", color=color.rgb(30, 100, 40), scale=(0.3, 3.0, 0.3), position=(0, 0.1, -2.5), rotation_x=90)
# Kuyruk Pervanesi Göbeği
tail_hub = Entity(parent=player, model="sphere", color=color.rgb(35, 120, 45), scale=(0.4, 0.4, 0.4), position=(0, 0.1, -4.0))
# Ana Pervane Sistemi (Kare yerine yassı ince küreler)
rotor_base = Entity(parent=player, position=(0, 0.8, 0))
blade1 = Entity(parent=rotor_base, model="sphere", color=color.black, scale=(7.5, 0.05, 0.3))
blade2 = Entity(parent=rotor_base, model="sphere", color=color.black, scale=(0.3, 0.05, 7.5))
# 4. SKOR VE SİSTEM DEĞİŞKENLERİ
score = 0
score_text = Text(text=f"SKOR: {score}", position=(-0.85, 0.45), scale=2, color=color.yellow)
bullets = []
enemies = []
shoot_cooldown = 0.0
# 5. AERODİNAMİK DÜŞMAN FÜZELERİ
def spawn_enemy():
enemy = Entity(position=(uniform(-18, 18), 3, player.z + 60))
# Füze Gövdesi (Pürüzsüz Kırmızı Silindir)
Entity(parent=enemy, model="cylinder", color=color.red, scale=(1.0, 3.5, 1.0), rotation_x=90)
# Füze Ucu (Keskin Siyah Koni, tam aerodinamik)
Entity(parent=enemy, model="cone", color=color.black, scale=(1.0, 1.5, 1.0), position=(0, 0, -2.0), rotation_x=-90)
# Füze Motoru/Egzoz (Arka uçta yuvarlak çıkıntı)
Entity(parent=enemy, model="sphere", color=color.dark_gray, scale=(0.8, 0.8, 0.8), position=(0, 0, 1.7))
enemies.append(enemy)
invoke(spawn_enemy, delay=0.8) # Her 0.8 saniyede bir yeni füze
spawn_enemy()
# 6. OYUN DÖNGÜSÜ VE FİZİKLER
def update():
global score, shoot_cooldown
move_speed = 18 * time.dt
# Pervaneyi gerçekçi bir şekilde fırıl fırıl döndür
rotor_base.rotation_y += 2000 * time.dt
# HAREKET KONTROLLERİ (A/D tuşlarıyla yatma efekti)
if held_keys["a"] or held_keys["left arrow"]:
player.x -= move_speed
player.rotation_z = 25
elif held_keys["d"] or held_keys["right arrow"]:
player.x += move_speed
player.rotation_z = -25
else:
player.rotation_z = 0
if held_keys["w"] or held_keys["up arrow"]:
player.z += move_speed
if held_keys["s"] or held_keys["down arrow"]:
player.z -= move_speed
# Uçuş Sınırları
player.x = max(-20, min(20, player.x))
# Kamera helikopteri pürüzsüzce takip eder
camera.x = player.x
camera.z = player.z - 22
# --- SERİ ATEŞ ETME (Boşluk Tuşuna Basılı Tut) ---
shoot_cooldown -= time.dt
if held_keys["space"] and shoot_cooldown <= 0:
# İki kanattan yuvarlak sarı mermiler
b1 = Entity(model="sphere", color=color.yellow, scale=0.6, position=player.position + Vec3(-1.2, -0.2, 1.5))
b2 = Entity(model="sphere", color=color.yellow, scale=0.6, position=player.position + Vec3(1.2, -0.2, 1.5))
bullets.extend([b1, b2])
shoot_cooldown = 0.12 # Ateş hızı
# Mermileri ileri uçur
for b in bullets[:]:
b.z += 80 * time.dt
if b.z > player.z + 70:
bullets.remove(b)
destroy(b)
# Füzeleri üstüne doğru uçur
for e in enemies[:]:
e.z -= 15 * time.dt
if e.z < player.z - 15:
enemies.remove(e)
destroy(e)
# %100 KESİN VURUŞ KONTROLÜ (Mesafe hesaplama)
for b in bullets[:]:
for e in enemies[:]:
if (b.position - e.position).length() < 3.0:
score += 100
score_text.text = f"SKOR: {score}"
if e in enemies:
enemies.remove(e)
destroy(e)
if b in bullets:
bullets.remove(b)
destroy(b)
break
app.run()