From 8859dc0da5a26d64d3ddfb1c13b1b7603fff9114 Mon Sep 17 00:00:00 2001 From: Frost-ZX Date: Wed, 22 Jul 2026 20:34:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E5=A7=8B=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/DesktopRoachRampage.exe | Bin 0 -> 19456 bytes DesktopRoachRampage/app/Program.cs | 706 ++++++++++++++++++ .../bin/DesktopRoachRampage.exe | Bin 0 -> 19456 bytes DesktopRoachRampage/bin/images/fly_00.png | Bin 0 -> 633 bytes DesktopRoachRampage/bin/images/fly_01.png | Bin 0 -> 639 bytes DesktopRoachRampage/bin/images/fly_02.png | Bin 0 -> 642 bytes DesktopRoachRampage/bin/images/fly_03.png | Bin 0 -> 665 bytes DesktopRoachRampage/bin/images/fly_04.png | Bin 0 -> 652 bytes DesktopRoachRampage/bin/images/fly_05.png | Bin 0 -> 634 bytes DesktopRoachRampage/bin/images/fly_06.png | Bin 0 -> 629 bytes DesktopRoachRampage/bin/images/fly_07.png | Bin 0 -> 649 bytes DesktopRoachRampage/bin/images/walk_00.png | Bin 0 -> 570 bytes DesktopRoachRampage/bin/images/walk_01.png | Bin 0 -> 578 bytes DesktopRoachRampage/bin/images/walk_02.png | Bin 0 -> 582 bytes DesktopRoachRampage/bin/images/walk_03.png | Bin 0 -> 590 bytes DesktopRoachRampage/bin/images/walk_04.png | Bin 0 -> 585 bytes DesktopRoachRampage/bin/images/walk_05.png | Bin 0 -> 595 bytes DesktopRoachRampage/bin/images/walk_06.png | Bin 0 -> 602 bytes DesktopRoachRampage/bin/images/walk_07.png | Bin 0 -> 589 bytes DesktopRoachRampage/build.bat | 24 + DesktopRoachRampage/run.bat | 12 + tools/GenerateCockroaches.cs | 283 +++++++ tools/GenerateCockroaches.exe | Bin 0 -> 7680 bytes tools/generate_images.py | 40 + 24 files changed, 1065 insertions(+) create mode 100644 DesktopRoachRampage/app/DesktopRoachRampage.exe create mode 100644 DesktopRoachRampage/app/Program.cs create mode 100644 DesktopRoachRampage/bin/DesktopRoachRampage.exe create mode 100644 DesktopRoachRampage/bin/images/fly_00.png create mode 100644 DesktopRoachRampage/bin/images/fly_01.png create mode 100644 DesktopRoachRampage/bin/images/fly_02.png create mode 100644 DesktopRoachRampage/bin/images/fly_03.png create mode 100644 DesktopRoachRampage/bin/images/fly_04.png create mode 100644 DesktopRoachRampage/bin/images/fly_05.png create mode 100644 DesktopRoachRampage/bin/images/fly_06.png create mode 100644 DesktopRoachRampage/bin/images/fly_07.png create mode 100644 DesktopRoachRampage/bin/images/walk_00.png create mode 100644 DesktopRoachRampage/bin/images/walk_01.png create mode 100644 DesktopRoachRampage/bin/images/walk_02.png create mode 100644 DesktopRoachRampage/bin/images/walk_03.png create mode 100644 DesktopRoachRampage/bin/images/walk_04.png create mode 100644 DesktopRoachRampage/bin/images/walk_05.png create mode 100644 DesktopRoachRampage/bin/images/walk_06.png create mode 100644 DesktopRoachRampage/bin/images/walk_07.png create mode 100644 DesktopRoachRampage/build.bat create mode 100644 DesktopRoachRampage/run.bat create mode 100644 tools/GenerateCockroaches.cs create mode 100644 tools/GenerateCockroaches.exe create mode 100644 tools/generate_images.py diff --git a/DesktopRoachRampage/app/DesktopRoachRampage.exe b/DesktopRoachRampage/app/DesktopRoachRampage.exe new file mode 100644 index 0000000000000000000000000000000000000000..56560141c983749209db11539c1d4c3c7a27c10a GIT binary patch literal 19456 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 literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/app/Program.cs b/DesktopRoachRampage/app/Program.cs new file mode 100644 index 0000000..54ca45a --- /dev/null +++ b/DesktopRoachRampage/app/Program.cs @@ -0,0 +1,706 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Windows.Forms; +using System.IO; +using Microsoft.Win32; + +namespace DesktopRoachRampage +{ + static class Program + { + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } + + enum CockroachState + { + Walking, + Flying, + Dead // 死亡状态 + } + + class Cockroach + { + public float X { get; set; } + public float Y { get; set; } + public float DirectionX { get; set; } + public float DirectionY { get; set; } + public float CurrentAngle { get; set; } + public int CurrentFrame { get; set; } + public Random Random { get; set; } + public CockroachState State { get; set; } + public float FlyHeightOffset { get; set; } + public float StateTimer { get; set; } + public float DeathTimer { get; set; } // 死亡后消失计时器 + public float Scale { get; set; } // 缩放比例,死亡时缩小 + + public Cockroach(float x, float y, Random rand) + { + X = x; + Y = y; + Random = rand; + State = CockroachState.Walking; + FlyHeightOffset = 0; + StateTimer = 0; + DeathTimer = 0; + Scale = 1f; + + double angle = rand.NextDouble() * Math.PI * 2; + float speed = 2f + (float)rand.NextDouble() * 2f; + DirectionX = (float)Math.Cos(angle) * speed; + DirectionY = (float)Math.Sin(angle) * speed; + + CurrentAngle = (float)(angle * 180 / Math.PI) + 90f; + CurrentFrame = rand.Next(8); + } + + // 被打死 + public void Kill() + { + if (State == CockroachState.Dead) return; + + State = CockroachState.Dead; + DeathTimer = 0; + DirectionX = 0; + DirectionY = 0; + } + + public void Update(Rectangle totalBounds, int petSize) + { + // 如果已经死亡,处理消失动画 + if (State == CockroachState.Dead) + { + DeathTimer++; + Scale = Math.Max(0, 1f - DeathTimer / 30f); // 30帧内缩小到消失 + return; + } + + StateTimer++; + + // 更频繁检查状态切换(约5秒),飞行概率更高 + if (StateTimer > 100) + { + StateTimer = 0; + if (Random.NextDouble() < 0.7) // 70%概率切换 + { + if (State == CockroachState.Walking) + { + // 开始飞行 - 速度大幅提升 + State = CockroachState.Flying; + float flySpeed = 7f + (float)Random.NextDouble() * 4f; // 飞行速度7-11 + double flyAngle = Random.NextDouble() * Math.PI * 2; + DirectionX = (float)Math.Cos(flyAngle) * flySpeed; + DirectionY = (float)Math.Sin(flyAngle) * flySpeed; + } + else + { + // 降落 + State = CockroachState.Walking; + FlyHeightOffset = 0; + float walkSpeed = 2f + (float)Random.NextDouble() * 2f; + double walkAngle = Random.NextDouble() * Math.PI * 2; + DirectionX = (float)Math.Cos(walkAngle) * walkSpeed; + DirectionY = (float)Math.Sin(walkAngle) * walkSpeed; + } + } + } + + // 飞行时高度偏移 + if (State == CockroachState.Flying) + { + FlyHeightOffset = (float)Math.Sin(StateTimer * 0.1) * 5f - 8f; + } + + // 移动 + X += DirectionX; + Y += DirectionY; + + // 边界检测与反弹 + if (X <= totalBounds.Left || X >= totalBounds.Right - petSize) + { + DirectionX = -DirectionX + (float)(Random.NextDouble() - 0.5) * 2; + float minSpeed = State == CockroachState.Flying ? 6f : 1.5f; + if (Math.Abs(DirectionX) < minSpeed) DirectionX = DirectionX > 0 ? minSpeed + 1 : -minSpeed - 1; + X = Math.Max(totalBounds.Left, Math.Min(X, totalBounds.Right - petSize)); + } + + if (Y <= totalBounds.Top || Y >= totalBounds.Bottom - petSize) + { + DirectionY = -DirectionY + (float)(Random.NextDouble() - 0.5) * 2; + float minSpeed = State == CockroachState.Flying ? 6f : 1.5f; + if (Math.Abs(DirectionY) < minSpeed) DirectionY = DirectionY > 0 ? minSpeed + 1 : -minSpeed - 1; + Y = Math.Max(totalBounds.Top, Math.Min(Y, totalBounds.Bottom - petSize)); + } + + // 随机改变方向 + if (Random.Next(100) < 5) + { + float changeRange = State == CockroachState.Flying ? 6f : 3f; + DirectionX += (float)(Random.NextDouble() - 0.5) * changeRange; + DirectionY += (float)(Random.NextDouble() - 0.5) * changeRange; + float maxSpeed = State == CockroachState.Flying ? 12f : 5f; + DirectionX = Math.Max(-maxSpeed, Math.Min(maxSpeed, DirectionX)); + DirectionY = Math.Max(-maxSpeed, Math.Min(maxSpeed, DirectionY)); + } + + CurrentFrame = (CurrentFrame + 1) % 8; + } + + public void Draw(Graphics g, Image[] walkFrames, Image[] flyFrames, int petSize) + { + Image[] frames = State == CockroachState.Flying ? flyFrames : walkFrames; + if (frames == null || frames.Length == 0) return; + + Image frame = frames[CurrentFrame % frames.Length]; + if (frame == null) return; + + float targetAngle = (float)(Math.Atan2(DirectionY, DirectionX) * 180 / Math.PI) + 90f; + + float angleDiff = targetAngle - CurrentAngle; + if (angleDiff > 180) angleDiff -= 360; + if (angleDiff < -180) angleDiff += 360; + CurrentAngle += angleDiff * 0.15f; + + Matrix oldMatrix = g.Transform; + + float drawY = Y + FlyHeightOffset; + float drawSize = petSize * Scale; + + // 绘制缩放和旋转 + g.TranslateTransform(X + drawSize / 2, drawY + drawSize / 2); + g.RotateTransform(CurrentAngle); + g.ScaleTransform(Scale, Scale); + g.TranslateTransform(-drawSize / 2, -drawSize / 2); + + g.DrawImage(frame, 0, 0, drawSize, drawSize); + + g.Transform = oldMatrix; + } + } + + // 点击特效类 + class ClickEffect + { + public float X { get; set; } + public float Y { get; set; } + public float Timer { get; set; } + public const float MaxTime = 15f; // 持续15帧 + + public ClickEffect(float x, float y) + { + X = x; + Y = y; + Timer = 0; + } + + public void Update() + { + Timer++; + } + + public void Draw(Graphics g) + { + float progress = Timer / MaxTime; + float size = 20 + progress * 30; // 从20扩散到50 + float alpha = 1f - progress; // 逐渐透明 + + using (Pen pen = new Pen(Color.FromArgb((int)(alpha * 200), 255, 100, 100), 3)) + { + g.DrawEllipse(pen, X - size / 2, Y - size / 2, size, size); + } + } + + public bool IsDead() + { + return Timer >= MaxTime; + } + } + + class MainForm : Form + { + private List cockroaches; + private Image[] walkFrames; + private Image[] flyFrames; + private Timer mainTimer; + private Timer breedTimer; + private Random random; + private const int PetSize = 64; + private bool dragging = false; + private int dragIndex = -1; + private Point dragOffset; + private const int MaxCockroaches = 50; + private Rectangle totalScreenBounds; + private Bitmap bufferBitmap; + private Graphics bufferGraphics; + + // 打蟑螂相关 + private int score = 0; // 分数 + private int lastScore = 0; // 上次的分数 + private float scoreIdleTimer = 0; // 分数没变化的时间 + private bool showScore = true; // 是否显示分数 + private List clickEffects; // 点击特效 + private Font scoreFont; + + public MainForm() + { + random = new Random(); + cockroaches = new List(); + clickEffects = new List(); + + // 启用双缓冲优化 + this.SetStyle(ControlStyles.DoubleBuffer | + ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer, true); + this.UpdateStyles(); + + CalculateTotalScreenBounds(); + + this.FormBorderStyle = FormBorderStyle.None; + this.ShowInTaskbar = false; + this.TopMost = true; + this.TransparencyKey = Color.Magenta; + this.BackColor = Color.Magenta; + this.Bounds = totalScreenBounds; + + LoadFrames(); + + // 创建双缓冲位图 + CreateBufferBitmap(); + + // 创建分数字体 + scoreFont = new Font("Arial", 14f, FontStyle.Bold); + + SpawnCockroachOnPrimary(); + + mainTimer = new Timer(); + mainTimer.Interval = 50; + mainTimer.Tick += MainTimer_Tick; + mainTimer.Start(); + + breedTimer = new Timer(); + breedTimer.Interval = 8000; + breedTimer.Tick += BreedTimer_Tick; + breedTimer.Start(); + + ContextMenuStrip menu = new ContextMenuStrip(); + menu.Items.Add("清除所有蟑螂", null, (s, e) => ClearAll()); + menu.Items.Add("添加一只蟑螂", null, (s, e) => SpawnCockroach()); + menu.Items.Add("让所有蟑螂起飞!", null, (s, e) => MakeAllFly()); + menu.Items.Add("让所有蟑螂降落!", null, (s, e) => MakeAllLand()); + menu.Items.Add("随机分布到所有屏幕", null, (s, e) => RedistributeAll()); + menu.Items.Add("-", null, null); + menu.Items.Add("重置分数", null, (s, e) => ResetScore()); + menu.Items.Add("-", null, null); + menu.Items.Add("Exit / 退出", null, (s, e) => Application.Exit()); + this.ContextMenuStrip = menu; + + this.MouseDown += MainForm_MouseDown; + this.MouseMove += MainForm_MouseMove; + this.MouseUp += MainForm_MouseUp; + + SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged; + } + + private void ResetScore() + { + score = 0; + lastScore = 0; + showScore = true; + scoreIdleTimer = 0; + this.Invalidate(); + } + + private void CreateBufferBitmap() + { + if (bufferBitmap != null) + { + bufferBitmap.Dispose(); + bufferGraphics.Dispose(); + } + + bufferBitmap = new Bitmap(totalScreenBounds.Width, totalScreenBounds.Height, PixelFormat.Format32bppArgb); + bufferGraphics = Graphics.FromImage(bufferBitmap); + bufferGraphics.InterpolationMode = InterpolationMode.NearestNeighbor; + bufferGraphics.SmoothingMode = SmoothingMode.None; + } + + private void CalculateTotalScreenBounds() + { + totalScreenBounds = Rectangle.Empty; + foreach (Screen screen in Screen.AllScreens) + { + totalScreenBounds = Rectangle.Union(totalScreenBounds, screen.Bounds); + } + } + + private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) + { + CalculateTotalScreenBounds(); + this.Bounds = totalScreenBounds; + CreateBufferBitmap(); + this.Invalidate(); + } + + private void SpawnCockroachOnPrimary() + { + if (cockroaches.Count >= MaxCockroaches) return; + + Rectangle primary = Screen.PrimaryScreen.WorkingArea; + float x = primary.Left + random.Next(100, primary.Width - 100 - PetSize); + float y = primary.Top + random.Next(100, primary.Height - 100 - PetSize); + + cockroaches.Add(new Cockroach(x, y, random)); + + UpdateTitle(); + } + + private void SpawnCockroach() + { + if (cockroaches.Count >= MaxCockroaches) return; + + Screen[] screens = Screen.AllScreens; + Screen randomScreen = screens[random.Next(screens.Length)]; + Rectangle workingArea = randomScreen.WorkingArea; + + float x = workingArea.Left + random.Next(50, workingArea.Width - 50 - PetSize); + float y = workingArea.Top + random.Next(50, workingArea.Height - 50 - PetSize); + + cockroaches.Add(new Cockroach(x, y, random)); + + UpdateTitle(); + } + + private void MakeAllFly() + { + foreach (var roach in cockroaches) + { + if (roach.State != CockroachState.Dead) + { + roach.State = CockroachState.Flying; + roach.StateTimer = 0; + float flySpeed = 7f + (float)random.NextDouble() * 4f; + double flyAngle = random.NextDouble() * Math.PI * 2; + roach.DirectionX = (float)Math.Cos(flyAngle) * flySpeed; + roach.DirectionY = (float)Math.Sin(flyAngle) * flySpeed; + } + } + this.Invalidate(); + } + + private void MakeAllLand() + { + foreach (var roach in cockroaches) + { + if (roach.State != CockroachState.Dead) + { + roach.State = CockroachState.Walking; + roach.FlyHeightOffset = 0; + roach.StateTimer = 0; + float walkSpeed = 2f + (float)random.NextDouble() * 2f; + double walkAngle = random.NextDouble() * Math.PI * 2; + roach.DirectionX = (float)Math.Cos(walkAngle) * walkSpeed; + roach.DirectionY = (float)Math.Sin(walkAngle) * walkSpeed; + } + } + this.Invalidate(); + } + + private void RedistributeAll() + { + Screen[] screens = Screen.AllScreens; + foreach (var roach in cockroaches) + { + if (roach.State != CockroachState.Dead) + { + Screen randomScreen = screens[random.Next(screens.Length)]; + Rectangle workingArea = randomScreen.WorkingArea; + + roach.X = workingArea.Left + random.Next(50, workingArea.Width - 50 - PetSize); + roach.Y = workingArea.Top + random.Next(50, workingArea.Height - 50 - PetSize); + } + } + this.Invalidate(); + } + + private void UpdateTitle() + { + int flyCount = 0; + int walkCount = 0; + int deadCount = 0; + foreach (var roach in cockroaches) + { + if (roach.State == CockroachState.Flying) + flyCount++; + else if (roach.State == CockroachState.Walking) + walkCount++; + else + deadCount++; + } + this.Text = string.Format("Desktop Roach Rampage - {0} roaches alive (flying:{1} walking:{2}) - killed: {3}", + cockroaches.Count - deadCount, flyCount, walkCount, score); + } + + private void BreedTimer_Tick(object sender, EventArgs e) + { + // 检查是否所有蟑螂都被消灭了 + int aliveCount = cockroaches.FindAll(r => r.State != CockroachState.Dead).Count; + + if (aliveCount == 0) + { + // 蟑螂全被消灭了,自动生成一只 + SpawnCockroachOnPrimary(); + return; + } + + int currentCount = cockroaches.Count; + for (int i = 0; i < currentCount && cockroaches.Count < MaxCockroaches; i++) + { + // 飞行中的蟑螂繁殖概率更高 + double breedChance = cockroaches[i].State == CockroachState.Flying ? 0.6 : 0.4; + if (cockroaches[i].State != CockroachState.Dead && random.NextDouble() < breedChance) + { + Cockroach parent = cockroaches[i]; + float offsetX = (float)(random.NextDouble() - 0.5) * 80; + float offsetY = (float)(random.NextDouble() - 0.5) * 80; + + float newX = parent.X + offsetX; + float newY = parent.Y + offsetY; + + newX = Math.Max(totalScreenBounds.Left, Math.Min(newX, totalScreenBounds.Right - PetSize)); + newY = Math.Max(totalScreenBounds.Top, Math.Min(newY, totalScreenBounds.Bottom - PetSize)); + + cockroaches.Add(new Cockroach(newX, newY, random)); + } + } + + UpdateTitle(); + this.Invalidate(); + } + + private void ClearAll() + { + cockroaches.Clear(); + SpawnCockroachOnPrimary(); + this.Invalidate(); + } + + private void MainForm_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + Point mousePos = this.PointToClient(e.Location); + + // 从后往前检测(点到最上面的蟑螂) + bool hit = false; + for (int i = cockroaches.Count - 1; i >= 0; i--) + { + Cockroach roach = cockroaches[i]; + if (roach.State == CockroachState.Dead) continue; + + float drawY = roach.Y + roach.FlyHeightOffset; + RectangleF rect = new RectangleF(roach.X - this.Left, drawY - this.Top, PetSize, PetSize); + if (rect.Contains(mousePos)) + { + // 打到蟑螂了! + roach.Kill(); + score++; + hit = true; + showScore = true; // 立即显示分数 + scoreIdleTimer = 0; + + // 添加点击特效 + float effectX = mousePos.X + this.Left; + float effectY = mousePos.Y + this.Top; + clickEffects.Add(new ClickEffect(effectX, effectY)); + break; + } + } + + // 如果没打到,也添加一个空的点击特效 + if (!hit) + { + float effectX = mousePos.X + this.Left; + float effectY = mousePos.Y + this.Top; + clickEffects.Add(new ClickEffect(effectX, effectY)); + } + + // 检查是否拖动(只有没打到蟑螂时才拖动) + if (!hit) + { + for (int i = cockroaches.Count - 1; i >= 0; i--) + { + Cockroach roach = cockroaches[i]; + if (roach.State == CockroachState.Dead) continue; + + float drawY = roach.Y + roach.FlyHeightOffset; + RectangleF rect = new RectangleF(roach.X - this.Left, drawY - this.Top, PetSize, PetSize); + if (rect.Contains(mousePos)) + { + dragging = true; + dragIndex = i; + dragOffset = new Point(mousePos.X - (int)(roach.X - this.Left), mousePos.Y - (int)(drawY - this.Top)); + break; + } + } + } + } + } + + private void MainForm_MouseMove(object sender, MouseEventArgs e) + { + if (dragging && dragIndex >= 0 && dragIndex < cockroaches.Count) + { + Point mousePos = this.PointToClient(e.Location); + Cockroach roach = cockroaches[dragIndex]; + roach.X = mousePos.X - dragOffset.X + this.Left; + roach.Y = mousePos.Y - dragOffset.Y + this.Top - roach.FlyHeightOffset; + this.Invalidate(); + } + } + + private void MainForm_MouseUp(object sender, MouseEventArgs e) + { + dragging = false; + dragIndex = -1; + } + + private void LoadFrames() + { + string basePath = AppDomain.CurrentDomain.BaseDirectory; + string imagePath = Path.Combine(basePath, "images"); + + if (!Directory.Exists(imagePath)) + { + imagePath = Path.Combine(basePath, "..", "images"); + } + + walkFrames = new Image[8]; + flyFrames = new Image[8]; + + for (int i = 0; i < 8; i++) + { + string walkFrameFile = Path.Combine(imagePath, string.Format("walk_{0:D2}.png", i)); + if (File.Exists(walkFrameFile)) + walkFrames[i] = Image.FromFile(walkFrameFile); + + string flyFrameFile = Path.Combine(imagePath, string.Format("fly_{0:D2}.png", i)); + if (File.Exists(flyFrameFile)) + flyFrames[i] = Image.FromFile(flyFrameFile); + } + } + + private void MainTimer_Tick(object sender, EventArgs e) + { + // 更新蟑螂 + foreach (var roach in cockroaches) + { + roach.Update(totalScreenBounds, PetSize); + } + + // 移除完全消失的死蟑螂 + cockroaches.RemoveAll(r => r.State == CockroachState.Dead && r.Scale <= 0); + + // 更新点击特效 + for (int i = clickEffects.Count - 1; i >= 0; i--) + { + clickEffects[i].Update(); + if (clickEffects[i].IsDead()) + { + clickEffects.RemoveAt(i); + } + } + + // 分数显示逻辑:分数变化时显示,2秒不变化则隐藏 + if (score != lastScore) + { + lastScore = score; + scoreIdleTimer = 0; + showScore = true; + } + else + { + scoreIdleTimer++; + // 50ms每帧,40帧 = 2秒 + if (scoreIdleTimer >= 40) + { + showScore = false; + } + } + + UpdateTitle(); + this.Invalidate(); + } + + protected override void OnPaint(PaintEventArgs e) + { + // 使用双缓冲绘制 + Graphics g = bufferGraphics; + + g.Clear(Color.Magenta); + + g.TranslateTransform(-this.Left, -this.Top); + + // 绘制蟑螂 + foreach (var roach in cockroaches) + { + roach.Draw(g, walkFrames, flyFrames, PetSize); + } + + // 绘制点击特效 + foreach (var effect in clickEffects) + { + effect.Draw(g); + } + + // 绘制分数(在主屏幕左上角) + if (showScore) + { + g.ResetTransform(); + g.TranslateTransform(Screen.PrimaryScreen.Bounds.Left - this.Left, + Screen.PrimaryScreen.Bounds.Top - this.Top); + + string scoreText = string.Format("Killed: {0}", score); + g.DrawString(scoreText, scoreFont, Brushes.Red, 10, 10); + + // 绘制剩余数量 + int alive = cockroaches.FindAll(r => r.State != CockroachState.Dead).Count; + string countText = string.Format("Alive: {0}", alive); + g.DrawString(countText, scoreFont, Brushes.DarkOrange, 10, 35); + + g.ResetTransform(); + } + + // 一次性绘制到屏幕 + e.Graphics.DrawImage(bufferBitmap, 0, 0); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged; + if (mainTimer != null) mainTimer.Dispose(); + if (breedTimer != null) breedTimer.Dispose(); + if (bufferBitmap != null) bufferBitmap.Dispose(); + if (bufferGraphics != null) bufferGraphics.Dispose(); + if (scoreFont != null) scoreFont.Dispose(); + if (walkFrames != null) + foreach (var frame in walkFrames) + if (frame != null) frame.Dispose(); + if (flyFrames != null) + foreach (var frame in flyFrames) + if (frame != null) frame.Dispose(); + } + base.Dispose(disposing); + } + } +} diff --git a/DesktopRoachRampage/bin/DesktopRoachRampage.exe b/DesktopRoachRampage/bin/DesktopRoachRampage.exe new file mode 100644 index 0000000000000000000000000000000000000000..56560141c983749209db11539c1d4c3c7a27c10a GIT binary patch literal 19456 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 literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/fly_00.png b/DesktopRoachRampage/bin/images/fly_00.png new file mode 100644 index 0000000000000000000000000000000000000000..f4b8ffacfbf773024ca3cfe2d601068fc465d31d GIT binary patch literal 633 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-3`~5UE{-7;ac`#?1|2pKaS1MFo@H{y#3b`l zz~u`UmiYPl&Yk5PP%M;}>UKusb9(r+)ZgA>n>FwGRCwIKwN?FGo+5z;;I zAbOg^A~T5}UtiW;7V@~F#xjrT`;`_KUxN(3JJH-i#Xo=klVOUVUOegh^yB*tBsR2c z(0_A$=ERCzo69mDXH;b#yxp+B>7la3I+oq{&uzW_dJ#hn)0@WWZQE6sJS+Rka)ar^ zI@xdKkxm{Z9$9(QS!?F>T|a#6yab!3uELq_hmYUnac`J!$YZpeVNR{~1A9>cxppR&50AD8MiaFaCy{fF5@~-YH?XuD0`!Q z*rM)*LF-+07_L8kR^@PL_75)ayEj7^%jVvV=N6iGW4GkLV+)d5Z+s}L=k=(VY-Q7S t^g-}%Tg8i9JoC8jGhvS)NSys(o$k)Tt7P%O5SUyTJYD@<);T3K0RUbg0j>Z5 literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/fly_01.png b/DesktopRoachRampage/bin/images/fly_01.png new file mode 100644 index 0000000000000000000000000000000000000000..e1c5b832ad0ad443177e8f0eb3be740918981666 GIT binary patch literal 639 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-3``=PE{-7;ac^gA^gHYz;1c|q-6V5GX2zu@ z3zsci=;`b0J9k$9f@j`8v==)^ZJD*xI{wYqn;AhiCoAWC&pYO&vr)P&aXAmCsmBUO zCtjhf2?5P5QYu#z7P6rU={>Bm;^X{cJF}WiD0oJ7ho;M0&m_LU_Emy=**iHF@z0D% zN^5da5p3_95!if0$cNY9>ppLVjVfy!qprI;0FAb-tlcBc^Cw#0#mr;|0I(Dcfvx04BqJc;twm=$2H`3wHxZyzEb@ob0_&S zYXoQeU*D-BLb5^J`>Pn=FMoXBvFN%4Tc+j$liTaov;LXRR21JC!?0& z;PQnFOZF}wdctFx+yCmE_wR1pGtiuuvbXp6zj{H(H_I|_RkpR5dsH;z zBVwedUoPZYu)g)k)(vJAEk|V5=ozxVHulsx_$x>=YOZ4vudd$Bq-8BFtYOo)%?NC2 zQT6VQ*p#lR5_Q4&LX5|jly27vFHZjanb`GUbKHa%ov)cveoR!I@Pd&|K9Z^PTEc_t z%YQFaose<%_vy#+8NDB5zHb4VmEZnXWTIV5cftn=yCCE9OhT%4`|Ot=xc)T8^@cKY z_QT-w$$}Qa%J+ER&uMn)+{rrS-mbPg?Z&2NkqrB;S{|vj2u_~ND)X&8(#fHOBpaU@wCeRC}5^Os~3$!217Z3QQrXecu?Xi!yhmPa#cGt7_nRYTg`8VtHG>1b> zl@DWn1Tk)Gxe}x8vBtGJTVl>g}28SrsjSQ id4-3(LicbIKUg0G-<$S)e;O#2F?hQAxvXt`)7D9)&m%gI?m9$OZqFNpEjlG5us;l;_1Uo$x#oUd|Rq`r>(!o%r0jV}BKKPIV8$T<4) z?N56dwz~Sto@oN_@_9M6_uI!ef2g&K`*9;zpGEz<*Ng@hzlHCwr@#7JI4{T}qEoct z1;e!uyIA&$onOz&slAfvgJzNg_a?sYD}kC`7)*88Q(;btpOR#Me6S!?1vwj!D&%Z|BGqvjmr-$=i*R(;S~OpQ=`qP^dB7KK46>ew8%_?ZRbsw`hm@%e67OGcvyH-#ah%yj8aEfyryst8M<@_Sz%emMAVMbWuT&7dH|8 zxX6l+^GldVPV3TxtU`Mqi^eEi)V>E~s&0w$y8KH{B`afVO7~2TPSpz0hlYo_IQjQ< zMKBA^%UQ@Fr2Aqgi;(U?rE}~3n;V|5W9>BMjBVhnKP}`@@%iUBpMwS!>smIxwp9!~ zd_2*fmZ>x7 zU)}!pBj=yisOoASFOp;1qHw+MtnZ1vh0BFJrWl1asLgFY=;d+!@flyyhQ_P|GiPf( z*ie6B64N5*g0$_dHFNu}KYb!`Sm7Gev9$8ohCd035=WvM{xQB;#_-p1k@)5MNC~!$ zA`70s{9REaFj2#GKjSaWtu@R~emu)}aGExw$_pqhX7H`7G?c+kl@Vl)N$ftx9Vw@o zTJ*SPFdtT!##FFOU1iTfgA;ojsu{mColvy6EG#6qWWT26F#``z#;SGVDrMDyIm85VI|HGc$-|^DM#{`&y7(8A5T-G@yGywp7=n0Mh literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/fly_05.png b/DesktopRoachRampage/bin/images/fly_05.png new file mode 100644 index 0000000000000000000000000000000000000000..a43bce21103c9adea8f97e29ce8fde081e576600 GIT binary patch literal 634 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-3{3o zV$y>L4<0>`TeL&{<=U8?mprch&t9LNlfP*etAAJAmd8KqFTZ=|#9@7Y!Us0ae0)Ub z)!Bm1|Df1&u9jao!m(YSlQo_fDUcbVX7nN@C-aj+vS&RTr{f${9aXxG0=0 zI4yh41c`%_8n;Z4IB6^9nB;kGy}#pu_tTn=OxmHRz*~P>$U}#bZGS4KN>yQH^*o;D z#{2PdtG!N~&2DXJ>pyJAv9kX(SA{Q+4SU?=bHDe^JN*9qb^D#4O($e1^5*c`hdS}- zK73lN!|*&>A#rKRb!CYSY&*l6ynkG>jPlqrA)2c>v*Y@5);n+Y9scPRM)IUErk{%3 z(ab6oR>Ugvjo&rNp@idHj4R{(<;mBXQtpKvkmBn2zr;y&ec-vebP{bOc)b8ZR??e&lkmhcEZaAnWD2^S_*^UkdbJeUA9?kH8Fa#KG<5kc`eY)-QK|oH-ZXWiv4(1qAuvP9?U+(J*)Vc!b4u6dpL<7%x?rg VF@$zDRRGfqgQu&X%Q~loCIBGw1#$oY literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/fly_06.png b/DesktopRoachRampage/bin/images/fly_06.png new file mode 100644 index 0000000000000000000000000000000000000000..4a328f1337a43089d911e512c74ab66e8ef5a664 GIT binary patch literal 629 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-3`|^}E{-7;ac`$>^kX&@a9R12d6vl)6O+tK z0hcdaSmNjFJ9k$9f@j`8w3U@3H>K5-f2*qXGzquStUB>}uH}@|u^bQmB!#jj1T?ou zsa#Q5$i`{vvBJ@b7g?w?`f-g-3&*c0k2_p@4+^V9eTZ7b`rg_z;zQi3BP*;uz8EB( z6f`dOsCck-%kdsnkBTJSLq*59ItABAt`HSc-g!*PW6jBzPYqQ*k zJYL3WtLQxOPGFQc;k1%r&vmZOxD5?|-_=c%5Rf$rZD3ca^7O8g<6p;mq%xW@n$bMO z;ZM^i9fiGd>sK{g;-4U5*O)kA7SpH7O2(zXqZKbY|C{3WkG*2gKOvPh4}zt>N}YLs zP*!Kci-lW6+8ndE4$NFyy=KA(w!;e3m~0du^0ql{V*xT}Mbw92$6fBsz1{IPwh!bX*q+#4R|M>2J)9(b@_r}4<0ga_A`|DHX~ z;n3;t*WJ}?;?D0s@L1)8M8&x|6FxMt#>C03WZ;QndVbobL~z24L$?#}Yi?t>xn|Mv zqyti4?(D1FVfSvWm{6R`p19II%mz0^O7`*gyKZqf)V{Hj@J*_Rwz77)lSe}u%F>){ZWTtt_#mk zt>WJBJ~_IfHYs_-ET%U5Np-|wWv^t(%|RbJb{`@(}?pI^OW=-!+4$(qgS7?*&_ zo=vZqSgP3*B$jMzurFp;kYJk`bRbKv literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/walk_00.png b/DesktopRoachRampage/bin/images/walk_00.png new file mode 100644 index 0000000000000000000000000000000000000000..7853398b49a7e794c5f5d92493d28066da55ae48 GIT binary patch literal 570 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc4d*>w978JN-dA#mjA^`5&5_NH z$p#W8v)UgVJ=}T1GEwc$wv$U((~heDSa|bZbi(&3K~|QFAG9?|bLDC5ScroWU9-=2 z8PD%|ZtokN`Y+CYv9QXQOF6_`G;lu~E9+O^G~;t;G&D5xq6*zw4)N?|{t~yHwRPq- zzAfLLivSJXu>AY--60RYe{)Lozs9|y-M)xZmI_=gc)Hu^(ys;G@cwWx=yc@4DA{AQD1f@Yjb&hjaK5@md5yF+AXM&o4!;kL^;&j z>N&SI9r8EtWOm~|kiEFrJwRgXGtY+`yqnLvI4Vl*J8-aH!VXWk|76-QL%VuI-|soV P_-62Q^>bP0l+XkKD2?=y literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/walk_01.png b/DesktopRoachRampage/bin/images/walk_01.png new file mode 100644 index 0000000000000000000000000000000000000000..eb09998a2f4073b274f09337d8329b0aa0896202 GIT binary patch literal 578 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc4c9$g978JN-dS>bZ%G21f@If06#+D!d zD*PnB+4jaUx5_ORzv%pRmWbO5J*`D`yj)zby3eG|Fd-ytTF zcFXF*wfn&f9<&{rXBRIQ)M$U3yVW*Qe}UY;6RH6>nEC3S2x**YW8QCjSAG`@S62M` z{{3vHnAdmqoxhiVJ>7(~)3D<@0CGJ&i$5p4S|7sMXq4B`= zQG)KG&sqTzt>s+ouNv1cba7m`FL?Xw*sdpx8x?K#3$dEYu+8QE@t*s{e?E(V(@fLu z{aCczPn*l@tF#i|wp7L+ZM(Mg1d3F-l&eV9%e*crE?_kI0n*i4wgBF$Z=sWO1Bd>Eh`7)pCJY?Yj(D$CY&|j}oHA8v3s+P3>89 zL3x*Q_I&n5tXGad2D$W4=|qc!EetkhR_{5u7H_+wDN~mFVWx(L%VBYgAA*O|MeYO? hI3MI?HOFMwZJk}!S9u-=3VAa zY|&-UYBji2AH#BJ+P?eqmd&)=CfcIg8s}j5M|FC`23FZWle`@yeA)k1ROZATdY)*1 z_RGdFj=baFpWBPiWLpIW>}c96&8i?;Z-b zZ2dC#QewzyCO3xyiLaazj0b(&1HZH05if{mn03i`uE3p`{mgETFE)O0*7!etMf2Rv z41cFbRqvGp+Rl2tj(>{ShLUN*hoZdSM=fHWCbr>|j%rYRSOL_>paQ zUv9a}?c_`du*SKv;GM5)e${rU=jEnhh3 za!Y(X81D4qA=>9)5RuCHz(p%Q+M4JxZStu;KVH?BVZDsd$1->mftj9a=h4pFH wM18A@+#hFbYnlXjolH0`D!4RbFg~+xn4w+W9yiqzmIP3^{2V|qV$B|_YjWg9byl6xa+g9Usw9p z@SudZ+d<;tr0ER?lk^__eyb_^YkRfhjo=roR}RlF=H#fpaPa(2mX?bp5BjGc->k=Y z@a^-zKkqwKKCoQ-`mVsWA2zbVf!}L>DE(j8yv--p{(D8Xg2ff~IO9Efj_;qgY`A)* z-j_XkQE5Co(7F#tuhhm0-0?f!eq|E-m1SS%`Ele~_3YArASQOP7<<-*#B&&2|!E$F{kbxgPQL4bS|dr&d=iDmCzH$7N( zc*Q-|7sjVq5BjzT?&Usl=Wsg6+^9_rf&zC+Bue8C)H0fHXt?(LQ^$KoKMuaH(-%0g zzm7bxqJN*%p|GkKpMu+8M>^EjuKn5*&2=#G)rFaSH=-KiZtr?82K0X7bGGweW_T&0(Sra literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/walk_05.png b/DesktopRoachRampage/bin/images/walk_05.png new file mode 100644 index 0000000000000000000000000000000000000000..fb7bd93d3d8e24d204cf89b7df75989ec01bdb1e GIT binary patch literal 595 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc4KF-h978JN-d@}2ci2Fr_2IcajNamDV$<|= z&gkgqoH5%MwIvv&QWX@^aG+fN8Aa_nGJlxoSq%GhCM zAHP0$QLS!E_Qui=JPTW23+UdN-+AG1?F!4qcFc+0g6%Se=Y^V@Utj2})^RL&73*@| zbgzKhjp7Ai9Lj%>yDGeS`TK3=sV{r?D!kGB!gT7P{!W$_+ZPX}$1okru=;TP^kdiQ z4Hq7NE}3Ig`~J_rKg*XkPQS9Q+_~UHyWjfAU(xJqXYQ_JX<7T_g6-kgLSKxt{A09P z*loA)U0YNZ&(2~lyTW}}zg?srN8a+sheIZ_U0L>N@14Wy9C=nfS&;`gK=iIo)+_s_ zUQS-kyj3URNOHVWfkr)(v24y+Cb!y;Qw6qNa=zXcALS6&ROj}#GrRRcfLs)NkTXPHjD_TH+#PPFOporS`(8@4g*-BxyASK!-%!+N~)UQB-4 nv_V{Uk6Fz#IXgUY@soAK4DIU6JD(Z>69R*$tDnm{r-UW|mC^vX literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/walk_06.png b/DesktopRoachRampage/bin/images/walk_06.png new file mode 100644 index 0000000000000000000000000000000000000000..edb6e8e1df77d8ceb920ce53dde9102c5a7a1184 GIT binary patch literal 602 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc4evc&978JN-drHQyC(#Y^!qEQjXV#mg<5X}3+h#dc|&gXJI9=?xp$W&cd_c98g3XXR&H>+|wJ zzW;aeSf-}-_1BNzS3EVpmv>Lv%QYMv(KlPqZ#-UdLCV&9{&DW6_Tu*pvKw0Gi83lS z@m+I1Z)7{)GFxEJO9$m=o0abIa@_MfzI){{wkylt%vo`snI+$ z&%*z7X{o~2Z4AZlV)Qxgl}KFO#Za4G>G)yU;T6|dCEh>eZ8Dd21DeGIqVI|oL?5t^ zcR2E$!Jk8U+P)c6{_iT;FpX8`@9XHQeS#cvr?}7Czb??_j<7l{d??I&{j7_O+1wZI zubsP_wW)op_p1$C4_2R(ZQLL(Ta)`kgX5+`O7jF>Co@cj{e~IZ)$7vcSp(ApgQu&X J%Q~loCICwv^O^tv literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/bin/images/walk_07.png b/DesktopRoachRampage/bin/images/walk_07.png new file mode 100644 index 0000000000000000000000000000000000000000..db22eb8947edbe04b4242601cb93099be0c8c10c GIT binary patch literal 589 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc4Uars978JN-dr1`voNs*aU|-6m$7fg$o-E8fE~(04dxbCH_YPfw zswnFVxBfqG5a2yD&n{lB&8L35c#Cao+<}T8%F`P*u*?2Ap{np@8S{SIyYjnOTBP1@ ze?8&l`+afp^;=CoOuF>=u7J#^rI*j^{EcSUomo}G&$0H)CDX&Ng}zvNz2C7`K<3LO zs~ciVi)97wlq`^XDN~!iQ(?#5b>+^UQUSA1rSEL_2TDk6O=YxI*zwZf)qQ=1y}6|e zbh%%A+$Qh5!tnb>lYfVoHm{95a7TXM&gZKe9~kT_$o#RC^@*y_+}BMPyy8t|J#=*y zW?EfmJ(yVIDeJa2wqf4urU%OouK*gtc+j^!@Hx{t);Zh`!BxwIn`VEmcKG&uKS%20 z^Les4XPLfiuFsNOE08rMZsJmXm!+&d^6O6*I2O#*$ChtsWo2p(4FxTxULEWqnzg2}MoFhjfgnQZbxU=m>PboFyt=akR{0NxGv?*IS* literal 0 HcmV?d00001 diff --git a/DesktopRoachRampage/build.bat b/DesktopRoachRampage/build.bat new file mode 100644 index 0000000..005ff2f --- /dev/null +++ b/DesktopRoachRampage/build.bat @@ -0,0 +1,24 @@ +@echo off +REM Build script for Desktop Roach Rampage +REM Compiles the C# source code into a Windows executable + +echo Building Desktop Roach Rampage... +cd /d "%~dp0app" + +REM Use .NET Framework compiler +C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /target:winexe /r:System.dll /r:System.Drawing.dll /r:System.Windows.Forms.dll /out:DesktopRoachRampage.exe Program.cs + +if %ERRORLEVEL% NEQ 0 ( + echo Build failed! + pause + exit /b 1 +) + +echo Copying executable to bin directory... +if not exist "..\bin" mkdir "..\bin" +copy /Y "DesktopRoachRampage.exe" "..\bin\" > nul + +echo. +echo Build completed successfully! +echo Executable: DesktopRoachRampage\bin\DesktopRoachRampage.exe +pause diff --git a/DesktopRoachRampage/run.bat b/DesktopRoachRampage/run.bat new file mode 100644 index 0000000..7d7626f --- /dev/null +++ b/DesktopRoachRampage/run.bat @@ -0,0 +1,12 @@ +@echo off +REM Run Desktop Roach Rampage + +cd /d "%~dp0bin" +if not exist "DesktopRoachRampage.exe" ( + echo Executable not found! Please run build.bat first. + pause + exit /b 1 +) + +echo Starting Desktop Roach Rampage... +start "" DesktopRoachRampage.exe diff --git a/tools/GenerateCockroaches.cs b/tools/GenerateCockroaches.cs new file mode 100644 index 0000000..d80004d --- /dev/null +++ b/tools/GenerateCockroaches.cs @@ -0,0 +1,283 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; + +class GenerateCockroaches +{ + static string saveDir = @"e:\Temp\desktop-pets\DesktopRoachRampage\images"; + + static void DrawPixel(Bitmap bmp, int x, int y, Color color) + { + if (x >= 0 && x < bmp.Width && y >= 0 && y < bmp.Height) + bmp.SetPixel(x, y, color); + } + + static void DrawThickLeg(Bitmap bmp, int x1, int y1, int x2, int y2, int x3, int y3, Color color, Color colorDark) + { + // 第一段 - 3像素宽 + DrawPixel(bmp, x1, y1, color); + DrawPixel(bmp, x1 - 1, y1, color); + DrawPixel(bmp, x1 + 1, y1, color); + DrawPixel(bmp, x1, y1 - 1, color); + DrawPixel(bmp, x1, y1 + 1, color); + + // 第二段 - 3像素宽 + DrawPixel(bmp, x2, y2, color); + DrawPixel(bmp, x2 - 1, y2, color); + DrawPixel(bmp, x2 + 1, y2, color); + DrawPixel(bmp, x2, y2 - 1, color); + DrawPixel(bmp, x2, y2 + 1, color); + + // 第三段末端(深色)- 略窄 + DrawPixel(bmp, x3, y3, colorDark); + DrawPixel(bmp, x3 - 1, y3, colorDark); + DrawPixel(bmp, x3 + 1, y3, colorDark); + } + + static void DrawCockroachBody(Bitmap bmp, int centerX, int centerY, int frame, int totalFrames, bool isFlying, bool isScared = false, bool isCrawling = false) + { + // 蟑螂颜色 + var colorHead = Color.FromArgb(100, 65, 35); + var colorBody = Color.FromArgb(80, 50, 25); + var colorBodyDark = Color.FromArgb(55, 30, 10); + var colorLeg = Color.FromArgb(110, 75, 45); + var colorLegDark = Color.FromArgb(85, 55, 30); + var colorAnt = Color.FromArgb(130, 90, 60); + var colorWing = Color.FromArgb(160, 130, 100); + var colorWingLight = Color.FromArgb(200, 170, 140); + var colorWingVein = Color.FromArgb(120, 90, 60); + + int cy = centerY; + + // 受惊吓时身体略抬高 + int bodyOffsetY = isScared ? -3 : (isCrawling ? 2 : 0); + + // ========================================== + // 身体主体 + // ========================================== + + // 头部 + DrawPixel(bmp, centerX - 1, cy - 14 + bodyOffsetY, colorHead); + DrawPixel(bmp, centerX, cy - 14 + bodyOffsetY, colorHead); + DrawPixel(bmp, centerX + 1, cy - 14 + bodyOffsetY, colorHead); + + // 头部区域 + for (int y = -13; y <= -10; y++) { + int width = (y + 13) * 2 + 3; + for (int x = -width / 2; x <= width / 2; x++) { + DrawPixel(bmp, centerX + x, cy + y + bodyOffsetY, colorHead); + } + } + + // 前胸区域 + for (int y = -9; y <= -5; y++) { + int width = 9 + (y + 9) * 2; + for (int x = -width / 2; x <= width / 2; x++) { + DrawPixel(bmp, centerX + x, cy + y + bodyOffsetY, colorBody); + } + } + + // 腹部主体 + for (int y = -4; y <= 8; y++) { + for (int x = -8; x <= 8; x++) { + DrawPixel(bmp, centerX + x, cy + y + bodyOffsetY, colorBodyDark); + } + } + + // 腹部后段 + for (int y = 9; y <= 12; y++) { + int width = 17 - (y - 9) * 2; + for (int x = -width / 2; x <= width / 2; x++) { + DrawPixel(bmp, centerX + x, cy + y + bodyOffsetY, colorBodyDark); + } + } + + // 尾部末端 + for (int x = -3; x <= 3; x++) + DrawPixel(bmp, centerX + x, cy + 13 + bodyOffsetY, colorBodyDark); + for (int x = -2; x <= 2; x++) + DrawPixel(bmp, centerX + x, cy + 14 + bodyOffsetY, colorBodyDark); + + // 身体中线纹理 + for (int y = -10; y <= 12; y++) { + DrawPixel(bmp, centerX, cy + y + bodyOffsetY, colorBody); + } + + // ========================================== + // 翅膀 + // ========================================== + if (isFlying) + { + double wingPhase = (double)frame / totalFrames * Math.PI * 2; + int wingSpread = (int)(Math.Sin(wingPhase) * 4) + 8; + int wingAngle = (int)(Math.Sin(wingPhase * 2) * 2); + + // 左翅膀 + for (int i = 1; i <= wingSpread; i++) { + for (int j = -3; j <= 7; j++) { + int yOffset = j + wingAngle; + if (i > wingSpread - 2) { + DrawPixel(bmp, centerX - 8 - i, cy + yOffset - 4 + bodyOffsetY, colorWingLight); + } else { + DrawPixel(bmp, centerX - 8 - i, cy + yOffset - 4 + bodyOffsetY, colorWing); + } + } + } + + // 右翅膀 + for (int i = 1; i <= wingSpread; i++) { + for (int j = -3; j <= 7; j++) { + int yOffset = j - wingAngle; + if (i > wingSpread - 2) { + DrawPixel(bmp, centerX + 8 + i, cy + yOffset - 4 + bodyOffsetY, colorWingLight); + } else { + DrawPixel(bmp, centerX + 8 + i, cy + yOffset - 4 + bodyOffsetY, colorWing); + } + } + } + + // 翅膀纹理 + for (int i = 2; i <= wingSpread - 2; i += 3) { + for (int j = 0; j <= 4; j++) { + DrawPixel(bmp, centerX - 8 - i, cy + j - 3 + bodyOffsetY, colorWingVein); + DrawPixel(bmp, centerX + 8 + i, cy + j - 3 + bodyOffsetY, colorWingVein); + } + } + } + + // ========================================== + // 6条腿 - 非常粗壮 + // ========================================== + int[] legPosY = { cy - 8 + bodyOffsetY, cy + bodyOffsetY, cy + 10 + bodyOffsetY }; + + double phase = (double)frame / totalFrames * Math.PI * 2; + + if (isFlying) + { + // 飞行时腿悬空摆动 + for (int i = 0; i < 3; i++) { + double legPhase = phase + i * 0.8; + int swingX = (int)(Math.Sin(legPhase) * 4); + int swingY = (int)(Math.Cos(legPhase) * 2); + + // 左腿 + DrawThickLeg(bmp, + centerX - 8 + swingX, legPosY[i] + swingY, + centerX - 11 + swingX, legPosY[i] + 2 + swingY, + centerX - 14 + swingX, legPosY[i] + swingY, + colorLeg, colorLegDark); + + // 右腿 + DrawThickLeg(bmp, + centerX + 8 - swingX, legPosY[i] + swingY, + centerX + 11 - swingX, legPosY[i] + 2 + swingY, + centerX + 14 - swingX, legPosY[i] + swingY, + colorLeg, colorLegDark); + } + } + else + { + // 走路、爬行、受惊吓时的腿 + for (int i = 0; i < 3; i++) { + double legPhase = phase + i * 0.8; + int swing = (int)(Math.Sin(legPhase) * 2); + + // 爬行时腿的位置更低 + int crawlOffset = isCrawling ? 2 : 0; + int scaredOffset = isScared ? -1 : 0; + + // 左腿 + DrawThickLeg(bmp, + centerX - 8, legPosY[i] + crawlOffset + scaredOffset, + centerX - 11, legPosY[i] + 2 + swing + crawlOffset + scaredOffset, + centerX - 14, legPosY[i] + swing + crawlOffset + scaredOffset, + colorLeg, colorLegDark); + + // 右腿 + DrawThickLeg(bmp, + centerX + 8, legPosY[i] + crawlOffset + scaredOffset, + centerX + 11, legPosY[i] + 2 - swing + crawlOffset + scaredOffset, + centerX + 14, legPosY[i] - swing + crawlOffset + scaredOffset, + colorLeg, colorLegDark); + } + } + + // ========================================== + // 触角 + // ========================================== + double antPhase = phase * 0.5; + int antSwingL = (int)(Math.Sin(antPhase) * 2); + int antSwingR = (int)(Math.Sin(antPhase + Math.PI) * 2); + + // 受惊吓时触角竖起 + int antHeight = isScared ? -2 : 0; + + // 左触角 - 加粗 + for (int i = 1; i <= 7; i++) { + DrawPixel(bmp, centerX - 3 - i * 2, cy - 15 - i + antSwingL + bodyOffsetY + antHeight, colorAnt); + if (i > 2) { + DrawPixel(bmp, centerX - 3 - i * 2 + 1, cy - 15 - i + antSwingL + bodyOffsetY + antHeight, colorAnt); + } + } + + // 右触角 - 加粗 + for (int i = 1; i <= 7; i++) { + DrawPixel(bmp, centerX + 3 + i * 2, cy - 15 - i + antSwingR + bodyOffsetY + antHeight, colorAnt); + if (i > 2) { + DrawPixel(bmp, centerX + 3 + i * 2 - 1, cy - 15 - i + antSwingR + bodyOffsetY + antHeight, colorAnt); + } + } + } + + static void CreateCockroachImage(string filename, int frame, int totalFrames, bool isFlying, bool isScared = false, bool isCrawling = false) + { + int size = 64; + using (var bmp = new Bitmap(size, size, PixelFormat.Format32bppArgb)) + { + // 清空为透明 + for (int y = 0; y < size; y++) + for (int x = 0; x < size; x++) + bmp.SetPixel(x, y, Color.Transparent); + + int centerX = size / 2; + int centerY = size / 2 + 5; + + DrawCockroachBody(bmp, centerX, centerY, frame, totalFrames, isFlying, isScared, isCrawling); + + bmp.Save(Path.Combine(saveDir, filename), ImageFormat.Png); + } + Console.WriteLine("Saved: " + filename); + } + + static void Main() + { + if (!Directory.Exists(saveDir)) + Directory.CreateDirectory(saveDir); + + Console.WriteLine("正在生成像素风格蟑螂动画帧..."); + + // 生成8个行走动画帧 + int walkFrames = 8; + for (int i = 0; i < walkFrames; i++) { + CreateCockroachImage(string.Format("walk_{0:D2}.png", i), i, walkFrames, false); + } + + // 生成8个飞行动画帧 + int flyFrames = 8; + for (int i = 0; i < flyFrames; i++) { + CreateCockroachImage(string.Format("fly_{0:D2}.png", i), i, flyFrames, true); + } + + // 空闲帧 + CreateCockroachImage("cockroach_idle.png", 0, walkFrames, false); + + // 单独的动作帧 - 腿部加粗版本 + CreateCockroachImage("cockroach_walk1.png", 0, 4, false); + CreateCockroachImage("cockroach_walk2.png", 2, 4, false); + CreateCockroachImage("cockroach_crawl.png", 1, 4, false, false, true); // 爬行状态 + CreateCockroachImage("cockroach_scared.png", 0, 4, false, true, false); // 受惊吓状态 + + Console.WriteLine("所有图片生成完成!"); + } +} diff --git a/tools/GenerateCockroaches.exe b/tools/GenerateCockroaches.exe new file mode 100644 index 0000000000000000000000000000000000000000..4c97ddbbaa0679f266f255c047423ff4a96271d3 GIT binary patch literal 7680 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