You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# WinForm中点击按钮添加多个移动的熊猫图片

实现多只移动熊猫的解决方案

嘿,我来帮你搞定这个问题!你当前的代码只用了单个变量来存储熊猫的图像和位置,每次点击按钮都会覆盖掉之前的实例,所以永远只能看到一只熊猫。要实现点击多次生成多只同时移动的熊猫,我们需要用一个集合来管理所有的熊猫实例,然后分别处理每只熊猫的移动和绘制。

步骤1:优化熊猫类,封装移动逻辑

首先,我们可以把移动逻辑封装到panda类内部,让每只熊猫自己负责更新位置,这样代码更模块化,也方便后续扩展:

using System.Drawing;

namespace test_moving_pic
{
    class panda
    {
        public Image img_panda;
        public Rectangle rect_panda;
        private readonly int _moveSpeed = 3; // 移动速度,用只读字段避免被外部修改

        public panda(Image img, Rectangle rect)
        {
            img_panda = img;
            rect_panda = rect;
        }

        // 让熊猫自己处理移动逻辑
        public void UpdatePosition()
        {
            rect_panda.X += _moveSpeed;
            rect_panda.Y += _moveSpeed;

            if (rect_panda.X <= 100 && rect_panda.Y <= 100)
            {
                rect_panda.X += _moveSpeed;
                rect_panda.Y += _moveSpeed;
            }
            else
            {
                rect_panda.Y += _moveSpeed;
                if (rect_panda.Y >= 100)
                {
                    rect_panda.Y = 100;
                    rect_panda.X += _moveSpeed;
                }
            }
        }
    }
}

步骤2:修改Form代码,用集合管理所有熊猫

接下来修改Form1的代码,用List<panda>来存储所有生成的熊猫实例,然后在Timer和Paint事件里遍历集合处理每只熊猫:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace test_moving_pic
{
    public partial class Form1 : Form
    {
        // 用List集合保存所有熊猫实例
        private readonly List<panda> _pandas = new List<panda>();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            // 遍历集合,绘制每一只熊猫
            foreach (var panda in _pandas)
            {
                g.DrawImage(panda.img_panda, panda.rect_panda);
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // 遍历集合,更新每一只熊猫的位置
            foreach (var panda in _pandas)
            {
                panda.UpdatePosition();
            }
            Invalidate(); // 刷新界面,触发Paint事件重新绘制
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 创建新熊猫并添加到集合中,不会覆盖之前的实例
            var newPanda = new panda(
                Image.FromFile("C:\\Users\\hsnha\\OneDrive\\Desktop\\Panda.png"),
                new Rectangle(20, 20, 70, 70)
            );
            _pandas.Add(newPanda);
        }

        // 可选:程序关闭时释放图片资源,避免内存泄漏
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            foreach (var panda in _pandas)
            {
                panda.img_panda.Dispose();
            }
        }
    }
}

关键修改点说明

  • 用集合替代单个变量:原来的image和rect变量每次点击都会被覆盖,现在用List<panda>存储所有实例,每次点击只新增元素,不会丢失之前的熊猫。
  • 封装移动逻辑:把移动代码放到panda类的UpdatePosition方法里,让每个熊猫独立管理自己的位置,代码更清晰,也方便后续给不同熊猫设置不同的移动规则。
  • 遍历处理所有熊猫:在Timer事件里更新每只熊猫的位置,在Paint事件里绘制每只熊猫,这样所有熊猫都会同时移动并显示在界面上。

额外提醒

  • 用Image.FromFile会锁定图片文件,如果后续需要修改或替换图片会出现问题,建议改用Image.FromStream加载图片,示例如下(需要先把图片读取到内存流):
    using (var stream = new System.IO.FileStream("C:\\Users\\hsnha\\OneDrive\\Desktop\\Panda.png", System.IO.FileMode.Open))
    {
        var newPanda = new panda(Image.FromStream(stream), new Rectangle(20, 20, 70, 70));
        _pandas.Add(newPanda);
    }
    
  • 记得在Form关闭时调用Dispose释放所有图片资源,避免内存泄漏,上面的代码已经添加了FormClosing事件处理。

内容的提问来源于stack exchange,提问作者Hassan HAJJAR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:39:25