vala
English
English
  • Учебник Vala
  • Основы
    • Элементы языка
      • Типы данных
      • Управляющие конструкции
      • Методы
      • Делегаты
      • Лямбды / Замыкания
      • Пространства имён
      • Структуры
      • Классы
    • ООП
      • Основы
      • Конструктор
      • Деструктор
      • Сигналы
      • Свойства(Properties)
      • Наследование
      • Абстрактные классы
      • Интерфейсы / Миксины
      • Полиморфизм
      • Сокрытие методов
      • Информация о типах времени выполнения(Run-Time Type Information)
      • Динамическое приведение типов(Dynamic Type Casting)
      • Универсальные шаблоны(Generics)
      • Создание объектов в стиле GObject
      • Интеграция с D-Bus
      • Профили(Другие бэкенды помимо GLib)
  • Продвинутые возможности
    • Ассерты и контрактное программирование
    • Обработка ошибок
    • Управление параметрами
    • Методы с поддержкой синтаксиса
    • Многопоточность
    • Главный цикл(The Main Loop)
    • Асинхронные методы(Coroutine)
    • Слабые ссылки(Weak References)
    • Список аргументов переменной длины
    • Указатели
    • Классы не наследующие Object
    • Коллекции
      • Введение
      • HashSet<G>
      • ArrayList<G>
      • HashMap<K,V>
      • Lock-free структуры
  • Экспериментальные фичи
    • Введение
    • Строгий не null режим(Rust mode)
    • Литералы регулярных выражений(regexp)
    • Цепочки связанных выражений
  • Использование и создание библиотек
    • Введение
    • Инструменты
    • Генерирование VAPI файла из предыдущего с помощью vapigen.
    • Использование библиотек
    • Создание библиотеки
    • Vala and C
    • Meson
      • Config file
      • Static Library
      • Shared Library
      • Target GLib Version
  • Технические приёмы
    • Unit тестирование
    • Отладка
    • Использование GLib
  • Продвинуты гайд(WIP)
  • Functional Programming
    • Gpseq
    • Compose
  • Examples
    • Basic
    • GTK
      • Базовые GTK программы
      • Flappy Bird(WIP)
      • DnD
    • Websocket
  • Apps
    • Games
  • Meson-Book
    • MesonBook
    • Wrap
    • Crosscompile
    • Object files
    • Library
    • Executable
    • Code Generation
    • Installing
    • Unit Tests
    • Meson 0.54
    • Meson 0.53
  • golang-book
    • Ваша первая программа
    • Типы
    • UPDATE.MD
Powered by GitBook
On this page

Was this helpful?

  1. Examples
  2. GTK

Flappy Bird(WIP)

PreviousБазовые GTK программыNextDnD

Last updated 5 years ago

Was this helpful?

Flappy GNOME - руководство по разработке игр с боковой прокруткой, использующее Vala и GTK +.

Финальным результатом урока является мини-игра в стиле Flappy Bird.

Шаги учебника должны быть простыми, каждый шаг должен быть одним коммитом с минимальным необходимым различием. Кроме того, код довольно хорошо прокомментирован, короток и организован, поэтому его должно быть легко читать. Я осознаю тот факт, что GTK + не является фреймворком для разработки игр, не предназначен для этой цели, однако для простых игр его поддержки должно быть достаточно.

1. Базовый интерфейс игры

  • главное окно

  • окно прокрутки для боковой прокрутки

  • игровая зона

  • стрелка игрока

  • метка оценки

  • изначально визуализированные трубы

2. Прокрутка анимации

  • на клавиатуре Space отпущена, запустить анимацию

  • анимация прокручивает игровую область

  • когда достигните конца полосы прокрутки, остановитесь

3. Бесконечная прокрутка

  • когда мы прокручиваем в крайнее левое положение, изменим размер игровой области и добавим новую трубу

4. Управление игроком и движение

  • игрок падает по умолчанию

  • игрок прыгает на кнопку Space отпущен

  • игра заканчивается, когда игрок падает на дно

5. Обнаружение столкновения

  • добавлен список с ограничительными рамками труб

  • удалите предметы, когда мы проходим

  • рассчитать ограничивающую рамку игрока

  • завершить игру при столкновении игрока с трубкой

6. Новая поддержка игры

  • добавлена ​​клавиша F2 для запуска новой игры

