void OnDrawGizmos() { ChaseState chase = GetComponent <ChaseState>(); if (chase != null) { Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(position, chase.boardingDistance); } BoardingState boarding = GetComponent <BoardingState>(); if (boarding != null) { Gizmos.color = Color.magenta; Gizmos.DrawWireSphere(position, boarding.boardRadius); } }
/// <summary> /// Check for being close enough to demand boarding /// </summary> /// <returns>True if close enough</returns> protected virtual bool CheckForBoarding() { Vector3 heading = GetHeadingToTarget(); // Check if lost sight if (heading.magnitude > GetComponent <Crew>().GetSpotDistance()) { GiveUpChase(); } // Check for boarding distance else if (heading.sqrMagnitude <= _boardingDistance * _boardingDistance) { if (BoardingManager.CanDemandBoarding(_ship, _target)) { BoardingState boarding = _controller.ChangeToState <BoardingState>(); boarding.target = _target; } } return(false); }
public override void Update(Vector2 targetSize, GameTime gameTime) { float aspect = targetSize.X / (float)targetSize.Y; ScreenUtils su = new ScreenUtils(targetSize, new Vector2(aspect * 2, 2), 0); Vector2 turretD = su.ScreenToWorld(MouseTracker().Position) - turretPosW; float dstTurretRotation = (float)(-Math.Atan2(-turretD.Y, turretD.X)) + (float)Math.PI * 1.5f; float totalTime = (float)gameTime.TotalGameTime.TotalSeconds; float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; //laserBuffer = laserBuffer + gameTime. // NOTE: this code sucks, but I'm tired if (turretRotation < dstTurretRotation) { turretRotation += 0.5f * elapsedTime; } else { turretRotation -= 0.5f * elapsedTime; } laserBuffer = Math.Min(laserBuffer + elapsedTime * 0.5f, maxLasers); MouseTracker().Update(); if (MouseTracker().WasPressed() && laserBuffer >= 1) { //Vector2 target = su.ScreenToWorld(MouseTracker().Position); Laser laser = new Laser(); laser.Pos = turretPosW; laser.Dir = new Vector2(-(float)Math.Sin(turretRotation), (float)Math.Cos(turretRotation)); //Vector2.Normalize(target - laser.Pos); laser.Length = 0.1f; laser.Speed = 0.05f; friendlyLasers.Add(laser); laserBuffer -= 1; if (boardingState == BoardingState.PREPARED) { boardingState = BoardingState.BOARDING; } } enemyRegion.Position = new Vector2(0.4f * (float)Math.Sin(totalTime * 1.5f), -0.6f + 0.02f * (float)Math.Cos(totalTime * 0.5f)); if (boardingState == BoardingState.PREPARED) { boardingRegion.Position = enemyRegion.Position; } else if (boardingState == BoardingState.BOARDING) { Vector2 d = shipPosW - boardingRegion.Position; d.Normalize(); boardingRegion.Position += d * 0.1f * elapsedTime; } else if (boardingState == BoardingState.DESTROYED) { // TODO: animate this, use acceleration boardingRegion.Acceleration = new Vector2(1, 0); boardingRegion.Velocity = boardingRegion.Acceleration * elapsedTime; boardingRegion.Position += boardingRegion.Velocity; //asset.Velocity = asset.Acceleration * elapsedTime; //asset.Position += su.ScaleToScreen(asset.Velocity); } shipPosW = new Vector2(0.2f * (float)Math.Sin(totalTime), 0.6f + 0.02f * (float)Math.Cos(totalTime * 0.5f)); turretPosW = shipPosW + new Vector2(0.26f, 0.0f); for (int i = 0; i < NUM_STREAKS; i++) { float speed = 2 + (i % 4); float x = -aspect + (float)Math.Cos(i) + speed * totalTime; //20 + 50 * (float)Math.Cos(i); int screenWidths = (int)(x / (2 * aspect)); x = x - screenWidths * (2 * aspect) - aspect; float y = 2 * ((i + 1.0f) / (NUM_STREAKS + 1)) - 1; //+ 30.0f * (float)Math.Sin(i); streaks[i].Position = new Vector2(x, y); streaks[i].Distance = targetSize.X * 0.002f * speed; streaks[i].Thickness = 2; } // remove distant lasers List <Laser> unimpactedLasers = new List <Laser>(); foreach (Laser laser in friendlyLasers) { Vector2 prevPos = laser.Pos; Vector2 newPos = laser.Pos + laser.Dir * laser.Speed; Vector2?enemyImpactPos = enemyRegion.Trace(prevPos, newPos); Vector2?boardingImpactPos = boardingRegion.Trace(prevPos, newPos); float boardingDistance = shipPosW.Y - boardingRegion.Position.Y; if (boardingState == BoardingState.BOARDING && boardingImpactPos != null && boardingDistance > 0.15f) { var explosion = new TextureAnimationAsset(explosionTexture, 3, 5); explosion.Position = su.WorldToScreen(boardingImpactPos.Value); explosion.Acceleration = new Vector2(1, 0); AddChild("explosion_effect", explosion); boardingHealth--; if (boardingHealth == 0) { boardingState = BoardingState.DESTROYED; } } else if (enemyImpactPos != null) { var explosion = new TextureAnimationAsset(explosionTexture, 3, 5); explosion.Position = su.WorldToScreen(enemyImpactPos.Value); explosion.Acceleration = new Vector2(1, 0); AddChild("explosion_effect", explosion); } else if (laser.Pos.Length() < 10) { unimpactedLasers.Add(laser); } laser.Pos = laser.Pos + laser.Dir * laser.Speed; } friendlyLasers = unimpactedLasers; foreach (KeyValuePair <string, Asset> pair in children) { if (typeof(TextureAnimationAsset).IsInstanceOfType(pair.Value)) { TextureAnimationAsset asset = (TextureAnimationAsset)pair.Value; asset.Velocity = asset.Acceleration * elapsedTime; asset.Position += su.ScaleToScreen(asset.Velocity); } } bool isNotFinishedExplosion(Asset asset) { if (typeof(TextureAnimationAsset).IsInstanceOfType(asset)) { TextureAnimationAsset anim = (TextureAnimationAsset)asset; return(!anim.IsFinished()); } return(true); } children = children.FindAll(pair => isNotFinishedExplosion(pair.Value)); }