0

私は現在、透明なパネルでのアニメーションを必要とするプロジェクトに取り組んでいます。透明なパネルを作成して描画することはできましたが、ペンツールで描画したパネルを更新すると、透明として再描画されません。これは、私が以前に描いたものの最後の位置をパネルに染み込ませたままにします。

OnPaintまたはRefreshをオーバーライドして、パネル上のすべてのピクセルを透明として再描画する簡単な方法があると思いますが、オンラインで解決策を見つけたり、自分で解決したりすることはできません。

背景を透明にするために使用したコードは次のとおりです。

public class TransparentPanel : Panel
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
    }
 }

これは、背景を透明として再描画するための私の最も失敗した試みでした。

protected override void OnPaint(PaintEventArgs pe)
{
        pe.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(100,255,255,255)), this.ClientRectangle);
}

このソリューションの問題は、数回更新した後、背景が不透明な白になることです。

誰かが私がこれを行う方法を理解するのを手伝ってもらえますか?私はグラフィックスとアニメーションに非常に慣れていないので、これにはかなり簡単な答えがあると思います。前もって感謝します。


***編集*** Dyppl の応答に従って、パネルへのグラフィックの描画方法を変更しました。これが私の現在のコードです:

    public TransparentPanel fighterPanel;
...
    fighterPanel.Paint +=new PaintEventHandler(fighterPanel_Paint);
...
    fighterPanel = new TransparentPanel();
    fighterPanel.Location = new System.Drawing.Point(600, 300);
    fighterPanel.Size = new System.Drawing.Size(400, 400);
    gameArenaForm.Controls.Add(fighterPanel);
    fighterPanel.BringToFront();        
...
    private void fighterPanel_Paint(object sender, PaintEventArgs e)
    {
        using (Pen blackPen = new Pen(Color.Black, 3), redPen = new Pen(Color.Red, 3), bluePen = new Pen(Color.Blue, 3))
        {
            //head     
            e.Graphics.DrawEllipse
                (blackPen,
                head.DrawPoint(torso.GetTorsoAngle(), torso.neck.getLocationX(), torso.neck.getLocationY()).X,
                head.DrawPoint(torso.GetTorsoAngle(), torso.neck.getLocationX(), torso.neck.getLocationY()).Y,
                head.radius * 2,
                head.radius * 2
                );
            //torso
            e.Graphics.DrawLine(blackPen, torso.neck.getLocationX(), torso.neck.getLocationY(), torso.shoulders.getLocationX(), torso.shoulders.getLocationY());
            e.Graphics.DrawLine(blackPen, torso.shoulders.getLocationX(), torso.shoulders.getLocationY(), torso.hips.getLocationX(), torso.hips.getLocationY());
            //right arm
            e.Graphics.DrawLine(blackPen, torso.shoulders.getLocationX(), torso.shoulders.getLocationY(), rightArm.elbow.getLocationX(), rightArm.elbow.getLocationY());
            e.Graphics.DrawLine(redPen, rightArm.elbow.getLocationX(), rightArm.elbow.getLocationY(), rightArm.attachHand.getLocationX(), rightArm.attachHand.getLocationY());
            //left arm
            e.Graphics.DrawLine(blackPen, torso.shoulders.getLocationX(), torso.shoulders.getLocationY(), leftArm.elbow.getLocationX(), leftArm.elbow.getLocationY());
            e.Graphics.DrawLine(bluePen, leftArm.elbow.getLocationX(), leftArm.elbow.getLocationY(), leftArm.attachHand.getLocationX(), leftArm.attachHand.getLocationY());
            //right leg
            e.Graphics.DrawLine(blackPen, torso.hips.getLocationX(), torso.hips.getLocationY(), rightLeg.knee.getLocationX(), rightLeg.knee.getLocationY());
            e.Graphics.DrawLine(redPen, rightLeg.knee.getLocationX(), rightLeg.knee.getLocationY(), rightLeg.attachFoot.getLocationX(), rightLeg.attachFoot.getLocationY());
            //left leg
            e.Graphics.DrawLine(blackPen, torso.hips.getLocationX(), torso.hips.getLocationY(), leftLeg.knee.getLocationX(), leftLeg.knee.getLocationY());
            e.Graphics.DrawLine(bluePen, leftLeg.knee.getLocationX(), leftLeg.knee.getLocationY(), leftLeg.attachFoot.getLocationX(), leftLeg.attachFoot.getLocationY());
        }
    }

オブジェクトが移動して数回更新される前後の写真を次に示します。

申し訳ありませんが、10担当者がいない限り、画像を埋め込むことはできません。

4

1 に答える 1

0

CreateGraphicsあなたはあなたの仕事のために使うべきではありません。パネルのイベントをサブスクライブし、代わりにオブジェクトとしてPaint使用して、イベントハンドラーですべての描画を行います。PaintEventArgs.GraphicsGraphics

private void transparentPanel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawRectangle(new Pen(Color.Red,2), 4,4,64,64);
}

これがあなたTransparentPanelと私のイベントハンドラーを使って得たものです:

結果画像

更新:Graphics.Clear問題は、以前のすべての描画を削除するために、すべての描画サイクルの最初にメソッドを呼び出さなければならないことです。それはあなたの透明な背景を台無しにします。このリンクは、問題に関するいくつかのアドバイスを提供します。重要な点は、「透明な」背景を取得するには、パネルの親コントロールも無効にする必要があるということです。

それで、私はそのままのコードを残しましたTransparentPanelが、メインフォームのコードを変更しました:

readonly Random _rand =new Random();

private void transparentPanel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawRectangle(new Pen(Color.Red,2), _rand.Next(60),_rand.Next(30),64,64);
}

private void button1_Click(object sender, EventArgs e)
{
   Invalidate(new Rectangle(transparentPanel1.Location, transparentPanel1.Size),true);
}

これで、フォームのボタンをクリックするたびに、パネルが再描画され、ランダムな場所に1つの長方形が表示されます。transparantPanel1自体を無効にすると、クリアされず、赤い長方形が散らかって表示されます。


更新(Alexによる): これは、問題を解決したDypplからのリンクで提供されているコードです。透明なパネルクラスに配置する必要があります。

public void InvalidateEx()
    {
        if (Parent == null)
            return;
        Rectangle rc = new Rectangle(this.Location, this.Size);
        Parent.Invalidate(rc, true);
    } 

パネルを更新するたびにこのコードを呼び出し、背景を透明に保ちます。

于 2011-06-05T08:49:17.033 に答える