Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 16
1

Паттерн Strategy + paintEvent

31.03.2015, 18:12. Показов 1609. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуте. В универе задали создать игру Тетрис. Прорисовку окон сказали осуществить с использованием шаблона Strategy. Тоесть у меня есть один виджет на котором все прорисовывается в зависимости какой должен быть экран. Не могу понять каким образом переопределять paintEvent и правильно ли будет наследовать класс унаследованный от QWidget. Зарание прошу прощения если влопрос поставлен некоректно,с шаблонами только начал ознакамливатся.

Вообщем нужно переделать Стратегию так что бы вместо virtual void use(void) = 0; был paintEvent()
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class Strategy
{
public:
    Strategy(void){}
    ~Strategy(void){}
 
    virtual void use(void) = 0;
};
 
class Strategy_1: public Strategy
{
public:
    Strategy_1(){}
    ~Strategy_1(){}
 
    void use(void){ cout << "Strategy_1" << endl; };
};
 
class Strategy_2: public Strategy
{
public:
    Strategy_2(){}
    ~Strategy_2(){}
 
    void use(void){ cout << "Strategy_2" << endl; };
};
 
class Strategy_3: public Strategy
{
public:
    Strategy_3(){}
    ~Strategy_3(){}
 
    void use(void){ cout << "Strategy_3" << endl; };
};
 
class Context
{
protected:
       Strategy* operation;
 
public:
    Context(void){}
    ~Context(void){}
 
    virtual void UseStrategy(void) = 0;
    virtual void SetStrategy(Strategy* v) = 0;
};
 
class Client: public Context
{
    public:
    Client(void){}
    ~Client(void){}
 
    void UseStrategy(void)
    {
        operation->use();
    }
 
    void SetStrategy(Strategy* o)
    {
        operation = o;
    }
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    Client customClient;
    Strategy_1 str1;
    Strategy_2 str2;
    Strategy_3 str3;
 
