Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Pritcher от Май 30, 2014, 18:46



Название: [РЕШЕНО] Пятнашки
Отправлено: Pritcher от Май 30, 2014, 18:46
Доброго времени суток!

Решил написать свои пятнашки на Qt. Определил класс для ячеек Cell (потомок QWidget), класс для главного окна приложения MainField (также потомок QWidget). При создании ячеек в конструкторе с помощью QPalette задаю цвет фона каждой ячейки.
Есть идея организовать смену цвета ячейки, когда та встает на нужное место (например, ячейка 1 оказывается в левом верхнем углу).
Как это можно реализовать?
После очередного хода игрока, программа проверяет, не выиграл ли пользователь после очередного шага. Проверка полным перебором. Вызывается как слот класса MainField

Ячейки хранятся одномерным массивом Cell widgets[16].
Помимо ячеек хранятся номера на ячейках, массив intCell[16]. Таким образом устанавливается взаимно-однозначное соответствие.

Код:
void MainField::isWin()
{
bool t = true;
for ( int i = 0; i < 16 && t; i++ ) {
if ( intCell[i] != (i + 1) )
t = false;
}
if ( t )
emit gameWon();
}

Как можно внутри этого слота сделать замену цвета ячейки, если она стоит на своем месте? Данное условие intCell == (i+1).


Название: Re: Пятнашки
Отправлено: gil9red от Май 30, 2014, 19:16
По поводу цвета, можно у класса Cell переопределить событие перерисовки paintEvent и рисовать через QPainter :)

Код
C++ (Qt)
class Cell : public QWidget
{
Q_OBJECT
 
public:
Cell( QWidget * parent = 0 )
  : QWidget( parent  ), color( Qt::green )
{  
}
...
 
private:
QColor color;
 
protected:
void paintEvent( QPaintEvent * )
{
QPainter painter( this );
painter.setBrush( color );
painter.drawRect( this->rect() );
}
 
};

Но я бы лучше попробовал сделать пятнашки через QGraphicsScene - документация для старенькой версии, зато переведена http://doc.crossplatform.ru/qt/4.4.3/qgraphicsscene.html :)

Да и, кажется, удобнее будет хранить не в одномерном массиве, а в двухмерном - доска пятнашек ведь сама, по сути, является двухмерным массивом )


Название: Re: Пятнашки
Отправлено: Pritcher от Май 30, 2014, 19:38
Хм, я не знал о существовании QGraphicsScene, спасибо за информацию и за столь молниеносный ответ)

Я нашёл пол решения.

Добавил в класс Cell следующий метод:
Код:
void Cell::changeColor( QColor color )
{
QPalette palette;
palette.setColor( this->backgroundRole(), color );
this->setAutoFillBackground( true );
this->setPalette( palette );

}

Сделал тест: создал в main.cpp лишь 1 ячейку, без создания поля MainField. Все работает замечательно, цвет меняется. Как только вызываю данный метод для члена класса MainField, для какого-нибудь widgets, (для любого i от 0 до 15), так ничего не происходит D:


Название: Re: Пятнашки
Отправлено: gil9red от Май 30, 2014, 19:45
Хм, я не знал о существовании QGraphicsScene, спасибо за информацию и за столь молниеносный ответ)

Я нашёл пол решения.

Добавил в класс Cell следующий метод:
Код:
void Cell::changeColor( QColor color )
{
QPalette palette;
palette.setColor( this->backgroundRole(), color );
this->setAutoFillBackground( true );
this->setPalette( palette );

}

Сделал тест: создал в main.cpp лишь 1 ячейку, без создания поля MainField. Все работает замечательно, цвет меняется. Как только вызываю данный метод для члена класса MainField, для какого-нибудь widgets, (для любого i от 0 до 15), так ничего не происходит D:

Кода бы побольше :)


Название: Re: Пятнашки
Отправлено: Pritcher от Май 30, 2014, 19:51
Прошу прощения, у меня руки растут не оттуда, откуда нужно. Все работает)
Метод рабочий.
Я останавливал цикл, когда находил несоответствующую порядку ячейку, в итоге проверка была не для всех ячеек, поэтому мне казалось, что работает неверно.

Тему можно закрывать.
Спасибо за советы)

Было
Код:
void MainField::isWin()
{
bool t = true;
for ( int i = 0; i < 16 && t; i++ ) {
QColor color;
if ( intCell[i] != ( i + 1 ) ) {
t = false;
color.setRgb( 254, 228, 167 );
//widgets[i]->changeColor( QColor( 254, 228, 167 ) ); // желтый
}
else
color.setRgb( 149, 255, 114 );
widgets[i]->changeColor( color );
//widgets[i]->changeColor( QColor( 149, 255, 114 ) ); // зеленый
}
if ( t )
emit gameWon();
}

Стало без второго условия в цикле.