Obstacle collisons pt. 5, Solving collisions

Having info that there is collision between two objects there is nothing more left but solving the collision. What I want to do is to move object away so that there is no longer a collision, and to do this by doing as little movement of objects as possible. So Rather than having info that collision happened, I need to have info what kind of collision happened – in what axis objects collided and how much of objects are colliding. This is exactly the same thing I did in circle-circle collision, just way more generic case.

High level implementation should do something like this: find collision displacement (axis and collision size) and move object along this axis (it should point out of the object) by the size of collision – this will put game object outside of obstacle boundaries.

private void CalculateCollisions(IGameObject o1)
{
    foreach (var obstacle in Obstacles)
    {
        var collisionDisplacement = ObstacleCollide(obstacle, o1);
        if (collisionDisplacement != null)
        {
            // Item1 - axis unit vector, Item2 collision size
            var collisionFix = collisionDisplacement.Item1.Scale(collisionDisplacement.Item2);
            o1.Position = o1.Position.Add(collisionFix);
        }
    }
}

This means I have to update my collision detection code. I am storing smallest collision values in variable and updating it whenever I find collision with smaller size then previously found. Still in case of finding out that there is no collision, code quits quickly and returns null.

private Tuple<Vector2d, double> ObstacleCollide(Obstacle obstacle, IGameObject gameObject)
{
    var smallestDisplacement = Tuple.Create(new Vector2d(0, 0), new Range(double.MinValue, double.MaxValue));

    foreach (var axisVector in GetAxisVectors(obstacle, gameObject))
    {
        var obstacleProjection = ProjectOntoAxis(axisVector, obstacle);
        var objectProjection = ProjectOntoAxis(axisVector, gameObject);

        var intersectionRange = obstacleProjection.Intersect(objectProjection);

        if (intersectionRange.Length < 0.0001)
            return null;

        if (intersectionRange.Length < smallestDisplacement.Item2.Length)
            smallestDisplacement = Tuple.Create(axisVector, intersectionRange);
    }

    return Tuple.Create(smallestDisplacement.Item1, smallestDisplacement.Item2.Length);
}

That should be it. And, to my surprise, it works. Well, at least it works for some sides of the object. Those that are most to the left and top. Why is that? Well, this obstacle I’m testing my code with is rectangle. This means there are parallel sides which in turn share the same normal axis (just with different sign, so on may point upward, while the second one will point downward). When creating axis vector it is converted into unit vector and this means it starts in point (0, 0). That is OK for detecting collisions, but since those axes may differ only in sign, it means that intersection size will be the same for both of them! True – ranges themlseves will be different, but length of intersection, used to verify if collison is smaller or larger at this axis, will be the same so the code will find first axis with collision (for example the top one), record that it has collision size for example 1 and then move to the right and finally bottom side (I’m building my polygons so that points are ordered clockwise). But since bottom side also has collison size of 1 collision axis will not get updated even though player comes from the bottom side of the rectangle. This means algorithm will try to push player to the top a little bit, actually pushing player inside obstacle, not outside! And this will repeat for every frame until object is ejected either from top of rectangle or from the sides (left side to be precise) if rectangle happens to be higher than wider.

This cannot stay that way. So to fix this I had to figure out where the mistake is. And after a while I got it – I cannot look just at the size of collision, but rather at distance of collision from beginning of obstacle’s side. Or, to put it in other words, I have to adjust intersection range by how far the side is, not keep it from axis origin (point 0, 0). How far is side form axes origin? Well, it is exactly axis dotProduct sideOriginPoint away!

Little update to my axis generator. Now it returns axis and numeric value saying how far polygon side is form 0,0 point. And this is how much I have to move my intersection region.

private IEnumerable<Tuple<Vector2d, double>> GetAxisVectors(Obstacle obstacle, IGameObject gameObject)
{
    var prevPoint = obstacle.Points[0];

    for (int i = 1; i <= obstacle.Points.Length; i++)
    {
        var currentPoint = obstacle.Points[i % obstacle.Points.Length];
        var sideVector = currentPoint.Subtract(prevPoint);
        var axisVector = sideVector.Unit().Normal();
        var displacementFromOrigin = axisVector.DotProduct(prevPoint);
        yield return Tuple.Create(axisVector, -displacementFromOrigin);
        prevPoint = currentPoint;
    }

    for (int i = 0; i < obstacle.Points.Length; i++)
    {
        var circleToPointVector = gameObject.Position.Subtract(obstacle.Points[i]).Unit();
        var displacementFromOrigin = circleToPointVector.DotProduct(obstacle.Points[i]);
        yield return Tuple.Create(circleToPointVector, -displacementFromOrigin);
    }
}

