programı ulu dan cpp uzantılı herhangi boş bir dosyaya kopyala yapıştır yapıp, derledikten sonra çalıştırabilirsiniz, sfml ve c++ ın kütüphane, fonksiyon, metot isimleri çok anlaşılır zaten. return döndür. define tanımla, include içine al, input output stream girdi çıktı akış kütüphanesi, sin cos terimleri bildiğiniz lise trigonometrisi, event olay, key pressed tuşa basıldıysa, draw çizdir, clear sil, update güncelle v.s. v.s.
bu arada derleme komutunuz:
g++ labirent.cpp -o labirent -lsfml-graphics -lsfml-window -lsfml-system -lGL -lGLU
// Çıkış konumu
struct cikis {
float x, y;
} cikis = {8.5f, 7.5f}; // Çıkışın merkezi (haritadaki 'e' konumu)
// Oyuncu yapısı: Konum ve bakış açısı
struct oyuncu {
float x, y; // Oyuncunun haritadaki x ve y koordinatları
float aci; // Oyuncunun bakış açısı (radyan cinsinden)
} oyuncu = {1.5f, 1.5f, 0.0f}; // Başlangıç: (1.5, 1.5) konumunda, 0 derece açı
// Renk yapısı: RGB bileşenleri
struct renk {
unsigned char kirmizi, yesil, mavi; // Renk değerleri (0-255)
};
// Zemin, tavan ve duvarlar için renk tanımları
renk zemin_rengi = {50, 50, 50}; // Gri zemin
renk tavan_rengi = {100, 100, 100}; // Açık gri tavan
renk acik_sari = {255, 255, 150}; // Yakın mesafe duvar rengi
renk sari = {255, 255, 0}; // Orta mesafe duvar rengi
renk kirmizi = {255, 0, 0}; // Çıkışa yakın duvar rengi
// Çıkışa yakınlık ve duvar mesafesine göre renk geçişi
if (normalize_cikis_mesafesi < 0.5f) { // Çıkışa yakın: Sarı -> Kırmızı geçişi
float t = normalize_cikis_mesafesi * 2.0f; // 0-1 aralığına ölçekle
sonuc.kirmizi = sari.kirmizi + (kirmizi.kirmizi - sari.kirmizi) * (1.0f - t);
sonuc.yesil = sari.yesil + (kirmizi.yesil - sari.yesil) * (1.0f - t);
sonuc.mavi = sari.mavi + (kirmizi.mavi - sari.mavi) * (1.0f - t);
} else { // Çıkıştan uzak: Açık sarı -> Sarı geçişi
float t = normalize_duvar_mesafesi; // Duvar mesafesine bağlı geçiş
sonuc.kirmizi = acik_sari.kirmizi + (sari.kirmizi - acik_sari.kirmizi) * t;
sonuc.yesil = acik_sari.yesil + (sari.yesil - acik_sari.yesil) * t;
sonuc.mavi = acik_sari.mavi + (sari.mavi - acik_sari.mavi) * t;
}
return sonuc; // Hesaplanan rengi döndür
}
// Kendi raycasting motorumuz: Işınları gönderip görüntüyü oluşturur
void isinlari_gonder(sf::Uint8* pikseller) {
float gorus_alani = M_PI / 3; // Görüş alanı: 60 derece (radyan)
// Ekranın her sütunu için bir ışın gönder
for (int x = 0; x < ekran_genisligi; x++) {
// Bu sütun için ışın açısını hesapla: Oyuncu açısı ± görüş alanının yarısı
float isin_acisi = oyuncu.aci - (gorus_alani / 2) + (x * gorus_alani) / ekran_genisligi;
float duvara_mesafe = 0; // Işının duvara olan mesafesi
bool duvara_carpti = false; // Duvara çarpıp çarpmadığını kontrol et
float goz_x = cos(isin_acisi); // Işının x yönü (kosinüs)
float goz_y = sin(isin_acisi); // Işının y yönü (sinüs)
// Duvara çarpana veya maksimum mesafeye ulaşana kadar ışını ilerlet
while (!duvara_carpti && duvara_mesafe < 20) {
duvara_mesafe += 0.05f; // Küçük adımlarla ilerle (hassasiyet için)
int test_x = (int)(oyuncu.x + goz_x * duvara_mesafe); // Test edilecek x koordinatı
int test_y = (int)(oyuncu.y + goz_y * duvara_mesafe); // Test edilecek y koordinatı
// Harita sınırlarını kontrol et
if (test_x < 0 || test_x >= harita_genisligi || test_y < 0 || test_y >= harita_yuksekligi) {
duvara_carpti = true; // Sınırlara çarpılırsa duvar kabul et
duvara_mesafe = 20; // Maksimum mesafeye sabitle
}
// Haritada duvara çarpıp çarpmadığını kontrol et
else if (harita[test_y][test_x] == '#') {
duvara_carpti = true; // Duvarsa çarpma tespit edildi
}
}
// Duvar yüksekliğini hesapla (perspektif için açıyı düzelt)
int duvar_yuksekligi = (int)(ekran_yuksekligi / (duvara_mesafe * cos(isin_acisi - oyuncu.aci)));
if (duvar_yuksekligi > ekran_yuksekligi) duvar_yuksekligi = ekran_yuksekligi; // Ekranı aşmasın
// Tavan ve zemin sınırlarını belirle
int tavan = (ekran_yuksekligi / 2) - (duvar_yuksekligi / 2); // Tavanın üst sınırı
int zemin = tavan + duvar_yuksekligi; // Zemin başlangıcı
// Mesafeye bağlı duvar rengini hesapla
renk duvar_rengi = mesafeye_gore_renk_hesapla(duvara_mesafe);
// Sütunun her pikselini doldur
for (int y = 0; y < ekran_yuksekligi; y++) {
int piksel_indeksi = (y * ekran_genisligi + x) * 4; // Pikselin bellekteki konumu (RGBA)
if (y < tavan) { // Tavan alanı
pikseller[piksel_indeksi] = tavan_rengi.kirmizi; // Kırmızı bileşen
pikseller[piksel_indeksi + 1] = tavan_rengi.yesil; // Yeşil bileşen
pikseller[piksel_indeksi + 2] = tavan_rengi.mavi; // Mavi bileşen
pikseller[piksel_indeksi + 3] = 255; // Opaklık (alpha)
}
else if (y >= tavan && y < zemin) { // Duvar alanı
pikseller[piksel_indeksi] = duvar_rengi.kirmizi; // Kırmızı bileşen
pikseller[piksel_indeksi + 1] = duvar_rengi.yesil; // Yeşil bileşen
pikseller[piksel_indeksi + 2] = duvar_rengi.mavi; // Mavi bileşen
pikseller[piksel_indeksi + 3] = 255; // Opaklık (alpha)
}
else { // Zemin alanı
pikseller[piksel_indeksi] = zemin_rengi.kirmizi; // Kırmızı bileşen
pikseller[piksel_indeksi + 1] = zemin_rengi.yesil; // Yeşil bileşen
pikseller[piksel_indeksi + 2] = zemin_rengi.mavi; // Mavi bileşen
pikseller[piksel_indeksi + 3] = 255; // Opaklık (alpha)
}
}
}
}
// Ana program
int main() {
// Oyun penceresini oluştur
sf::RenderWindow pencere(sf::VideoMode(ekran_genisligi, ekran_yuksekligi), "90'lar raycasting labirenti");
pencere.setFramerateLimit(30); // Kare hızını 30 FPS ile sınırla
// Oyun döngüsü
while (pencere.isOpen()) {
sf::Event olay; // Olayları işlemek için yapı
while (pencere.pollEvent(olay)) {
if (olay.type == sf::Event::Closed) pencere.close(); // Pencere kapatılırsa çık
}
float hareket_hizi = 0.1f; // Oyuncunun hareket hızı
float donus_hizi = 0.05f; // Oyuncunun dönüş hızı
// ileri hareket
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
float yeni_x = oyuncu.x + cos(oyuncu.aci) * hareket_hizi; // Yeni x konumu
float yeni_y = oyuncu.y + sin(oyuncu.aci) * hareket_hizi; // Yeni y konumu
if (harita(int)yeni_y](int)yeni_x] != '#') { // Çarpışma yoksa hareket et
oyuncu.x = yeni_x;
oyuncu.y = yeni_y;
}
}
// Geri hareket
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
float yeni_x = oyuncu.x - cos(oyuncu.aci) * hareket_hizi; // Yeni x konumu
float yeni_y = oyuncu.y - sin(oyuncu.aci) * hareket_hizi; // Yeni y konumu
if (harita(int)yeni_y](int)yeni_x] != '#') { // Çarpışma yoksa hareket et
oyuncu.x = yeni_x;
oyuncu.y = yeni_y;
}
}
// Sola dönüş
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
oyuncu.aci -= donus_hizi; // Açıyı saat yönünün tersine çevir
}
// Sağa dönüş
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
oyuncu.aci += donus_hizi; // Açıyı saat yönüne çevir
}
// Piksel dizisini sıfırla (temizle)
for (int i = 0; i < ekran_genisligi * ekran_yuksekligi * 4; i++) {
pikseller[i] = 0;
}
// Raycasting ile görüntüyü oluştur
isinlari_gonder(pikseller);