Задать вопрос
Akigami
@Akigami
Технарь - аналитик

Какой выбрать язык и платформу под мою цель?

Привет ребят. Я хочу написать что то вроде колоды карт с 3d эффектами на андроид, визуально ближе всего по задумке обычные лаунчеры под андроид(их гриды + перелистывания и пр.). Я перебирала кучу вариантов и... Это мягко говоря какая то жесть. Андроид студию нужно настраивать неделю на всякие зависимости и пр. утрировано с его котлин. Ее вообще не предлагайте, он мне все нервы убил

Мне важно визуально накидывать объекты а не прописывать координатами как в киви на питоне. И еще важно что бы код был... Я не знаю как его описать, попробую и надеюсь вы поймете.

пример C# кода рандомный
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

// 1. Определение интерфейсов для паттерна "Наблюдатель"
// Интерфейс для наблюдателя (Observer)
public interface IObserver
{
    // Метод, вызываемый при обновлении данных
    void Update(object sender, DataChangedEventArgs args);
}

// Интерфейс для субъекта наблюдения (Subject)
public interface ISubject
{
    void RegisterObserver(IObserver observer);
    void RemoveObserver(IObserver observer);
    void NotifyObservers(DataChangedEventArgs args);
}

// Класс аргументов события (передача данных)
public class DataChangedEventArgs : EventArgs
{
    public DateTime Timestamp { get; }
    public double Value { get; }
    public string Description { get; }

    public DataChangedEventArgs(double value, string description)
    {
        Value = value;
        Description = description;
        Timestamp = DateTime.Now;
    }
}

// 2. Реализация Субъекта (Датчик данных)
public class DataSensor : ISubject
{
    // Использование коллекции для хранения подписчиков
    private readonly List<IObserver> _observers = new List<IObserver>();
    private Random _random = new Random();

    public void RegisterObserver(IObserver observer)
    {
        Console.WriteLine($"&#91;СЕНСОР&#93;: Наблюдатель {observer.GetType().Name} подписан.");
        _observers.Add(observer);
    }

    public void RemoveObserver(IObserver observer)
    {
        _observers.Remove(observer);
        Console.WriteLine($"&#91;СЕНСОР&#93;: Наблюдатель {observer.GetType().Name} отписан.");
    }

    public void NotifyObservers(DataChangedEventArgs args)
    {
        // Уведомляем всех подписчиков в цикле
        foreach (var observer in _observers)
        {
            observer.Update(this, args);
        }
    }

    // Асинхронный метод, имитирующий работу датчика
    public async Task StartMonitoringAsync(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            // Имитация получения новых данных
            double newValue = 20.0 + _random.NextDouble() * 10.0; 
            var args = new DataChangedEventArgs(newValue, "Новое значение температуры");
            
            Console.WriteLine($"\n&#91;СЕНСОР&#93;: Генерация новых данных: {newValue:F2}°C");
            NotifyObservers(args);

            // Ожидание перед следующим измерением (асинхронно, не блокирует поток UI/Main)
            await Task.Delay(2000, token);
        }
    }
}

// 3. Реализация конкретных Наблюдателей
public class ConsoleLogger : IObserver
{
    public void Update(object sender, DataChangedEventArgs args)
    {
        Console.WriteLine($"&#91;ЛОГГЕР&#93;: Время: {args.Timestamp:HH:mm:ss} | Получено значение: {args.Value:F2}°C");
    }
}

public class AlertSystem : IObserver
{
    private const double AlertThreshold = 28.0;

    public void Update(object sender, DataChangedEventArgs args)
    {
        if (args.Value > AlertThreshold)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine($"&#91;!!! СИГНАЛ !!!&#93;: ВНИМАНИЕ! Превышен порог {AlertThreshold}°C! Текущее значение: {args.Value:F2}°C");
            Console.ResetColor();
        }
    }
}

