#include <QDebug>
#include "GameWidget.h"
// 颜色数组 存储每个数字对应的背景色
QColor digitBkg[11] = {QColor::fromRgb(0xEE, 0xE5, 0xDB), QColor::fromRgb(0xEC, 0xE0, 0xC8),
QColor::fromRgb(0xF2, 0xAF, 0x78), QColor::fromRgb(0xEE, 0x8A, 0x54),
QColor::fromRgb(0xFE, 0x76, 0x5E), QColor::fromRgb(0xE7, 0x58, 0xC),
QColor::fromRgb(0xFF, 0x66, 0x66), QColor::fromRgb(0xF1, 0xCF, 0x48),
QColor::fromRgb(0xCC, 0x33, 0x33), QColor::fromRgb(0xE3, 0xB9, 0x11),
QColor::fromRgb(0xFF, 0x00, 0x00)};
// 每个方向位置的增量
QPointF dPos[5] = {QPointF(-10, 0), QPointF(10, 0), QPointF(0, -10), QPointF(0, 10), QPointF(-2, -2)};
GameWidget::GameWidget(QWidget *parent) :
QWidget(parent)
{
// 连接手势移动信号和相应的槽函数
connect(this, SIGNAL(GestureMove(GestureDirect)), SLOT(onGestureMove(GestureDirect)));
// 初始化board数组
memset(board, 0, sizeof(board));
// 随机填入两个2
board[rand() % 4][rand() % 4] = 2;
while(true) {
int x = rand() % 4;
int y = rand() % 4;
if (board[x][y] != 0) {
continue;
}
else {
board[x][y] = 2;
break;
}
}
// 分数初始化为0
score = 0;
// 数码个数初始化为2
digitCount = 2;
isAnimating = false;
cacheImg = NULL;
}
void GameWidget::keyPressEvent(QKeyEvent *event)
{
if (isAnimating)
return;
switch (event->key()) {
case Qt::Key_Left:
emit GestureMove(LEFT);
break;
case Qt::Key_Right:
emit GestureMove(RIGHT);
break;
case Qt::Key_Down:
emit GestureMove(DOWN);
break;
case Qt::Key_Up:
emit GestureMove(UP);
break;
default:
break;
}
QWidget::keyPressEvent(event);
}
void GameWidget::mousePressEvent(QMouseEvent *e)
{
// 获取起点坐标
startPos = e->pos();
}
void GameWidget::mouseReleaseEvent(QMouseEvent *e)
{
// 如果在播放动画效果则直接退出防止重复产生手势事件
if (isAnimating)
return;
// 根据终点坐标和起点坐标计算XY坐标的增量
float dX = (float)(e->pos().x() - startPos.x());
float dY = (float)(e->pos().y() - startPos.y());
// 确定手势方向
if (abs(dX) > abs(dY))
{
if (dX < 0)
emit GestureMove(LEFT);
else
emit GestureMove(RIGHT);
}
else
{
if (dY < 0)
emit GestureMove(UP);
else
emit GestureMove(DOWN);
}
}
void GameWidget::onGestureMove(GestureDirect direct)
{
int i, j, k;
Animation a;
// 是否合并过方格
bool combine = false;
// 处理不同方向
switch (direct)
{
// 向左
case LEFT:
// 循环每一行
for (i = 0; i < 4; i++)
{
/* 初始化j k为0
* 这里j表示要交换的数字列号
* k表示交换到的位置的列号
* */
j = 0, k = 0, combine = false;
while (true)
{
// 循环找到第一个不是0的数字对应的列号
while (j < 4 && board[i][j] == 0)
j++;
// 如果超过了3则说明搜索完毕 推出循环
if (j > 3)
break;
// 交换两个数字
qSwap(board[i][k], board[i][j]);
// 记录动画信息
a.type = MOVE;
a.startPos = QPointF(7 + (w + 5) * j, 7 + (h + 5) * i);
a.endPos = QPointF(7 + (w + 5) * k, 7 + (h + 5) * i);
a.digit = a.digit2 = board[i][k];
a.direct = LEFT;
//如果交换后的数字与其前一列的数字相同
if (!combine && k > 0 && board[i][k] == board[i][k - 1])
{
// 前一列的数字*2
board[i][k - 1] <<= 1;
// 这一列的数字置为0
board[i][k] = 0;
// 记录动画信息
a.digit2 = board[i][k - 1];
a.endPos = QPointF(7 + (w + 5) * (k - 1), 7 + (h + 5) * i);
// 增加分数
score += board[i][k - 1];
// 发射增加分数的信号
emit ScoreInc(score);
// 数码个数-1
digitCount--;
combine = true;
}
else
k++;
j++;
// 添加到动画链表
animationList.append(a);
}
}
break;
// 其余三个方向与左向类似
case RIGHT:
for (i = 0; i < 4; i++)
{
j = 3, k = 3, combine = false;
while (true)
{
while (j > -1 && board[i][j] == 0)
j--;
if (j < 0)
break;
qSwap(board[i][k], board[i][j]);
a.type = MOVE;
a.startPos = QPointF(7 + (w + 5) * j, 7 + (h + 5) * i);
a.endPos = QPointF(7 + (w + 5) * k, 7 + (h + 5) * i);
a.digit = a.digit2 = board[i][k];
a.direct = RIGHT;
if (!combine && k < 3 && board[i][k] == board[i][k + 1])
{
board[i][k + 1] <<= 1;
board[i][k] = 0;
a.digit2 = board[i][k + 1];
a.endPos = QPointF(7 + (w + 5) * (k + 1), 7 + (h + 5) * i);
score += board[i][k + 1];
emit ScoreInc(score);
digitCount--;
combine = true;
}
else
k--;
j--;
animationList.append(a);
}
}
break;
case UP:
for (i = 0; i < 4; i++)
{
j = 0, k = 0, combine = false;
while (true)
{
while (j < 4 && board[j][i] == 0)
j++;
if (j > 3)
break;
qSwap(board[k][i], board[j][i]);
a.type = MOVE;
a.startPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * j);
a.endPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * k);
a.digit = a.digit2 = board[k][i];
a.direct = UP;
if (!combine && k > 0 && board[k][i] == board[k - 1][i])
{
board[k - 1][i] <<= 1;
board[k][i] = 0;
a.digit2 = board[k - 1][i];
a.endPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * (k - 1));
score += board[k - 1][i];
emit ScoreInc(score);
digitCount--;
combine = true;
}
else
k++;
j++;
animationList.append(a);
}
}
break;
case DOWN:
for (i = 0; i < 4; i++)
{
j = 3, k = 3, combine = false;
while (true)
{
while (j > -1 && board[j][i] == 0)
j--;
if (j < 0)
break;
qSwap(board[k][i], board[j][i]);
a.type = MOVE;
a.startPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * j);