Проблема с перерисовкой группового ящика

Мне кажется, я поискал в Интернете ответ, но до сих пор не решил эту проблему. Я создаю игру «Палач» на C # (с которой я еще новичок), и у меня есть групповой блок в моей форме, где я рисую различные «части тела». Проблема в том, что он перерисовывается каждый раз при вызове события рисования. Так что у меня будет голова, потом просто рука, нога и т. Д.

Я пробовал делать такие вещи, как переопределение OnPaintBackground, и хотя это решает проблему с перерисовкой, это портит всю форму, и когда я это делаю, это выглядит ужасно. Я также пытался рисовать на панели вместо группового ящика, но по какой-то причине у меня не получалось даже рисовать.

Может ли кто-нибудь предложить какие-либо предложения? Между прочим, это НЕ домашнее задание, а просто личный проект и опыт обучения.

Некоторый код: это то, что я использую для запуска функции рисования (она запускается при других условиях, которые у меня есть)

this.groupBoxHang.Paint += new System.Windows.Forms.PaintEventHandler(this.groupBoxHangMan_Paint);

Затем он доходит до этого и вызывает фактическую функцию, которая находится в отдельном классе.

    private void groupBoxHangMan_Paint(object sender, PaintEventArgs e)
    {          
       draw.DrawHangMan(e.Graphics, GetRemainingGuess());      
    }

Вот часть другого класса:

    public void DrawHangMan(Graphics dM, int guessesRemaining)
    {        
        Pen blackPen = new Pen(Brushes.Black);

        Pen deathPen = new Pen(Brushes.Red);
        deathPen.Width = 2.0F;

        if (guessesRemaining == 7)
        {
            dM.DrawEllipse(blackPen, 94, 75, 60, 60);//head
        }
        else if (guessesRemaining == 6)
        {
            dM.DrawLine(blackPen, 124, 210, 124, 135);//body
        }
        else if (guessesRemaining == 5)
        {
            dM.DrawLine(blackPen, 123, 170, 65, 145);//left arm
        }
        else if (guessesRemaining == 4)
        {
            dM.DrawLine(blackPen, 123, 170, 181, 145); //right arm
        }
        else if (guessesRemaining == 3)
        {
            dM.DrawLine(blackPen, 123, 210, 65, 255);//left leg
        }
        else if (guessesRemaining == 2)
        {
            dM.DrawLine(blackPen, 123, 210, 181, 255);//right leg
        }
        else if (guessesRemaining == 1)
        {
            dM.DrawEllipse(blackPen, 105, 93, 10, 10); //left open eye
            dM.DrawEllipse(blackPen, 133, 93, 10, 10); //right open eye
        }
        else if (guessesRemaining == 0)
        {
            dM.DrawLine(deathPen, 102, 104, 118, 92);//left eye dead
            dM.DrawLine(deathPen, 118, 104, 102, 92);

            dM.DrawLine(deathPen, 130, 104, 146, 92);//right dead eye
            dM.DrawLine(deathPen, 146, 104, 130, 92);
        }         

    }

person Aarin Covyeau    schedule 16.11.2012    source источник


Ответы (1)


Две вещи с вашими операторами If. Они настроены на активацию только тогда, когда он равен счетчику, поэтому вы избегаете перерисовки, когда счетчик меньше порога, во-вторых, с вашими операторами else вы запускаете только один из уровней. Правильно делать это в вашем Paint событии. Попробуйте что-то вроде этого:

public void DrawHangMan(Graphics dM, int guessesRemaining)
{
    Pen blackPen = new Pen(Brushes.Black);
    Pen deathPen = new Pen(Brushes.Red);
    deathPen.Width = 2.0F;

    if (guessesRemaining < 8)
    {
        dM.DrawEllipse(blackPen, 94, 75, 60, 60);//head
    }
    if (guessesRemaining < 7)
    {
        dM.DrawLine(blackPen, 124, 210, 124, 135);//body
    }
    if (guessesRemaining < 6)
    {
        dM.DrawLine(blackPen, 123, 170, 65, 145);//left arm
    }
    if (guessesRemaining < 5)
    {
        dM.DrawLine(blackPen, 123, 170, 181, 145); //right arm
    }
    if (guessesRemaining < 4)
    {
        dM.DrawLine(blackPen, 123, 210, 65, 255);//left leg
    }
    if (guessesRemaining < 3)
    {
        dM.DrawLine(blackPen, 123, 210, 181, 255);//right leg
    }
    if (guessesRemaining < 2)
    {
        dM.DrawEllipse(blackPen, 105, 93, 10, 10); //left open eye
        dM.DrawEllipse(blackPen, 133, 93, 10, 10); //right open eye
    }
    if (guessesRemaining < 1)
    {
        dM.DrawLine(deathPen, 102, 104, 118, 92);//left eye dead
        dM.DrawLine(deathPen, 118, 104, 102, 92);
        dM.DrawLine(deathPen, 130, 104, 146, 92);//right dead eye
        dM.DrawLine(deathPen, 146, 104, 130, 92);
    }

}
person Mark Hall    schedule 16.11.2012
comment
Спасибо за ответ. Я даже не подумал о том, чтобы сделать это таким образом, в основном потому, что я пытался исправить это в первую очередь очисткой. Это работает довольно хорошо, даже если каждый раз перерисовывает части. Хотя мне все еще любопытно. Это лучший способ сделать это, когда вам не нужно перерисовывать одни и те же части более одного раза? Я предполагаю, что это связано с вызовами OnPaint и OnPaintBackground. - person Aarin Covyeau; 16.11.2012
comment
@AarinCovyeau Процедура рисования должна будет иметь возможность рисовать полную картину, если форма недействительна. Единственные известные мне способы облегчить некоторые из рисунков - это создать области и аннулировать их только при изменении своего состояния, но вам все равно понадобится код, подобный тому, который я дал вам выше, или создать рисунок Bitmap для этого, а затем обновить окно с картинками или симуляцию с изображением. - person Mark Hall; 16.11.2012