void Enemy::easyAI(float angle, sf::Vector2f &playerCoord, Bullet *bullet, sf::RenderWindow *window){ visibleRadius = 400; damage = 2; waitFireTime = 1000; sf::Vector2f distToScreen((window->getSize().x / 2 - window->getSize().x *0.1), (window->getSize().y / 2 - window->getSize().y *0.1)); sf::Vector2f distToPlayer((x - playerCoord.x), (y - playerCoord.y)); if (distToScreen.y < abs(distToPlayer.y)){ if (distToPlayer.y < 0){ //игрок снизу от врага dir = DOWN_2D; currentSpeed = regularSpeed; } if (distToPlayer.y > 0){ //игрок сверху от врага dir = UP_2D; currentSpeed = regularSpeed; } } if (distToScreen.x < abs(distToPlayer.x)){ if (distToPlayer.x < 0){ //игрок справа от врага dir = RIGHT_2D; currentSpeed = regularSpeed; } if (distToPlayer.x > 0){ //игрок слева от врага dir = LEFT_2D; currentSpeed = regularSpeed; } } if (isTryToFind && !isPlayerVisible){ switch (dir)//реализуем поведение в зависимости от направления. (каждая цифра соответствует направлению) { case RIGHT_2D: dx = currentSpeed; dy = 0; break;//по иксу задаем положительную скорость, по игреку зануляем. получаем, что персонаж идет только вправо case LEFT_2D: dx = -currentSpeed; dy = 0; break;//по иксу задаем отрицательную скорость, по игреку зануляем. получается, что персонаж идет только влево case DOWN_2D: dx = 0; dy = currentSpeed; break;//по иксу задаем нулевое значение, по игреку положительное. получается, что персонаж идет только вниз case UP_2D: dx = 0; dy = -currentSpeed; break;//по иксу задаем нулевое значение, по игреку отрицательное. получается, что персонаж идет только вверх } } else { dx = 0; dy = 0; } if ((distToScreen.x > abs(distToPlayer.x)) && (distToScreen.y > abs(distToPlayer.y))) isPlayerVisible = true; else isPlayerVisible = false; if (isPlayerVisible){ if (shotTimer > waitFireTime){ isTryToFind = true; shotTimer = 0; if (ammo > 0) { ammo--; bullet->isMove = true; } }//меняет направление примерно каждые 3 сек sprite.setRotation(angle); } }
bool Bullet::update(Server& s, QList<Unit*>& plrs) { double v = sqrt(vx*vx + vy*vy); double len = v * FRAME_TIME; double ex = x + vx * FRAME_TIME; double ey = y + vy * FRAME_TIME; double vx0=vx/v, vy0=vy/v; int nearest=-1; double nDist=1e200; for(int i=0; i<plrs.size(); ++i) { double px = plrs[i]->x, py = plrs[i]->y; double d; if ((d=distToPlayer(x,y,px,py,vx0,vy0))<nDist && dist(x,y,ex,ey,px,py) < PLAYER_RADIUS) { nearest = i; nDist = d; } } #if 0 Area& a = s.area; int ix=x, iy=y; int idx=vx<0?-1:1, idy=vy<0?-1:1; double x0=x,y0=y; double d2; while((d2=(x-x0)*(x-x0) + (y-y0)*(y-y0)) <= len*len) { if (d2 >= nDist*nDist) { s.hitPlayer(*plrs[nearest], type); return 1; } if (a.blocked(ix,iy)) return 1; int ix2=ix+idx, iy2=iy+idy; double dx = idx<0 ? x-ix : ix2-x; double dy = idy<0 ? y-iy : iy2-y; double xx = dy*fabs(vx0/vy0); double yy = dx*fabs(vy0/vx0); if (yy>dy) { y=idy<0?iy:iy2; iy=iy2; x += vx0*xx; } else { x=idx<0?ix:ix2; ix=ix2; y += vy0*yy; } } if (nDist < len) { s.hitPlayer(*plrs[nearest], type); return 1; } x=ex,y=ey; return 0; #else if (nDist < len) { ex = x + vx0*nDist; ey = y + vy0*nDist; } QPointF p = getWallHitPoint(x,y,ex,ey,s.area); x=p.x(), y=p.y(); if (nDist<len && fabs(x-ex)<1e-3 && fabs(y-ey)<1e-3) { s.bulletHit(plrs[nearest], *this); return 1; } if (fabs(x-ex)>1e-3 || fabs(x-ex)>1e-3) { x -= 1e-3*vx0; y -= 1e-3*vy0; s.bulletHit(0, *this); return 1; } return 0; #endif }