/* * Rohmer Maxime * STD Project * 25/01/2023 * V1.0 * GraphicalClient.cs * A graphical override for the client object */ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Caisses { public class GraphicalClient : Client { const float MAX_CLIENT_SPEED = 2.5f; //5 At 60FPS const float MIN_CLIENT_SPEED = -2.5f; //-5 At 60FPS private PointF _speed; private PointF _position; private Color _color; private Size _size; private Rectangle _area; public PointF Speed { get => _speed; set => _speed = value; } public PointF Position { get => _position; set => _position = value; } public Color Color { get => _color; set => _color = value; } public Size Size { get => _size; set => _size = value; } public Rectangle Area { get => _area; set => _area = value; } public GraphicalClient(Point Entrance, Random random) : base(random) { Random = random; Position = Entrance; //Position = new Point(Random.Next(0, 100), Random.Next(0, 100)); Speed = new PointF(NextFloat(MIN_CLIENT_SPEED, MAX_CLIENT_SPEED), NextFloat(MIN_CLIENT_SPEED, MAX_CLIENT_SPEED)); Color = Color.FromArgb(ShoppingTime * 2, 0, 0); int clientWidth = Random.Next(25, 30); Size = new Size(clientWidth, clientWidth); } static float NextFloat(float min, float max) { double val = (Random.NextDouble() * (max - min) + min); return (float)val; } public void Update(Size StoreArea, Size WaitingRoomArea) { //base.Tick(); Position = checkBounds(Position, StoreArea, WaitingRoomArea); Color = Color.FromArgb(ShoppingTime * 2, 0, 0); if (State == ClientState.Waiting) { Speed = new PointF(Speed.X + WaitingTime / 100f,Speed.Y + WaitingTime / 100f); } } public void Draw(Bitmap storeImage, Bitmap waitingRoomImage) { Update(storeImage.Size, waitingRoomImage.Size); Graphics g = Graphics.FromImage(storeImage); if (this.State == Client.ClientState.Waiting) g = Graphics.FromImage(waitingRoomImage); switch (State) { case ClientState.Shopping: Color = Color.FromArgb(ShoppingTime * 2,ShoppingTime * 2,ShoppingTime* 2); g.FillEllipse(new SolidBrush(Color), new RectangleF(Position, Size)); g.DrawString(ShoppingTime.ToString(), new Font("Arial", 16), new SolidBrush(Color.White), new PointF(Position.X, Position.Y)); break; case ClientState.Waiting: Color = Color.FromArgb(244, 113, 116); g.FillEllipse(new SolidBrush(Color), new RectangleF(Position, Size)); g.DrawString(WaitingTime.ToString(), new Font("Arial", 16), new SolidBrush(Color.White), new PointF(Position.X, Position.Y)); break; case ClientState.Inline: //g.FillEllipse(new SolidBrush(Color.Violet), new RectangleF(Position, Size)); break; case ClientState.Checkout: //g.FillEllipse(new SolidBrush(Color.Green), new RectangleF(Position, Size)); //g.DrawString(CheckoutTime.ToString(), new Font("Arial", 16), new SolidBrush(Color.Black), new PointF(Position.X, Position.Y)); break; default: break; } } public PointF checkBounds(PointF position, Size StoreArea, Size WaitingArea) { PointF newPosition = new PointF(position.X, position.Y); Size area = StoreArea; if (this.State == Client.ClientState.Waiting) area = WaitingArea; if (Position.X + Size.Width / 2 > area.Width || Position.Y + Size.Height / 2 > area.Height) { //Its just that sometimes when transfered from the store to the waiting room, the clients ar stuck outside the bounds newPosition = new PointF(0,0); } else { if (position.X + Speed.X > 0 && position.X + Size.Width + Speed.X < area.Width) { newPosition.X = position.X + Speed.X; } else { float diff = Math.Abs(position.X + Speed.X); newPosition.X = diff; Speed = new PointF(Speed.X * -1, Speed.Y); } if (position.Y + Speed.Y > 0 && position.Y + Size.Height + Speed.Y < area.Height) { newPosition.Y = position.Y + Speed.Y; } else { float diff = Math.Abs(position.Y + Speed.Y); newPosition.Y = diff; Speed = new PointF(Speed.X, Speed.Y * -1); } } return newPosition; } } }