帮助使用按键和计时器移动 PictureBox

发布于 2024-12-01 16:42:06 字数 2185 浏览 0 评论 0原文

我正在制作一款类似太空侵略者的射击游戏。我的 PictureBox pb 无法使用按键移动,并且 PictureBox pb1 上有问题,空间盘在一秒钟后消失。它不会左右移动。

到目前为止,这是我的代码。

namespace SpaceShoot
{
class Shoot
{

    private Form f;
    private Button bLeft, bRight;
    private PictureBox pb;
    private PictureBox pb1;
    private Boolean check = false;
    private int X, Y;
    Timer Clock = new Timer();
    private int k = 0;
    int x = 0;

    public Shoot()
    {
        f = new Form();

        bLeft = new Button();
        bRight = new Button();

        pb = new PictureBox();  //spaceship
        pb1 = new PictureBox(); //spacedisc

        Clock = new Timer();

    }

    public void Launch()
    {

        pb1.Image = new Bitmap("spacedisc.png");
        pb1.SetBounds(20, 20, 120, 70);

        pb1.SizeMode = PictureBoxSizeMode.StretchImage;

        f.BackColor = System.Drawing.Color.Black;
        f.Size = new Size(700, 700);
        f.StartPosition = FormStartPosition.CenterScreen;
        f.Controls.Add(pb);
        f.Controls.Add(pb1);

        bLeft.KeyDown += new KeyEventHandler(Space_KeyDown);
        bRight.KeyDown += new KeyEventHandler(Space_KeyDown);

        pb.SetBounds(300, 580, 60, 60);
        pb.Image = new Bitmap("spaceship.png");         

        pb.SizeMode = PictureBoxSizeMode.StretchImage;

        Clock = new Timer();
        Clock.Interval = 800;
        Clock.Tick += new EventHandler(Clock_Tick);
        Clock.Start();
        f.ShowDialog();
    }

    public void Clock_Tick(object sender, EventArgs e)
    {

        for (x = 0; x >= 0; x += 2)
        {
            pb1.Location = new Point(0 + x, 20);
        }
        for (x = 500; x >= 500; x -= 2)
        {
            pb1.Location = new Point(500 - x, 20);
        }
         f.Invalidate();           
    }

    public void Space_KeyDown(object sender, KeyEventArgs e)
    {
        int x = pb.Location.X;
        if (e.KeyCode == Keys.Right)
        {
            x += 5;
            pb.Location = new Point(300 + x, 580);
        }
        else if (e.KeyCode == Keys.Left)
        {
            x -= 5;
            pb.Location = new Point(300 + x, 580);
        }

    }
}

}

I'm making a shooting game like space invaders. My PictureBox pb won't move using keys and I have a problem on PictureBox pb1, the space disc disappears after a second. It won't move left and right.

Here's my codes so far.

namespace SpaceShoot
{
class Shoot
{

    private Form f;
    private Button bLeft, bRight;
    private PictureBox pb;
    private PictureBox pb1;
    private Boolean check = false;
    private int X, Y;
    Timer Clock = new Timer();
    private int k = 0;
    int x = 0;

    public Shoot()
    {
        f = new Form();

        bLeft = new Button();
        bRight = new Button();

        pb = new PictureBox();  //spaceship
        pb1 = new PictureBox(); //spacedisc

        Clock = new Timer();

    }

    public void Launch()
    {

        pb1.Image = new Bitmap("spacedisc.png");
        pb1.SetBounds(20, 20, 120, 70);

        pb1.SizeMode = PictureBoxSizeMode.StretchImage;

        f.BackColor = System.Drawing.Color.Black;
        f.Size = new Size(700, 700);
        f.StartPosition = FormStartPosition.CenterScreen;
        f.Controls.Add(pb);
        f.Controls.Add(pb1);

        bLeft.KeyDown += new KeyEventHandler(Space_KeyDown);
        bRight.KeyDown += new KeyEventHandler(Space_KeyDown);

        pb.SetBounds(300, 580, 60, 60);
        pb.Image = new Bitmap("spaceship.png");         

        pb.SizeMode = PictureBoxSizeMode.StretchImage;

        Clock = new Timer();
        Clock.Interval = 800;
        Clock.Tick += new EventHandler(Clock_Tick);
        Clock.Start();
        f.ShowDialog();
    }