And finally adding logic to find smallest collision size possible, and in case sizes are the same, to find the one closer to the origin of the side (closer to the side itself):

private Tuple<Vector2d, double> ObstacleCollide(Obstacle obstacle, IGameObject gameObject)
{
    var smallestDisplacement = Tuple.Create(new Vector2d(0, 0), new Range(double.MinValue, double.MaxValue));

    foreach (var axisVector in GetAxisVectors(obstacle, gameObject))
    {
        var obstacleProjection = ProjectOntoAxis(axisVector.Item1, obstacle);
        var objectProjection = ProjectOntoAxis(axisVector.Item1, gameObject);

        var intersectionRange = obstacleProjection.Intersect(objectProjection);
        intersectionRange = intersectionRange.Add(axisVector.Item2);

        if (intersectionRange.Length < 0.0001)
            return null;

        if (intersectionRange.Length < smallestDisplacement.Item2.Length ||
            (Math.Abs(intersectionRange.Length - smallestDisplacement.Item2.Length) < 0.0001 && Math.Abs(intersectionRange.Start) < Math.Abs(smallestDisplacement.Item2.Start)))
            smallestDisplacement = Tuple.Create(axisVector.Item1, intersectionRange);
    }

    return Tuple.Create(smallestDisplacement.Item1, smallestDisplacement.Item2.Length);
}

The if condition seems bit large, but it is pretty simple: if collision size is smaller than the smallest one found until now – we have new smallest collison. But if it happenes to be the same (comparing doubles with small tolerance) – check if new collision intersection happens to be closer to axis origin, and if so – update smallest collision.

And now it works for all sides of the rectangle, never letting player inside obstacle.

circle to corner collision

Obstacle Collision pt 4 SAT corner cases

Last part finished with Separate Axis Theorem implemented for collisions between polygon and circle, with one exception left: when circle is next to one of the corners of polygon, it may produce false collisions.

False collision with SAT

False collision with SAT

To fix this there is only one way – check more axes. After all there has to be one that gives some distance between objects’ projections, if theory is correct. I’ve checked all reasonable axes form polygon object, but none of the potential axes of the circle. Problem is – circles, being as cools as they are, have infinite corners, so checking every axis based on “sides” of circle, so to say, is time consuming. But – we can get more clever than that! The circle is not colliding with polygon if there is space between circle and polygon sides (that was checked by polygon axes) and if every corner of polygon is outside of circle. Hmm, how about I check every corner’s position? That would do, but that wouldn’t be SAT to be precise. But What if I checked every axis build between circle’s center point and polygon corner? Well, there would certainly have to be some space if there is no collision!

circle to corner collision

circle to corner collision

What about the code? The difference is impressively small!

private bool ObstacleCollide(Obstacle obstacle, IGameObject gameObject)
{
    var prevPoint = obstacle.Points[0];

    foreach (var axisVector in GetAxisVectors(obstacle, gameObject))
    {
        var obstacleProjection = ProjectOntoAxis(axisVector, obstacle);
        var objectProjection = ProjectOntoAxis(axisVector, gameObject);

        var intersectionRange = obstacleProjection.Intersect(objectProjection);

        if (intersectionRange.Length < 0.0001)
            return false;
    }

    return true;
}

private IEnumerable<Vector2d> GetAxisVectors(Obstacle obstacle, IGameObject gameObject)
{
    var prevPoint = obstacle.Points[0];

    for (int i = 1; i < obstacle.Points.Length; i++)
    {
        var currentPoint = obstacle.Points[i];
        var sideVector = currentPoint.Subtract(prevPoint);
        yield return sideVector.Unit().Normal();
    }

    for (int i = 0; i < obstacle.Points.Length; i++)
    {
        var circleToPointVector = gameObject.Position.Subtract(obstacle.Points[i]);
        yield return circleToPointVector.Unit();
    }
}

So what I did is moved the axes extraction to separate method. In main method I can now just iterate over all possible axes that are returned from specialized piece of code that knows exactly what axes I have to check. In this method I first return all the usual cases for polygon sides, and later on, if all polygon axes reported collision, I build axes between every corner of polygon and circle center. Notice that there is no normalisation step involved in here – axis produced this way is already oriented correctly and will be perpendicular to posisbly separating line between two objects, like I want.

