Skip to content

Commit

Permalink
20 camera movement (#22)
Browse files Browse the repository at this point in the history
* Started adding camera system
Cleaned up Gamemodel file

* Basic camera working

---------

Co-authored-by: Maxwell Edwards <[email protected]>
  • Loading branch information
caden-maxwell and MaxEdwards20 authored Apr 1, 2024
1 parent e3678ce commit a70e7db
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 197 deletions.
292 changes: 150 additions & 142 deletions src/Client/GameModel.cs
Original file line number Diff line number Diff line change
@@ -1,177 +1,185 @@
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Shared.Entities;

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Client.Menu;
using Microsoft.Xna.Framework;

using Shared.Components;
using Shared.Components.Appearance;
using Shared.Entities;

namespace Client;

namespace Client
public class GameModel
{
public class GameModel
private ContentManager m_contentManager;
private Dictionary<uint, Entity> m_entities;
private Systems.Network m_systemNetwork;
private Systems.Camera m_systemCamera;
private Systems.KeyboardInput m_systemKeyboardInput;
private Systems.Interpolation m_systemInterpolation;
private Systems.Renderer m_systemRenderer;
private Controls m_controls;
private GraphicsDeviceManager m_graphics;

/// <summary>
/// This is where everything performs its update.
/// </summary>
public void update(TimeSpan elapsedTime)
{
private ContentManager m_contentManager;
private Dictionary<uint, Entity> m_entities;
private Systems.Network m_systemNetwork;
private Systems.KeyboardInput m_systemKeyboardInput;
private Systems.Interpolation m_systemInterpolation;
private Systems.Renderer m_systemRenderer;
private Controls m_controls;

/// <summary>
/// This is where everything performs its update.
/// </summary>
public void update(TimeSpan elapsedTime)
{
m_systemNetwork.update(elapsedTime, MessageQueueClient.instance.getMessages());
m_systemKeyboardInput.update(elapsedTime);
m_systemInterpolation.update(elapsedTime);
}
m_systemNetwork.update(elapsedTime, MessageQueueClient.instance.getMessages());
m_systemKeyboardInput.update(elapsedTime);
m_systemInterpolation.update(elapsedTime);
m_systemCamera.update(elapsedTime);
}

/// <summary>
/// Where we render everything
/// </summary>
/// <summary>
/// Where we render everything
/// </summary>

public void render(TimeSpan elapsedTime, SpriteBatch spriteBatch)
{
m_systemRenderer.render(elapsedTime, spriteBatch);
}
public void render(TimeSpan elapsedTime, SpriteBatch spriteBatch)
{
m_systemRenderer.render(elapsedTime, spriteBatch);
}

/// <summary>
/// This is where all game model initialization occurs. In the case
/// of this "game', start by initializing the systems and then
/// loading the art assets.
/// </summary>
public bool initialize(ContentManager contentManager, Controls controls, GraphicsDeviceManager graphics)
{
m_contentManager = contentManager;
m_entities = new Dictionary<uint, Entity>();
m_systemInterpolation = new Systems.Interpolation();
m_systemCamera = new Systems.Camera();
m_systemRenderer = new Systems.Renderer(m_systemCamera, graphics);
m_systemNetwork = new Systems.Network();

m_systemNetwork.registerNewEntityHandler(handleNewEntity);
m_systemNetwork.registerRemoveEntityHandler(handleRemoveEntity);
m_controls = controls;

m_systemKeyboardInput = new Systems.KeyboardInput(new List<Tuple<Shared.Components.Input.Type, Keys>>
{ }, m_controls);

/// <summary>
/// This is where all game model initialization occurs. In the case
/// of this "game', start by initializing the systems and then
/// loading the art assets.
/// </summary>
public bool initialize(ContentManager contentManager, Controls controls)
return true;
}

public void shutdown()
{

}

/// <summary>
/// Based upon an Entity received from the server, create the
/// entity at the client.
/// </summary>
private Entity createEntity(Shared.Messages.NewEntity message)
{
Entity entity = new Entity(message.id);

if (message.hasAppearance)
{
m_contentManager = contentManager;
m_entities = new Dictionary<uint, Entity>();
m_systemInterpolation = new Systems.Interpolation();
m_systemRenderer = new Systems.Renderer();
m_systemNetwork = new Systems.Network();

m_systemNetwork.registerNewEntityHandler(handleNewEntity);
m_systemNetwork.registerRemoveEntityHandler(handleRemoveEntity);
m_controls = controls;

m_systemKeyboardInput = new Systems.KeyboardInput(new List<Tuple<Shared.Components.Input.Type, Keys>>
{ }, m_controls);

return true;
Texture2D texture = m_contentManager.Load<Texture2D>(message.texture);
entity.add(new Components.Sprite(texture));
}

public void shutdown()
if (message.hasPosition)
{

entity.add(new Shared.Components.Position(message.position, message.orientation));
}

/// <summary>
/// Based upon an Entity received from the server, create the
/// entity at the client.
/// </summary>
private Entity createEntity(Shared.Messages.NewEntity message)
if (message.hasSize)
{
Entity entity = new Entity(message.id);

if (message.hasAppearance)
{
Texture2D texture = m_contentManager.Load<Texture2D>(message.texture);
entity.add(new Components.Sprite(texture));
}
if (message.hasPosition)
{
entity.add(new Shared.Components.Position(message.position, message.orientation));
}

if (message.hasSize)
{
entity.add(new Shared.Components.Size(message.size));
}

if (message.hasMovement)
{
entity.add(new Shared.Components.Movement(message.moveRate, message.rotateRate));
}

if (message.hasInput)
{
entity.add(new Shared.Components.Input(message.inputs));
}

return entity;
entity.add(new Shared.Components.Size(message.size));
}

/// <summary>
/// As entities are added to the game model, they are run by the systems
/// to see if they are interested in knowing about them during their
/// updates.
/// </summary>
private void addEntity(Entity entity)
if (message.hasMovement)
{
if (entity == null)
{
return;
}
// TODO: Update the systems we use here
m_entities[entity.id] = entity;
m_systemKeyboardInput.add(entity);
m_systemRenderer.add(entity);
m_systemNetwork.add(entity);
m_systemInterpolation.add(entity);
entity.add(new Shared.Components.Movement(message.moveRate, message.rotateRate));
}

/// <summary>
/// All entity lists for the systems must be given a chance to remove
/// the entity.
/// </summary>
private void removeEntity(uint id)
if (message.hasInput)
{
// TODO: Update the systems we use here
m_entities.Remove(id);
m_systemKeyboardInput.remove(id);
m_systemNetwork.remove(id);
m_systemRenderer.remove(id);
m_systemInterpolation.remove(id);
entity.add(new Shared.Components.Input(message.inputs));
}

private void handleNewEntity(Shared.Messages.NewEntity message)
return entity;
}

/// <summary>
/// As entities are added to the game model, they are run by the systems
/// to see if they are interested in knowing about them during their
/// updates.
/// </summary>
private void addEntity(Entity entity)
{
if (entity == null)
{
Entity entity = createEntity(message);
addEntity(entity);
return;
}
// TODO: Update the systems we use here
m_entities[entity.id] = entity;
m_systemKeyboardInput.add(entity);
m_systemRenderer.add(entity);
m_systemNetwork.add(entity);
m_systemInterpolation.add(entity);
m_systemCamera.add(entity);
}

/// <summary>
/// All entity lists for the systems must be given a chance to remove
/// the entity.
/// </summary>
private void removeEntity(uint id)
{
// TODO: Update the systems we use here
m_entities.Remove(id);
m_systemKeyboardInput.remove(id);
m_systemNetwork.remove(id);
m_systemRenderer.remove(id);
m_systemInterpolation.remove(id);
m_systemCamera.remove(id);
}

private void handleNewEntity(Shared.Messages.NewEntity message)
{
Entity entity = createEntity(message);
addEntity(entity);
}

/// <summary>
/// Handler for the RemoveEntity message. It removes the entity from
/// the client game model (that's us!).
/// </summary>
private void handleRemoveEntity(Shared.Messages.RemoveEntity message)
/// <summary>
/// Handler for the RemoveEntity message. It removes the entity from
/// the client game model (that's us!).
/// </summary>
private void handleRemoveEntity(Shared.Messages.RemoveEntity message)
{
removeEntity(message.id);
}

private Color parseColor(string color)
{
// Pattern to extract the RGBA values from the string
var pattern = @"\{R:(\d+)\sG:(\d+)\sB:(\d+)\sA:(\d+)\}";
var match = Regex.Match(color, pattern);
if (match.Success)
{
removeEntity(message.id);
// Extracting the RGBA values
int r = int.Parse(match.Groups[1].Value);
int g = int.Parse(match.Groups[2].Value);
int b = int.Parse(match.Groups[3].Value);
int a = int.Parse(match.Groups[4].Value);

// Creating a new Color object with the extracted values
return new Color(r, g, b, a);
}

private Color parseColor(string color)
else
{
// Pattern to extract the RGBA values from the string
var pattern = @"\{R:(\d+)\sG:(\d+)\sB:(\d+)\sA:(\d+)\}";
var match = Regex.Match(color, pattern);
if (match.Success)
{
// Extracting the RGBA values
int r = int.Parse(match.Groups[1].Value);
int g = int.Parse(match.Groups[2].Value);
int b = int.Parse(match.Groups[3].Value);
int a = int.Parse(match.Groups[4].Value);

// Creating a new Color object with the extracted values
return new Color(r, g, b, a);
}else{
// If the string does not match the pattern, return a default color
return Color.White;
}
// If the string does not match the pattern, return a default color
return Color.White;
}
}
}

3 changes: 1 addition & 2 deletions src/Client/Menu/GamePlayView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class GamePlayView : GameStateView
private TimeSpan m_connectToServerTime = TimeSpan.Zero;
private Controls m_controls;


public GamePlayView(Controls controls)
{
m_controls = controls;
Expand All @@ -30,7 +29,7 @@ public GamePlayView(Controls controls)
public override void initialize()
{
m_gameModel = new GameModel();
m_gameModel.initialize(m_contentManager, m_controls);
m_gameModel.initialize(m_contentManager, m_controls, m_graphics);
m_isSetup = false;
m_isKeyboardRegistered = false;
m_newState = MenuStateEnum.GamePlay;
Expand Down
29 changes: 28 additions & 1 deletion src/Client/Systems/Camera.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
using Microsoft.Xna.Framework;
using Shared.Entities;
using System;
using System.Diagnostics;
using System.Linq;

namespace Client.Systems;

public class Camera : Shared.Systems.System
{
private Rectangle m_viewport = new();
public Rectangle Viewport { get { return m_viewport; } }

public Camera() :
base(
typeof(Shared.Components.Position),
typeof(Shared.Components.Movement),
typeof(Shared.Components.Input)
)
{ }

public override void update(TimeSpan elapsedTime)
{
throw new NotImplementedException();
if (m_entities.Count > 1)
throw new Exception("Got an invalid number of players on the client side.");

if (m_entities.Count < 1)
{
Debug.WriteLine("No Player Found");
return;
}

Entity player = m_entities.Values.ToArray()[0];
Point pos = player.get<Shared.Components.Position>().position.ToPoint();

m_viewport.Location = pos;
}
}
Loading

0 comments on commit a70e7db

Please sign in to comment.