diff --git a/SnakeGame/Form1.Designer.cs b/SnakeGame/Form1.Designer.cs
index 7f79ba2..15bdff2 100644
--- a/SnakeGame/Form1.Designer.cs
+++ b/SnakeGame/Form1.Designer.cs
@@ -38,6 +38,7 @@
this.scoreLabel = new System.Windows.Forms.Label();
this.livesLabel = new System.Windows.Forms.Label();
this.DialogPanel = new System.Windows.Forms.Panel();
+ this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
@@ -48,9 +49,9 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.Color.Black;
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.panel1.Location = new System.Drawing.Point(12, 64);
+ this.panel1.Location = new System.Drawing.Point(12, 83);
this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(600, 357);
+ this.panel1.Size = new System.Drawing.Size(600, 338);
this.panel1.TabIndex = 0;
this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
//
@@ -129,7 +130,7 @@
// livesLabel
//
this.livesLabel.AutoSize = true;
- this.livesLabel.Location = new System.Drawing.Point(14, 48);
+ this.livesLabel.Location = new System.Drawing.Point(14, 53);
this.livesLabel.Name = "livesLabel";
this.livesLabel.Size = new System.Drawing.Size(32, 13);
this.livesLabel.TabIndex = 3;
@@ -146,12 +147,23 @@
this.DialogPanel.TabIndex = 0;
this.DialogPanel.Visible = false;
//
+ // flowLayoutPanel1
+ //
+ this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
+ this.flowLayoutPanel1.Location = new System.Drawing.Point(239, 31);
+ this.flowLayoutPanel1.Name = "flowLayoutPanel1";
+ this.flowLayoutPanel1.Size = new System.Drawing.Size(373, 46);
+ this.flowLayoutPanel1.TabIndex = 4;
+ //
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(624, 442);
+ this.Controls.Add(this.flowLayoutPanel1);
this.Controls.Add(this.DialogPanel);
this.Controls.Add(this.livesLabel);
this.Controls.Add(this.scoreLabel);
@@ -187,6 +199,7 @@
private System.Windows.Forms.Label livesLabel;
private System.Windows.Forms.Panel DialogPanel;
private System.Windows.Forms.ToolStripTextBox toolStripTextBox1;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
}
}
diff --git a/SnakeGame/Form1.cs b/SnakeGame/Form1.cs
index aa57a0e..1680776 100644
--- a/SnakeGame/Form1.cs
+++ b/SnakeGame/Form1.cs
@@ -28,13 +28,16 @@ namespace SnakeGame
{
if (!MSGBox.Shown)
{
- if (value && !timerenabled) //Only start if not running already
+ Instance.Invoke(new Action(delegate
{
- Timer.Start();
- SpeedTimer.Start();
- }
- timerenabled = value;
- Instance.toolStripTextBox1.Enabled = !value;
+ if (value && !timerenabled) //Only start if not running already
+ {
+ Timer.Start();
+ SpeedTimer.Start();
+ }
+ timerenabled = value;
+ Instance.toolStripTextBox1.Enabled = !value;
+ }));
}
}
}
@@ -128,6 +131,8 @@ namespace SnakeGame
private bool formdeactivated = false;
private void Form1_Activated(object sender, EventArgs e)
{
+ if (Network.ConnectedMatch != null)
+ return;
if (formdeactivated)
Game.Paused = false;
formdeactivated = false;
@@ -135,6 +140,8 @@ namespace SnakeGame
private void Form1_Deactivate(object sender, EventArgs e)
{
+ if (Network.ConnectedMatch != null)
+ return;
formdeactivated = !Game.Paused;
Game.Paused = true;
}
@@ -171,6 +178,35 @@ namespace SnakeGame
{
Network.Leave(); //Stop threads and such
}
+
+ public static void RefreshPlayerList()
+ {
+ if (Instance == null)
+ return;
+ Action action = new Action(() =>
+ {
+ Instance.flowLayoutPanel1.Controls.Clear();
+ /*if (Network.ConnectedMatch == null)
+ {
+ Instance.flowLayoutPanel1.Controls.Add(new Label { Text = Game.Player.Name, ForeColor = Game.Player.Color });
+ Instance.flowLayoutPanel1.Controls.Add(new Label { Text = "Score: " + Game.Player.Score, ForeColor = Game.Player.Color });
+ }*/
+ if (Network.ConnectedMatch != null)
+ {
+ foreach (Player player in Network.ConnectedMatch.Players)
+ {
+ if (player.Name == Game.Player.Name)
+ continue; //The current player's score/lives value is shown already
+ Instance.flowLayoutPanel1.Controls.Add(new Label { Text = player.Name, ForeColor = Game.Player.Color });
+ Instance.flowLayoutPanel1.Controls.Add(new Label { Text = "Score: " + Game.Player.Score, ForeColor = Game.Player.Color });
+ }
+ }
+ });
+ if (Instance.InvokeRequired)
+ Instance.Invoke(action);
+ else
+ action();
+ }
}
public static class Ext
{
diff --git a/SnakeGame/Game.cs b/SnakeGame/Game.cs
index d7800f0..63bc956 100644
--- a/SnakeGame/Game.cs
+++ b/SnakeGame/Game.cs
@@ -24,6 +24,7 @@ namespace SnakeGame
//public static string UserName;
public static Player Player = new Player("Player", true);
private static int score;
+ [Obsolete("Use Game.Player.Score")]
public static int Score
{
get
@@ -37,6 +38,7 @@ namespace SnakeGame
}
}
private static int lives;
+ [Obsolete("Use Game.Player.Lives")]
public static int Lives
{
get
@@ -51,6 +53,8 @@ namespace SnakeGame
}
///
/// Opposite of Form1.TimerEnabled
+ /// TODO: Send pause/resume event
+ /// (View -> Task List -> Comments
///
public static bool Paused
{
@@ -104,7 +108,7 @@ namespace SnakeGame
match.Players.Add(Game.Player);
Game.Reset();
Network.CreateGame(match);
- Game.Paused = false;
+ //Game.Paused = false; - Start in thread
}
else
Game.Paused = true;
@@ -131,7 +135,7 @@ namespace SnakeGame
{
Game.Reset();
Network.Connect(Network.Matches[num]);
- Game.Paused = false;
+ //Game.Paused = false; - Start in thread
}
else
Game.Paused = true;
@@ -226,7 +230,7 @@ namespace SnakeGame
}
}
Point nextcoord = MovePlayerPre(Player, MoveDirection);
- Network.SyncUpdate(NetUpdateType.Move);
+ Network.SyncUpdate(NetUpdateType.Move, MoveDirection);
/*if (nextcoord.X >= GameField.GetLength(0) || nextcoord.Y >= GameField.GetLength(1))
{
MessageBox.Show("Error!");
@@ -235,6 +239,7 @@ namespace SnakeGame
if (Game.GameField[nextcoord.X, nextcoord.Y].Tick != 0 && Game.GameField[nextcoord.X, nextcoord.Y].Type != SquareType.Point)
{
Lives--;
+ LivesLabel.ForeColor = Color.Red;
if (Lives <= 0)
Stop();
else
@@ -242,11 +247,15 @@ namespace SnakeGame
}
else
{
+ LivesLabel.ForeColor = Color.White;
if (GameField[nextcoord.X, nextcoord.Y].Type == SquareType.Point)
{
Score += 1000;
+ ScoreLabel.ForeColor = Color.Blue;
Game.AddPoint();
}
+ else
+ ScoreLabel.ForeColor = Color.White;
if (Score > 0)
Score -= new Random().Next(1, 20);
MovePlayerPost(Player, nextcoord);
@@ -328,6 +337,22 @@ namespace SnakeGame
colors = colorlist.ToArray();
return Color.FromKnownColor(colors[new Random().Next(colors.Length)]);
}
+ ///
+ /// TODO
+ ///
+ ///
+ public static void Load(string filename)
+ {
+ throw new NotImplementedException();
+ }
+ ///
+ /// TODO
+ ///
+ ///
+ public static void Save(string filename)
+ {
+ throw new NotImplementedException();
+ }
}
public enum GameStartMode
{
diff --git a/SnakeGame/NetMatch.cs b/SnakeGame/NetMatch.cs
index 54c97e0..202a45a 100644
--- a/SnakeGame/NetMatch.cs
+++ b/SnakeGame/NetMatch.cs
@@ -13,7 +13,12 @@ namespace SnakeGame
public string Name = "";
public int MaxPlayers = 0;
//public List PlayerNames = new List();
- public List Players = new List();
+ ///
+ /// TODO: Send player join/leave to master server
+ ///
+ //public List Players = new List();
+ public PlayerCollection Players = new PlayerCollection();
+
private string ownername = "";
public string OwnerName
{
diff --git a/SnakeGame/Network.Client.cs b/SnakeGame/Network.Client.cs
index 228fe66..b85ff27 100644
--- a/SnakeGame/Network.Client.cs
+++ b/SnakeGame/Network.Client.cs
@@ -35,16 +35,23 @@ namespace SnakeGame
{
for (int j = 0; j < Game.GameSize.Y; j++)
{
- Game.GameField[i, j].PlayerName = (string)readdata["GameField"][i][j]["PlayerName"];
- Game.GameField[i, j].Tick = (int)readdata["GameField"][i][j]["Tick"];
- Game.GameField[i, j].Type = (SquareType)Enum.Parse(typeof(SquareType), (string)readdata["GameField"][i][j]["Type"]);
+ Game.GameField[i, j].PlayerName = (string)readdata["GameField"][i + ""][j + ""]["PlayerName"];
+ Game.GameField[i, j].Tick = (int)readdata["GameField"][i + ""][j + ""]["Tick"];
+ Game.GameField[i, j].Type = (SquareType)Enum.Parse(typeof(SquareType), (string)readdata["GameField"][i + ""][j + ""]["Type"]);
}
}
- foreach(JObject item in readdata["Players"])
+ foreach(JProperty item in readdata["Players"])
{
- MessageBox.Show(item.ToString());
+ ConnectedMatch.Players.Add(new Player(item.Name, color: Color.FromArgb((int)item.Value["Color"]), x: (int)item.Value["Position"]["X"], y: (int)item.Value["Position"]["Y"]));
+ }
+ Game.Paused = false;
+ SendUpdate = true;
+ while (true)
+ {
+ string playername = sr.ReadString();
+ Player player = ConnectedMatch.Players.Single(entry => entry.Name == playername);
+ ReceiveAndProcessData(player, sr);
}
-
}
}
}
diff --git a/SnakeGame/Network.Server.cs b/SnakeGame/Network.Server.cs
index a8109b9..949229f 100644
--- a/SnakeGame/Network.Server.cs
+++ b/SnakeGame/Network.Server.cs
@@ -71,71 +71,45 @@ namespace SnakeGame
BinaryWriter bwp = new BinaryWriter(ns);
var senddata = new JObject();
senddata["Length"] = Game.Length;
+ senddata["GameSize"] = new JObject();
senddata["GameSize"]["X"] = Game.GameSize.X;
senddata["GameSize"]["Y"] = Game.GameSize.Y;
+ senddata["GameField"] = new JObject();
for (int i = 0; i < Game.GameSize.X; i++)
{
+ senddata["GameField"][i + ""] = new JObject();
for (int j = 0; j < Game.GameSize.Y; j++)
{
- senddata["GameField"][i][j]["PlayerName"] = Game.GameField[i, j].PlayerName;
- senddata["GameField"][i][j]["Tick"] = Game.GameField[i, j].Tick;
- senddata["GameField"][i][j]["Type"] = Game.GameField[i, j].Type.ToString();
+ senddata["GameField"][i + ""][j + ""] = new JObject();
+ senddata["GameField"][i + ""][j + ""]["PlayerName"] = Game.GameField[i, j].PlayerName;
+ senddata["GameField"][i + ""][j + ""]["Tick"] = Game.GameField[i, j].Tick;
+ senddata["GameField"][i + ""][j + ""]["Type"] = Game.GameField[i, j].Type.ToString();
}
}
+ senddata["Players"] = new JObject();
foreach (Player joinedplayer in ConnectedMatch.Players)
{
+ if (joinedplayer.Name == player.Name)
+ continue;
+ senddata["Players"][joinedplayer.Name] = new JObject();
+ senddata["Players"][joinedplayer.Name]["Position"] = new JObject();
senddata["Players"][joinedplayer.Name]["Position"]["X"] = joinedplayer.Position.X;
senddata["Players"][joinedplayer.Name]["Position"]["Y"] = joinedplayer.Position.Y;
senddata["Players"][joinedplayer.Name]["Color"] = joinedplayer.Color.ToArgb();
}
bwp.Write(senddata.ToString());
+ Game.Paused = false;
+ SendUpdate = true;
while (true)
{
- NetUpdateType updatetype = (NetUpdateType)br.ReadInt32();
- switch (updatetype)
- {
- case NetUpdateType.Name:
- string newname = br.ReadString();
- player.Name = newname;
- foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
- { //ForwardMessage prepares each send and then here the only thing to do is to send the extra data
- bw.Write(newname);
- }
- break;
- case NetUpdateType.Color:
- Color color = Color.FromArgb(br.ReadInt32());
- player.Color = color;
- foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
- {
- bw.Write(color.ToArgb());
- }
- break;
- case NetUpdateType.Move:
- Direction direction = (Direction)br.ReadInt32();
- Game.MovePlayerPost(player, Game.MovePlayerPre(player, direction));
- foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
- {
- bw.Write((int)direction);
- }
- break;
- /*case NetUpdateType.Login:
- ConnectedMatch.Players.Add(new Player(playername, ConnectedMatch.NextID));
- break;*/
- case NetUpdateType.Leave:
- foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
- {
- }
- Network.ConnectedMatch.Players.RemoveAll(entry => entry.Name == playername);
- client.Close();
- break;
- }
+ if (!ReceiveAndProcessData(player, br))
+ break;
}
}
private static IEnumerable ForwardMessage(Player player, string playername, int updatetype)
{
if (ConnectedMatch.OwnerName == Game.Player.Name)
{
- //foreach (Player p in ConnectedMatch.Players)
Player p;
while (ConnectedMatch.Players.GetEnumerator().MoveNext())
{
@@ -143,8 +117,7 @@ namespace SnakeGame
if (p == player)
continue;
var bw = new BinaryWriter(p.Client.GetStream());
- //bw.Write(52); - It should only send it once
- //bw.Write(playername); - It should only send it once
+ bw.Write(playername);
bw.Write(updatetype);
yield return bw;
}
diff --git a/SnakeGame/Network.cs b/SnakeGame/Network.cs
index 96c7e8c..8273620 100644
--- a/SnakeGame/Network.cs
+++ b/SnakeGame/Network.cs
@@ -19,9 +19,45 @@ namespace SnakeGame
public static partial class Network
{
public const int Port = 12885;
- public static void SyncUpdate(NetUpdateType updatetype) //If we are a server, forward every valid data we get
+ public static void SyncUpdate(NetUpdateType updatetype, object data)
{
-
+ if (ConnectedMatch == null)
+ return;
+ BinaryWriter bw;
+ foreach (Player player in ConnectedMatch.Players)
+ {
+ if (player.Name == Game.Player.Name)
+ continue; //Don't send to ourselves
+ bool isserver = ConnectedMatch.OwnerName == Game.Player.Name;
+ if (!isserver)
+ {
+ bw = new BinaryWriter(ConnectedMatch.GetPlayerByName(ConnectedMatch.OwnerName).Client.GetStream());
+ }
+ else
+ {
+ bw = new BinaryWriter(player.Client.GetStream());
+ }
+ bw.Write((int)updatetype);
+ switch (updatetype)
+ {
+ case NetUpdateType.Name:
+ string newname = (string)data;
+ bw.Write(newname);
+ break;
+ case NetUpdateType.Color:
+ int color = ((Color)data).ToArgb();
+ bw.Write(color);
+ break;
+ case NetUpdateType.Move:
+ int direction = (int)data; //Converting to enum and back to int is unnecessary
+ bw.Write(direction);
+ break;
+ case NetUpdateType.Leave:
+ break;
+ }
+ if (!isserver)
+ break; //If not server, only send to the server
+ }
}
public static List Matches = new List();
public static NetMatch ConnectedMatch { get; private set; }
@@ -111,6 +147,8 @@ namespace SnakeGame
{
if (ConnectedMatch == null)
return;
+ SendUpdate = false;
+ SyncUpdate(NetUpdateType.Leave, null);
if (ConnectedMatch.OwnerName == Game.Player.Name)
{
using (var client = new WebClient())
@@ -170,6 +208,57 @@ namespace SnakeGame
(ReceiverThread = new Thread(new ThreadStart(ClientListenerThreadRun))).Start();
}
}
+ public static bool SendUpdate = false;
+ private static bool ReceiveAndProcessData(Player player, BinaryReader br)
+ {
+ string playername = player.Name;
+ try
+ {
+ NetUpdateType updatetype = (NetUpdateType)br.ReadInt32();
+ switch (updatetype)
+ {
+ case NetUpdateType.Name:
+ string newname = br.ReadString();
+ player.Name = newname;
+ foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
+ { //ForwardMessage prepares each send and then here the only thing to do is to send the extra data
+ bw.Write(newname);
+ }
+ break;
+ case NetUpdateType.Color:
+ Color color = Color.FromArgb(br.ReadInt32());
+ player.Color = color;
+ foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
+ {
+ bw.Write(color.ToArgb());
+ }
+ break;
+ case NetUpdateType.Move:
+ Direction direction = (Direction)br.ReadInt32();
+ Game.MovePlayerPost(player, Game.MovePlayerPre(player, direction));
+ foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
+ {
+ bw.Write((int)direction);
+ }
+ break;
+ /*case NetUpdateType.Login:
+ ConnectedMatch.Players.Add(new Player(playername, ConnectedMatch.NextID));
+ break;*/
+ case NetUpdateType.Leave:
+ foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
+ {
+ }
+ Network.ConnectedMatch.Players.RemoveAll(entry => entry.Name == playername);
+ player.Client.Close();
+ break;
+ }
+ }
+ catch (IOException)
+ {
+ return false;
+ }
+ return true;
+ }
}
public enum NetUpdateType
{
diff --git a/SnakeGame/Player.cs b/SnakeGame/Player.cs
index 7a93dde..6a1e243 100644
--- a/SnakeGame/Player.cs
+++ b/SnakeGame/Player.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
@@ -20,9 +21,10 @@ namespace SnakeGame
}
set
{
- name = value;
if (Own)
- Network.SyncUpdate(NetUpdateType.Name);
+ Network.SyncUpdate(NetUpdateType.Name, value);
+ name = value; //Only set name after sending update (which sends old name too)
+ Form1.RefreshPlayerList();
}
}
private Color color;
@@ -36,14 +38,17 @@ namespace SnakeGame
{
color = value;
if (Own)
- Network.SyncUpdate(NetUpdateType.Color);
+ Network.SyncUpdate(NetUpdateType.Color, value);
+ Form1.RefreshPlayerList();
}
}
public Point Position;
public TcpClient Client;
+ public int Score;
+ public int Lives;
//public readonly int ID;
public readonly bool Own;
- public Player(string name, bool own = false, Color color = default(Color))
+ public Player(string name, bool own = false, Color color = default(Color), int x = 0, int y = 0)
{
Name = name;
if (color == default(Color))
@@ -55,11 +60,101 @@ namespace SnakeGame
//ID = NextID;
//NextID++;
Own = own;
- Position = new Point(0, 0);
+ //Position = new Point(0, 0);
+ Position = new Point(x, y);
+ Score = 0;
+ Lives = 3;
}
/*public static void Reset()
{
NextID = 0;
}*/
}
+ public class PlayerCollection : IList
+ {
+ private List _list = new List();
+
+ public int IndexOf(Player item)
+ {
+ return _list.IndexOf(item);
+ }
+
+ public void Insert(int index, Player item)
+ {
+ _list.Insert(index, item);
+ Form1.RefreshPlayerList();
+ }
+
+ public void RemoveAt(int index)
+ {
+ _list.RemoveAt(index);
+ Form1.RefreshPlayerList();
+ }
+
+ public Player this[int index]
+ {
+ get
+ {
+ return _list[index];
+ }
+ set
+ {
+ _list[index] = value;
+ }
+ }
+
+ public void Add(Player item)
+ {
+ _list.Add(item);
+ Form1.RefreshPlayerList();
+ }
+
+ public void Clear()
+ {
+ _list.Clear();
+ Form1.RefreshPlayerList();
+ }
+
+ public bool Contains(Player item)
+ {
+ return _list.Contains(item);
+ }
+
+ public void CopyTo(Player[] array, int arrayIndex)
+ {
+ _list.CopyTo(array, arrayIndex);
+ }
+
+ public int Count
+ {
+ get { return _list.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+
+ public bool Remove(Player item)
+ {
+ bool ret = _list.Remove(item);
+ Form1.RefreshPlayerList();
+ return ret;
+ }
+
+ public int RemoveAll(Predicate match)
+ {
+ return _list.RemoveAll(match);
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return _list.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _list.GetEnumerator();
+ }
+ }
}
diff --git a/SnakeGame/SnakeGame.csproj b/SnakeGame/SnakeGame.csproj
index e63393e..369a05a 100644
--- a/SnakeGame/SnakeGame.csproj
+++ b/SnakeGame/SnakeGame.csproj
@@ -33,20 +33,10 @@
4
-
- ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll
-
-
- ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll
-
-
- ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll
-
False
bin\Debug\Newtonsoft.Json.dll
-