我无法使用keydown事件来移动我的图像

时间:2013-10-07 22:04:42

标签: c# windows winforms 2d picturebox

我正在制作一款2D自上而下的游戏,玩家控制着一只猫。为此,该人使用WASD键移动。我有Form1,GameManager,Cat和Moveable类。 Form1向GameManager发送cat imagelist和e.graphics(用于图片框)。 GameManager有一个计时器,每个勾选检查猫是否已移动。 Cat处理移动逻辑。当我运行程序时,cat精灵显示在其初始位置,但在按下键时不会移动。我无法弄清楚我的问题,有人可以帮忙吗?

以下是我的课程:

Form1中:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CatAndMouse
{
    public partial class Form1 : Form
    {
        GameManager myGM = new GameManager();
        public Form1()
        {
            InitializeComponent();
            newGame();
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (this.myGM != null)
                this.myGM.paint(e.Graphics);
        }

        public void newGame()
        {
            myGM.newGame(imgCat);
        }
    }
}

游戏管理:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CatAndMouse
{
    class GameManager
    {
        Cat ca1 = new Cat();
        int amount = 5;
        Timer time = new Timer();
        public ImageList imgCat = new ImageList();

        public void newGame(ImageList cat)
        {
            imgCat = cat;
            time.Start();
        }

        public void move()
        {
            ca1.Move(amount);
        }

        public void paint(Graphics g)
        {
            g.DrawImage(imgCat.Images[0], ca1.getLocation());
        }

        private void time_Tick(object sender, EventArgs e)
        {
            move();
        }
    }
}

猫:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CatAndMouse
{
    class Cat: Moveable
    {
        Random myCLoc = new Random();
        private Moveable myCatMove;
        public Point p = new Point(100, 100);
        int dir = 0;

        public void Move(int n)
        {
            if (dir == 0)
            {
                p.Y = p.Y - n;
            }
            if (dir == 1)
            {
                p.X = p.X + n;
            }
            if (dir == 2)
            {
                p.Y = p.Y + n;
            }
            if (dir == 3)
            {
                p.X = p.X - n;
            }
        }
        private void KeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up)
            {
                dir = 0;
            }
            if (e.KeyCode == Keys.Right)
            {
                dir = 1;
            }
            if (e.KeyCode == Keys.Down)
            {
                dir = 2;
            }
            if (e.KeyCode == Keys.Left)
            {
                dir = 3;
            }
        }
        public void changeDirection()
        {

        }

        public Point getLocation()
        {
            return p;
        }

        public void paint(PaintEventArgs e)
        {

        }
    }
}

可移动的:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CatAndMouse
{
    public interface Moveable
    {
        void Move(int n);
        void changeDirection();
        //Point getLocation();
        void paint(PaintEventArgs e);
    }
}

所以,我没有任何调用KeyDown()的东西。如果需要KeyEventArgs e?

,如何调用KeyDown()

Picturebox1没有keydown事件,form1没有。我还需要在cat类中使用keydown事件,因此它知道它面向的方向,因此它知道要移动的方向。

这个问题在另一个问题上没有答案。那个告诉我修复keydown事件,在这里我问如何修复keydown事件!

我真的需要帮助绘制图像!

3 个答案:

答案 0 :(得分:1)

您是否有任何理由将Windows窗体用于游戏,而不是使用XNA或其他东西?它会更合适,它会使这项任务变得更容易。

关于问题本身,您需要在移动后调用表单绘制事件,并且要挂钩键盘输入,您应该为表单本身设置一个事件(转到表单视图,单击属性窗口中的闪电,查找KEYDOWN)。利用此事件可以让您获得所需的输出。

引发事件时调用的方法看起来有点像这样:

public void KeyPressed(object sender, KeyPressEventArgs ex)
{
    switch (ex.KeyChar) // Get the value of the key pressed
    {
        case 'a':
            // Do stuff if the pressed key is the letter "a"
        case 'b':
            // Do stuff if the pressed key is the letter "b"
    }
}

答案 1 :(得分:1)

  • @XtrmJosh是对的,XNA更适合这样的任务

  • 你最好在https://gamedev.stackexchange.com/中提出这样的问题,而不是在SO中,这是 关于游戏开发问题的地方

  • 让您的猫在ProcessCmdKey中移动,而不是使用Control.KeyDown来捕获事件,而只有才能抓住 ,如果该控件具有焦点。

代码:

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

    private void Form1_Load(object sender, EventArgs e)
    {
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        // Move your cat here
        return base.ProcessCmdKey(ref msg, keyData);
    }
}
  • 你什么时候在GameManager中连接你的计时器嘀嗒事件?

    private void Form1_Load(object sender, EventArgs e)
    {
        Timer timer = new Timer();
        timer.Tick += timer_Tick;
    }
    
    void timer_Tick(object sender, EventArgs e)
    {
        // Do your thing
    }
    
  • 在同一个刻度事件中,你正在移动东西,但是你没有绘制它们

  • 使用Cat.Move(int n)移动您的猫,Cat.KeyDown 无关,除非Cat是Control(它永远不会被调用)。但是将该逻辑放在ProcessCmdKey中。考虑使用Keys而不是整数。而其他人'如果'应该'否则'如果'。 (请参阅开关,因为它不易出错)

代码:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    // Move your Cat here
    switch (keyData)
    {
        case Keys.Left:
            cat.Move(keyData);
            break;
        case Keys.Right:
            break;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

public class Cat
{
    public void Move(Keys keyData)
    {
        switch (keyData)
        {
            case Keys.Left:
                // act accordingly ...
                break;
            case Keys.Right:
                break;
        }
    }
}

答案 2 :(得分:0)

我认为你的问题是对事件机制的误解。您似乎已为“KeyDown”事件创建了事件处理程序,但未将其附加到事件本身。

您需要将附件代码添加到事件中,如下所示:

Cat cat1 = new Cat();
KeyDown += cat1.cat1_KeyDown;

这可以在form1类的构造函数中完成。

然后,您需要修改Cat类中事件处理程序的参数以匹配事件处理程序签名。 e.g。

public void cat1_KeyDown(object sender, KeyEventArgs e)
{
    // Do the movement logic here....
}