📄 snake.c
字号:
//Function :Snake game!//Date :2005-07-20 start//Finish Date :2005-07-21 end#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <minigui/common.h>#include <minigui/minigui.h>#include <minigui/gdi.h>#include <minigui/window.h>#include <minigui/control.h>#include <minigui/mgext.h>#include "snake.h"static HWND hMainWnd = HWND_INVALID;#define SNAKE_STACK 64#define SNAKE_PANEL SNAKE_STACK#define STEP_X 16#define STEP_Y 16#define PANEL_WIDTH 15#define PANEL_HEIGHT 18#define TIME_ID 1000#define MAX_PATH 256#define BT_CLOSE 100static BITMAP bmpSnake,bmpBlock_h,bmpBlock_v,bmpGround,bmpPill,bmpMouse,bmpSnake_h,bmpPanel;static int iCurForward;//当前蛇的前进方向Snake snake[PANEL_WIDTH * PANEL_HEIGHT];//蛇身的栈int head,tail;//蛇身体队列指针int iSnakeLen = 4;int iEatMouse = 0;int iCur_Time = 0;BOOL bHasPill = FALSE;int iSetTime = 30;Panel panel[PANEL_WIDTH][PANEL_HEIGHT];//行走盘大小enum {//定义方向值 LEFT, //向左 RIGHT, //向右 UP, //向上 DOWN //向下 };static BOOL bStartGame = FALSE;//游戏开始标志Snake GetNextStep(Snake,int);void CutSnakeTail();Snake Gethead(){ return snake[head];}//Function :获得下一块的状态//return :GROUND// MOUSE// BLOCK// SNAKE // PILLstatic int GetNextBlockStatus()//问题在这??{ Snake pCur = Gethead(); Snake pnext = GetNextStep(pCur,iCurForward);#if 0 char *tmp; switch(iCurForward) { case LEFT: tmp = "LEFT"; break; case RIGHT: tmp = "RIGHT"; break; case UP: tmp = "UP"; break; case DOWN: tmp = "DOWN"; break; } printf("Current For %s\n",tmp);#endif return pnext.full; }static void EatMouse(){ Snake pCur = Gethead(); Snake pNext = GetNextStep(pCur,iCurForward); panel[pNext.x][pNext.y].full = GROUND;//释放鼠占快 SetNewHead(pNext); iSnakeLen ++; iEatMouse ++; }BOOL IsGround(int x,int y){ if (panel[x][y].full == GROUND)//盘为可用 { int i; for (i = 0; i < PANEL_WIDTH * PANEL_HEIGHT; i++) { if (snake[i].full == SNAKE) { if (!(snake[i].x == x && snake[i].y == y)) return TRUE; } } } return FALSE;}//Function :随机生成老鼠static void CreateMouse(){ //random create a mouse int x,y; do{ x = rand() % PANEL_WIDTH; y = rand() % PANEL_HEIGHT; x = x < 0 ? x*(-1) : x; y = y < 0 ? y*(-1) : y; } while(!IsGround(x,y)); panel[x][y].full = MOUSE; printf("Create Mouse:[%d,%d]\n",x,y);}//Function :吃到消化药蛇身减一static void EatPill(){ Snake pCur = Gethead(); Snake pNext = GetNextStep(pCur,iCurForward); panel[pNext.x][pNext.y].full = GROUND;//释放药片块 SetNewHead(pNext); CutSnakeTail(); CutSnakeTail(); iSnakeLen --; bHasPill = FALSE; }static void InitGame(){ srand(time(NULL)); //填充盘 int x,y; for (x = 0; x < PANEL_WIDTH; x ++) { for (y = 0; y < PANEL_HEIGHT; y++) { if (x == 0 || y == 0) { panel[x][y].full = BLOCK; } else if (x == PANEL_WIDTH -1 || y == PANEL_HEIGHT -1) { panel[x][y].full = BLOCK; } else if (y == PANEL_HEIGHT/3 && ( x >PANEL_WIDTH / 4) && (x < PANEL_WIDTH*3 /4)) { panel[x][y].full = BLOCK; } else if (y == PANEL_HEIGHT*2/3 && ( x >PANEL_WIDTH / 4) && (x < PANEL_WIDTH*3 /4)) { panel[x][y].full = BLOCK; } else { panel[x][y].full = GROUND; } } } //填充蛇 int i; head = 0; tail = 3; for (i = 0; i < PANEL_WIDTH * PANEL_HEIGHT; i++) { snake[i].x = 10+i;//蛇头的位置 snake[i].y = PANEL_HEIGHT - 2; if (i < tail + 1) snake[i].full = SNAKE; else snake[i].full = GROUND; } //生成鼠4 for (i = 0; i < 4; i++) CreateMouse(); }//Function :获得蛇头的下一个位置//Param :param1--当前蛇头位置// param2--当前蛇前进方向//return :蛇头下一个位置Snake GetNextStep(Snake pCur,int forward){ Snake tmp; tmp = pCur; switch(forward) { case LEFT: tmp.x --; break; case RIGHT: tmp.x ++; break; case UP: tmp.y --; break; case DOWN: tmp.y ++; break; default: break; } //检查下一个是否是蛇身 int i; for (i = 0; i < PANEL_WIDTH * PANEL_HEIGHT; i++) { if (snake[i].full == SNAKE) { if (snake[i].x == tmp.x && snake[i].y == tmp.y) { tmp.full = SNAKE; return tmp; } } } tmp.full = panel[tmp.x][tmp.y].full; //获得前一块的状态值 return tmp;}//Function :增加一节蛇头void SetNewHead(Snake newHead){ newHead.full = SNAKE; if (head -1 >= 0) { snake[head-1] = newHead; head --; } else { head = head -1 + PANEL_WIDTH * PANEL_HEIGHT;//如果下溢,将蛇头放于数组尾 snake[head] = newHead; }}//Function :去掉一节蛇尾void CutSnakeTail(){ snake[tail].full = GROUND;//去掉原蛇尾 if (tail -1 >= 0) { tail --; } else { tail = tail -1 + PANEL_WIDTH * PANEL_HEIGHT;//如果下溢,将蛇尾放于数组尾 }}//Function :蛇向前前进一步//Param :当前蛇的前进方向static void Forward(int forward){ Snake pCur = Gethead(); Snake pNext = GetNextStep(pCur,iCurForward); SetNewHead(pNext); CutSnakeTail(); }//Function :蛇向左转//Param :当前蛇的前进方向static void TurnLeft(int forward){ switch(forward) { case RIGHT: return;//方向返向不处理 break; case LEFT: //Forward(LEFT); //同向加快行走 break; case UP: case DOWN: iCurForward = LEFT; //Forward(LEFT); break; default: break; }}static void TurnRight(int forward){ switch(forward) { case RIGHT: //Forward(RIGHT); break; case LEFT: return; break; case UP: case DOWN: iCurForward = RIGHT; //Forward(RIGHT); break; default: break; }}static void TurnUp(int forward){ switch(forward) { case UP: //Forward(UP); break; case DOWN: return; case LEFT: case RIGHT: iCurForward = UP; //Forward(UP); break; default: break; }}static void TurnDown(int forward){ switch(forward) { case UP: return; break; case DOWN: //Forward(DOWN); break; case RIGHT: case LEFT: iCurForward = DOWN; //Forward(DOWN); break; default: break; } }static void DrawMyBitmap(HDC hdc, PBITMAP bmp, int x, int y, int w, int h){ if (bmp) FillBoxWithBitmap(hdc,x,y,w,h,bmp); else TextOut(hdc,x,y,"a");}static int myLoadBitmap (BITMAP *bm, const char* filename){ char full_path[MAX_PATH +1]; strcpy(full_path, "res/"); strcat(full_path,filename); return LoadBitmap(HDC_SCREEN,bm,full_path);}static void DrawSnake(HDC hdc){ int i; for (i = 0; i< PANEL_WIDTH * PANEL_HEIGHT; i++) { if (snake[i].full == SNAKE) { DrawMyBitmap(hdc,&bmpSnake,snake[i].x * STEP_X,snake[i].y * STEP_Y,STEP_X,STEP_Y); //TextOut(hdc,snake[i].x * STEP_X,snake[i].y * STEP_Y,"O"); } } DrawMyBitmap(hdc,&bmpSnake_h,snake[head].x *STEP_X,snake[head].y * STEP_Y,STEP_X,STEP_Y);}static void DrawPanel(HDC hdc){ int x,y; for(x = 0; x < PANEL_WIDTH ; x ++) { for(y = 0; y < PANEL_HEIGHT; y ++) { //char *tmp; PBITMAP bmp; switch(panel[x][y].full) { case GROUND: //tmp = " ";//full ground bmp = &bmpGround; break; case SNAKE: //tmp = "O";//full snake bmp = &bmpSnake; break; case MOUSE: //tmp = "M";//full mouse bmp = &bmpMouse; break; case BLOCK: //tmp = "B";//full block if (x == 0 || x == PANEL_WIDTH -1) bmp = &bmpBlock_h; else bmp = &bmpBlock_v; break; case PILL: //tmp = "P"; bmp = &bmpPill; break; default: break; } //TextOut(hdc,x*STEP_X,y*STEP_Y,tmp); DrawMyBitmap(hdc,bmp,x*STEP_X,y*STEP_Y,STEP_X,STEP_Y); } } DrawMyBitmap(hdc,&bmpPanel,0,288,240,32);//Draw the bottom panel} static void CreatePill(){ int x,y; do{ x = rand() % PANEL_WIDTH; y = rand() % PANEL_HEIGHT; x = x < 0 ? x*(-1) : x; y = y < 0 ? y*(-1) : y; } while(!IsGround(x,y)); panel[x][y].full = PILL; }static void StartGame(HWND hWnd){ static BOOL bFirstStart = 1; if (bFirstStart) { bStartGame = TRUE; iCurForward = LEFT; SetTimer(hWnd,TIME_ID,iSetTime); bFirstStart = 0; } else{ MessageBox(hWnd,"请选择重新开始游戏!","tip",MB_OK); } }static void RestartGame(HWND hWnd){ if (bStartGame) { KillTimer(hWnd,TIME_ID); if (MessageBox(hWnd,"游戏未结束!\n是否重新开始?","tip",1) == IDOK) { InitGame(); bStartGame = TRUE; iCurForward = LEFT; bHasPill = FALSE; iCur_Time = 0; iEatMouse = 0; SetTimer(hWnd,TIME_ID,iSetTime); } else { SetTimer(hWnd,TIME_ID,iSetTime); } } else { InitGame(); bStartGame = TRUE; iCurForward = LEFT; bHasPill = FALSE; iCur_Time = 0; iEatMouse = 0; SetTimer(hWnd,TIME_ID,iSetTime); }}static void GoToNextStage(HWND hWnd){ char *sTmp; int iTmp; BOOL bFlag = FALSE; switch (iEatMouse)//每吃50个鼠进入下一关 { case 20: sTmp = "进入第二关!"; iTmp = 5; bFlag = TRUE; break; case 40: sTmp = "进入第三关!"; iTmp = 10; bFlag = TRUE; break; case 60: sTmp = "进入第四关!"; iTmp = 15; bFlag = TRUE; break; case 80: sTmp = "进入第五关!"; iTmp = 20; bFlag = TRUE; break; } if (bFlag) { KillTimer(hWnd,TIME_ID); MessageBox(hWnd,sTmp,"tip",MB_OK | MB_ICONINFORMATION); { InitGame(); iCurForward = LEFT; bHasPill = FALSE; iCur_Time = 0; } SetTimer(hWnd,TIME_ID,iSetTime - iTmp); }}static int ControlTestWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam){ HDC hdc; switch (message) { case MSG_CREATE: { if (myLoadBitmap(&bmpPanel,"panel.bmp") < 0) fprintf(stderr,"panel.bmp error!\n"); if (myLoadBitmap(&bmpSnake,"snake.bmp") < 0) fprintf(stderr,"snake.bmp error!\n"); if (myLoadBitmap(&bmpBlock_v,"block_v.bmp") < 0) fprintf(stderr,"load block_v.bmp error\n"); if (myLoadBitmap(&bmpBlock_h,"block_h.bmp") < 0) fprintf(stderr,"load block_h.bmp error\n"); if (myLoadBitmap(&bmpGround,"ground.bmp") < 0) fprintf(stderr,"load ground.bmp error\n"); if (myLoadBitmap(&bmpPill,"pill.bmp") < 0) fprintf(stderr,"load pill.bmp error\n"); if (myLoadBitmap(&bmpMouse,"mouse.bmp") < 0) fprintf(stderr,"load mouse.bmp error\n"); if (myLoadBitmap(&bmpSnake_h,"snake_h.bmp") < 0); fprintf(stderr,"load snake_h.bmp error\n"); InitGame(); } break; case MSG_TIMER: { if (bStartGame) { // printf("The fore block status :%d\n",flag);// printf("The snake len:%d\n",iSnakeLen); iCur_Time ++; if (iCur_Time > 40)//规定时间范围产生药片 { if (iSnakeLen > 4 && (!bHasPill)) { CreatePill(); bHasPill = TRUE; iCur_Time = 0; } } int flag = GetNextBlockStatus(); switch(flag) { case GROUND: Forward(iCurForward); printf("Forward\n"); break; case MOUSE: EatMouse(); CreateMouse(); GoToNextStage(hWnd);//查看进入下一关 printf("Eat mouse\n"); break; case BLOCK: //goto dead bStartGame = FALSE; Forward(iCurForward); //Draw the finish next break; case SNAKE: bStartGame = FALSE; Forward(iCurForward); //goto dead break; case PILL: EatPill(); iCur_Time = 0; printf("Eat pill\n"); default: break; } //Forward(iCurForward); SendMessage(hWnd,MSG_PAINT,0,0); } else { KillTimer(hWnd,TIME_ID); MessageBox(hWnd,"Game Over!","tip",MB_OK | MB_ICONINFORMATION); } } break; case MSG_LBUTTONUP: { int x = LOWORD(lParam);//获得鼠标的坐标 int y = HIWORD(lParam); if (x >181 && x <229 && y >293 && y < 312)//close window { KillTimer(hWnd,TIME_ID); if (bStartGame) { if (MessageBox(hWnd,"游戏未结束!\n是否退出?","tip",1|MB_ICONINFORMATION) == IDOK) { SendMessage(hWnd,MSG_CLOSE,0,0); } else { SetTimer(hWnd,TIME_ID,iSetTime); } } else { if (MessageBox(hWnd,"是否退出?","tip",1) == IDOK) { SendMessage(hWnd,MSG_CLOSE,0,0); } } } if (x > 14 && x <61 && y > 293 && y < 316)//start Game { StartGame(hWnd); } if (x > 72 && x < 87 && y > 295 && y < 307)//restart Game { RestartGame(hWnd); } printf("The [x,y]=[%d,%d]\n",x,y); } break; case MSG_KEYDOWN: { int iKey = LOWORD(wParam); switch(iKey) { case SCANCODE_F2://Game restart { RestartGame(hWnd); } break; case SCANCODE_F1://Game Start { StartGame(hWnd); } break; case SCANCODE_CURSORBLOCKUP://Turn Up { TurnUp(iCurForward); } break; case SCANCODE_CURSORBLOCKDOWN://Turn Down { TurnDown(iCurForward); } break; case SCANCODE_CURSORBLOCKLEFT://Turn Left { TurnLeft(iCurForward); } break; case SCANCODE_CURSORBLOCKRIGHT://Turn Right { TurnRight(iCurForward); } break; default: break; } } case MSG_PAINT: { char ch[20]; hdc = BeginPaint(hWnd); //TextOut(hdc,100,100,"fdsa"); DrawPanel(hdc); DrawSnake(hdc); sprintf(ch,"%d",iEatMouse); TextOut(hdc,136,295,ch);//Show the Score EndPaint(hWnd,hdc); } case MSG_COMMAND: { } break; case MSG_DESTROY: DestroyAllControls (hWnd); hMainWnd = HWND_INVALID; return 0; case MSG_CLOSE: UnloadBitmap(&bmpGround); UnloadBitmap(&bmpMouse); UnloadBitmap(&bmpBlock_v); UnloadBitmap(&bmpBlock_h); UnloadBitmap(&bmpPill); UnloadBitmap(&bmpSnake); UnloadBitmap(&bmpSnake_h); UnloadBitmap(&bmpPanel); KillTimer(hWnd,TIME_ID); DestroyMainWindow (hWnd); MainWindowCleanup (hWnd); return 0; } return DefaultMainWinProc(hWnd, message, wParam, lParam);}static void InitCreateInfo(PMAINWINCREATE pCreateInfo){ pCreateInfo->dwStyle = WS_VISIBLE; // WS_CAPTION | WS_BORDER | pCreateInfo->dwExStyle = WS_EX_NONE; pCreateInfo->spCaption = "about"; pCreateInfo->hMenu = 0; pCreateInfo->hCursor = GetSystemCursor(0); pCreateInfo->hIcon = 0; pCreateInfo->MainWindowProc = ControlTestWinProc; pCreateInfo->lx = 0; pCreateInfo->ty = 0; pCreateInfo->rx = 240; pCreateInfo->by = 320; pCreateInfo->iBkColor = GetWindowElementColor (BKC_CONTROL_DEF); pCreateInfo->dwAddData = 0; pCreateInfo->hHosting = HWND_DESKTOP;}void show_snake(HWND hwnd){ MAINWINCREATE CreateInfo; if (hMainWnd != HWND_INVALID) { ShowWindow (hMainWnd, SW_SHOWNORMAL); return; } InitCreateInfo (&CreateInfo); CreateInfo.hHosting = hwnd; hMainWnd = CreateMainWindow (&CreateInfo);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -