Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.05.2025, 00:20   #71
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 370
По умолчанию

Цитата:
Сообщение от gimes Посмотреть сообщение
Здравствуйте. Нижняя часть демо версии скрипта с отображением каналов открылась только через прокси и часть вкладок не рабочие в этом случае. Или не через тот браузер запускаю. А в каком браузере это работает (я из России)?

А в этом фрагменте не понятно, что именно интересно. Есть ли у Вас другая запись, где ясно слышно, что Вы имели в виду и хотели показать?
Вот специально для тебя сделал 2 версию -> ссылка где можно изменять количество фреймов. Для тех у кого слишком долго загружается, и так же можно вводить любое число а не только от 1 до 19. И потом отпиши смог ли ты пообщаться с призраками...

Последний раз редактировалось MakarovDs; 06.05.2025 в 02:52.
MakarovDs на форуме Ответить с цитированием
Старый 27.05.2025, 02:56   #72
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 370
По умолчанию

Четвертая версия ЭГФ Хоруса

Код:
import tkinter as tk
from tkinter import filedialog, messagebox
import os
import random
from pydub import AudioSegment

# Глобальный список выбранных аудио
selected_audios = []

def convert_audio_to_bytes(path):
    with open(path, 'rb') as f:
        return f.read()

def save_bytes_as_audio(byte_data, output_path):
    with open(output_path, 'wb') as f:
        f.write(byte_data)

def create_eghf():
    # Получаем длину в секундах из поля ввода
    duration_sec = int(entry_duration.get())
    duration_ms = duration_sec * 1000

    combined_bytes = bytearray()
    header_length = 100
    block_size = 64

    for audio_path in selected_audios:
        byte_data = convert_audio_to_bytes(audio_path)
        byte_list = list(byte_data)
        data_to_shuffle = byte_list[header_length:]
        num_blocks = len(data_to_shuffle) // block_size
        blocks = [data_to_shuffle[i*block_size:(i+1)*block_size] for i in range(num_blocks)]
        random.shuffle(blocks)
        shuffled_data = [byte for block in blocks for byte in block]
        byte_list[header_length:] = shuffled_data
        shuffled_byte_data = bytes(byte_list)
        combined_bytes.extend(shuffled_byte_data)

    # Обрезаем итоговый байтовый поток до нужной длины
    # Предполагается, что байты — это 16-битный звук, т.е. 2 байта на сэмпл
    # Тогда длина в байтах = (длина в миллисекундах / 1000) * частота * число каналов * 2
    # Но для простоты, можно просто взять первые N байт, соответствующие нужной длительности
    # Например, если частота 44100 Гц, 2 канала, 2 байта на сэмпл:
    sample_rate = 44100
    channels = 2
    bytes_per_sample = 2
    total_bytes = int((duration_sec * sample_rate * channels * bytes_per_sample))
    trimmed_bytes = combined_bytes[:total_bytes]

    # Создаем аудио из байтов
    output_path = os.path.join(os.path.expanduser("~"), "Desktop", "evp_audio.mp4")
    save_bytes_as_audio(trimmed_bytes, output_path)
    messagebox.showinfo("Готово", f"ЭГФ сохранен: {output_path}")

# Создаем интерфейс
root = tk.Tk()
root.title("Создание ЭГФ из аудио")
root.geometry("500x400")

# Поле для ввода длины
tk.Label(root, text="Длина ЭГФ (сек):").pack(pady=5)
entry_duration = tk.Entry(root)
entry_duration.pack(pady=5)
entry_duration.insert(0, "60")  # по умолчанию 10 секунд

# Кнопка выбора аудио
def select_audio():
    file_path = filedialog.askopenfilename(
        title="Выберите аудио файл",
        filetypes=[("Audio files", "*.mp3;*.wav;*.ogg")]
    )
    if file_path:
        selected_audios.append(file_path)
        listbox.insert(tk.END, file_path)

listbox = tk.Listbox(root, width=60)
listbox.pack(pady=10)

tk.Button(root, text="Выбрать аудио", command=select_audio).pack(pady=5)
tk.Button(root, text="Создать ЭГФ", command=create_eghf).pack(pady=5)

