Графическое программирование на C с Allegro: возможности библиотеки
Для кого эта статья:
- начинающие разработчики игр и графических приложений
- студенты и энтузиасты, интересующиеся программированием на C
преподаватели и наставники, обучающие графическому программированию и разработке игр
Графическое программирование – вотчина энтузиастов, готовых погрузиться в мир пикселей, спрайтов и визуальных эффектов. Библиотека Allegro на C предлагает идеальный баланс между низкоуровневым контролем и доступностью для начинающих разработчиков. Это не просто инструмент – это входной билет в мир компьютерной графики без необходимости разбираться в сложных API вроде DirectX или OpenGL с первого дня. Allegro позволяет создавать от простых визуализаций до полноценных 2D игр с минимальными требованиями к оборудованию и максимальной кроссплатформенностью. 🎮
Погружаясь в мир графического программирования с Allegro, вы закладываете фундамент для более сложных проектов в будущем. Многие принципы работы с графикой универсальны и применимы в веб-разработке, особенно при создании интерактивных элементов и анимаций. Если вас интересует профессиональное применение этих навыков, Обучение веб-разработке от Skypro поможет трансформировать ваши знания в востребованную карьеру. Курс охватывает не только фронтенд-технологии, но и основы алгоритмов визуализации, которые вы начнёте осваивать с Allegro.
Основы Allegro: что это и почему стоит выбрать для графики в C
Allegro (Allegro Low LEvel Game ROutines) – это кроссплатформенная библиотека, ориентированная на разработку игр и мультимедийных приложений на языке C. Впервые выпущенная в 1990-х годах, она прошла долгий путь эволюции и сегодня предлагает широкий набор функций для работы с графикой, звуком, пользовательским вводом и даже сетевыми возможностями.
Ключевое преимущество Allegro перед другими графическими библиотеками – баланс между мощностью и простотой освоения. В отличие от низкоуровневых API, Allegro абстрагирует многие сложные аспекты графического программирования, позволяя сосредоточиться на логике приложения.
Андрей Северов, преподаватель курса "Разработка игр на C"
Моё знакомство с Allegro произошло на третьем курсе университета, когда перед нашей группой поставили задачу разработать 2D-платформер за месяц. Большинство студентов выбрали SDL или SFML, но я решил попробовать Allegro по рекомендации старшекурсника. Первое, что меня приятно удивило – скорость развёртывания проекта. Пока однокурсники боролись с настройкой SDL, я уже имел рабочее окно с движущимся спрайтом.
Ключевым моментом стала работа с коллизиями – в Allegro есть встроенные примитивы для обработки пересечений, что сэкономило мне около недели работы. В итоге мой проект не только получил высший балл, но и был единственным, где удалось реализовать все запланированные механики, включая систему частиц для визуальных эффектов.
Почему стоит выбрать именно Allegro для изучения графики в C? Рассмотрим основные преимущества:
- Низкий порог входа – даже с базовыми знаниями C можно создать простое графическое приложение за несколько десятков строк кода
- Кроссплатформенность – код работает на Windows, Linux, macOS, Android и iOS с минимальными изменениями
- Комплексность решения – помимо графики, библиотека предоставляет инструменты для работы со звуком, шрифтами, пользовательским вводом
- Активное сообщество – множество обучающих материалов, готовых примеров и форумов, где можно получить помощь
- Производительность – несмотря на относительную простоту, Allegro обеспечивает высокую скорость работы даже на слабом оборудовании
| Характеристика | Allegro | SDL | SFML | OpenGL (чистый) |
|---|---|---|---|---|
| Язык программирования | C | C | C++ | C/C++ |
| Сложность освоения | Низкая | Средняя | Низкая | Высокая |
| Встроенная физика | Базовая | Нет | Нет | Нет |
| Работа с аудио | Да | Да | Да | Нет |
| Объём документации | Средний | Большой | Большой | Огромный |
Allegro 5 (текущая версия) значительно модернизирована по сравнению с предыдущими версиями. Она использует объектно-ориентированный подход, даже будучи C-библиотекой, что делает код более структурированным и понятным.

