我尝试在C# Visual Studio中创建一个简单的snake游戏作为练习。我对Windows窗体应用程序知之甚少,但它似乎是使用箭头访问绘图和用户输入的最简单方法。
这是一个很好的框架,用于一个简单的游戏,像这样的C#?
但这是我真实的的问题。我试图创建一个游戏循环,它每秒循环一次,并改变下一次要画蛇头的位置。但我不知道如何多次调用Paint事件。它似乎调用了一次,然后退出。如果我在()在paint方法内部循环,它每秒绘制一个矩形,但我无法访问KeyEventArgs或其他任何内容,因为正在运行的代码被困在Paint调用内部。
我希望初始的paint调用绘制蛇的起始点,然后循环paint调用,我猜是另一个paint方法(?),它询问控制器最后按下的是哪个按钮,然后在那个方向绘制下一个矩形。* 完成此操作并创建游戏循环的预期方式是什么?*
我将感谢任何信息和知识,以帮助教我这个过程,任何其他的建议或投入是欢迎的!
下面是我目前的代码:'''
public partial class FormMain : Form
{
private readonly int pixelSize;
private readonly int gridSize;
private readonly int center;
private string currDirection;
public FormMain()
{
pixelSize = 30;
currDirection = "right";
// Calculating size of the grid based on the size of the 'pixel'
gridSize = 640 / pixelSize;
// Calculating the starting position of the snake in the center of the screen
center = (gridSize / 2) * pixelSize;
InitializeComponent();
}
private void FormMain_Paint(object sender, PaintEventArgs e)
{
// referencing the Graphics object and setting the color of the snake
Graphics g = e.Graphics;
Pen seaPen = new Pen(Color.MediumSeaGreen);
// This draws the initial center rectangle
Point currentHeadLocation = new Point(center, center);
Rectangle r;
// Here's the loop that should happen every second or so, probably in another method.
while (true)
{
r = new Rectangle(currentHeadLocation, new Size(pixelSize, pixelSize));
g.DrawRectangle(seaPen, r);
if (currDirection.Equals("right"))
{
currentHeadLocation = new Point(currentHeadLocation.X + pixelSize, currentHeadLocation.Y);
}
else if (currDirection.Equals("left"))
{
currentHeadLocation = new Point(currentHeadLocation.X - pixelSize, currentHeadLocation.Y);
}
else if (currDirection.Equals("up"))
{
currentHeadLocation = new Point(currentHeadLocation.X, currentHeadLocation.Y - pixelSize);
}
else if (currDirection.Equals("down"))
{
currentHeadLocation = new Point(currentHeadLocation.X, currentHeadLocation.Y + pixelSize);
}
Thread.Sleep(1000);
}
}
private void FormMain_KeyDown(object sender, KeyEventArgs e)
{
switch(e.KeyCode)
{
case Keys.Left:
currDirection = "left";
break;
case Keys.Right:
currDirection = "right";
break;
case Keys.Up:
currDirection = "up";
break;
case Keys.Down:
currDirection = "down";
break;
}
}
}
'''
1条答案
按热度按时间v64noz0r1#
在这种情况下使用Thread.Sleep()几乎总是一个坏主意,因为它会冻结您唯一的线程,也就是UI线程。
您可能希望使用timer。
快速示例:
如果您要胁迫控件重新绘制,只要呼叫
Invalidate()
即可。