您的位置首页生活百科

求一个用C语言编写的小游戏代码

求一个用C语言编写的小游戏代码

的有关信息介绍如下:

求一个用C语言编写的小游戏代码

#include #include #include /////////////////////////////////////////////// 定义常量、枚举量、结构体、全局变量/////////////////////////////////////////////#define WIDTH 10 // 游戏区宽度#define HEIGHT 22 // 游戏区高度#define SIZE 20 // 每个游戏区单位的实际像素// 定义操作类型enum CMD{ CMD_ROTATE, // 方块旋转 CMD_LEFT, CMD_RIGHT, CMD_DOWN, // 方块左、右、下移动 CMD_SINK, // 方块沉底 CMD_QUIT // 退出游戏};// 定义绘制方块的方法enum DRAW{ SHOW, // 显示方块 HIDE, // 隐藏方块 FIX // 固定方块};// 定义七种俄罗斯方块struct BLOCK{ WORD dir[4]; // 方块的四个旋转状态 COLORREF color; // 方块的颜色} g_Blocks[7] = { {0x0F00, 0x4444, 0x0F00, 0x4444, RED}, // I {0x0660, 0x0660, 0x0660, 0x0660, BLUE}, // 口 {0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA}, // L {0x2260, 0x0E20, 0x0644, 0x0470, YELLOW}, // 反L {0x0C60, 0x2640, 0x0C60, 0x2640, CYAN}, // Z {0x0360, 0x4620, 0x0360, 0x4620, GREEN}, // 反Z {0x4E00, 0x4C40, 0x0E40, 0x4640, BROWN}}; // T// 定义当前方块、下一个方块的信息struct BLOCKINFO{ byte id; // 方块 ID char x, y; // 方块在游戏区中的坐标 byte dir:2; // 方向} g_CurBlock, g_NextBlock;// 定义游戏区BYTE g_World[WIDTH][HEIGHT] = {0};/////////////////////////////////////////////// 函数声明/////////////////////////////////////////////void Init(); // 初始化游戏void Quit(); // 退出游戏void NewGame(); // 开始新游戏void GameOver(); // 结束游戏CMD GetCmd(); // 获取控制命令void DispatchCmd(CMD _cmd); // 分发控制命令void NewBlock(); // 生成新的方块bool CheckBlock(BLOCKINFO _block); // 检测指定方块是否可以放下void DrawBlock(BLOCKINFO _block, DRAW _draw = SHOW); // 画方块void OnRotate(); // 旋转方块void OnLeft(); // 左移方块void OnRight(); // 右移方块void OnDown(); // 下移方块void OnSink(); // 沉底方块/////////////////////////////////////////////// 函数定义/////////////////////////////////////////////// 主函数void main(){ Init(); CMD c; while(true) { c = GetCmd(); DispatchCmd(c); // 按退出时,显示对话框咨询用户是否退出 if (c == CMD_QUIT) { HWND wnd = GetHWnd(); if (MessageBox(wnd, _T("您要退出游戏吗?"), _T("提醒"), MB_OKCANCEL | MB_ICONQUESTION) == IDOK) Quit(); } }}// 初始化游戏void Init(){ initgraph(640, 480); srand((unsigned)time(NULL)); // 显示操作说明 setfont(14, 0, _T("宋体")); outtextxy(20, 330, _T("操作说明")); outtextxy(20, 350, _T("上:旋转")); outtextxy(20, 370, _T("左:左移")); outtextxy(20, 390, _T("右:右移")); outtextxy(20, 410, _T("下:下移")); outtextxy(20, 430, _T("空格:沉底")); outtextxy(20, 450, _T("ESC:退出")); // 设置坐标原点 setorigin(220, 20); // 绘制游戏区边界 rectangle(-1, -1, WIDTH * SIZE, HEIGHT * SIZE); rectangle((WIDTH + 1) * SIZE - 1, -1, (WIDTH + 5) * SIZE, 4 * SIZE); // 开始新游戏 NewGame();}// 退出游戏void Quit(){ closegraph(); exit(0);}// 开始新游戏void NewGame(){ // 清空游戏区 setfillstyle(BLACK); bar(0, 0, WIDTH * SIZE - 1, HEIGHT * SIZE - 1); ZeroMemory(g_World, WIDTH * HEIGHT); // 生成下一个方块 g_NextBlock.id = rand() % 7; g_NextBlock.dir = rand() % 4; g_NextBlock.x = WIDTH + 1; g_NextBlock.y = HEIGHT - 1; // 获取新方块 NewBlock();}// 结束游戏void GameOver(){ HWND wnd = GetHWnd(); if (MessageBox(wnd, _T("游戏结束。\n您想重新来一局吗?"), _T("游戏结束"), MB_YESNO | MB_ICONQUESTION) == IDYES) NewGame(); else Quit();}// 获取控制命令DWORD m_oldtime;CMD GetCmd(){ // 获取控制值 while(true) { // 如果超时,自动下落一格 DWORD newtime = GetTickCount(); if (newtime - m_oldtime >= 500) { m_oldtime = newtime; return CMD_DOWN; } // 如果有按键,返回按键对应的功能 if (kbhit()) { switch(getch()) { case 'w': case 'W': return CMD_ROTATE; case 'a': case 'A': return CMD_LEFT; case 'd': case 'D': return CMD_RIGHT; case 's': case 'S': return CMD_DOWN; case 27: return CMD_QUIT; case ' ': return CMD_SINK; case 0: case 0xE0: switch(getch()) { case 72: return CMD_ROTATE; case 75: return CMD_LEFT; case 77: return CMD_RIGHT; case 80: return CMD_DOWN; } } } // 延时 (降低 CPU 占用率) Sleep(20); }}// 分发控制命令void DispatchCmd(CMD _cmd){ switch(_cmd) { case CMD_ROTATE: OnRotate(); break; case CMD_LEFT: OnLeft(); break; case CMD_RIGHT: OnRight(); break; case CMD_DOWN: OnDown(); break; case CMD_SINK: OnSink(); break; case CMD_QUIT: break; }}// 生成新的方块void NewBlock(){ g_CurBlock.id = g_NextBlock.id, g_NextBlock.id = rand() % 7; g_CurBlock.dir = g_NextBlock.dir, g_NextBlock.dir = rand() % 4; g_CurBlock.x = (WIDTH - 4) / 2; g_CurBlock.y = HEIGHT + 2; // 下移新方块直到有局部显示 WORD c = g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir]; while((c & 0xF) == 0) { g_CurBlock.y--; c >>= 4; } // 绘制新方块 DrawBlock(g_CurBlock); // 绘制下一个方块 setfillstyle(BLACK); bar((WIDTH + 1) * SIZE, 0, (WIDTH + 5) * SIZE - 1, 4 * SIZE - 1); DrawBlock(g_NextBlock); // 设置计时器,用于判断自动下落 m_oldtime = GetTickCount();}// 画方块void DrawBlock(BLOCKINFO _block, DRAW _draw){ WORD b = g_Blocks[_block.id].dir[_block.dir]; int x, y; int color = BLACK; switch(_draw) { case SHOW: color = g_Blocks[_block.id].color; break; case HIDE: color = BLACK; break; case FIX: color = g_Blocks[_block.id].color / 3; break; } setfillstyle(color); for(int i=0; i<16; i++) { if (b & 0x8000) { x = _block.x + i % 4; y = _block.y - i / 4; if (y < HEIGHT) { if (_draw != HIDE) bar3d(x * SIZE + 2, (HEIGHT - y - 1) * SIZE + 2, (x + 1) * SIZE - 4, (HEIGHT - y) * SIZE - 4, 3, true); else bar(x * SIZE, (HEIGHT - y - 1) * SIZE, (x + 1) * SIZE - 1, (HEIGHT - y) * SIZE - 1); } } b <<= 1; }}// 检测指定方块是否可以放下bool CheckBlock(BLOCKINFO _block){ WORD b = g_Blocks[_block.id].dir[_block.dir]; int x, y; for(int i=0; i<16; i++) { if (b & 0x8000) { x = _block.x + i % 4; y = _block.y - i / 4; if ((x < 0) || (x >= WIDTH) || (y < 0)) return false; if ((y < HEIGHT) && (g_World[x][y])) return false; } b <<= 1; } return true;}// 旋转方块void OnRotate(){ // 获取可以旋转的 x 偏移量 int dx; BLOCKINFO tmp = g_CurBlock; tmp.dir++; if (CheckBlock(tmp)) { dx = 0; goto rotate; } tmp.x = g_CurBlock.x - 1; if (CheckBlock(tmp)) { dx = -1; goto rotate; } tmp.x = g_CurBlock.x + 1; if (CheckBlock(tmp)) { dx = 1; goto rotate; } tmp.x = g_CurBlock.x - 2; if (CheckBlock(tmp)) { dx = -2; goto rotate; } tmp.x = g_CurBlock.x + 2; if (CheckBlock(tmp)) { dx = 2; goto rotate; } return;rotate: // 旋转 DrawBlock(g_CurBlock, HIDE); g_CurBlock.dir++; g_CurBlock.x += dx; DrawBlock(g_CurBlock);}// 左移方块void OnLeft(){ BLOCKINFO tmp = g_CurBlock; tmp.x--; if (CheckBlock(tmp)) { DrawBlock(g_CurBlock, HIDE); g_CurBlock.x--; DrawBlock(g_CurBlock); }}// 右移方块void OnRight(){ BLOCKINFO tmp = g_CurBlock; tmp.x++; if (CheckBlock(tmp)) { DrawBlock(g_CurBlock, HIDE); g_CurBlock.x++; DrawBlock(g_CurBlock); }}// 下移方块void OnDown(){ BLOCKINFO tmp = g_CurBlock; tmp.y--; if (CheckBlock(tmp)) { DrawBlock(g_CurBlock, HIDE); g_CurBlock.y--; DrawBlock(g_CurBlock); } else OnSink(); // 不可下移时,执行“沉底方块”操作}// 沉底方块void OnSink(){ int i, x, y; // 连续下移方块 DrawBlock(g_CurBlock, HIDE); BLOCKINFO tmp = g_CurBlock; tmp.y--; while (CheckBlock(tmp)) { g_CurBlock.y--; tmp.y--; } DrawBlock(g_CurBlock, FIX); // 固定方块在游戏区 WORD b = g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir]; for(i = 0; i < 16; i++) { if (b & 0x8000) { if (g_CurBlock.y - i / 4 >= HEIGHT) { // 如果方块的固定位置超出高度,结束游戏 GameOver(); return; } else g_World[g_CurBlock.x + i % 4][g_CurBlock.y - i / 4] = 1; } b <<= 1; } // 检查是否需要消掉行,并标记 int row[4] = {0}; bool bRow = false; for(y = g_CurBlock.y; y >= max(g_CurBlock.y - 3, 0); y--) { i = 0; for(x = 0; x < WIDTH; x++) if (g_World[x][y] == 1) i++; if (i == WIDTH) { bRow = true; row[g_CurBlock.y - y] = 1; setfillstyle(WHITE, DIAGCROSS2_FILL); bar(0, (HEIGHT - y - 1) * SIZE + SIZE / 2 - 2, WIDTH * SIZE - 1, (HEIGHT - y - 1) * SIZE + SIZE / 2 + 2); } } if (bRow) { // 延时 200 毫秒 Sleep(200); // 擦掉刚才标记的行 IMAGE img; for(i = 0; i < 4; i++) { if (row[i]) { for(y = g_CurBlock.y - i + 1; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) { g_World[x][y - 1] = g_World[x][y]; g_World[x][y] = 0; } getimage(&img, 0, 0, WIDTH * SIZE, (HEIGHT - (g_CurBlock.y - i + 1)) * SIZE); putimage(0, SIZE, &img); } } } // 产生新方块 NewBlock();}