ksquares
gameboardscene.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "gameboardscene.h"
00011
00012 #include "highlightanimation.h"
00013
00014 #include <math.h>
00015
00016 #include <QGraphicsSceneMouseEvent>
00017 #include <QGraphicsEllipseItem>
00018
00019 #include <kdebug.h>
00020 #include <kggzmod/module.h>
00021
00022 GameBoardScene::GameBoardScene(int newWidth, int newHeight, QObject *parent) : QGraphicsScene(parent), width(newWidth), height(newHeight), acceptEvents(true)
00023 {
00024
00025
00026 for(int i = 0; i < (2*width*height + width + height); i++)
00027 {
00028 lineList.append(false);
00029 }
00030
00031 spacing = 40;
00032 for(int iWidth = 0; iWidth <= width; iWidth++)
00033 {
00034 for(int iHeight = 0; iHeight <= height; iHeight++)
00035 {
00036 int x = iWidth*spacing;
00037 int y = iHeight*spacing;
00038 QGraphicsEllipseItem *dot = new QGraphicsEllipseItem(QRectF(-2,-2,4,4));
00039 dot->moveBy(x,y);
00040 dot->setBrush(Qt::SolidPattern);
00041 dot->setZValue(20);
00042 addItem(dot);
00043 }
00044 }
00045 QPen feintPen(Qt::DotLine);
00046 feintPen.setWidth(1);
00047 feintPen.setColor(Qt::lightGray);
00048 for(int iWidth = 0; iWidth <= width; iWidth++)
00049 {
00050 addLine(QLineF(spacing*iWidth, 0, spacing*iWidth, spacing*height), feintPen);
00051 }
00052 for(int iHeight = 0; iHeight <= height; iHeight++)
00053 {
00054 addLine(QLineF(0, spacing*iHeight, spacing*width, spacing*iHeight), feintPen);
00055 }
00056
00057 setBackgroundBrush(QBrush(Qt::white));
00058
00059 indicatorLine = new QGraphicsLineItem(1,1,1,1);
00060 indicatorLine->setZValue(10);
00061 indicatorLine->setPen(QPen(Qt::yellow, 2.5));
00062 indicatorLine->hide();
00063 addItem(indicatorLine);
00064
00065 QGraphicsEllipseItem tempItem;
00066 QGraphicsEllipseItemType = tempItem.type();
00067
00068 qreal border = 10;
00069 QRectF rect = sceneRect();
00070 rect.setLeft(rect.left() - border);
00071 rect.setRight(rect.right() + border);
00072 rect.setTop(rect.top() - border);
00073 rect.setBottom(rect.bottom() + border);
00074 setSceneRect(rect);
00075 }
00076
00077 GameBoardScene::~GameBoardScene()
00078 {
00079 kDebug() << "GameBoardScene::~GameBoardScene()";
00080 delete indicatorLine;
00081 }
00082
00083 void GameBoardScene::drawLine(int index, const QColor &colour)
00084 {
00085 QGraphicsLineItem* line = new QGraphicsLineItem(lineFromIndex(index));
00086 line->setZValue(10);
00087 line->setPen(QPen(QBrush(colour), 2.5));
00088 addItem(line);
00089 lineList[index] = true;
00090 indicatorLine->hide();
00091 update(line->boundingRect());
00092 }
00093
00094 void GameBoardScene::highlightLine(int index)
00095 {
00096 HighlightAnimation* anim = new HighlightAnimation(lineFromIndex(index));
00097 anim->setZValue(9);
00098 addItem(anim);
00099 }
00100
00101 void GameBoardScene::drawSquare(int index, const QColor &colour)
00102 {
00103 QBrush brush(colour, Qt::SolidPattern);
00104
00105 addRect(QRectF(qreal((index%width)*spacing), qreal((index/width)*spacing), qreal(spacing), qreal(spacing)), QPen(), brush)->setZValue(-1);
00106 }
00107
00108 int GameBoardScene::indexFromPointPair(const QList<QGraphicsEllipseItem*> &pointPair) const
00109 {
00110
00111 if (pointPair.size() != 2)
00112 return -1;
00113
00114 qreal pointOneX = pointPair.at(0)->scenePos().x()/spacing;
00115 qreal pointOneY = pointPair.at(0)->scenePos().y()/spacing;
00116 qreal pointTwoX = pointPair.at(1)->scenePos().x()/spacing;
00117 qreal pointTwoY = pointPair.at(1)->scenePos().y()/spacing;
00118
00119
00120 qreal refX;
00121 qreal refY;
00122
00123 int index = -1;
00124 if (pointOneX == pointTwoX)
00125 {
00126
00127 refX = pointOneX;
00128 if (pointTwoY < pointOneY)
00129 refY = pointTwoY;
00130 else
00131 refY = pointOneY;
00132 index = static_cast<int>(refY * ((2*width)+1) + refX + width);
00133 }
00134
00135 else if (pointOneY == pointTwoY)
00136 {
00137
00138 refY = pointOneY;
00139 if (pointOneX < pointTwoX)
00140 refX = pointOneX;
00141 else
00142 refX = pointTwoX;
00143 index = static_cast<int>(refY * ((2*width)+1) + refX);
00144 }
00145 return index;
00146 }
00147
00148 QLineF GameBoardScene::lineFromIndex(int index) const
00149 {
00150 int index2 = index % ((2*width) + 1);
00151 enum{HORIZONTAL, VERTICAL} dir;
00152 if(index2 < width)
00153 dir = HORIZONTAL;
00154 else
00155 dir = VERTICAL;
00156
00157 int yCoordStart = (index / ((2*width) + 1)) * spacing;
00158 int xCoordStart = 0;
00159 int yCoordEnd = 0;
00160 int xCoordEnd = 0;
00161 switch(dir)
00162 {
00163 case HORIZONTAL:
00164 xCoordStart = index2 * spacing;
00165 yCoordEnd = yCoordStart;
00166 xCoordEnd = xCoordStart + spacing;
00167 break;
00168 case VERTICAL:
00169 xCoordStart = (index2 - width) * spacing;
00170 yCoordEnd = yCoordStart + spacing;
00171 xCoordEnd = xCoordStart;
00172 break;
00173 }
00174 return QLineF(xCoordStart, yCoordStart, xCoordEnd, yCoordEnd);
00175 }
00176
00177 bool GameBoardScene::isLineAlready(const QList<QGraphicsEllipseItem*> &pointPair) const
00178 {
00179 int index = indexFromPointPair(pointPair);
00180 if (index == -1)
00181 return true;
00182
00183 return lineList.at(index);
00184 }
00185
00186 void GameBoardScene::addLineToIndex(const QList<QGraphicsEllipseItem*> &pointPair)
00187 {
00188 int index = indexFromPointPair(pointPair);
00189 if (index == -1)
00190 return;
00191
00192 emit lineDrawn(index);
00193 }
00194
00195 QList<QGraphicsEllipseItem*> GameBoardScene::getTwoNearestPoints(const QPointF &pos) const
00196 {
00197 QList<QGraphicsItem*> itemList = items();
00198 QList<QGraphicsEllipseItem*> connectList;
00199 for (int i = 0; i < itemList.size(); ++i)
00200 {
00201 if (itemList.at(i)->type() == QGraphicsEllipseItemType)
00202 {
00203
00204 QPointF dist(pos - itemList.at(i)->scenePos());
00205 qreal distMod = sqrt(dist.x()*dist.x() + dist.y()*dist.y());
00206
00207 if (distMod < spacing-5)
00208 {
00209 connectList << qgraphicsitem_cast<QGraphicsEllipseItem*>(itemList.at(i));
00210 }
00211 }
00212 }
00213 return connectList;
00214 }
00215
00216 const QSize GameBoardScene::minimumSizeHint() const
00217 {
00218 return QSize((width*spacing)+10, (height*spacing)+10);
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 void GameBoardScene::mouseReleaseEvent (QGraphicsSceneMouseEvent* mouseEvent)
00228 {
00229 if (!acceptEvents)
00230 {
00231 QGraphicsScene::mouseReleaseEvent(mouseEvent);
00232 return;
00233 }
00234
00235
00236 if (mouseEvent->button() == Qt::LeftButton)
00237 {
00238 QList<QGraphicsEllipseItem*> connectList = getTwoNearestPoints(mouseEvent->scenePos());
00239 if (connectList.size() == 2)
00240 {
00241 if(KGGZMod::Module::instance())
00242 {
00243 int x1 = (qint8)(connectList.at(0)->scenePos().x() / spacing);
00244 int y1 = (qint8)(connectList.at(0)->scenePos().y() / spacing);
00245 int x2 = (qint8)(connectList.at(1)->scenePos().x() / spacing);
00246 int y2 = (qint8)(connectList.at(1)->scenePos().y() / spacing);
00247 emit signalMoveRequest(x1, y1, x2, y2);
00248 }
00249 else
00250 {
00251 addLineToIndex(connectList);
00252 }
00253 }
00254 }
00255
00256 QGraphicsScene::mouseReleaseEvent(mouseEvent);
00257 }
00258
00259 void GameBoardScene::acknowledgeMove(int x1, int y1, int x2, int y2)
00260 {
00261 QPoint calculatedpos(((x1 + x2) / 2.0) * spacing, ((y1 + y2) / 2.0) * spacing);
00262 QList<QGraphicsEllipseItem*> connectList = getTwoNearestPoints(calculatedpos);
00263 addLineToIndex(connectList);
00264 }
00265
00266 void GameBoardScene::mouseMoveEvent (QGraphicsSceneMouseEvent* mouseEvent)
00267 {
00268 if (!acceptEvents) return;
00269
00270
00271
00272
00273
00274 QList<QGraphicsEllipseItem*> connectList = getTwoNearestPoints(mouseEvent->scenePos());
00275
00276 if (connectList.size() == 2 && !isLineAlready(connectList))
00277 {
00278 indicatorLine->setLine(QLineF(connectList.at(0)->scenePos(), connectList.at(1)->scenePos()));
00279 indicatorLine->show();
00280 }
00281 else
00282 {
00283 indicatorLine->hide();
00284 }
00285
00286 QGraphicsScene::mouseMoveEvent(mouseEvent);
00287 }
00288
00289 #include "gameboardscene.moc"