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

绘制矩形后如何修改其属性?Flappy Bird复刻中控件不移动求助

解决Flappy Bird复刻版中控件/图形不更新的问题

嘿,我完全懂你现在的困扰——明明改了坐标数值,界面上的小鸟和管道就是纹丝不动,断点看数值又确实在变,这种情况在WinForms开发里太常见啦!咱们一步步拆解问题,搞定它:

核心原因:WinForms不会自动刷新修改后的属性

WinForms的控件/界面绘制是有触发时机的(比如首次加载、窗口被遮挡后恢复),你后台代码修改了X/Y属性后,系统不知道要重新绘制,所以必须手动触发重绘操作。


方案1:用控件(如Panel/PictureBox)实现移动

如果你是用现成控件来做小鸟和管道,修改坐标后一定要调用刷新方法:

1. 小鸟的下落与跳跃

  • 先划重点:WinForms的Y轴是从上到下递增的,所以下落应该是Y += gravity,跳跃是Y -= 跳跃力度,别搞反方向哦!
  • Timer的Tick事件处理下落:
    private void timer1_Tick(object sender, EventArgs e)
    {
        // 让小鸟持续下落(Y值增加)
        rect.Y += gravity; 
        // 关键:刷新小鸟控件,触发重绘
        rect.Refresh(); 
        
        // 顺便处理管道移动
        MovePipes();
    }
    
  • 空格键触发跳跃:
    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            // 跳跃:让Y值减少
            rect.Y -= 50; 
            rect.Refresh();
        }
    }
    

2. 管道的左移与重置

private void MovePipes()
{
    pipe1.X -= 5; // 管道左移
    
    // 管道完全移出屏幕后,重置到右侧并随机高度
    if (pipe1.X + pipe1.Width < 0)
    {
        pipe1.X = this.Width;
        pipe1.Height = new Random().Next(100, this.Height - 200);
    }
    
    pipe1.Refresh(); // 刷新管道控件
}

方案2:用自定义Graphics绘制(更适合游戏场景)

如果是直接在Form的Paint事件里画矩形,这种方式比控件更高效,步骤如下:

  1. 先定义全局变量存坐标和尺寸:
    private int birdX = 50;
    private int birdY = 100;
    private int pipeX;
    private int pipeHeight = 150;
    private readonly int gravity = 2;
    
  2. 在Form的Paint事件里绘制小鸟和管道:
    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        // 画小鸟
        e.Graphics.FillRectangle(Brushes.Yellow, birdX, birdY, 30, 30);
        
        // 画上管道
        e.Graphics.FillRectangle(Brushes.Green, pipeX, 0, 60, pipeHeight);
        // 画下管道(留出空隙让小鸟通过)
        e.Graphics.FillRectangle(Brushes.Green, pipeX, pipeHeight + 150, 60, this.Height - pipeHeight - 150);
    }
    
  3. Timer和空格键事件里只修改变量,然后触发重绘:
    private void timer1_Tick(object sender, EventArgs e)
    {
        birdY += gravity; // 下落
        pipeX -= 5; // 管道左移
        
        // 管道重置逻辑
        if (pipeX + 60 < 0)
        {
            pipeX = this.Width;
            pipeHeight = new Random().Next(100, this.Height - 200);
        }
        
        this.Invalidate(); // 触发Form重绘,调用Paint事件
    }
    
    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            birdY -= 50; // 跳跃
            this.Invalidate();
        }
    }
    

额外调试注意点

  • 检查Timer的Enabled属性是否设为true,Interval建议设为16-20ms(对应50-60帧,游戏更流畅)。
  • 如果用控件,确保控件的Visible属性是true,且没有被其他控件遮挡。
  • 断点看到数值变化说明逻辑没问题,重点排查是否触发了重绘操作。

内容的提问来源于stack exchange,提问作者Andrej Ilic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:22:50