One possible optimisation here would be to just check one corner – the closes one to the circle. If this corner reports no collision – we’re good to go. If it reports collision, it must be because it lies inside the circle so the collision is definite and there is no point in checking other corners.

So there it is. SAT implemented. But system does not react to obstacle collisions at all. I will know what to do about this by the time I write next post, I hope!

Newton's cradle

Obstacle collisions pt 3 SAT implementation

In previous I’ve introduced the idea of separating axis theorem and how it is useful to find out if two objects collide. Today I will show the code, the interesting bits. You will be surprised how easy and neat it looks!

First high level – go through all obstacles and check with which my game object collides.

private void CalculateCollisions(IGameObject o1)
{
    foreach (var obstacle in Obstacles)
    {
        if (ObstacleCollide(obstacle, o1))
        {
            // handle collision
        }
    }
}

Then, for each object, check every possible side of obstacle and see if there is an intersection between obstacle projection onto normal axis for this side, and game object projection to onto tis axis. As you can see, my object representation is list of points, not sides, so I have to build side vector. Obvious optimization would be to just hold objects’s sides, not points, but points are good for now. Also see, that if there is any axis found where there is no intersection (common range of projections is less than small number I picked; remember those are doubles and hence may not always get precise values in decimal system we are used to so never compare two doubles by simple == if you want to avoid bugs) I escape collision checking at once – since there is an axis that objects do not have overlapping projections there is no collision happening for sure and I can save few microseconds by not checking remaining sides.

private bool ObstacleCollide(Obstacle obstacle, IGameObject gameObject)
{
    var prevPoint = obstacle.Points[0];

    for (int i = 1; i < obstacle.Points.Length; i++)
    {
        var currentPoint = obstacle.Points[i];
        var sideVector = currentPoint.Subtract(prevPoint);
        var axisVector = sideVector.Unit().Normal();

        var obstacleProjection = ProjectOntoAxis(axisVector, obstacle);
        var objectProjection = ProjectOntoAxis(axisVector, gameObject);

        var intersectionRange = obstacleProjection.Intersect(objectProjection);

        if (intersectionRange.Length < 0.0001)
            return false;
    }

    return true;
}

All operations above should be pretty self explanatory, except maybe for building normal vector (call to Normal() method in line 9). Normal vector is vector that is at 90 degrees to current vector. In 2D there are of course two such vectors (if original vector goes straight up, normal vectors would be one pointing to left and one pointing to right). How is this vector obtained? Extremely simple – it is just a vector with swapped X and Y coordinate, and one of those coordinates multiplied by -1 (which one will be multiplied determines if it will be left or right normal vector). Imagine vector [0, 1]. If you will swap coordinates, you will get [1, 0]. If you will multiply X by -1, you will get left normal vector [-1, 0]; if you will multiply Y you will get right normal vector [1, 0] (the same as vector just after swap, but that’s just because it is 0 coordinate, usually that won’t be the case).

public Vector2d Normal()
{
    return new Vector2d(Y, -X);
}

For SAT calculations, does it matter which one we will pick? For the moment – no. The difference will be – will the normal vector point inside or outside of the object. But that does not matter for collision verification, instead of positive numbers on axis I may get negative ones, but is still valid math, thank you very much :)

OK, next thing on the list is doing projections of object onto given axis. Visually – easy. Mathematically? Well… easy-if-not-easier! From high school math, vectors, remember dot product operation? For vectors A[X, Y] and B[X, Y], dot product is defined as AX * BX + AY * BY. How does that help? Turns out (thanks to some clever math) that this scalar value is equal to length of vector B projected onto vector A. Yea, that’s what I need. Since I have my object hold all points as vectors (which could be interpreted as vector from 0,0 coordinate to object’s vertex) I can project it onto axis vector and get distance from beginning of the axis. If done for all points in object, and recorded minimum and maximum value, the result would be set of two numbers that define from where to where objects projection goes.

private Range ProjectOntoAxis(Vector2d axisVector, Obstacle obstacle)
{
    double min = double.MaxValue;
    double max = double.MinValue;

    for (int i = 0; i < obstacle.Points.Length; i++)
    {
        var currentPoint = obstacle.Points[i];

        var projectionSize = axisVector.DotProduct(currentPoint);
        if (projectionSize < min)
            min = projectionSize;
        if (projectionSize > max)
            max = projectionSize;
    }

    return new Range(min, max);
}

