1

对于这个游戏的一些常见问题,我很抱歉,但我不知道在哪里以及如何在我的游戏中实现游戏循环。我希望游戏循环像这样工作:

Settings();
if (startClicked == true)
{
    Spawn();
}
while (enemyKilled == true)
{
    Spawn();
}

这是我的代码:

public partial class Form1 : Form
{
    public int score1 = 0;
    public PictureBox enemy = new PictureBox();
    public PictureBox missile = new PictureBox();
    public int enemyX;
    public int enemyY;
    public int missileX;
    public int missileY;
    public bool enemyKilled;
    public bool startClicked;
    public Form1()
    {
        InitializeComponent();
        logo.Visible = false;
        startbutton.Visible = false;
        spaceship.Visible = false;
        score.Visible = false;
        labelEnemyX.Visible = false;
        labelEnemyY.Visible = false;
        labelMissileX.Visible = false;
        labelMissileY.Visible = false;

    }

    private void Settings()
    {
        logo.Visible = true;
        startbutton.Visible = true;
        score.Text = Convert.ToString(score1);
    }

    private void Spawn()
    {
        enemy.Visible = true;
        missile.Visible = true;
        System.Timers.Timer enemyMove = new System.Timers.Timer();
        enemyMove.Interval = 100;
        Random enemyPosition = new Random();
        int enemyX = enemyPosition.Next(30, 400);
        int enemyY = enemy.Location.Y;
        enemy.Location = new Point(enemyX, 0);
        enemy.Image = WindowsFormsApplication16.Properties.Resources.Enemy2;
        enemy.Width = 36;
        enemy.Height = 29;
        this.Controls.Add(enemy);
        enemyMove.Elapsed += (sender, args) =>
            {
                enemy.Location = new Point(enemyX, enemy.Location.Y + 2);
                enemyX = enemy.Location.X;
                enemyY = enemy.Location.Y;
                labelEnemyX.Text = Convert.ToString(enemyX);
                labelEnemyY.Text = Convert.ToString(enemyY);
                if (enemyY <= -10)
                {
                    enemyKilled = false;
                }
            }; enemyMove.Start();
    }

    private void AddScore()
    {
        if (enemyKilled == true)
        {
            score1++;
            score.Text = Convert.ToString(score1);
        }
    }

    private void MissileMove()
    {
        System.Timers.Timer missileMove = new System.Timers.Timer();
        missileMove.Interval = 30;
        missileMove.Elapsed += (sender, args) =>
            {
                if (missile.Location.Y >= -30)
                {
                    missile.Location = new Point(missile.Location.X, missile.Location.Y - 15);
                    missileX = missile.Location.X;
                    missileY = missile.Location.Y;
                    labelMissileX.Text = Convert.ToString(missileX);
                    labelMissileY.Text = Convert.ToString(missileY);
                    int enemyToMissileLocationX = Convert.ToInt32(labelEnemyX.Text);
                    int enemyToMissileLocationY = Convert.ToInt32(labelEnemyY.Text);
                    if ((missileX - enemyToMissileLocationX <= 20 && missileY - enemyToMissileLocationY <= 20 && missileX - enemyToMissileLocationX >= 0 && missileY - enemyToMissileLocationY >= 0) || (enemyToMissileLocationX - missileX <= 20 && enemyToMissileLocationY - missileY <= 20 && enemyToMissileLocationX - missileX >= 0 && enemyToMissileLocationY - missileY >= 0))
                    {
                        missile.Visible = false;
                        enemy.Visible = false;
                        enemyKilled = true;
                    }
                }
            }; missileMove.Start();

    }

    void Form1_Load(object sender, EventArgs e)
    {
        Settings();
        if (startClicked == true)
        {
            Spawn();
        }
        while (enemyKilled == true)
        {
            Spawn();
        }
    }

    private void startbutton_Click(object sender, EventArgs e)
    {
        this.startClicked = true;
        logo.Visible = false;
        startbutton.Visible = false;
        spaceship.Visible = true;
        score.Visible = true;
        startbutton.Enabled = false;

    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Right)
        {
            if (spaceship.Location.X <= 370)
            {
                spaceship.Location = new Point(spaceship.Location.X + 10, spaceship.Location.Y);
            }
        }
        if (e.KeyCode == Keys.Left)
        {
            if (spaceship.Location.X >= 0)
            {
                spaceship.Location = new Point(spaceship.Location.X - 10, spaceship.Location.Y);
            }
        }
        if (e.KeyCode == Keys.Space)
        {
            missile.Image = WindowsFormsApplication16.Properties.Resources.Missile;
            missile.Height = 42;
            missile.Width = 12;
            missile.Location = new Point(spaceship.Location.X + 28, spaceship.Location.Y + 15);
            this.Controls.Add(missile);
            MissileMove();

        }
    }
}

更新:

    private void MissileMove()
    {
        System.Timers.Timer missileMove = new System.Timers.Timer();
        missileMove.Interval = 30;
        missileMove.Elapsed += (sender, args) =>
            {
                if (missile.Location.Y >= -30)
                {
                    missile.Location = new Point(missile.Location.X, missile.Location.Y - 15);
                    missileX = missile.Location.X;
                    missileY = missile.Location.Y;
                    labelMissileX.Text = Convert.ToString(missileX);
                    labelMissileY.Text = Convert.ToString(missileY);
                    int enemyToMissileLocationX = Convert.ToInt32(labelEnemyX.Text);
                    int enemyToMissileLocationY = Convert.ToInt32(labelEnemyY.Text);
                    if ((missileX - enemyToMissileLocationX <= 20 && missileY - enemyToMissileLocationY <= 20 && missileX - enemyToMissileLocationX >= 0 && missileY - enemyToMissileLocationY >= 0) || (enemyToMissileLocationX - missileX <= 20 && enemyToMissileLocationY - missileY <= 20 && enemyToMissileLocationX - missileX >= 0 && enemyToMissileLocationY - missileY >= 0))
                    {
                        missile.Visible = false;
                        enemy.Visible = false;
                        enemyKilled = true;
                        System.Threading.Thread.Sleep(100);
                        Application.DoEvents();
                        Spawn();
                    }
                }
            }; missileMove.Start();

尝试对班级进行此操作,是的,它再次产生了敌人,但动画出现了错误,我可以看到敌人从一个位置跳到另一个位置。谢谢你的帮助。

4

2 回答 2

2

我的建议是实现游戏循环,就像你在一个函数中一样Form_Load(或者main如果你熟悉将它集成到 Windows 窗体应用程序中的函数),但是Application.DoEvents在循环内部添加调用以确保窗口仍然响应诸如移动和调整大小以及单击按钮之类的事件。除此之外,您可能必须澄清当前解决方案遇到的问题,以获得更完整和详细的答案。

于 2013-10-21T19:49:16.397 回答
1

这看起来像一个 Windows 窗体。因此,我建议您有一个在 while 循环中运行并处理游戏的所有移动/更新逻辑的后台线程。复杂的部分将是管理 Windows 窗体线程和游戏线程之间的状态。您需要确保您是按钮单击等事件处理程序,更新游戏状态以线程安全的方式执行,因为它们将在 GUI 线程上。游戏循环线程需要更新 GUI 上的状态,这将需要所谓的 marshelling,因为只有 GUI 线程被允许访问表单上存在的控件,如按钮等。

线程管理、线程安全和编组的主题留给你研究。

这假设它是某种实时游戏,而不是基于回合的游戏。如果它是回合制的,那么你真的不需要游戏循环。您可以通过使用状态图和纯事件驱动设计来实现相同的目标。

于 2013-10-21T17:31:36.517 回答