/// <summary> /// Funkcja sprawdza czy samolot bedzie mogl trafic rakieta w inny obiekt. /// </summary> /// <param name="plane">Samolot strzelajacy.</param> /// <param name="enemyPlane">Samolot, ktory chemy trafic.</param> /// <returns>Zwraca true jesli moze trafic wrogi samolot; false - w przeciwnym /// przypadku.</returns> /// <author>Michal Ziober</author> public static CollisionDirectionLocation CanHitEnemyPlane(Plane plane, Plane enemyPlane, float tolerance, bool biDirectional) { if (!biDirectional) { if (plane.Direction == Direction.Right && plane.Center.X > enemyPlane.Center.X) { return(CollisionDirectionLocation.NONE); } if (plane.Direction == Direction.Left && plane.Center.X < enemyPlane.Center.X) { return(CollisionDirectionLocation.NONE); } } if (System.Math.Abs(plane.Center.X - enemyPlane.Center.X) < 10 && System.Math.Abs(plane.Center.Y - enemyPlane.Center.Y) < 10) { return(CollisionDirectionLocation.NONE); } if (System.Math.Abs((plane.Center - enemyPlane.Center).EuclidesLength) > ViewRange) { return(CollisionDirectionLocation.NONE); } Quadrangle planeQuad = new Quadrangle(plane.Bounds.Peaks); planeQuad.Move(0, -HeightShift); Line lineA = new Line(planeQuad.Peaks[1], planeQuad.Peaks[2]); for (int i = 0; i < enemyPlane.Bounds.Peaks.Count - 1; i++) { PointD start = enemyPlane.Bounds.Peaks[i]; start += new PointD(Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f), Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f)); PointD finish = enemyPlane.Bounds.Peaks[i + 1]; finish += new PointD(Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f), Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f)); Line lineB = new Line(start, finish); PointD cut = lineA.Intersect(lineB); if (cut == null) { continue; } if ((enemyPlane.Center - cut).EuclidesLength < HitShift) { //ViewHelper.AttachCross(plane.Level.Controller.GetFramework().SceneMgr, cut, 10); //return true; return((plane.Direction == Direction.Right && plane.Center.X > enemyPlane.Center.X || plane.Direction == Direction.Left && plane.Center.X < enemyPlane.Center.X) ? CollisionDirectionLocation.BACKWARD : CollisionDirectionLocation.FORWARD); } } return(CollisionDirectionLocation.NONE); }
/// <summary> /// Zmienia pozycje rakiety. /// </summary> /// <param name="time">Czas od ostatniego przesuniecia.</param> /// <author>Michal Ziober</author> protected virtual void ChangePosition(int time) { float coefficient = Mathematics.GetMoveFactor(time, MoveInterval); timeCounter += time; if (timeCounter <= dropTime) //swobodne spadanie { PointD vector = new PointD(moveVector.X * coefficient * 6, moveVector.Y * coefficient); boundRectangle.Move(vector); } else //naped silnikowy { // Console.WriteLine(flyVector.X); float minFlyingSpeed = Owner.IsEnemy ? GameConsts.EnemyFighter.Singleton.RangeFastWheelingMaxSpeed * GameConsts.EnemyFighter.Singleton.MaxSpeed : GameConsts.GenericPlane.CurrentUserPlane.RangeFastWheelingMaxSpeed * GameConsts.GenericPlane.CurrentUserPlane.MaxSpeed; // rakieta wytraca prędkość uzyskaną od samolotu if (Math.Abs(flyVector.X) > Math.Abs(minFlyingSpeed * GameConsts.Rocket.BaseSpeed)) { flyVector.X *= 0.995f; } if (Math.Abs(flyVector.Y) > Math.Abs(minFlyingSpeed * GameConsts.Rocket.BaseSpeed)) { flyVector.Y *= 0.995f; } float angle = zRotationPerSecond * coefficient; // boundRectangle.Rotate(angle); // moveVector.Rotate(PointD.ZERO, angle); relativeAngle += angle * (int)Direction; flyVector.Rotate(PointD.ZERO, angle); PointD vector = new PointD(flyVector.X * coefficient, flyVector.Y * coefficient); boundRectangle.Move(vector); travelledDistance += vector.EuclidesLength; } }
/// <summary> /// Ustawia kat dzialka. /// </summary> /// <author>Michal Ziober</author> protected virtual void SetAngle(int time) { float interval = refToLevel.UserPlane.Center.X; if (horizon != null) { interval -= horizon.Center.X + GetGunXShift(); } //pionowo nad ziemia if (interval == 0) { angle = NinetyDegree; } float evaluateAngle = 0; if (interval < 0) { evaluateAngle = Math.PI - Math.ATan(refToLevel.UserPlane.Center.Y / Math.Abs(interval)).ValueRadians; } else { evaluateAngle = Math.ATan(refToLevel.UserPlane.Center.Y / interval).ValueRadians; } //Ustawiam kat. angle = System.Math.Min(MaxAngle, System.Math.Max(evaluateAngle, MinAngle)); // Console.WriteLine("Kat:" +angle+ " "+(angle / (Math.PI))); //Ustawiam kat reflectora if (UsingReflector) { SetReflectorAngle(time); } }
/* public static bool CanHitObjectByGun(IObject2D owner, IObject2D target) * { * return CanHitObjectByGun(owner, target, 0); * } * public static bool CanHitObjectByGun(IObject2D owner, IObject2D target, float tolerance) * { * return CanHitObjectByGun(owner, target, tolerance, false); * }*/ /// <summary> /// Funkcja sprawdza czy samolot bedzie mogl trafic dzialkiem w inny obiekt. /// </summary> /// <param name="owner">Samolot strzelajacy.</param> /// <param name="target">Samolot do ktorego strzelaja.</param> /// <param name="tolerance">Tolerancja. 0 - oznacza pewne trafienie.</param> /// <returns>Zwraca true jesli moze trafic wrogi samolot; false - w przeciwnym /// przypadku.</returns> /// <author>Michal Ziober</author> public static bool CanHitObjectByGun(IObject2D owner, IObject2D target, float tolerance, bool biDirectional) { // UWAGA: Zakladamy ze if (!biDirectional) { Direction gunDirection = owner.MovementVector.X > 0 ? Direction.Right : Direction.Left; // Console.WriteLine( (int)owner.Direction * (owner.Bounds.Peaks[2].X - owner.Bounds.Peaks[1].X)); if (gunDirection == Direction.Right && owner.Center.X > target.Center.X) { return(false); } if (gunDirection == Direction.Left && owner.Center.X < target.Center.X) { return(false); } } /* if (System.Math.Abs(owner.Center.X - target.Center.X) < 10 && * System.Math.Abs(owner.Center.Y - target.Center.Y) < 10) * return false; */ /* * if ((owner.Bounds.Center - target.Bounds.Center).EuclidesLength > Math.Sqrt(RangeX * RangeX + RangeY * RangeY)) * { * return false; * } * */ Quadrangle ownerBound = owner.Bounds; Quadrangle targetBound = target.Bounds; Line lineA = new Line(ownerBound.Peaks[1], ownerBound.Peaks[2]); for (int i = 0; i < targetBound.Peaks.Count - 1; i++) { PointD start = targetBound.Peaks[i]; start += new PointD(Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f), Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f)); PointD finish = targetBound.Peaks[i + 1]; finish += new PointD(Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f), Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f)); Line lineB = new Line(start, finish); PointD cut = lineA.Intersect(lineB); if (cut == null) { continue; } if (IsCutInRange(cut, target)) { return(true); } } return(false); }
/// <summary> /// Sprawdza kolizje z ziemia. /// </summary> /// <param name="planeBound">Prostokat opisujacy samolot.</param> /// <param name="position">Pozycja samolotu.</param> /// <param name="direction">Kierunek lotu samolotu</param> /// <returns>Zwraca punkt zderzenia pocisku z nawierzchnia.</returns> /// <author>Adam Witczak</author> public PointD GetHitPosition(Quadrangle planeBound, PointD position, Direction direction) { // czy trafienie bedzie po prawej od samolotu czy po lewej Direction hitDirection; if (Math.Abs(planeBound.Angle) < Mogre.Math.HALF_PI) { hitDirection = Direction.Left; } else { hitDirection = Direction.Right; } if (direction == Direction.Right) { if (hitDirection == Direction.Left) { hitDirection = Direction.Right; } else { hitDirection = Direction.Left; } } LevelTile tile; int startIndex; int maxIndex; if (hitDirection == Direction.Left) { maxIndex = GetStartIndex(position.X); startIndex = System.Math.Max(0, maxIndex - 12); } else { startIndex = GetStartIndex(position.X); maxIndex = startIndex + 12; } for (int i = startIndex; i < maxIndex && i < referenceToLevel.LevelTiles.Count; i++) { // przeszukaj 12 tile'ów do przodu tile = referenceToLevel.LevelTiles[i]; if (tile.HitBound != null) { Line lineA = new Line(tile.HitBound.Peaks[1], tile.HitBound.Peaks[2]); Line lineB = new Line(planeBound.Peaks[0], planeBound.Peaks[3]); PointD cut = lineA.Intersect(lineB); if (cut == null) { continue; } if (cut.X > tile.HitBound.Peaks[2].X || cut.X < tile.HitBound.Peaks[1].X) { continue; // sytuacja gdy samolot strzela dalej, za tile'em (czyli de facto kula uderzy³aby gdzies dalej mimo ze jest 'intersection' z prost¹) } if (IsCutInRangeX(cut, planeBound.Center)) { return(cut); } } } return(null); }
/// <summary> /// Prowadzi ostrzal samolotu. /// </summary> /// <author>Michal Ziober</author> public virtual void Fire(int time) { if (!IsDestroyed && UserPlaneNotYetDestroyed) { if (HasRockets) { if (ShouldFire && CanFire) { // rakiety gotowe. zaczynamy liczyc czas if (volleyCount == maxVolleyCount) { preparingToVolleyTime += time; } if (preparingToVolleyTime >= volleyPrepareDelay) { if (volleyCount > 0) { preparingToNextMissileTime += time; if (preparingToNextMissileTime > volleyPrepareDelay * 0.1f) { // strzal PointD dir = refToLevel.UserPlane.Position - Center; dir.Normalise(); bool inView = (dir.Angle > Math.PI * 0.5f - Math.PI * 0.3f && dir.Angle < Math.PI * 0.5f + Math.PI * 0.3f); if (inView) { float dist = refToLevel.UserPlane.DistanceToClosestEnemyPlane(); if (dist > valleyFireDistance / 2.0) { // strzelaj tak zeby nie rozwalic samolotow japonskich PointD moveVector = GameConsts.Rocket.BaseSpeed * RocketSpeedMultiplier * dir; dir.X *= (moveVector.X >= 0) ? 1.0f : -1.0f; float relative = dir.Angle + Math.RangeRandom(-0.1f * Math.PI, 0.1f * Math.PI); Rocket rocket = Weapon.RocketFire(relative, moveVector, bazookaRotationPerSecond); rocket.MaxDistanceToOwner *= RocketDistanceMultiplier * Mathematics.RangeRandom(0.8f, 1.2f); rocket.MaxHeightDistanceToOwner *= RocketDistanceMultiplier * Mathematics.RangeRandom(0.8f, 1.2f); volleyCount--; preparingToNextMissileTime = 0; } } } } else { volleyCount = maxVolleyCount; preparingToVolleyTime = 0; } } } } } }