Russian Qt Forum
Сентябрь 27, 2024, 22:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Вопросы по архитектуре приложения ... 2D графика.  (Прочитано 3116 раз)
patison
Гость
« : Май 29, 2010, 00:49 »

Всем привет!

В Qt я, пока, отсносительный нуб.
Сейчас очень хочется соорудить простенькое игровое приложение.
В данный момент хочу просто на поле передвигать кнопками объект. Сначала начал ориентироваться по примеру Colliding Mice (кажется  так называется), сейчас просматриваю Ported Asteroids, но тут всё немного сложно для меня.

Итак, сейчас у меня имеются файлы main.cpp, mainview.cpp (+mainview.h), stick.cpp (+stick.h).
mainview - это класс унаследованный от QGraphicsView, который собсна представляет собой игровое поле.
stick - класс от QGraphicsItem, объект которого представляет собой "палку", которую я хочу передвигать по экрану.

main.cpp
Код:
#include <QtGui/QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QObject>
#include <QTimer>

#include "stick.h"
#include "mainview.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainView mView;

    QGraphicsScene scene;
    scene.setSceneRect(0, 0, 495, 495);
    scene.setItemIndexMethod(QGraphicsScene::NoIndex);

    Stick *userStick = new Stick;

    userStick->setPos(300, 200);
    scene.addItem(userStick);
   
    mView.setScene(&scene);
    mView.setBackgroundBrush(QPixmap("images/background-space.jpg"));
    mView.setCacheMode(QGraphicsView::CacheBackground);
    mView.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Space Bouncing"));
    mView.resize(500, 500);
    mView.show();

    QObject::connect( &mView, SIGNAL(keyPressed(QKeyEvent*)), &scene, SLOT(advance()) );

    return a.exec();
}

mainview.h
Код:
#ifndef MAINVIEW_H
#define MAINVIEW_H

#include <QGraphicsView>
#include <QObject>

class MainView : public QGraphicsView
{
    Q_OBJECT

public:
    MainView();

protected:
    // Events
    void keyPressEvent(QKeyEvent *event);

signals:
    void keyPressed(QKeyEvent *event);

};
#endif // MAINVIEW_H

mainview.cpp
Код:
#include <QMessageBox>
#include <QKeyEvent>
#include <QGraphicsItem>
#include "mainview.h"

MainView::MainView()
{}

void MainView::keyPressEvent(QKeyEvent *event) {

    emit keyPressed(event);
}

stick.h
Код:
#ifndef STICK_H
#define STICK_H

#include <QGraphicsItem>
#include <QKeyEvent>

class Stick : public QGraphicsItem
{
public:
    Stick();

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QPainterPath shape() const;
    QRectF boundingRect() const;

protected:
    void advance(int step);
};

#endif // STICK_H

stick.cpp
Код:
#include <QPainter>
#include <QMessageBox>

#include "stick.h"

Stick::Stick()
{
}

void Stick::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) {

    QRect qRect;
    painter->setBrush(Qt::white);

    qRect.setWidth(100);
    qRect.setHeight(30);

    painter->drawRect(qRect);
}

void Stick::advance(int step) {

    if(step==1)
        moveBy(10, 0);
}

// Не понял до конца зачем эта функция...
QPainterPath Stick::shape() const
{
    QPainterPath path;
    path.addEllipse(boundingRect());
    return path;
}

// Не понятно до конца зачем эта функция
QRectF Stick::boundingRect() const
{
    qreal adjust = 0.5;
    return QRectF(-18 - adjust, -22 - adjust,
                  36 + adjust, 60 + adjust);
}

Примерно так.
Как видно из комментов в последнем файле - не понял толком зачем функции boundingRect и shape.

Второй вопрос - относительно обработки нажатия клавиш. Не уверен что подход который я тут использовал - правильный, но как сделать обработку нажатия клавиши на прямую в классе Stick - я не разобрался.

Ну и третий вопрос, как сделать так что-бы графический объект Stick полностью передвигался по экрану. В данный момент, при нажатии на клавишу, от палки как-бы откалывается кусок прямоугольника, и двигается только он.

Заранее спасибо. Буду благодарен ответам на вопросы выше, плюс интересно услышать мнения относительно архитектуры предложения в целом. Догадываюсь что в моём случае она не совсем правильная.
Записан
Lostinnet
Гость
« Ответ #1 : Май 31, 2010, 11:16 »

все очень просто!
boundingRect - задает прямоугольную область в которой отображается твой элемент. Из-за того что ты ее не правильно задаешь, то и палка у тебя плохо стирается/отрисовывается
shape - задает область в которой элемент получает события мыши.
Записан
ieroglif
Гость
« Ответ #2 : Май 31, 2010, 15:20 »

я бы сделал такую архитектуру.
1. классы.

1.1 класс окна (О). умеет ловить события мыши-клавы и отправлять их другим игровым объектам. умеет перерисовываться.
1.2 класс игрового поля (ИП). умеет отрисовывать себя на QPainter и отдавать команду отрисовки своим "детям".
1.3 класс фигурки (Ф). умеет себя рисовать на QPainter. умеет ловить команды "вверх, вниз, влево, вправо" и пересчитывать свои собственные координаты.

связываться это будет такими цепочками:
1. О.paintEvent -> QPainter p; -> ИП.draw(&p) -> Ф.draw(&p); - получили отрисовку всего чего надо.
2. О.keyEvent -> switch (key ) -> Ф.moveUp/Down/Left/Right -> Ф.x++ / y++ / x-- / y --; -> О.update();

вроде вот так.
таким образом всё у нас красиво и очевидно =) добавляем рисование через буффер - получаем картинку без подёргиваний.
хотим перерисовывать в OpenGL - просто добавляем функции drawGL в которых определяем нужные оглу отрисовки.
Записан
patison
Гость
« Ответ #3 : Июнь 01, 2010, 20:41 »

Спасибо. многое прояснилось с вашими ответами.
Пока ждал эти ответы, взялся основательно за литературу Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.044 секунд. Запросов: 21.