// 4. Основная программа для запуска
class Program
{
    static async Task Main(string&#91;&#93; args)
    {
        Console.WriteLine("--- Запуск Системы Мониторинга (Async Observer Pattern) ---");
        
        var sensor = new DataSensor();
        var logger = new ConsoleLogger();
        var alertSystem = new AlertSystem();

        // Подписка наблюдателей на события датчика
        sensor.RegisterObserver(logger);
        sensor.RegisterObserver(alertSystem);

        // Используем CancellationTokenSource для возможности отмены асинхронной задачи
        var cts = new CancellationTokenSource();
        
        try
        {
            // Запуск мониторинга в асинхронном режиме
            var monitoringTask = sensor.StartMonitoringAsync(cts.Token);
            
            Console.WriteLine("\nСистема работает. Нажмите любую клавишу для отмены и выхода.");
            Console.ReadKey(); // Блокируем Main поток, пока пользователь не нажмет клавишу

            // Отмена задачи мониторинга
            cts.Cancel();
            await monitoringTask; // Ожидаем завершения асинхронной задачи

        }
        catch (TaskCanceledException)
        {
            Console.WriteLine("\nЗадача мониторинга была отменена.");
        }
        finally
        {
            // Отписка перед выходом
            sensor.RemoveObserver(logger);
            sensor.RemoveObserver(alertSystem);
            Console.WriteLine("\n--- Работа системы завершена. ---");
        }
    }
}



qt рандомный
import QtQuick
import QtQuick.Window

Window {
    width: 400
    height: 600
    visible: true
    title: "3D Карта в Qt QML"

    property real rotY: 0
    property real rotX: 0
    property bool dragging: false

    Timer {
        interval: 16  // ~60fps
        running: !dragging
        repeat: true
        onTriggered: rotY += 1  // Авто-ротация по Y
    }

    MouseArea {
        anchors.fill: parent
        onPressed: { dragging = true; mouse.accepted = true }
        onReleased: dragging = false
        onPositionChanged: (mouse) => {
            if (dragging) {
                rotY += mouse.x - pmouse.x  // Горизонталь по Y
                rotX -= mouse.y - pmouse.y  // Вертикаль по X (инверт)
            }
        }
    }

    Rectangle {
        width: 250
        height: 350
        anchors.centerIn: parent
        color: "#007bff"
        radius: 20
        layer.enabled: true  // Для smooth

        Image {
            anchors.fill: parent
            source: "card.png"  // Кинь PNG карты в папку, или убери для цвета
            fillMode: Image.Stretch
        }

        Text {
            anchors.centerIn: parent
            text: "Твоя карта"
            color: "white"
            font.pixelSize: 28
        }

        transform: &#91;
            Rotation { origin.x: width/2; origin.y: height/2; axis { x: 0; y: 1; z: 0 }; angle: rotY },
            Rotation { origin.x: width/2; origin.y: height/2; axis { x: 1; y: 0; z: 0 }; angle: rotX },
            Rotation { origin.x: width/2; origin.y: height/2; axis { x: 0; y: 0; z: 1 }; angle: 45 }  // Фикс перспектива
        &#93;

        Rectangle {  // Тень для 3D-вида
            anchors.centerIn: parent
            width: parent.width; height: parent.height
            color: "black"
            opacity: 0.3
            radius: 20
            z: -1
            transform: Rotation { origin.x: width/2; origin.y: height/2; axis { x: 1; y: 0; z: 0 }; angle: 90 }
        }
    }
}


Да это qt а не ЯП. Я понимаю, но это просто пример что бы обьяснить. В С# идет куча всяких нагромождений... Я не знаю как это назвать. Параметров для функции что ли. Что бы написать что то простое из разряда "Привет qna.habr!" нужно создавать кучу всяких параметров функций, а так же в целом код какой то тяжелый для визуального восприятия.
В qt не нужно создавать кучу параметров что бы задать размеры обьекта и пр. ты просто пишешь ширина такая то и все. И + там как то все логично устроено что ли, я не знаю, но визуально он читается проще.
Повторюсь, я в курсе что qt это по сути оболочка для питона со своими приколами. Но здесь я просто показала что там код более лаконичный что ли. Я не знаю как это назвать.

И еще, я не матерый программист, а скорее дизайнер с навыками программирования. В основном писала на питоне, но тоже не сказать что я его прям хорошо знаю. Он мне знаком если что. Я это к тому, что я могу не понять если вы скажете что то замудреное

Для реализации моей задумки что подойдет ? посоветуйте. Я просто могу не знать других ЯП и пр. Есть всякие Nym, go и пр. может кто то что то пишет и подскажет. Пока приглядываюсь как раз к qt + питон
  • Вопрос задан
  • 66 просмотров
Подписаться 1 Простой 5 комментариев
Помогут разобраться в теме Все курсы
  • Нетология
    Android-разработчик с нуля
    14 месяцев
    Далее
  • Skillbox
    Разработчик игр на Unreal Engine 4 с нуля до Middle
    12 месяцев
    Далее
  • Яндекс Практикум
    Android-разработчик
    12 месяцев
    Далее
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы