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

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

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 15.09.2014, 09:34   #1
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
Восклицание Инструкция по созданию заготовки для 2D игр (для начинающих)

Привет!

Для заготовки нам понадобится Qt (только для окна, функции обработки клавиш и таймера). OpenGL - только для рисования квадрата c помощью функции Rect( x1, y1, y2, y2 ). Остальное - это стандартный C++ и полная свобода творчества!

Заготовка представляет из себя медленно падающий квадрат, который мы можем перемещать влево и вправо с помощью стрелок.

Сначала представлю заготовку, потом инструкцию по её созданию, потом краткие объяснения основных моментов (объяснения я буду дополнять и переписывать по мере наличия свободного времени).

Примечание:
- актуальные изменения будут здесь: http://www.gamedev.ru/code/forum/?id=193241
- и здесь: http://www.prog.org.ru/topic_27605_0.html

Код заготовки (обратите внимание на то, какая заготовка маленькая и как много она уже умеет!)

Scene.h
Код:
#ifndef SCENE_H
#define SCENE_H

#include <QGLWidget>
#include <QTimer>
#include <QKeyEvent>

class Scene : public QGLWidget
{
    Q_OBJECT

public:
    Scene( QWidget *parent = 0 );

private slots:
    void slotMove();

private:
    void initializeGL();
    void paintGL();
    void resizeGL( int w, int h );

    void keyPressEvent( QKeyEvent * event );

private:
    // Square position and size
    int x;
    int y;
    const int rsize;

    // Step size in x and y directions
    // (number of pixels to move each time)
    int xstep;
    int ystep;

    // Keep track of windows changing width and height
    GLfloat windowWidth;
    GLfloat windowHeight;

    // Timer
    QTimer *timer;
};

#endif // SCENE_H
Scene.cpp
Код:

#include "Scene.h"

Scene::Scene( QWidget *parent ) :
    QGLWidget( parent ),
    x( 0 ),
    y( 100 ),
    rsize( 25 ),
    xstep( 25 ),
    ystep( 1 )
{
    timer = new QTimer( this );
    connect( timer, SIGNAL( timeout() ),
             this, SLOT( slotMove() ) );
    timer->start( 33 );

    this->setFocusPolicy( Qt::StrongFocus );
}

void Scene::slotMove()
{
    y -= ystep;

    updateGL();
}

void Scene::initializeGL()
{
    glClearColor( 0.8f, 0.8f, 0.6f, 1.0f );
}

void Scene::paintGL()
{
    // Clear the window with current clearing color
    glClear( GL_COLOR_BUFFER_BIT );

    // Set current drawing color
    glColor3f( 0.0f, 0.5f, 0.5f );

    // Draw a filled rectangle with current color
    glRectf( x, y, x + rsize, y - rsize );
}

void Scene::resizeGL( int w, int h )
{
    // Prevent a divide by zero
    if ( h == 0 ) {
        h = 1;
    }

    // Set Viewport to window dimensions
    glViewport( 0, 0, w, h );

    // Reset coordinate system
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    // Establish clipping volume (left, right, bottom, top, near, far)
    GLfloat aspectRatio = ( GLfloat ) w / ( GLfloat ) h;

    if ( w <= h ) {
        windowWidth = 100.0f;
        windowHeight = 100.0f / aspectRatio;
        glOrtho( -100.0, 100.0, -windowHeight, windowHeight,
                 1.0, -1.0 );
    } else {
        windowWidth = 100.0 * aspectRatio;
        windowHeight = 100.0;
        glOrtho( -windowWidth, windowWidth, -100.0, 100.0,
                 1.0, -1.0 );
    }

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
}

