forms实现贪吃蛇
说明:
forms实现贪吃蛇
效果图:
step1:C:\Users\wangrusheng\RiderProjects\WinFormsApp2\WinFormsApp2\Form1.cs
namespace WinFormsApp2
{
public partial class Form1 : Form
{
// 游戏配置常量
private const int GridSize = 20;
private const int CanvasSize = 400;
// 游戏核心组件
private readonly System.Windows.Forms.Timer gameTimer = new System.Windows.Forms.Timer();
private List<Point> snake = new List<Point>();
private Point food;
private Direction currentDirection = Direction.Right;
private int score = 0;
private bool isPaused = false;
// UI控件
private PictureBox canvas;
private Label lblScore;
private Button btnPause;
private Button btnReset;
private enum Direction { Up, Down, Left, Right }
// 新增方向按钮控件
private Button btnUp;
private Button btnDown;
private Button btnLeft;
private Button btnRight;
public Form1()
{
InitializeComponent();
CreateGameUI();
InitializeGame();
SetupTimer();
this.KeyPreview = true;
this.ClientSize = new Size(600, 500); // 扩大窗体尺寸
}
private void CreateGameUI()
{
// 创建画布
canvas = new PictureBox
{
BackColor = Color.FromArgb(26, 27, 38),
Size = new Size(CanvasSize, CanvasSize),
Location = new Point(20, 50)
};
canvas.Paint += Canvas_Paint;
// 分数显示
lblScore = new Label
{
Text = $"Score: {score}",
AutoSize = true,
ForeColor = Color.White,
Font = new Font("Microsoft Sans Serif", 12),
Location = new Point(20, 15)
};
// 暂停按钮
btnPause = new Button
{
Text = "暂停",
Size = new Size(75, 30),
Location = new Point(300, 12)
};
btnPause.Click += BtnPause_Click;
// 重置按钮
btnReset = new Button
{
Text = "重置",
Size = new Size(75, 30),
Location = new Point(380, 12)
};
btnReset.Click += BtnReset_Click;
// 新增方向按钮
int buttonSize = 50;
int startX = CanvasSize + 40; // 画布右侧
int startY = 150;
btnUp = new Button
{
Text = "↑",
Size = new Size(buttonSize, buttonSize),
Location = new Point(startX + buttonSize, startY),
Font = new Font("Arial", 16),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(60, 60, 80)
};
btnUp.Click += BtnUp_Click;
btnUp.FlatAppearance.BorderSize = 0;
btnDown = new Button
{
Text = "↓",
Size = new Size(buttonSize, buttonSize),
Location = new Point(startX + buttonSize, startY + buttonSize + 10),
Font = new Font("Arial", 16),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(60, 60, 80)
};
btnDown.Click += BtnDown_Click;
btnDown.FlatAppearance.BorderSize = 0;
btnLeft = new Button
{
Text = "←",
Size = new Size(buttonSize, buttonSize),
Location = new Point(startX, startY + buttonSize),
Font = new Font("Arial", 16),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(60, 60, 80)
};
btnLeft.Click += BtnLeft_Click;
btnLeft.FlatAppearance.BorderSize = 0;
btnRight = new Button
{
Text = "→",
Size = new Size(buttonSize, buttonSize),
Location = new Point(startX + buttonSize * 2, startY + buttonSize),
Font = new Font("Arial", 16),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(60, 60, 80)
};
btnRight.Click += BtnRight_Click;
btnRight.FlatAppearance.BorderSize = 0;
// 添加新控件到窗体
Controls.AddRange(new Control[] { btnUp, btnDown, btnLeft, btnRight });
// 添加控件到窗体
Controls.AddRange(new Control[] { canvas, lblScore, btnPause, btnReset });
}
// 新增方向按钮事件处理
private void BtnUp_Click(object sender, EventArgs e)
{
if (currentDirection != Direction.Down)
currentDirection = Direction.Up;
}
private void BtnDown_Click(object sender, EventArgs e)
{
if (currentDirection != Direction.Up)
currentDirection = Direction.Down;
}
private void BtnLeft_Click(object sender, EventArgs e)
{
if (currentDirection != Direction.Right)
currentDirection = Direction.Left;
}
private void BtnRight_Click(object sender, EventArgs e)
{
if (currentDirection != Direction.Left)
currentDirection = Direction.Right;
}
private void InitializeGame()
{
snake.Clear();
snake.Add(new Point(10, 10));
GenerateFood();
score = 0;
lblScore.Text = $"Score: {score}";
currentDirection = Direction.Right;
}
private void SetupTimer()
{
gameTimer.Interval = 200; //控制蛇的速度 speed
gameTimer.Tick += GameLoop;
gameTimer.Start();
}
// 以下是游戏逻辑方法(保持原有实现)
private void GenerateFood()
{
var random = new Random();
do
{
food = new Point(
random.Next(0, CanvasSize / GridSize),
random.Next(0, CanvasSize / GridSize)
);
} while (snake.Contains(food));
}
private void GameLoop(object sender, EventArgs e)
{
if (isPaused) return;
var head = snake[0];
var newHead = new Point(head.X, head.Y);
switch (currentDirection)
{
case Direction.Up: newHead.Y--; break;
case Direction.Down: newHead.Y++; break;
case Direction.Left: newHead.X--; break;
case Direction.Right: newHead.X++; break;
}
if (CheckCollision(newHead))
{
gameTimer.Stop();
MessageBox.Show($"Game Over! Score: {score}");
InitializeGame();
gameTimer.Start();
return;
}
snake.Insert(0, newHead);
if (newHead == food)
{
score++;
lblScore.Text = $"Score: {score}";
gameTimer.Interval = Math.Max(50, gameTimer.Interval - 2);
GenerateFood();
}
else
{
snake.RemoveAt(snake.Count - 1);
}
canvas.Invalidate();
}
private bool CheckCollision(Point position)
{
if (position.X < 0 || position.X >= CanvasSize / GridSize ||
position.Y < 0 || position.Y >= CanvasSize / GridSize)
return true;
for (int i = 1; i < snake.Count; i++)
{
if (snake[i] == position)
return true;
}
return false;
}
// 渲染和输入处理
private void Canvas_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
g.Clear(Color.FromArgb(0x1a, 0x1b, 0x26));
// 绘制食物
using (var brush = new SolidBrush(Color.FromArgb(0xf7, 0x76, 0x8e)))
{
DrawRoundedRectangle(g, brush, food.X * GridSize + 2, food.Y * GridSize + 2, 16, 16, 4);
}
// 绘制蛇
for (int i = 0; i < snake.Count; i++)
{
var color = i == 0 ?
Color.FromArgb(0x9e, 0xce, 0x6a) :
Color.FromArgb(0x73, 0xda, 0xca);
using (var brush = new SolidBrush(color))
{
int radius = i == 0 ? 6 : 4;
DrawRoundedRectangle(g, brush,
snake[i].X * GridSize + 2,
snake[i].Y * GridSize + 2,
16, 16, radius);
}
}
}
private void DrawRoundedRectangle(Graphics g, Brush brush, int x, int y, int width, int height, int radius)
{
using (var path = new System.Drawing.Drawing2D.GraphicsPath())
{
path.AddArc(x, y, radius, radius, 180, 90);
path.AddArc(x + width - radius, y, radius, radius, 270, 90);
path.AddArc(x + width - radius, y + height - radius, radius, radius, 0, 90);
path.AddArc(x, y + height - radius, radius, radius, 90, 90);
path.CloseFigure();
g.FillPath(brush, path);
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
switch (e.KeyCode)
{
case Keys.Up when currentDirection != Direction.Down:
currentDirection = Direction.Up;
break;
case Keys.Down when currentDirection != Direction.Up:
currentDirection = Direction.Down;
break;
case Keys.Left when currentDirection != Direction.Right:
currentDirection = Direction.Left;
break;
case Keys.Right when currentDirection != Direction.Left:
currentDirection = Direction.Right;
break;
case Keys.Space:
TogglePause();
break;
}
}
// 事件处理方法
private void BtnPause_Click(object sender, EventArgs e) => TogglePause();
private void BtnReset_Click(object sender, EventArgs e)
{
InitializeGame();
gameTimer.Interval = 150;
isPaused = false;
btnPause.Text = "暂停";
canvas.Invalidate();
}
private void TogglePause()
{
isPaused = !isPaused;
btnPause.Text = isPaused ? "继续" : "暂停";
}
}
}
end