0

I am making a 2d top-down game where the player controls a cat. To do this, the person uses the WASD keys to move. I have Form1, GameManager, Cat, and Moveable classes. Form1 sends GameManager the cat imagelist and e.graphics (for the picturebox). GameManager has a timer and each tick checks to see if the cat has moved. Cat handles the move logic. When I run the program, the cat sprite shows up at its initial position, but does not move upon pressing a key. I can't figure out my issue, could somebody please help?

Here are my classes:

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

GameManager:

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

Cat:

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)
        {

        }
    }
}

Moveable:

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

So, I don't have anything calling KeyDown(). How do I make something call KeyDown() if it needs KeyEventArgs e?

Picturebox1 does not have a keydown event, form1 does. I also need to use the keydown event in the cat class so it knows what direction it is facing, so it knows what direction to move.

This question DOES NOT have an answer in the other question. That one tells me to fix the keydown event, here I am ask HOW to fix the keydown event!

I REALLY NEED HELP WITH PAINTING THE IMAGE!

4

3 回答 3

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"
    }
}
于 2013-10-07T22:08:53.480 回答
1
  • @XtrmJosh 是对的,XNA 更适合这样的任务

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

  • 相反,让您的猫在ProcessCmdKey中移动,事件将始终被捕获,而不是当该控件具有焦点时才使用Control.KeyDownwhich 捕获它们。

代码 :

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 是 a (它永远不会被调用) ,否则它Cat.KeyDown无关紧要的。Control但是把这个逻辑放在 ProcessCmdKey 中。考虑使用Keys而不是整数。而其他的'if'应该是'else if'。(请参阅 switch,因为它不太容易出错)

代码 :

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;
        }
    }
}
于 2013-10-07T22:17:14.963 回答
0

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

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

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

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

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

public void cat1_KeyDown(object sender, KeyEventArgs e)
{
    // Do the movement logic here....
}
于 2013-10-07T22:22:20.010 回答