void Scene::keyPressEvent( QKeyEvent *event )
{
    switch( event->key() ) {
    case Qt::Key_Left:
        x -= xstep;
        break;
    case Qt::Key_Right:
        x += xstep;
        break;
    }
}
Инструкция по созданию заготовки
- Установка Qt
- Переключение Qt Creator'a на английский
- Создание нового проекта
- Скопируем код заготовки в Scene.h и Scene.cpp
- Запускаем приложение. Мы видим падающий вниз квадрат, который мы можем перемещать влево и вправо

Последний раз редактировалось 8Observer8; 15.09.2014 в 09:47.
8Observer8 вне форума Ответить с цитированием
Старый 15.09.2014, 09:35   #2
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Краткие объяснения основных моментов

Примечание. Начало координат находится в середине окна.

- paintGL() - выполняется автоматически, когда приложению надо перерисовать окно. К примеру, если мы свернём окно и развернём, то тело этой функции выполнится. Или если перекроем наше окно каким-то другим. Или изменим размер нашего окна. В этой функции мы рисуем квадрат с помощью такой функции:

Код:
glRectf( x, y, x + rsize, y - rsize );
Здесь:
x - глобальная переменная, которая хранит x-координату левого верхнего угла прямоугольника
y - глобальная переменная, которая хранит y-координату левого верхнего угла прямоугольника
rsize - глобальная константа, которая хранит размер стороны квадрата
(x + rsize) - x-координата правого нижнего угла квадрата
(y - rsize) - y-координата правого нижнего угла квадрата

- slotMove() - выполняется примерно 30 раз в секунду. Главное, чтобы было больше, чем 24 кадра в секунду. В этой функции мы меняем координаты квадрата (глобальные переменные x и y) и вызываем updateGL(), чтобы спровоцировать вызов paintGL() и тем самым перерисовать квадрат с новыми координатами

- keyPressEvent - вызывается при нажатии любой клавиши. В заготовке мы используем только стрелки: "влево" и "вправо". При нажатии кнопки "влево" нам надо уменьшить координату x, а если переместить вправо, то увеличить y

- "Почему падает кубик?" Потому что каждые "30 раз в секунду" вызывается функция slotMove() и уменьшаетглобальную переменную y, которая хранит y-координату нашего квадрата

- windowWidth и windowHeight - глобальные переменные, которые хранят актуальные размеры клиентской области (области, в которой мы рисуем)

- glClearColor( 0.3f, 0.3f, 1.0f, 1.0f ) - с помощью этой функции мы задаём цвет фона. Первые три параметра - это соответственно: красный, зелёный, синий. Их можно менять в диапазоне [0.0, 1.0]. Четвёрный параметр нам не нужен, поэтому мы его выставляем в значение поумолчанию - в единицу.

- glColor3f( 0.0f, 0.5f, 0.5f ); - с помощью этой функции мы задаём цвет нашего квадрата. Здесь так же: красный, зелёный, синий

- resizeGL() - не обращайте внимания на содержимое этой функции. Просто не трогайте её.

P.S. Это информации достаточно, чтобы написать свой тетрис. Если что-то непонятно, то сначала поищите с помощью google.com, а потом пишите свои вопросы в комментариях

Последний раз редактировалось 8Observer8; 16.09.2014 в 07:51.
8Observer8 вне форума Ответить с цитированием
Старый 15.10.2014, 10:40   #3
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Изменил название инструкции. Рекомендую читать в таком порядке:

- Инструкция с нуля. Первый шаг в OpenGL на Qt для начинающих

- Примеры из SuperBible (3-го издания) на Qt

Последний раз редактировалось 8Observer8; 16.10.2014 в 08:29.
8Observer8 вне форума Ответить с цитированием
Старый 16.10.2014, 08:45   #4
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Цитата:
начинающим на C++ вообще рано OpenGL и Qt смотреть
С "начинающими" я оговорился. Надо было сказать "знающие основы". В книге SuperBible используется Си и Glut. Для примеров из книги - от Qt нужны только окно и таймер. В инструкции я описал, как создать заготовку для примеров из книги. Заготовка это класс "Scene". В нём есть три метода наподобие тех, что в Glut: initializeGL(), paintGL(), resizeGL( int w, int h ). Внутри этих методов код из книги записывается без изменений

