summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoredGuy <osome3717@gmail.com>2026-01-25 16:30:24 -0800
committerBoredGuy <osome3717@gmail.com>2026-01-25 16:30:24 -0800
commitc18e714aebab35442347cd114bad66a014d8f7ca (patch)
tree60981a0a46766672956faf8b85148800d30ec2b6
parent148607dad5ca84bedf93031892c77e071d1873cc (diff)
Snake Movement Before I move on with my life
-rw-r--r--DungeonSlime/Game1.cs390
1 files changed, 125 insertions, 265 deletions
diff --git a/DungeonSlime/Game1.cs b/DungeonSlime/Game1.cs
index 387f6b5..abb6559 100644
--- a/DungeonSlime/Game1.cs
+++ b/DungeonSlime/Game1.cs
@@ -1,4 +1,7 @@
using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Runtime.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
@@ -7,338 +10,195 @@ using MonoGameLibrary;
namespace DungeonSlime;
-internal enum GameState
+enum Direction
{
- MenuState,
- WaitingState,
- PollingState,
- GameOverState
+ Up,
+ Down,
+ Left,
+ Right
}
-internal class GameStateMachine
+static class DirectionHelper
{
- private GameState _state;
-
- public GameStateMachine(GameState startState)
- {
- if (!IsValidState(startState))
- {
- throw new ArgumentOutOfRangeException($"{startState}");
- }
-
- _state = startState;
- }
-
- public GameState State
- {
- get => _state;
- set
- {
- if (!IsValidState(value))
- {
- throw new ArgumentOutOfRangeException($"{value}");
- }
-
- if (!IsValidStateTransition(value))
- {
- throw new InvalidOperationException($"Cannot go from {State} to {value}!");
- }
-
- _state = value;
- }
- }
-
- private static bool IsValidState(GameState state)
- {
- return state is
- GameState.MenuState or
- GameState.WaitingState or
- GameState.PollingState or
- GameState.GameOverState;
- }
-
- private bool IsValidStateTransition(GameState targetState)
- {
- return State switch
+ /// <summary>
+ /// Returns a normalized vector which indicates where
+ /// the direction points to in world space
+ /// </summary>
+ /// <param name="direction">The direction</param>
+ public static Vector2 ToNormalVector(Direction direction)
+ {
+ return direction switch
{
- GameState.MenuState => targetState == GameState.WaitingState,
- GameState.WaitingState => targetState == GameState.PollingState || targetState == GameState.GameOverState,
- GameState.PollingState => targetState == GameState.GameOverState,
- GameState.GameOverState => targetState == GameState.MenuState || targetState == GameState.WaitingState,
- _ => false
+ Direction.Up => new Vector2(0, -1),
+ Direction.Down => new Vector2(0, 1),
+ Direction.Left => new Vector2(-1, 0),
+ Direction.Right => new Vector2(1, 0),
+ _ => throw new ArgumentOutOfRangeException($"Invalid direction {direction}")
};
}
}
-internal class MouseInputManager
-{
- private MouseState _currentState;
- private MouseState _pastState;
- public MouseState MouseState { get => _currentState; }
+struct Segment {
+ public Vector2 pastPosition;
+ public Vector2 targetPosition;
- public MouseInputManager(MouseState startMouseState)
+ public Vector2 GetPosition(float portionTraveled)
{
- _pastState = _currentState = startMouseState;
+ return Vector2.Lerp(pastPosition, targetPosition, portionTraveled);
}
+}
- public bool IsMouseClicked
- {
- get
- {
- if (_currentState.LeftButton == ButtonState.Pressed && _pastState.LeftButton == ButtonState.Released)
- {
- return true;
- }
+class Snake
+{
+ public static readonly Point SegmentSize = new Point(100, 100);
+ public Direction Heading { get; set; }
+ List<Segment> tail = [];
+ Segment head;
- return false;
- }
- }
+ float portionTraveled = 0;
+ Texture2D whitePixel;
+ public float Speed { get; set; }
- public void Update(MouseState mouseState)
+ public Snake(Point postionOnGrid, Direction heading, Texture2D whitePixel)
{
- _pastState = _currentState;
- _currentState = mouseState;
- }
-}
+ this.Heading = heading;
-public class Game1 : Core
-{
- private const int MinTimeToReactMilis = 50;
- private const int MaxTimeToReactMillis = 400;
-
- private GameStateMachine _stateMachine;
- private SpriteFont _arial;
- private MouseInputManager _mouseInput;
- private Random _random;
- private Vector2 WindowCenter
- {
- get
+ head = new Segment
{
- return new Vector2(
- Window.ClientBounds.Width,
- Window.ClientBounds.Height
- ) * 0.5f;
- }
- }
- private Color ClearColor
- {
- get
- {
- return _stateMachine.State switch
- {
- GameState.MenuState => Color.Green,
- GameState.WaitingState => Color.CornflowerBlue,
- GameState.PollingState => Color.Red,
- GameState.GameOverState => Color.Green,
- _ => throw new ArgumentOutOfRangeException($"{_stateMachine.State}"),
- };
- }
- }
-
- //Gameplay fields
- private TimeSpan _timeToReact;
- private bool _clickedTooEarly;
+ pastPosition = (postionOnGrid * SegmentSize).ToVector2()
+ };
+ head.targetPosition = head.pastPosition + GetHeadTargetOffset();
- public Game1() : base("Reaction Test", 1280, 720, false)
- {
- IsFixedTimeStep = false; //For fastest possible updates
- }
+ tail.Add(new Segment
+ {
+ pastPosition = (postionOnGrid * SegmentSize).ToVector2(),
+ targetPosition = head.pastPosition
+ });
- protected override void Initialize()
- {
- base.Initialize();
+ this.whitePixel = whitePixel;
- _stateMachine = new GameStateMachine(GameState.MenuState);
- _mouseInput = new MouseInputManager(Mouse.GetState());
- _random = new Random();
+ Speed = 2.0f;
}
- protected override void LoadContent()
+ private Vector2 GetHeadTargetOffset()
{
- _arial = Content.Load<SpriteFont>("Fonts/Ariel");
+ return DirectionHelper.ToNormalVector(Heading) * SegmentSize.ToVector2();
}
- protected override void Update(GameTime gameTime)
+ public void Update(float dt)
{
- base.Update(gameTime);
- _mouseInput.Update(Mouse.GetState());
+ portionTraveled += Speed * dt;
- switch (_stateMachine.State)
+ //Keep leftover for consistent movment
+ if (portionTraveled >= 1f)
{
- case GameState.MenuState:
- UpdateMenu();
- break;
- case GameState.WaitingState:
- UpdateWaiting(gameTime);
- break;
- case GameState.GameOverState:
- UpdateGameOver();
- break;
- case GameState.PollingState:
- UpdatePolling(gameTime);
- break;
- }
- }
+ portionTraveled -= 1f;
- protected override void Draw(GameTime gameTime)
- {
- GraphicsDevice.Clear(ClearColor);
+ //Snap all segments in tail to next grid position
+ if (tail.Count > 0)
+ {
+ for (int i = tail.Count - 1; i > 0; i--)
+ {
+ tail[i] = tail[i-1];
+ }
- switch (_stateMachine.State)
- {
- case GameState.MenuState:
- DrawMenu();
- break;
- case GameState.WaitingState:
- DrawWaiting();
- break;
- case GameState.GameOverState:
- DrawGameOver();
- break;
- }
+ Segment tailSegment = tail[0];
- base.Draw(gameTime);
- }
+ tailSegment.pastPosition = head.pastPosition;
+ tailSegment.targetPosition = head.targetPosition;
- private void StartPlaying()
- {
- _stateMachine.State = GameState.WaitingState;
- _timeToReact = TimeSpan.FromMilliseconds(
- MinTimeToReactMilis + _random.Next() % (MaxTimeToReactMillis - MinTimeToReactMilis + 1)
- );
- _clickedTooEarly = false;
- }
+ tail[0] = tailSegment;
+ }
- private void UpdateMenu()
- {
- if (_mouseInput.IsMouseClicked)
- {
- StartPlaying();
+ //Snap head to next grid position
+ head.pastPosition = head.targetPosition;
+ head.targetPosition = head.pastPosition + GetHeadTargetOffset();
}
}
- private void DrawMenu()
+ public void DrawSegment(Segment s, SpriteBatch spriteBatch)
{
- SpriteBatch.Begin();
-
- //Draw the menu header
- string header = "Welcome to the reaction time test!";
- SpriteBatch.DrawString(
- _arial,
- header,
- WindowCenter,
- Color.White,
- 0f,
- _arial.MeasureString(header) * 0.5f,
- 1.5f,
- SpriteEffects.None,
- 0f
+ spriteBatch.Draw(
+ whitePixel,
+ new Rectangle(
+ s.GetPosition(portionTraveled).ToPoint(),
+ SegmentSize
+ ),
+ Color.White
);
+ }
- //Draw the menu subheader
- string subheader = "Click to play!";
- SpriteBatch.DrawString(
- _arial,
- subheader,
- new Vector2(
- Window.ClientBounds.Width * 0.5f,
- Window.ClientBounds.Height * 0.6f
+ public void Draw(SpriteBatch spriteBatch)
+ {
+ spriteBatch.Draw(
+ whitePixel,
+ new Rectangle(
+ head.GetPosition(portionTraveled).ToPoint(),
+ SegmentSize
),
- Color.White,
- 0f,
- _arial.MeasureString(subheader) * 0.5f,
- 0.75f,
- SpriteEffects.None,
- 0f
+ Color.Red
);
- SpriteBatch.End();
+ foreach (var i in tail)
+ {
+
+ }
}
+}
- private void ClickedTooEarly()
- {
- _clickedTooEarly = true;
- _stateMachine.State = GameState.GameOverState;
- }
+public class Game1 : Core
+{
+ Texture2D whitePixel;
+ Snake snake;
- private void StartPolling()
+ public Game1() : base("Reaction Test", 1280, 720, false)
{
- _stateMachine.State = GameState.PollingState;
- _timeToReact = TimeSpan.Zero;
+
}
- private void UpdateWaiting(GameTime gameTime)
+ protected override void Initialize()
{
- _timeToReact -= gameTime.ElapsedGameTime;
+ base.Initialize();
- if (_timeToReact.CompareTo(TimeSpan.Zero) <= 0)
- {
- StartPolling();
- return;
- }
+ whitePixel = new Texture2D(GraphicsDevice, 1, 1);
+ whitePixel.SetData<Color>([Color.White]);
- if (_mouseInput.IsMouseClicked)
- {
- ClickedTooEarly();
- }
+ snake = new Snake(new Point(2, 2), Direction.Right, whitePixel);
}
- private void DrawWaiting()
+ protected override void LoadContent()
{
- SpriteBatch.Begin();
-
- string message = "Click when the background turns red!";
- SpriteBatch.DrawString(
- _arial,
- message,
- WindowCenter,
- Color.White,
- 0f,
- _arial.MeasureString(message) * 0.5f,
- 1f,
- SpriteEffects.None,
- 0f
- );
-
- SpriteBatch.End();
}
- private void UpdatePolling(GameTime gameTime)
+ protected override void Update(GameTime gameTime)
{
- _timeToReact += gameTime.ElapsedGameTime;
+ base.Update(gameTime);
- if (_mouseInput.IsMouseClicked)
+ if (Keyboard.GetState().IsKeyDown(Keys.Down))
{
- _stateMachine.State = GameState.GameOverState;
- }
- }
-
- private void UpdateGameOver()
- {
- if (_mouseInput.IsMouseClicked)
+ snake.Heading = Direction.Down;
+ } else if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
- _stateMachine.State = GameState.MenuState;
+ snake.Heading = Direction.Up;
+ } else if (Keyboard.GetState().IsKeyDown(Keys.Left))
+ {
+ snake.Heading = Direction.Left;
+ } else if (Keyboard.GetState().IsKeyDown(Keys.Right))
+ {
+ snake.Heading = Direction.Right;
}
+
+ snake.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
}
- private void DrawGameOver()
+ protected override void Draw(GameTime gameTime)
{
- string header = _clickedTooEarly ? "Too Early!" : $"You reacted in {Math.Round(_timeToReact.TotalMilliseconds)}ms!";
+ GraphicsDevice.Clear(Color.CornflowerBlue);
SpriteBatch.Begin();
-
- SpriteBatch.DrawString(
- _arial,
- header,
- WindowCenter,
- Color.White,
- 0f,
- _arial.MeasureString(header) * 0.5f,
- 1f,
- SpriteEffects.None,
- 0f
- );
-
+ snake.Draw(SpriteBatch);
SpriteBatch.End();
+
+ base.Draw(gameTime);
}
}