7. Стиль интерфейса

  • добавить стиль CSS

  • стиль трубы с градиентом

  • добавить статический пол, не прокручивать

  • использовать разные стили для верхней и нижней труб

  • переместить горизонтальную полосу прокрутки над игровой областью

  • переместить виджет счета из игровой зоны на этаж

  • использовать сигнал для обработки обновлений счета

8. Дальнейшие улучшения интерфейса

  • использовать общедоступные изображения SVG вместо стрелок

  • добавить кнопку перезагрузки для легкого перезапуска игры

const string SCORE_TEMPLATE = "Score: <b>%u</b>";

private static bool original = false;

private const GLib.OptionEntry[] options = {
    { "original", 0, 0, OptionArg.NONE, ref original, "Run with original icons", null },
    { null }
};

int main (string[] args) {
    try {
        var opt_context = new OptionContext ();
        opt_context.set_help_enabled (true);
        opt_context.add_main_entries (options, null);
        opt_context.parse (ref args);
    } catch (OptionError e) {
        warning ("error: %s\n", e.message);
        error ("Run '%s --help' to see a full list of available command line options.\n", args[0]);
        return 0;
    }

    Gtk.init (ref args);

    var css_provider = new Gtk.CssProvider ();                  // Initialize a CSS provider
    try {
        css_provider.load_from_resource ("/org/gtk/Flappy/flappy.css"); // from the css file in the current directory
    } catch (GLib.Error e) {
        warning ("Error loading css styles: %s", e.message);    // warn in case of an error
    }

    Gtk.StyleContext.add_provider_for_screen (                  // use the css provider
        Gdk.Screen.get_default (),                              // on the default screen
        css_provider,
        Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);

    var window = new Gtk.Window ();                             // Set up a window
    window.window_position = Gtk.WindowPosition.CENTER;         // centered on the screen
    window.title = "FlappyGnome";                               // proudly displaying the application name in the titlebar
    window.set_size_request (WIN_WIDTH, WIN_HEIGHT);            // with an appropriate size requested
    window.resizable = false;                                   // as we don't want to deal with dynamic resizing for now
    window.destroy.connect (Gtk.main_quit);                     // and quit the application when this window is closed

    var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);        // add a box representing the content area

    var scrolled_window = new Gtk.ScrolledWindow (null, null);  // Add a scrollable area
    scrolled_window.set_policy (Gtk.PolicyType.ALWAYS,          // always show the horizontal scrollbar
                                Gtk.PolicyType.NEVER);          // but never show the vertical one
    scrolled_window.expand = true;                              // use all available space for this component
    scrolled_window.set_placement (Gtk.CornerType.BOTTOM_LEFT); // move the scrollable content below the horizontal scrollbar

    var ground = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);   // static component without scrolling
    ground.set_size_request (WIN_WIDTH, GROUND_HEIGHT);         // with a fixed size
    ground.get_style_context ().add_class ("ground");           // used as the floor

    var restart_button = new Gtk.Button.from_icon_name (        // create a restart button
                                "view-refresh-symbolic",        // with a refresh icon
                                Gtk.IconSize.DND);              // with an image 32x32 px
    restart_button.set_size_request (64, 64);
    ground.pack_start (restart_button, false, false, 0);        // add the restart button to the bottom left corner
    restart_button.margin = 20;                                 // add a margin to avoid the restart button expanding to the window border
    restart_button.can_focus = false;                           // disable can_focus to avoid stealing space keypress after clicked

    var score_label = new Gtk.Label ("");                       // create a score widget
    ground.pack_end (score_label, false, false, 0);             // pack it in the bottom right corner
    score_label.margin = 20;                                    // add a margin to avoid the score label expanding to the window border

    box.add (scrolled_window);                                  // add the scrolled area to the content area
    box.add (ground);                                           // add the floor to the content area
    window.add (box);                                           // and add the content container to the main window

    var game_area = new GameArea (original);                    // Add the game area
    scrolled_window.add (game_area);                            // to the scrollable to support scrolling, as we are doing a side-scroller

    game_area.score_changed.connect ( (score) => {              // connect to the score changed signal
        score_label.set_markup (SCORE_TEMPLATE.printf (score)); // and update the score label on each change
    });

    restart_button.clicked.connect ((event) => {                // connect to the restart button clicked signal
        game_area.setup_new_game ();                            // to start a new game
    });
    game_area.setup_new_game ();                                // setup a new game
    window.show_all ();                                         // Show the window and each component withing

    Gtk.main ();                                                // Start the application
    return 0;
}