PDA

View Full Version : Turn items and progress



giorgik
29th October 2012, 16:30
Hello everyone, I have created (with QtCreator 2.5.2 and Qt 4.8.2) a program that displays a rectangle in my QGraphicsScene.
This rectangle walking along the y axis of the scene. I wish to advance over the rectangle can also rotate around its center of gravity (always maintaining the path along the y axis). For the animation use QGraphicsItem::advance(int phase) together with a timer defined in the constructor of my item (derived from the class QGraphicsItem). How should I do?
This is my code for the item:


#include "robot.h"
#include <QDebug>

Robot::Robot() : angolo(10), velocita(5), posizione(0, 0), flagCollisione(false)
{
// posizione iniziale rispetto angolo in alto a sinsitra della scena
int startX = 200;
int startY = 200;

// posiziono il baricentro del robot nel centro della scena
setPos(mapToParent(startX, startY));

// rendo possibile spostare il robot con il mouse
this->setFlags(QGraphicsItem::ItemIsMovable);
}

// definisci le dimensioni perimetrali del robot
QRectF Robot::boundingRect() const
{
// origine assi robot angolo in alto a sinistra
//return QRect(0, 0, 20, 30);

// origine assi robot nel baricentro del robot
return QRect(-10, -15, 20, 30);
}

// ridisegna robot ogni volta che si fa setPos()
void Robot::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QRectF corpo = boundingRect();

// definisci colore pennello area robot: grigio
QBrush Pennello(Qt::gray);

// individuazione base collisione
if(scene()->collidingItems(this).isEmpty())
{
// nessuna collisione: usa colore area verde item
Pennello.setColor(Qt::green);
}
else
{
// collisione!!!: usa colore area rossa item
Pennello.setColor(Qt::red);
flagCollisione = !flagCollisione;

// individua il punto di collisione
vaiCollisione();
}

// colora area robot
painter->fillRect(corpo, Pennello);

// ridisegna robot
painter->drawRect(corpo);
}

void Robot::advance(int phase)
{
if(!phase) return;

// leggi la posizione attuale
posizione = this->pos();

if(flagCollisione == false)
setPos(mapToParent(0, -(velocita)));
else if(flagCollisione == true)
setPos(mapToParent(0, velocita));
}

void Robot::vaiCollisione()
{
// leggi una nuova posizione
posizione = this->pos();

// vedere se la nuova posizione è nel perimetro
if(!(scene()->sceneRect().contains(posizione)))
{
// siamo fuori dell'area scena

// muovilo indietro nel perimetro
setPos(mapToParent(200, velocita));
posizione = this->pos();
flagCollisione = false;
}
else
{
// siamo all'interno dell'area scena
// imposta la nuova posizione
setPos(posizione);
}
}

while the MainWindow is:


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "robot.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

pScena = new QGraphicsScene(this);
ui->graphicsView->setScene(pScena);

ui->graphicsView->setRenderHint(QPainter::Antialiasing);
pScena->setSceneRect(0, 0, 400, 400);

QPen miaPenna = QPen(Qt::red);

// crea il contorno scena
QLineF LineaAlto(pScena->sceneRect().topLeft(), pScena->sceneRect().topRight());
QLineF LineaSinistra(pScena->sceneRect().topLeft(), pScena->sceneRect().bottomLeft());
QLineF LineaDestra(pScena->sceneRect().topRight(), pScena->sceneRect().bottomRight());
QLineF LineaBasso(pScena->sceneRect().bottomLeft(), pScena->sceneRect().bottomRight());

pScena->addLine(LineaAlto, miaPenna);
pScena->addLine(LineaSinistra, miaPenna);
pScena->addLine(LineaDestra, miaPenna);
pScena->addLine(LineaBasso, miaPenna);

int contaRobot = 1;

for(int i = 0; i < contaRobot; i++)
{
Robot *pRobot = new Robot();
pScena->addItem(pRobot);
}

pTimer = new QTimer(this);
connect(pTimer, SIGNAL(timeout()), pScena, SLOT(advance()));
pTimer->start(100);
}

MainWindow::~MainWindow()
{
delete ui;
}

giorgik
31st October 2012, 11:32
Resolved:


void Robot::advance(int phase)
{
if(!phase) return;

angolo += 10;

if(flagCollisione == false)
{
avanzamento += 5;
}
else if(flagCollisione == true)
{
avanzamento -= 5;
}
// rototraslazione
setTransform(QTransform().translate(0, -(avanzamento)).rotate(angolo));
}