用MFC做的貪吃蛇遊戲,求大神。?
用MFC實現了簡單的貪吃蛇遊戲,採用的CFromView基類,方便添加控制項,但我添加任意控制項了之後,在運行遊戲的時候,方向鍵就不管用了,不能控制蛇的爬行方向,是怎麼回事啊?
void CSnakeView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
///////////////獲取按鍵方向//////////////////////
switch(nChar)
{
case VK_UP:if(snake[0].r!=2)snake[0].r=1;break;
case VK_DOWN:if(snake[0].r!=1)snake[0].r=2;break;
case VK_LEFT:if(snake[0].r!=4)snake[0].r=3;break;
case VK_RIGHT:if(snake[0].r!=3)snake[0].r=4;break;
}
CFormView::OnKeyDown(nChar, nRepCnt, nFlags);
}
這是獲取方向鍵的代碼
void CSnakeView::OnDraw(CDC* pDC){
// TODO: Add your specialized code here and/or call the base class CBrush backBrush(RGB(255,255,255));CBrush* pOldBrush = pDC-&>SelectObject(backBrush);
CRect rect; pDC-&>GetClipBox(rect);// 獲取需要用背景刷子塗抹的區域 pDC-&>PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),PATCOPY); pDC-&>SelectObject(pOldBrush);CSnakeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc); pDC-&>Rectangle(19,19,501,501); pDC-&>Rectangle(29,29,491,491); pDC-&>Rectangle(39,39,481,481);oninit();
}這是通過OnDraw()實現的背景
首先是CFormView吧?
其次。。。你這個問題。。。
不貼代碼你以為有人能回答的出來?答得出來的都是騙子,或者是猜中了。。。。這種小遊戲感覺還是直接用控制台比較合適,我也真是無聊呀
#include&
#include&
#include&
using namespace std;
HANDLE hOut;
HANDLE hIn;
unsigned long num_write;
int maxHeight=20;
int maxWidth=20;
void clearScreen()
{
CONSOLE_SCREEN_BUFFER_INFO bInfo;
GetConsoleScreenBufferInfo( hOut, bInfo );
COORD home = {0, 0};
unsigned long size =bInfo.dwSize.X * bInfo.dwSize.Y;
FillConsoleOutputAttribute(hOut, bInfo.wAttributes, size, home, num_write);
FillConsoleOutputCharacter(hOut, " ", size, home, num_write);
SetConsoleCursorPosition( hOut, home );
};
void DrawBox(int x,int y,bool isFood=false,bool background=false)
{
CONSOLE_SCREEN_BUFFER_INFO bInfo; // 窗口緩衝區信息
WORD att0,att1,attBack;
int i;
GetConsoleScreenBufferInfo( hOut, bInfo ); // 獲取窗口緩衝區信息
// 計算顯示窗口大小和位置
att0 = FOREGROUND_GREEN| BACKGROUND_RED; // 陰影屬性
att1 = FOREGROUND_RED |FOREGROUND_GREEN |FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE;// 文本屬性
attBack = BACKGROUND_INTENSITY | FOREGROUND_INTENSITY; // 文本屬性
COORD posText = {x, y};
if(!background)
FillConsoleOutputAttribute(hOut, isFood?att0:att1,1, posText, num_write);
else
{
COORD bg={0,0};
FillConsoleOutputAttribute(hOut, attBack,bInfo.dwSize.X*maxHeight, bg, num_write);
}
SetConsoleTextAttribute(hOut, bInfo.wAttributes);
};
struct SnakeNode
{
int XPos,YPos;
SnakeNode* next;
SnakeNode(int x,int y,SnakeNode*n=NULL)
:XPos(x),YPos(y),next(n)
{
}
};
SnakeNode* Head,*Food;
int DirX=1;
int DirY=0;
int StartPosX=0;
int StartPosY=0;
/*
area: ?X?
*/
void ShowSnake(SnakeNode* head)
{
DrawBox(0,0,false,true);
SnakeNode* ptr=head;
while(ptr)
{
DrawBox(ptr-&>XPos,ptr-&>YPos);
ptr=ptr-&>next;
}
}
bool UpdateSnake(SnakeNode*Head)
{
DWORD wait = 200;
Sleep(wait);
clearScreen();
INPUT_RECORD _InRec;
WORD vKey=0;
//while(true)
//{
if(PeekConsoleInput(hIn,_InRec,1,num_write))
{
vKey=_InRec.Event.KeyEvent.wVirtualKeyCode;
if(_InRec.EventType == KEY_EVENT)
{
if(vKey==37)//left
{
DirX=-1;
DirY=0;
}
else if(vKey==39)//right
{
DirX=1;
DirY=0;
}
else if(vKey==38)//up
{
DirX=0;
DirY=-1;
}
else if(vKey==40)//down
{
DirX=0;
DirY=1;
}
}
};
FlushConsoleInputBuffer(hIn);
//}
int lastX=0;
int lastY=0;
SnakeNode* ptr=Head;
if(Head-&>XPos+DirX==Food-&>XPosHead-&>YPos+DirY==Food-&>YPos)
{
//add this node
SnakeNode* oldHead=new SnakeNode(Head-&>XPos,Head-&>YPos,Head-&>next);
Head-&>XPos=Food-&>XPos;
Head-&>YPos=Food-&>YPos;
Head-&>next=oldHead;
delete Food;
Food=new SnakeNode((rand()%20)*2,(rand()%maxHeight),0);
}
else
{
while(ptr)
{
if(ptr==Head)
{
lastX=ptr-&>XPos;
lastY = ptr-&>YPos;
ptr-&>XPos+=DirX;
ptr-&>YPos+=DirY;
}
else
{
int tmp=ptr-&>XPos;
ptr-&>XPos=lastX;
lastX=tmp;
tmp=ptr-&>YPos;
ptr-&>YPos=lastY;
lastY=tmp;
}
ptr=ptr-&>next;
}
}
//check boundary
CONSOLE_SCREEN_BUFFER_INFO bInfo;
GetConsoleScreenBufferInfo( hOut, bInfo );
if(Head-&>XPos&<0||Head-&>XPos&>=bInfo.dwSize.X||
Head-&>YPos&<0||Head-&>YPos&>=maxHeight)
{
cout&<&<"Thanks for playing
created by kalluwa!";
return false;
}
ShowSnake(Head);
DrawBox(Food-&>XPos,Food-&>YPos,true);
return true;
}
int main(int argc, char** argv)
{
hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 獲取標準輸出設備句柄
hIn = GetStdHandle(STD_INPUT_HANDLE);
//create snake
Head=new SnakeNode(2,1,0);
Head-&>next=new SnakeNode(1,1,0);
Food = new SnakeNode(10,10,0);
while(UpdateSnake(Head));
return 0;
}
OnKeyDown只有在焦點才能獲得事件所以你加一個控制項,把焦點搶了,自然就拿不到了參看MSDN
A nonsystem key is a keyboard key that is pressed when the ALT key is not pressed or a keyboard key that is pressed when CWnd has the input focus.
Because of auto-repeat, more than one OnKeyDown call may occur before an OnKeyUp member function call is made. The bit that indicates the previous key state can be used to determine whether the OnKeyDown call is the first down transition or a repeated down transition.
For
IBM Enhanced 101- and 102-key keyboards, enhanced keys are the right
ALT and the right CTRL keys on the main section of the keyboard; the
INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters
to the left of the numeric keypad; and the slash (/) and ENTER keys in
the numeric keypad. Some other keyboards may support the extended-key bit in nFlags.
其實我想說用mfc做貪吃蛇有多想不開……
應該是焦點的問題,窗口初始化時將焦點設置到整個窗口可以。不過感覺如果點擊控制項焦點還是會變,建議搜索下其他截獲鍵盤的功能,如鉤子.
推薦閱讀:
※C++ primer 第四版這段關於vector的程序是否有未定義的行為?
※c/c++中簡單加法出現奇怪的錯誤?
※如何使用C++11實現跨平台的定時器timer?
※在 Windows 上不用 Win32 API 可以繪製出一個窗口么?
※我用的是visual studio 2010 c語言為什麼學了好長時間還是控制台程序和dos窗口啊?