蛇游戏意外滞后

时间:2014-02-02 18:20:35

标签: c# lag 2d-games

我创建了一小段代码,创建了一个非常基本的蛇游戏(它还没有完成)。 但它似乎以一种奇怪的方式滞后。在游戏开始时,一切都很顺利,但随着我的转变,游戏变得越来越光滑和懒散。

(顺便说一句:我知道我不需要重新绘制每一帧但我觉得它更通用,我知道问题不在那里)

namespace Snake
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    #region variables

        static List<Snake_part> parts;
        static List<Turn> turns;

        System.Timers.Timer _timer;
        static Graphics g;

    #endregion

    private void Form1_Load(object sender, EventArgs e)
    {
        g = this.CreateGraphics();

        parts = new List<Snake_part>();
        turns = new List<Turn>();

        parts.Add(new Snake_part("Right",new Rectangle(50,10,25,25)));
        parts.Add(new Snake_part("Right", new Rectangle(24, 10, 25, 25)));

        _timer = new System.Timers.Timer(30);
        _timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        _timer.Enabled = true;
    }

    static void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        turn();
        changePos();

        draw();
    }

    static private void draw()
    {
        try
        {
            g.Clear(Color.Black);
        }
        catch { }
        foreach(Snake_part part in parts)
        {
            g.FillRectangle(Brushes.White, part.Rect);
        }
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Left) { turns.Add(new Turn(parts[0].Rect.X, parts[0].Rect.Y,"Left")); }
        else if (e.KeyCode == Keys.Right) { turns.Add(new Turn(parts[0].Rect.X, parts[0].Rect.Y, "Right")); }
        else if (e.KeyCode == Keys.Up) {
            turns.Add(new Turn(parts[0].Rect.X, parts[0].Rect.Y, "Up"));
        }
        else if (e.KeyCode == Keys.Down) { turns.Add(new Turn(parts[0].Rect.X, parts[0].Rect.Y, "Down")); }
    }

    static private void turn()
    {
        if(turns.Count >= 1){
            foreach (Snake_part part in parts)
            {
                if (turns.Count >= 1)
                {
                    try
                    {
                        foreach (Turn turn in turns)
                        {
                            if (part.Dire == "Right")
                            {
                                if (part.Rect.IntersectsWith(new Rectangle(turn.X + 25, turn.Y, 1, 1)))
                                {
                                    part.Dire = turn.Dire;
                                    if (part == parts.Last())
                                    {
                                        turns.Remove(turns.Last());
                                    }
                                }
                            }
                            else if (part.Dire == "Down")
                            {
                                if (part.Rect.IntersectsWith(new Rectangle(turn.X, turn.Y + 25, 1, 1)))
                                {
                                    part.Dire = turn.Dire;
                                    if (part == parts.Last())
                                    {
                                        turns.Remove(turns.Last());
                                    }
                                }
                            }
                            else if (part.Dire == "Up")
                            {
                                if (part.Rect.IntersectsWith(new Rectangle(turn.X, turn.Y - 25, 1, 1)))
                                {
                                    part.Dire = turn.Dire;
                                    if (part == parts.Last())
                                    {
                                        turns.Remove(turns.Last());
                                    }
                                }
                            }
                            else if (part.Dire == "Left")
                            {
                                if (part.Rect.IntersectsWith(new Rectangle(turn.X - 25, turn.Y - 25, 1, 2)))
                                {
                                    part.Dire = turn.Dire;
                                    if (part == parts.Last())
                                    {
                                        turns.Remove(turns.Last());
                                    }
                                }
                            }
                        }
                    }
                    catch { }
                }
            }
        }
    }

    static private void changePos()
    {
        foreach (Snake_part part in parts)
        {
            if (part.Dire == "Right") { part.Rect = new Rectangle(part.Rect.X + 2,part.Rect.Y,part.Rect.Width,part.Rect.Height); }
            if (part.Dire == "Left") { part.Rect = new Rectangle(part.Rect.X - 2, part.Rect.Y, part.Rect.Width, part.Rect.Height); }
            if (part.Dire == "Up") { part.Rect = new Rectangle(part.Rect.X, part.Rect.Y - 2, part.Rect.Width, part.Rect.Height); }
            if (part.Dire == "Down") { part.Rect = new Rectangle(part.Rect.X, part.Rect.Y + 2, part.Rect.Width, part.Rect.Height); }
        }
    }
}
}

谢谢

1 个答案:

答案 0 :(得分:0)

那些空的catch块是一个红色标志 - 你永远不想这样做......这不是缓存和重用Graphics对象的有效方法。每次都要换一个新的,然后处理它。

private void Draw()
{
    using (Graphics g = this.CreateGraphics())
    {
        g.Clear(Color.Black);

        foreach (Snake_part part in parts)
            g.FillRectangle(Brushes.White, part.Rect);
    }
}

在'turn'方法中,你不能从Turn迭代器中移除一个转弯。最好找到一种方法将Turn标记为'done'并在最后清理。并且有许多Turn对象永远不会被删除 - 例如只需按住右键,您将看到Turns列表快速建立。