disallow dropping a card onto another

This commit is contained in:
Max-Wilhelm Bruker 2010-07-17 23:37:22 +02:00
parent 1b286973dd
commit cbfbc542e7
5 changed files with 41 additions and 4 deletions

View file

@ -5,12 +5,21 @@
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QCursor> #include <QCursor>
#include <QPainter>
CardDragItem::CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag) CardDragItem::CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag)
: AbstractCardDragItem(_item, _hotSpot, parentDrag), id(_id), faceDown(_faceDown), currentZone(0) : AbstractCardDragItem(_item, _hotSpot, parentDrag), id(_id), faceDown(_faceDown), occupied(false), currentZone(0)
{ {
} }
void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
AbstractCardDragItem::paint(painter, option, widget);
if (occupied)
painter->fillRect(boundingRect(), QColor(200, 0, 0, 100));
}
void CardDragItem::updatePosition(const QPointF &cursorScenePos) void CardDragItem::updatePosition(const QPointF &cursorScenePos)
{ {
QList<QGraphicsItem *> colliding = scene()->items(cursorScenePos); QList<QGraphicsItem *> colliding = scene()->items(cursorScenePos);
@ -36,12 +45,23 @@ void CardDragItem::updatePosition(const QPointF &cursorScenePos)
QPointF zonePos = currentZone->scenePos(); QPointF zonePos = currentZone->scenePos();
QPointF cursorPosInZone = cursorScenePos - zonePos; QPointF cursorPosInZone = cursorScenePos - zonePos;
QPointF cardTopLeft = cursorPosInZone - hotSpot; QPointF cardTopLeft = cursorPosInZone - hotSpot;
QPointF newPos = zonePos + cursorZone->closestGridPoint(cardTopLeft); QPointF closestGridPoint = cursorZone->closestGridPoint(cardTopLeft);
QPointF newPos = zonePos + closestGridPoint;
if (newPos != pos()) { if (newPos != pos()) {
for (int i = 0; i < childDrags.size(); i++) for (int i = 0; i < childDrags.size(); i++)
childDrags[i]->setPos(newPos + childDrags[i]->getHotSpot()); childDrags[i]->setPos(newPos + childDrags[i]->getHotSpot());
setPos(newPos); setPos(newPos);
bool newOccupied = false;
TableZone *table = qobject_cast<TableZone *>(cursorZone);
if (table)
if (table->getCardFromCoords(closestGridPoint))
newOccupied = true;
if (newOccupied != occupied) {
occupied = newOccupied;
update();
}
} }
} }
@ -54,10 +74,11 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
CardZone *startZone = static_cast<CardItem *>(item)->getZone(); CardZone *startZone = static_cast<CardItem *>(item)->getZone();
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone))) { if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone))) {
currentZone->handleDropEvent(id, startZone, (sp - currentZone->scenePos()).toPoint(), faceDown); if (!occupied)
currentZone->handleDropEvent(id, startZone, (sp - currentZone->scenePos()).toPoint(), faceDown);
for (int i = 0; i < childDrags.size(); i++) { for (int i = 0; i < childDrags.size(); i++) {
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]); CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);
if (!(static_cast<CardItem *>(c->item)->getAttachedTo() && (startZone == currentZone))) if (!(static_cast<CardItem *>(c->item)->getAttachedTo() && (startZone == currentZone)) && !c->occupied)
currentZone->handleDropEvent(c->id, startZone, (sp - currentZone->scenePos() + c->getHotSpot()).toPoint(), faceDown); currentZone->handleDropEvent(c->id, startZone, (sp - currentZone->scenePos() + c->getHotSpot()).toPoint(), faceDown);
sc->removeItem(c); sc->removeItem(c);
} }

View file

@ -9,9 +9,11 @@ class CardDragItem : public AbstractCardDragItem {
private: private:
int id; int id;
bool faceDown; bool faceDown;
bool occupied;
CardZone *currentZone; CardZone *currentZone;
public: public:
CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag = 0); CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag = 0);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void updatePosition(const QPointF &cursorScenePos); void updatePosition(const QPointF &cursorScenePos);
protected: protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

View file

@ -202,6 +202,13 @@ CardItem *TableZone::getCardFromGrid(const QPoint &gridPoint) const
return 0; return 0;
} }
CardItem *TableZone::getCardFromCoords(const QPointF &point) const
{
QPoint gridPoint = mapToGrid(point);
return getCardFromGrid(gridPoint);
}
QPointF TableZone::mapFromGrid(const QPoint &gridPoint) const QPointF TableZone::mapFromGrid(const QPoint &gridPoint) const
{ {
if ((gridPoint.y() == 3) && (settingsCache->getEconomicGrid())) if ((gridPoint.y() == 3) && (settingsCache->getEconomicGrid()))

View file

@ -30,6 +30,7 @@ public:
void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown = false); void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown = false);
void handleDropEventByGrid(int cardId, CardZone *startZone, const QPoint &gridPoint, bool faceDown = false, bool tapped = false); void handleDropEventByGrid(int cardId, CardZone *startZone, const QPoint &gridPoint, bool faceDown = false, bool tapped = false);
CardItem *getCardFromGrid(const QPoint &gridPoint) const; CardItem *getCardFromGrid(const QPoint &gridPoint) const;
CardItem *getCardFromCoords(const QPointF &point) const;
QPointF mapFromGrid(const QPoint &gridPoint) const; QPointF mapFromGrid(const QPoint &gridPoint) const;
QPoint mapToGrid(const QPointF &mapPoint) const; QPoint mapToGrid(const QPointF &mapPoint) const;
QPointF closestGridPoint(const QPointF &point); QPointF closestGridPoint(const QPointF &point);

View file

@ -512,6 +512,12 @@ ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player *
if ((!startzone) || (!targetzone)) if ((!startzone) || (!targetzone))
return RespNameNotFound; return RespNameNotFound;
// Collision detection
if (targetzone->hasCoords())
for (int i = 0; i < targetzone->cards.size(); ++i)
if ((targetzone->cards[i]->getX() == x) && (targetzone->cards[i]->getY() == y))
return RespContextError;
int position = -1; int position = -1;
Server_Card *card = startzone->getCard(_cardId, true, &position); Server_Card *card = startzone->getCard(_cardId, true, &position);
if (!card) if (!card)