1
0
Files
2026-07-22 20:34:10 +08:00

284 lines
11 KiB
C#

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("所有图片生成完成!");
}
}