Why do I return numbers as Ranges? To encapsulate some operations inside of it. Remember the line that calculates intersection of two ranges from two objects? It is neatly hidden behind Range abstraction.

public class Range
{
    public double Start { get; set; }
    public double End { get; set; }
    public double Length { get { return End - Start; } }

    public Range(double a, double b)
    {
        Start = a < b ? a : b;
        End = a < b ? b : a;
    }

    public Range Intersect(Range other)
    {
        var firstRange = Start < other.Start ? this : other;
        var secondRange = firstRange == this ? other : this;

        if (firstRange.End < secondRange.Start)
            return new Range(0, 0);

        return new Range(secondRange.Start, firstRange.End);
    }
}

Intersection is simply calculated by taking minimum value of range further to left on axis, and maximum value is end of range closer to the right end of axis. Unless of course those ranges are separated, in which case empty range is returned. Don’t believe me? Draw it on a piece of paper and you will see that it works.

And that’s it, right? We have projections, intersections, all done using very basic math on vectors. Collisions should be detected perfectly, right? Well, not so fast. One of the object is convex polygon, true, but the other is circle. Since iterating over all vertices of circle would take a while (like an infinite while), there must be a better way right?

Fortunately circles are extremely nice creatures and pure joy to work with. They always have the same size in any way you look at them (2 * cirle radius). So calculating projections will also be simple. If I was only interested in size it would just be one multiplication. But I need to have circle’s position in normal axis as well. The only point in circle that I know where is, is circle’s origin point, right there in the middle. Projecting it onto axis (again, dot product) gives center projection. From there add and subtract size once and there it is, projection done like a champ.

private Range ProjectOntoAxis(Vector2d axisVector, IGameObject gameObject)
{
    var centerProjection = axisVector.DotProduct(gameObject.Position);
    return new Range(centerProjection - gameObject.Size, centerProjection + gameObject.Size);
}

And you know what? That’s it! it will find collisions, it will work… except it won’t. In some cases it will find collisions that aren’t there. When? If circle is placed next to the corner of the rectangle, all projections from rectangle sides will show collision, but there is clearly a separation! Let’s work on that in next part.

False collision with SAT

False collision with SAT

SAT axis projections

Obstacle collisions, pt 2 Separating Axis Theorem

So there is a rectangle. And there is a circle. How to figure out if they are overlaping? Unfortunately there is no easy formula like for circles, or few ifs to do it (like for multiple rectangles). But this does not mean there is no way to do it at all. Meet Separating Axis Theorem.

It is really simple actually. Given two convex shapes (shapes where all internal angles are less or equal to 180 degrees), there will be at least one line you can draw that will not cross any of those shapes – you do not have collision. If there is no such line to be drawn, collision is certain.

SAT line separating objects

SAT line separating objects

What at first may seem very tricky is – how to find whether such line exists at all. Human eyes are extremely good at this, after all you can spot collision immediately (unles objects are really, really close to each other). But mathematically or algorithmically speaking this must be hard, right? No. In fact, it comes down just to few operations, none of them complex at all, to get the right answer.

SAT says that there will be a way to draw the line between two objects to exclude collision possibility. But checking every possible line will not be easy. Here comes axis part. If there is a line that goes between two objects without touching any one of them, it means that there must be axis (perpendicular to that line), onto which we could project our shapes and get a hole between both shapes’ projections.

SAT axis projections

SAT axis projections

But back to the issue. If I don’t know where to draw the line, it is basically the same problem – what axes to check? I can’t check every one of them (counting to infinity take a very long time). But there is no need to check every one. What has to be checked is only a set of axes related to set of shapes’ sides. But not the ones matching the sides, but rather the ones matching normal vectors shape’s side. Normal vector is vector pointing at 90 degrees angle from another vector (we can assume that shape’s side is a vector). Why normal vectors?

SAT false collision

SAT false collision

Check those two triangles. Clearly not colliding, and yet, if you were to check only the axes aligned with triangles’ sides, you will see that there is no spacing between them on any of those axis. And if there is overlaping area on every axis, there is a collision. That would be wrong result. But if there are separating lines, at least one of them will be parallel to one of the shapes’ side. Given this, I know I only need to check axes perpendicular to shapes’ sides (since resulting line is “represented” by empty space on axis with objects projections).

