2015.03.13

This commit is contained in:
Norbi Peti 2017-01-07 23:23:59 +01:00
parent f82cc05f82
commit 170c174bdf
10 changed files with 300 additions and 152 deletions

View file

@ -8,7 +8,7 @@ using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WPFInput = System.Windows.Input;
//using WPFInput = System.Windows.Input;
namespace SnakeGame
{
@ -30,26 +30,31 @@ namespace SnakeGame
{
Instance.Invoke(new Action(delegate
{
if (value && !timerenabled) //Only start if not running already
{
Timer.Start();
SpeedTimer.Start();
}
timerenabled = value;
Instance.toolStripTextBox1.Enabled = !value;
Network.SyncUpdate(NetUpdateType.Pause, !value);
SetTimerWithoutSend(value);
}));
}
}
}
public static void SetTimerWithoutSend(bool value)
{
if (!MSGBox.Shown)
{
Instance.Invoke(new Action(delegate
{
if (value && !timerenabled) //Only start if not running already
{
Timer.Start();
SpeedTimer.Start();
}
timerenabled = value;
Instance.toolStripTextBox1.Enabled = !value;
}));
}
}
public Form1()
{
InitializeComponent();
/*Bitmap img = new Bitmap(1, 1);
img.SetPixel(0, 0, Color.Black);
menuStrip1.BackgroundImage = img;
newSingleplayerGameToolStripMenuItem.BackgroundImage = img;
newMultiplayerGameToolStripMenuItem.BackgroundImage = img;
joinMultiplayerGameToolStripMenuItem.BackgroundImage = img;*/
menuStrip1.Renderer = new ToolStripProfessionalRenderer(new MenuColorTable());
menuStrip1.ForeColor = Color.White;
GameRenderer.Panel = panel1;
@ -68,7 +73,6 @@ namespace SnakeGame
if (TimerEnabled)
Timer.Start();
};
//Timer.Start();
SpeedTimer = new Timer();
SpeedTimer.Interval = 10000;
SpeedTimer.Tick += delegate
@ -91,10 +95,8 @@ namespace SnakeGame
GameRenderer.Render();
}
//private static bool playerpaused = false;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
//if (e.KeyCode == Keys.Down && WPFInput.Keyboard.IsKeyDown(WPFInput.Key.Down))
if (e.KeyCode == Keys.Down)
Game.MoveDirection = Direction.Down;
else if (e.KeyCode == Keys.Up)
@ -105,17 +107,12 @@ namespace SnakeGame
Game.MoveDirection = Direction.Right;
else if (e.KeyCode == Keys.Enter)
{
//MSGBox.CloseMSGBox();
if (MSGBox.OnCloseEvent != null)
MSGBox.OnCloseEvent(sender, e);
}
else if (e.KeyCode == Keys.P || e.KeyCode == Keys.Pause)
{
Game.Paused = !Game.Paused;
/*if (Game.Paused)
playerpaused = true;
else
playerpaused = false;*/
}
else
return;
@ -161,7 +158,6 @@ namespace SnakeGame
Game.Player.Name = toolStripTextBox1.Text;
}
//private static Timer resizetimer = new Timer();
private void Form1_Resize(object sender, EventArgs e)
{
GameRenderer.Render();
@ -186,21 +182,18 @@ namespace SnakeGame
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 });
continue;
Instance.flowLayoutPanel1.Controls.Add(new Label { Text = player.Name, ForeColor = player.Color });
Instance.flowLayoutPanel1.Controls.Add(new Label { Text = "Score: " + player.Score, ForeColor = player.Color });
}
}
Instance.scoreLabel.Text = "Score: " + Game.Player.Score;
Instance.livesLabel.Text = "Lives: " + Game.Player.Lives;
});
if (Instance.InvokeRequired)
Instance.Invoke(action);

View file

