Server Ok but not the ball
This commit is contained in:
+23
-88
@@ -1,127 +1,62 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using MonoGame.Extended;
|
using MonoGame.Extended;
|
||||||
using MonoGame.Extended.Timers;
|
using MonoGame.Extended.Collisions;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace client
|
namespace client
|
||||||
{
|
{
|
||||||
internal class Ball
|
internal class Ball: IEntity
|
||||||
{
|
{
|
||||||
public Vector2 Position = new Vector2(0, 0);
|
public Vector2 DefaultPosition;
|
||||||
public Vector2 DefaultPosition = new Vector2(0, 0);
|
|
||||||
public int Radius = 5;
|
// Movements
|
||||||
|
public Vector2 Velocity;
|
||||||
public bool CanMove = false;
|
public bool CanMove = false;
|
||||||
|
public IShapeF Bounds { get; }
|
||||||
// Movement
|
|
||||||
private float MoveX = 0f;
|
|
||||||
private float MoveY = 0f;
|
|
||||||
private float Speed = 100f;
|
|
||||||
|
|
||||||
Random random = new Random();
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
public Ball(GraphicsDevice graphicsDevice, GameTime gameTime)
|
public Ball(CircleF circleF)
|
||||||
{
|
{
|
||||||
}
|
Bounds = circleF;
|
||||||
|
DefaultPosition = Bounds.Position;
|
||||||
public Ball(Vector2 position, int radius, float speed)
|
|
||||||
{
|
|
||||||
Position = position;
|
|
||||||
DefaultPosition = position;
|
|
||||||
Radius = radius;
|
|
||||||
Speed = speed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default Position
|
// Default Position
|
||||||
public Ball GetBackToDefaultPos()
|
public Ball GetBackToDefaultPos()
|
||||||
{
|
{
|
||||||
Position = DefaultPosition;
|
Bounds.Position = DefaultPosition;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw ball
|
// Draw ball
|
||||||
public Ball Draw(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
|
spriteBatch.DrawCircle((CircleF)Bounds, 10, Color.White, 3f);
|
||||||
spriteBatch.DrawCircle(
|
|
||||||
Position,
|
|
||||||
Radius,
|
|
||||||
360,
|
|
||||||
Color.White,
|
|
||||||
Radius
|
|
||||||
);
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start | Stop ball moving
|
// Start | Stop ball moving
|
||||||
public Ball StartMoving()
|
public void StartMoving()
|
||||||
{
|
{
|
||||||
/*MoveX = random.Next((int)-Speed, (int)Speed);
|
|
||||||
MoveY = 1000f;*/
|
|
||||||
MoveX = Speed;
|
|
||||||
MoveY = Speed;
|
|
||||||
CanMove = true;
|
CanMove = true;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Ball Move(GameTime gameTime, float screenHeight, float screenWidth, Player p1, Player p2)
|
public void Update(GameTime gameTime)
|
||||||
{
|
{
|
||||||
if (CanMove)
|
if (CanMove)
|
||||||
{
|
{
|
||||||
/*// X
|
Bounds.Position += Velocity * gameTime.GetElapsedSeconds() * 50;
|
||||||
if (Position.X < 0)
|
|
||||||
{
|
|
||||||
MoveX -= Speed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MoveX += Speed;
|
|
||||||
}
|
|
||||||
// Y
|
|
||||||
if (Position.Y < 0)
|
|
||||||
{
|
|
||||||
MoveY -= Speed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MoveY += Speed;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Position.X += MoveX + Speed;
|
|
||||||
Position.Y += MoveY + Speed;
|
|
||||||
|
|
||||||
// Collisions
|
|
||||||
if (Position.Y < Radius * 2 && MoveY < 0)
|
|
||||||
{
|
|
||||||
MoveY = Math.Abs(MoveY);
|
|
||||||
}
|
|
||||||
if (Position.Y > screenHeight - Radius * 2 && MoveY > 0)
|
|
||||||
{
|
|
||||||
MoveY = -MoveY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
Position.X < p1.Position.X + p1.width && Position.X > p1.Position.X && Position.Y > p1.Position.Y && Position.Y < p1.Position.Y + p1.height ||
|
|
||||||
Position.X + Radius * 2 > p2.Position.X && Position.X + Radius * 2 < p2.Position.X + p2.width && Position.Y > p2.Position.Y && Position.Y < p2.Position.Y + p2.height
|
|
||||||
)
|
|
||||||
{
|
|
||||||
MoveX = -MoveX;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Ball StopMoving()
|
public void StopMoving()
|
||||||
{
|
{
|
||||||
CanMove = false;
|
CanMove = false;
|
||||||
return this;
|
}
|
||||||
|
|
||||||
|
// Collisions
|
||||||
|
public void OnCollision(CollisionEventArgs collisionInfo)
|
||||||
|
{
|
||||||
|
Bounds.Position -= collisionInfo.PenetrationVector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+143
-64
@@ -1,34 +1,54 @@
|
|||||||
using System;
|
using LiteNetLib;
|
||||||
using System.Collections.Generic;
|
|
||||||
using LiteNetLib;
|
|
||||||
using LiteNetLib.Utils;
|
using LiteNetLib.Utils;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using MonoGame.Extended;
|
||||||
|
using MonoGame.Extended.Collisions;
|
||||||
using shared;
|
using shared;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace client
|
namespace client
|
||||||
{
|
{
|
||||||
public class Game1 : Game
|
public class Game1 : Game
|
||||||
{
|
{
|
||||||
// Network
|
// Network
|
||||||
EventBasedNetListener listener = new();
|
EventBasedNetListener listener;
|
||||||
NetManager client;
|
NetManager client;
|
||||||
NetPeer server;
|
NetPeer _server;
|
||||||
NetPacketProcessor processor = new();
|
NetPacketProcessor processor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
None => Waiting for minimum 2 clients
|
||||||
|
Idle => Preparaing the game, waiting for client 1 to start the game
|
||||||
|
Playing => Game actually playing
|
||||||
|
Paused => Game paused by a player
|
||||||
|
Ended => Game Ended, waiting for client 1 decision (exiting or restart)
|
||||||
|
Disconnected => One of the two players has been disconnected
|
||||||
|
*/
|
||||||
|
string gameState = "None";
|
||||||
|
/*
|
||||||
|
1 => Player 1
|
||||||
|
2 => Player 2
|
||||||
|
3 => Spectator (default)
|
||||||
|
*/
|
||||||
|
int controller = 2;
|
||||||
|
|
||||||
// Game instances
|
// Game instances
|
||||||
private Player pl1;
|
private Player pl1;
|
||||||
private Player pl2;
|
private Player pl2;
|
||||||
private Ball ball;
|
private Ball ball;
|
||||||
|
private ScreenBounds sb1;
|
||||||
|
private ScreenBounds sb2;
|
||||||
private KillZone killZone1;
|
private KillZone killZone1;
|
||||||
private KillZone killZone2;
|
private KillZone killZone2;
|
||||||
|
|
||||||
private UI UI;
|
|
||||||
private SpriteFont spriteFont;
|
|
||||||
|
|
||||||
private GraphicsDeviceManager _graphics;
|
private GraphicsDeviceManager _graphics;
|
||||||
private SpriteBatch _spriteBatch;
|
private SpriteBatch _spriteBatch;
|
||||||
|
|
||||||
|
private CollisionComponent _collisionComponent;
|
||||||
|
private readonly List<IEntity> _entities = new List<IEntity>();
|
||||||
|
|
||||||
public Game1()
|
public Game1()
|
||||||
{
|
{
|
||||||
_graphics = new GraphicsDeviceManager(this);
|
_graphics = new GraphicsDeviceManager(this);
|
||||||
@@ -39,91 +59,128 @@ namespace client
|
|||||||
if (!settings.ContainsKey("SERVER_IP") || (settings.ContainsKey("SERVER_IP") && Lib.ReadSetting("SERVER_IP") == null))
|
if (!settings.ContainsKey("SERVER_IP") || (settings.ContainsKey("SERVER_IP") && Lib.ReadSetting("SERVER_IP") == null))
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Server IP missing in config file!");
|
Console.Error.WriteLine("Server IP missing in config file!");
|
||||||
} else if (!settings.ContainsKey("PORT") || (settings.ContainsKey("PORT") && Lib.ReadSetting("PORT") == null))
|
}
|
||||||
|
else if (!settings.ContainsKey("PORT") || (settings.ContainsKey("PORT") && Lib.ReadSetting("PORT") == null))
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Port missing in config file!");
|
Console.Error.WriteLine("Port missing in config file!");
|
||||||
} else if (!settings.ContainsKey("PSWD") || (settings.ContainsKey("PSWD") && Lib.ReadSetting("PSWD") == null))
|
}
|
||||||
|
else if (!settings.ContainsKey("PSWD") || (settings.ContainsKey("PSWD") && Lib.ReadSetting("PSWD") == null))
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Server password missing in config file!");
|
Console.Error.WriteLine("Server password missing in config file!");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
|
_collisionComponent = new CollisionComponent(new RectangleF(0, 0, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight));
|
||||||
// Network
|
// Network
|
||||||
|
listener = new EventBasedNetListener();
|
||||||
|
processor = new NetPacketProcessor();
|
||||||
|
|
||||||
|
listener.PeerConnectedEvent += server =>
|
||||||
|
{
|
||||||
|
_server = server;
|
||||||
|
Console.WriteLine($"Connected to {server}");
|
||||||
|
};
|
||||||
|
|
||||||
|
listener.NetworkReceiveEvent += (server, reader, deliveryMethod) =>
|
||||||
|
{
|
||||||
|
processor.ReadAllPackets(reader, server);
|
||||||
|
};
|
||||||
|
|
||||||
|
processor.SubscribeReusable<GameStateChange>(GameStateHandler);
|
||||||
|
processor.SubscribeReusable<Assignation>(AssignationHandler);
|
||||||
|
processor.SubscribeReusable<Position>(Positionhandler);
|
||||||
|
|
||||||
client = new NetManager(listener);
|
client = new NetManager(listener);
|
||||||
client.Start();
|
client.Start();
|
||||||
server = client.Connect(Lib.ReadSetting("SERVER_IP"), int.Parse(Lib.ReadSetting("PORT")), Lib.ReadSetting("PSWD"));
|
client.Connect(Lib.ReadSetting("SERVER_IP"), int.Parse(Lib.ReadSetting("PORT")), Lib.ReadSetting("PSWD"));
|
||||||
if (server == null)
|
|
||||||
{
|
|
||||||
// TODO: Replace by a error message :)
|
|
||||||
Exit();
|
|
||||||
}
|
|
||||||
processor.SubscribeReusable<Assignation>(AssignationHandler);
|
|
||||||
|
|
||||||
// Window
|
// Window
|
||||||
Window.Title = "Pong";
|
Window.Title = "Pong";
|
||||||
|
Window.AllowAltF4 = false;
|
||||||
// UI
|
|
||||||
UI = new UI();
|
|
||||||
|
|
||||||
// PLAYERS
|
// PLAYERS
|
||||||
pl1 = new Player(
|
pl1 = new Player(
|
||||||
new Vector2(15, _graphics.PreferredBackBufferHeight / 2 - 50),
|
new RectangleF(new Point(15, _graphics.PreferredBackBufferHeight / 2 - 50), new Size2(15, 100)),
|
||||||
15,
|
_graphics.PreferredBackBufferHeight,
|
||||||
100,
|
processor
|
||||||
100f
|
|
||||||
);
|
);
|
||||||
|
_entities.Add(pl1);
|
||||||
|
|
||||||
pl2 = new Player(
|
pl2 = new Player(
|
||||||
new Vector2(_graphics.PreferredBackBufferWidth - 30, _graphics.PreferredBackBufferHeight / 2 - 50),
|
new RectangleF(new Point(_graphics.PreferredBackBufferWidth - 30, _graphics.PreferredBackBufferHeight / 2 - 50), new Size2(15, 100)),
|
||||||
15,
|
_graphics.PreferredBackBufferHeight,
|
||||||
100,
|
processor
|
||||||
100f
|
|
||||||
);
|
);
|
||||||
|
_entities.Add(pl2);
|
||||||
|
|
||||||
// BALL
|
// BALL
|
||||||
ball = new Ball(
|
ball = new Ball(
|
||||||
new Vector2(_graphics.PreferredBackBufferWidth / 2 - 5, _graphics.PreferredBackBufferHeight / 2 - 5),
|
new CircleF(new Point(_graphics.PreferredBackBufferWidth / 2 - 10, _graphics.PreferredBackBufferHeight / 2 - 10), 10)
|
||||||
10,
|
|
||||||
1f
|
|
||||||
);
|
);
|
||||||
|
_entities.Add(ball);
|
||||||
|
|
||||||
|
// SCREEN BOUNDS
|
||||||
|
sb1 = new ScreenBounds(
|
||||||
|
new RectangleF(new Point(0, -1), new Size2(_graphics.PreferredBackBufferWidth, 1))
|
||||||
|
);
|
||||||
|
_entities.Add(sb1);
|
||||||
|
sb2 = new ScreenBounds(
|
||||||
|
new RectangleF(new Point(0, _graphics.PreferredBackBufferHeight), new Size2(_graphics.PreferredBackBufferWidth, 1))
|
||||||
|
);
|
||||||
|
_entities.Add(sb2);
|
||||||
|
|
||||||
// KILLZONE
|
// KILLZONE
|
||||||
killZone1 = new KillZone(
|
/*killZone1 = new KillZone(
|
||||||
new Vector2(0, 0),
|
new Vector2(0, 0),
|
||||||
15,
|
15,
|
||||||
_graphics.PreferredBackBufferHeight
|
_graphics.PreferredBackBufferHeight
|
||||||
);
|
);
|
||||||
|
_entities.Add(killZone1);
|
||||||
|
|
||||||
killZone2 = new KillZone(
|
killZone2 = new KillZone(
|
||||||
new Vector2(_graphics.PreferredBackBufferWidth - 15, 0),
|
new Vector2(_graphics.PreferredBackBufferWidth - 15, 0),
|
||||||
15,
|
15,
|
||||||
_graphics.PreferredBackBufferHeight
|
_graphics.PreferredBackBufferHeight
|
||||||
);
|
);
|
||||||
killZone2.isLeft = false;
|
killZone2.isLeft = false;
|
||||||
|
_entities.Add(killZone2);*/
|
||||||
|
|
||||||
|
|
||||||
// TEST
|
foreach (IEntity actor in _entities)
|
||||||
ball.StartMoving();
|
{
|
||||||
|
_collisionComponent.Insert(actor);
|
||||||
|
}
|
||||||
|
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnExiting(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
client.DisconnectPeer(_server);
|
||||||
|
base.OnExiting(sender, args);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void LoadContent()
|
protected override void LoadContent()
|
||||||
{
|
{
|
||||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||||
spriteFont = Content.Load<SpriteFont>("scoreFont");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update(GameTime gameTime)
|
protected override void Update(GameTime gameTime)
|
||||||
{
|
{
|
||||||
pl1.InputsControls(gameTime, _graphics.PreferredBackBufferHeight);
|
// Network
|
||||||
|
client.PollEvents();
|
||||||
|
|
||||||
ball.Move(gameTime, _graphics.PreferredBackBufferHeight, _graphics.PreferredBackBufferWidth, pl1, pl2);
|
pl1.UpdateStats(controller, gameState, _server);
|
||||||
|
pl2.UpdateStats(controller, gameState, _server);
|
||||||
|
foreach (IEntity entity in _entities)
|
||||||
|
{
|
||||||
|
entity.Update(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
killZone1.Collisions(ball);
|
_collisionComponent.Update(gameTime);
|
||||||
killZone2.Collisions(ball);
|
|
||||||
|
|
||||||
base.Update(gameTime);
|
base.Update(gameTime);
|
||||||
}
|
}
|
||||||
@@ -133,37 +190,59 @@ namespace client
|
|||||||
GraphicsDevice.Clear(Color.Black);
|
GraphicsDevice.Clear(Color.Black);
|
||||||
_spriteBatch.Begin();
|
_spriteBatch.Begin();
|
||||||
|
|
||||||
UI.Draw(_spriteBatch, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight, spriteFont, 0, 0);
|
foreach (IEntity entitiy in _entities)
|
||||||
|
{
|
||||||
pl1.DrawPlayer(_spriteBatch, GraphicsDevice);
|
entitiy.Draw(_spriteBatch);
|
||||||
pl2.DrawPlayer(_spriteBatch, GraphicsDevice);
|
}
|
||||||
|
|
||||||
ball.Draw(_spriteBatch, GraphicsDevice);
|
|
||||||
|
|
||||||
killZone1.Draw(_spriteBatch, GraphicsDevice);
|
|
||||||
killZone2.Draw(_spriteBatch, GraphicsDevice);
|
|
||||||
|
|
||||||
_spriteBatch.End();
|
_spriteBatch.End();
|
||||||
base.Draw(gameTime);
|
base.Draw(gameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Network
|
||||||
private void AssignationHandler(Assignation assignation)
|
private void AssignationHandler(Assignation assignation)
|
||||||
{
|
{
|
||||||
if (assignation != null)
|
controller = assignation.controller;
|
||||||
|
ball.Velocity = new Vector2(assignation.ballX, assignation.ballY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Positionhandler(Position position)
|
||||||
|
{
|
||||||
|
if (!pl1.canMove && position.controller == 0)
|
||||||
{
|
{
|
||||||
if (assignation.controller == 0) {
|
pl1.setPos(new Vector2(position.x, position.y));
|
||||||
|
}
|
||||||
|
else if (!pl2.canMove && position.controller == 1)
|
||||||
|
{
|
||||||
|
pl2.setPos(new Vector2(position.x, position.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GameStateHandler(GameStateChange change)
|
||||||
|
{
|
||||||
|
gameState = change.gameState;
|
||||||
|
|
||||||
|
if (gameState == "Playing")
|
||||||
|
{
|
||||||
|
if (controller == 0)
|
||||||
|
{
|
||||||
pl1.SetControllable(true);
|
pl1.SetControllable(true);
|
||||||
pl2.SetControllable(false);
|
pl2.SetControllable(false);
|
||||||
}
|
}
|
||||||
else
|
else if (controller == 1)
|
||||||
{
|
{
|
||||||
pl1.SetControllable(false);
|
pl1.SetControllable(false);
|
||||||
pl2.SetControllable(true);
|
pl2.SetControllable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ball.StartMoving();
|
||||||
}
|
}
|
||||||
else
|
else if (gameState == "Paused" || gameState == "Ended" || gameState == "Disconnected")
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Packet malformed!");
|
pl1.SetControllable(false);
|
||||||
|
pl2.SetControllable(false);
|
||||||
|
|
||||||
|
ball.StopMoving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using MonoGame.Extended.Collisions;
|
||||||
|
|
||||||
|
namespace client
|
||||||
|
{
|
||||||
|
public interface IEntity : ICollisionActor
|
||||||
|
{
|
||||||
|
public void Update(GameTime gameTime);
|
||||||
|
public void Draw(SpriteBatch spriteBatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -44,7 +44,7 @@ namespace client
|
|||||||
spriteBatch.Draw(texture, Position, Color.White);
|
spriteBatch.Draw(texture, Position, Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Collisions(Ball ball)
|
/*public void Collisions(Ball ball)
|
||||||
{
|
{
|
||||||
if (isLeft)
|
if (isLeft)
|
||||||
{
|
{
|
||||||
@@ -60,6 +60,6 @@ namespace client
|
|||||||
//ball.StopMoving();
|
//ball.StopMoving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+94
-86
@@ -1,116 +1,124 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using LiteNetLib;
|
||||||
|
using LiteNetLib.Utils;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
using System;
|
using MonoGame.Extended;
|
||||||
using System.Collections.Generic;
|
using MonoGame.Extended.Collisions;
|
||||||
using System.Linq;
|
using shared;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace client
|
namespace client
|
||||||
{
|
{
|
||||||
internal class Player
|
internal class Player : IEntity
|
||||||
{
|
{
|
||||||
public Vector2 Position { get; set; }
|
|
||||||
private Vector2 DefaultPosition { get; set; }
|
public Vector2 Velocity;
|
||||||
public int width;
|
public IShapeF Bounds { get; }
|
||||||
public int height;
|
public float _screenHeight;
|
||||||
public float speed;
|
|
||||||
public bool canMove = false;
|
public bool canMove = false;
|
||||||
|
private Vector2 DefaultPosition { get; set; }
|
||||||
|
|
||||||
|
// Network
|
||||||
|
NetPeer _server;
|
||||||
|
NetPacketProcessor _processor;
|
||||||
|
int _controller = 3;
|
||||||
|
string _gameState = "None";
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
public Player()
|
public Player(RectangleF rectangleF, float screenHeight, NetPacketProcessor processor)
|
||||||
{
|
{
|
||||||
Position = new Vector2(0, 0);
|
Bounds = rectangleF;
|
||||||
DefaultPosition = new Vector2(0, 0);
|
_screenHeight = screenHeight;
|
||||||
width = 20;
|
DefaultPosition = Bounds.Position;
|
||||||
height = 100;
|
_processor = processor;
|
||||||
speed = 100f;
|
|
||||||
|
Velocity = new Vector2(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player(Vector2 position, int width, int height, float speed)
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
Position = position;
|
spriteBatch.DrawRectangle((RectangleF)Bounds, Color.White, 3);
|
||||||
DefaultPosition = position;
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
this.speed = speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the player's position
|
|
||||||
public Player setPos(Vector2 pos)
|
|
||||||
{
|
|
||||||
Position = pos;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set | Get default player position
|
|
||||||
public Player setDefaultPos(Vector2 pos)
|
|
||||||
{
|
|
||||||
DefaultPosition = pos;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 getDefaultPos()
|
|
||||||
{
|
|
||||||
return DefaultPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player BackToDefaultPos()
|
|
||||||
{
|
|
||||||
Position = DefaultPosition;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set controllable by input
|
|
||||||
public Player SetControllable(bool state)
|
|
||||||
{
|
|
||||||
canMove = state;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw player on screen
|
|
||||||
public Player DrawPlayer(SpriteBatch spriteBatch, GraphicsDevice _graphicsDevice)
|
|
||||||
{
|
|
||||||
Texture2D texture = new Texture2D(_graphicsDevice, width, height);
|
|
||||||
Color[] data = new Color[width * height];
|
|
||||||
for (int i = 0; i < data.Length; ++i)
|
|
||||||
{
|
|
||||||
data[i] = Color.White;
|
|
||||||
}
|
|
||||||
texture.SetData(data);
|
|
||||||
|
|
||||||
spriteBatch.Draw(texture, Position, Color.White);
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inputs controls
|
// Inputs controls
|
||||||
public Player InputsControls(GameTime gameTime, float screenHeight)
|
public void Update(GameTime gameTime)
|
||||||
{
|
{
|
||||||
if (canMove)
|
if (canMove)
|
||||||
{
|
{
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.Up))
|
if (Keyboard.GetState().IsKeyDown(Keys.Up) || Keyboard.GetState().IsKeyDown(Keys.Down))
|
||||||
{
|
{
|
||||||
Vector2 asked = new Vector2(Position.X, Position.Y - speed * (float)gameTime.ElapsedGameTime.TotalSeconds);
|
if (Keyboard.GetState().IsKeyDown(Keys.Up))
|
||||||
if (asked.Y <= 0)
|
|
||||||
{
|
{
|
||||||
asked.Y = 0f;
|
float asked = Bounds.Position.Y - Velocity.Y * gameTime.GetElapsedSeconds() * 50;
|
||||||
|
if (asked <= 0f)
|
||||||
|
{
|
||||||
|
asked = 0f;
|
||||||
|
}
|
||||||
|
Bounds.Position = new Vector2(Bounds.Position.X, asked);
|
||||||
}
|
}
|
||||||
Position = asked;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.Down))
|
if (Keyboard.GetState().IsKeyDown(Keys.Down))
|
||||||
{
|
|
||||||
Vector2 asked = new Vector2(Position.X, Position.Y + speed * (float)gameTime.ElapsedGameTime.TotalSeconds);
|
|
||||||
if (asked.Y >= screenHeight - height)
|
|
||||||
{
|
{
|
||||||
asked.Y = screenHeight - height;
|
float asked = Bounds.Position.Y + Velocity.Y * gameTime.GetElapsedSeconds() * 50;
|
||||||
|
if (asked >= _screenHeight)
|
||||||
|
{
|
||||||
|
asked = _screenHeight;
|
||||||
|
}
|
||||||
|
Bounds.Position = new Vector2(Bounds.Position.X, asked);
|
||||||
}
|
}
|
||||||
Position = asked;
|
|
||||||
|
Position packet = new() { controller = _controller, x = Bounds.Position.X, y = Bounds.Position.Y };
|
||||||
|
_processor.Send(_server, packet, DeliveryMethod.ReliableOrdered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
|
||||||
|
// START / RESTART
|
||||||
|
if (_controller == 0 && (_gameState == "Idle" || _gameState == "Ended") && Keyboard.GetState().IsKeyDown(Keys.Space))
|
||||||
|
{
|
||||||
|
GameStateChange packet = new() { gameState = "Playing" };
|
||||||
|
_processor.Send(_server, packet, DeliveryMethod.ReliableOrdered);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PAUSE SWITCH
|
||||||
|
if (Keyboard.GetState().IsKeyDown(Keys.Escape) && _controller == 0)
|
||||||
|
{
|
||||||
|
if (_gameState == "Playing")
|
||||||
|
{
|
||||||
|
GameStateChange packet = new() { gameState = "Paused" };
|
||||||
|
_processor.Send(_server, packet, DeliveryMethod.ReliableOrdered);
|
||||||
|
}
|
||||||
|
else if (_gameState == "Paused")
|
||||||
|
{
|
||||||
|
GameStateChange packet = new() { gameState = "Playing" };
|
||||||
|
_processor.Send(_server, packet, DeliveryMethod.ReliableOrdered);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCollision(CollisionEventArgs collisionsInfos) { }
|
||||||
|
|
||||||
|
public void setPos(Vector2 pos)
|
||||||
|
{
|
||||||
|
Bounds.Position = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BackToDefaultPos()
|
||||||
|
{
|
||||||
|
Bounds.Position = DefaultPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetControllable(bool state)
|
||||||
|
{
|
||||||
|
canMove = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateStats(int controller, string gameState, NetPeer server)
|
||||||
|
{
|
||||||
|
_controller = controller;
|
||||||
|
_gameState = gameState;
|
||||||
|
_server = server;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using MonoGame.Extended;
|
||||||
|
using MonoGame.Extended.Collisions;
|
||||||
|
|
||||||
|
namespace client
|
||||||
|
{
|
||||||
|
internal class ScreenBounds : IEntity
|
||||||
|
{
|
||||||
|
public IShapeF Bounds { get; }
|
||||||
|
|
||||||
|
public ScreenBounds(RectangleF rectangleF)
|
||||||
|
{
|
||||||
|
Bounds = rectangleF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
|
{
|
||||||
|
spriteBatch.DrawRectangle((RectangleF)Bounds, Color.White, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(GameTime gameTime) { }
|
||||||
|
|
||||||
|
public void OnCollision(CollisionEventArgs collisionInfos) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
using MonoGame.Extended;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace client
|
|
||||||
{
|
|
||||||
internal class UI
|
|
||||||
{
|
|
||||||
public UI()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, float screenWidth, float screenHeight, SpriteFont spriteFont, int score1, int score2)
|
|
||||||
{
|
|
||||||
// Lines
|
|
||||||
int divider = 21;
|
|
||||||
for(int i = 0; i < screenHeight / divider; i++)
|
|
||||||
{
|
|
||||||
if (i % 2 == 0)
|
|
||||||
{
|
|
||||||
spriteBatch.DrawLine(
|
|
||||||
new Vector2(screenWidth / 2, screenHeight / divider * i),
|
|
||||||
new Vector2(screenWidth / 2, screenHeight / divider * (i+1)),
|
|
||||||
Color.White
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scores
|
|
||||||
int spacing = 25;
|
|
||||||
spriteBatch.DrawString(spriteFont, $"{score1}", new Vector2(screenWidth / 2 - spriteFont.MeasureString($"{score1}").X - spacing, 5), Color.LightGray);
|
|
||||||
spriteBatch.DrawString(spriteFont, $"{score2}", new Vector2(screenWidth / 2 + spacing, 5), Color.LightGray);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<RollForward>Major</RollForward>
|
<RollForward>Major</RollForward>
|
||||||
<PublishReadyToRun>false</PublishReadyToRun>
|
<PublishReadyToRun>false</PublishReadyToRun>
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="LiteNetLib" Version="0.9.5.2" />
|
<PackageReference Include="LiteNetLib" Version="0.9.5.2" />
|
||||||
<PackageReference Include="MonoGame.Extended" Version="3.8.0" />
|
<PackageReference Include="MonoGame.Extended" Version="3.8.0" />
|
||||||
|
<PackageReference Include="MonoGame.Extended.Collisions" Version="3.8.0" />
|
||||||
|
<PackageReference Include="MonoGame.Extended.Content.Pipeline" Version="3.8.0" />
|
||||||
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
|
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
|
||||||
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
|
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
|
||||||
<PackageReference Include="MonoGame.UI.Forms" Version="1.0.1" />
|
<PackageReference Include="MonoGame.UI.Forms" Version="1.0.1" />
|
||||||
|
|||||||
+81
-19
@@ -6,36 +6,60 @@ namespace Server
|
|||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
static EventBasedNetListener listener = new();
|
static EventBasedNetListener listener;
|
||||||
static NetManager? server;
|
static NetManager server;
|
||||||
static NetPacketProcessor processor = new();
|
static NetPacketProcessor processor;
|
||||||
static NetSerializer serializer = new();
|
|
||||||
|
|
||||||
static string? port;
|
static string? port;
|
||||||
static string? pswd;
|
static string? pswd;
|
||||||
|
/*
|
||||||
static string gameState = "Idle"; // Idle || Playing || Paused || Ended
|
None => Waiting for minimum 2 clients
|
||||||
|
Idle => Preparaing the game, waiting for client 1 to start the game
|
||||||
|
Playing => Game actually playing
|
||||||
|
Paused => Game paused by a player
|
||||||
|
Ended => Game Ended, waiting for client 1 decision (exiting or restart)
|
||||||
|
Disconnected => One of the two players has been disconnected
|
||||||
|
*/
|
||||||
|
static string gameState = "None";
|
||||||
|
static List<NetPeer> activeConnections;
|
||||||
static List<NetPeer> players;
|
static List<NetPeer> players;
|
||||||
|
|
||||||
|
// Game
|
||||||
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
Random random = new Random(Guid.NewGuid().GetHashCode());
|
||||||
|
// Application
|
||||||
|
Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
|
||||||
|
|
||||||
|
listener = new EventBasedNetListener();
|
||||||
server = new NetManager(listener);
|
server = new NetManager(listener);
|
||||||
|
processor = new NetPacketProcessor();
|
||||||
|
|
||||||
|
activeConnections = new List<NetPeer>();
|
||||||
|
players = new List<NetPeer>();
|
||||||
|
|
||||||
|
processor.SubscribeReusable<GameStateChange>(GameStateHandler);
|
||||||
|
processor.SubscribeReusable<Position>(PositionHandler);
|
||||||
|
|
||||||
|
|
||||||
port = Lib.ReadSetting("PORT");
|
port = Lib.ReadSetting("PORT");
|
||||||
pswd = Lib.ReadSetting("PSWD");
|
pswd = Lib.ReadSetting("PSWD");
|
||||||
|
|
||||||
if (port != null && pswd != null)
|
if (port != null && pswd != null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Server started on port {port}");
|
|
||||||
server.Start(int.Parse(port));
|
server.Start(int.Parse(port));
|
||||||
|
Console.WriteLine($"Server started on port {port}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Missing port or password in config file !\nClosing server...");
|
Console.Error.WriteLine("Missing port or password in config file !\nClosing server...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
listener.NetworkReceiveEvent += (client, reader, deliveryMethod) =>
|
||||||
serializer.Register<Assignation>();
|
{
|
||||||
|
processor.ReadAllPackets(reader, client);
|
||||||
|
};
|
||||||
|
|
||||||
listener.ConnectionRequestEvent += request =>
|
listener.ConnectionRequestEvent += request =>
|
||||||
{
|
{
|
||||||
@@ -48,29 +72,50 @@ namespace Server
|
|||||||
Console.WriteLine("Connection accepted for: {0}", peer.EndPoint);
|
Console.WriteLine("Connection accepted for: {0}", peer.EndPoint);
|
||||||
if (peer != null)
|
if (peer != null)
|
||||||
{
|
{
|
||||||
players.Add(peer);
|
activeConnections.Add(peer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
listener.PeerDisconnectedEvent += (peer, infos) =>
|
listener.PeerDisconnectedEvent += (peer, infos) =>
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{peer.EndPoint} has left.\nError code: {infos.SocketErrorCode}\nReason: {infos.Reason}");
|
Console.WriteLine($"{peer.EndPoint} has left.\nError code: {infos.SocketErrorCode}\nReason: {infos.Reason}");
|
||||||
players.Remove(peer);
|
activeConnections.Remove(peer);
|
||||||
|
if (players.Contains(peer))
|
||||||
|
{
|
||||||
|
players.Remove(peer);
|
||||||
|
gameState = "Disconnected";
|
||||||
|
GameStateChange packet = new() { gameState = "Disconnected" };
|
||||||
|
server.SendToAll(processor.Write(packet), DeliveryMethod.ReliableOrdered);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeConnections.Count < 2)
|
||||||
|
{
|
||||||
|
gameState = "None";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
while (!Console.KeyAvailable)
|
while (!Console.KeyAvailable)
|
||||||
{
|
{
|
||||||
server.PollEvents();
|
server.PollEvents();
|
||||||
if (server.GetPeersCount(ConnectionState.Connected) >= 2)
|
if (activeConnections.Count >= 2)
|
||||||
{
|
{
|
||||||
// Differents game states
|
// Differents game states
|
||||||
if (gameState == "Idle")
|
if (gameState == "None")
|
||||||
{
|
{
|
||||||
Assignation packet = new() { controller = 2, ballX = 0, ballY = 0 };
|
float MoveX = new float[2] { -2f, 2f }[random.Next(2)];
|
||||||
processor.Send(players[0], packet, DeliveryMethod.ReliableOrdered);
|
float MoveY = new float[2] { -2f, 2f }[random.Next(2)];
|
||||||
processor.Send(players[1], packet, DeliveryMethod.ReliableOrdered);
|
Assignation packet = new() { controller = 0, ballX = MoveX, ballY = MoveY };
|
||||||
Console.WriteLine("Assignation sended");
|
processor.Send(activeConnections[0], packet, DeliveryMethod.ReliableOrdered);
|
||||||
gameState = "Playing";
|
players.Add(activeConnections[0]);
|
||||||
|
|
||||||
|
packet.controller = 1;
|
||||||
|
|
||||||
|
processor.Send(activeConnections[1], packet, DeliveryMethod.ReliableOrdered);
|
||||||
|
players.Add(activeConnections[1]);
|
||||||
|
|
||||||
|
gameState = "Idle";
|
||||||
|
Console.WriteLine($"Change GameState to {gameState}");
|
||||||
|
server.SendToAll(processor.Write(new GameStateChange() { gameState = "Idle" }), DeliveryMethod.ReliableOrdered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Thread.Sleep(15);
|
Thread.Sleep(15);
|
||||||
@@ -78,5 +123,22 @@ namespace Server
|
|||||||
|
|
||||||
server.Stop();
|
server.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
|
||||||
|
{
|
||||||
|
server.DisconnectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PositionHandler(Position position)
|
||||||
|
{
|
||||||
|
server.SendToAll(processor.Write(position), DeliveryMethod.ReliableOrdered);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GameStateHandler(GameStateChange change)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Change GameState to {change.gameState}");
|
||||||
|
gameState = change.gameState;
|
||||||
|
server.SendToAll(processor.Write(change), DeliveryMethod.ReliableOrdered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,4 +6,16 @@
|
|||||||
public float ballX { get; set; }
|
public float ballX { get; set; }
|
||||||
public float ballY { get; set; }
|
public float ballY { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Position
|
||||||
|
{
|
||||||
|
public int controller { get; set; }
|
||||||
|
public float x { get; set; }
|
||||||
|
public float y { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GameStateChange
|
||||||
|
{
|
||||||
|
public string gameState { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user