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.Graphics;
|
||||
using MonoGame.Extended;
|
||||
using MonoGame.Extended.Timers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MonoGame.Extended.Collisions;
|
||||
|
||||
namespace client
|
||||
{
|
||||
internal class Ball
|
||||
internal class Ball: IEntity
|
||||
{
|
||||
public Vector2 Position = new Vector2(0, 0);
|
||||
public Vector2 DefaultPosition = new Vector2(0, 0);
|
||||
public int Radius = 5;
|
||||
public Vector2 DefaultPosition;
|
||||
|
||||
// Movements
|
||||
public Vector2 Velocity;
|
||||
public bool CanMove = false;
|
||||
|
||||
// Movement
|
||||
private float MoveX = 0f;
|
||||
private float MoveY = 0f;
|
||||
private float Speed = 100f;
|
||||
|
||||
Random random = new Random();
|
||||
public IShapeF Bounds { get; }
|
||||
|
||||
// Constructors
|
||||
public Ball(GraphicsDevice graphicsDevice, GameTime gameTime)
|
||||
public Ball(CircleF circleF)
|
||||
{
|
||||
}
|
||||
|
||||
public Ball(Vector2 position, int radius, float speed)
|
||||
{
|
||||
Position = position;
|
||||
DefaultPosition = position;
|
||||
Radius = radius;
|
||||
Speed = speed;
|
||||
Bounds = circleF;
|
||||
DefaultPosition = Bounds.Position;
|
||||
}
|
||||
|
||||
// Default Position
|
||||
public Ball GetBackToDefaultPos()
|
||||
{
|
||||
Position = DefaultPosition;
|
||||
Bounds.Position = DefaultPosition;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Draw ball
|
||||
public Ball Draw(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
|
||||
spriteBatch.DrawCircle(
|
||||
Position,
|
||||
Radius,
|
||||
360,
|
||||
Color.White,
|
||||
Radius
|
||||
);
|
||||
return this;
|
||||
spriteBatch.DrawCircle((CircleF)Bounds, 10, Color.White, 3f);
|
||||
}
|
||||
|
||||
// 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;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Ball Move(GameTime gameTime, float screenHeight, float screenWidth, Player p1, Player p2)
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
if (CanMove)
|
||||
{
|
||||
/*// X
|
||||
if (Position.X < 0)
|
||||
{
|
||||
MoveX -= Speed;
|
||||
Bounds.Position += Velocity * gameTime.GetElapsedSeconds() * 50;
|
||||
}
|
||||
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;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Collisions
|
||||
public void OnCollision(CollisionEventArgs collisionInfo)
|
||||
{
|
||||
Bounds.Position -= collisionInfo.PenetrationVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+133
-54
@@ -1,34 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using LiteNetLib;
|
||||
using LiteNetLib;
|
||||
using LiteNetLib.Utils;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using MonoGame.Extended;
|
||||
using MonoGame.Extended.Collisions;
|
||||
using shared;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace client
|
||||
{
|
||||
public class Game1 : Game
|
||||
{
|
||||
// Network
|
||||
EventBasedNetListener listener = new();
|
||||
EventBasedNetListener listener;
|
||||
NetManager client;
|
||||
NetPeer server;
|
||||
NetPacketProcessor processor = new();
|
||||
NetPeer _server;
|
||||
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
|
||||
private Player pl1;
|
||||
private Player pl2;
|
||||
private Ball ball;
|
||||
private ScreenBounds sb1;
|
||||
private ScreenBounds sb2;
|
||||
private KillZone killZone1;
|
||||
private KillZone killZone2;
|
||||
|
||||
private UI UI;
|
||||
private SpriteFont spriteFont;
|
||||
|
||||
private GraphicsDeviceManager _graphics;
|
||||
private SpriteBatch _spriteBatch;
|
||||
|
||||
private CollisionComponent _collisionComponent;
|
||||
private readonly List<IEntity> _entities = new List<IEntity>();
|
||||
|
||||
public Game1()
|
||||
{
|
||||
_graphics = new GraphicsDeviceManager(this);
|
||||
@@ -39,62 +59,86 @@ namespace client
|
||||
if (!settings.ContainsKey("SERVER_IP") || (settings.ContainsKey("SERVER_IP") && Lib.ReadSetting("SERVER_IP") == null))
|
||||
{
|
||||
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!");
|
||||
} 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!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
_collisionComponent = new CollisionComponent(new RectangleF(0, 0, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight));
|
||||
// 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.Start();
|
||||
server = 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);
|
||||
client.Connect(Lib.ReadSetting("SERVER_IP"), int.Parse(Lib.ReadSetting("PORT")), Lib.ReadSetting("PSWD"));
|
||||
|
||||
// Window
|
||||
Window.Title = "Pong";
|
||||
|
||||
// UI
|
||||
UI = new UI();
|
||||
Window.AllowAltF4 = false;
|
||||
|
||||
// PLAYERS
|
||||
pl1 = new Player(
|
||||
new Vector2(15, _graphics.PreferredBackBufferHeight / 2 - 50),
|
||||
15,
|
||||
100,
|
||||
100f
|
||||
new RectangleF(new Point(15, _graphics.PreferredBackBufferHeight / 2 - 50), new Size2(15, 100)),
|
||||
_graphics.PreferredBackBufferHeight,
|
||||
processor
|
||||
);
|
||||
_entities.Add(pl1);
|
||||
|
||||
pl2 = new Player(
|
||||
new Vector2(_graphics.PreferredBackBufferWidth - 30, _graphics.PreferredBackBufferHeight / 2 - 50),
|
||||
15,
|
||||
100,
|
||||
100f
|
||||
new RectangleF(new Point(_graphics.PreferredBackBufferWidth - 30, _graphics.PreferredBackBufferHeight / 2 - 50), new Size2(15, 100)),
|
||||
_graphics.PreferredBackBufferHeight,
|
||||
processor
|
||||
);
|
||||
_entities.Add(pl2);
|
||||
|
||||
// BALL
|
||||
ball = new Ball(
|
||||
new Vector2(_graphics.PreferredBackBufferWidth / 2 - 5, _graphics.PreferredBackBufferHeight / 2 - 5),
|
||||
10,
|
||||
1f
|
||||
new CircleF(new Point(_graphics.PreferredBackBufferWidth / 2 - 10, _graphics.PreferredBackBufferHeight / 2 - 10), 10)
|
||||
);
|
||||
_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
|
||||
killZone1 = new KillZone(
|
||||
/*killZone1 = new KillZone(
|
||||
new Vector2(0, 0),
|
||||
15,
|
||||
_graphics.PreferredBackBufferHeight
|
||||
);
|
||||
_entities.Add(killZone1);
|
||||
|
||||
killZone2 = new KillZone(
|
||||
new Vector2(_graphics.PreferredBackBufferWidth - 15, 0),
|
||||
@@ -102,28 +146,41 @@ namespace client
|
||||
_graphics.PreferredBackBufferHeight
|
||||
);
|
||||
killZone2.isLeft = false;
|
||||
_entities.Add(killZone2);*/
|
||||
|
||||
|
||||
// TEST
|
||||
ball.StartMoving();
|
||||
foreach (IEntity actor in _entities)
|
||||
{
|
||||
_collisionComponent.Insert(actor);
|
||||
}
|
||||
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
protected override void OnExiting(object sender, EventArgs args)
|
||||
{
|
||||
client.DisconnectPeer(_server);
|
||||
base.OnExiting(sender, args);
|
||||
}
|
||||
|
||||
protected override void LoadContent()
|
||||
{
|
||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||
spriteFont = Content.Load<SpriteFont>("scoreFont");
|
||||
}
|
||||
|
||||
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);
|
||||
killZone2.Collisions(ball);
|
||||
_collisionComponent.Update(gameTime);
|
||||
|
||||
base.Update(gameTime);
|
||||
}
|
||||
@@ -133,37 +190,59 @@ namespace client
|
||||
GraphicsDevice.Clear(Color.Black);
|
||||
_spriteBatch.Begin();
|
||||
|
||||
UI.Draw(_spriteBatch, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight, spriteFont, 0, 0);
|
||||
|
||||
pl1.DrawPlayer(_spriteBatch, GraphicsDevice);
|
||||
pl2.DrawPlayer(_spriteBatch, GraphicsDevice);
|
||||
|
||||
ball.Draw(_spriteBatch, GraphicsDevice);
|
||||
|
||||
killZone1.Draw(_spriteBatch, GraphicsDevice);
|
||||
killZone2.Draw(_spriteBatch, GraphicsDevice);
|
||||
foreach (IEntity entitiy in _entities)
|
||||
{
|
||||
entitiy.Draw(_spriteBatch);
|
||||
}
|
||||
|
||||
_spriteBatch.End();
|
||||
base.Draw(gameTime);
|
||||
}
|
||||
|
||||
// Network
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (assignation.controller == 0) {
|
||||
pl1.SetControllable(true);
|
||||
pl2.SetControllable(false);
|
||||
}
|
||||
else
|
||||
else if (controller == 1)
|
||||
{
|
||||
pl1.SetControllable(false);
|
||||
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);
|
||||
}
|
||||
|
||||
public void Collisions(Ball ball)
|
||||
/*public void Collisions(Ball ball)
|
||||
{
|
||||
if (isLeft)
|
||||
{
|
||||
@@ -60,6 +60,6 @@ namespace client
|
||||
//ball.StopMoving();
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
+90
-82
@@ -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.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MonoGame.Extended;
|
||||
using MonoGame.Extended.Collisions;
|
||||
using shared;
|
||||
|
||||
namespace client
|
||||
{
|
||||
internal class Player
|
||||
internal class Player : IEntity
|
||||
{
|
||||
public Vector2 Position { get; set; }
|
||||
private Vector2 DefaultPosition { get; set; }
|
||||
public int width;
|
||||
public int height;
|
||||
public float speed;
|
||||
|
||||
public Vector2 Velocity;
|
||||
public IShapeF Bounds { get; }
|
||||
public float _screenHeight;
|
||||
|
||||
public bool canMove = false;
|
||||
private Vector2 DefaultPosition { get; set; }
|
||||
|
||||
// Network
|
||||
NetPeer _server;
|
||||
NetPacketProcessor _processor;
|
||||
int _controller = 3;
|
||||
string _gameState = "None";
|
||||
|
||||
// Constructors
|
||||
public Player()
|
||||
public Player(RectangleF rectangleF, float screenHeight, NetPacketProcessor processor)
|
||||
{
|
||||
Position = new Vector2(0, 0);
|
||||
DefaultPosition = new Vector2(0, 0);
|
||||
width = 20;
|
||||
height = 100;
|
||||
speed = 100f;
|
||||
Bounds = rectangleF;
|
||||
_screenHeight = screenHeight;
|
||||
DefaultPosition = Bounds.Position;
|
||||
_processor = processor;
|
||||
|
||||
Velocity = new Vector2(0, 2);
|
||||
}
|
||||
|
||||
public Player(Vector2 position, int width, int height, float speed)
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
Position = position;
|
||||
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;
|
||||
spriteBatch.DrawRectangle((RectangleF)Bounds, Color.White, 3);
|
||||
}
|
||||
|
||||
// Inputs controls
|
||||
public Player InputsControls(GameTime gameTime, float screenHeight)
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
if (canMove)
|
||||
{
|
||||
if (Keyboard.GetState().IsKeyDown(Keys.Up) || Keyboard.GetState().IsKeyDown(Keys.Down))
|
||||
{
|
||||
if (Keyboard.GetState().IsKeyDown(Keys.Up))
|
||||
{
|
||||
Vector2 asked = new Vector2(Position.X, Position.Y - speed * (float)gameTime.ElapsedGameTime.TotalSeconds);
|
||||
if (asked.Y <= 0)
|
||||
float asked = Bounds.Position.Y - Velocity.Y * gameTime.GetElapsedSeconds() * 50;
|
||||
if (asked <= 0f)
|
||||
{
|
||||
asked.Y = 0f;
|
||||
asked = 0f;
|
||||
}
|
||||
Position = asked;
|
||||
Bounds.Position = new Vector2(Bounds.Position.X, asked);
|
||||
}
|
||||
|
||||
if (Keyboard.GetState().IsKeyDown(Keys.Down))
|
||||
{
|
||||
Vector2 asked = new Vector2(Position.X, Position.Y + speed * (float)gameTime.ElapsedGameTime.TotalSeconds);
|
||||
if (asked.Y >= screenHeight - height)
|
||||
float asked = Bounds.Position.Y + Velocity.Y * gameTime.GetElapsedSeconds() * 50;
|
||||
if (asked >= _screenHeight)
|
||||
{
|
||||
asked.Y = screenHeight - height;
|
||||
asked = _screenHeight;
|
||||
}
|
||||
Position = asked;
|
||||
Bounds.Position = new Vector2(Bounds.Position.X, 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">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RollForward>Major</RollForward>
|
||||
<PublishReadyToRun>false</PublishReadyToRun>
|
||||
@@ -21,6 +21,8 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LiteNetLib" Version="0.9.5.2" />
|
||||
<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.Content.Builder.Task" Version="3.8.1.303" />
|
||||
<PackageReference Include="MonoGame.UI.Forms" Version="1.0.1" />
|
||||
|
||||
+80
-18
@@ -6,36 +6,60 @@ namespace Server
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
static EventBasedNetListener listener = new();
|
||||
static NetManager? server;
|
||||
static NetPacketProcessor processor = new();
|
||||
static NetSerializer serializer = new();
|
||||
static EventBasedNetListener listener;
|
||||
static NetManager server;
|
||||
static NetPacketProcessor processor;
|
||||
|
||||
static string? port;
|
||||
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;
|
||||
|
||||
// Game
|
||||
|
||||
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);
|
||||
processor = new NetPacketProcessor();
|
||||
|
||||
activeConnections = new List<NetPeer>();
|
||||
players = new List<NetPeer>();
|
||||
|
||||
processor.SubscribeReusable<GameStateChange>(GameStateHandler);
|
||||
processor.SubscribeReusable<Position>(PositionHandler);
|
||||
|
||||
|
||||
port = Lib.ReadSetting("PORT");
|
||||
pswd = Lib.ReadSetting("PSWD");
|
||||
|
||||
if (port != null && pswd != null)
|
||||
{
|
||||
Console.WriteLine($"Server started on port {port}");
|
||||
server.Start(int.Parse(port));
|
||||
Console.WriteLine($"Server started on port {port}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine("Missing port or password in config file !\nClosing server...");
|
||||
return;
|
||||
}
|
||||
|
||||
serializer.Register<Assignation>();
|
||||
|
||||
listener.NetworkReceiveEvent += (client, reader, deliveryMethod) =>
|
||||
{
|
||||
processor.ReadAllPackets(reader, client);
|
||||
};
|
||||
|
||||
listener.ConnectionRequestEvent += request =>
|
||||
{
|
||||
@@ -48,29 +72,50 @@ namespace Server
|
||||
Console.WriteLine("Connection accepted for: {0}", peer.EndPoint);
|
||||
if (peer != null)
|
||||
{
|
||||
players.Add(peer);
|
||||
activeConnections.Add(peer);
|
||||
}
|
||||
};
|
||||
|
||||
listener.PeerDisconnectedEvent += (peer, infos) =>
|
||||
{
|
||||
Console.WriteLine($"{peer.EndPoint} has left.\nError code: {infos.SocketErrorCode}\nReason: {infos.Reason}");
|
||||
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)
|
||||
{
|
||||
server.PollEvents();
|
||||
if (server.GetPeersCount(ConnectionState.Connected) >= 2)
|
||||
if (activeConnections.Count >= 2)
|
||||
{
|
||||
// Differents game states
|
||||
if (gameState == "Idle")
|
||||
if (gameState == "None")
|
||||
{
|
||||
Assignation packet = new() { controller = 2, ballX = 0, ballY = 0 };
|
||||
processor.Send(players[0], packet, DeliveryMethod.ReliableOrdered);
|
||||
processor.Send(players[1], packet, DeliveryMethod.ReliableOrdered);
|
||||
Console.WriteLine("Assignation sended");
|
||||
gameState = "Playing";
|
||||
float MoveX = new float[2] { -2f, 2f }[random.Next(2)];
|
||||
float MoveY = new float[2] { -2f, 2f }[random.Next(2)];
|
||||
Assignation packet = new() { controller = 0, ballX = MoveX, ballY = MoveY };
|
||||
processor.Send(activeConnections[0], packet, DeliveryMethod.ReliableOrdered);
|
||||
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);
|
||||
@@ -78,5 +123,22 @@ namespace Server
|
||||
|
||||
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 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