300 lines
6.3 KiB
C++
300 lines
6.3 KiB
C++
#include "alien.h"
|
|
|
|
#include <cmath>
|
|
|
|
Alien::Alien(games *parent, float alienspeed)
|
|
{
|
|
game = parent;
|
|
Speed = alienspeed;
|
|
TmpCells = new int*[game->size.width()];
|
|
for (int i = 0; i < game->size.width(); i++)
|
|
TmpCells[i] = new int[game->size.height()];
|
|
position = game->start*game->cellsize;
|
|
path.clear();
|
|
PicIndex = 0;
|
|
RecreatePath();
|
|
}
|
|
|
|
|
|
bool Alien::RecreatePath()
|
|
{
|
|
for (int i = 0; i < game->size.width(); i++)
|
|
{
|
|
for (int j = 0; j < game->size.height(); j++)
|
|
{
|
|
if (game->Cells[i][j] < 0 ) TmpCells[i][j] = -1;
|
|
else TmpCells[i][j] = 0;
|
|
}
|
|
}
|
|
QPointF tp;
|
|
QPoint start;
|
|
QVector<QPoint> srcPath;
|
|
QVector<QPointF> tmpPath;
|
|
PathIndex = 1;
|
|
start.setX(qRound(position.x()/(float)game->cellsize));
|
|
start.setY(qRound(position.y()/(float)game->cellsize));
|
|
srcPath = InvWaveTrace(game->finish,WaveTrace(start,game->finish));
|
|
for (int i=0; i<srcPath.size();i++)
|
|
{
|
|
game->Cells[srcPath.at(i).x()][srcPath.at(i).y()] = 1;
|
|
tmpPath.push_back(QPointF(srcPath.at(i)));
|
|
}
|
|
srcPath.clear();
|
|
//qDebug() << tmpPath.size();
|
|
if (!tmpPath.isEmpty())
|
|
{
|
|
for (int j=0; j<4; j++)
|
|
{
|
|
path.clear();
|
|
tp = tmpPath.at(0);
|
|
path.push_back(tp);
|
|
for (int i = 0; i < tmpPath.size() - 1; i++)
|
|
{
|
|
//if (j > 1) path.push_back(tmpPath[i]);
|
|
tp.setX((tmpPath.at(i).x() + tmpPath.at(i + 1).x()) / 2.0);
|
|
tp.setY((tmpPath.at(i).y() + tmpPath.at(i + 1).y()) / 2.0);
|
|
path.push_back(tp);
|
|
}
|
|
tp = tmpPath.at(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;
|
|
}
|
|
|
|
|
|
bool Alien::update()
|
|
{
|
|
float tmpdx,tmpdy,angl,arctg = 0;
|
|
tmpdx = position.x() - path.at(PathIndex).x()*game->cellsize;
|
|
tmpdy = position.y() - path.at(PathIndex).y()*game->cellsize;
|
|
while (std::sqrt(tmpdx*tmpdx +tmpdy*tmpdy) < 2*Speed*game->cellsize)
|
|
{
|
|
PathIndex++;
|
|
if (PathIndex >= path.size()) return false;
|
|
/*{
|
|
PathIndex = 0;
|
|
position = game->start*game->cellsize;
|
|
}*/
|
|
tmpdx = position.x() - path.at(PathIndex).x()*game->cellsize;
|
|
tmpdy = position.y() - path.at(PathIndex).y()*game->cellsize;
|
|
//qDebug() << "next";
|
|
}
|
|
arctg = std::atan(tmpdx/tmpdy);
|
|
if (tmpdy < 0) arctg=arctg+3.1416f;
|
|
angl = 180.0f*(-arctg)/3.1416f;
|
|
/*if (PathIndex > 1)
|
|
{
|
|
if ((Position.angle-angl < -5 || Position.angle-angl > 5) && angl < 175 && angl > -175)
|
|
{
|
|
if (angl > Position.angle) Position.angle += 5;
|
|
else Position.angle -= 5;
|
|
}
|
|
else Position.angle = angl;
|
|
}
|
|
else*/ angle = angl;
|
|
//qDebug() << "[" << PathIndex << ";" << PicIndex << "]" << "angle:" << Position.angle << "arctg:" << arctg << "Pos:" << Position.pnt;
|
|
position.setX(position.x()
|
|
-Speed*(float)game->cellsize*std::sin(arctg));
|
|
position.setY(position.y()
|
|
-Speed*(float)game->cellsize*std::cos(arctg));
|
|
PicIndex++;
|
|
return true;
|
|
}
|
|
|
|
|
|
int Alien::WaveTrace(QPoint start, QPoint finish)
|
|
{
|
|
bool stop = false;
|
|
int step = 2;
|
|
QPoint cp, tp;
|
|
QRect fr(0, 0, game->size.width(), game->size.height());
|
|
QVector<QPoint> 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.at(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<QPoint> Alien::InvWaveTrace(QPoint finish, int cnt)
|
|
{
|
|
QPoint wp, Ppnt;
|
|
QVector<QPoint> 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 < game->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 < game->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;
|
|
}
|