Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我能';使用keydown事件无法移动我的图像_C#_Windows_Winforms_2d_Picturebox - Fatal编程技术网

C# 我能';使用keydown事件无法移动我的图像

C# 我能';使用keydown事件无法移动我的图像,c#,windows,winforms,2d,picturebox,C#,Windows,Winforms,2d,Picturebox,我正在制作一个2d自上而下的游戏,玩家控制一只猫。为此,用户使用WASD键进行移动。我有Form1、GameManager、Cat和Moveable类。Form1向GameManager发送cat图像列表和e.graphics(用于picturebox)。GameManager有一个计时器,每个刻度都会检查猫是否移动。Cat处理移动逻辑。当我运行程序时,cat精灵显示在其初始位置,但按下键后不会移动。我想不出我的问题,有人能帮忙吗 以下是我的课程: 表格1: using System; usin

我正在制作一个2d自上而下的游戏,玩家控制一只猫。为此,用户使用WASD键进行移动。我有Form1、GameManager、Cat和Moveable类。Form1向GameManager发送cat图像列表和e.graphics(用于picturebox)。GameManager有一个计时器,每个刻度都会检查猫是否移动。Cat处理移动逻辑。当我运行程序时,cat精灵显示在其初始位置,但按下键后不会移动。我想不出我的问题,有人能帮忙吗

以下是我的课程:

表格1:

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
{
    public interface Moveable
    {
        void Move(int n);
        void changeDirection();
        //Point getLocation();
        void paint(PaintEventArgs e);
    }
}
所以,我没有任何调用KeyDown()的内容。如果需要KeyEventArgs,如何调用KeyDown()

Picturebox1没有键控事件,form1有。我还需要在cat类中使用keydown事件,以便它知道它所面对的方向,从而知道移动的方向

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


我真的需要你帮我画这幅画

与使用XNA或其他东西相比,您使用Windows窗体进行游戏有什么原因吗?这会更合适,而且会使这项任务更容易

关于问题本身,您需要在移动后调用forms paint事件,要钩住键盘输入,您应该有一个表单本身的事件(转到表单视图,单击属性窗口中的闪电,查找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"
    }
}
  • @XtrmJosh是对的,XNA更适合这样的任务

  • 你最好在游戏中问这样的问题,而不是在游戏中问这样的问题,这是游戏开发问题的所在

  • 取而代之的是,让您的猫移入,事件将始终被捕获,而不是使用
    控件。按下键
    ,如果该控件具有焦点,则只捕获事件

代码:

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);
    }
}
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;
        }
    }
}
  • 你什么时候在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
    不相关的。但将该逻辑放在ProcessCmdKey中。考虑使用<代码>键<代码>而不是一个整数。其他的“如果”应该是“如果”。(请参见开关,因为它不太容易出错)

代码:

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);
    }
}
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;
        }
    }
}

我认为你的问题是对事件机制的误解。您似乎为“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....
}

这个问题你已经有了2个答案。我将此标记为一个副本。@Brian它看起来确实像另一个问题“它为什么不移动”,而不是“我如何识别键盘事件?”我必须按照老师的指示使用windows窗体进行游戏。如果我在form1中使用keydown事件,我将如何获得cat的运行方向?将有一些事件参数传递到方法中,该方法在事件发生时被调用,我相信它们是KeydownEventArgs,它们将包含一个存储按下字符的变量。我将很快更新答案,提供关于私有void Form1_KeyDown(对象发送者,KeyEventArgs e){if(e.KeyCode==Keys.Up){dir=0;}if(e.KeyCode==Keys.Right){dir=1;}if(e.KeyCode==Keys.Right)的更多信息(e.KeyCode==Keys.Down){dir=2;}如果(e.KeyCode==Keys.Left){dir=3;}也可以,但是如果您想要有多个控件(例如,一个按钮打开库存,一个按钮重新启动,或者一个按钮执行任何其他操作)你可能会想使用switch语句,因为它们更容易阅读,也更适合多个选项。关于焦点的有效点在那里,但如果游戏不包含按钮和框等,我想我的方法会起作用。正输入,+'d。对于OPs参考,焦点意味着如果你点击一个按钮,那么该按钮就会成为焦点。这意味着您通常会传递给表单的事件(例如按键事件)将被发送到button对象,而不是表单对象。结果是该事件不会针对表单引发,因此使用我的方法,您需要为表单上的每个控件创建事件,以防它被选中。此外,尝试不太为OP辩护,但哦,他正在使用的代码与游戏开发没有太大关系,所以我觉得他在这里得到回应的机会比在游戏开发方面要大得多。主要是因为他们几乎只会说我们暗示的话(使用XNA)是的,我同意你:-)实际上,keydown事件似乎也直接链接到cat对象,这意味着除非cat继承自一个基于GUI的对象(我想,至少!),否则就不可能调用它。我的错误。好吧,我有了cat cat1=new cat();和keydown+=cat1.cat1keydown;公共格式1()我用按键代码进行了cat1_按键。但是没有任何移动!您是否更新了GameManager中的“画图”以使用cat1的位置?我有g.DrawImage(imgCat.Images[0],ca1.getLocation());