Minecraft MIDI & Pixelart

Minecraft dünyanızda müzik çalabileceğiniz ve pixelart oluşturabileceğiniz bir uygulama.


Python MCRCON Lib OpenCV MIDI
projectDetails.md

# Proje Özeti

2 sekmeden oluşan uygulamam size hem müzik çalmanızı hem de resim çizmenizi sağlıyor...

Proje Ekran Görüntüsü Resim 1: Editörlerin ekran görüntüsü.

Uygulamayı çalıştırmak için...

MIDI çalarken python scripti ile aynı dizinde 'music.txt'...

bash command BASH
pip install mcrcon

Bu komutla ilk önce kütüphaneyi kurmanız gerekmektedir...

# Scriptler

midi.py python
from mcrcon import MCRcon
import time
import ast
import os
import threading
from collections import defaultdict

sunucuIP = "127.0.0.1"
sunucuPASS = "12345"

blok = 'minecraft:redstone_block'

# RCON bağlantısı için thread lock
rcon_lock = threading.Lock()

# Her enstrüman için farklı Y koordinatları
INSTRUMENT_Y = {
    'harp': 57,      # Herhangi bir blok
    'bass': 60,      # Oak planks
    'bell': 63,      # Gold block
    'flute': 66,     # Clay
    'chime': 69,     # Packed ice
    'guitar': 72,    # White wool
    'xylophone': 75  # Bone block
}

# Her enstrüman için nota koordinatları
NOTA_Z_KOORDS = {
    'harp': {
        'fad1': 1, 'sol1': 2, 'sold1': 3, 'la1': 4, 'lad1': 5, 'si1': 6,
        'do2': 7, 'dod2': 8, 're2': 9, 'red2': 10, 'mi2': 11, 'fa2': 12,
        'fad2': 13, 'sol2': 14, 'sold2': 15, 'la2': 16, 'lad2': 17, 'si2': 18,
        'do3': 19, 'dod3': 20, 're3': 21, 'red3': 22, 'mi3': 23, 'fa3': 24, 'fad3': 25
    },
    'bass': {
        'fad0': 1, 'sol0': 2, 'sold0': 3, 'la0': 4, 'lad0': 5, 'si0': 6,
        'do1': 7, 'dod1': 8, 're1': 9, 'red1': 10, 'mi1': 11, 'fa1': 12,
        'fad1': 13, 'sol1': 14, 'sold1': 15, 'la1': 16, 'lad1': 17, 'si1': 18,
        'do2': 19, 'dod2': 20, 're2': 21, 'red2': 22, 'mi2': 23, 'fa2': 24, 'fad2': 25
    },
    'bell': {
        'fad3': 1, 'sol3': 2, 'sold3': 3, 'la3': 4, 'lad3': 5, 'si3': 6,
        'do4': 7, 'dod4': 8, 're4': 9, 'red4': 10, 'mi4': 11, 'fa4': 12,
        'fad4': 13, 'sol4': 14, 'sold4': 15, 'la4': 16, 'lad4': 17, 'si4': 18,
        'do5': 19, 'dod5': 20, 're5': 21, 'red5': 22, 'mi5': 23, 'fa5': 24, 'fad5': 25
    },
    'flute': {
        'fad2': 1, 'sol2': 2, 'sold2': 3, 'la2': 4, 'lad2': 5, 'si2': 6,
        'do3': 7, 'dod3': 8, 're3': 9, 'red3': 10, 'mi3': 11, 'fa3': 12,
        'fad3': 13, 'sol3': 14, 'sold3': 15, 'la3': 16, 'lad3': 17, 'si3': 18,
        'do4': 19, 'dod4': 20, 're4': 21, 'red4': 22, 'mi4': 23, 'fa4': 24, 'fad4': 25
    },
    'chime': {
        'fad3': 1, 'sol3': 2, 'sold3': 3, 'la3': 4, 'lad3': 5, 'si3': 6,
        'do4': 7, 'dod4': 8, 're4': 9, 'red4': 10, 'mi4': 11, 'fa4': 12,
        'fad4': 13, 'sol4': 14, 'sold4': 15, 'la4': 16, 'lad4': 17, 'si4': 18,
        'do5': 19, 'dod5': 20, 're5': 21, 'red5': 22, 'mi5': 23, 'fa5': 24, 'fad5': 25
    },
    'guitar': {
        'fad1': 1, 'sol1': 2, 'sold1': 3, 'la1': 4, 'lad1': 5, 'si1': 6,
        'do2': 7, 'dod2': 8, 're2': 9, 'red2': 10, 'mi2': 11, 'fa2': 12,
        'fad2': 13, 'sol2': 14, 'sold2': 15, 'la2': 16, 'lad2': 17, 'si2': 18,
        'do3': 19, 'dod3': 20, 're3': 21, 'red3': 22, 'mi3': 23, 'fa3': 24, 'fad3': 25
    },
    'xylophone': {
        'fad3': 1, 'sol3': 2, 'sold3': 3, 'la3': 4, 'lad3': 5, 'si3': 6,
        'do4': 7, 'dod4': 8, 're4': 9, 'red4': 10, 'mi4': 11, 'fa4': 12,
        'fad4': 13, 'sol4': 14, 'sold4': 15, 'la4': 16, 'lad4': 17, 'si4': 18,
        'do5': 19, 'dod5': 20, 're5': 21, 'red5': 22, 'mi5': 23, 'fa5': 24, 'fad5': 25
    }
}


def muzik_yukle(dosya_adi='music.txt'):
    """music.txt dosyasından müzik dizisini yükle"""
    try:
        script_dir = os.path.dirname(os.path.abspath(__file__))
        dosya_yolu = os.path.join(script_dir, dosya_adi)
        
        if not os.path.exists(dosya_yolu):
            print(f"❌ Hata: {dosya_adi} dosyası bulunamadı!")
            print(f"📁 Aranan konum: {dosya_yolu}")
            print(f"💡 Çözüm: music.txt dosyasını şu konuma kaydedin: {script_dir}")
            
            try:
                dosyalar = os.listdir(script_dir)
                print(f"\n📂 Mevcut dizindeki dosyalar:")
                for d in dosyalar:
                    print(f"  - {d}")
            except:
                pass
            
            return []
        
        with open(dosya_yolu, 'r', encoding='utf-8') as f:
            icerik = f.read()
        
        # "music = [" ile başlıyorsa, sadece liste kısmını al
        if 'music = [' in icerik:
            baslangic = icerik.find('[')
            bitis = icerik.rfind(']') + 1
            liste_str = icerik[baslangic:bitis]
        else:
            liste_str = icerik
        
        # String'i Python listesine çevir
        music = ast.literal_eval(liste_str)
        
        # Format kontrolü - yeni format (zaman, nota, enstruman)
        if music and len(music[0]) == 3 and isinstance(music[0][0], (int, float)):
            print(f"✅ {len(music)} nota yüklendi (mutlak zamanlama)")
        else:
            print(f"❌ Hata: Geçersiz müzik formatı!")
            print(f"💡 Format: (zaman_saniye, nota, enstruman)")
            return []
        
        return music
    
    except FileNotFoundError:
        print(f"❌ Hata: {dosya_adi} dosyası bulunamadı!")
        return []
    except Exception as e:
        print(f"❌ Müzik dosyası okunurken hata: {e}")
        return []


def nota_cal(note_name, instrument, mcr):
    """Belirtilen enstrüman ve notayı çal"""
    y_coord = INSTRUMENT_Y.get(instrument)
    z_coord = NOTA_Z_KOORDS.get(instrument, {}).get(note_name)
    
    if y_coord is None or z_coord is None:
        return
    
    try:
        with rcon_lock:
            cmd = f'setblock 0 {y_coord} {z_coord} {blok}'
            mcr.command(cmd)
            time.sleep(0.05)
            cmd = f'setblock 0 {y_coord} {z_coord} air'
            mcr.command(cmd)
    except Exception as e:
        print(f"Hata ({note_name}/{instrument}): {e}")


