Skip to content

Commit

Permalink
Mouse plumbing (#29)
Browse files Browse the repository at this point in the history
* Fixes crash

* Adds mouse plumbing

* Adds menu

* Adds todos and defaults to using the keyboard
  • Loading branch information
MaxEdwards20 authored Apr 2, 2024
1 parent d8906c7 commit d6912c6
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 46 deletions.
6 changes: 3 additions & 3 deletions src/Client/ClientMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class ClientMain : Game
private Texture2D m_background;
private GameModel m_gameModel;
private Controls m_controls;
private SettingsPersistence m_settingsPersistence;
private ControlsPersistence _mControlsPersistence;

public ClientMain()
{
Expand All @@ -36,7 +36,7 @@ public ClientMain()
IsMouseVisible = true;
m_gameModel = new GameModel();
m_controls = new Controls();
m_settingsPersistence = new SettingsPersistence();
_mControlsPersistence = new ControlsPersistence();

}

Expand All @@ -49,7 +49,7 @@ protected override void Initialize()

// Load the controls
// We pass in our own controls so we always have them as a default if they were not saved
m_settingsPersistence.LoadControls(m_controls);
_mControlsPersistence.LoadControls(m_controls);

// Create all the game states here
m_states = new Dictionary<MenuStateEnum, IGameState>
Expand Down
9 changes: 7 additions & 2 deletions src/Client/GameModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class GameModel
private Systems.Network m_systemNetwork;
private Systems.Camera m_systemCamera;
private Systems.KeyboardInput m_systemKeyboardInput;
private Systems.MouseInput m_systemMouseInput;
private Systems.Interpolation m_systemInterpolation;
private Systems.Renderer m_systemRenderer;
private Controls m_controls;
Expand All @@ -31,6 +32,7 @@ public void update(TimeSpan elapsedTime)
{
m_systemNetwork.update(elapsedTime, MessageQueueClient.instance.getMessages());
m_systemKeyboardInput.update(elapsedTime);
m_systemMouseInput.update(elapsedTime);
m_systemInterpolation.update(elapsedTime);
m_systemCamera.update(elapsedTime);
}
Expand Down Expand Up @@ -64,6 +66,7 @@ public bool initialize(ContentManager contentManager, Controls controls, Graphic

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

return true;
}
Expand Down Expand Up @@ -147,9 +150,10 @@ private void addEntity(Entity entity)
{
return;
}
// TODO: Update the systems we use here
// NOTE: Update the systems we use here
m_entities[entity.id] = entity;
m_systemKeyboardInput.add(entity);
m_systemMouseInput.add(entity);
m_systemRenderer.add(entity);
m_systemNetwork.add(entity);
m_systemInterpolation.add(entity);
Expand All @@ -162,9 +166,10 @@ private void addEntity(Entity entity)
/// </summary>
private void removeEntity(uint id)
{
// TODO: Update the systems we use here
// NOTE: Update the systems we use here
m_entities.Remove(id);
m_systemKeyboardInput.remove(id);
m_systemMouseInput.remove(id);
m_systemNetwork.remove(id);
m_systemRenderer.remove(id);
m_systemInterpolation.remove(id);
Expand Down
7 changes: 5 additions & 2 deletions src/Client/Menu/ControlSettingsView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class ControlSettingsView : GameStateView
private ControlStateEnum updatingKey = ControlStateEnum.None;
private bool isUpdatingKey = false;
private Controls m_controls;
private SettingsPersistence m_settingsPersistence = new SettingsPersistence();
private ControlsPersistence _mControlsPersistence = new ControlsPersistence();

public enum ControlStateEnum
{
Expand Down Expand Up @@ -81,12 +81,15 @@ public override void update(GameTime gameTime)
break;
}
// Now we persist any changes
m_settingsPersistence.SaveControls(m_controls);
_mControlsPersistence.SaveControls(m_controls);
}
}
}
}

