c#控制台蛇卡住了长按键 [英] c# console snake gets stuck on long key press

查看:159
本文介绍了c#控制台蛇卡住了长按键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习编程几个月前,决定做一个控制台蛇游戏。一切工作伟大的希望一件事。



如果我的蛇向上,我按下箭头并保持按下,我的蛇只停止,停止甚至停止后一段时间按下按钮。



同样的事情发生,如果我的蛇向右,我按右箭头太长,我失去控制一段时间(但蛇不停止)。它发生在每一种方式(左,右,上,下)。



我试图比较cki和另一个ConsoleKeyInfo,它们之间有轻微的延迟,但它没有关系。如果我保持按下的键,我的程序只是保持那一点和更新一个键。 (至少我认为这是问题)



这是Console.ReadKey的功能还是有一些方法? / p>

请记住,我刚刚开始,所以我不知道高级的东西。



  public void LiikutaMato()// movesnake 
{

if(Console.KeyAvailable)
{
ConsoleKeyInfo cki;
cki = Console.ReadKey(true); // < - 我相信这是它被卡住的地方

}


解决方案

使用这个...使用一个紧的循环来消耗按键,直到设置的延迟过期。你也不必按住键来保持蛇的移动。它对我的系统响应非常快:

  class Program 
{

public enum Direction
{
Up,
Down,
Right,
Left
}

static void Main(string [] args)
{
const int delay = 75;
string snake =O;
char border ='X';

int x,y;
int length;
bool crashed = false;
Direction curDirection = Direction.Up;
字典< string,bool> eaten = new Dictionary< string,bool>();
Console.CursorVisible = false;

ConsoleKeyInfo cki;
bool quit = false;
while(!quit)
{
Console.Clear();
Console.Title =使用'a','s','d'和'w'来操纵,点击'q'退出。

//在控制台周围绘制边框:
string row = new String(border,Console.WindowWidth);
Console.SetCursorPosition(0,0);
Console.Write(row);
Console.SetCursorPosition(0,Console.WindowHeight - 2);
Console.Write(row);
for(int borderY = 0; borderY< Console.WindowHeight - 2; borderY ++)
{
Console.SetCursorPosition(0,borderY);
Console.Write(border.ToString());
Console.SetCursorPosition(Console.WindowWidth - 1,borderY);
Console.Write(border.ToString());
}

//重置所有游戏变量:
length = 1;
crashed = false;
curDirection = Direction.Up;
eaten.Clear();
x = Console.WindowWidth / 2;
y = Console.WindowHeight / 2;
eaten.Add(x.ToString(00)+ y.ToString(00),true);

//绘制新的蛇:
Console.SetCursorPosition(x,y);
Console.Write(snake);

//等待初始按键:
while(!Console.KeyAvailable)
{
System.Threading.Thread.Sleep(10);
}

//看看是否应改变intitial方向:
cki = Console.ReadKey(true);
switch(cki.KeyChar)
{
case'w':
curDirection = Direction.Up;
break;

case's':
curDirection = Direction.Down;
break;

case'a':
curDirection = Direction.Left;
break;

case'd':
curDirection = Direction.Right;
break;

case'q':
quit = true;
break;
}

//主游戏循环:
DateTime nextCheck = DateTime.Now.AddMilliseconds(delay);
while(!quit&&!crashed)
{
Console.Title =Length:+ length.ToString();

//消耗击键并改变当前方向,直到延迟过期:
// *蛇在延迟之后实际上不会移动!
while(nextCheck> DateTime.Now)
{
if(Console.KeyAvailable)
{
cki = Console.ReadKey(true);
switch(cki.KeyChar)
{
case'w':
curDirection = Direction.Up;
break;

case's':
curDirection = Direction.Down;
break;

case'a':
curDirection = Direction.Left;
break;

case'd':
curDirection = Direction.Right;
break;

case'q':
quit = true;
break;
}
}
}

//如果用户没有退出,尝试移动而不触及边框:
if(!quit)
{
string key =;
switch(curDirection)
{
case Direction.Up:
if(y> 1)
{
y--
}
else
{
crashed = true;
}
break;

case Direction.Down:
if(y< Console.WindowHeight - 3)
{
y ++;
}
else
{
crashed = true;
}
break;

case Direction.Left:
if(x> 1)
{
x--
}
else
{
crashed = true;
}

break;

case Direction.Right:
if(x< Console.WindowWidth - 2)
{
x ++;
}
else
{
crashed = true;
}
break;
}

//如果用户没有敲击边框,看看他们是否击中了蛇
if(!crashed)
{
key = x.ToString(00)+ y.ToString(00);
if(!eaten.ContainsKey(key))
{
length ++;
eaten.Add(key,true);
Console.SetCursorPosition(x,y);
Console.Write(snake);
}
else
{
crashed = true;
}
}

//设置下一个延迟:
nextCheck = DateTime.Now.AddMilliseconds(delay);
}
} //结束主游戏循环

if(crashed)
{
Console.Title =*** Crashed!***长度:+ length.ToString()+命中'q'退出,或'r'重试!

//等待退出或重试:
bool retry = false;
while(!quit&&!retry)
{
if(Console.KeyAvailable)
{
cki = Console.ReadKey(true);
switch(cki.KeyChar)
{
case'q':
quit = true;
break;

case'r':
retry = true;
break;
}
}
}
}

} //结束主程序循环

} // end Main

}


I just started learning programming couple months ago and decided to do a console snake game. Everything works great expect for one thing.

If my snake is going upwards and I press down arrow and keep it pressed, my snake just stops and stays stopped even awhile after I stop pressing the button.

Same thing happens if my snake is going right and I press right arrow too long, I lose control for some time(but snake does not stop). It happens for every way(left,right,up,down).

I tried to compare the cki to another ConsoleKeyInfo with slight delay between them, but it doesn't matter. If I keep the key pressed, my program just stays that spot and updates for a key. (atleast I think thats the problem)

Is this a "feature" of the Console.ReadKey or is there some way arount this?

Keep in mind, that I just started so I don't know about the advanced stuff, yet.

Everything works flawless as long as I don't keep the key pressed more than 1 sec.

   public void LiikutaMato() //movesnake
    {

        if (Console.KeyAvailable)
        {
                ConsoleKeyInfo cki;
                cki = Console.ReadKey(true); // <-- I believe this is where it gets stuck 

    }

解决方案

Play with this...it uses a tight loop to consume the keypresses until the set delay has expired. You also don't have to hold down the key to keep the snake moving. It was very responsive on my system:

class Program
{

    public enum Direction
    {
        Up, 
        Down, 
        Right, 
        Left
    }

    static void Main(string[] args)
    {
        const int delay = 75;
        string snake = "O";
        char border = 'X';

        int x, y;
        int length;
        bool crashed = false;
        Direction curDirection = Direction.Up;
        Dictionary<string, bool> eaten = new Dictionary<string, bool>();
        Console.CursorVisible = false;

        ConsoleKeyInfo cki;
        bool quit = false;
        while (!quit)
        {
            Console.Clear();
            Console.Title = "Use 'a', 's', 'd' and 'w' to steer.  Hit 'q' to quit.";

            // draw border around the console:
            string row = new String(border, Console.WindowWidth);
            Console.SetCursorPosition(0, 0);
            Console.Write(row);
            Console.SetCursorPosition(0, Console.WindowHeight - 2);
            Console.Write(row);
            for (int borderY = 0; borderY < Console.WindowHeight - 2; borderY++)
            {
                Console.SetCursorPosition(0, borderY);
                Console.Write(border.ToString());
                Console.SetCursorPosition(Console.WindowWidth - 1, borderY);
                Console.Write(border.ToString());
            }

            // reset all game variables:
            length = 1;
            crashed = false;
            curDirection = Direction.Up;
            eaten.Clear();
            x = Console.WindowWidth / 2;
            y = Console.WindowHeight / 2;
            eaten.Add(x.ToString("00") + y.ToString("00"), true);

            // draw new snake:
            Console.SetCursorPosition(x, y);
            Console.Write(snake);

            // wait for initial keypress:
            while (!Console.KeyAvailable)
            {
                System.Threading.Thread.Sleep(10);
            }

            // see if intitial direction should be changed:
            cki = Console.ReadKey(true);
            switch (cki.KeyChar)
            {
                case 'w':
                    curDirection = Direction.Up;
                    break;

                case 's':
                    curDirection = Direction.Down;
                    break;

                case 'a':
                    curDirection = Direction.Left;
                    break;

                case 'd':
                    curDirection = Direction.Right;
                    break;

                case 'q':
                    quit = true;
                    break;
            }

            // main game loop:
            DateTime nextCheck = DateTime.Now.AddMilliseconds(delay);
            while (!quit && !crashed)
            {
                Console.Title = "Length: " + length.ToString();

                // consume keystrokes and change current direction until the delay has expired:
                // *The snake won't actually move until after the delay!
                while (nextCheck > DateTime.Now)
                {
                    if (Console.KeyAvailable)
                    {
                        cki = Console.ReadKey(true);
                        switch (cki.KeyChar)
                        {
                            case 'w':
                                curDirection = Direction.Up;
                                break;

                            case 's':
                                curDirection = Direction.Down;
                                break;

                            case 'a':
                                curDirection = Direction.Left;
                                break;

                            case 'd':
                                curDirection = Direction.Right;
                                break;

                            case 'q':
                                quit = true;
                                break;
                        }
                    }
                }

                // if the user didn't quit, attempt to move without hitting the border:
                if (!quit)
                {
                    string key = "";
                    switch (curDirection)
                    {
                        case Direction.Up:
                            if (y > 1)
                            {
                                y--;
                            }
                            else
                            {
                                crashed = true;
                            }
                            break;

                        case Direction.Down:
                            if (y < Console.WindowHeight - 3)
                            {
                                y++;
                            }
                            else
                            {
                                crashed = true;
                            }
                            break;

                        case Direction.Left:
                            if (x > 1)
                            {
                                x--;
                            }
                            else
                            {
                                crashed = true;
                            }

                            break;

                        case Direction.Right:
                            if (x < Console.WindowWidth - 2)
                            {
                                x++;
                            }
                            else
                            {
                                crashed = true;
                            }
                            break;
                    }

                    // if the user didn't hit the border, see if they hit the snake
                    if (!crashed)
                    {
                        key = x.ToString("00") + y.ToString("00");
                        if (!eaten.ContainsKey(key))
                        {
                            length++;
                            eaten.Add(key, true);
                            Console.SetCursorPosition(x, y);
                            Console.Write(snake);
                        }
                        else
                        {
                            crashed = true;
                        }
                    }

                    // set the next delay:
                    nextCheck = DateTime.Now.AddMilliseconds(delay);
                }
            } // end main game loop

            if (crashed)
            {
                Console.Title = "*** Crashed! *** Length: " + length.ToString() + "     Hit 'q' to quit, or 'r' to retry!";

                // wait for quit or retry:
                bool retry = false;
                while (!quit && !retry)
                {
                    if (Console.KeyAvailable)
                    {
                        cki = Console.ReadKey(true);
                        switch (cki.KeyChar)
                        {
                            case 'q':
                                quit = true;
                                break;

                            case 'r':
                                retry = true;
                                break;
                        }
                    }
                }
            } 

        } // end main program loop

    } // end Main()

}

这篇关于c#控制台蛇卡住了长按键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