Hope this makes sense, since the idea is pretty smart and works really well. If you want to have a little bit of fun with interactive presentations of this problems, check out this tutorial where there is a great explenation of how this works in N game. Great game too!

Next time I will dive into code directly, so make sure you get the idea. Feel free to ask any question, I will clear things up as good as I can.

Overcoming obstacles, or more about collisions, pt 1

I don’t know if shooting game could be that much fun without something to hide behind and catch a breath. I will put some obstacles onto the map. What I imagine them to do is first, block all player movement through the obstacle, block all incoming bullets that hit obstacle, and, in future, block player’s view of the part of arena hidden behind obstacle.

I will start ith easy part first. I need obstacles to be visible on the screen. Invisible walls never really suited me, I’m shy guy after all. First, I extended my Arena class to hold list of obstacles. What is obstacle? Well, basicaly a thingy with list of points that define obstacle shape. It works for now, mybe will have something more in future to prove even more useful. But we like list of points, right?

public class Obstacle
{
    public Vector2d[] Points { get; set; }

    public Obstacle()
    {
        Points = new Vector2d[4]
        {
            new Vector2d(50, 100),
            new Vector2d(100, 75),
            new Vector2d(50, 0),
            new Vector2d(0, 25)
        };
    }
}

Since there are four points in this sample obstacle, you know it is going to be quadrilateral (yay for fancy words!, I’m not native speaker as you probably could’ve guessed ;)). I can tell you even more – it is going to be rectangle at an angle (see what I did here?).

And Arena looks pretty much the same but with a twist;

public class Arena
{
    ...
    public List<Obstacle> Obstacles = new List<Obstacle>() { new Obstacle() };
    ...
}

And this gets returned to the player once he signs into the game.

// RaimHub
public void Register(string name)
{
    name = HttpUtility.HtmlEncode(name);

    var player = arena.RegisterPlayer(name);
    players.Add(Context.ConnectionId, player);

    Clients.Caller.SignedIn(player.Id);
    Clients.Caller.SetupArena(arena);
    Clients.All.Registered(player);
    Clients.Caller.OtherPlayers(players.Values.Where(p => p.Name != name));
}

On a client this arena object is available for graphics “engine” to a) draw arena border, and b) draw all the obstacles. See the code, it is pretty simple:

var drawArena = function (gameObjects) {
    drawingContext.clearRect(0, 0, canvas.width, canvas.height);

    drawArenaBorders();
    drawObstacles();

    ...
};

function drawArenaBorders() {
    if (args.arena() == undefined) return;

    drawRectangle([
        { X: 0, Y: 0 },
        { X: 0, Y: args.arena().ArenaSize.Y },
        { X: args.arena().ArenaSize.X, Y: args.arena().ArenaSize.Y },
        { X: args.arena().ArenaSize.X, Y: 0 }]);
}

function drawObstacles() {
    if (args.arena() == undefined) return;

    var obstacles = args.arena().Obstacles;
    for (var i = 0; i < obstacles.length; i++) {
        drawRectangle(obstacles[i].Points);
    }
}

function drawRectangle(points) {
    if (points.length < 2) return;

    drawingContext.beginPath();

    drawingContext.moveTo(points[0].X + args.viewport().x, -(points[0].Y + args.viewport().y));
    for (var i = 1; i < points.length; i++) {
        drawingContext.lineTo(points[i].X + args.viewport().x, -(points[i].Y + args.viewport().y));
    }

    drawingContext.lineTo(points[0].X + args.viewport().x, -(points[0].Y + args.viewport().y));

    drawingContext.strokeStyle = "rgba(0, 0, 0, 1)";
    drawingContext.stroke();
    drawingContext.closePath();
}

The same function draws borders and obstacles. All are rectangles, just one limits you from escaping and the other blocks you from going in. Well, sort-of. It will in future. I promise.

Master of time, or about benefits of server updates

As pointed out in some previous post, there are some disadvantages to calculating newarena state on server only when some client sends update. There is also a disadvantage to sending server updates on every client action – this puts a lot of stress on server (10 players, sending 10 updates a second, would mean server has to send 10×10=100 updates to server per second; 10 updates from client a second is really low number).