def muzik_cal(melody, mcr):
    """Müziği polifonik olarak çalar - mutlak zamanlama ile"""
    if not melody:
        return
    
    # Zamanı aynı olan notaları grupla (20ms tolerans)
    nota_gruplari = defaultdict(list)
    for zaman, note, instrument in melody:
        zaman_anahtari = round(zaman * 50) / 50  # 20ms hassasiyet
        nota_gruplari[zaman_anahtari].append((note, instrument))
    
    # Sıralı zamanları al
    zamanlar = sorted(nota_gruplari.keys())
    
    baslangic = time.time()
    
    for hedef_zaman in zamanlar:
        # Hedef zamana kadar bekle
        simdiki_zaman = time.time() - baslangic
        bekleme = hedef_zaman - simdiki_zaman
        
        if bekleme > 0:
            time.sleep(bekleme)
        
        # Bu zamandaki tüm notaları paralel çal
        notalar = nota_gruplari[hedef_zaman]
        
        if len(notalar) > 1:
            # Birden fazla nota varsa thread'lerle paralel çal
            threads = []
            for note, instrument in notalar:
                t = threading.Thread(target=nota_cal, args=(note, instrument, mcr))
                t.start()
                threads.append(t)
            
            # Tüm notaların çalmasını bekle
            for t in threads:
                t.join()
        else:
            # Tek nota
            note, instrument = notalar[0]
            nota_cal(note, instrument, mcr)


# Ana program
if __name__ == "__main__":
    music = muzik_yukle('music.txt')
    
    if not music:
        print("Müzik yüklenemedi, program sonlandırılıyor...")
        exit()
    
    try:
        with MCRcon(sunucuIP, sunucuPASS) as mcr:
            print("🎵 Müzik çalıyor... (Durdurmak için Ctrl+C)")
            time.sleep(2)
            muzik_cal(music, mcr)
            print("Müzik bitti.")
    except KeyboardInterrupt:
        print("\n⏹️ Müzik durduruldu!")
    except Exception as e:
        print(f"❌ Bağlantı hatası: {e}")
                                
              
mcpp.py python
from mcrcon import MCRcon
import time

sunucuIP = "127.0.0.1"
sunucuPASS = "12345"
resim_matrisi = [] # Matrisi buraya yapıştıracaksınız.

# Buradaki blokları kendi istediğiniz gibi deeğiştirebilirsiniz. 
# Ancak web uygulama buradaki sıralamaya göre renkler üretecektir. Buna dikkat edin.
RENKLI_BLOKLAR = { 
    1: "minecraft:white_concrete_powder",
    2: "minecraft:light_gray_concrete_powder",
    3: "minecraft:gray_concrete_powder",
    4: "minecraft:black_concrete_powder",
    5: "minecraft:brown_concrete_powder",
    6: "minecraft:red_concrete_powder",
    7: "minecraft:orange_concrete_powder",
    8: "minecraft:yellow_concrete_powder",
    9: "minecraft:lime_concrete_powder",
    10: "minecraft:green_concrete_powder",
    11: "minecraft:cyan_concrete_powder",
    12: "minecraft:light_blue_concrete_powder",
    13: "minecraft:blue_concrete_powder",
    14: "minecraft:purple_concrete_powder",
    15: "minecraft:magenta_concrete_powder",
    16: "minecraft:pink_concrete_powder",
}

with MCRcon(sunucuIP, sunucuPASS) as mcr:  
    cmd = f'fill -20 57 32 -20 88 1 air'
    mcr.command(cmd) 
    
    cmd = f'fill -20 56 32 -20 56 1 minecraft:stone'
    mcr.command(cmd)   
    x = 32
    y = 57
    z = 0
    for i in range(0, 32):
        for i in range (0, 32):
            blok_sirasi = resim_matrisi[z]
            blok = RENKLI_BLOKLAR.get(blok_sirasi)
            cmd = f'setblock -20 {y} {x} {blok}'
            mcr.command(cmd)
            x -= 1
            z += 1
            time.sleep(0.001)
        x = 32
        y += 1
        time.sleep(0.01)