我正在制作一款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事件!
我真的需要帮助绘制图像!
答案 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....
}