Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collision detection #54

Merged
merged 7 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@ A game of Snake built using C# in the MonoGame framework, themed around everyone
- [ ] Caden: Map generation
- [ ] Caden: Spice generation when we spawn
- [ ] Caden: Periodic spice generation throughout the game
- [ ] Max: Keyboard support for left, right, up, down, diagonal up left and diagonal up right. Also add these to the wormMovement system.
- [ ] Menu Screen to let player name themselves (probably similar to how control selection screen will work) - Satchel

- [ ] Max: Collision detection. Know whether we hit spice or another sandworm

## Items to Develop

- [ ] Fix ability to exit the game and come back in. Dean talked about what we need to do in Teams.
- [ ] 3 different animated sprites for the spice
- [ ] Sound effects on death of worm and when food is eaten - Satchel
- [ ] Collision detection. Know whether we hit spice or another sandworm
- [ ] On collision, sandworm breaks apart and is available as food for other snakes
- [ ] Record players score, kills and highest position. Probably can be added to the `GameScores` object.
- [ ] Game over screen with score, kills, and highest position achieved. This is an overlay on the multiplayer game behind it.
Expand All @@ -30,6 +29,8 @@ A game of Snake built using C# in the MonoGame framework, themed around everyone
- [ ] Add a player status in leaderboard to show whether the player is currently invincible.

## Done

- [x] Max: Keyboard support for left, right, up, down, diagonal up left and diagonal up right. Also add these to the wormMovement system.
- [x] Max: Snake Movement with the queue system
- [x] Max: Upgrade our movement system to reduce the lag in rotation
- [x] Max: Add name support for the player
Expand Down
12 changes: 12 additions & 0 deletions src/Client/Content/Content.mgcb
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,15 @@
/processorParam:TextureFormat=Color
/build:Textures/tail.png


#begin Textures/wall.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/wall.png
Binary file added src/Client/Content/Textures/wall.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/Client/GameModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class GameModel
private Systems.Interpolation m_systemInterpolation;
private Systems.Renderer m_renderer;
private Shared.Systems.WormMovement m_systemWormMovement;
private Shared.Systems.CollisionHandler m_systemCollisionHandler;
private Controls m_controls;
private GraphicsDeviceManager m_graphics;
private SpriteFont m_font;
Expand All @@ -35,6 +36,7 @@ public void update(TimeSpan elapsedTime)
{
m_systemNetwork.update(elapsedTime, MessageQueueClient.instance.getMessages());
m_systemKeyboardInput.update(elapsedTime);
m_systemCollisionHandler.update(elapsedTime);
m_systemWormMovement.update(elapsedTime);
m_systemInterpolation.update(elapsedTime);
m_systemCamera.update(elapsedTime);
Expand Down Expand Up @@ -65,6 +67,7 @@ public bool initialize(ContentManager contentManager, Controls controls, Graphic
m_systemCamera = new Systems.Camera(new Vector2(graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight));

m_renderer = new Systems.Renderer(m_systemCamera, graphics, m_font, m_sand);
m_systemCollisionHandler = new Shared.Systems.CollisionHandler();
m_systemWormMovement = new Shared.Systems.WormMovement();
m_systemNetwork = new Systems.Network();

Expand Down Expand Up @@ -120,6 +123,11 @@ private Entity createEntity(Shared.Messages.NewEntity message)
{
entity.add(new Collision());
}

if (message.hasWall)
{
entity.add(new Shared.Components.Wall());
}

// Worm parts

Expand Down Expand Up @@ -171,6 +179,7 @@ private void addEntity(Entity entity)
// NOTE: Update the systems we use here
m_entities[entity.id] = entity;
m_systemKeyboardInput.add(entity);
m_systemCollisionHandler.add(entity);
m_systemWormMovement.add(entity);
m_renderer.add(entity);
m_systemNetwork.add(entity);
Expand All @@ -187,6 +196,7 @@ private void removeEntity(uint id)
// NOTE: Update the systems we use here
m_entities.Remove(id);
m_systemKeyboardInput.remove(id);
m_systemCollisionHandler.remove(id);
m_systemWormMovement.remove(id);
m_systemNetwork.remove(id);
m_renderer.remove(id);
Expand Down
4 changes: 2 additions & 2 deletions src/Client/Menu/ChooseNameView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public override void render(GameTime gameTime)
(m_graphics.PreferredBackBufferHeight - textSize.Y) / 2);

// Draw "Enter Your Name" text
m_spriteBatch.DrawString(font, enterNameText, textPosition, Color.PaleGoldenrod);
m_spriteBatch.DrawString(font, enterNameText, textPosition, Colors.displayColor);

// Draw "Press Enter to proceed" below the name text if a name has been entered
if (playerName.Length > 0)
Expand All @@ -93,7 +93,7 @@ public override void render(GameTime gameTime)
(m_graphics.PreferredBackBufferWidth - proceedTextSize.X) / 2,
textPosition.Y + textSize.Y + 20); // 20 pixels below the name text

