Skip to content

Commit

Permalink
Adds snake movement and rotation. (The trickle down is not great, wil…
Browse files Browse the repository at this point in the history
…l resolve that going forward) (#25)

* Adds networing for the snakeMovement

* Controls work and we are passing the head and tail status from client and server

* Adds automatic movement and ability to rotate

* Adds updates to the movement to get them to grab the head of the entity

* Adds snake rotation
  • Loading branch information
MaxEdwards20 authored Apr 2, 2024
1 parent ee658b8 commit 7614f50
Show file tree
Hide file tree
Showing 20 changed files with 306 additions and 127 deletions.
27 changes: 27 additions & 0 deletions src/Client/GameModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,33 @@ private Entity createEntity(Shared.Messages.NewEntity message)
{
entity.add(new Shared.Components.Input(message.inputs));
}

// Worm parts

if (message.hasHead)
{
entity.add(new Head());
}

if (message.hasTail)
{
entity.add(new Tail());
}

if (message.hasParent)
{
entity.add(new ParentId(message.parentId));
}

if (message.hasChild)
{
entity.add(new ChildId(message.childId));
}

if (message.collision)
{
entity.add(new Collision());
}

return entity;
}
Expand Down
20 changes: 2 additions & 18 deletions src/Client/Menu/ControlSettingsView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ public enum ControlStateEnum
{
SnakeLeft,
SnakeRight,
SnakeUp,
SnakeDown,
SnakeBoost,
None
}

Expand Down Expand Up @@ -82,15 +79,6 @@ public override void update(GameTime gameTime)
case ControlStateEnum.SnakeRight:
m_controls.SnakeRight.switchKey(key);
break;
case ControlStateEnum.SnakeUp:
m_controls.SnakeUp.switchKey(key);
break;
case ControlStateEnum.SnakeDown:
m_controls.SnakeDown.switchKey(key);
break;
case ControlStateEnum.SnakeBoost:
m_controls.SnakeBoost.switchKey(key);
break;
}
// Now we persist any changes
m_settingsPersistence.SaveControls(m_controls);
Expand All @@ -117,10 +105,6 @@ public override void render(GameTime gameTime)
Drawing.DrawShadedString(m_font, MESSAGE, new Vector2(halfWidth, halfHeight - headerStringSize.Y), Colors.displayColor, m_spriteBatch);
Drawing.DrawShadedString(m_font, "Move Left " + m_controls.SnakeLeft.key, new Vector2(halfWidth, halfHeight - headerStringSize.Y + 2 + 50), getStringColor(ControlStateEnum.SnakeLeft), m_spriteBatch);
Drawing.DrawShadedString(m_font, "Move Right " + m_controls.SnakeRight.key, new Vector2(halfWidth, halfHeight - headerStringSize.Y + 2 + 100), getStringColor(ControlStateEnum.SnakeRight), m_spriteBatch);
Drawing.DrawShadedString(m_font, "Move Up " + m_controls.SnakeUp.key, new Vector2(halfWidth, halfHeight - headerStringSize.Y + 2 + 150), getStringColor(ControlStateEnum.SnakeUp), m_spriteBatch);
Drawing.DrawShadedString(m_font, "Move Down " + m_controls.SnakeDown.key, new Vector2(halfWidth, halfHeight - headerStringSize.Y + 2 + 200), getStringColor(ControlStateEnum.SnakeDown), m_spriteBatch);
Drawing.DrawShadedString(m_font, "Boost " + m_controls.SnakeBoost.key, new Vector2(halfWidth, halfHeight - headerStringSize.Y + 2 + 250), getStringColor(ControlStateEnum.SnakeBoost), m_spriteBatch);

m_spriteBatch.End();
}

