Skip to content

Commit

Permalink
Fixed bug: stars did not return from socketprotocol. Improved keyboar…
Browse files Browse the repository at this point in the history
…dcontrol
  • Loading branch information
bondehagen committed Mar 26, 2012
1 parent 71a65b4 commit a3a6ad3
Show file tree
Hide file tree
Showing 47 changed files with 2,831 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
bin
obj
*.user
*.ReSharper
*.DotSettings
*.suo
243 changes: 243 additions & 0 deletions SpaceBump.Core/Bumpership.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;

namespace SpaceBumper
{
public class Bumpership
{
private readonly double factor1;
private readonly double factor2;
private readonly IInputHandler input;
private readonly Vector spawnPosition;
private readonly World world;
private Bumpership lastcollider;
private Vector oldPosition;

public Bumpership(IInputHandler input, World world, object shape, string name, Vector spawnPosition)
{
this.input = input;
this.world = world;
Shape = shape;
Name = name;
this.spawnPosition = spawnPosition;

Radius = 0.5;
factor1 = 0.05;
factor2 = 0.1;

Spawn();
}

public object Shape { get; private set; }
public double Radius { get; private set; }
public Vector Velocity { get; set; }
public Vector Position { get; private set; }
public int Score { get; internal set; }
public string Name { get; set; }

public double Angle
{
get { return Velocity.GetAngle() * (180 / Math.PI); }
}


/// <summary>
/// Moves this instanse.
/// </summary>
/// <param name="acceleration">The acceleration.</param>
public void Move(Vector acceleration)
{
// The strength is calculated as sqrt(x*x+y*y)
double strength = acceleration.Length;

if (strength == 0)
return;

if (strength > 1.0)
acceleration.Normalize();

Velocity += acceleration * factor1;
}

public void Update(int iterations)
{
input.Update(iterations, world, this);

Velocity *= 0.97;

oldPosition = Position.Clone();
Position += Velocity * factor2;

Cell currentCell = GetCurrentCell();

if (currentCell.CellType == CellType.Attractor && Collide(currentCell))
{
Score += 50;
currentCell.CellType = CellType.Normal;
}

foreach (Bumpership b in world.Bumperships.Where(b => b != this && Collide(b)))
{
Position = oldPosition;

Vector oldVelocityA = Velocity.Clone();
Vector oldVelocityB = b.Velocity.Clone();

Velocity = Reflect(Velocity, Normalize(Position - b.Position));
b.Velocity = Reflect(b.Velocity, Normalize(b.Position - Position));

lastcollider = b;
b.lastcollider = this;

if (Velocity.Length > b.Velocity.Length)
{
b.Velocity += oldVelocityA * 0.8;
Velocity *= 0.2;
Score += 5;
b.Score -= 5;
}
else
{
b.Velocity += oldVelocityB * 0.8;
Velocity *= 0.2;
b.Score += 5;
Score -= 5;
}
}

if (currentCell.CellType == CellType.None)
{
if (lastcollider != null)
{
lastcollider.Score += 50;
lastcollider = null;
}
if (IsSpawnable())
{
Score -= 50;
Spawn();
}
}

foreach (Cell cell in GetTouchingCells().Where(Collide))
{
if (cell.CellType == CellType.Blocked && Collide(cell.Position, 0.5))
{
Position = oldPosition;
Velocity = Reflect(Velocity, Normalize(Position - cell.Position));
}
else if (cell.CellType == CellType.Boost)
Velocity *= 1.1;
else if (cell.CellType == CellType.SlowDown)
Velocity *= 0.9;
}
}


/// <summary>
/// Determines whether this instance is spawnable.
/// A position is spawnable if no other bumpercars have their position wihtin
/// a distance of 1.0 units from the position.
/// </summary>
/// <returns>
/// <c>true</c> if this instance is spawnable; otherwise, <c>false</c>.
/// </returns>
private bool IsSpawnable()
{
return world.Bumperships.All(b => (b.Position - spawnPosition).Length > 1);
}

private static Vector Normalize(Vector vector)
{
vector.Normalize();
return vector;
}

private static Vector Reflect(Vector velocity, Vector normal)
{
return velocity - (2.0 * normal * velocity.Dot(normal));
}

private void Spawn()
{
Velocity = new Vector(0, 0);
Position = spawnPosition;
}

public IEnumerable<Cell> GetTouchingCells()
{
return world.Map.Grid.GetTouchingCells(Position, Radius);
}

/// <summary>
/// Check for collision with the specified Bumpership
/// A bumpercar collides with another bumpership if the distance between the
/// centers of the two bumperships is lower than the sum of the radiuses of the bumperships.
/// </summary>
/// <param name = "b">The Bumpership.</param>
/// <returns></returns>
private bool Collide(Bumpership b)
{
return Collide(b.Position, b.Radius);
}

/// <summary>
/// Check for collision with the specified object position and radius.
/// A bumpercar collides with another bumpercar if the distance between the
/// centers of the two bumpercars is lower than the sum of the radiuses of the bumpercars.
/// </summary>
/// <param name = "objectPosition">The object position.</param>
/// <param name = "objectRadius">The object radius.</param>
/// <returns></returns>
private bool Collide(Vector objectPosition, double objectRadius)
{
return (objectPosition - Position).Length < objectRadius + Radius;
}


/// <summary>
/// Check for collision with the specified cell.
/// A bumpership collides with a cell if the circle defined by
/// the bumperships position and radius overlaps the interior of the cell.
/// </summary>
/// <param name = "cell">The cell.</param>
/// <returns></returns>
private bool Collide(Cell cell)
{
Vector closestPoint = new Vector(Position.X, Position.Y);

if (Position.X < cell.Min.X)
closestPoint.X = cell.Min.X;
else if (Position.X > cell.Max.X)
closestPoint.X = cell.Max.X;

if (Position.Y < cell.Min.Y)
closestPoint.Y = cell.Min.Y;
else if (Position.Y > cell.Max.Y)
closestPoint.Y = cell.Max.Y;

Vector diff = closestPoint - Position;
return diff.X * diff.X + diff.Y * diff.Y <= Radius * Radius;
}

public Cell GetCurrentCell()
{
return world.Map.Grid.GetCell(Position);
}


public Vector GetDeltaPosition(double delta)
{
return Position + Velocity * factor2 * delta;
}


public void Start()
{
input.Start(world);
}
}
}
30 changes: 30 additions & 0 deletions SpaceBump.Core/Cell.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Windows;

