如何在.NET Framework WinForms C#中绘制可取值的动态RPG功率条
.NET Framework WinForms C# 实现RPG风格功率条
一、自定义功率条控件
创建继承自Control的自定义控件,负责绘制三色区域、动态箭头,并处理点击逻辑。
1. 控件核心代码
using System; using System.Drawing; using System.Windows.Forms; public class PowerBarControl : Control { private int _arrowY; private Timer _moveTimer; private bool _movingUp = true; // 定义功率选中事件,供外部订阅 public event EventHandler<int> PowerSelected; public PowerBarControl() { // 设置控件默认尺寸 Size = new Size(80, 300); DoubleBuffered = true; // 防止绘制闪烁 // 初始化箭头移动定时器 _moveTimer = new Timer { Interval = 20 }; _moveTimer.Tick += MoveTimer_Tick; _moveTimer.Start(); } private void MoveTimer_Tick(object sender, EventArgs e) { // 更新箭头Y坐标,到达边界切换方向 if (_movingUp) { _arrowY -= 2; if (_arrowY <= 0) _movingUp = false; } else { _arrowY += 2; if (_arrowY >= Height - 20) _movingUp = true; // 20为箭头高度,避免超出控件范围 } Invalidate(); // 触发控件重绘 } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // 计算三个区域的高度 int sectionHeight = Height / 3; // 绘制红色区域(底部,低功率) using (Brush redBrush = new SolidBrush(Color.FromArgb(220, 255, 80, 80))) { g.FillRectangle(redBrush, 0, 2 * sectionHeight, Width, sectionHeight); } // 绘制黄色区域(中间) using (Brush yellowBrush = new SolidBrush(Color.FromArgb(220, 255, 255, 80))) { g.FillRectangle(yellowBrush, 0, sectionHeight, Width, sectionHeight); } // 绘制绿色区域(顶部,高功率) using (Brush greenBrush = new SolidBrush(Color.FromArgb(220, 80, 255, 80))) { g.FillRectangle(greenBrush, 0, 0, Width, sectionHeight); } // 绘制控件边框 using (Pen borderPen = new Pen(Color.Black, 2)) { g.DrawRectangle(borderPen, 0, 0, Width - 1, Height - 1); } // 绘制右侧箭头(三角形) Point[] arrowPoints = new[] { new Point(Width - 15, _arrowY), new Point(Width - 5, _arrowY + 10), new Point(Width - 15, _arrowY + 20) }; using (Brush arrowBrush = new SolidBrush(Color.Black)) { g.FillPolygon(arrowBrush, arrowPoints); } } protected override void OnMouseClick(MouseEventArgs e) { base.OnMouseClick(e); // 计算当前功率值:顶部(Y=0)对应100,底部(Y=Height)对应0 int powerValue = 100 - (int)((float)_arrowY / Height * 100); // 触发事件传递功率值 PowerSelected?.Invoke(this, powerValue); // 可选:点击后停止箭头移动,取消下方注释即可 // _moveTimer.Stop(); } // 控件销毁时释放定时器资源 protected override void Dispose(bool disposing) { if (disposing) { _moveTimer?.Dispose(); } base.Dispose(disposing); } }
二、主窗体集成与赛车逻辑关联
在WinForms窗体中添加自定义控件,订阅功率选中事件,根据功率值计算赛车行驶距离。
1. 窗体代码示例
public partial class MainForm : Form { private int _carDistance = 0; public MainForm() { InitializeComponent(); // 添加自定义功率条控件到窗体 var powerBar = new PowerBarControl(); powerBar.Location = new Point(50, 50); powerBar.PowerSelected += PowerBar_PowerSelected; Controls.Add(powerBar); // 添加显示行驶距离的Label var distanceLabel = new Label { Name = "distanceLabel", Location = new Point(200, 150), Size = new Size(200, 30), Font = new Font("Arial", 12) }; Controls.Add(distanceLabel); } private void PowerBar_PowerSelected(object sender, int powerValue) { // 计算行驶距离:功率值 × 自定义系数(可根据需求调整) _carDistance += powerValue * 2; // 更新距离显示 ((Label)Controls.Find("distanceLabel", true)[0]).Text = $"当前行驶距离:{_carDistance} 米"; } }
三、关键说明
- 区域划分:控件高度默认三等分,顶部绿色对应最高功率(100),底部红色对应最低功率(0),可修改
sectionHeight的计算逻辑调整区域比例。 - 箭头移动:通过定时器控制箭头移动速度,修改
Interval(定时器间隔)和步长(2)可调整移动快慢。 - 功率计算:基于箭头Y坐标线性映射到0-100区间,若需要绿色区域权重更高,可改为非线性映射(比如对绿色区域的Y坐标做平方运算)。
- 性能优化:开启
DoubleBuffered避免绘制闪烁,提升视觉流畅度。
内容的提问来源于stack exchange,提问作者Filipe Cruz
相关产品推荐
相关产品推荐