First I thought that I will address this simply by having arena raise event every time it thinks update is needed (so 30-60 times per second). After solving initial problem with events in SignalR hubs, it got to me – since there is no hub, there can be a time (and that will often be the case) when there is no one to handle event. Well, that’s easy – I will create my own hub. Well, not so fast – you can’t just do that. Hubs need to be created by hub pipeline, and it is not something I want to mess with. Well, that’s a pity. What should I do?

Thankfully SignalR creators thought about such use case and came up with possible solution. What is required is to create class that will take over some of the hub possibilites, like communicating with clients, make it singleton (well, not necessarily, but it works for me at this point), and subscribe to timer events in this class. This class will always be in memory (at least when I want it to handle my timer request), it will do what it needs and then send updates to clients like normal hub. From client point of view nothing really changes – they will all get normal updates in javascript like before.

Show me the code you say:

public class ArenaTicker
{
    private readonly static ArenaTicker _instance = new ArenaTicker(GlobalHost.ConnectionManager.GetHubContext<RaimHub>().Clients);
    private const int _updateInterval = 1000 / 60;

    private readonly IHubConnectionContext<dynamic> _clients;
    private readonly Timer _timer;

    public static ArenaTicker Instance {  get { return _instance; } }

    private ArenaTicker(IHubConnectionContext<dynamic> clients)
    {
        _clients = clients;
        _timer = new Timer(UpdateArena, null, _updateInterval, _updateInterval);
    }

    private void UpdateArena(object state)
    {
        var go = RaimHub.arena.UpdatePositions(DateTime.Now);
        _clients.All.PlayerMoved(go);
    }
}

What is going on is – there is private constructor so there will be guaranteed only one instance of this class. In it, it takes hub context. As you can see when creating this instance I’m hooking up to GlobalHost.ConnectionManager to get the context. It is slow operation so it should be done rarely, possibly just once per application runtime (or maybe one for each arena I need to update maybe?). This context will get updated with every client that connects, disconnects etc., just like in normal hub. Then there is a timer, that ticks 60 times per second (but easly adjustable to any other frame rate). It will call update on arena and then notify all clients on new arena state.
Please forgive the little ugliness of the code around getting arena – there is a static instance of this class in hub, I did not move it anywhere else since for a moment it does its job.

One more thing – notice that the code that returns objects to client changed a little bit. Before it looked like this;

_clients.All.PlayerMoved(RaimHub.arena.GameObjects);

This however resulted in issues with collection being changed when iterated over. That’s not good, I can’t have server crushing every time new player registers or some player shoots. This is now changed to return set of objects that were returned from update method. And it takes care of returning immutable collection when inside lock (to avoid changing collections when doing update to arena state).

public IEnumerable<IGameObject> UpdatePositions(DateTime? updateTimestamp)
{
    ...
    lock (_lock)
    {
        ...
        return GameObjects.ToArray();
    }
}

And now server is running 60 “frames” every second, always having pretty actual state, limitting number of updates to clients and improving on collision detection.

We are counting scores here

One useful info in any game that promotes rivalry of any kind is score each player gets. How else do you decide who is actualy better? In Raim, stuff is pretty simple – you get one point for any other player you hit with your bullet. Clear rules are the best.

Actual implementation? Well, that’s a simple one this time:

private void HandleCollision(Player o1, Bullet o2)
{
    o1.IsDestroyed = true;
    o2.IsDestroyed = true;
    o2.KilledPlayer();
}
public void KilledPlayer()
{
    Player.KilledEnemy();
}
public void KilledEnemy()
{
    Score++;
}

Bullet knows what to do in case it hit the other player. This time it only notifies player it belongs to that something like that happened so player can update internal score. In future maybe this will do something more.

Score is property of player so it will notify all players when the next update from server will be sent to clients. And what clients should do is to update leaderboard.

var playerMoved = function (gameObjectsFromServer) {
    gameObjects = gameObjectsFromServer;
    players.updateLeaderboard(gameObjects);
};
var updateLeaderboard = function (gameObjects) {
    for (var i = 0; i < _players.length; i++) {
        _players[i] = gameObjects.find(function (g) { return g.Id == _players[i].Id; });
        var playersList = document.getElementById(playersListElementId);
        var playerListElement = playersList.getElementsByTagName("span")[i];
        playerListElement.textContent = _players[i].Name + " " + _players[i].Score;
        playerListElement.id = _players[i].Id;
    }

    for (var i = _player.length; i < playerListElements.length; i++) {
        playersList.removeChild(playerListElements[i]);
    }
};

That is one ugly piece of code, but it will do for now :)