连续移动控件时,怎么才不闪烁

pig357 2013-07-27 11:03:23
环境:VS2008 winform C# win7
问题:我用一张大图片作为背景,再添加了个自定义控件Players0,目的时当右键背景时,控件就从当前位置orgPt以speed0的速度移动到目标地点destPt,现在就是不管定时器设置为多少间隔,都会很闪烁。

private void timerPlay_Tick(object sender, EventArgs e)
{
if (Players0.Location != destPt)
{
orgPt = Players0.Location;
turn[0] = Players0.Left - destPt.X;
turn[1] = Players0.Top - destPt.Y;
double s = Math.Sqrt((orgPt.X - destPt.X) * (orgPt.X - destPt.X) + (orgPt.Y - destPt.Y) * (orgPt.Y - destPt.Y));
Players0.Left += (int)(Speed0 * (destPt.X - orgPt.X) / s);
Players0.Top += (int)(Speed0 * (destPt.Y - orgPt.Y) / s);
int xx = Players0.Left - destPt.X;
int yy = Players0.Top - destPt.Y;
if(xx * turn[0] <= 0) //是否改变了方向,防止左右晃动
Players0.Left = destPt.X;
if (yy * turn[1] <= 0)
Players0.Top = destPt.Y;
}
else
{
timerPlay.Enabled = false;
}
}


不知道这么算坐标是否有问题?为什么timer的间隔任意设置都感觉很闪烁?
...全文
192 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Regan-lin 2013-07-27
  • 打赏
  • 举报
回复
speed0你设了多少?
江湖评谈 2013-07-27
  • 打赏
  • 举报
回复
双缓冲技术 ,可以解决
智商余额不足 2013-07-27
  • 打赏
  • 举报
回复
来个模拟的

public partial class Form1 : Form
{
    //目标坐标X
    private int targetX=-1;
    //目标坐标Y
    private int targetY=-1;
    //计时器,实现游戏循环
    private Timer loop;
    //角色
    private Player player;
    //速度
    private int speed = 5;


    public Form1()
    {
        InitializeComponent();

        DoubleBuffered = true;  
        player = new Player();
        loop = new Timer();
        loop.Interval = 10;
        loop.Tick += GameLoop;
        loop.Start();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        player.Render(e.Graphics);
    }

    private void GameLoop(object sender, EventArgs e)
    {
        float dx = targetX - player.X;
        float dy = targetY - player.Y;
        float dd = (float)Math.Sqrt(dx * dx + dy * dy);
            
        if (dd < 5)
        {
            player.X = targetX;
            player.Y = targetY;
        }
        else
        {
            player.X += dx / dd*speed;
            player.Y += dy / dd*speed;
        }
        this.Invalidate();
    }

    private void Form1_MouseClick(object sender, MouseEventArgs e)
    {
        // 目标坐标
        targetX = e.X;
        targetY = e.Y;
    }
}
/// <summary>
/// 角色
/// </summary>
public class Player
{
    public float X { get; set; }
    public float Y { get; set; }

    public void Render(Graphics g)
    {
        using (Brush brush = new SolidBrush(Color.Red))
        {
            g.FillRectangle(brush, X-10, Y-10, 20, 20);
        }
    }
}
智商余额不足 2013-07-27
  • 打赏
  • 举报
回复
引用 6 楼 pig357 的回复:
[quote=引用 5 楼 hwenycocodq520 的回复:] 你想做游戏?...
这种效果该如何实现呢[/quote]做游戏就不用控件了,至少2D来个GDI+吧~~
charles_y 2013-07-27
  • 打赏
  • 举报
回复
控件的重绘除非你自己重写,否则闪烁难免。 自己做图吧,别用控件
人生导师 2013-07-27
  • 打赏
  • 举报
回复
搜索下WinForm中的双缓冲技术,具体代码参考7楼的代码
laisui 2013-07-27
  • 打赏
  • 举报
回复
是背景闪烁还是控件闪烁? 在构造函数加上这几句话看看 SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.DoubleBuffer, true);
pig357 2013-07-27
  • 打赏
  • 举报
回复
引用 5 楼 hwenycocodq520 的回复:
你想做游戏?...
这种效果该如何实现呢
智商余额不足 2013-07-27
  • 打赏
  • 举报
回复
你想做游戏?...
pig357 2013-07-27
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
Timer? 我不知道动不动就定时器的人,是可怜还是可恨。一般来说,这种程序是一锅粥里边投入的老鼠屎,这种代码会让人家的程序变得奇慢无比、诡异无比。 界面组件被用户拖动,你应该捕获由底层抛出的各种“MoveXXX”事件。而那种折腾定时器的,是害人的。
我想实现的是:比如控件Players0在(0,0),现在右键点击了背景(0,100)的位置,则Players0就以speed0=20的速度逐渐移动到(0,100),需要时间5s. 这样应该需要定时器的吧,因为需要不断的改变控件Players0的位置。还是有更好的方法?
  • 打赏
  • 举报
回复
整个系统会有一个协调的Dispatcher之类的“界面控制”机制,其它的程序只能注册操作或者撤销那些还未来得及做执行的操作。这样才能流畅。不是你想定时强迫人家刷新显示人家也能保证流畅的。
  • 打赏
  • 举报
回复
Timer? 我不知道动不动就定时器的人,是可怜还是可恨。一般来说,这种程序是一锅粥里边投入的老鼠屎,这种代码会让人家的程序变得奇慢无比、诡异无比。 界面组件被用户拖动,你应该捕获由底层抛出的各种“MoveXXX”事件。而那种折腾定时器的,是害人的。

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