// TODO: Add a pill toggle to change whether we are in keyboard or mouse mode
// TODO: Add a menu mouse input system to handle the mouse input

}
public override void render(GameTime gameTime)
{
Expand Down
37 changes: 12 additions & 25 deletions src/Client/Systems/KeyboardInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public KeyboardInput(List<Tuple<Shared.Components.Input.Type, Keys>> mapping, Co

public override void update(TimeSpan elapsedTime)
{
if (!m_controls.UseKeyboard)
{
return;
}
var keyboardState = Keyboard.GetState();
m_keysPressed.Clear();

Expand All @@ -32,18 +36,21 @@ public override void update(TimeSpan elapsedTime)
foreach (var entity in m_entities)
{
var inputs = new List<Input.Type>();
inputs.Add(Input.Type.SnakeUp);
if (keyPressed(m_controls.SnakeLeft.key))
{
inputs.Add(Input.Type.RotateLeft);
Utility.rotateLeft(entity.Value, elapsedTime, m_entities);

}
if (keyPressed(m_controls.SnakeRight.key))
{
inputs.Add(Input.Type.RotateRight);
Utility.rotateRight(entity.Value, elapsedTime, m_entities);

}

// Now we handle the input locally before sending the message to the server
performInputAction(entity.Value, elapsedTime, inputs);
// Always add thrust
inputs.Add(Input.Type.SnakeUp);
Utility.thrust(entity.Value, elapsedTime, m_entities);

if (inputs.Count > 0)
{
Expand All @@ -55,27 +62,7 @@ public override void update(TimeSpan elapsedTime)
m_statePrevious = keyboardState;
}

private void performInputAction(Entity entity, TimeSpan elapsedTime, List<Input.Type> inputs)
{
for (int i = 0; i < inputs.Count; i++)
{
var inputType = inputs[i];
// Perform action based on inputType
// NOTE: Could do an optimization here where we have all of the combinations of possible inputs
switch (inputType)
{
case Input.Type.SnakeUp:
Utility.thrust(entity, elapsedTime, m_entities);
break;
case Input.Type.RotateLeft:
Utility.rotateLeft(entity, elapsedTime, m_entities);
break;
case Input.Type.RotateRight:
Utility.rotateRight(entity, elapsedTime, m_entities);
break;
}
}
}


public override bool add(Entity entity)
{
Expand Down
23 changes: 20 additions & 3 deletions src/Client/Systems/MouseInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public MouseInput(Controls controls) : base(typeof(Shared.Components.Input))

public override void update(TimeSpan elapsedTime)
{
if (m_controls.UseKeyboard)
{
return;
}

var mouseState = Mouse.GetState();
var currentPosition = new Vector2(mouseState.X, mouseState.Y);

Expand All @@ -29,18 +34,30 @@ public override void update(TimeSpan elapsedTime)
try
{
var positionComponent = entity.get<Position>();

var wormHeadPosition = positionComponent.position;
var direction = currentPosition - wormHeadPosition;
var inputs = new List<Input.Type>();

// Check mouse movement relative to the worm head's position to decide on turn direction
if (direction.X < 0 && currentPosition != previousMouseState.Position.ToVector2()) // Mouse moved left
{
HandleTurnLeft(entity, elapsedTime);
inputs.Add(Input.Type.RotateLeft);
}
else if (direction.X > 0 && currentPosition != previousMouseState.Position.ToVector2()) // Mouse moved right
{
HandleTurnRight(entity, elapsedTime);
inputs.Add(Input.Type.RotateLeft);
}

// Always add thrust
inputs.Add(Input.Type.SnakeUp);
Utility.thrust(entity, elapsedTime, m_entities);

if (inputs.Count > 0)
{
// Assuming you have a messaging system to handle input
MessageQueueClient.instance.sendMessageWithId(new Shared.Messages.Input(entityPair.Key, inputs, elapsedTime));
}
}
catch (KeyNotFoundException)
Expand All @@ -54,12 +71,12 @@ public override void update(TimeSpan elapsedTime)

private void HandleTurnLeft(Entity entity, TimeSpan elapsedTime)
{
// Logic for left turn
Utility.rotateLeft(entity, elapsedTime, m_entities);
}

private void HandleTurnRight(Entity entity, TimeSpan elapsedTime)
{
// Logic for right turn
Utility.rotateRight(entity, elapsedTime, m_entities);
}
}
}
2 changes: 1 addition & 1 deletion src/Server/MessageQueueServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ private void initializeReceiver()
byte[] size = new byte[sizeof(int)];

List<int> remove = new List<int>();
// TODO: This is a busy loop, would be nice to efficiently wait for an incoming message
// NOTE: This is a busy loop, would be nice to efficiently wait for an incoming message
// from a client
while (m_keepRunning)
{
Expand Down
8 changes: 2 additions & 6 deletions src/Shared/Components/Controls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@ namespace Shared.Components
[DataContract(Name = "Controls")]
public class Controls : Component
{
[DataMember(Name = "SnakeUp")]
public Control SnakeUp = new Control(Keys.Up);
[DataMember(Name = "SnakeLeft")]
public Control SnakeLeft = new Control(Keys.Left);
[DataMember(Name = "SnakeRight")]
public Control SnakeRight = new Control(Keys.Right);
[DataMember(Name = "SnakeDown")]
public Control SnakeDown = new Control(Keys.Down);
[DataMember (Name = "SnakeBoost")]
public Control SnakeBoost = new Control(Keys.Space);
[DataMember (Name = "UseKeyboard")]
public bool UseKeyboard = true;
}

[DataContract(Name = "Control")]
Expand Down
7 changes: 3 additions & 4 deletions src/Shared/Systems/ControlsPersistence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Shared.Systems;

public class SettingsPersistence: System
public class ControlsPersistence: System
{
// Now we want to make all of these control settings persist across game sessions. We will use the same serialization technique we used for the high scores.
private bool saving = false;
Expand All @@ -32,11 +32,10 @@ public void LoadControls(Controls controls) {
var res = finalizeLoadControlsAsync();
res.Wait(); // we want to load the controls before letting the user start playing
// All of them have a default value in case they were not saved
controls.SnakeUp = m_loadedState.SnakeUp == null? new Control(Keys.Up) : m_loadedState.SnakeUp;
controls.SnakeLeft = m_loadedState.SnakeLeft == null? new Control(Keys.Left) : m_loadedState.SnakeLeft;
controls.SnakeRight = m_loadedState.SnakeRight == null? new Control(Keys.Right) : m_loadedState.SnakeRight;
controls.SnakeDown = m_loadedState.SnakeDown == null ? new Control(Keys.Down) : m_loadedState.SnakeDown;
controls.SnakeBoost = m_loadedState.SnakeBoost == null ? new Control(Keys.Space): m_loadedState.SnakeBoost;
// controls.UseKeyboard = m_loadedState.UseKeyboard == null ? true: m_loadedState.UseKeyboard; // Real.
controls.UseKeyboard = true; // FOR TESTING. Allow us to switch keyboard on and off.
}
}
private async Task finalizeSaveControlsAsync(Controls controls)
Expand Down

0 comments on commit d6912c6

Please sign in to comment.