m_spriteBatch.DrawString(font, proceedText, proceedTextPosition, Color.PaleGoldenrod);
m_spriteBatch.DrawString(font, proceedText, proceedTextPosition, Colors.displayColor);
}

m_spriteBatch.End();
Expand Down
6 changes: 3 additions & 3 deletions src/Client/Menu/HowToPlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,22 @@ public override void render(GameTime gameTime)
// Title
Vector2 titlePosition = new Vector2(m_graphics.PreferredBackBufferWidth / 2, m_graphics.PreferredBackBufferHeight / 4);
Vector2 titleOrigin = font.MeasureString(titleMessage) / 2;
m_spriteBatch.DrawString(font, titleMessage, titlePosition - (titleOrigin * textScale), Color.PaleGoldenrod, 0f, Vector2.Zero, textScale, SpriteEffects.None, 0f);
m_spriteBatch.DrawString(font, titleMessage, titlePosition - (titleOrigin * textScale), Colors.displayColor, 0f, Vector2.Zero, textScale, SpriteEffects.None, 0f);

// How to Play Instructions
Vector2 instructionsPosition = new Vector2(m_graphics.PreferredBackBufferWidth / 2, m_graphics.PreferredBackBufferHeight / 2.5f);
string[] lines = howToPlayMessage.Split('\n');
foreach (string line in lines)
{
Vector2 lineSize = font.MeasureString(line) * textScale;
m_spriteBatch.DrawString(font, line, instructionsPosition - new Vector2(lineSize.X / 2, 0), Color.PaleGoldenrod, 0f, Vector2.Zero, textScale, SpriteEffects.None, 0f);
m_spriteBatch.DrawString(font, line, instructionsPosition - new Vector2(lineSize.X / 2, 0), Colors.displayColor, 0f, Vector2.Zero, textScale, SpriteEffects.None, 0f);
instructionsPosition.Y += lineSize.Y + 5; // Adjust spacing between lines if necessary, taking scale into account
}

// Continue Prompt
Vector2 continuePosition = new Vector2(m_graphics.PreferredBackBufferWidth / 2, (m_graphics.PreferredBackBufferHeight / 4) * 3);
Vector2 continueOrigin = font.MeasureString(continueMessage) / 2;
m_spriteBatch.DrawString(font, continueMessage, continuePosition - (continueOrigin * textScale), Color.PaleGoldenrod, 0f, Vector2.Zero, textScale, SpriteEffects.None, 0f);
m_spriteBatch.DrawString(font, continueMessage, continuePosition - (continueOrigin * textScale), Colors.displayColor, 0f, Vector2.Zero, textScale, SpriteEffects.None, 0f);

m_spriteBatch.End();
}
Expand Down
10 changes: 0 additions & 10 deletions src/Client/Systems/CollisionDetection.cs

This file was deleted.

5 changes: 5 additions & 0 deletions src/Client/Systems/Network.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public Network() :
{
m_removeEntityHandler((RemoveEntity)message);
});

}

// Have to implement this because it is abstract in the base class
Expand Down Expand Up @@ -187,6 +188,10 @@ private void handleUpdateEntity(TimeSpan elapsedTime, UpdateEntity message)

m_updatedEntities.Add(entity.id);
}
if (entity.contains<SpicePower>() && message.hasSpicePower)
{
entity.get<SpicePower>().setPower(message.spicePower);
}
}
}
}
Expand Down
52 changes: 46 additions & 6 deletions src/Server/GameModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

using Microsoft.Xna.Framework;
using Server.Systems;
using Shared.Components;
using Shared.Components.Appearance;
using Shared.Entities;
Expand All @@ -14,7 +15,10 @@
private Dictionary<uint, Entity> m_entities = new Dictionary<uint, Entity>();
private Dictionary<int, uint> m_clientToEntityId = new Dictionary<int, uint>();
private WormMovement m_systemWormMovement = new WormMovement();
private CollisionDetection m_systemCollisionDetection = new CollisionDetection();
private CollisionHandler m_systemCollisionHandler = new CollisionHandler();
Systems.Network m_systemNetwork = new Server.Systems.Network();
private int mapSize = 5000;