@ -12,45 +12,14 @@ namespace SnakeGame
public static class Game
{
public static Point GameSize;
//public static List<SqCoord> GameField;
public static SqCoord[,] GameField;
//public static Point Player.Position;
public static int Length = 4;
public static int UpdateTime = 800;
public static Direction MoveDirection;
public static Label ScoreLabel;
public static Label LivesLabel;
public static Panel DialogPanel;
//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
{
return score;
}
set
{
score = value;
ScoreLabel.Text = "Score: " + score;
}
}
private static int lives;
[Obsolete("Use Game.Player.Lives")]
public static int Lives
{
get
{
return lives;
}
set
{
lives = value;
LivesLabel.Text = "Lives: " + lives;
}
}
/// <summary>
/// Opposite of Form1.TimerEnabled
/// TODO: Send pause/resume event
@ -75,16 +44,18 @@ namespace SnakeGame
case GameStartMode.SinglePlayer:
MSGBox.ShowMSGBox("New singleplayer game", "Size:", MSGBoxType.SizeInput, new EventHandler<string>(delegate(object s, string inp)
{
//string[] strs=input.Split(' ');
//int x, y;
//if (strs.Length == 2 && int.TryParse(strs[0], out x) && int.TryParse(strs[1], out y))
int input = int.Parse(inp);
if (input > 5)
{
//GameSize = new Point(x, y);
GameRenderer.Panel.CreateGraphics().FillRectangle(new SolidBrush(Color.Black), new Rectangle(new Point(), GameRenderer.Panel.Size));
int xy = GameRenderer.Panel.Size.Width / input;
GameSize = new Point(xy, xy);
//int xy = GameRenderer.Panel.Size.Width / input;
//GameSize = new Point(xy, xy);
if (GameRenderer.Panel.Size.Width / input < 3 || GameRenderer.Panel.Size.Height / input < 3)
{
Game.Paused = true;
return;
}
GameSize = new Point(GameRenderer.Panel.Size.Width / input, GameRenderer.Panel.Size.Height / input);
Game.Reset();
Form1.TimerEnabled = true;
}
@ -108,7 +79,6 @@ namespace SnakeGame
match.Players.Add(Game.Player);
Game.Reset();
Network.CreateGame(match);
//Game.Paused = false; - Start in thread
}
else
Game.Paused = true;
@ -121,21 +91,15 @@ namespace SnakeGame
break;
}
Network.DownloadGameList();
/*string matches = "";
for (int i = 0; i < Network.Matches.Count; i++)
{
matches += Network.Matches[i].Name + " " + Network.Matches[i].Players.Count + "/" + Network.Matches[i].MaxPlayers + " " + Network.Matches[i].OwnerName + "\n";
}*/
string matches = Network.Matches.Combine<NetMatch, string>((match, combiner) => combiner += match.Name + " " + match.Players.Count + "/" + match.MaxPlayers + " " + match.OwnerName + "\n");
MSGBox.ShowMSGBox("Connect to game", matches, MSGBoxType.List, new EventHandler<string>(delegate(object s, string input)
{
//Network.Connect(Network.Matches[int.Parse(input)]);
int num = 0;
if (int.TryParse(input, out num) && num != -1)
{
Game.Reset();
Network.Connect(Network.Matches[num]);
//Game.Paused = false; - Start in thread
Game.Reset(false);
}
else
Game.Paused = true;
@ -148,24 +112,8 @@ namespace SnakeGame
public static void Load(Size size)
{
//GameSize = size;
//GameSize = SquareCoord.PointToSqCoord(new Point(size));
//GameSize = new SqCoord { X = size.Width / 20, Y = size.Height / 20 };
//GameField = new List<SqCoord>(GameSize.X * GameSize.Y);
//GameField = new int[GameSize.X, GameSize.Y];
GameSize = new Point { X = size.Width / 20, Y = size.Height / 20 };
//UserName = "Player";
//Player = new Player("Player", 0);
Game.Reset();
//GameField.Single(entry => entry.X == Player.Position.X && entry.Y == Player.Position.Y).Tick;
/*for (int i = 0; i < GameField.Count; i++)
{
if(GameField[i].X==Player.Position.X && GameField[i].Y==Player.Position.Y)
{
GameField[i].Tick = Length;
}
}*/
//GameRenderer.Render(); - It has no effect in loading part
}
public static void Reset(bool fullreset)
@ -173,13 +121,36 @@ namespace SnakeGame
if (fullreset)
Network.Leave();
Size size = GameRenderer.Panel.Size;
//GameSize = new Point { X = size.Width / 20, Y = size.Height / 20 };
GameField = new SqCoord[GameSize.X, GameSize.Y];
Player.Position = new Point { X = GameSize.X / 2, Y = 1 };
//Player.Position = new Point { X = GameSize.X / 2, Y = 1 };
var rand=new Random();
Direction dir = (Direction)rand.Next(4);
do
{
switch (dir)
{
case Direction.Up:
Player.Position = new Point(rand.Next(1, GameSize.X - 2), 1);
MoveDirection = Direction.Down;
break;
case Direction.Down:
Player.Position = new Point(rand.Next(1, GameSize.X - 2), GameSize.Y - 2);
MoveDirection = Direction.Up;
break;
case Direction.Left:
Player.Position = new Point(1, rand.Next(1, GameSize.Y - 2));
MoveDirection = Direction.Right;
break;
case Direction.Right:
Player.Position = new Point(GameSize.X - 2, rand.Next(1, GameSize.Y - 2));
MoveDirection = Direction.Left;
break;
}
} while (GameField[Player.Position.X, Player.Position.Y].Tick > 0);
if (fullreset)
{
Score = 0;
Lives = 3;
Player.Score = 0;
Player.Lives = 3;
UpdateTime = 800;
Length = 4;
}
@ -188,12 +159,6 @@ namespace SnakeGame
{
for (int j = 0; j < GameSize.Y; j++)
{
/*SqCoord coord = new SqCoord { X = i, Y = j, Tick = 0 };
if (i == 0 || j == 0 || i == GameSize.X - 1 || j == GameSize.Y - 1)
coord.Tick = -1;
else if (i == Player.Position.X && j == Player.Position.Y)
coord.Tick = 4;
GameField.Add(coord);*/
if (i == 0 || j == 0 || i == GameSize.X - 1 || j == GameSize.Y - 1)
{
GameField[i, j].Type = SquareType.Wall;
@ -208,7 +173,7 @@ namespace SnakeGame
}
}
Game.AddPoint();
MoveDirection = Direction.Down;
//MoveDirection = Direction.Down;
}
public static void Reset()
@ -232,16 +197,12 @@ namespace SnakeGame
}
Point nextcoord = MovePlayerPre(Player, MoveDirection);
Network.SyncUpdate(NetUpdateType.Move, MoveDirection);
/*if (nextcoord.X >= GameField.GetLength(0) || nextcoord.Y >= GameField.GetLength(1))
if (nextcoord.X >= Game.GameSize.X || nextcoord.Y >= Game.GameSize.Y
|| (Game.GameField[nextcoord.X, nextcoord.Y].Tick != 0 && Game.GameField[nextcoord.X, nextcoord.Y].Type != SquareType.Point))
{
MessageBox.Show("Error!");
return;
}*/
if (Game.GameField[nextcoord.X, nextcoord.Y].Tick != 0 && Game.GameField[nextcoord.X, nextcoord.Y].Type != SquareType.Point)
{
Lives--;
Player.Lives--;
LivesLabel.ForeColor = Color.Red;
if (Lives <= 0)
if (Player.Lives <= 0)
Stop();
else
Reset(false);
@ -251,14 +212,14 @@ namespace SnakeGame
LivesLabel.ForeColor = Color.White;
if (GameField[nextcoord.X, nextcoord.Y].Type == SquareType.Point)
{
Score += 1000;
Player.Score += 1000;
ScoreLabel.ForeColor = Color.Blue;
Game.AddPoint();
}
else
ScoreLabel.ForeColor = Color.White;
if (Score > 0)
Score -= new Random().Next(1, 20);
if (Player.Score > 0)
Player.Score -= new Random().Next(1, 20);
MovePlayerPost(Player, nextcoord);
}
GameRenderer.Render();
@ -277,16 +238,8 @@ namespace SnakeGame
GameField[x, y].Type = SquareType.Point;
}
/*public static SqCoord GetCoord(SqCoord nextcoord)
{
return GameField.Single(entry => entry.X == nextcoord.X && entry.Y == nextcoord.Y);
}*/
public static void Stop()
{
//Form1.Timer.Stop();
//Form1.TimerEnabled = false;
//MessageBox.Show("Game over!");
MSGBox.ShowMSGBox("Game over!", "", MSGBoxType.Text);
Game.Paused = true;
}
@ -312,9 +265,6 @@ namespace SnakeGame
nextcoord = player.Position;
break;
}
//GameField[nextcoord.X, nextcoord.Y].Tick = Length;
//GameField[nextcoord.X, nextcoord.Y].Type = SquareType.Player;
//player.Position = new Point { X = nextcoord.X, Y = nextcoord.Y };
return nextcoord;
}
public static void MovePlayerPost(Player player, Point point)