    customClient.SetStrategy(&str1);
    customClient.UseStrategy();
    customClient.SetStrategy(&str2);
    customClient.UseStrategy();
    customClient.SetStrategy(&str3);
    customClient.UseStrategy();
 
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.03.2015, 18:12
Ответы с готовыми решениями:

паттерн strategy
в приложенном архиве примерчик гостевой книги. В общем в форму html вводятся данные (user, email,...

Паттерн Strategy и игрушка
Есть задание: применить паттерн Strategy к игрушке (всякие перемещения для объектов). Немного...

Почему паттерн абстрактная фабрика - паттерн уровня объектов, если в нём могут быть статические отношения?
Взято из Шевчук А., Охрименко Д., Касьянов А. Design Patterns via C#. Приемы...

Source Strategy
Название - Source Strategy Платформа - Android (пока что) Жанр - Стратегия Разработчик - к...

9
66 / 66 / 18
Регистрация: 31.03.2015
Сообщений: 253
31.03.2015, 19:02 2
Я бы посоветовал использовать QGraphicsView, а не рисовать прямо на виджете. Виджет не совсем для этого предназначен.
Если же нужно именно так, то вызвать repaint() нужного виджета в теле функции use.
А переопределить paintEvent:
C++
1
2
3
4
5
6
7
8
9
10
11
12
class QMyWidget : public QWidget {
    Q_OBJECT
...
protected:
    void paintEvent(QPaintEvent * event);
...
}
 
void QMyWidget::paintEvent(QPaintEvent * event) {
    QPainter p(this);
//ну и дальше p->drawXXXX(...);
}
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.03.2015, 19:19 3
Цитата Сообщение от yarko Посмотреть сообщение
Я бы посоветовал использовать QGraphicsView, а не рисовать прямо на виджете. Виджет не совсем для этого предназначен.
Не советуйте дурно, все как раз таки и наоборот. Назначение QGraphicsView это реализация механизмов манипуляции с объектами, а не просто рисование.


van4esco, Думаю не стоит привязывать механизмы твоей игры, к виджету.

Цитата Сообщение от van4esco Посмотреть сообщение
образом переопределять paintEvent и правильно ли будет наследовать класс унаследованный от QWidget.
Переопределение paintEvent нужно тебе только для возможности рисования, не вижу смысла что бы наследовать и плодить свои классы.

Цитата Сообщение от van4esco Посмотреть сообщение
в зависимости какой должен быть экран.
Имеется ввиду размер экрана?
Т.е. что будет в игре меняться при разных размерах экрана?
0
0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 16
31.03.2015, 19:22  [ТС] 4
Тогда как по-вашему лучше поступить в таком случае?

Добавлено через 3 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Не советуйте дурно, все как раз таки и наоборот. Назначение QGraphicsView это реализация механизмов манипуляции с объектами, а не просто рисование.


van4esco, Думаю не стоит привязывать механизмы твоей игры, к виджету.


Переопределение paintEvent нужно тебе только для возможности рисования, не вижу смысла что бы наследовать и плодить свои классы.


Имеется ввиду размер экрана?
Т.е. что будет в игре меняться при разных размерах экрана?
Имеется ввиду,что у игры есть пускай Н экранов, например Главное меню,Таблица,Результатов,Загрузка... Так вот эти все окна должны прорисовыватся на одном виджете методом paintEvent() по шаблону Strategy
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.03.2015, 19:42 5
Ну приблизительно такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class AbstractScreenStrategy
{
  public:
     void virtual draw(QPainter* painter)=0;
     virtual ~AbstractScreenStrategy();
};
 
class SmallScreenStrategy: public AbstractScreenStrategy
{
  public:
     void virtual draw(QPainter* painter)
    {  
       //   painter->drawLine( ... ) 
    };
};
 
class BigScreenStrategy: public AbstractScreenStrategy
{
  public:
     void virtual draw(QPainter* painter)
    { //  ... };
};
 
class Game
{
      AbstractScreenStrategy* screenStrategy_;
  public:
      Game(AbstractScreenStrategy* screenStrategy):screenStrategy_(screenStrategy){};
 
     void draw(QPainter* painter)
     {
         screenStrategy_->draw(painter);
     }
}
 
// ... 
AbstractScreenStrategy* strategy= new SmallScreenStrategy;
Game game(strategy);
// ...
void QMainWindow::paintEvent(QPaintEvent * event)
{
    QPainter painter(this);
    game.draw(&painter);
}
Добавлено через 2 минуты
Цитата Сообщение от van4esco Посмотреть сообщение
Имеется ввиду,что у игры есть пускай Н экранов, например Главное меню,Таблица,Результатов,Загрузка... Так вот эти все окна должны прорисовыватся на одном виджете методом paintEvent() по шаблону Strategy
Какое отношение это имеет к паттерну Strategy ?
Стратегия это класс определяющий поведение другого класса.
В данном примере поведение прорисовки в игре: каким цветом будут прорисовываться, линии фигур, какие края, стиль итп.
2
66 / 66 / 18
Регистрация: 31.03.2015
Сообщений: 253
01.04.2015, 09:18 6
Цитата Сообщение от Avazart Посмотреть сообщение
Не советуйте дурно, все как раз таки и наоборот. Назначение QGraphicsView это реализация механизмов манипуляции с объектами, а не просто рисование.
Это тетрис, а не програма а-ля MS Paint
Выгоднее передвинуть готовую нарисованую фигурку, чем заново ее рисовать.
0
0 / 0 / 0
Регистрация: 03.04.2015
Сообщений: 4
03.04.2015, 11:09 7
Avazart, у меня почти такая самая ситуация .Нужно реализировать паттерн State для смены состояний игрыдля начало только два) Loading - загрузка игры, Menu - меню игры.Всю прорисовку состояний должен делать GameWidget.Перейти нужно с Loading в Menu. Есть клас Game сделаный с помощью Singleton'a.

Game.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Game
{
    GameWidget *WinGame;
public:
    static Game& Instance();
    void run();
    class State *current;
    void setCurrent(State *s)
    {
        current = s;
    }
 
private:
    Game();
    Game(const Game& root);
    Game& operator=(const Game&);
};
Метод run() которого отображает GameWidget

Game.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Game::Game()
{
    WinGame = new GameWidget;
}
 
Game& Game::Instance()
{
    static Game theSingleInstance;
    return theSingleInstance;
}
 
void Game::run()
{
    WinGame->show();
    current = new Loading;
}
 
}
Loading - класс загрузки унаследованный от абстрактного класа State:
State.h
C++ (Qt)
1
2
3
4
5
6
class State
{
 
public:
    virtual void draw();
};
GameWidget.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
class GameWidget : public QWidget
{
    Q_OBJECT
 
public:
    GameWidget(QWidget *parent = 0);
    ~GameWidget();
    void paintEvent(QPaintEvent *event);
};
main.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
 
    Game::Instance().run();
 
    return a.exec();
}
Помогите сделать так, щоб прорисовку екрана делал только GameWidget в зависимости от состояния игры.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.04.2015, 12:48 8
http://cpp-reference.ru/patter... rns/state/
http://rsdn.ru/article/patterns/State.xml

Добавлено через 15 минут
Вероятно можно где-то по лучше найти описание паттерна, но я с ним не имел дела не могу подсказать.
1
0 / 0 / 0
Регистрация: 03.04.2015
Сообщений: 4
03.04.2015, 22:04 9
Avazart, Спасибо !

Добавлено через 4 часа 58 минут
Avazart, еще один вопрос. Как с помощью QList'a передать обьекты для отрисовки с класса состояния или стратегии в класс GameWidget ( унаследованного от QWidget ), а именно отрисовать paintEvent'ом ?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
04.04.2015, 12:34 10
Цитата Сообщение от Afterwork Посмотреть сообщение
Avazart, еще один вопрос. Как с помощью QList'a передать обьекты для отрисовки с класса состояния или стратегии в класс GameWidget ( унаследованного от QWidget ), а именно отрисовать paintEvent'ом ?
А зачем их передавать?
Передавай QPainter внутрь метода draw объекта Game как в моем примере со стратегией.
0
04.04.2015, 12:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.04.2015, 12:34
Помогаю со студенческими работами здесь

strategy pattern
Как можно понять етот пример? а т.е. ведь метод DoAlgorithm(); не может быть вызван в этом месте:...

Использование паттерна Strategy
Помогите написать php код с применением ООП. Дан каталог компьютеров. Свойства компьютеров...

EJB read mostly strategy
Есть бин, примерно 200-300 записей в базе, которые он представляет. Эти записи обновляются каждый...

Design Pattern - Strategy
Всем привет! Хочется услышать мнение со стороны о получившемся коде. Все работает, и вроде как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru