#include "alien.h" #include Alien::Alien(GameData * AlienData, float alienspeed) { data = AlienData; Speed = alienspeed; TmpCells = new int*[data->size.width()]; for (int i = 0; i < data->size.width(); i++) TmpCells[i] = new int[data->size.height()]; Position.pnt = data->start*data->cellsize; RecreatePath(); } bool Alien::RecreatePath() { for (int i = 0; i < data->size.width(); i++) { for (int j = 0; j < data->size.height(); j++) { if (data->Cells[i][j] < 0 ) TmpCells[i][j] = -1; else TmpCells[i][j] = 0; } } QPointF tp; QPoint start; QVector srcPath; QVector tmpPath; PathIndex = 1; start.setX(qRound(Position.pnt.x()/(float)data->cellsize)); start.setY(qRound(Position.pnt.y()/(float)data->cellsize)); srcPath = InvWaveTrace(data->finish,WaveTrace(start,data->finish)); for (int i=0; iCells[srcPath[i].x()][srcPath[i].y()] = 1; tmpPath.push_back(QPointF(srcPath[i])); } srcPath.clear(); //qDebug() << tmpPath.size(); if (!tmpPath.isEmpty()) { for (int j=0; j<4; j++) { path.clear(); tp = tmpPath[0]; path.push_back(tp); for (int i = 0; i < tmpPath.size() - 1; i++) { tp.setX((tmpPath[i].x() + tmpPath[i + 1].x()) / 2.0); tp.setY((tmpPath[i].y() + tmpPath[i + 1].y()) / 2.0); path.push_back(tp); } tp = tmpPath[tmpPath.size() - 1]; path.push_back(tp); tmpPath = path; } tmpPath.clear(); if (path.size() > 10) { path.remove(1); path.remove(1); path.remove(path.size()-2); path.remove(path.size()-2); } return true; } return false; } void Alien::update() { float tmpdx,tmpdy,angl,arctg = 0; tmpdx = Position.pnt.x() - path[PathIndex].x()*data->cellsize; tmpdy = Position.pnt.y() - path[PathIndex].y()*data->cellsize; while (std::sqrt(tmpdx*tmpdx +tmpdy*tmpdy) < 2*Speed*data->cellsize) { PathIndex++; if (PathIndex >= path.size()) PathIndex = 0; tmpdx = Position.pnt.x() - path[PathIndex].x()*data->cellsize; tmpdy = Position.pnt.y() - path[PathIndex].y()*data->cellsize; //qDebug() << "next"; } arctg = std::atan(tmpdx/tmpdy); if (tmpdy < 0) arctg=arctg+3.1416f; angl = 180.0f*(-arctg)/3.1416f; //if (qAbs(Position.angle-angl) > 10) Position.angle = 5*angl/qAbs(angl); //else Position.angle = angl; //qDebug() << "[" << PathIndex << ";" << PicIndex << "]" << "angle:" << Position.angle << "arctg:" << arctg << "Pos:" << Position.pnt; Position.pnt.setX(Position.pnt.x() -Speed*(float)data->cellsize*std::sin(arctg)); Position.pnt.setY(Position.pnt.y() -Speed*(float)data->cellsize*std::cos(arctg)); PicIndex++; } /*bool Aliens::PathIntersect(Alien* Al, Rectangle rect) { //PathIntersect = False for (int i = Al->PathIndex; i<=Al->path.size(); i++) // To UBound(Al.path(), 1) if (Al->path[i].x + 0.5 >= rect.x0 - 1 && Al->path[i].x + 0.5 <= rect.x1 + 1) if (Al->path[i].y + 0.5 >= rect.y0 - 1 && Al->path[i].y + 0.5 <= rect.y1 + 1) return true; //PathIntersect = True //Exit Function return false; }*/ int Alien::WaveTrace(QPoint start, QPoint finish) { bool stop = false; int step = 2; QPoint cp, tp; QRect fr(0, 0, data->size.width(), data->size.height()); QVector tmpp, curp; cp = start; curp.push_back(cp); TmpCells[cp.x()][cp.y()] = 1; //qDebug() << "trace"; while (!stop) { tmpp = curp; curp.clear(); stop = true; for (int i = 0; i < tmpp.size(); i++) { cp = tmpp[i]; if (cp == finish) { TmpCells[cp.x()][cp.y()] = step; //qDebug() << "trace done!"; return step; } tp.setX(cp.x() - 1); tp.setY(cp.y()); if (fr.contains(tp) && TmpCells[tp.x()][tp.y()] == 0) { TmpCells[tp.x()][tp.y()] = step; curp.push_back(tp); stop = false; } tp.setX(cp.x() + 1); if (fr.contains(tp) && TmpCells[tp.x()][tp.y()] == 0) { TmpCells[tp.x()][tp.y()] = step; curp.push_back(tp); stop = false; } tp.setX(cp.x()); tp.setY(cp.y() - 1); if (fr.contains(tp) && TmpCells[tp.x()][tp.y()] == 0) { TmpCells[tp.x()][tp.y()] = step; curp.push_back(tp); stop = false; } tp.setY(cp.y() + 1); if (fr.contains(tp) && TmpCells[tp.x()][tp.y()] == 0) { TmpCells[tp.x()][tp.y()] = step; curp.push_back(tp); stop = false; } } step++; } qDebug() << "trace false"; return -1; } QVector Alien::InvWaveTrace(QPoint finish, int cnt) { QPoint wp, Ppnt; QVector alpath; if (cnt < 2) return alpath; int Ind, c, xpp, ypp, xnn, ynn; unsigned char chk; Ppnt = wp = finish; xnn=0; xpp=0; ynn=0; ypp=0; cnt--; alpath.push_front(Ppnt); while (cnt > 1) { cnt--; chk = 0; Ind = 0; c = 0; if (wp.x() - 1 >= 0 && TmpCells[wp.x()-1][wp.y()] == cnt) { chk = chk | 0x01; c++; } if (wp.x() + 1 < data->size.width() && TmpCells[wp.x()+1][wp.y()] == cnt) { chk = chk | 0x02; c++; } if (wp.y() - 1 >= 0 && TmpCells[wp.x()][wp.y()-1] == cnt) { chk = chk | 0x04; c++; } if (wp.y() + 1 < data->size.height() && TmpCells[wp.x()][wp.y()+1] == cnt) { chk = chk | 0x08; c++; } if (c == 0 || chk == 0) qDebug() << "ERROR!!!"; if (c > 1) { if ((chk & 0x01)==0x01 && (chk & 0x04)==0x04) { if (xnn <= ynn && Ind == 0){ wp.rx()--; xnn++; if (xnn == ynn) xnn++; Ind = 1; } else if (Ind == 0) { wp.ry()--; ynn++; ynn++; Ind = 1; } } if ((chk & 0x02)==0x02 && (chk & 0x04)==0x04) { if (xpp <= ynn && Ind == 0){ wp.rx()++; xpp++; if (xpp == ynn) xpp++; Ind = 1; } else if (Ind == 0) { wp.ry()--; ynn++; ynn++; Ind = 1; } } if ((chk & 0x01)==0x01 && (chk & 0x08)==0x08) { if (xnn <= ypp && Ind == 0){ wp.rx()--; xnn++; if (xnn == ypp) xnn++; Ind = 1; } else if (Ind == 0) { wp.ry()++; ypp++; ypp++; Ind = 1; } } if ((chk & 0x02)==0x02 && (chk & 0x08)==0x08) { if (xpp <= ypp && Ind == 0){ wp.rx()++; xpp++; if (xpp == ypp) xpp++; Ind = 1; } else if (Ind == 0) { wp.ry()++; ypp++; ypp++; Ind = 1; } } } if (c == 1 || Ind == 0) { xnn=0; xpp=0; ynn=0; ypp=0; if ((chk & 0x01)==0x01) { wp.rx()--; xnn++; } else if ((chk & 0x02)==0x02) { wp.rx()++; xpp++; } else if ((chk & 0x04)==0x04) { wp.ry()--; ynn++; } else if ((chk & 0x08)==0x08) { wp.ry()++; ypp++; } } Ppnt = wp; alpath.push_front(Ppnt); } return alpath; }