ich bin am überlegen wie ich es am besten hinkriege das gezeichnete Objekte - die ich evtl. mit der Maus bewege - nicht einfach überlagern, falls es nicht erwünscht ist.
Nun habe ich einfach mal probiert ne Positionsabfrage zu machen und gegebenenfalls die Position-koordinaten zurückzusetzen, das finde ich aber dann doch recht aufwändig...
gibt es eine schnelle möglichkeit ein GrphicItem unddurchlässig für andere bildchen zu machen?
Kollisionsabfrage von QGraphicsItems
ich glaube das geht nicht so sehr in den bereich kollisionsabfrage, denn ich will ja verhindern, dass eine spielfigur ein ein objekt reingeschoben wird...
ich werde mal mein problemcode reinstellen...
das ist ein teil der "figur" die klasse ist von QGrphicsItem abgeleitet...
das ist das objekt (HAUS; WALD; SONTIGES) bei dem eine kollision überprüft wird...
man sieht die auskommentierten ansätze... ich habe noch nie mit sowas gearbeitet und frage mich wie man sowas am effektivsten macht...
evtl sollte ich an der figur und nicht am hindernis prüfen... aber das müsste eigentlich egal sein?!
ich werde mal mein problemcode reinstellen...
das ist ein teil der "figur" die klasse ist von QGrphicsItem abgeleitet...
Code: Alles auswählen
void QUnit::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::darkGray);
//painter->drawEllipse(-7, -7, unit_size, unit_size); //(-7, -7, 20, 20)
QRadialGradient gradient(-3, -3, 10);
if (option->state & QStyle::State_Sunken)
{
gradient.setCenter(3, 3);
gradient.setFocalPoint(3, 3);
gradient.setColorAt(1, QColor(Qt::yellow).light(120));
gradient.setColorAt(0, QColor(Qt::darkYellow).light(120));
}
else
{
gradient.setColorAt(0, Qt::yellow);
gradient.setColorAt(1, Qt::darkYellow);
}
painter->setBrush(gradient);
painter->setPen(QPen(Qt::black, 0));
painter->drawEllipse(-10, -10, unit_size, unit_size); //(-7, -7, 20, 20)
/*
if(this->collidingItems().size() > 1)
setFlags(QGraphicsItem::ItemIsSelectable);
if(this->collidingItems().size() == 0)
setFlags(ItemIsSelectable | ItemIsMovable);
*/
motion_buffer.append(this->pos() );
}
Code: Alles auswählen
QList<QPointF> QUnit::last_pos()
{
return motion_buffer;
}Code: Alles auswählen
void QArea::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
painter = draw_area(AType, painter);
QList<QGraphicsItem*> collisions = check_collision();
}
/*this function is reimplemented;
the shape is used for collision detection*/
QPainterPath QArea::shape() const
{
QPainterPath path;
path.addRect(-10, -10, width_area, height_area);
return path;
}
QPainter *QArea::draw_area(AreaType type, QPainter *pntr)
{
QPainter *painter = pntr;
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::darkGray);
if(type == bunker)
{
QRectF rectangle(-7, -7, width_area, height_area);
painter->drawRect(rectangle);
QLinearGradient gradient(-7, -7, width_area, height_area);
gradient.setColorAt(0, QColor(Qt::darkYellow).light(120));
painter->setBrush(gradient);
painter->setPen(QPen(Qt::black, 0));
painter->drawRect(-10, -10, width_area, height_area);
std::cout<<"Draw bunker"<<std::endl;
}
return painter;
}
QList<QGraphicsItem*> QArea::check_collision()
{
QList<QGraphicsItem*> collisions = collidingItems();
for(int i = 0; i < collisions.size(); i++)
{
std::cout<<"collision with: "<<collisions.at(i)<<std::endl;
}
if(collisions.size() > 1)
for(int i = 0; i < collisions.size(); i++)
{
//temp item to reset position
QGraphicsItem *item = collisions.at(i);
/*
//position of crashing GrphicsItem
QPointF *position = new QPointF;
position = &item->pos();
if(position->rx() >= (this->pos() ).rx() )
{
//20 should be the radius of the crashing one
item->setPos((this->pos()).rx() - 20, position->ry());
std::cout<<"1.) crashing one moved back horizontally"<<std::endl;
}
if(position->rx() <= (this->pos() ).rx() + width_area)
{
//20 should be the radius of the crashing one
item->setPos((this->pos()).rx() + width_area + 20, position->ry());
std::cout<<"2.) crashing one moved back horizontally"<<std::endl;
}
*/
QUnit *UItem = static_cast<QUnit *>(item);
QList<QPointF> MBuffer = UItem->last_pos();
std::cout<<MBuffer.size()<<std::endl;
for(int i = MBuffer.size() - 1; i >= 0; i--)
{
UItem->setPos(MBuffer.at(i) );
std::cout<<"crashing one moving back"<<std::endl;
}
}
return collisions;
}
evtl sollte ich an der figur und nicht am hindernis prüfen... aber das müsste eigentlich egal sein?!
wie meinst du das? ich habe mir gedacht ich speichere die positionsdaten von der figur bei der bewegung in ein array und setz das bei ner kollision schrittweise wieder zurück (d.h. ich mache eine abfrage ab welcher position noch keine kollision stattgefunden hätte)?! ich denke dass würde am schnellsten gehen. aber ich habe noch nie mit GraphicItems gearbeitet und komm nicht so sehr óft zum programmieren, sodass mir auf dem gebiet erfahrungen fehlen.
Dann würde ich mich an deiner Stelle ein bißchen in dieses Thema einarbeiten. Hier in diesem Beispiel wird z.B. auch eine Kollisionsabfrage verwendet...
naja, ich denke ich bin grad dabei mich einzuarbeiten^^ ich mach ja schließlich nur ein übungsspielchen...
danach wollte ich ein bissel netzwerkzeugs und verschlüsselung üben und eine art instant messanger basteln.
das mice-example kenne ich übrigens.. nur das dort lediglich einje kollision abgefragt wird (bool) mit der einfachen funktion und dann die ohren sich umfärben... aber ich habe schon eine idee wie ich das in den griff kriege. wenn ich so weit bin, werde ich mal die auflösung hier reinstellen.
mal sehen ob ich heute mal dran rumbastel...
danach wollte ich ein bissel netzwerkzeugs und verschlüsselung üben und eine art instant messanger basteln.
das mice-example kenne ich übrigens.. nur das dort lediglich einje kollision abgefragt wird (bool) mit der einfachen funktion und dann die ohren sich umfärben... aber ich habe schon eine idee wie ich das in den griff kriege. wenn ich so weit bin, werde ich mal die auflösung hier reinstellen.
mal sehen ob ich heute mal dran rumbastel...