控制台程序用键盘操作字符移动的小程序,请高手指点一下啊
小弟才学C++不久,不太会些程序,今天试试写了一个用键盘操作字符移动的小程序,完全控制台的,在VC++6.0下写的,弄了半天,总算可以运行了,但是很多问题,主要是我设置了...
小弟才学C++不久,不太会些程序,今天试试写了一个用键盘操作字符移动的小程序,完全控制台的,在VC++6.0下写的,弄了半天,总算可以运行了,但是很多问题,主要是我设置了一个边框范围,就是长宽各为30米的,就是想移动到边框的时候移不过去,但是实际移动到边框的时候,字符就停在那里了,回不来了,不能动了,想了半天,实在是不知道怎么解决,请高手指点一下啊,下面是代码,小弟才学不久,写的很乱,而且为了省事就用的是面向过程的方法写的,没有用类封装在一个函数里面,所以4段if语句基本是复制粘贴的,请高手看着别嫌烦啊,呵呵,先谢过了~~~~~
代码:
#include<iostream>
#include<windows.h>
using namespace std;
main()
{
int x=4;
int y=4;
HANDLE hand;
hand=GetStdHandle(STD_OUTPUT_HANDLE);
int colour=200;
int len=2;
COORD point;
point.X=x;
point.Y=y;
char *string="■";
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
INPUT_RECORD keyRec;
DWORD res;
HANDLE hnd;
hnd=GetStdHandle(STD_INPUT_HANDLE);
for(;;)
{
ReadConsoleInput(hnd,&keyRec,1,&res);
if(keyRec.EventType==KEY_EVENT)
{
if(keyRec.Event.KeyEvent.wVirtualKeyCode==65)
{
if(point.X<30&&point.X>2&&point.Y>2&&point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,NULL);
WriteConsoleOutputCharacter(hand," ",len,point,NULL);
point.X-=1;
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
}
else point.X+=1;
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==68)
{
if(point.X<30&&point.X>2&&point.Y>2&&point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,NULL);
WriteConsoleOutputCharacter(hand," ",len,point,NULL);
point.X+=1;
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
}
else point.X-=1;
}if(keyRec.Event.KeyEvent.wVirtualKeyCode==87)
{
if(point.X<30&&point.X>2&&point.Y>2&&point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,NULL);
WriteConsoleOutputCharacter(hand," ",len,point,NULL);
point.Y-=1;
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
}
else point.Y+=1;
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==83)
{
if(point.X<30&&point.X>2&&point.Y>2&&point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,NULL);
WriteConsoleOutputCharacter(hand," ",len,point,NULL);
point.Y+=1;
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
}
else point.Y-=1;
}
}
}
}
忘了说了,是按键盘 a s d w ,分别是 左 下 右 上 展开
代码:
#include<iostream>
#include<windows.h>
using namespace std;
main()
{
int x=4;
int y=4;
HANDLE hand;
hand=GetStdHandle(STD_OUTPUT_HANDLE);
int colour=200;
int len=2;
COORD point;
point.X=x;
point.Y=y;
char *string="■";
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
INPUT_RECORD keyRec;
DWORD res;
HANDLE hnd;
hnd=GetStdHandle(STD_INPUT_HANDLE);
for(;;)
{
ReadConsoleInput(hnd,&keyRec,1,&res);
if(keyRec.EventType==KEY_EVENT)
{
if(keyRec.Event.KeyEvent.wVirtualKeyCode==65)
{
if(point.X<30&&point.X>2&&point.Y>2&&point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,NULL);
WriteConsoleOutputCharacter(hand," ",len,point,NULL);
point.X-=1;
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
}
else point.X+=1;
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==68)
{
if(point.X<30&&point.X>2&&point.Y>2&&point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,NULL);
WriteConsoleOutputCharacter(hand," ",len,point,NULL);
point.X+=1;
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
}
else point.X-=1;
}if(keyRec.Event.KeyEvent.wVirtualKeyCode==87)
{
if(point.X<30&&point.X>2&&point.Y>2&&point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,NULL);
WriteConsoleOutputCharacter(hand," ",len,point,NULL);
point.Y-=1;
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
}
else point.Y+=1;
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==83)
{
if(point.X<30&&point.X>2&&point.Y>2&&point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,NULL);
WriteConsoleOutputCharacter(hand," ",len,point,NULL);
point.Y+=1;
FillConsoleOutputAttribute(hand,colour,len,point,NULL);
WriteConsoleOutputCharacter(hand,string,len,point,NULL);
}
else point.Y-=1;
}
}
}
}
忘了说了,是按键盘 a s d w ,分别是 左 下 右 上 展开
1个回答
展开全部
问题一:
其实主要是else语句弄巧成拙了。如果你希望point.X小于等于2的时候方块就不能往左移动了,那对应的当它小于2时,你不做任何处理,他不就停在那里不动了吗?
问题二:
最后要记得用CloseHandle关闭句柄
问题三:
两个函数的最后一个参数用NULL会出错,应该这样用:
DWORD written;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
这种用法参考自:
http://hi.baidu.com/console_app/blog/item/30488bec119a5a4779f055df.html
其实我也看到网上有个教程里就这样用,但是在codeblocks下运行程序会出错,改过来就可以运行了
此外我加了一个输出方块当前位置的语句,你可以看出,由于■在dos窗口上占两个字节的宽度,因此即使你按一下方向键,对应坐标也会变化2个单位。
简单改了一下。我建议还是用函数实现好一点,因为这个程序中类似的代码段重复出现,使程序变得很长。
代码:
#include<iostream>
#include<iomanip>
#include<windows.h>
using namespace std;
int main()
{
int x=4;
int y=4;
HANDLE hand;
hand=GetStdHandle(STD_OUTPUT_HANDLE);
int colour=200;
int len=2;
COORD point;
point.X=x;
point.Y=y;
char *string="■";
SMALL_RECT rt = {0,0,35,35}; // 窗口尺寸
SetConsoleWindowInfo(hand,true,&rt); // 由于DOS默认只有25行,为了便于观察,把dos窗口行数调为35,这个也可以用system函数实现
DWORD written;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
INPUT_RECORD keyRec;
DWORD res;
HANDLE hnd;
hnd=GetStdHandle(STD_INPUT_HANDLE);
for(;;)
{
cout<<setfill('0')<<"("<<setw(2)<<point.X<<","<<setw(2)<<point.Y<<")";
ReadConsoleInput(hnd,&keyRec,1,&res);
if(keyRec.EventType==KEY_EVENT)
{
if(keyRec.Event.KeyEvent.wVirtualKeyCode==65)
{
if(point.X>2) // 这里不用那么麻烦,因为按a时只会使X减小,下同
{
FillConsoleOutputAttribute(hand,1,len,point,&written);
WriteConsoleOutputCharacter(hand," ",len,point,&written);
point.X-=1;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
}
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==68)
{
if(point.X<30)
{
FillConsoleOutputAttribute(hand,1,len,point,&written);
WriteConsoleOutputCharacter(hand," ",len,point,&written);
point.X+=1;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
}
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==87)
{
if(point.Y>2)
{
FillConsoleOutputAttribute(hand,1,len,point,&written);
WriteConsoleOutputCharacter(hand," ",len,point,&written);
point.Y-=1;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
}
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==83)
{
if(point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,&written);
WriteConsoleOutputCharacter(hand," ",len,point,&written);
point.Y+=1;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
}
}
}
cout<<"\b\b\b\b\b\b\b";
}
// 最后记得关闭
CloseHandle(hand);
CloseHandle(hnd);
return 0;
}
其实主要是else语句弄巧成拙了。如果你希望point.X小于等于2的时候方块就不能往左移动了,那对应的当它小于2时,你不做任何处理,他不就停在那里不动了吗?
问题二:
最后要记得用CloseHandle关闭句柄
问题三:
两个函数的最后一个参数用NULL会出错,应该这样用:
DWORD written;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
这种用法参考自:
http://hi.baidu.com/console_app/blog/item/30488bec119a5a4779f055df.html
其实我也看到网上有个教程里就这样用,但是在codeblocks下运行程序会出错,改过来就可以运行了
此外我加了一个输出方块当前位置的语句,你可以看出,由于■在dos窗口上占两个字节的宽度,因此即使你按一下方向键,对应坐标也会变化2个单位。
简单改了一下。我建议还是用函数实现好一点,因为这个程序中类似的代码段重复出现,使程序变得很长。
代码:
#include<iostream>
#include<iomanip>
#include<windows.h>
using namespace std;
int main()
{
int x=4;
int y=4;
HANDLE hand;
hand=GetStdHandle(STD_OUTPUT_HANDLE);
int colour=200;
int len=2;
COORD point;
point.X=x;
point.Y=y;
char *string="■";
SMALL_RECT rt = {0,0,35,35}; // 窗口尺寸
SetConsoleWindowInfo(hand,true,&rt); // 由于DOS默认只有25行,为了便于观察,把dos窗口行数调为35,这个也可以用system函数实现
DWORD written;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
INPUT_RECORD keyRec;
DWORD res;
HANDLE hnd;
hnd=GetStdHandle(STD_INPUT_HANDLE);
for(;;)
{
cout<<setfill('0')<<"("<<setw(2)<<point.X<<","<<setw(2)<<point.Y<<")";
ReadConsoleInput(hnd,&keyRec,1,&res);
if(keyRec.EventType==KEY_EVENT)
{
if(keyRec.Event.KeyEvent.wVirtualKeyCode==65)
{
if(point.X>2) // 这里不用那么麻烦,因为按a时只会使X减小,下同
{
FillConsoleOutputAttribute(hand,1,len,point,&written);
WriteConsoleOutputCharacter(hand," ",len,point,&written);
point.X-=1;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
}
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==68)
{
if(point.X<30)
{
FillConsoleOutputAttribute(hand,1,len,point,&written);
WriteConsoleOutputCharacter(hand," ",len,point,&written);
point.X+=1;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
}
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==87)
{
if(point.Y>2)
{
FillConsoleOutputAttribute(hand,1,len,point,&written);
WriteConsoleOutputCharacter(hand," ",len,point,&written);
point.Y-=1;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
}
}
if(keyRec.Event.KeyEvent.wVirtualKeyCode==83)
{
if(point.Y<30)
{
FillConsoleOutputAttribute(hand,1,len,point,&written);
WriteConsoleOutputCharacter(hand," ",len,point,&written);
point.Y+=1;
FillConsoleOutputAttribute(hand,colour,len,point,&written);
WriteConsoleOutputCharacter(hand,string,len,point,&written);
}
}
}
cout<<"\b\b\b\b\b\b\b";
}
// 最后记得关闭
CloseHandle(hand);
CloseHandle(hnd);
return 0;
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询