Установка и настройка Allegro для разных операционных систем
Установка Allegro может показаться сложной задачей, особенно новичкам, но следуя пошаговым инструкциям, вы быстро настроите рабочую среду. Рассмотрим процесс для основных операционных систем. 🔧
Установка на Windows
Для Windows рекомендую использовать менеджер пакетов MSYS2 или предкомпилированные бинарные файлы:
Через MSYS2:
- Установите MSYS2 с официального сайта (msys2.org)
- Откройте MSYS2 Shell и выполните:
pacman -S mingw-w64-x86_64-allegro - Настройте переменную PATH для включения путей к библиотекам MSYS2
Через предкомпилированные файлы:
- Скачайте бинарные файлы для вашей версии компилятора с официального сайта
- Распакуйте архив и скопируйте файлы в директории вашего проекта
- Настройте компилятор для использования заголовочных файлов и библиотек Allegro
Пример настройки в Code::Blocks:
- Откройте настройки проекта (Project > Build options)
- В разделе Search directories > Compiler добавьте путь к заголовочным файлам (например,
C:\allegro\include) - В разделе Search directories > Linker добавьте путь к библиотекам (например,
C:\allegro\lib) - В разделе Linker settings добавьте библиотеки:
allegro-5.0.10-monolith-mt.lib
Установка на Linux
На Linux установка проще благодаря менеджерам пакетов:
Для Ubuntu/Debian:
sudo apt-get update
sudo apt-get install liballegro5-dev
Для Fedora:
sudo dnf install allegro5-devel
Для Arch Linux:
sudo pacman -S allegro
Установка на macOS
Через Homebrew:
brew update
brew install allegro
Михаил Овчинников, разработчик игровых движков
Помню свой первый опыт установки Allegro на Windows – это был настоящий квест. Я работал над учебным проектом визуализации сортировок для студентов первого курса. Сначала я попытался использовать предкомпилированные библиотеки, но столкнулся с несовместимостью версий компилятора.
После нескольких часов мучений я нашёл решение – MSYS2 с MinGW. Установка заняла буквально 15 минут, включая настройку PATH. Ключевым моментом было понимание, что разные версии библиотеки требуют разных флагов компиляции.
Когда я наконец увидел запустившееся окно с цветными прямоугольниками, представляющими элементы массива, это был момент настоящего триумфа. Теперь при обучении студентов я всегда начинаю с настройки окружения, чтобы они могли сосредоточиться на алгоритмах, а не на технических сложностях.
После установки проверьте, что библиотека работает корректно, скомпилировав простую программу:
#include <allegro5/allegro.h>
#include <stdio.h>
int main() {
if (!al_init()) {
fprintf(stderr, "Не удалось инициализировать Allegro.\n");
return -1;
}
printf("Allegro успешно инициализирована! Версия: %s\n", ALLEGRO_VERSION_STR);
return 0;
}
| Операционная система | Команда компиляции | Типичные проблемы | Решение |
|---|---|---|---|
| Windows (MinGW) | gcc -Wall -o test test.c $(pkg-config --cflags --libs allegro-5) | Ошибка "не найден pkg-config" | Установить pkg-config через MSYS2 |
| Windows (MSVC) | cl test.c /I"path\to\allegro\include" /link "path\to\allegro\lib\allegro-5.0.10-monolith-mt.lib" | Ошибки линковки | Проверить соответствие версии библиотеки и компилятора |
| Linux | gcc -Wall -o test test.c $(pkg-config --cflags --libs allegro-5) | Ошибка "allegro-5.pc not found" | Установить dev-пакеты Allegro |
| macOS | gcc -Wall -o test test.c $(pkg-config --cflags --libs allegro-5) | Ошибки с фреймворками | Добавить флаг -framework Cocoa |
Первый графический проект: создаём окно и рисуем примитивы
Создание первого графического приложения с Allegro – захватывающий момент. Начнем с самого базового – открытия окна и отрисовки простых геометрических фигур. 🖼️
Прежде всего, необходимо инициализировать основные компоненты Allegro. Вот минимальный скелет программы:
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <stdio.h>
int main() {
// Инициализация Allegro
if (!al_init()) {
fprintf(stderr, "Не удалось инициализировать Allegro.\n");
return -1;
}
// Инициализация модуля примитивов
if (!al_init_primitives_addon()) {
fprintf(stderr, "Не удалось инициализировать модуль примитивов.\n");
return -1;
}
// Создание дисплея
ALLEGRO_DISPLAY *display = al_create_display(800, 600);
if (!display) {
fprintf(stderr, "Не удалось создать дисплей.\n");
return -1;
}
// Устанавливаем заголовок окна
al_set_window_title(display, "Мое первое приложение Allegro");
// Очистка экрана (заливка черным цветом)
al_clear_to_color(al_map_rgb(0, 0, 0));
// Здесь будет наш код для рисования
// Обновление экрана
al_flip_display();
// Ждем 5 секунд
al_rest(5.0);
// Освобождение ресурсов
al_destroy_display(display);
return 0;
}
Теперь добавим рисование различных примитивов. Замените комментарий "Здесь будет наш код для рисования" следующим кодом:
// Рисуем линию (красную)
al_draw_line(100, 100, 300, 100, al_map_rgb(255, 0, 0), 2.0);
// Рисуем прямоугольник (зеленый)
al_draw_rectangle(100, 150, 300, 250, al_map_rgb(0, 255, 0), 2.0);
// Рисуем заполненный прямоугольник (синий)
al_draw_filled_rectangle(350, 150, 550, 250, al_map_rgb(0, 0, 255));
// Рисуем круг (желтый)
al_draw_circle(200, 350, 50, al_map_rgb(255, 255, 0), 2.0);
// Рисуем заполненный круг (пурпурный)
al_draw_filled_circle(450, 350, 50, al_map_rgb(255, 0, 255));
// Рисуем эллипс (бирюзовый)
al_draw_ellipse(200, 450, 75, 30, al_map_rgb(0, 255, 255), 2.0);
// Рисуем треугольник (белый)
al_draw_triangle(450, 400, 400, 500, 500, 500, al_map_rgb(255, 255, 255), 2.0);
Для компиляции этой программы используйте команду:
На Linux/macOS:
gcc -Wall -o first_app first_app.c $(pkg-config --cflags --libs allegro-5 allegro_primitives-5)
На Windows с MinGW:
gcc -Wall -o first_app.exe first_app.c -lallegro-5.0.10-monolith-mt
Давайте расширим наш пример, добавив обработку событий, чтобы программа закрывалась при нажатии на кнопку закрытия окна или клавишу Escape:
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <stdio.h>
int main() {
// Инициализация компонентов
if (!al_init()) {
fprintf(stderr, "Не удалось инициализировать Allegro.\n");
return -1;
}
if (!al_install_keyboard()) {
fprintf(stderr, "Не удалось инициализировать клавиатуру.\n");
return -1;
}
if (!al_init_primitives_addon()) {
fprintf(stderr, "Не удалось инициализировать модуль примитивов.\n");
return -1;
}
// Создание очереди событий
ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
if (!event_queue) {
fprintf(stderr, "Не удалось создать очередь событий.\n");
return -1;
}
// Создание дисплея
ALLEGRO_DISPLAY *display = al_create_display(800, 600);
if (!display) {
fprintf(stderr, "Не удалось создать дисплей.\n");
al_destroy_event_queue(event_queue);
return -1;
}
// Регистрация источников событий
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_keyboard_event_source());
// Основной цикл
bool done = false;
while (!done) {
// Очистка экрана
al_clear_to_color(al_map_rgb(0, 0, 0));
// Рисование примитивов
al_draw_line(100, 100, 300, 100, al_map_rgb(255, 0, 0), 2.0);
al_draw_rectangle(100, 150, 300, 250, al_map_rgb(0, 255, 0), 2.0);
al_draw_filled_rectangle(350, 150, 550, 250, al_map_rgb(0, 0, 255));
al_draw_circle(200, 350, 50, al_map_rgb(255, 255, 0), 2.0);
al_draw_filled_circle(450, 350, 50, al_map_rgb(255, 0, 255));
al_draw_ellipse(200, 450, 75, 30, al_map_rgb(0, 255, 255), 2.0);
al_draw_triangle(450, 400, 400, 500, 500, 500, al_map_rgb(255, 255, 255), 2.0);
// Отображение на экран
al_flip_display();
// Обработка событий
ALLEGRO_EVENT ev;
while (al_get_next_event(event_queue, &ev)) {
if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE ||
(ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE)) {
done = true;
}
}
}
// Освобождение ресурсов
al_destroy_display(display);
al_destroy_event_queue(event_queue);
return 0;
}
Этот код создаёт интерактивное окно с нарисованными примитивами, которое реагирует на пользовательский ввод. Для расширения функционала можно использовать дополнительные возможности библиотеки:
- Трансформации – поворот, масштабирование и перемещение объектов с помощью матричных преобразований
- Градиенты – создание плавных переходов между цветами
- Альфа-канал – добавление прозрачности к объектам
- Сглаживание – улучшение визуального качества линий и кривых
Пример использования трансформаций:
// Сохраняем текущую трансформацию
ALLEGRO_TRANSFORM transform;
al_identity_transform(&transform);
// Смещаем координаты
al_translate_transform(&transform, 100, 100);
// Вращаем на 45 градусов
al_rotate_transform(&transform, ALLEGRO_PI / 4);
// Масштабируем в 1.5 раза
al_scale_transform(&transform, 1.5, 1.5);
// Применяем трансформацию
al_use_transform(&transform);
// Рисуем прямоугольник, который будет повёрнут, увеличен и смещён
al_draw_rectangle(0, 0, 100, 100, al_map_rgb(255, 255, 0), 2.0);
// Возвращаем исходную трансформацию
al_identity_transform(&transform);
al_use_transform(&transform);
Продвинутая работа с графикой: спрайты, анимации и эффекты
Переходя от базовых примитивов к более сложной графике, мы погружаемся в мир спрайтов, анимаций и визуальных эффектов. Это тот уровень, где ваши приложения начинают выглядеть по-настоящему профессионально. 🚀
Для работы со спрайтами в Allegro используется структура ALLEGRO_BITMAP. Вот основные операции:
Загрузка изображения из файла:
// Инициализация аддона для работы с изображениями
if (!al_init_image_addon()) {
fprintf(stderr, "Не удалось инициализировать аддон изображений.\n");
return -1;
}
// Загрузка спрайта
ALLEGRO_BITMAP *sprite = al_load_bitmap("sprite.png");
if (!sprite) {
fprintf(stderr, "Не удалось загрузить изображение.\n");
return -1;
}
Отрисовка спрайта:
// Простая отрисовка
al_draw_bitmap(sprite, x, y, 0);
// Отрисовка с флагами (отражение, поворот)
al_draw_bitmap(sprite, x, y, ALLEGRO_FLIP_HORIZONTAL);
// Отрисовка с масштабированием
al_draw_scaled_bitmap(sprite,
0, 0, al_get_bitmap_width(sprite), al_get_bitmap_height(sprite), // исходный прямоугольник
x, y, width, height, // целевой прямоугольник
0); // флаги
// Отрисовка с поворотом и масштабированием
al_draw_rotated_bitmap(sprite,
center_x, center_y, // центр вращения относительно спрайта
dest_x, dest_y, // позиция
angle, // угол в радианах
0); // флаги
Создание анимаций требует использования спрайтовых листов (sprite sheets) – изображений, содержащих несколько кадров анимации. Рассмотрим, как реализовать простую анимацию:
// Структура для хранения информации об анимации
typedef struct {
ALLEGRO_BITMAP *spritesheet;
int frame_width;
int frame_height;
int frame_count;
float fps;
float current_frame;
} Animation;
// Инициализация анимации
void init_animation(Animation *anim, const char *filename, int frame_width, int frame_height, int frame_count, float fps) {
anim->spritesheet = al_load_bitmap(filename);
anim->frame_width = frame_width;
anim->frame_height = frame_height;
anim->frame_count = frame_count;
anim->fps = fps;
anim->current_frame = 0.0f;
}
// Обновление анимации
void update_animation(Animation *anim, float dt) {
anim->current_frame += anim->fps * dt;
if (anim->current_frame >= anim->frame_count) {
anim->current_frame = 0.0f;
}
}
// Отрисовка текущего кадра анимации
void draw_animation(Animation *anim, float x, float y, int flags) {
int current_frame = (int)anim->current_frame;
int row = current_frame / (al_get_bitmap_width(anim->spritesheet) / anim->frame_width);
int col = current_frame % (al_get_bitmap_width(anim->spritesheet) / anim->frame_width);
al_draw_bitmap_region(anim->spritesheet,
col * anim->frame_width, row * anim->frame_height,
anim->frame_width, anim->frame_height,
x, y,
flags);
}
Для использования этой системы анимации в основном коде:
// Создаём таймер для управления временем
ALLEGRO_TIMER *timer = al_create_timer(1.0 / 60.0); // 60 FPS
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_start_timer(timer);
// Инициализируем анимацию
Animation player_anim;
init_animation(&player_anim, "player_run.png", 64, 64, 8, 10.0f); // 10 кадров в секунду
float x = 400, y = 300;
bool redraw = true;
// Основной игровой цикл
while (!done) {
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if (ev.type == ALLEGRO_EVENT_TIMER) {
// Обновляем анимацию
update_animation(&player_anim, 1.0f / 60.0f);
redraw = true;
}
else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
done = true;
}
if (redraw && al_is_event_queue_empty(event_queue)) {
redraw = false;
al_clear_to_color(al_map_rgb(0, 0, 0));
// Отрисовываем текущий кадр анимации
draw_animation(&player_anim, x, y, 0);
al_flip_display();
}
}
| Визуальный эффект | Функция Allegro | Пример использования |
|---|---|---|
| Прозрачность | al_draw_tinted_bitmap | al_draw_tinted_bitmap(bitmap, al_map_rgba(255, 255, 255, 128), x, y, 0); |
| Тонирование (изменение цвета) | al_draw_tinted_bitmap | al_draw_tinted_bitmap(bitmap, al_map_rgb(255, 0, 0), x, y, 0); |
| Размытие | Пользовательский шейдер | Требует использования GLSL шейдеров через al_use_shader |
| Система частиц | Пользовательская реализация | Использование массива частиц и их отрисовка через al_draw_bitmap |
| Параллакс-эффект | Многослойная отрисовка | Отрисовка нескольких слоёв фона с разной скоростью движения |
Чтобы создавать продвинутые эффекты, часто используют буферизацию – рисование сначала в отдельный битмап, а затем применение к нему различных трансформаций перед выводом на экран:
// Создаём буфер для рендеринга
ALLEGRO_BITMAP *buffer = al_create_bitmap(800, 600);
// Переключаемся на рисование в буфер
al_set_target_bitmap(buffer);
// Выполняем рисование в буфер
al_clear_to_color(al_map_rgba(0, 0, 0, 0));
al_draw_bitmap(sprite, x, y, 0);
// Возвращаемся к рисованию на экран
al_set_target_backbuffer(display);
// Отрисовываем буфер с эффектом
al_draw_tinted_bitmap(buffer, al_map_rgba(255, 255, 255, 128), 0, 0, 0);
// После использования буфер следует уничтожить
al_destroy_bitmap(buffer);
Практический проект: разработка простой игры с Allegro на C
Теперь, когда мы освоили основные концепции Allegro, пришло время объединить полученные знания в практическом проекте – простой аркадной игре. Мы создадим базовую игру в жанре "избегай препятствий", где игрок управляет персонажем, уклоняясь от падающих объектов. 🎮
Начнем с определения структур данных для нашей игры:
// Структура игрока
typedef struct {
float x, y;
float speed;
int width, height;
int lives;
ALLEGRO_BITMAP *sprite;
} Player;
// Структура препятствия
typedef struct {
float x, y;
float speed;
int width, height;
bool active;
ALLEGRO_BITMAP *sprite;
} Obstacle;
// Глобальные параметры игры
#define MAX_OBSTACLES 20
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
Теперь основной код игры:
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
// Объявление структур (как выше)
// Инициализация игрока
void init_player(Player *player, ALLEGRO_BITMAP *sprite) {
player->x = SCREEN_WIDTH / 2;
player->y = SCREEN_HEIGHT – 50;
player->speed = 5.0;
player->width = 40;
player->height = 40;
player->lives = 3;
player->sprite = sprite;
}
// Инициализация препятствий
void init_obstacles(Obstacle obstacles[], int count) {
for (int i = 0; i < count; i++) {
obstacles[i].active = false;
obstacles[i].width = 30;
obstacles[i].height = 30;
}
}
// Создание нового препятствия
void spawn_obstacle(Obstacle obstacles[], int count, ALLEGRO_BITMAP *sprite) {
for (int i = 0; i < count; i++) {
if (!obstacles[i].active) {
obstacles[i].active = true;
obstacles[i].x = rand() % (SCREEN_WIDTH – obstacles[i].width);
obstacles[i].y = -obstacles[i].height;
obstacles[i].speed = 2.0 + ((float)rand() / RAND_MAX) * 3.0; // Скорость от 2 до 5
obstacles[i].sprite = sprite;
break;
}
}
}
// Обновление состояния препятствий
void update_obstacles(Obstacle obstacles[], int count) {
for (int i = 0; i < count; i++) {
if (obstacles[i].active) {
obstacles[i].y += obstacles[i].speed;
// Если препятствие вышло за пределы экрана
if (obstacles[i].y > SCREEN_HEIGHT) {
obstacles[i].active = false;
}
}
}
}
// Проверка столкновений
bool check_collision(Player *player, Obstacle *obstacle) {
if (!obstacle->active) return false;
// Простая проверка пересечения прямоугольников
return (player->x < obstacle->x + obstacle->width &&
player->x + player->width > obstacle->x &&
player->y < obstacle->y + obstacle->height &&
player->y + player->height > obstacle->y);
}
int main() {
// Инициализация компонентов Allegro
al_init();
al_install_keyboard();
al_init_image_addon();
al_init_primitives_addon();
al_init_font_addon();
al_init_ttf_addon();
// Инициализация генератора случайных чисел
srand(time(NULL));
// Создание дисплея и очереди событий
ALLEGRO_DISPLAY *display = al_create_display(SCREEN_WIDTH, SCREEN_HEIGHT);
ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
ALLEGRO_TIMER *timer = al_create_timer(1.0 / 60.0); // 60 FPS
// Загрузка ресурсов
ALLEGRO_BITMAP *player_sprite = al_load_bitmap("player.png");
ALLEGRO_BITMAP *obstacle_sprite = al_load_bitmap("obstacle.png");
ALLEGRO_FONT *font = al_load_ttf_font("arial.ttf", 24, 0);
// Создание заглушек, если спрайты не загрузились
if (!player_sprite) {
player_sprite = al_create_bitmap(40, 40);
al_set_target_bitmap(player_sprite);
al_clear_to_color(al_map_rgb(0, 255, 0));
al_set_target_backbuffer(display);
}
if (!obstacle_sprite) {
obstacle_sprite = al_create_bitmap(30, 30);
al_set_target_bitmap(obstacle_sprite);
al_clear_to_color(al_map_rgb(255, 0, 0));
al_set_target_backbuffer(display);
}
// Инициализация игровых объектов
Player player;
Obstacle obstacles[MAX_OBSTACLES];
init_player(&player, player_sprite);
init_obstacles(obstacles, MAX_OBSTACLES);
// Регистрация источников событий
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_start_timer(timer);
// Игровые переменные
bool done = false;
bool redraw = true;
bool keys[ALLEGRO_KEY_MAX] = {0};
int score = 0;
int frame_counter = 0;
// Основной игровой цикл
while (!done && player.lives > 0) {
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if (ev.type == ALLEGRO_EVENT_TIMER) {
// Обновление логики игры
if (keys[ALLEGRO_KEY_LEFT] && player.x > 0) {
player.x -= player.speed;
}
if (keys[ALLEGRO_KEY_RIGHT] && player.x < SCREEN_WIDTH – player.width) {
player.x += player.speed;
}
// Создание нового препятствия каждые 45 кадров (примерно каждые 0.75 секунды)
frame_counter++;
if (frame_counter >= 45) {
spawn_obstacle(obstacles, MAX_OBSTACLES, obstacle_sprite);
frame_counter = 0;
score++; // Увеличиваем счет за каждое новое препятствие
}
// Обновление препятствий
update_obstacles(obstacles, MAX_OBSTACLES);
// Проверка столкновений
for (int i = 0; i < MAX_OBSTACLES; i++) {
if (check_collision(&player, &obstacles[i])) {
player.lives--;
obstacles[i].active = false;
// Можно добавить звуковой эффект или анимацию столкновения
}
}
redraw = true;
}
else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {
keys[ev.keyboard.keycode] = true;
if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
done = true;
}
}
else if (ev.type == ALLEGRO_EVENT_KEY_UP) {
keys[ev.keyboard.keycode] = false;
}
else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
done = true;
}
if (redraw && al_is_event_queue_empty(event_queue)) {
redraw = false;
// Очистка экрана
al_clear_to_color(al_map_rgb(0, 0, 0));
// Отрисовка игрока
al_draw_bitmap(player.sprite, player.x, player.y, 0);
// Отрисовка препятствий
for (int i = 0; i < MAX_OBSTACLES; i++) {
if (obstacles[i].active) {
al_draw_bitmap(obstacles[i].sprite, obstacles[i].x, obstacles[i].y, 0);
}
}
// Отображение счета и жизней
al_draw_textf(font, al_map_rgb(255, 255, 255), 10, 10, 0, "Счет: %d", score);
al_draw_textf(font, al_map_rgb(255, 255, 255), SCREEN_WIDTH – 150, 10, 0, "Жизни: %d", player.lives);
al_flip_display();
}
}
// Показываем экран "Игра окончена"
al_clear_to_color(al_map_rgb(0, 0, 0));
al_draw_textf(font, al_map_rgb(255, 255, 255), SCREEN_WIDTH / 2 – 100, SCREEN_HEIGHT / 2 – 24, 0, "Игра окончена");
al_draw_textf(font, al_map_rgb(255, 255, 255), SCREEN_WIDTH / 2 – 100, SCREEN_HEIGHT / 2 + 24, 0, "Ваш счет: %d", score);
al_flip_display();
al_rest(3.0); // Ждем 3 секунды перед закрытием
// Освобождение ресурсов
al_destroy_bitmap(player_sprite);
al_destroy_bitmap(obstacle_sprite);
al_destroy_font(font);
al_destroy_timer(timer);
al_destroy_display(display);
al_destroy_event_queue(event_queue);
return 0;
}
Этот код создает полноценную игру с механикой уклонения от падающих препятствий. Для улучшения игры можно добавить следующие элементы:
- Звуковые эффекты – с использованием
al_init_audio_addon()иal_init_acodec_addon() - Меню и разные уровни сложности – с постепенным увеличением скорости и частоты препятствий
- Бонусы и способности – временная неуязвимость, замедление времени и т.д.
- Сохранение рекордов – запись лучших результатов в файл
- Визуальные эффекты – взрывы при столкновении, частицы, фоновые эффекты
Для компиляции этой игры используйте команду:
gcc -Wall -o dodge_game dodge_game.c $(pkg-config --cflags --libs allegro-5 allegro_image-5 allegro_primitives-5 allegro_font-5 allegro_ttf-5)
Структура игры демонстрирует основные принципы игровой разработки:
- Игровой цикл – обработка ввода, обновление состояния, отрисовка
- Управление ресурсами – загрузка и освобождение спрайтов и других ресурсов
- Обработка столкновений – определение пересечений между игровыми объектами
- Управление состоянием игры – отслеживание жизней, счета и условий завершения
Этот практический проект охватывает большинство базовых концепций разработки игр и может служить отправной точкой для более сложных проектов с использованием Allegro и C.
Использование Allegro для графики на C открывает путь к созданию эффективных и увлекательных визуальных приложений. От простых программ до полноценных игр – эта библиотека предлагает все необходимые инструменты при сохранении низкого порога входа. Освоив принципы работы с Allegro, вы приобретаете фундаментальные навыки графического программирования, которые легко переносятся на другие технологии и платформы. Начните с малого, экспериментируйте и постепенно усложняйте свои проекты – именно так растут настоящие разработчики игр и графических приложений.
Читайте также
- Обработка изображений в C: оптимизация и примеры использования
- SDL-библиотека для графического программирования на C – что это такое
- Как установить graphics.h: настройка библиотеки в разных ОС
- Графика в C: освоение примитивов для создания визуальных приложений
- Рисование прямоугольников в C: библиотеки, функции и алгоритмы
- Библиотека graphics.h: полное руководство для C/C++ разработчиков
- Графические библиотеки C: выбор инструментов для 2D и 3D разработки
- Библиотека graphics.h в C/C++: 15 примеров от новичка до профи
- Настройка графики на C: OpenGL, GLFW, SDL2 для новичков
- Построение графиков функций в C: лучшие библиотеки и примеры