    public void Clock_Tick(object sender, EventArgs e)
    {

        for (x = 0; x >= 0; x += 2)
        {
            pb1.Location = new Point(0 + x, 20);
        }
        for (x = 500; x >= 500; x -= 2)
        {
            pb1.Location = new Point(500 - x, 20);
        }
         f.Invalidate();           
    }

    public void Space_KeyDown(object sender, KeyEventArgs e)
    {
        int x = pb.Location.X;
        if (e.KeyCode == Keys.Right)
        {
            x += 5;
            pb.Location = new Point(300 + x, 580);
        }
        else if (e.KeyCode == Keys.Left)
        {
            x -= 5;
            pb.Location = new Point(300 + x, 580);
        }

    }
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风渺 2024-12-08 16:42:06

oOo...从哪里开始?好吧,一次只做一件事。

首先,您有一个无限循环:

            for (x = 0; x >= 0; x += 2)
            {
                pb1.Location = new Point(0 + x, 20);
            }

因此应用程序永远不会运行超过一个刻度。

其次你正在一个对话框中运行......我真的不推荐。将:替换

f.ShowDialog();

为:

Application.Run(f);

您的program.cs可能看起来像这样:

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Shoot shoot = new Shoot();
        shoot.Launch();

如果您已经在WinForm应用程序中,那么只需.Show()该表单并.Hide()任何以前的表单即可。

第三...我很感激您可能只是在这里玩得开心...但无论如何:这是使用 WinForm 制作游戏的一种非常糟糕的方式。 Windows 控件并非设计用于这种方式,您最终会遇到许多剪切、透明度和其他渲染问题。我建议让游戏更新绘制到占据整个窗体的控件边界的图像。这样,您可以一次性执行所有渲染,而不必依赖您正在使用的每个控件的许多单独的绘制方法。屏幕上的精灵越多,它的缩放效果也越好(因为控件是相对较重的物体)。

我强烈建议您阅读常见问题解答GDI+。多年前,正是它帮助我领会了如何在 WinForm 中出色地绘图。 :)

简而言之:

  • 组织代码为游戏的每个帧创建图像
  • 创建自定义控件(继承自 Control 的对象),然后将“当前”图像渲染到图形对象中(重写 OnPaint 方法来执行此操作)用于控制。

oOo.... where to start? Okay, one thing at a time.

First off, you have an infinite loop:

            for (x = 0; x >= 0; x += 2)
            {
                pb1.Location = new Point(0 + x, 20);
            }

So the app never runs past a single tick.

Secondly you're running in a dialog.... which I really don't recommend. Replace:

f.ShowDialog();

with:

Application.Run(f);

With your program.cs probably looking something like this:

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Shoot shoot = new Shoot();
        shoot.Launch();

If you're already within a WinForm application then just .Show() the form and .Hide() any previous forms.

Thirdly... and I appreciate you're probably just having fun here... but anyway: this is a pretty bad way to make a game using WinForm. Windows controls are not designed to be used this way and you will eventually run into a number of issues with clipping, transparency and other rendering issues. What I would recommend is to have the game update an image that is painted into the bounds of a control that occupies the entire form. This way you can perform all the rendering in one hit instead of having to rely on lots of individual paint methods of each control you are using. It will also scale better the more sprites you have on screen (as controls are relatively heavy objects).

I highly recommend reading the this FAQ on the GDI+. It's the same one that helped me appreciate how to draw nicely in WinForm many years ago. :)

In short:

  • Organise your code to create images for each frame of the game
  • Create a custom control (an object that inherits from Control) to then render the "current" image into the graphics object (override the OnPaint method to do this) for the control.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文