root.mainloop()
Как всегда гитхаб ссылка.



Теперь можно выбрать разные видео, и из разных наборов делать одно ЭГФ аудио.

Последний раз редактировалось MakarovDs; 27.05.2025 в 14:42.
MakarovDs на форуме Ответить с цитированием
Старый 28.05.2025, 20:37   #73
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 370
По умолчанию

Третья версия EVP-аудиомикшера

Код:
import tkinter as tk
from tkinter import filedialog, messagebox
import random
import numpy as np
import pygame
from threading import Thread
import time
from pydub import AudioSegment

# Глобальный список выбранных аудио
selected_audios = []

class AudioMosaic:
    def __init__(self):
        self.segments = []
        self.sample_rate = 0
        self.is_playing = False
        self.thread = None
        pygame.mixer.init()

    def convert_audio_to_segments(self, path):
        audio = AudioSegment.from_file(path)
        segments = []
        current_time = 0
        while current_time < len(audio):
            segment_duration_ms = random.randint(100, 1000)
            segment = audio[current_time:current_time + segment_duration_ms]
            segments.append(segment.raw_data)
            current_time += segment_duration_ms
        return segments, audio.frame_rate

    def prepare_segments(self, files):
        all_segments = []
        sample_rate = 0
        for file in files:
            segments, rate = self.convert_audio_to_segments(file)
            all_segments.extend(segments)
            sample_rate = rate
        self.segments = all_segments
        self.sample_rate = sample_rate

    def mix_audio_segments(self):
        random.shuffle(self.segments)
        return b''.join(self.segments)

    def play_audio(self):
        self.is_playing = True
        while self.is_playing:
            shuffled_audio = self.mix_audio_segments()
            sound_array = np.frombuffer(shuffled_audio, dtype=np.int16)
            sound = pygame.mixer.Sound(buffer=sound_array)
            sound.play()
            duration = len(shuffled_audio) / (self.sample_rate * 2)
            time.sleep(duration) 
        # После окончания воспроизведения, цикл снова начнется, если self.is_playing == True

    def start_playback(self):
        if not self.is_playing:
            self.thread = Thread(target=self.play_audio, daemon=True)
            self.thread.start()

    def stop_audio(self):
        self.is_playing = False
        pygame.mixer.stop()

# Создаем главное окно
root = tk.Tk()
root.title("Генератор случайного аудио")
root.geometry("600x400")

audio_mosaic = AudioMosaic()

# --- Область для отображения выбранных аудио ---
frame_listbox = tk.Frame(root)
frame_listbox.pack(pady=10)

listbox = tk.Listbox(frame_listbox, width=70, height=8)
listbox.pack(side=tk.LEFT, padx=5)

