/// <summary> /// Updates one of our state structures, using the current inputs to turn /// the tank, and applying the velocity and inertia calculations. This /// method is used directly to update locally controlled tanks, and also /// indirectly to predict the motion of remote tanks. /// </summary> void UpdateState(ref TankState state) { // Gradually turn the tank and turret to face the requested direction. state.TankRotation = TurnToFace(state.TankRotation, tankInput, TankTurnRate); state.TurretRotation = TurnToFace(state.TurretRotation, turretInput, TurretTurnRate); // How close the desired direction is the tank facing? Vector2 tankForward = new Vector2((float)Math.Cos(state.TankRotation), (float)Math.Sin(state.TankRotation)); Vector2 targetForward = new Vector2(tankInput.X, -tankInput.Y); float facingForward = Vector2.Dot(tankForward, targetForward); // If we have finished turning, also start moving forward. if (facingForward > 0) { float speed = facingForward * facingForward * TankSpeed; state.Velocity += tankForward * speed; } // Update the position and velocity. state.Position += state.Velocity; state.Velocity *= TankFriction; // Clamp so the tank cannot drive off the edge of the screen. state.Position = Vector2.Clamp(state.Position, Vector2.Zero, screenSize); }
public void TankVol(string message) { try { tankLbl.Text = message; int val = Convert.ToInt32(message); if (val < 300) { _tankState = TankState.Low; } else if (val >= 300 & val <= 700) { _tankState = TankState.Ok; } else { _tankState = TankState.Overflow; } if (_tankState == TankState.Ok || _tankState == TankState.Overflow) { _acriLightPub.FuelOn(); } } catch (Exception) { // } }
private void DestroyTank() { if (currentState == TankState.destroyed) { return; } currentState = TankState.destroyed; FullStop(); StopTurret(); ClearUnbankedPoints(); explosivo1.transform.position = transform.position; explosivo2.transform.position = transform.position; explosivo1.SetActive(true); explosivo2.SetActive(true); var em = smokeParticleSystem.emission; em.enabled = true; tankExplosion.Play(); destroyTime = DateTime.Now; }
public Task Login(string name, string password) { if (name == "" || password == "") { return(Clients.Caller.SendAsync("LoginError", "Fields can't be empty")); } else if (_context.Users.Where(c => c.Username == name).Count() == 0) { return(Clients.Caller.SendAsync("LoginError", "User Does not exist")); } else { if (_context.Users.Where(c => c.Username == name).First().Password == password) { Player player = _context.Users.Include(p => p.Player).ThenInclude(t => t.Tank).Include(p => p.Player).ThenInclude(t => t.TankState). Where(c => c.Username == name).First().Player; _context.Lobbies.Include(l => l.Players).Where(p => p.Players.Where(pp => pp.Name == player.Name) != null).FirstOrDefault().Players.Remove(player); _context.Players.Where(c => c.Name == name).FirstOrDefault().ConnectionId = Context.ConnectionId; _context.Players.Where(c => c.Name == name).FirstOrDefault().ReadyState = false; TankState state = player.TankState; state.Pos_X = rand.Next(100, 700); _context.SaveChanges(); string playerData = JsonConvert.SerializeObject(_context.Players.Where(c => c.Name == name).FirstOrDefault()); return(Clients.Caller.SendAsync("LoginSuccess", playerData)); } else { return(Clients.Caller.SendAsync("LoginError", "Wrong password")); } } }
public void SetTankState(TankState state) { int color; switch (state) { case TankState.Normal: color = ALCore.NormalState; break; case TankState.Warning: color = ALCore.WarningState; break; case TankState.Alert: color = ALCore.AlertState; break; case TankState.Inactive: color = ALCore.InactiveState; break; default: color = ALCore.NormalState; break; } BackColor = UIHelper.CreateColor(color); }
public Task Register(string name, string password) { if (name == "" || password == "") { return(Clients.Caller.SendAsync("RegisterError", "Fields can't be empty")); } if (_context.Users.Where(c => c.Username == name).Count() == 0) { TankState tankstate = GetRandomTankState(); _context.TankStates.Add(tankstate); Tank tank = new Tank { Chasis_id = 1, Color_id = 1, Trucks_id = 1, Turret_id = 1 }; _context.Tanks.Add(tank); Player player = new Player { ConnectionId = "", Icon = "", Name = name, ReadyState = false, Tank = tank, TankState = tankstate }; _context.Players.Add(player); User user = new User { Username = name, Password = password, Player = player }; _context.Users.Add(user); _context.SaveChanges(); return(Clients.Caller.SendAsync("Registered", "Successful registration")); } else { return(Clients.Caller.SendAsync("RegisterError", "User already exists")); } }
public static bool HandleCollisions(TankState state, TankAppliance appliance, VectorGroup oppos, float elapsed) { var selfBounds = appliance.Bounds .Rotate(appliance.Origin, state.Rotation) .Move(state.Position); var intersected = false; var interections = selfBounds.FindIntersections(oppos); foreach (var((c, d), (a, b)) in interections) { intersected = true; var dir = state.Position.X * (a.Y - b.Y) * state.Position.Y * (b.X - a.X) + (a.X * b.Y - a.Y * b.X); var v = b - a; if (dir == 0) // sorry, that's magic { continue; } var n = new Vector(v.Y, -v.X) * -(dir / MathF.Abs(dir)); // direction to throw body away state.Speed = 0; state.Position += n * 0.05f * elapsed; } return(intersected); }
public override void Update(float deltaTime) { if (Input.IsKeyDown(System.Windows.Forms.Keys.Left)) { movDir = -1; } else if (Input.IsKeyDown(System.Windows.Forms.Keys.Right)) { movDir = 1; } else { movDir = 0; } // Got to the next phase if (Input.IsKeyDown(System.Windows.Forms.Keys.Space)) { Tank mytank = GameplayScene.tankDict[NetworkManager.Instance.myConnId()]; TankState state = mytank.State; state.Pos_X = tank.transform.position.x; state.Pos_Y = tank.transform.position.y; NetworkManager.Instance.SavePos(tank.transform.position); tank.SetPhase(new TankAiming(tank)); } MoveTank(deltaTime); }
private void TankUpdates(TankState cs, IEnumerable <TankState> ens) { currentState = cs; enemiesStates = ens; _isConnected = true; Refresh(); }
public void Reset() { _tm.ToggleThrust(); lastCollisionPos = _initialPos; transform.position = _initialPos; transform.rotation = _initialRot; _rb.velocity = Vector3.zero; _rb.angularVelocity = Vector3.zero; _rb.isKinematic = true; state = TankState.NORMAL; CurrentSpeed = START_ACCEL; SpecialCounter = 0; _rb.constraints = RigidbodyConstraints.None; numCollisions = 0; //For training purposes only. I'm too lazy to do it right. Vector3 rot = transform.rotation.eulerAngles; rot.y = UnityEngine.Random.Range(0, 360); transform.rotation = Quaternion.Euler(rot); StartCoroutine(ResetWait()); }
public override void Load() { TankBuilder builder = new UsaTankBuilder(true); playerTank = builder.Build() as PlayerTank; /*playerTank = new TankBuilder(true) * .SetChassis(0, 0) * .SetTurret(0) * .SetTracks(0) * .Build() as PlayerTank;*/ CreateEntity(playerTank); playerTank.transform.SetPosition(new Vector2(200, 300)); playerTank.StartTurn(); TankState state = new TankState(); state.Pos_X = playerTank.transform.position.x; state.Pos_Y = playerTank.transform.position.y; playerTank.UpdateTankState(state); Tank npcTank = builder.Build(); /*Tank npcTank = new TankBuilder(false) * .SetChassis(1, 1) * .SetTurret(1) * .SetTracks(1) * .Build();*/ CreateEntity(npcTank); npcTank.transform.SetPosition(new Vector2(500, 300)); }
public Task Explode(float x, float y, string lobbyName) { List <Player> connectedPlayers = _context.Lobbies.Include(p => p.Players).ThenInclude(s => s.TankState).Where(l => l.ID == 1).FirstOrDefault().Players.ToList(); //var ts = _context.TankStates.Where(m => ids.Contains(m.ID)); bool death = false; foreach (Player player in connectedPlayers) { TankState tank = player.TankState; int t = circle((int)tank.Pos_X, (int)tank.Pos_Y + 5, (int)x, (int)y, 50, 30); if (t >= 0) { tank.Health = tank.Health - 50; if (tank.Health <= 0) { death = true; } _context.SaveChanges(); Clients.Client(player.ConnectionId).SendAsync("HealthUpdate", tank.Health).Wait(); } } if (death) { Clients.Group(lobbyName).SendAsync("ProjectileExplode").Wait(); return(GameOver(lobbyName)); } else { return(Clients.Group(lobbyName).SendAsync("ProjectileExplode")); } }
public static void Update(TankState state, TankAppliance appliance, PlayerData data, float elapsed) { state.Position += Vector.FromAngle(state.Rotation) * state.Speed * elapsed; if (data.keys.Contains("W")) { state.Speed += (float)(appliance.Acceleration * Math.Cos(Math.PI * (state.Speed / appliance.MaxSpeed) / 2f) * elapsed); } if (data.keys.Contains("S")) { state.Speed = (float)PolyTanks.Helpers.MathF.Max(0, state.Speed - appliance.Acceleration * elapsed); } if (data.keys.Contains("A")) { var movement = appliance.RotationSpeed * elapsed; state.Rotation += movement; state.GunRotation += movement; } if (data.keys.Contains("D")) { var movement = appliance.RotationSpeed * elapsed; state.Rotation -= movement; state.GunRotation -= movement; } state.Loading += 0.5f * elapsed; //gun rotation var target = 0f; if (Math.Abs(data.mouseDir - state.GunRotation) > 180) { if (state.GunRotation > 0) { target = 180; } else if (state.GunRotation < 0) { target = -180; } } else { target = data.mouseDir; } if (state.GunRotation == 180 || state.GunRotation == -180) { state.GunRotation = 179 * Math.Sign(data.mouseDir); } else { state.GunRotation = MathF.Reach(state.GunRotation, target, appliance.TurretSpeed * elapsed); } }
private TankState CreateNewTank() { var go = new TankState(); go.Position = new Vector(0, 0); return(go); }
public void TransitionToState(TankState nextState) { if (nextState != remainState) { currentState = nextState; OnExitState(); } }
private void Instance_HealthUpdated(int obj) { Tank myTank = tankDict[NetworkManager.Instance.myConnId()]; TankState state = myTank.State; state.Health = obj; tank.UpdateTankState(state); }
public override void HitWithBullet(Vector3 position) { gameObject.transform.position -= Vector3.up * 100; gameObject.SetActive(false); ResetStateMachineToIdle(); base.HitWithBullet(position); _tankState = TankState.Disabled; }
public void Destruction() { if (state == TankState.alive) { state = TankState.dead; audioSource.PlayOneShot(tankDestroyedAudio); } }
private IEnumerator CollisionStateHandler() { state = TankState.COLLIDED; CurrentSpeed = START_ACCEL; yield return(new WaitForSeconds(1)); state = TankState.NORMAL; }
public static void Init() { AxolotlState = new AxolotlState(); HungerState = new HungerState(); TankState = new TankState(); FilterState = new FilterState(); TimeKeeper = new TimeKeeper(); Xp = 0; }
public void ChangeState(TankState newTankState) { if (currentState != null) { currentState.OnExitState(); } currentState = newTankState; currentState.OnEnterState(); }
public void SetBall(Ball theBall) { if (currTankState == TankState.EMPTY) { ball = theBall; ball.gameObject.SetActive(false); currTankState = TankState.LOADED; } }
public Task SaveTankPos(float x, float y, int lobbyId) { string lobbyName = "Lobby" + lobbyId; TankState state = _context.Players.Include(t => t.TankState).Where(c => c.ConnectionId == Context.ConnectionId).FirstOrDefault().TankState; state.Pos_X = x; state.Pos_Y = y; _context.SaveChanges(); return(Clients.Group(lobbyName).SendAsync("ReceiveMessage", state.Pos_X.ToString())); }
private IEnumerator BlockRoutine() { state = TankState.BLOCK; SpecialCounter -= Mathf.Clamp(MAX_SPECIAL * .3f, 0, MAX_SPECIAL); yield return(new WaitUntil(BlockPredicate)); state = TankState.NORMAL; _rb.constraints = RigidbodyConstraints.None; }
public void UnsetBall(Ball theBall) { if (currTankState != TankState.EMPTY) { if (theBall == ball) { ball = null; currTankState = TankState.EMPTY; } } }
// Use this for initialization public override void Start() { base.Start(); state = TankState.attacking; characterType = CharacterConstants.CharacterType.enemy; //set our tank's abilities abilityOne = new MoveScript(this); abilityTwo = new BasicAttackScript(this); abilityThree = new PushScript(this); }
/// <summary> /// Moves a locally controlled tank in response to the specified inputs. /// </summary> public void UpdateLocal(Vector2 tankInput, Vector2 turretInput) { this.tankInput = tankInput; this.turretInput = turretInput; // Update the master simulation state. UpdateState(ref simulationState); // Locally controlled tanks have no prediction or smoothing, so we // just copy the simulation state directly into the display state. displayState = simulationState; }
async Task ITank.ResetAsync() { try { TankState s = new TankState(this.Id); await this.SetStateAsync <TankState>(s); } catch (Exception E) { this.Log(E); } }
public void terrainMovement() { if ((tankPosition.X > 190 && tankPosition.X < 468) || (tankPosition.X > 1160 && tankPosition.X < 1260)) { currentTankState = TankState.Downhill; checkAngle2(); tankPic = Game.Content.Load <Texture2D>(@"Images/tankRotated1"); if (keyState.IsKeyDown(Keys.A) || controller.ThumbSticks.Left.X < 0) { if (collideLeft) { if (tankPosition.X > 0) { tankPosition.Y -= 1.2f; } } } } else if ((tankPosition.X > 705 && tankPosition.X < 950) || (tankPosition.X > 1538 && tankPosition.X < 1795)) { currentTankState = TankState.Uphill; checkAngle(); tankPic = Game.Content.Load <Texture2D>(@"Images/tankRotated2"); if (keyState.IsKeyDown(Keys.D) || controller.ThumbSticks.Left.X > 0) { if (collideLeft) { if (tankPosition.X > 0) { tankPosition.Y -= 1.2f; } } } } else { tankPic = Game.Content.Load <Texture2D>(@"Images/tank"); currentTankState = TankState.Normal; } tankRect.Width = tankPic.Width; tankRect.Height = tankPic.Height; tankTextureData = new Color[tankPic.Width * tankPic.Height]; tankPic.GetData(tankTextureData); }
// Use this for initialization void Start() { audioSource = GetComponent <AudioSource> (); rb = GetComponent <Rigidbody2D> (); spriteRenderer = GetComponent <SpriteRenderer> (); CurrentProjectile = ProjectileType.Std; state = TankState.alive; alphaLevel = 1.0f; tFire = 0.0f; angle = Mathf.Deg2Rad * transform.rotation.eulerAngles.z; spriteRenderer.color = new Color(colour.r, colour.g, colour.b, alphaLevel); SetFireDelay(); }
private Direction?DetectCloseIn(TankAction previousAction, TankState previousState, TankState currentState) { if (previousAction == TankAction.TurnLeft || previousAction == TankAction.TurnRight) { return(null); } var closeIn = default(Direction?); var right_closeIn = false; var left_closeIn = false; if (currentState[Direction.Left] < previousState[Direction.Left]) { left_closeIn = true; } if (currentState[Direction.Right] < previousState[Direction.Right]) { right_closeIn = true; } if (right_closeIn && left_closeIn) { if (currentState[Direction.Left] - previousState[Direction.Left] <= currentState[Direction.Right] - previousState[Direction.Right]) { closeIn = Direction.Left; } else { closeIn = Direction.Right; } } else if (left_closeIn) { closeIn = Direction.Left; } else if (right_closeIn) { closeIn = Direction.Right; } if (closeIn.HasValue && currentState[closeIn.Value] == 1) { closeIn = null; } return(closeIn); }
public override void StartTurn() { base.StartTurn(); state = TankState.pushing; //TODO: if tank is next to enemy //push. //otherwise, move and attack /* if(rangeToPlayer <= abilityTwo.range) { state = TankState.pushing; } } else { state = TankState.attacking; } */ }
private Direction? DetectCloseIn(TankAction previousAction, TankState previousState, TankState currentState) { if (previousAction == TankAction.TurnLeft || previousAction == TankAction.TurnRight) { return null; } var closeIn = default(Direction?); var right_closeIn = false; var left_closeIn = false; if (currentState[Direction.Left] < previousState[Direction.Left]) left_closeIn = true; if (currentState[Direction.Right] < previousState[Direction.Right]) right_closeIn = true; if (right_closeIn && left_closeIn) { if (currentState[Direction.Left] - previousState[Direction.Left] <= currentState[Direction.Right] - previousState[Direction.Right]) { closeIn = Direction.Left; } else { closeIn = Direction.Right; } } else if (left_closeIn) { closeIn = Direction.Left; } else if (right_closeIn) { closeIn = Direction.Right; } if (closeIn.HasValue && currentState[closeIn.Value] == 1) closeIn = null; return closeIn; }
public TankAction TakeDecision(TankState state) { var closeIn = default(Direction?); var nextAction = TankAction.Unknown; var previousState = _stateMemory.LastOrDefault(); var previousAction = _actionMemory.Select(x => (TankAction?)x).LastOrDefault(); if (previousState != null && previousAction.HasValue) { closeIn = DetectCloseIn(previousAction.Value, previousState, state); } if (_currentBehavior == null) { if (closeIn.HasValue) { _currentBehavior = new TurnShootTurn(closeIn.Value); } } if (_currentBehavior == null) { nextAction = GetDefaultBehavior().GetNextAction(previousAction); } else { nextAction = _currentBehavior.GetNextAction(previousAction); if (nextAction == TankAction.Unknown) { // the previous behaviour ended _currentBehavior = null; nextAction = GetDefaultBehavior().GetNextAction(previousAction); } } if (nextAction == TankAction.Unknown) { throw new ApplicationException("Tank is at a loss! It doesn't know what to do next!!"); } _stateMemory.Add(state); _actionMemory.Add(nextAction); return nextAction; }
/// <summary> /// /// </summary> public void Print(TankState state) { var points = _tiles.Keys.ToList(); if (!points.Any()) { return; } var minX = points.Min(point => point.X); var maxX = points.Max(point => point.X); var minY = points.Min(point => point.Y); var maxY = points.Max(point => point.Y); var width = Math.Abs(maxX - minX); var height = Math.Abs(maxY - minY); for (var y = maxY; y >= 0; y--) { var builder = new StringBuilder(); for (var x = minX; x < width; x++) { var ch = " "; var point = new Point(x, y); if (point == state.CurrentPosition) { ch = "T"; } else if (_tiles.ContainsKey(point)) { ch = _tileChars[_tiles[point]]; } builder.Append(ch); } Console.WriteLine(builder.ToString()); } }
// Constructors public UserTank(SpriteInfo si, Texture2D gunTexture, TankState ts, SpriteDestroyedHandler handler) : base(si, ts, handler) { this.gunTexture = gunTexture; this.playerIndex = ts.playerIndex; }
// Create functions public static byte CreateTank(TankState state, Dictionary<byte, Tank> tanks) { SpriteInfo si = tankSpriteInfo[state.tankInfo.tankType]; if (state.tankIndex == 0xff) { // Need auto generate tankindex. We don't need to generate tank index // if we are client or loading from a save game. byte r = (byte)TankAGame.Random.Next(200); // Keep trying until we find unique tank index. while (tanks.ContainsKey(r)) { ++r; if (r > 200) r = 0; } state.tankIndex = r; } if (state.playerIndex == 0xff) { // Not a user-controlled tank. Tank t = new Tank(si, state, destroyed); created(t); return state.tankIndex; } // Usertank. UserTank uT = new UserTank(si, gunTextures[state.tankInfo.gunType], state, destroyed); var config = TankAConfig.Instance; if (uT.PlayerIndex == 0) config.userTeam = uT.Team; created(uT); return state.tankIndex; }
public EffectData SelectEffect(int index) { EffectData result = new EffectData(new EffectInfo()); lock (this) { if (index >= 0 && index < _effectList.Count) { _effectList[_activeIndex].Deactivate(); _activeIndex = index; result = GetEffectData(index); _effectList[_activeIndex].Activate(); State = TankState.Running; } } return result; }
/// <summary> /// /// </summary> static TankAPI() { _currentPosition = new Point(0, 0); _currentState = TankState.Current; _currentDirection = Compass.North; }
public static void NewTurn() { _currentState = TankState.Current; _isTurnCompleted = false; }
public void terrainMovement() { if ((tankPosition.X > 190 && tankPosition.X < 468) || (tankPosition.X > 1160 && tankPosition.X < 1260)) { currentTankState = TankState.Downhill; checkAngle2(); tankPic = Game.Content.Load<Texture2D>(@"Images/tankRotated1"); if (keyState.IsKeyDown(Keys.A) || controller.ThumbSticks.Left.X < 0) { if (collideLeft) { if (tankPosition.X > 0) { tankPosition.Y -= 1.2f; } } } } else if ((tankPosition.X > 705 && tankPosition.X < 950) || (tankPosition.X > 1538 && tankPosition.X < 1795)) { currentTankState = TankState.Uphill; checkAngle(); tankPic = Game.Content.Load<Texture2D>(@"Images/tankRotated2"); if (keyState.IsKeyDown(Keys.D) || controller.ThumbSticks.Left.X > 0) { if (collideLeft) { if (tankPosition.X > 0) { tankPosition.Y -= 1.2f; } } } } else { tankPic = Game.Content.Load<Texture2D>(@"Images/tank"); currentTankState = TankState.Normal; } tankRect.Width = tankPic.Width; tankRect.Height = tankPic.Height; tankTextureData = new Color[tankPic.Width * tankPic.Height]; tankPic.GetData(tankTextureData); }
public Tank(TankGame game, Vector2 tankPosition, float turretAngle) : base(game) { this.game = game; this.tankPosition = tankPosition; turretPosition = new Vector2(tankPosition.X + 40, tankPosition.Y + 25); this.turretAngle = turretAngle; health = 200; turnTime = 0; moveLimit = 0; originalTurretDirection = new Vector2(0, 1); turretDirection = new Vector2((float)(Math.Cos(-turretAngle) * originalTurretDirection.X - Math.Sin(-turretAngle) * originalTurretDirection.Y), (float)(Math.Sin(-turretAngle) * originalTurretDirection.X + Math.Cos(-turretAngle) * originalTurretDirection.Y)); bullet = new Bullet(game); type = BulletType.BasicBullet; inventory = new Inventory(game); damageClouds = null; timer = 0.0f; currentTankState = TankState.Normal; }
/// <summary> /// Allows the game component to update itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> /// private void Spawn() { //Vector2 speed = Vector2.Zero; //Vector2 position = Vector2.Zero; TankState ts = new TankState { tankInfo = new TankInfo() { tankType = TankType.Bot1, realSize = new Point(50, 50), gunType = GunType.Gun1, gunDirection = Direction.Down, health = 100, armor = 5, speed = 5, timeBetweenFires = 1000, ammoInfo = new AmmoInfo() { type = AmmoType.Basic, realSize = new Point(0, 0), speed = 10, damage = 30, range = 300 } }, playerIndex = 0xff, tankIndex = 0xff, team = 255, }; ts.position = ict.RandomTankPosition(); Factory.CreateTank(ts, ict.AllTanksInMap()); if (RandomTypeOfBot() == 1) randomPlayerToChase(playerToChase.Count - 1); foreach (Tank t in ict.AllTanksInMap().Values) { indexOfTank.Add(t.TankIndex); timeChange.Add(ResetChangeDirectionTime()); directionOfBot.Add(ChangeDirection()); typeOfBot.Add(RandomTypeOfBot()); } }
public void fireMissile(Projectile newMissile) { if (tankState != TankState.Idle || tankState != TankState.Firing) { //You fired a projectile missile = newMissile; tankState = TankState.Firing; } }
public override void Initialize() { textureName = "Tank"; tankState = TankState.Idle; moveState = TankMovementState.Idle; score = 0; //Set-up Cannon shotAngle = 0; force = 50; contentManager = new ContentManager(Game.Services, "Content"); cannonTexture = contentManager.Load<Texture2D>("Cannon"); cannonLocation = new Vector2((worldPosition.X + 50), (worldPosition.Y + 10)); base.Initialize(); }
/// <summary> /// /// </summary> /// <param name="state"></param> public void UpdateMap(TankState state) { var cardinalMapping = CompassMapping.GetCompassMap(state.CardinalDirection); var directions = new[] { Direction.Front, Direction.Back, Direction.Left, Direction.Right}; foreach (var tankSide in directions) { var isTargetInSight = tankSide == Direction.Front ? (bool?) state.TargetInSight : null; var cardinalDirection = cardinalMapping[tankSide]; _compassMap[cardinalDirection](state.CurrentPosition, isTargetInSight, state[tankSide]); } }
/// <summary> /// Constructs a new Tank instance. /// </summary> public Tank(int gamerIndex, ContentManager content, int screenWidth, int screenHeight) { // Use the gamer index to compute a starting position, so each player // starts in a different place as opposed to all on top of each other. float x = screenWidth / 4 + (gamerIndex % 5) * screenWidth / 8; float y = screenHeight / 4 + (gamerIndex / 5) * screenHeight / 5; simulationState.Position = new Vector2(x, y); simulationState.TankRotation = -MathHelper.PiOver2; simulationState.TurretRotation = -MathHelper.PiOver2; // Initialize all three versions of our state to the same values. previousState = simulationState; displayState = simulationState; // Load textures. tankTexture = content.Load<Texture2D>("Tank"); turretTexture = content.Load<Texture2D>("Turret"); screenSize = new Vector2(screenWidth, screenHeight); }
/// <summary> /// Reads the state of a remotely controlled tank from a network packet. /// </summary> public void ReadNetworkPacket(PacketReader packetReader, GameTime gameTime, TimeSpan latency, bool enablePrediction, bool enableSmoothing) { if (enableSmoothing) { // Start a new smoothing interpolation from our current // state toward this new state we just received. previousState = displayState; currentSmoothing = 1; } else { currentSmoothing = 0; } // Read what time this packet was sent. float packetSendTime = packetReader.ReadSingle(); // Read simulation state from the network packet. simulationState.Position = packetReader.ReadVector2(); simulationState.Velocity = packetReader.ReadVector2(); simulationState.TankRotation = packetReader.ReadSingle(); simulationState.TurretRotation = packetReader.ReadSingle(); // Read remote inputs from the network packet. tankInput = packetReader.ReadVector2(); turretInput = packetReader.ReadVector2(); // Optionally apply prediction to compensate for // how long it took this packet to reach us. if (enablePrediction) { ApplyPrediction(gameTime, latency, packetSendTime); } }
/// <summary> /// Applies prediction and smoothing to a remotely controlled tank. /// </summary> public void UpdateRemote(int framesBetweenPackets, bool enablePrediction) { // Update the smoothing amount, which interpolates from the previous // state toward the current simultation state. The speed of this decay // depends on the number of frames between packets: we want to finish // our smoothing interpolation at the same time the next packet is due. float smoothingDecay = 1.0f / framesBetweenPackets; currentSmoothing -= smoothingDecay; if (currentSmoothing < 0) currentSmoothing = 0; if (enablePrediction) { // Predict how the remote tank will move by updating // our local copy of its simultation state. UpdateState(ref simulationState); // If both smoothing and prediction are active, // also apply prediction to the previous state. if (currentSmoothing > 0) { UpdateState(ref previousState); } } if (currentSmoothing > 0) { // Interpolate the display state gradually from the // previous state to the current simultation state. ApplySmoothing(); } else { // Copy the simulation state directly into the display state. displayState = simulationState; } }