| using System; |
| using System.Collections.Generic; |
| using Microsoft.Xna.Framework; |
| using Microsoft.Xna.Framework.Audio; |
| using Microsoft.Xna.Framework.Content; |
| using Microsoft.Xna.Framework.GamerServices; |
| using Microsoft.Xna.Framework.Graphics; |
| using Microsoft.Xna.Framework.Input; |
| using Microsoft.Xna.Framework.Net; |
| using Microsoft.Xna.Framework.Storage; |
| using Lidgren.Library.Network; |
| |
| namespace Multiplayer |
| { |
| /// <summary> |
| /// This is the main type for your game |
| /// </summary> |
| public class Game1 : Microsoft.Xna.Framework.Game |
| { |
| GraphicsDeviceManager graphics; |
| SpriteBatch spriteBatch; |
| private KeyboardState ks; |
| public NetClient client; |
| public NetServer server; |
| private NetLog Log; |
| private NetAppConfiguration nac; |
| Texture2D backgroundTexture; |
| int currentPlayer = 0; |
| |
| GraphicsDevice device; |
| SpriteFont font; |
| |
| |
| int screenWidth; |
| int screenHeight; |
| |
| public Game1() |
| { |
| graphics = new GraphicsDeviceManager(this); |
| Content.RootDirectory = "Content"; |
| } |
| |
| /// <summary> |
| /// Allows the game to perform any initialization it needs to before starting to run. |
| /// This is where it can query for any required services and load any non-graphic |
| /// related content. Calling base.Initialize will enumerate through any components |
| /// and initialize them as well. |
| /// </summary> |
| protected override void Initialize() |
| { |
| graphics.PreferredBackBufferWidth = 1000; |
| graphics.PreferredBackBufferHeight = 700; |
| graphics.IsFullScreen = false; |
| graphics.ApplyChanges(); |
| |
| base.Initialize(); |
| } |
| |
| /// <summary> |
| /// LoadContent will be called once per game and is the place to load |
| /// all of your content. |
| /// </summary> |
| protected override void LoadContent() |
| { |
| device = graphics.GraphicsDevice; |
| spriteBatch = new SpriteBatch(GraphicsDevice); |
| |
| backgroundTexture = Content.Load<Texture2D>("Screens\\background"); |
| |
| screenWidth = device.PresentationParameters.BackBufferWidth; |
| screenHeight = device.PresentationParameters.BackBufferHeight; |
| font = Content.Load<SpriteFont>("menu"); |
| } |
| |
| /// <summary> |
| /// UnloadContent will be called once per game and is the place to unload |
| /// all content. |
| /// </summary> |
| protected override void UnloadContent() |
| { |
| // TODO: Unload any non ContentManager content here |
| } |
| |
| /// <summary> |
| /// Allows the game to run logic such as updating the world, |
| /// checking for collisions, gathering input, and playing audio. |
| /// </summary> |
| /// <param name="gameTime">Provides a snapshot of timing values.</param> |
| protected override void Update(GameTime gameTime) |
| { |
| // Allows the game to exit |
| if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) |
| this.Exit(); |
| |
| |
| if (client != null || server != null) |
| { |
| UpdateNetwork(); |
| } |
| else |
| { |
| ks = Keyboard.GetState(); |
| if (ks.IsKeyDown(Keys.H)) |
| { |
| HostClicked(); |
| } |
| if (ks.IsKeyDown(Keys.C)) |
| { |
| ClientClicked(); |
| } |
| } |
| |
| base.Update(gameTime); |
| } |
| |
| public void HostClicked() |
| { |
| this.Window.Title = "Hosting...."; |
| nac = new NetAppConfiguration("Rebaltanks", 12345); |
| nac.MaximumConnections = 32; |
| nac.ServerName = "Rebaltanks!"; |
| Log = new NetLog(); |
| server = new NetServer(nac, Log); |
| server.StatusChanged += new |
| EventHandler<NetStatusEventArgs>(server_StatusChanged); |
| } |
| |
| |
| public void ClientClicked() |
| { |
| this.Window.Title = "Trying To Connect...."; |
| |
| //Since this is a client we dont have to specify a port here |
| nac = new NetAppConfiguration("RebalTanks"); |
| Log = new NetLog(); |
| |
| //Im Using this to show how to log files, So we pick that we want |
| //to ignore nothing, Change this depending on what your |
| //wanting to log for various debugging. |
| Log.IgnoreTypes = NetLogEntryTypes.None; |
| |
| //Specify if you want to enable output to a file which we do. |
| Log.IsOutputToFileEnabled = true; |
| |
| //If we output to a file we have to pick a filename to output it to. |
| Log.OutputFileName = "Client.html"; |
| |
| //We Initiate the client here, it has not connected to the server yet. |
| client = new NetClient(nac, Log); |
| |
| //We Want to Log Events that are fired from the client |
| client.StatusChanged += |
| new EventHandler<NetStatusEventArgs>(server_StatusChanged); |
| |
| //Finally we connect to the server, Specify the IP Address and |
| //port if your wanting to connect to xxx.xxx.xxx.xxx |
| //we would change this line to "192.168.1.1",12345 |
| client.Connect("localhost", 12345); |
| } |
| |
| void server_StatusChanged(object sender, NetStatusEventArgs e) |
| { |
| |
| if (e.Connection.Status == NetConnectionStatus.Connected) |
| { |
| DrawGame(); |
| NetMessage msg = new NetMessage(); |
| msg.Write("Hello Server! I Am Connected And Able To Communicate!"); |
| client.SendMessage(msg, NetChannel.ReliableUnordered); |
| |
| |
| } |
| if (e.Connection.Status == NetConnectionStatus.Disconnected) |
| { |
| this.Window.Title = "We Were disconnected"; |
| } |
| } |
| |
| |
| public void UpdateNetwork() |
| { |
| if (client != null) |
| { |
| //this line here, Pumps the Session with any packets |
| //that we have received since last time. |
| client.Heartbeat(); |
| |
| //This will hold our NetMessage, or our packet |
| NetMessage msg; |
| |
| //This will be called for every message we have reveived, |
| //when the message is received we read the message from the packet. |
| while ((msg = client.ReadMessage()) != null) |
| { |
| //We will call this routing to handle the message |
| //and process it accordingly. |
| HandleMSG(msg); |
| } |
| } |
| //This is the same as uptop, just for the server. |
| if (server != null) |
| { |
| server.Heartbeat(); |
| NetMessage msg; |
| |
| while ((msg = server.ReadMessage()) != null) |
| { |
| HandleMSG(msg); |
| } |
| } |
| } |
| |
| public void HandleMSG(NetMessage msg) |
| { |
| string str = msg.ReadString(); |
| this.Window.Title = str; |
| } |
| |
| /// <summary> |
| /// This is called when the game should draw itself. |
| /// </summary> |
| /// <param name="gameTime">Provides a snapshot of timing values.</param> |
| protected override void Draw(GameTime gameTime) |
| { |
| graphics.GraphicsDevice.Clear(Color.CornflowerBlue); |
| base.Draw(gameTime); |
| } |
| |
| private void DrawScenery() |
| { |
| Rectangle screenRectangle = new Rectangle(0, 0, screenWidth, screenHeight); |
| spriteBatch.Draw(backgroundTexture, screenRectangle, Color.White); |
| } |
| |
| private void DrawText() |
| { |
| spriteBatch.DrawString(font, "H = Host Game", new Vector2(20, 45), Color.White); |
| spriteBatch.DrawString(font, "C = Connect to Game", new Vector2(20, 100), Color.White); |
| } |
| |
| private void DrawGame() |
| { |
| spriteBatch.DrawString(font, "GAMEPLAY!", new Vector2(20, 45), Color.Red); |
| } |
| } |
| } |
| |