Expand Down Expand Up @@ -175,7 +159,7 @@ public void MoveUp(GameTime gameTime, float scale)
}
if (controlState == ControlStateEnum.SnakeLeft)
{
controlState = ControlStateEnum.SnakeBoost;
controlState = ControlStateEnum.SnakeRight;
}
else
{
Expand All @@ -189,7 +173,7 @@ public void MoveDown(GameTime gameTime, float scale)
{
return;
}
if (controlState == ControlStateEnum.SnakeBoost)
if (controlState == ControlStateEnum.SnakeRight)
{
controlState = ControlStateEnum.SnakeLeft;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Client/Menu/GamePlayView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public override void RegisterCommands()

private bool connectToServer()
{
return MessageQueueClient.instance.initialize("localhost", 4000);
return MessageQueueClient.instance.initialize("localhost", 4010);
}

private void escape(GameTime gameTime, float scale)
Expand All @@ -117,7 +117,7 @@ private MenuStateEnum handleSwitchToMainMenu()
}
catch (SocketException e)
{
// Console.WriteLine(e); // This happens if we were not able to connect to the server and try to exit from it
// Console.WriteLine(e); // This happens if we were not able to connect to the server and try to exit from the menu screen
}
return temp;
}
Expand Down
44 changes: 24 additions & 20 deletions src/Client/Systems/KeyboardInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Client.Systems
public class KeyboardInput : Shared.Systems.System
{
private HashSet<Keys> m_keysPressed = new HashSet<Keys>();

private KeyboardState m_statePrevious = Keyboard.GetState();
private Controls m_controls;

Expand All @@ -33,11 +32,18 @@ public override void update(TimeSpan elapsedTime)
foreach (var entity in m_entities)
{
var inputs = new List<Input.Type>();
checkAndPerformAction(m_controls.SnakeUp, Input.Type.SnakeUp, entity.Value, elapsedTime, inputs);
checkAndPerformAction(m_controls.SnakeLeft, Input.Type.RotateLeft, entity.Value, elapsedTime, inputs);
checkAndPerformAction(m_controls.SnakeRight, Input.Type.RotateRight, entity.Value, elapsedTime, inputs);
checkAndPerformAction(m_controls.SnakeDown, Input.Type.SnakeDown, entity.Value, elapsedTime, inputs);
checkAndPerformAction(m_controls.SnakeBoost, Input.Type.Boost, entity.Value, elapsedTime, inputs);
inputs.Add(Input.Type.SnakeUp);
if (keyPressed(m_controls.SnakeLeft.key))
{
inputs.Add(Input.Type.RotateLeft);
}
if (keyPressed(m_controls.SnakeRight.key))
{
inputs.Add(Input.Type.RotateRight);
}

// Now we handle the input locally before sending the message to the server
performInputAction(entity.Value, elapsedTime, inputs);

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

private void checkAndPerformAction(Control control, Input.Type inputType, Entity entity, TimeSpan elapsedTime, List<Input.Type> inputs)
private void performInputAction(Entity entity, TimeSpan elapsedTime, List<Input.Type> inputs)
{
if (m_keysPressed.Contains(control.key))
for (int i = 0; i < inputs.Count; i++)
{
inputs.Add(inputType);
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);
break;
case Input.Type.SnakeDown:
Utility.thrust(entity, elapsedTime);
Utility.thrust(entity, elapsedTime, m_entities);
break;
case Input.Type.Boost:
Utility.boost(entity, elapsedTime);
break;
case Input.Type.RotateLeft:
Utility.rotateLeft(entity, elapsedTime);
Utility.rotateLeft(entity, elapsedTime, m_entities);
break;
case Input.Type.RotateRight:
Utility.rotateRight(entity, elapsedTime);
Utility.rotateRight(entity, elapsedTime, m_entities);
break;
}
}

}

public override bool add(Entity entity)
Expand All @@ -94,10 +94,14 @@ public override void remove(uint id)
/// <summary>
/// Checks to see if a key was newly pressed
/// </summary>
private bool keyPressed(Keys key)
private bool keyNewlyPressed(Keys key)
{
return (Keyboard.GetState().IsKeyDown(key) && !m_statePrevious.IsKeyDown(key));
}

private bool keyPressed(Keys key)
{
return m_keysPressed.Contains(key);
}
}
}
14 changes: 5 additions & 9 deletions src/Client/Systems/Network.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public void update(TimeSpan elapsedTime, Queue<Message> messages)

// After processing all the messages, perform server reconciliation by
// resimulating the inputs from any sent messages not yet acknowledged by the server.

