Files
aliendefender/alien.cpp
buull 6a11d7fbcd now this work
but angle isn't slowly
2010-02-06 12:33:21 +03:00

296 lines
6.4 KiB
C++

#include "alien.h"
#include <cmath>
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<QPoint> srcPath;
QVector<QPointF> 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; i<srcPath.size();i++)
{
data->Cells[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<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[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 < 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;
}