scrollbar = tk.Scrollbar(frame_listbox, orient=tk.VERTICAL)
scrollbar.config(command=listbox.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

listbox.config(yscrollcommand=scrollbar.set)

# --- Функция выбора файла ---
def select_audio():
    global selected_audios
    file_path = filedialog.askopenfilename(
        title="Выберите аудио файл",
        filetypes=[("Audio Files", "*.wav;*.mp3;*.mp4;*.ogg;*.flac")]
    )
    if file_path:
        selected_audios.append(file_path)
        listbox.insert(tk.END, file_path)

# --- Удаление выбранного файла из списка ---
def remove_selected():
    global selected_audios
    selected_indices = listbox.curselection()
    if not selected_indices:
        messagebox.showwarning("Предупреждение", "Выберите файл для удаления.")
        return
    for index in reversed(selected_indices):
        listbox.delete(index)
        del selected_audios[index]

# --- Воспроизведение и остановка ---
def start_audio():
    global selected_audios
    if not selected_audios:
        messagebox.showwarning("Предупреждение", "Пожалуйста, выберите аудиофайлы.")
        return
    # Объединяем сегменты из всех выбранных файлов
    audio_mosaic.prepare_segments(selected_audios)
    audio_mosaic.start_playback()

def stop_audio():
    global selected_audios
    audio_mosaic.stop_audio()

# --- Кнопки ---
button_frame = tk.Frame(root)
button_frame.pack(pady=10)

start_button = tk.Button(button_frame, text="Старт", command=start_audio)
start_button.pack(side=tk.LEFT, padx=10)

stop_button = tk.Button(button_frame, text="Стоп", command=stop_audio)
stop_button.pack(side=tk.LEFT, padx=10)

remove_button = tk.Button(root, text="Удалить выбранное", command=remove_selected)
remove_button.pack(pady=5)

# --- Кнопка выбора файла ---
select_button = tk.Button(root, text="Выбрать аудио", command=select_audio)
select_button.pack(pady=5)

# Запуск интерфейса
root.mainloop()
Код гитхаба -> ссылка.

Последний раз редактировалось MakarovDs; 29.05.2025 в 01:46.
MakarovDs на форуме Ответить с цитированием
Старый 28.05.2025, 22:27   #74
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 370
По умолчанию

Пятая версия ЭГФ Хоруса

Код:
import tkinter as tk
from tkinter import filedialog, messagebox
import os
import random
from pydub import AudioSegment

# Глобальный список выбранных аудио
selected_audios = []

def convert_audio_to_bytes(path):
    with open(path, 'rb') as f:
        return f.read()

def save_bytes_as_audio(byte_data, output_path):
    with open(output_path, 'wb') as f:
        f.write(byte_data)

def create_eghf():
    # Получаем длину в секундах из поля ввода
    duration_sec = int(entry_duration.get())
    combined_bytes = bytearray()
    header_length = 100
    block_size = 64

    for audio_path in selected_audios:
        byte_data = convert_audio_to_bytes(audio_path)
        byte_list = list(byte_data)
        data_to_shuffle = byte_list[header_length:]
        num_blocks = len(data_to_shuffle) // block_size
        blocks = [data_to_shuffle[i*block_size:(i+1)*block_size] for i in range(num_blocks)]
        random.shuffle(blocks)
        shuffled_data = [byte for block in blocks for byte in block]
        byte_list[header_length:] = shuffled_data
        shuffled_byte_data = bytes(byte_list)
        combined_bytes.extend(shuffled_byte_data)

    # Обрезаем итоговый байтовый поток до нужной длины
    sample_rate = 44100
    channels = 2
    bytes_per_sample = 2
    total_bytes = int((duration_sec * sample_rate * channels * bytes_per_sample))
    trimmed_bytes = combined_bytes[:total_bytes]

    # Создаем аудио из байтов
    output_path = os.path.join(os.path.expanduser("~"), "Desktop", "evp_audio.mp4")
    save_bytes_as_audio(trimmed_bytes, output_path)
    messagebox.showinfo("Готово", f"ЭГФ сохранен: {output_path}")

# Создаем интерфейс
root = tk.Tk()
root.title("Создание ЭГФ из аудио")
root.geometry("500x400")

# Поле для ввода длины
tk.Label(root, text="Длина ЭГФ (сек):").pack(pady=5)
entry_duration = tk.Entry(root)
entry_duration.pack(pady=5)
entry_duration.insert(0, "60")  # по умолчанию 60 секунд

# Область для списка выбранных файлов
listbox = tk.Listbox(root, width=60)
listbox.pack(pady=10)

# Кнопка выбора файла
def select_audio():
    global selected_audios
    file_path = filedialog.askopenfilename(
        title="Выберите аудио файл",
        filetypes=[("Audio files", ".mp3;.wav;*.ogg")]
    )
    if file_path:
        selected_audios.append(file_path)
        listbox.insert(tk.END, file_path)

tk.Button(root, text="Выбрать аудио", command=select_audio).pack(pady=5)

# --- Кнопка "Удалить выбранное" ---
def remove_selected():
    global selected_audios
    selected_indices = listbox.curselection()
    if not selected_indices:
        messagebox.showwarning("Предупреждение", "Выберите файл для удаления.")
        return
    for index in reversed(selected_indices):
        listbox.delete(index)
        del selected_audios[index]

tk.Button(root, text="Удалить выбранное", command=remove_selected).pack(pady=5)

# --- Кнопка "Создать ЭГФ" ---
tk.Button(root, text="Создать ЭГФ", command=create_eghf).pack(pady=5)

root.mainloop()
Она та же что и четвертая версия просто забыл добавить опцию "Удалить выбранное".



ссылка гитхаб -> github.
MakarovDs на форуме Ответить с цитированием
Старый Вчера, 02:55   #75
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 370
По умолчанию

Шестая версия ЭГФ Хоруса
Код:
import tkinter as tk
from tkinter import filedialog, messagebox
import os
import random
from pydub import AudioSegment
from moviepy.editor import VideoFileClip

# Глобальный список выбранных файлов
selected_files = []

def extract_audio_from_video(video_path):
    try:
        clip = VideoFileClip(video_path)
        audio_path = os.path.splitext(video_path)[0] + "_temp_audio.mp3"
        clip.audio.write_audiofile(audio_path, verbose=False, logger=None)
        clip.close()
        return audio_path
    except Exception as e:
        messagebox.showerror("Ошибка", f"Не удалось извлечь аудио из видео: {e}")
        return None

def convert_audio_to_bytes(path):
    with open(path, 'rb') as f:
        return f.read()

def save_bytes_as_audio(byte_data, output_path):
    with open(output_path, 'wb') as f:
        f.write(byte_data)

def create_eghf():
    # Получаем длину в секундах из поля ввода
    try:
        duration_sec = int(entry_duration.get())
    except ValueError:
        messagebox.showerror("Ошибка", "Пожалуйста, введите корректное число для длины.")
        return

    combined_bytes = bytearray()
    header_length = 100
    block_size = 64

    for file_path in selected_files:
        ext = os.path.splitext(file_path)[1].lower()
        if ext in ['.mp4', '.avi', '.mov', '.mkv']:
            # Извлекаем аудио из видео
            audio_path = extract_audio_from_video(file_path)
            if not audio_path:
                continue
            byte_data = convert_audio_to_bytes(audio_path)
            # Удаляем временный файл
            os.remove(audio_path)
        else:
            # Аудио файл
            byte_data = convert_audio_to_bytes(file_path)

        byte_list = list(byte_data)
        data_to_shuffle = byte_list[header_length:]
        num_blocks = len(data_to_shuffle) // block_size
        blocks = [data_to_shuffle[i*block_size:(i+1)*block_size] for i in range(num_blocks)]
        random.shuffle(blocks)
        shuffled_data = [byte for block in blocks for byte in block]
        byte_list[header_length:] = shuffled_data
        shuffled_byte_data = bytes(byte_list)
        combined_bytes.extend(shuffled_byte_data)

    # Обрезаем итоговый байтовый поток до нужной длины
    sample_rate = 44100
    channels = 2
    bytes_per_sample = 2
    total_bytes = int((duration_sec * sample_rate * channels * bytes_per_sample))
    trimmed_bytes = combined_bytes[:total_bytes]

    # Создаем аудио из байтов
    output_path = os.path.join(os.path.expanduser("~"), "Desktop", "evp_audio.mp3")
    save_bytes_as_audio(trimmed_bytes, output_path)
    messagebox.showinfo("Готово", f"ЭГФ сохранен: {output_path}")

# Создаем интерфейс
root = tk.Tk()
root.title("Создание ЭГФ из аудио/видео")
root.geometry("600x500")

# Поле для ввода длины
tk.Label(root, text="Длина ЭГФ (сек):").pack(pady=5)
entry_duration = tk.Entry(root)
entry_duration.pack(pady=5)
entry_duration.insert(0, "60")  # по умолчанию 60 секунд

# Область для списка выбранных файлов
listbox = tk.Listbox(root, width=70)
listbox.pack(pady=10)

# --- Функция выбора файлов ---
def select_files():
    global selected_files
    file_paths = filedialog.askopenfilenames(
        title="Выберите файлы",
        filetypes=[
            ("Аудио и видео файлы", "*.mp3;*.wav;*.ogg;*.mp4;*.avi;*.mov;*.mkv"),
            ("Все файлы", "*.*")
        ]
    )
    if file_paths:
        for path in file_paths:
            selected_files.append(path)
            listbox.insert(tk.END, path)

tk.Button(root, text="Выбрать файлы", command=select_files).pack(pady=5)

# --- Удаление выбранных ---
def remove_selected():
    global selected_files
    selected_indices = listbox.curselection()
    if not selected_indices:
        messagebox.showwarning("Предупреждение", "Выберите файл для удаления.")
        return
    for index in reversed(selected_indices):
        listbox.delete(index)
        del selected_files[index]

tk.Button(root, text="Удалить выбранное", command=remove_selected).pack(pady=5)

# --- Создать ЭГФ ---
tk.Button(root, text="Создать ЭГФ", command=create_eghf).pack(pady=5)

root.mainloop()
Теперь мы можем делать ЭГФ из ЭГФ что-бы получить более чёткие голоса с того света.

Ссылка гитхаб -> github.

Там же посмотрите примеры ЭГФ.

Последний раз редактировалось MakarovDs; Вчера в 17:22.
MakarovDs на форуме Ответить с цитированием
Старый Сегодня, 03:29   #76
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 370
По умолчанию

Аудиомикшер 4 версия

Код:
import tkinter as tk
from tkinter import filedialog, messagebox
import random
import numpy as np
import pygame
from threading import Thread
import time
from pydub import AudioSegment

# Глобальный список выбранных аудио
selected_audios = []

class AudioMosaic:
    def __init__(self):
        self.segments = []
        self.sample_rate = 0
        self.is_playing = False
        self.thread = None
        pygame.mixer.init()

    def convert_audio_to_segments(self, path):
        audio = AudioSegment.from_file(path)
        segments = []
        current_time = 0
        while current_time < len(audio):
            segment_duration_ms = random.randint(100, 1000)
            segment = audio[current_time:current_time + segment_duration_ms]
            segments.append(segment.raw_data)
            current_time += segment_duration_ms
        return segments, audio.frame_rate

    def prepare_segments(self, files):
        all_segments = []
        sample_rate = 0
        for file in files:
            segments, rate = self.convert_audio_to_segments(file)
            all_segments.extend(segments)
            sample_rate = rate
        self.segments = all_segments
        self.sample_rate = sample_rate

    def mix_audio_segments(self):
        random.shuffle(self.segments)
        return b''.join(self.segments)

    def play_audio(self):
        self.is_playing = True
        # Получение настроек из интерфейса
        global mode, speed, min_time, max_time
        while self.is_playing:
            if mode.get() == "intermediate":
                # Генерируем случайное время
                interval_time = random.uniform(min_time.get(), max_time.get())
                # Выбираем случайный сегмент
                segment = random.choice(self.segments)
                # Воспроизводим сегмент
                sound_array = np.frombuffer(segment, dtype=np.int16)
                sound = pygame.mixer.Sound(buffer=sound_array)
                sound.play()
                # Ждем окончания воспроизведения сегмента
                duration = len(segment) / (self.sample_rate * 2)
                time.sleep(duration)
                # Минимальная задержка между сегментами для плавности
                time.sleep(0)  # 20 мс
            else:
                # Постоянный режим
                shuffled_audio = self.mix_audio_segments()
                sound_array = np.frombuffer(shuffled_audio, dtype=np.int16)
                sound = pygame.mixer.Sound(buffer=sound_array)
                sound.play()
                duration = len(shuffled_audio) / (self.sample_rate * 2)
                time.sleep(duration)

    def start_playback(self):
        if not self.is_playing:
            self.thread = Thread(target=self.play_audio, daemon=True)
            self.thread.start()

    def stop_audio(self):
        self.is_playing = False
        pygame.mixer.stop()

# Создаем главное окно
root = tk.Tk()
root.title("Генератор случайного аудио")
root.geometry("900x600")

audio_mosaic = AudioMosaic()

# --- Область для отображения выбранных аудио ---
frame_listbox = tk.Frame(root)
frame_listbox.pack(pady=10)

listbox = tk.Listbox(frame_listbox, width=70, height=8)
listbox.pack(side=tk.LEFT, padx=5)

scrollbar = tk.Scrollbar(frame_listbox, orient=tk.VERTICAL)
scrollbar.config(command=listbox.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

listbox.config(yscrollcommand=scrollbar.set)

# --- Функция выбора файла ---
def select_audio():
    global selected_audios
    file_path = filedialog.askopenfilename(
        title="Выберите аудио файл",
        filetypes=[("Audio Files", "*.wav;*.mp3;*.mp4;*.ogg;*.flac")]
    )
    if file_path:
        selected_audios.append(file_path)
        listbox.insert(tk.END, file_path)

# --- Удаление выбранного файла из списка ---
def remove_selected():
    global selected_audios
    selected_indices = listbox.curselection()
    if not selected_indices:
        messagebox.showwarning("Предупреждение", "Выберите файл для удаления.")
        return
    for index in reversed(selected_indices):
        listbox.delete(index)
        del selected_audios[index]

# --- Воспроизведение и остановка ---
def start_audio():
    global selected_audios
    if not selected_audios:
        messagebox.showwarning("Предупреждение", "Пожалуйста, выберите аудиофайлы.")
        return
    # Объединяем сегменты из всех выбранных файлов
    audio_mosaic.prepare_segments(selected_audios)
    audio_mosaic.start_playback()

def stop_audio():
    global selected_audios
    audio_mosaic.stop_audio()

# --- Настройки режима ---
mode = tk.StringVar(value="constant")  # "constant" или "intermediate"

# --- Поля для диапазона времени ---
min_time = tk.DoubleVar(value=0.5)
max_time = tk.DoubleVar(value=2.0)

# --- Поле для скорости переключения ---
speed_var = tk.DoubleVar(value=1.0)

# --- Интерфейс ---
frame_controls = tk.Frame(root)
frame_controls.pack(pady=10)

# --- Кнопки режима ---
intermediate_button = tk.Radiobutton(frame_controls, text="Промежуточный режим", variable=mode, value="intermediate")
intermediate_button.pack(side=tk.LEFT, padx=10)

constant_button = tk.Radiobutton(frame_controls, text="Постоянный режим", variable=mode, value="constant")
constant_button.pack(side=tk.LEFT, padx=10)

# --- Поля диапазона времени ---
tk.Label(frame_controls, text="Мин. время (сек):").pack(side=tk.LEFT)
min_entry = tk.Entry(frame_controls, textvariable=min_time, width=5)
min_entry.pack(side=tk.LEFT, padx=5)

tk.Label(frame_controls, text="Макс. время (сек):").pack(side=tk.LEFT)
max_entry = tk.Entry(frame_controls, textvariable=max_time, width=5)
max_entry.pack(side=tk.LEFT, padx=5)

# --- Поле скорости ---
tk.Label(frame_controls, text="Скорость переключения:").pack(side=tk.LEFT)
speed_entry = tk.Entry(frame_controls, textvariable=speed_var, width=5)
speed_entry.pack(side=tk.LEFT, padx=5)

# --- Кнопки ---
button_frame = tk.Frame(root)
button_frame.pack(pady=10)

start_button = tk.Button(button_frame, text="Старт", command=start_audio)
start_button.pack(side=tk.LEFT, padx=10)

stop_button = tk.Button(button_frame, text="Стоп", command=stop_audio)
stop_button.pack(side=tk.LEFT, padx=10)

remove_button = tk.Button(root, text="Удалить выбранное", command=remove_selected)
remove_button.pack(pady=5)

# --- Кнопка выбора файла ---
select_button = tk.Button(root, text="Выбрать аудио", command=select_audio)
select_button.pack(pady=5)

# Запуск интерфейса
root.mainloop()
Я добавил два режима в постоянном временные отрезки переключение одинакового размера, а в промежуточном отрезки времени генерируются случайного времени минимального до максимального значения.

Ссылка на гитхаб -> GITHUB.
MakarovDs на форуме Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Реализация симуляции банкомата A7A7A7 Общие вопросы C/C++ 0 15.09.2023 23:48
Технологии симуляции жизни в играх Человек_Борща Свободное общение 6 22.11.2013 14:59
Создание большого 3D мира ardor Gamedev - cоздание игр: Unity, OpenGL, DirectX 4 02.03.2012 00:14
Создание катры мира (от Яндекса) с помощью Дельфи Alex Cones Общие вопросы Delphi 2 27.05.2009 09:16
Компьютерное моделирование. Создание модели движения тел по определенной траектории. AnaVare Помощь студентам 7 18.03.2009 05:09