View file

@ -19,7 +19,6 @@ namespace SnakeGame
if (Shown)
return;
Game.DialogPanel.Controls.Add(new Label { Text = text, Location = new Point(10, 10), Font = new Font(FontFamily.GenericSansSerif, 10f), Size = new Size(200, 50) });
//TextBox input = null;
switch (type)
{
case MSGBoxType.Text:
@ -30,14 +29,6 @@ namespace SnakeGame
Game.DialogPanel.Size = new Size(200, 200);
Game.DialogPanel.Controls.Add(new Label { Text = inputtext, Location = new Point(10, 60), Size = new Size(100, 20) });
slidervalue = 20;
/*Game.DialogPanel.Controls.Add(input = new TextBox
{
Text = "",
Location = new Point(10, 60),
Multiline = false,
Font = new Font(FontFamily.GenericSansSerif, 10f),
Size = new Size(100, 1)
});*/
Graphics gr = Game.DialogPanel.CreateGraphics();
gr.FillRectangle(new SolidBrush(Color.Blue), new Rectangle(10, 80, slidervalue, slidervalue));
Game.DialogPanel.Paint += delegate
@ -81,7 +72,6 @@ namespace SnakeGame
strs = inputtext.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
else
strs = new string[0];
//Game.DialogPanel.Controls.Add(new Label { Text = strs[0], Location = new Point(10, 60), Size = new Size(100, 20) });
ListBox listbox = new ListBox { Location = new Point(10, 60), Size = new Size(190, 100) };
for (int i = 0; i < strs.Length; i++)
{
@ -112,7 +102,6 @@ namespace SnakeGame
{
Shown = false;
if (doneevent != null)
//doneevent(btn, (input == null ? "" : input.Text));
doneevent(btn, slidervalue.ToString());
CloseMSGBox();
};
@ -178,12 +167,7 @@ namespace SnakeGame
Game.DialogPanel.Visible = false;
Game.DialogPanel.Controls.Clear();
OnCloseEvent = null;
//Game.Paused = pause;
//Form1.Instance.Activate();
//GameRenderer.Panel.Select();
//Form1.Instance.Select();
Form1.Instance.Focus();
//Shown = false;
}
}
public enum MSGBoxType