namespace SpaceBumper
{
public class Cell
{
public Cell(CellType cellType)
{
CellType = cellType;
}

public Cell(CellType cellType, int col, int row) : this(cellType)
{
Col = col;
Row = row;

Min = new Vector(col * Map.CellSize, row * Map.CellSize);
Max = new Vector(col * Map.CellSize + Map.CellSize, row * Map.CellSize + Map.CellSize);
const double r = Map.CellSize / 2;
Position = new Vector(Min.X + r, Min.Y + r);
}

public int Col { get; private set; }
public int Row { get; private set; }
public CellType CellType { get; set; }
public Vector Max { get; private set; }
public Vector Min { get; private set; }
public Vector Position { get; private set; }
}
}
12 changes: 12 additions & 0 deletions SpaceBump.Core/CellType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace SpaceBumper
{
public enum CellType
{
None = 0,
Blocked,
Boost,
SlowDown,
Normal,
Attractor
}
}
93 changes: 93 additions & 0 deletions SpaceBump.Core/GameManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace SpaceBumper
{
public class GameManager : IDisposable
{
private readonly GameSettings gameSettings;
private readonly IGraphicsHandler graphics;
private readonly GameLoop gameLoop;
private readonly World world;
private static int iterations;

public GameManager(
GameSettings gameSettings,
IInputHandler keyboardHandler,
SocketManager socketManager,
IGraphicsHandler graphics)
{
this.gameSettings = gameSettings;
this.graphics = graphics;
const int ticksPerSecond = 30;
gameLoop = new GameLoop(5, ticksPerSecond);
gameLoop.Update += Update;
gameLoop.Render += Render;

Map map = new Map(gameSettings.Map);
world = new World(map);

int countShip = 0;
List<Bumpership> bumperships = gameSettings.Players.Take(world.Map.StartPositions.Count)
.Select(p => CreateBumpership(p, keyboardHandler, socketManager, ref countShip))
.ToList();
world.AddShips(bumperships);
}

private Bumpership CreateBumpership(PlayerType player, IInputHandler keyboardHandler, SocketManager socketManager, ref int countShip)
{
IInputHandler input;
string name = "";
switch (player)
{
case PlayerType.Human:
input = keyboardHandler;
name = "Human";
break;
case PlayerType.AI:
input = socketManager.GetNetworkPlayer();
break;
default:
input = new IdiotAi(); // Test
break;
}
Vector startPosition = world.Map.StartPositions[countShip];
countShip++;
return new Bumpership(input, world, graphics.CreateShip(), name, startPosition);
}

public void Dispose()
{
gameLoop.Dispose();
}

public void Start()
{
foreach (Bumpership bumpership in world.Bumperships)
bumpership.Start();

gameLoop.Start();
}

public bool Update()
{
iterations++;
return world.Update(iterations);
}

protected bool Render(float deltaTime)
{
graphics.BeforeRender(deltaTime);

graphics.RenderMap(world.Map);

foreach (Bumpership bumpership in world.Bumperships)
graphics.RenderShip(bumpership);

graphics.AfterRender();
return true;
}
}
}
Loading

0 comments on commit a3a6ad3

Please sign in to comment.