Files
2022-10-26 09:39:39 +02:00

269 lines
8.6 KiB
C#

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;
NetManager client;
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";
/*
0 => Player 1
1 => Player 2
2 => Spectator (default)
*/
int controller = 2;
// Game params
int score1 = 0;
int score2 = 0;
// Game instances
private Player pl1;
private Player pl2;
private Ball ball;
private ScreenBounds sb1;
private ScreenBounds sb2;
private KillZone killZone1;
private KillZone killZone2;
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
private CollisionComponent _collisionComponent;
private readonly List<IEntity> _entities = new List<IEntity>();
// UIs
private GameUI _gameUI;
private SpriteFont gameFont;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
Dictionary<string, string> settings = Lib.ReadAllSettings();
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))
{
Console.Error.WriteLine("Port missing in config file!");
}
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();
client.Connect(Lib.ReadSetting("SERVER_IP"), int.Parse(Lib.ReadSetting("PORT")), Lib.ReadSetting("PSWD"));
// Window
Window.Title = "Pong";
Window.AllowAltF4 = false;
// PLAYERS
pl1 = new Player(
new RectangleF(new Point(15, _graphics.PreferredBackBufferHeight / 2 - 50), new Size2(15, 100)),
_graphics.PreferredBackBufferHeight,
100,
processor
);
_entities.Add(pl1);
pl2 = new Player(
new RectangleF(new Point(_graphics.PreferredBackBufferWidth - 30, _graphics.PreferredBackBufferHeight / 2 - 50), new Size2(15, 100)),
_graphics.PreferredBackBufferHeight,
100,
processor
);
_entities.Add(pl2);
// BALL
ball = new Ball(
new CircleF(new Point(_graphics.PreferredBackBufferWidth / 2, _graphics.PreferredBackBufferHeight / 2), 10)
);
_entities.Add(ball);
// SCREEN BOUNDS
sb1 = new ScreenBounds(
new RectangleF(new Point(0, -1), new Size2(_graphics.PreferredBackBufferWidth, 2))
);
_entities.Add(sb1);
sb2 = new ScreenBounds(
new RectangleF(new Point(0, _graphics.PreferredBackBufferHeight - 1), new Size2(_graphics.PreferredBackBufferWidth, 2))
);
_entities.Add(sb2);
// KILLZONE
killZone1 = new KillZone(
new RectangleF(new Point(-1, 0), new Size2(2, _graphics.PreferredBackBufferHeight)),
processor
);
_entities.Add(killZone1);
killZone2 = new KillZone(
new RectangleF(new Point(_graphics.PreferredBackBufferWidth - 1, 0), new Size2(2, _graphics.PreferredBackBufferHeight)),
processor
);
_entities.Add(killZone2);
foreach (IEntity actor in _entities)
{
_collisionComponent.Insert(actor);
}
// UI
_gameUI = new();
base.Initialize();
}
protected override void OnExiting(object sender, EventArgs args)
{
if (_server != null)
{
client.DisconnectPeer(_server);
}
base.OnExiting(sender, args);
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
gameFont = Content.Load<SpriteFont>("scoreFont");
}
protected override void Update(GameTime gameTime)
{
// Network
client.PollEvents();
pl1.UpdateStats(controller, gameState, _server);
pl2.UpdateStats(controller, gameState, _server);
killZone1.UpdateStat(_server, gameState);
killZone2.UpdateStat(_server, gameState);
foreach (IEntity entity in _entities)
{
entity.Update(gameTime);
}
_collisionComponent.Update(gameTime);
_gameUI.Update(score1, score2);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
_spriteBatch.Begin();
foreach (IEntity entitiy in _entities)
{
entitiy.Draw(_spriteBatch);
}
_gameUI.Draw(_spriteBatch, gameFont, new Size2(_graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight));
_spriteBatch.End();
base.Draw(gameTime);
}
// Network
private void AssignationHandler(Assignation assignation)
{
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)
{
pl1.SetControllable(true);
pl2.SetControllable(false);
}
else if (controller == 1)
{
pl1.SetControllable(false);
pl2.SetControllable(true);
}
ball.StartMoving();
}
else if (gameState == "Paused" || gameState == "Ended" || gameState == "Disconnected")
{
pl1.SetControllable(false);
pl2.SetControllable(false);
ball.StopMoving();
}
}
}
}