using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.VisualBasic.CompilerServices; using SDL2; using testdrid.SdlWrapper; namespace SkyscraperUI { internal class CharSet { public CharSet(Texture texture) { _texture = texture; sourceRect.w = 24; sourceRect.h = 32; targetRect.w = 24; targetRect.h = 32; FacingDirection = CharSetFacing.Down; Stepping = CharSetStepping.Stand; } private Texture _texture; private byte _charNo; public byte CharacterNumber { get => _charNo; set { if (value > 7) throw new ArgumentOutOfRangeException(); _charNo = value; } } public bool IsMoving { get; set; } public CharSetFacing FacingDirection { get; set; } public CharSetStepping Stepping { get; set; } public int X { get; set; } public int Y { get; set; } private SDL.SDL_Rect sourceRect; private SDL.SDL_Rect targetRect; private static Point[] charNumberOffsets = new Point[] { new Point(0, 0), new Point(72, 0), new Point(144, 0), new Point(216, 0), new Point(0, 128), new Point(72, 128), new Point(144, 128), new Point(216, 128) }; private static int[] facingOffsets = new int[] { 0, 32, 64, 96 }; private static int[] steppingOffstes = new[] { 0,24, 48 }; private static int steppingDelay = 10; private int steppingRemain; private Point home; #region AutoMove private bool autoMoveUsed; private int targetX; private int targetY; public void AutoMoveTo(Point p) { autoMoveUsed = true; targetX = p.X; targetY = p.Y; IsMoving = true; } public bool AutoMoveTargetReached => (targetX == X) && (targetY == Y); public bool AutoMoving { get => autoMoveUsed; set => autoMoveUsed = value; } #endregion #region Home public void SetHome(Point p) { home = p; } public void AutoMoveToHome() { AutoMoveTo(home); } public int GetHomeX() { return home.X; } public int GetHomeY() { return home.Y; } #endregion public void Render(Renderer renderer) { if (autoMoveUsed) { if (targetY > Y) { FacingDirection = CharSetFacing.Down; Y++; } else if (targetY < Y) { FacingDirection = CharSetFacing.Up; Y--; } else if (targetX > X) { FacingDirection = CharSetFacing.Right; X++; } else if (targetX < X) { FacingDirection = CharSetFacing.Left; X--; } else { FacingDirection = CharSetFacing.Down; Stepping = CharSetStepping.Stand; IsMoving = false; } } sourceRect.x = 0; sourceRect.y = 0; sourceRect.x += charNumberOffsets[_charNo].X; sourceRect.y += charNumberOffsets[_charNo].Y; sourceRect.x += steppingOffstes[(byte)Stepping]; sourceRect.y += facingOffsets[(byte)FacingDirection]; if (IsMoving) { steppingRemain++; if (steppingRemain == steppingDelay) { steppingRemain = 0; switch (Stepping) { case CharSetStepping.Stand: Stepping = CharSetStepping.RightFootForward; break; case CharSetStepping.RightFootForward: Stepping = CharSetStepping.LeftFootForward; break; case CharSetStepping.LeftFootForward: Stepping = CharSetStepping.Stand; break; default: Stepping = CharSetStepping.Stand; break; } } } targetRect.x = X; targetRect.y = Y; renderer.Copy(_texture, ref sourceRect, ref targetRect); } } enum CharSetFacing : byte { Up = 0, Right = 1, Down = 2, Left = 3 } enum CharSetStepping : byte { LeftFootForward = 0, Stand = 1, RightFootForward = 2 } }