public Vector2D Add(float f) { Vector2D result = new Vector2D(this); result.x += f; result.y += f; return (result); }
public Vector2D Add(Vector2D lhs, Vector2D rhs) { Vector2D result = new Vector2D(lhs); result.x += rhs.x; result.y += rhs.y; return (result); }
public Vector2D Add(Vector2D v) { Vector2D result = new Vector2D(this); result.X += v.X; result.Y += v.Y; return (result); }
public Vector2D Multiply(Vector2D lhs, double rhs) { Vector2D result = new Vector2D(lhs); result.x *= rhs; result.y *= rhs; return (result); }
public Vector2D Multiply(double lhs, Vector2D rhs) { Vector2D result = new Vector2D(rhs); result.x *= lhs; result.y *= lhs; return (result); }
public float Dot(Vector2D v) { return ((float)(x * v.X + y * v.Y)); }
public Vector2D Subtract(Vector2D v) { Vector2D result = new Vector2D(this); result.X -= v.X; result.Y -= v.Y; return (result); }
public Vector2D(Vector2D v) { this.x = v.x; this.y = v.y; }
public Vector2D Subtract(Vector2D lhs, Vector2D rhs) { Vector2D result = new Vector2D(lhs); result.x -= rhs.x; result.y -= rhs.y; return (result); }
public Vector2D Normalize() { float l = Length(); Vector2D result = new Vector2D(this); result.x = result.x / l; result.y = result.y / l; if (double.IsNaN(result.x) || double.IsNaN(result.y)) l = l; return result; }
public Vector2D Multiply(double d) { Vector2D result = new Vector2D(this); result.x *= d; result.y *= d; return (result); }
private MoveResult MoveDiscoids() { if (!started) return null; MoveResult moveResult = new MoveResult() { DiscoidPositions = new List<DiscoidPosition>(), IsTurnOver = false }; //Flag indicating that the program is still calculating //the positions, that is, the balls are still in an inconsistent state. calculatingPositions = true; foreach (Discoid discoid in discoids) { if (Math.Abs(discoid.Position.X) < 5 && Math.Abs(discoid.Position.Y) < 5 && Math.Abs(discoid.TranslateVelocity.X) < 10 && Math.Abs(discoid.TranslateVelocity.Y) < 10) { discoid.Position.X = discoid.Position.Y = 0; discoid.TranslateVelocity = new Vector2D(0, 0); } } bool conflicted = true; //process this loop as long as some balls are still colliding while (conflicted) { conflicted = false; bool someCollision = true; while (someCollision) { foreach (Goal goal in goals) { bool inGoal = goal.IsBallInGoal(ball); } someCollision = false; foreach (Discoid discoidA in discoids) { if (discoidA is Player) { if (!((Player)discoidA).IsPlaying) break; } //Resolve collisions between balls and each of the 6 borders in the table RectangleCollision borderCollision = RectangleCollision.None; foreach (TableBorder tableBorder in tableBorders) { borderCollision = tableBorder.Colliding(discoidA); //if (borderCollision != RectangleCollision.None && !discoidA.IsBallInGoal) if (borderCollision != RectangleCollision.None) { someCollision = true; tableBorder.ResolveCollision(discoidA, borderCollision); } } //Resolve collisions between players foreach (Discoid discoidB in discoids) { if (discoidB is Player) { if (!((Player)discoidB).IsPlaying) break; } if (discoidA != discoidB) { //if (discoidA.Colliding(discoidB) && !discoidA.IsBallInGoal && !discoidB.IsBallInGoal) if (discoidA.Colliding(discoidB)) { if ((discoidA is Player && discoidB is Ball) || (discoidB is Player && discoidA is Ball)) { Player p = null; Ball b = null; if (discoidA is Player) { p = (Player)discoidA; b = (Ball)discoidB; } else { p = (Player)discoidB; b = (Ball)discoidA; } turnEvents.Add(new PlayerToBallContact(currentGame.PlayingTeamID, p, new Point(ball.Position.X, ball.Position.Y))); } else if (discoidA is Player && discoidB is Player) { if ( (((Player)discoidA).Team.TeamID != currentGame.PlayingTeamID) || ((Player)discoidB).Team.TeamID != currentGame.PlayingTeamID) { PlayerToPlayerContact p2p = new PlayerToPlayerContact(currentGame.PlayingTeamID, (Player)discoidA, (Player)discoidB, new Point(discoidA.Position.X, discoidA.Position.Y)); var q = from te in turnEvents where te is PlayerToBallContact where ((PlayerToBallContact)te).Player.Team.TeamID == currentGame.PlayingTeamID select te; if (!q.Any()) { turnEvents.Add(p2p); Player p = null; if (((Player)discoidA).Team.TeamID == currentGame.PlayingTeamID) { p = (Player)discoidA; } else { p = (Player)discoidB; } } } } if (discoidA.Points == 0) { strokenPlayers.Add(discoidB); } else if (discoidB.Points == 0) { strokenPlayers.Add(discoidA); } while (discoidA.Colliding(discoidB)) { someCollision = true; discoidA.ResolveCollision(discoidB); } } } } //Calculate ball's translation velocity (movement) as well as the spin velocity. //The friction coefficient is used to decrease ball's velocity if (discoidA.TranslateVelocity.X != 0.0d || discoidA.TranslateVelocity.Y != 0.0d) { double signalXVelocity = discoidA.TranslateVelocity.X >= 0.0f ? 1.0f : -1.0f; double signalYVelocity = discoidA.TranslateVelocity.Y >= 0.0f ? 1.0f : -1.0f; double absXVelocity = Math.Abs(discoidA.TranslateVelocity.X); double absYVelocity = Math.Abs(discoidA.TranslateVelocity.Y); Vector2D absVelocity = new Vector2D(absXVelocity, absYVelocity); Vector2D normalizedDiff = new Vector2D(absVelocity.X, absVelocity.Y); normalizedDiff.Normalize(); absVelocity.X = absVelocity.X * (1.0f - discoidA.Friction) - normalizedDiff.X * discoidA.Friction; absVelocity.Y = absVelocity.Y * (1.0f - discoidA.Friction) - normalizedDiff.Y * discoidA.Friction; if (absVelocity.X < 0f) absVelocity.X = 0f; if (absVelocity.Y < 0f) absVelocity.Y = 0f; double vx = absVelocity.X * signalXVelocity; double vy = absVelocity.Y * signalYVelocity; if (double.IsNaN(vx)) vx = 0; if (double.IsNaN(vy)) vy = 0; discoidA.TranslateVelocity = new Vector2D(vx, vy); } //Calculate ball's translation velocity (movement) as well as the spin velocity. //The friction coefficient is used to decrease ball's velocity if (discoidA.VSpinVelocity.X != 0.0d || discoidA.VSpinVelocity.Y != 0.0d) { double signalXVelocity = discoidA.VSpinVelocity.X >= 0.0f ? 1.0f : -1.0f; double signalYVelocity = discoidA.VSpinVelocity.Y >= 0.0f ? 1.0f : -1.0f; double absXVelocity = Math.Abs(discoidA.VSpinVelocity.X); double absYVelocity = Math.Abs(discoidA.VSpinVelocity.Y); Vector2D absVelocity = new Vector2D(absXVelocity, absYVelocity); Vector2D normalizedDiff = new Vector2D(absVelocity.X, absVelocity.Y); normalizedDiff.Normalize(); absVelocity.X = absVelocity.X - normalizedDiff.X * discoidA.Friction / 1.2f; absVelocity.Y = absVelocity.Y - normalizedDiff.Y * discoidA.Friction / 1.2f; if (absVelocity.X < 0f) absVelocity.X = 0f; if (absVelocity.Y < 0f) absVelocity.Y = 0f; discoidA.VSpinVelocity = new Vector2D(absVelocity.X * signalXVelocity, absVelocity.Y * signalYVelocity); } } //Calculate the ball position based on both the ball's translation velocity and vertical spin velocity. foreach (Discoid discoid in discoids) { discoid.Position.X += discoid.TranslateVelocity.X + discoid.VSpinVelocity.X; discoid.Position.Y += discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y; } } conflicted = false; } double totalVelocity = 0; foreach (Discoid discoid in discoids) { totalVelocity += discoid.TranslateVelocity.X; totalVelocity += discoid.TranslateVelocity.Y; } calculatingPositions = false; bool isTurnOver = false; if (Math.Abs(totalVelocity) < 0.005 && Math.Abs(lastTotalVelocity) > 0) { totalVelocity = 0; foreach(Discoid d in discoids) { d.TranslateVelocity = new Vector2D(0, 0); } //MoveDiscoids(); //poolState = PoolState.AwaitingShot; if (!goals[0].IsBallInGoal(ball) && !goals[1].IsBallInGoal(ball)) { ball.IsBallInGoal = false; } if (Math.Abs(lastTotalVelocity) > 0 && hasPendingGoalResolution) { //ResetPlayerPositions(currentGame.Teams[currentGame.Team1ID], currentGame.Teams[currentGame.Team2ID], rootCanvas, discoids, goalPost00Point.X, goalPost10Point.X, rowTopEscapeArea.Height.Value, fieldHeight - rowTopEscapeArea.Height.Value); //ball.X = (goalPost00Point.X + goalPost10Point.X) / 2; //ball.Y = (rowTopEscapeArea.Height.Value + fieldHeight - rowTopEscapeArea.Height.Value) / 2; } ProcessAfterTurn(); isTurnOver = true; GameHelper.Instance.IsMovingDiscoids = false; if (scoreControl.Time > totalTime) { Team selectedTeam = currentGame.Team1; currentGame = GetNextGame(selectedTeamID, currentGame.Date); LoadPlayerFaces(); ResetPlayerPositions(currentGame.Teams[currentGame.Team1ID], currentGame.Teams[currentGame.Team2ID], rootCanvas, discoids, goalPost00Point.X, goalPost10Point.X, rowTopEscapeArea.Height.Value, fieldHeight - rowTopEscapeArea.Height.Value); scoreControl.Team1Name = currentGame.Team1ID; scoreControl.Team1Score = currentGame.Scores[currentGame.Team1ID]; scoreControl.Team2Name = currentGame.Team2ID; scoreControl.Team2Score = currentGame.Scores[currentGame.Team2ID]; scoreControl.PlayingTeamID = currentGame.PlayingTeamID; scoreControl.Time = new DateTime(1, 1, 1, 0, 0, 1); ball.ResetPosition(); bf.SetValue(Canvas.LeftProperty, ball.Position.X - ball.Radius); bf.SetValue(Canvas.TopProperty, ball.Position.Y - ball.Radius); } } lastTotalVelocity = totalVelocity; //playerPositionList = GetBallPositionList(); return new MoveResult() { DiscoidPositions = moveResult.DiscoidPositions, IsTurnOver = isTurnOver }; }
void HitPlayer(double x, double y) { if (scoreControl.Time.Minute == 0 && scoreControl.Time.Second == 0) { scoreControl.Time = new DateTime(1, 1, 1, 0, 0, 1); clockTimer.Start(); } GameHelper.Instance.IsMovingDiscoids = true; turnEvents.Clear(); foreach (PlayerFace pf in playerFaces) { pf.UnSelect(); } started = true; double ballStrength = 50; if (currentGame.Team1ID == currentGame.PlayingTeamID) { ballStrength = currentGame.Team1BallStrength; } else { ballStrength = currentGame.Team2BallStrength; } double v = (ballStrength / 100.0) * 30.0; Player selectedPlayer = GameHelper.Instance.CurrentSelectedPlayer; ShowPlayerInfo(selectedPlayer); double dx = x - GameHelper.Instance.CurrentSelectedPlayer.Position.X; double dy = y - GameHelper.Instance.CurrentSelectedPlayer.Position.Y; double h = (float)(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2))); double sin = dy / h; double cos = dx / h; selectedPlayer.IsBallInGoal = false; selectedPlayer.TranslateVelocity = new Vector2D(v * cos, v * sin); Vector2D normalVelocity = new Vector2D(selectedPlayer.TranslateVelocity.X, selectedPlayer.TranslateVelocity.Y); normalVelocity.Normalize(); //Calculates the top spin/back spin velocity, in the same direction as the normal velocity, but in opposite angle double topBottomVelocityRatio = selectedPlayer.TranslateVelocity.Length() * (targetVector.Y / 100.0f); selectedPlayer.VSpinVelocity = new Vector2D(-1.0f * topBottomVelocityRatio * normalVelocity.X, -1.0f * topBottomVelocityRatio * normalVelocity.Y); //xSound defines if the sound is coming from the left or the right double xSound = (double)(selectedPlayer.Position.X - 300.0f) / 300.0f; //CreateSnapshot(GetBallPositionList()); //if (currentGameState != GameState.TestShot) //{ // PlayCue(GameSound.Shot01); //} //Calculates the ball positions as long as there are moving balls //MoveBalls(); fallenBallsProcessed = false; }