View file

@ -7,6 +7,7 @@ using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -21,7 +22,12 @@ namespace SnakeGame
//Connect to the server
TcpClient client = new TcpClient(AddressFamily.InterNetworkV6);
client.Connect(ConnectedMatch.OwnerIP, Port);
var ns = client.GetStream();
var ns = client.GetStream().ToSafeNetStream();
Thread t = Thread.CurrentThread;
ns.ErrorStopClient = client;
ns.ErrorStopThread = t;
var sw = new BinaryWriter(ns);
sw.Write(52);
JObject writedata = new JObject();

View file

@ -43,7 +43,7 @@ namespace SnakeGame
private static void ThreadPerPlayer(object c)
{
TcpClient client = c as TcpClient;
NetworkStream ns = client.GetStream();
SafeNetStream ns = client.GetStream().ToSafeNetStream(client, Thread.CurrentThread);
BinaryReader br = new BinaryReader(ns);
StopEventPerPlayer += delegate
{
@ -122,12 +122,14 @@ namespace SnakeGame
if (ConnectedMatch.OwnerName == Game.Player.Name)
{
Player p;
while (ConnectedMatch.Players.GetEnumerator().MoveNext())
//while (ConnectedMatch.Players.GetEnumerator().MoveNext())
var en = ConnectedMatch.Players.GetEnumerator();
while(en.MoveNext())
{
p = ConnectedMatch.Players.GetEnumerator().Current;
if (p == null || p.Name == player.Name || p.Name == Game.Player.Name)
continue;
var bw = new BinaryWriter(p.Client.GetStream());
var bw = new BinaryWriter(p.Client.GetStream().ToSafeNetStream(p.Client, Thread.CurrentThread));
bw.Write(playername);
bw.Write(updatetype);
yield return bw;

View file

@ -33,11 +33,15 @@ namespace SnakeGame
bool isserver = ConnectedMatch.OwnerName == Game.Player.Name;
if (!isserver)
{
bw = new BinaryWriter(ConnectedMatch.GetPlayerByName(ConnectedMatch.OwnerName).Client.GetStream()); //If not server, send only to server
//bw = new BinaryWriter(ConnectedMatch.GetPlayerByName(ConnectedMatch.OwnerName).Client.GetStream().ToSafeNetStream()); //If not server, send only to server
var c = ConnectedMatch.GetPlayerByName(ConnectedMatch.OwnerName).Client; //If not server, send only to server
bw = new BinaryWriter(c.GetStream().ToSafeNetStream(c, null));
}
else
{
bw = new BinaryWriter(player.Client.GetStream());
//bw = new BinaryWriter(player.Client.GetStream().ToSafeNetStream());
var c = player.Client;
bw = new BinaryWriter(c.GetStream().ToSafeNetStream(c, null));
bw.Write(Game.Player.Name); //Otherwise write playername as listener expects
}
bw.Write((int)updatetype);
@ -62,6 +66,18 @@ namespace SnakeGame
bw.Write(point.X);
bw.Write(point.Y);
break;
case NetUpdateType.Score:
int score = (int)data;
bw.Write(score);
break;
case NetUpdateType.Lives:
int lives = (int)data;
bw.Write(lives);
break;
case NetUpdateType.Pause:
bool pause = (bool)data;
bw.Write(pause);
break;
}
if (!isserver)
break; //If not server, only send to the server
@ -280,6 +296,27 @@ namespace SnakeGame
bw.Write(player.Position.Y);
}
break;
case NetUpdateType.Score:
player.Score = br.ReadInt32();
foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
{
bw.Write(player.Score);
}
break;
case NetUpdateType.Lives:
player.Lives = br.ReadInt32();
foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
{
bw.Write(player.Lives);
}
break;
case NetUpdateType.Pause:
Form1.SetTimerWithoutSend(!br.ReadBoolean());
foreach(BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype))
{
bw.Write(Game.Paused);
}
break;
}
}
catch (IOException)
@ -300,6 +337,9 @@ namespace SnakeGame
Move,
//Login, - Login==Connect
Leave,
Teleport
Teleport,
Score,
Lives,
Pause
}
}

