C#WinForms使用另一个类移动对象

C#WinForms使用另一个类移动对象,c#,keypress,C#,Keypress,我试图用c#编写我的第一个游戏,但目前我一直在努力让玩家移动 我看不出这里面有什么逻辑问题 当按下W键时,播放器实例中的“向下”选项将变为true,因此当ticketvent发生并触发player.move()时,该选项应向上 我希望你能在这里帮助我 我有一个职业球员: class Player : PictureBox { private int _playerspeed = 5; public bool up = false; public bool down

我试图用c#编写我的第一个游戏,但目前我一直在努力让玩家移动

我看不出这里面有什么逻辑问题

当按下W键时,播放器实例中的“向下”选项将变为true,因此当ticketvent发生并触发player.move()时,该选项应向上

我希望你能在这里帮助我

我有一个职业球员:

class Player : PictureBox
{
     private int _playerspeed = 5;
     public bool up = false;
     public bool down = false;
     public bool left = false;
     public bool right = false;
     public bool pshoot = false;

     Game _game;
     public Player(Game game)
     {
         _game = game;
     }

     public void spawn()
     {
          this.BackColor = Color.DarkGreen;
          this.Size = new Size(20, 20);
          this.Left = 540;
          this.Top = 580;
          this.Tag = "player";
          this.Visible = true;
          _game.Controls.Add(this);
          this.BringToFront();
     }

     public void move()
     {
          if (up)
          {
               this.Top -= _playerspeed;
          }

          if (down)
          {
               this.Top += _playerspeed;
          }
     }
}
还有一个班级游戏,形式如下:

public partial class Game : Form
{
     Player player;
     bool playerUp = false;
     bool playerDown = false;
     bool playerLeft = false;
     bool playerRight = false;
     bool playerShoot = false;

     public Game()
     {
          InitializeComponent();
     }

     private void btnStart_Click(object sender, EventArgs e)
     {
          player = new Player(this);

          btnStart.Visible = false;
          player.spawn();
          tmrGameloop.Start();
     }

     private void tmrGameloop_Tick(object sender, EventArgs e)
     {
          player.move();
          txtTick.Text = Convert.ToString(Convert.ToDecimal(txtTick.Text)+ 1);
     }

     private void Game_KeyDown(object sender, KeyEventArgs e)
     {
          switch (e.KeyCode)
          {
               case (Keys.W):
                    player.up = true;
                    break;

               case (Keys.S):
                    player.down = true;
                    break;

          }           
     }

     private void Game_KeyUp(object sender, KeyEventArgs e)
     {
          switch (e.KeyCode)
          {
               case (Keys.W):
                    player.up = false;
                    break;

               case (Keys.S):
                    player.down = false;
                    break;
          }           
     }
}
我看到了几个问题。 首先,使用enum可以为玩家节省大量的工作

比如:

  • 您以错误的方式使用图片框。为什么你的表格里没有图片框你可以把玩家画到图片框里。图片框里面有很多逻辑

  • 玩家不应该参考表格(游戏)。看,他可以把自己添加到控件中。问题是他可以删除一些东西,改变其他玩家/mpc的一些属性,这是你想要避免的事情,因为它真的很难(几乎不可能)阻止玩家对象

  • 我的解决方案:

    class Game{
        private Player player;
    
        // constructor etc.
    
        public void picturebox1_paint(object sender, PaintEventArgs e){
             Graphics g = e.Graphics;
             player.DrawYourSelf(g);
        }
    }
    
    picturebox1\u paint是picturebox的绘制事件。如果您使用的是Visual studio,则可以在事件选项卡中选择Picturebox->Properties->events(thunder图标)->双击Paint创建

    class Player{
         private Direction direction = Direction.notMoving;
         private Point position;
    
         // contructor etc.
    
         public void DrawYourSelf(Graphics g){
              // here use g to draw to player to picture box
         }
    }
    

    据我所知,只要按W或S键,您就需要定期移动播放器。(像一个关键的重复)

    但是,在您的代码中,
    player.up
    player.down
    布尔值永远不会设置为true!所以调用
    move()
    似乎没有效果

    您应该更正此问题,并在按键事件中设置为true:

     private void Game_KeyDown(object sender, KeyEventArgs e)
     {
          switch (e.KeyCode)
          {
               case (Keys.W):
                    player.up = true;
                    break;
    
               case (Keys.S):
                    player.down = true;
                    break;
    
          }           
     }
    

    嗨,谢谢你的回答,你说的“将玩家吸引到picturebox”是什么意思?我是这样做的,所以玩家是一个PicBox…我知道。这就是问题,随着应用程序的增长,您将遇到很多问题。正确的方法是使用paint事件在picturebox中绘制玩家。简单地说,像这样使用图片框是很复杂的。谢谢,但我仍然不明白我在谈论“将玩家绘制到图片框”时应该做什么。我不明白你的意思。@atzaka你知道什么是绘画活动吗?我想是的。。当控件被绘制到窗体时会发生这种情况,不是吗?在向上键和向下键事件中,您没有调用move()method@preciousbetine他在计时器中调用move()。他没有按按钮启动计时器events@preciousbetine他做了
    tmrGameloop.Start()啊,忘了在这里更改它。。我已经在我的代码中做过了,但它没有任何变化。你的计时器多长时间响一次?你确定它在你的按键按下的时间内滴答作响吗?然后,你可以调试以检查是否调用了
    move()
    ,以及你的播放器实例的坐标是否真的被修改了。如果是,则是刷新问题,您可以尝试在picturebox或表单上调用
    .refresh()
     private void Game_KeyDown(object sender, KeyEventArgs e)
     {
          switch (e.KeyCode)
          {
               case (Keys.W):
                    player.up = true;
                    break;
    
               case (Keys.S):
                    player.down = true;
                    break;
    
          }           
     }