Qt - это просто площадка для примеров (до конца книги можно забыть о Qt). Всё остальное в примерах из книги SuperBible (и в самой книге)

P.S. Я знаю, что третье издание (2006 года) - очень сильно устарело. Но это единственная книга на русском, в которой так разжёвываются основы 3D программирования
8Observer8 вне форума Ответить с цитированием
Старый 10.12.2014, 22:05   #5
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Записал видео: 01 Qt OpenGL GLSL. Рисуем треугольник Если сочтёте полезным для себя, то запишитесь на мой блог. Буду добавлять видео ролики по мере накопления опыта

Последний раз редактировалось 8Observer8; 10.12.2014 в 22:09.
8Observer8 вне форума Ответить с цитированием
Старый 24.12.2014, 14:30   #6
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Под каждым видео ссылка на исходники:

001 Qt C++ OpenGL GLSL Рисуем треугольник
002 Qt С++ OpenGL GLSL Передвигаем треугольник
003 Qt С++ OpenGL GLSL. Анимация. Передвигаем треугольник по таймеру
8Observer8 вне форума Ответить с цитированием
Старый 23.03.2015, 19:00   #8
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Краткое знакомство с инструментарием Blender Game Engine

Создание меню для игры на Blender Game Engine. Русский шрифт. Экспорт в exe

Последний раз редактировалось 8Observer8; 23.03.2015 в 19:02.
8Observer8 вне форума Ответить с цитированием
Старый 03.04.2016, 02:13   #9
Yar20
 
Регистрация: 03.04.2016
Сообщений: 7
По умолчанию

Спасибо за уроки. Помогли.
Попытался двигаться далее и загрузить вместо Blocks.jpg картинку с альфа каналом Blocks_new2.png. Собственнор вопрос: почему альфа канал не работает, что я делаю не так. С картинкой вроде всё ОК.
Если выводить на QLabel средствами Qt (без OpenGL) выглядит так:
QImage.JPG
т.е. QImage натянутый на QLabel прозрачность выводит.
А если через текстурированный квадрат (по Вашему уроку "008 Qt C++ OpenGL GLSL. Накладываем текстуру на квадрат") то получается так:
QImageGL.JPG
Как правильно воспользоваться альфа каналом PNG-файла с применением OpenGL?
Yar20 вне форума Ответить с цитированием
Старый 03.04.2016, 23:53   #10
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Цитата:
Сообщение от Yar20 Посмотреть сообщение
Спасибо за уроки. Помогли.
Если хотя бы одному человеку помогли, значит, не зря делал! Очень приятно

Цитата:
Сообщение от Yar20 Посмотреть сообщение
Как правильно воспользоваться альфа каналом PNG-файла с применением OpenGL?
Попробуйте в методе инициализации добавить две строки:

Код:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Эта табличка может быть полезна:
Изображения
Тип файла: jpg 102987_1420114032_blending.jpg (75.6 Кб, 229 просмотров)

Последний раз редактировалось 8Observer8; 04.04.2016 в 00:03. Причина: Добавил табличку
8Observer8 вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Уроки по созданию игр для новичков... -=DeS=- Gamedev - cоздание игр: Unity, OpenGL, DirectX 750 14.11.2017 20:26
Работа с файлами: запись, добавление, чтение (найти ошибку в коде) / C для начинающих Надо создать программу для работы с файлами Konlor Общие вопросы C/C++ 2 18.05.2014 12:37
Проблема с примером из темы "Уроки по созданию игр для новичков..." AvaMight Gamedev - cоздание игр: Unity, OpenGL, DirectX 1 11.02.2012 10:55
Не могли бы дать заготовки процедур для базы данных romich.91 Паскаль, Turbo Pascal, PascalABC.NET 2 27.05.2009 18:00