diff options
Diffstat (limited to 'Oneko.cs')
| -rw-r--r-- | Oneko.cs | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/Oneko.cs b/Oneko.cs new file mode 100644 index 0000000..274782c --- /dev/null +++ b/Oneko.cs @@ -0,0 +1,178 @@ +using System.Numerics; +using OnekoOnline.Net; +using Raylib_cs; + +namespace OnekoOnline; + +class Oneko : Drawable +{ + public readonly Bitmap SpriteSheet; + Vector2 TargetPosition; + OnekoAnimation Animation = ScratchSelf; + + float updateTimer = 0f; + const float updateRate = 1f/5f; + int Frame = 0; + + public static Oneko? LocalOneko; + + public static Dictionary<int, Oneko> NetNekos = []; + + public Oneko() + { + Size = new(32,32); + Position = new(320/2, 240/2); + + string SpriteSheetPath = OnekoOnline.Config.GetValue("SpriteSheetPath", "oneko.png"); + + if (File.Exists(SpriteSheetPath) && new FileInfo(SpriteSheetPath).Length < 128*256*3) { + SpriteSheet = Bitmap.FromPNGMemory(File.ReadAllBytes(SpriteSheetPath)); + } else { + Console.WriteLine("Path to spritesheet was invalid, using the default."); + SpriteSheet = Bitmap.FromPNGMemory(EmbeddedResources.GetResource("oneko.png")); + } + + LocalOneko ??= this; + + Drawables.Add(this); + } + + public Oneko(Bitmap spriteSheet) + { + Size = new(32,32); + Position = new(0, 0); + SpriteSheet = spriteSheet; + + Drawables.Add(this); + } + + public override void Draw() + { + Raylib.DrawTexturePro(SpriteSheet.Texture, Animation.GetFrame(Frame), new Rectangle(Position.X, Position.Y, Size.X, Size.Y), Size/2, Rotation, Color.WHITE); + } + + public override void Update(float delta) + { + if (this == LocalOneko) { + foreach (User user in Client.Users.Values) { + if (!NetNekos.ContainsKey(user.Id)) { + Bitmap spriteSheet = Bitmap.Deserialize(user.SpriteSheet); + NetNekos.Add(user.Id, new Oneko(spriteSheet)); + } + } + } + + updateTimer += delta; + if (updateTimer < updateRate) return; + + if (Raylib.IsWindowFocused()) { + TargetPosition = Raylib.GetMousePosition()/2; + } else { + TargetPosition = new Vector2(320/2, 240/2); + } + Vector2 TargetDirection = (TargetPosition-Position).LimitLength(10f); + if (TargetDirection.Length() > 1) Animation = GetDirectionalRun(TargetDirection); + else Animation = Idle; + Position += TargetDirection; + + Frame = (Frame + 1) % 2; + + updateTimer = 0f; + } + + public override void Dispose() + { + SpriteSheet.Dispose(); + Drawables.Remove(this); + } + + struct OnekoAnimation(Rectangle frame1, Rectangle frame2) + { + public Rectangle Frame1 = frame1; + Rectangle Frame2 = frame2; + + public readonly Rectangle GetFrame(int frame) { + return (frame % 2 == 0) ? Frame1 : Frame2; + } + } + + static OnekoAnimation GetDirectionalRun(Vector2 direction) + { + direction = Vector2.Normalize(direction); + + Vector2 nearestDir = Directions.Up; + float nearestDistance = 10f; + foreach (Vector2 dir in Directions.AllDirections) { + float distanceCheck = Vector2.Distance(direction, dir); + if (distanceCheck < nearestDistance) { + nearestDir = dir; + nearestDistance = distanceCheck; + } + } + + return RunDirections[nearestDir]; + } + + static readonly Rectangle Idle1 = new(32*3, 32*3, 32, 32); + static readonly Rectangle Alert1 = new(32*7, 32*3, 32, 32); + static readonly Rectangle Yawn1 = new(32*3, 32*2, 32, 32); + static readonly Rectangle Clean1 = new(32*7, 0, 32, 32); + static readonly Rectangle Scratch1 = new(32*5, 0, 32, 32); + static readonly Rectangle Scratch2 = new(32*6, 0, 32, 32); + static readonly Rectangle Sleep1 = new(32*2, 0, 32, 32); + static readonly Rectangle Sleep2 = new(32*2, 32, 32, 32); + static readonly Rectangle RunUp1 = new(32, 32*3, 32, 32); + static readonly Rectangle RunUp2 = new(32, 32*2, 32, 32); + static readonly Rectangle RunUpLeft1 = new(32, 32, 32, 32); + static readonly Rectangle RunUpLeft2 = new(32, 0, 32, 32); + static readonly Rectangle RunLeft1 = new(32*4, 32*3, 32, 32); + static readonly Rectangle RunLeft2 = new(32*4, 32*2, 32, 32); + static readonly Rectangle RunDownLeft1 = new(32*6, 32, 32, 32); + static readonly Rectangle RunDownLeft2 = new(32*5, 32*3, 32, 32); + static readonly Rectangle RunDown1 = new(32*7, 32*2, 32, 32); + static readonly Rectangle RunDown2 = new(32*6, 32*3, 32, 32); + static readonly Rectangle RunDownRight1 = new(32*5, 32*2, 32, 32); + static readonly Rectangle RunDownRight2 = new(32*5, 32, 32, 32); + static readonly Rectangle RunRight1 = new(32*3, 32, 32, 32); + static readonly Rectangle RunRight2 = new(32*3, 0, 32, 32); + static readonly Rectangle RunUpRight1 = new(0, 32*3, 32, 32); + static readonly Rectangle RunUpRight2 = new(0, 32*2, 32, 32); + static readonly Rectangle ScratchUp1 = new(0, 0, 32, 32); + static readonly Rectangle ScratchUp2 = new(0, 32, 32, 32); + static readonly Rectangle ScratchLeft1 = new(32*4, 0, 32, 32); + static readonly Rectangle ScratchLeft2 = new(32*4, 32, 32, 32); + static readonly Rectangle ScratchDown1 = new(32*7, 32, 32, 32); + static readonly Rectangle ScratchDown2 = new(32*6, 32*2, 32, 32); + static readonly Rectangle ScratchRight1 = new(32*2, 32*2, 32, 32); + static readonly Rectangle ScratchRight2 = new(32*2, 32*3, 32, 32); + + static readonly OnekoAnimation Idle = new(Idle1, Idle1); + static readonly OnekoAnimation Alert = new(Alert1, Alert1); + static readonly OnekoAnimation Yawn = new(Yawn1, Yawn1); + static readonly OnekoAnimation Clean = new(Clean1, Clean1); + static readonly OnekoAnimation ScratchSelf = new(Scratch1, Scratch2); + static readonly OnekoAnimation Sleep = new(Sleep1, Sleep2); + static readonly OnekoAnimation RunUp = new(RunUp1, RunUp2); + static readonly OnekoAnimation RunUpLeft = new(RunUpLeft1, RunUpLeft2); + static readonly OnekoAnimation RunLeft = new(RunLeft1, RunLeft2); + static readonly OnekoAnimation RunDownLeft = new(RunDownLeft1, RunDownLeft2); + static readonly OnekoAnimation RunDown = new(RunDown1, RunDown2); + static readonly OnekoAnimation RunDownRight = new(RunDownRight1, RunDownRight2); + static readonly OnekoAnimation RunRight = new(RunRight1, RunRight2); + static readonly OnekoAnimation RunUpRight = new(RunUpRight1, RunUpRight2); + static readonly OnekoAnimation ScratchUp = new(ScratchUp1, ScratchUp2); + static readonly OnekoAnimation ScratchLeft = new(ScratchLeft1, ScratchLeft2); + static readonly OnekoAnimation ScratchDown = new(ScratchDown1, ScratchDown2); + static readonly OnekoAnimation ScratchRight = new(ScratchRight1, ScratchRight2); + + static readonly Dictionary<Vector2, OnekoAnimation> RunDirections = new() { + {Directions.Up, RunUp}, + {Directions.Down, RunDown}, + {Directions.Left, RunLeft}, + {Directions.Right, RunRight}, + {Directions.UpLeft, RunUpLeft}, + {Directions.UpRight, RunUpRight}, + {Directions.DownRight, RunDownRight}, + {Directions.DownLeft, RunDownLeft}, + }; +}
\ No newline at end of file |