/// <summary>
/// This is where the server-side simulation takes place. Messages
Expand All @@ -23,7 +27,9 @@
/// </summary>
public void update(TimeSpan elapsedTime)
{
m_systemNetwork.update(elapsedTime, MessageQueueServer.instance.getMessages());

Check warning on line 30 in src/Server/GameModel.cs

View workflow job for this annotation

GitHub Actions / buildProject

Possible null reference argument for parameter 'messages' in 'void Network.update(TimeSpan elapsedTime, Queue<Tuple<int, Message>> messages)'.
m_systemCollisionDetection.update(elapsedTime);
m_systemCollisionHandler.update(elapsedTime);
m_systemWormMovement.update(elapsedTime);
}

Expand All @@ -32,14 +38,16 @@
/// </summary>
public bool initialize()
{
generateWalls();
m_systemNetwork.registerJoinHandler(handleJoin);
m_systemNetwork.registerDisconnectHandler(handleDisconnect);

MessageQueueServer.instance.registerConnectHandler(handleConnect);

m_systemCollisionDetection.registerRemoveEntity(removeEntity);
return true;
}



/// <summary>
/// Give everything a chance to gracefully shutdown.
/// </summary>
Expand Down Expand Up @@ -68,13 +76,11 @@
private void handleDisconnect(int clientId)
{
m_clients.Remove(clientId);

Message message = new Shared.Messages.RemoveEntity(m_clientToEntityId[clientId]);
MessageQueueServer.instance.broadcastMessage(message);

removeEntity(m_clientToEntityId[clientId]);

m_clientToEntityId.Remove(clientId);

}

/// <summary>
Expand All @@ -91,6 +97,8 @@

m_entities[entity.id] = entity;
m_systemNetwork.add(entity);
m_systemCollisionDetection.add(entity);
m_systemCollisionHandler.add(entity);
m_systemWormMovement.add(entity);
}

Expand All @@ -102,7 +110,10 @@
{
m_entities.Remove(id);
m_systemNetwork.remove(id);
m_systemCollisionDetection.remove(id);
m_systemCollisionHandler.remove(id);
m_systemWormMovement.remove(id);

}

/// <summary>
Expand Down Expand Up @@ -134,6 +145,33 @@
// to the newly joined client
createNewWorm(clientId, name);
}

private void generateWalls()
{
// We want to create wall entities around the entire map. 5000x5000 is the size of the map
// We'll create a wall every 100 units
var wallSize = 100;
for (int i = 0; i < mapSize/100; i++)
{
// Top wall
Entity wall = Shared.Entities.Wall.create(new Vector2(i * wallSize, 0), wallSize);
addEntity(wall);
// MessageQueueServer.instance.broadcastMessage(new NewEntity(wall));
// Bottom wall
wall = Shared.Entities.Wall.create(new Vector2(i * wallSize, mapSize-wallSize), wallSize);
addEntity(wall);
// MessageQueueServer.instance.broadcastMessage(new NewEntity(wall));
// Left wall
wall = Shared.Entities.Wall.create(new Vector2(0, i * wallSize), wallSize);
addEntity(wall);
// MessageQueueServer.instance.broadcastMessage(new NewEntity(wall));
// Right wall
wall = Shared.Entities.Wall.create(new Vector2(mapSize-wallSize, i * wallSize), wallSize);
addEntity(wall);
// MessageQueueServer.instance.broadcastMessage(new NewEntity(wall));
}

}

private void createNewWorm(int clientId, string name)
{
Expand Down Expand Up @@ -191,7 +229,7 @@
}
else
{
segment = null;

Check warning on line 232 in src/Server/GameModel.cs

View workflow job for this annotation

GitHub Actions / buildProject

Converting null literal or possible null value to non-nullable type.
}
}
}
Expand All @@ -201,7 +239,9 @@
// We want to start the player in the least dense area of the screen
// For now, we'll just start them randomly generated location
Random random = new Random();
return new Vector2(random.Next(0, 800), random.Next(0, 600));
var lowerBound = (int)(.1 * mapSize);
var upperBound = (int)(.9 * mapSize);
return new Vector2(random.Next(lowerBound, upperBound), random.Next(lowerBound, upperBound));
}
}
}
1 change: 0 additions & 1 deletion src/Server/MessageQueueServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ public void broadcastMessageWithLastId(Message message)
public void registerConnectHandler(ConnectHandler handler)
{
m_connectHandler = handler;

}

/// <summary>
Expand Down
Loading
Loading