View file

@ -44,8 +44,36 @@ namespace SnakeGame
}
public Point Position;
public TcpClient Client;
public int Score;
public int Lives;
private int score;
public int Score
{
get
{
return score;
}
set
{
score = value;
if (Own)
Network.SyncUpdate(NetUpdateType.Score, value);
Form1.RefreshPlayerList();
}
}
private int lives;
public int Lives
{
get
{
return lives;
}
set
{
lives = value;
if (Own)
Network.SyncUpdate(NetUpdateType.Lives, value);
Form1.RefreshPlayerList();
}
}
//public readonly int ID;
public readonly bool Own;
public Player(string name, bool own = false, Color color = default(Color), int x = 0, int y = 0)
@ -61,7 +89,10 @@ namespace SnakeGame
//NextID++;
Own = own;
//Position = new Point(0, 0);
Position = new Point(x, y);
if (x != 0 && y != 0)
Position = new Point(x, y);
else
Position = new Point(Game.GameSize.X / 2, 1);
Score = 0;
Lives = 3;
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -21,7 +22,11 @@ namespace SnakeGame
public static void HandleException(Exception e)
{
MessageBox.Show("Error!\n" + e.Message);
if (e.GetType() == typeof(ThreadAbortException))
{
}
else
MessageBox.Show("Error!\n" + e.Message);
}
}
}

136
SnakeGame/SafeNetStream.cs Normal file
View file

@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SnakeGame
{
public class SafeNetStream : Stream
{
private NetworkStream _ns;
//public event EventHandler ErrorEvent;
public TcpClient ErrorStopClient;
public Thread ErrorStopThread;
public override bool CanRead
{
get { return _ns.CanRead; }
}
public override bool CanSeek
{
get { return _ns.CanSeek; }
}
public override bool CanWrite
{
get { return _ns.CanWrite; }
}
public override void Flush()
{
try
{
_ns.Flush();
}
catch (IOException)
{
/*if (ErrorEvent != null)
ErrorEvent(this, EventArgs.Empty);*/
OnError();
}
}
public override long Length
{
get { return _ns.Length; }
}
public override long Position
{
get
{
return _ns.Position;
}
set
{
_ns.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
try
{
return _ns.Read(buffer, offset, count);
}
catch (IOException)
{
OnError();
return 0;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
return _ns.Seek(offset, origin);
}
public override void SetLength(long value)
{
try
{
_ns.SetLength(value);
}
catch (IOException)
{
OnError();
}
}
public override void Write(byte[] buffer, int offset, int count)
{
try
{
_ns.Write(buffer, offset, count);
}
catch(IOException)
{
OnError();
}
}
public SafeNetStream(NetworkStream stream, TcpClient errorstopclient, Thread errorstopthread)
{
_ns = stream;
ErrorStopClient = errorstopclient;
ErrorStopThread = errorstopthread;
}
private void OnError()
{
try
{
if (ErrorStopClient != null)
ErrorStopClient.Close();
}
catch { }
try
{
if (ErrorStopThread != null)
ErrorStopThread.Abort();
}
catch { }
}
}
public static class SafeNetStreamExt
{
public static SafeNetStream ToSafeNetStream(this NetworkStream stream, TcpClient errorstopclient = null, Thread errorstopthread = null)
{
return new SafeNetStream(stream, errorstopclient, errorstopthread);
}
}
}

View file

@ -68,6 +68,7 @@
<Compile Include="Player.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SafeNetStream.cs" />
<Compile Include="SquareCoord.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>