C# 自定义绘图方法不支持';我不能正常工作

C# 自定义绘图方法不支持';我不能正常工作,c#,C#,我想我应该试试俄罗斯方块的克隆版,但我遇到了一个问题。我有一个Tetromino类,其中有一个Draw()方法,以便在屏幕上绘制每个片段时更容易。但是,它不能正常工作,它似乎什么也没画,除非我删除graphics.Clear(Color.Black)行,这当然会导致混乱的结果(因为绘制表面不会在游戏循环的每次迭代中都被清除)。我将图形对象作为参数传递到我的方法中。我错过什么了吗?此外,我使用自定义计时器类来提高精度,但我认为这不重要 Game.cs: using System; using Sy

我想我应该试试俄罗斯方块的克隆版,但我遇到了一个问题。我有一个
Tetromino
类,其中有一个
Draw()
方法,以便在屏幕上绘制每个片段时更容易。但是,它不能正常工作,它似乎什么也没画,除非我删除
graphics.Clear(Color.Black)
行,这当然会导致混乱的结果(因为绘制表面不会在游戏循环的每次迭代中都被清除)。我将图形对象作为参数传递到我的方法中。我错过什么了吗?此外,我使用自定义计时器类来提高精度,但我认为这不重要

Game.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Tetris
{
    public partial class Game : Form
    {
        private Timer timer;
        private Graphics graphics;
        private List<Tetromino> tetrominos;

        private static readonly Random random = new Random();

        private const int SCREEN_WIDTH = 300;
        private const int SCREEN_HEIGHT = 600;

        public Game()
        {
            InitializeComponent();

            timer = new Timer();

            this.Text = "Tetris";
            this.DoubleBuffered = true;
            this.ClientSize = new Size(SCREEN_WIDTH, SCREEN_HEIGHT);
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            this.StartPosition = FormStartPosition.CenterScreen;
            this.MaximizeBox = false;
            graphics = this.CreateGraphics();

            tetrominos = new List<Tetromino>();
        }

        public void GameLoop()
        {
            // This is here just for testing.
            int tetromino = random.Next(0, 6);

            tetrominos.Add(new Tetromino((Tetromino.Tetrominos)tetromino));

            while (this.Created)
            {
                timer.Reset();
                GameUpdate();
                GameDraw();
                Application.DoEvents();
                while (timer.GetTicks() < 33) ;
            }
        }

        private void GameUpdate()
        {
            for (int i = 0; i < tetrominos.Count; i++)
                tetrominos[i].Offset(0, 5);
        }

        private void GameDraw()
        {
            graphics.Clear(Color.Black);

            for (int i = 0; i < tetrominos.Count; i++)
                tetrominos[i].Draw(graphics);
        }
    }
}

我添加了我的定时器类,让你检查出来,它只是击中了我!错误在于
startTick=0
应该是
startTick=GetTickCount()
。我可能打错了。哎哟,我想在疲劳状态下编码会对您产生类似的效果。

千万不要尝试缓存图形对象,因为它不会按您需要的方式工作。图形变量可能会有问题。WinForms确实希望您使用绘制事件。也看到
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;

namespace Tetris
{
    class Tetromino
    {
        private List<Rectangle> _tetromino;
        private Brush brush;

        public Tetromino(Tetrominos tetromino)
        {
            _tetromino = new List<Rectangle>();

            switch (tetromino)
            {
                //---[][][][]---
                case Tetrominos.I:
                    brush = Brushes.Cyan;
                    _tetromino.Add(new Rectangle(90, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X + 30, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[1].X + 30, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[2].X + 30, -60, 30, 30));
                    break;
                //----[][]----
                //----[][]----
                case Tetrominos.O:
                    brush = Brushes.Yellow;
                    _tetromino.Add(new Rectangle(120, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X + 30, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X + 30, -30, 30, 30));
                    break;
                //---- [] -----
                //---[][][]----
                case Tetrominos.T:
                    brush = Brushes.Purple;
                    _tetromino.Add(new Rectangle(120, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X - 30, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[1].X + 30, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[2].X + 30, -30, 30, 30));
                    break;
                //---- [][]----
                //---[][] -----
                case Tetrominos.S:
                    brush = Brushes.Green;
                    _tetromino.Add(new Rectangle(120, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X + 30, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X - 30, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X, -30, 30, 30));
                    break;
                //---[][] -----
                //---- [][]----
                case Tetrominos.Z:
                    brush = Brushes.Red;
                    _tetromino.Add(new Rectangle(90, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X + 30, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X + 30, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[2].X + 30, -30, 30, 30));
                    break;
                //---[]  ------
                //---[][][]----
                case Tetrominos.J:
                    brush = Brushes.Blue;
                    _tetromino.Add(new Rectangle(90, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X + 30, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[2].X + 30, -30, 30, 30));
                    break;
                //-----  []----
                //---[][][]----
                case Tetrominos.L:
                    brush = Brushes.Orange;
                    _tetromino.Add(new Rectangle(150, -60, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[0].X - 60, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[1].X + 30, -30, 30, 30));
                    _tetromino.Add(new Rectangle(_tetromino[2].X + 30, -30, 30, 30));
                    break;
            }
        }

        public void Offset(int x, int y)
        {
            for (int i = 0; i < _tetromino.Count; i++)
                _tetromino[i] = new Rectangle(_tetromino[i].X + x, _tetromino[i].Y + y, 30, 30);
        }

        public void Draw(Graphics graphics)
        {
            for (int i = 0; i < _tetromino.Count; i++)
                graphics.FillRectangle(brush, _tetromino[i]);
        }

        public void Rotate()
        {
            // TO-DO: Implement
        }

        public enum Tetrominos { I, O, T, S, Z, J, L }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace Tetris
{
    class Timer
    {
        [DllImport("kernel32.dll")]
        private static extern long GetTickCount();

        private long startTick;

        public Timer() { Reset(); }

        public void Reset() { startTick = 0; }

        public long GetTicks() => GetTickCount() - startTick;
    }
}