3 回答

TA貢獻1772條經驗 獲得超5個贊
? ? private List<Panel> _panels = new List<Panel>(); //class level list to track the panels
? ? private void button2_Click(object sender, EventArgs e)
? ? {
? ? ? ? //create a new panel when the button is clicked
? ? ? ? var p = new Panel();
? ? ? ? p.Size = new Size(10, 10);
? ? ? ? p.Location = new Point(10, DateTime.Now.Second * (this.Height / 60)); //"random" Y so they don't pile up
? ? ? ? p.BackColor = Color.Green;
? ? ? ? this.Controls.Add(p);? ? ? ? ? ? ? ? ? ? ? ? ? ?//add panel to form
? ? ? ? _panels.Add(p);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//add panel to list
? ? ? ? timer1.Enabled = true;? ? ? ? ? ? ? ? ? ? ? ? ? //animate
? ? }
? ? private void timer1_Tick(object sender, EventArgs e)
? ? {
? ? ? ? for (int i = _panels.Count - 1; i >= 0; i--)? ? //use a backwards int indexed loop because we are potentially removing items from the list.?
? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//Working backwards is the easiest way to not have to fiddle the index upon removal
? ? ? ? ? ? var p = _panels[i];? ? ? ? ? ? ? ? ? ? ? ? ?//temp reference to a panel in the list, not related to 'var p' in the button click
? ? ? ? ? ? p.Left += 25;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//move it
? ? ? ? ? ? if (p.Left > this.Width)? ? ? ? ? ? ? ? ? ? //panel that is off screen?
? ? ? ? ? ? ? ? _panels.RemoveAt(i);? ? ? ? ? ? ? ? ? ? //stop moving it then
? ? ? ? }
? ? ? ? if (_panels.Count == 0)? ? ? ? ? ? ? ? ? ? ? ? ?//no more panels to move?
? ? ? ? ? ? timer1.Stop();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //stop the timer
? ? }
this.Controls如果您不再使用不可見的面板,您應該考慮實現一些邏輯,將其從集合中刪除。

TA貢獻1786條經驗 獲得超11個贊
這是我寫的一個簡單的例子,這里我使用 1 個計時器來處理所有面板,如果你想讓它更平滑,使運動增量更?。◤?25 到更低)并增加計時器的滴答率,你也可以嘗試單獨為每個面板使用一個計時器,但在我看來這有點過分了。
編輯:如果您想要真正精確的定位和動畫,則需要使用更精確的雙精度移動,并舍入為動畫本身的整數,請使用 DateTime.Now 來非常精確地確定給定時間內行駛的距離,計時器不會t 確定距離,它只更新位置:
public partial class MainForm : Form
{
// X directional speed in pixels per second
const int XSpeed = 400;
private List<AnimationPanel> _panels = new List<AnimationPanel>();
public MainForm()
{
InitializeComponent();
}
private void OnButtonStartClick(object sender, System.EventArgs e)
{
AnimationPanel newPanel = new AnimationPanel
{
Bounds = new Rectangle(10, 10, 50, 50),
BorderStyle = BorderStyle.FixedSingle,
};
_panels.Add(newPanel);
Controls.Add(newPanel);
newPanel.StartBounds = newPanel.Bounds;
newPanel.StartTime = DateTime.Now;
_timer.Enabled = true;
}
private void OnTimerTick(object sender, System.EventArgs e)
{
for (int i = _panels.Count - 1; i >= 0; i--)
{
AnimationPanel currentPanel = _panels[i];
DateTime startTime = currentPanel.StartTime;
int xDelta = (int)Math.Round((DateTime.Now - startTime).TotalSeconds * XSpeed, 0);
Point newLocation = new Point(currentPanel.StartBounds.X + xDelta, currentPanel.StartBounds.Y);
// Check before or after collision (in this example before replacing the AnimationPanel)
if (newLocation.X > this.Width)
{
// I chose to remove after it reaches the edge, do whatever you want
_panels.RemoveAt(i);
Controls.Remove(currentPanel);
}
else
{
currentPanel.Location = newLocation;
}
}
if (_panels.Count == 0)
{
_timer.Enabled = false;
}
}
private class AnimationPanel : Panel
{
public Rectangle StartBounds { get; set; }
public DateTime StartTime { get; set; }
}
}

TA貢獻1820條經驗 獲得超9個贊
您可以使用如下代碼創建面板:
// init properties
var newPanel = new Panel
{
Name="Panel1",
BackColor = Color.Green,
Location = new Point(0, 0), // set the starting point
Width = 100, Height = 100
};
Controls.Add(newPanel);
- 3 回答
- 0 關注
- 154 瀏覽
添加回答
舉報