bool QTDTower::rotateTo(QTDUnit *unit, qint64 time)
{
// если обновление произошло слишком быстро,
// пропускаем ход
qint64 elapsed = time - m_lastTime;
if(!elapsed)
return false;
m_lastTime = time;
QPointF unitCenterPos = unit->centerPos();
QPointF thisCenterPos = centerPos();
QPointF diff = unitCenterPos - thisCenterPos;
// новый угол поворота
qreal angle = qAtan2(diff.y(), diff.x()) * (180/M_PI);
// скорость поворота
qreal delta = m_rotationSpeed * elapsed/1000.0f;
// выгодное направление поворота
qint8 disp = 1;
if(angle > rotation())
if(angle - rotation() > 180) disp = -1;
else disp = 1;
else
if(rotation() > angle)
if(rotation() - angle > 180) disp = 1;
else disp = -1;
qreal newRotation = rotation() + delta * disp;
// предотвращаем "переповорот" (сглаживание)
if((newRotation < 0 && newRotation < angle)
|| (newRotation > 0 && newRotation > angle))
newRotation = angle;
// фиксируем диапазон
if(newRotation > 180) newRotation = (360 - newRotation) * -1;
else if(newRotation < -180) newRotation = (360 + newRotation);
// рассчитываем оставшийся угол поворота
qreal adiff = newRotation - angle;
if (adiff < 0) adiff += 360;
if (adiff > 180) adiff = -(360 - adiff);
// поворачиваем
setRotation(newRotation);
// если оставшийся угол удовлетворяет углу атаки
// (например от 0 до 20 градусов), то можно стрелять
return qAbs(adiff) < m_attackAngle;
}
property var mapObjects: [
{ "row": 4, "col": 2, "wsize": 1, "hsize": 1, "wpos": 0, "hpos": 0,
"source": "qrc:/tiles/002-000-00.png", "width": 500, "height": 373 },
{ "row": 4, "col": 2, "wsize": 2, "hsize": 2, "wpos": 1, "hpos": 1,
"source": "qrc:/tiles/001-001-00.png", "width": 2079, "height": 3249 }, // tree
{ "row": 4, "col": 3, "wsize": 2, "hsize": 2, "wpos": 1, "hpos": 1,
"source": "qrc:/tiles/001-002-00.png", "width": 1100, "height": 823 }, // tree
{ "row": 4, "col": 2, "wsize": 1, "hsize": 1, "wpos": 1, "hpos": 1,
"source": "qrc:/tiles/002-000-00.png", "width": 500, "height": 373 },
{ "row": 4, "col": 3, "wsize": 1, "hsize": 1, "wpos": 1, "hpos": 0,
"source": "qrc:/tiles/002-000-00.png", "width": 500, "height": 373 },
{ "row": 4, "col": 3, "wsize": 1, "hsize": 1, "wpos": 1, "hpos": 1,
"source": "qrc:/tiles/002-000-00.png", "width": 500, "height": 373 },
]
function createMapObjects() {
mapObjects.map(function(tileInfo) {
// нормализация размера создаваемого тайла
var tile_w = tileWidth * tileInfo.wsize / cellDivider
var tile_h = tileWidth/tileInfo.width * tileInfo.height * tileInfo.hsize / cellDivider
// левая верхняя координата описывающего клетку прямоугольника
var tile_sx = (map.width/2 + tileInfo.col*tileWidth/2 - tileInfo.row*tileWidth/2 - tileWidth/2)
var tile_sy = (tileInfo.row*tileHeight/2 + tileInfo.col*tileHeight/2) - tile_h
// координата создаваемого тайла
var tile_x = tile_sx + tileWidth/cellDivider * tileInfo.wsize/cellDivider
+ (tileWidth/cellDivider * tileInfo.wsize/cellDivider * tileInfo.wpos) * (cellDivider - tileInfo.wsize)
- (tileHeight/cellDivider * tileInfo.hsize * tileInfo.hpos)
var tile_y = tile_sy + tileHeight/cellDivider * tileInfo.hsize/cellDivider
+ (tileHeight/cellDivider * tileInfo.hsize/cellDivider * tileInfo.hpos) * (cellDivider - tileInfo.hsize)
+ (tileHeight/cellDivider * tileInfo.wsize/cellDivider * tileInfo.wpos) * (cellDivider - tileInfo.wsize)
})
}
// псевдокод
frontPoint.x = cos ( body->rotation * PI / 180 ) * body->centerX() + body->width() / 2;
frontPoint.y = sin ( body->rotation * PI / 180 ) * body->centerY() + body->height() / 2;
rearPoint.x = cos ( body->rotation * PI / 180 ) * body->centerX() - body->width() / 2;
rearPoint.y = sin ( body->rotation * PI / 180 ) * body->centerY() - body->height() / 2;
// реализация на Qt
qint16 angle = qRound(body->rotation());
qint16 newFrontY, newRearY, newFrontX, newRearX;
if(angle == 0 || qAbs(angle) == 180) {
newFrontY = qFloor((newY - body->height()/2.1) / mCellSize);
newRearY = qFloor((newY + body->height()/2.1) / mCellSize);
}
else {
newFrontY = qAbs(qSin(angle * PI_DIFF_180) * newY - body->height()/2.1) / mCellSize;
newRearY = qAbs(qSin(angle * PI_DIFF_180) * newY + body->height()/2.1) / mCellSize;
}
if(qAbs(angle) == 90 || qAbs(angle) == 270) {
newFrontX = qFloor((newX - body->width()/2.1) / mCellSize);
newRearX = qFloor((newX + body->width()/2.1) / mCellSize);
}
else {
newFrontX = qAbs(qCos(angle * PI_DIFF_180) * newX - body->width()/2.1) / mCellSize;
newRearX = qAbs(qCos(angle * PI_DIFF_180) * newX + body->width()/2.1) / mCellSize;
}