// This is where all of the other worms are updated
var sent = MessageQueueClient.instance.getSendMessageHistory(m_lastMessageId);
while (sent.Count > 0)
{
Expand All @@ -95,19 +97,13 @@ public void update(TimeSpan elapsedTime, Queue<Message> messages)
switch (input)
{
case Shared.Components.Input.Type.SnakeUp:
Shared.Entities.Utility.thrust(entity, message.elapsedTime);
Shared.Entities.Utility.thrust(entity, message.elapsedTime, m_entities);
break;
case Shared.Components.Input.Type.RotateLeft:
Shared.Entities.Utility.rotateLeft(entity, message.elapsedTime);
Shared.Entities.Utility.rotateLeft(entity, message.elapsedTime, m_entities);
break;
case Shared.Components.Input.Type.RotateRight:
Shared.Entities.Utility.rotateRight(entity, message.elapsedTime);
break;
case Input.Type.Boost:
Shared.Entities.Utility.boost(entity, message.elapsedTime);
break;
case Input.Type.SnakeDown:
Shared.Entities.Utility.thrust(entity, -message.elapsedTime);
Shared.Entities.Utility.rotateRight(entity, message.elapsedTime, m_entities);
break;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Client/Systems/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public void render(TimeSpan elapsedTime, SpriteBatch spriteBatch)
matrix *= Matrix.CreateScale(scaleX, scaleY, 1);

spriteBatch.Begin(transformMatrix: matrix);
// TODO: Adjust this to render all of the tails first, then body segments, then heads
foreach (Entity entity in m_entities.Values)
renderEntity(elapsedTime, spriteBatch, entity);
spriteBatch.End();
Expand Down
25 changes: 16 additions & 9 deletions src/Server/GameModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,31 +131,38 @@ private void handleJoin(int clientId)

private void createNewWorm(int clientId)
{
var location = new Vector2(100, 100);
var startLocation = new Vector2(200, 200);
var rotationRate = (float) Math.PI / 1000;
var moveRate = 0.1f;
var headSize = 100;
var bodySize = 80;

// Create the head
Entity player = WormHead.create( Color.Aqua, location, 100, moveRate, rotationRate);
addEntity(player);
m_clientToEntityId[clientId] = player.id;
Entity player = WormHead.create(startLocation, 100, moveRate, rotationRate);

// Create a body segment
Entity segment = WormSegment.create(Color.Aqua, location + Vector2.One * 20, bodySize, moveRate, rotationRate, player.get<SegmentID>().id);
Entity segment = WormSegment.create( new Vector2(startLocation.X + 75, startLocation.Y - 20) , bodySize, moveRate, rotationRate, player.id);
player.add(new ChildId(segment.id));

// Create a tail segment
Entity tail = WormTail.create(new Vector2(startLocation.X + 130, startLocation.Y), bodySize, moveRate, rotationRate, segment.id);
segment.add(new ChildId(tail.id));

addEntity(player);
addEntity(segment);
addEntity(tail);

m_clientToEntityId[clientId] = player.id;
m_clientToEntityId[clientId] = segment.id;
// Create a tail segment
Entity tail = WormTail.create(Color.Aqua, location + Vector2.One * 21, bodySize, moveRate, rotationRate, segment.get<SegmentID>().id);
m_clientToEntityId[clientId] = tail.id;


// Step 3: Send the new player entity to the newly joined client
MessageQueueServer.instance.sendMessage(clientId, new NewEntity(player));
MessageQueueServer.instance.sendMessage(clientId, new NewEntity(segment));
MessageQueueServer.instance.sendMessage(clientId, new NewEntity(tail));
addEntity(tail);

// Step 4: Let all other clients know about this new player entity

// Remove components not needed for "other" players
player.remove<Shared.Components.Input>();
Message message = new NewEntity(player);
Expand Down
2 changes: 1 addition & 1 deletion src/Server/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"Server": {
"commandName": "Project",
"commandLineArgs": "--port 4000"
"commandLineArgs": "--port 4010"
}
}
}
6 changes: 3 additions & 3 deletions src/Server/Systems/Network.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ private void handleInput(Shared.Messages.Input message)
switch (input)
{
case Shared.Components.Input.Type.SnakeUp:
Shared.Entities.Utility.thrust(entity, message.elapsedTime);
Shared.Entities.Utility.thrust(entity, message.elapsedTime, m_entities);
m_reportThese.Add(message.entityId);
break;
case Shared.Components.Input.Type.RotateLeft:
Shared.Entities.Utility.rotateLeft(entity, message.elapsedTime);
Shared.Entities.Utility.rotateLeft(entity, message.elapsedTime, m_entities);
m_reportThese.Add(message.entityId);
break;
case Shared.Components.Input.Type.RotateRight:
Shared.Entities.Utility.rotateRight(entity, message.elapsedTime);
Shared.Entities.Utility.rotateRight(entity, message.elapsedTime, m_entities);
m_reportThese.Add(message.entityId);
break;
}
Expand Down
11 changes: 11 additions & 0 deletions src/Shared/Components/ChildId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Shared.Components;

public class ChildId : Component
{
public uint id { get; private set; }
public ChildId(uint id)
{
this.id = id;
}

}
6 changes: 6 additions & 0 deletions src/Shared/Components/Head.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Shared.Components;

public class Head : Component
{

}
2 changes: 0 additions & 2 deletions src/Shared/Components/Input.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ public class Input : Component
public enum Type : UInt16
{
SnakeUp,
SnakeDown,
RotateLeft,
RotateRight,
Boost
}

public Input(List<Type> inputs)
Expand Down
6 changes: 3 additions & 3 deletions src/Shared/Components/ParentID.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
namespace Shared.Components;

public class ParentID: Component
public class ParentId: Component
{
public Guid id { get; private set; }
public ParentID(Guid id)
public uint id { get; private set; }
public ParentId(uint id)
{
this.id = id;
}
Expand Down
12 changes: 0 additions & 12 deletions src/Shared/Components/SegmentID.cs

This file was deleted.

6 changes: 6 additions & 0 deletions src/Shared/Components/Tail.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Shared.Components;

public class Tail : Component
{

}
Loading

0 comments on commit 7614f50

Please sign in to comment.