Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: 8ull от Апрель 02, 2011, 18:12



Название: Арканоид
Отправлено: 8ull от Апрель 02, 2011, 18:12
Добрый день. Возникла необходимость работать с QGraphics. Нужно написать простенький арканоид. Возникают следующие вопросы:
1. Как организовать отскок мяча от стенок? (Не получается определить положение шара QGraphicsEllipseItem внутри сцены)
2. Как организовать анимацию шара? (Пробовал через QGraphicsItemAnimation, но не получается сделать перемещение шара внутри сцены бесконечным)
Спасибо.


Название: Re: Арканоид
Отправлено: madRoger от Апрель 02, 2011, 18:26
Положение итема на сцене можно определить с помошью QGraphicsItem::scenePos()
Проверять соприкосновение шара со стенкой можно без проверки координат, а с помощью QGraphicsItem::collidesWithItem - пересечение с объектом.
Анимацию можно реализовать по таймеру, переопределив timerEvent.
Единственная трудность в вашем случае - расчет траектории.

Я делал подобный проект - тетрис. На Qt все реализуется достаточно просто.


Название: Re: Арканоид
Отправлено: 8ull от Апрель 05, 2011, 18:25
Точка, которую возвращает ball->scenePos(), почему-то всегда имеет нулевые координаты в цикле анимации шара. Пробовал проверять столкновение шара с линией, протянутой по низу сцены - столкновение не фиксируется, шар продолжает движение через линию.

Код:
ui->graphicsView->setFixedSize(500, 300);
scene = new QGraphicsScene;
ui->graphicsView->setScene(scene);
QGraphicsLineItem *bottomline = new QGraphicsLineItem();
bottomline = scene->addLine(-249.0, 148.0, 249.0, 148.0);
ball = new QGraphicsEllipseItem(-10, -10, 10, 10);
scene->addItem(ball);
qreal dx=0;
qreal dy=0;
int velx=1;
int vely=1;
QTimeLine *timer = new QTimeLine(5000);
timer->setFrameRange(0, 100);
QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;
animation->setItem(ball);
animation->setTimeLine(timer);
timer->setUpdateInterval(10);
for (int i = 0; i < 400; ++i)
{
       
        if(ball->collidesWithItem(bottomline, Qt::IntersectsItemShape)) vely*=-1;
        animation->setPosAt(i / 400.0, QPointF(dx+velx, dy+vely));
        dx+=velx;
        dy+=vely;
}
timer->start();



Название: Re: Арканоид
Отправлено: madRoger от Апрель 05, 2011, 18:58
Минус Animation в том, что он устаннавливается на время.
Как вариант, все можно реализовать, переопределив timerEvent класса.

*.h
Код:
....какой-то класс
{
QGraphicsScene *gs;
QGraphicsLineItem *gli;
QGraphicsEllipseItem *gei;
в GUI имеем QGraphicsView *gv.

protected:
  void timerEvent(QTimerEvent *);
}


*.сpp
Код:
В конструкторе класса:
gs = new QGraphicsScene(this);
gs->setSceneRect(0,0,450,550);
ui->gv->setFixedSize(460,560);
ui->gv->setScene( gs );

gli = new QGraphicsLineItem(0,500,400,500);
gs->addItem( gli );

gei = new QGraphicsEllipseItem(0,0,50,50);
gei->setPos(200,200);
gs->addItem(gei);

startTimer( 100 );

...
...

void класс::timerEvent(QTimerEvent *te)
{
    Q_UNUSED(te);

    gei->setPos(gei->scenePos().x(),gei->scenePos().y()+10);

    if( gei->collidesWithItem(gli))
    {
       ...
    }
}


Название: Re: Арканоид
Отправлено: uriel от Апрель 06, 2011, 19:09
Когда только начинал изучать плюсы и Qt, тоже писал арканоид в качестве курсового.
Анимаций тогда ещё не было, делал всё через timerEvent - работает относительно шустро. Сам отскок сделал тоже примитивно: меняем угол на противоположный +- небольшое случайное число.
Если интересно, могу выложить исходники.


Название: Re: Арканоид
Отправлено: 8ull от Апрель 08, 2011, 15:56
Да, если не трудно. Было бы неплохо на них взглянуть.
madRoger, большое спасибо, с шаром и платформой разобрался.


Название: Re: Арканоид
Отправлено: uriel от Апрель 08, 2011, 20:05
Сначала честно хотел попробовать привести их в нормальный вид, но потом понял, что это бесполезно. :)