阅读量:6
前言
发现很多朋友都想要一些小项目来练手,却找不到从哪里寻找,给大家整理了游戏项目开发源代码汇总。
一、最经典游戏之俄罗斯方块
#include<iostream> #include<math.h> #include<Windows.h> #include<conio.h> #include<ctime> using namespace std; enum DIR { UP, RIGHT, DOWN, LEFT }; time_t start = 0, finish = 0; int _x = 6, _y = 1;//图形生成位置 int map[30][16] = { 0 }; int sharp[20][8] = { {0,0,0,0,0,0,0,0}, //I形 {0,0,0,1,0,2,0,3}, {0,0,1,0,2,0,3,0}, //■形 {0,0,1,0,0,1,1,1}, //L形 {0,0,0,1,0,2,1,2}, {0,0,0,1,1,0,2,0}, {0,0,1,0,1,1,1,2}, {0,1,1,1,2,0,2,1}, //J形 {0,2,1,0,1,1,1,2}, {0,0,0,1,1,1,2,1}, {0,0,0,1,0,2,1,0}, {0,0,1,0,2,0,2,1}, //Z形 {0,0,1,0,1,1,2,1}, {0,1,0,2,1,0,1,1}, //S形 {0,1,1,0,1,1,2,0}, {0,0,0,1,1,1,1,2}, //T形 {0,1,1,0,1,1,2,1}, {0,0,0,1,0,2,1,1}, {0,0,1,0,1,1,2,0}, {0,1,1,0,1,1,1,2} }; class Game { public: int score;//游戏分数 int _id;//图形编号 int top;//最高点高度 int speed;//下落速度 Game(); void showMenu();//显示菜单 void showGround();//显示游戏界面 void gameOver();//游戏结束界面 void Run();//运行游戏 void sharpDraw(int id, bool show = false);//绘制图形 void keyControl();//键盘控制 bool move(int dir, int id);//移动判断 bool downSet(int id);//下落 void Turn(int id);//旋转 void clean();//消行 }; void SetPos(int i, int j)//控制光标位置, 列, 行 { COORD pos = { i,j }; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); } int main() { CONSOLE_CURSOR_INFO cursor; GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor); cursor.bVisible = 0; //这四行用来设置光标不显示 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor); srand((unsigned)time(NULL)); Game game; game.showMenu(); return 0; } Game::Game() { score = 0; _id = 0; top = 58; speed = 1000; } void Game::showMenu() { for (int i = 0; i < 30; i++) { for (int j = 0; j < 26; j++) { if ((i == 0 || i == 29) || (j == 0 || j == 25)) { cout << "■"; } else { cout << " "; } } cout << endl; } SetPos(17, 8); cout << "俄 罗 斯 方 块" << endl; SetPos(13, 12); cout << "↑旋转方块 ↓加速下滑" << endl; SetPos(12, 14); cout << "← →左右移动 空格 暂停" << endl; SetPos(15, 20); cout << "0 退出 Enter 开始" << endl; while (1) { int select = _getch(); if (select == 13) { system("cls"); this->Run(); } else if (select = 48) { system("cls"); exit(0); } } } void Game::showGround() { for (int i = 0; i < 30; i++) { for (int j = 0; j < 26; j++) { if ((i == 0 || i == 29) || (j == 0 || j == 25 || j == 15)) { cout << "■"; } else if (i == 15 && j > 15) { cout << "■"; } else { cout << " "; } } cout << endl; } SetPos(31, 2); cout << "下 个图形" << endl; SetPos(31, 17); cout << "当 前得分" << endl; for (int i = 0; i < 30; i++) { for (int j = 0; j < 16; j++) { if ((i == 0 || i == 29) || (j == 0 || j == 15)) { map[i][j] = 1; } else { map[i][j] = 0; } } } } void Game::gameOver() { for (int i = 5; i < 15; i++) { SetPos(1, i); cout << " " << endl; } SetPos(8, 7); cout << "G a m e O v e r" << endl; SetPos(3, 10); cout << "0 退出 Enter 重新开始" << endl; while (1) { int select = _getch(); if (select == 13) { system("cls"); this->Run(); } else if (select == 48) { system("cls"); exit(0); } } } void Game::Run() { score = 0; _id = 0; top = 58; _x = 6; _y = 1; showGround(); start = clock(); int new_id = rand() % 19 + 1; while (1) { sharpDraw(_id); keyControl(); if (downSet(_id)) { sharpDraw(-new_id, 1); _id = new_id; new_id = rand() % 19 + 1; sharpDraw(new_id, 1); clean(); } SetPos(34, 20); cout << score << endl; } } void Game::sharpDraw(int id, bool show) { int x, y; if (show == true) { if (id > 0) { for (int i = 0; i < 4; i++) { x = 19 + sharp[id][2 * i]; y = 6 + sharp[id][2 * i + 1]; SetPos(2 * x, y); cout << "■"; } } else { for (int i = 0; i < 4; i++) { x = 19 + sharp[-id][2 * i]; y = 6 + sharp[-id][2 * i + 1]; SetPos(2 * x, y); cout << " "; } } return; } if (id > 0) { for (int i = 0; i < 4; i++) { x = _x + sharp[id][2 * i]; y = _y + sharp[id][2 * i + 1]; SetPos(2 * x, y); cout << "■"; } } else { for (int i = 0; i < 4; i++) { x = _x + sharp[-id][2 * i]; y = _y + sharp[-id][2 * i + 1]; SetPos(2 * x, y); cout << " "; } } return; } bool Game::downSet(int id) { if (id == 0) return true; finish = clock(); if (finish - start < speed) { return false; } start = clock(); if (!move(DOWN, _id)) { int x, y; for (int i = 0; i < 4; i++) { x = _x + sharp[id][2 * i]; y = _y + sharp[id][2 * i + 1]; map[y][x] = 1; if (y < top) { top = y; } if (top <= 1) { gameOver(); } } _x = 6; _y = 1; return true; } sharpDraw(-id); _y++; sharpDraw(id); return false; } bool Game::move(int dir, int id) { int x, y; switch (dir) { case UP: for (int i = 0; i < 4; i++) { x = _x + sharp[id][2 * i]; y = _y + sharp[id][2 * i + 1]; if (map[y][x] == 1) { return false; } } break; case DOWN: { for (int i = 0; i < 4; i++) { x = _x + sharp[id][2 * i]; y = _y + sharp[id][2 * i + 1]; if (map[y + 1][x] == 1) { return false; } } } break; case RIGHT: { for (int i = 0; i < 4; i++) { x = _x + sharp[id][2 * i]; y = _y + sharp[id][2 * i + 1]; if (map[y][x + 1] == 1) { return false; } } } break; case LEFT: { for (int i = 0; i < 4; i++) { x = _x + sharp[id][2 * i]; y = _y + sharp[id][2 * i + 1]; if (map[y][x - 1] == 1) { return false; } } } break; default: break; } return true; } void Game::Turn(int id) { switch (id) { case 1:id++; break; case 2:id--; break; case 3: break; case 4:id++; break; case 5:id++; break; case 6:id++; break; case 7:id -= 3; break; case 8:id++; break; case 9:id++; break; case 10:id++; break; case 11:id -= 3; break; case 12:id++; break; case 13:id--; break; case 14:id++; break; case 15:id--; break; case 16:id++; break; case 17:id++; break; case 18:id++; break; case 19:id -= 3; break; default: break; } if (!move(UP, id)) { return; } sharpDraw(-_id); _id = id; } void Game::keyControl() { if (!_kbhit()) return; int key = _getch(); switch (key) { case 72: Turn(_id); break; case 80: if (move(DOWN, _id)) { sharpDraw(-_id); _y++; } break; case 75: if (move(LEFT, _id)) { sharpDraw(-_id); _x--; } break; case 77: if (move(RIGHT, _id)) { sharpDraw(-_id); _x++; } break; case 32: { for (int i = 5; i < 15; i++) { SetPos(1, i); cout << " " << endl; } SetPos(10, 7); cout << "游 戏 暂 停" << endl; SetPos(3, 10); cout << "0 返回菜单 回车 继续游戏" << endl; while (1) { int select = _getch(); if (select == 13) { for (int i = 5; i < 15; i++) { SetPos(1, i); cout << " " << endl; } break; } else if (select == 48) { system("cls"); showMenu(); } } } default: break; } } void Game::clean() { int n = -1; int line = -1; while (1) { for (int i = 28; i > 0; i--) { for (int j = 1; j < 15; j++) { line = i; if (map[i][j] == 0) { line = -1; break; } } if (line != -1) break; } if (line == -1) break; for (int i = line; i > 0; i--) { for (int j = 1; j < 15; j++) { if (i == 1) map[i][j] = 0; else { map[i][j] = map[i - 1][j]; SetPos(2 * j, i); if (map[i][j] == 1) cout << "■"; else cout << " "; } } } top++; n++; } if (n >= 0) { score += n * n * 100 + 100; if (speed > 100) speed = 1000 - score / 10; } }
二、雷霆战机游戏源代码
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<graphics.h> #include<conio.h> #include<time.h> #include<mmsystem.h> #pragma comment(lib,"winmm.lib") typedef struct Node { int x; int y; struct Node *pnext; }NODE; #define WINDOW_WIDTH 1024 #define WINDOW_HEIGHT 680 #define WIDTH 480 //我机图片尺寸 #define pw 86 #define ph 82 //敌机图片尺寸 #define aw 70 #define ah 70 #define boss1w 192 #define boss1h 290 //敌机重出现的y坐标 #define APStart -ah-20 NODE *p_bullet = NULL; //MyPlane NODE *p_MP = NULL; //AttackPlane NODE* p_AP = NULL; //子弹时间差 NODE* p_AP2 = NULL; DWORD b1, b2, b3, b4, b5, b6; IMAGE i_MP,i_MPS,i_AP,i_APS; IMAGE i_backeve, i_backxing, i_backduicheng, i_backguan,i_backcontrol,i_backgo; IMAGE i_boss1_1, i_boss1_1S, i_boss1_2, i_boss1_2S; //backxing的左右移动 int left = (WINDOW_WIDTH / 2 - WIDTH / 2); //分数 int score = 0; //击毁敌机的数量 int kill = 0; //boss是否出现 int boss1show = 0; //boss1贴图开关 int boss1image = 0; int boss1hp = 20; int line1_x = WINDOW_WIDTH / 2 - 20; int line1_y = boss1h; int line2_x = WINDOW_WIDTH / 2 + 20; int line2_y = boss1h; //Beam只播放一次 int test = 1; int MP_HP = 1; void CreateList() { p_MP = (NODE*)malloc(sizeof(NODE)); p_MP->x = WINDOW_WIDTH / 2 - pw / 2; p_MP->y = WINDOW_HEIGHT-100; p_MP->pnext = NULL; p_bullet = (NODE*)malloc(sizeof(NODE)); p_bullet->pnext = NULL; b1 = GetTickCount(); p_AP = (NODE*)malloc(sizeof(NODE)); srand((unsigned)time(NULL)); p_AP->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2); p_AP->y = APStart; p_AP->pnext = NULL; b3 = GetTickCount(); p_AP2 = (NODE*)malloc(sizeof(NODE)); p_AP2->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2); p_AP2->y = -350; p_AP2->pnext = NULL; b5 = GetTickCount(); } void GameBackInit() { loadimage(&i_MP, L"mp.jpg"); loadimage(&i_MPS, L"mpbit.jpg"); loadimage(&i_backeve, L"backeve.jpg"); loadimage(&i_backxing, L"backtaikong.jpg"); loadimage(&i_AP, L"AP.jpg", aw, ah); loadimage(&i_APS, L"APS.jpg", aw, ah); loadimage(&i_backduicheng, L"backduicheng.jpg"); loadimage(&i_backguan, L"backguan.jpg", WIDTH, WINDOW_HEIGHT); loadimage(&i_backcontrol, L"backcontrol.jpg",WINDOW_WIDTH,WINDOW_HEIGHT); loadimage(&i_boss1_1, L"boss1_1.jpg"); loadimage(&i_boss1_1S, L"boss1_1S.jpg"); loadimage(&i_boss1_2, L"boss1_2.jpg"); loadimage(&i_boss1_2S, L"boss1_1S.jpg"); loadimage(&i_backgo, L"Gameover.jpg", WINDOW_WIDTH, WINDOW_HEIGHT); putimage(0, 30, &i_backeve); Sleep(1000); PlaySound(L"baozou.wav", NULL, SND_FILENAME | SND_ASYNC); putimage(0, 0, &i_backcontrol); outtextxy(600, 540, L"【PRESS】 按任意键进入游戏"); system("pause"); mciSendString(L"open bgmusic.mp3 alias bg", NULL, 0, NULL); mciSendString(L"play bg repeat", NULL, 0, NULL); putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0, WIDTH, WINDOW_HEIGHT, &i_backguan, 0, 0, SRCCOPY); putimage(0, 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 0, 100, SRCCOPY); putimage((WINDOW_WIDTH / 2 + WIDTH / 2), 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 1200 - (WINDOW_WIDTH / 2 - WIDTH / 2), 100, SRCCOPY); //字体出现的高度 int text_h = WINDOW_HEIGHT/2; Sleep(300); BeginBatchDraw(); for (int i = 0; i < text_h; i++) { clearrectangle((WINDOW_WIDTH / 2 - WIDTH / 2), 0, (WINDOW_WIDTH / 2 + WIDTH / 2), WINDOW_HEIGHT); putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0-i, WIDTH, text_h , &i_backguan, 0, 0, SRCCOPY); putimage((WINDOW_WIDTH / 2 - WIDTH / 2), text_h + i, WIDTH, WINDOW_HEIGHT - (text_h + i), &i_backguan, 0, text_h, SRCCOPY); putimage((WINDOW_WIDTH / 2 - WIDTH / 2), text_h - i, WIDTH, 2*i, &i_backxing, left, text_h-i, SRCCOPY); FlushBatchDraw(); Sleep(5); } EndBatchDraw(); Sleep(100); } void Boss1show() { p_AP->y = WINDOW_HEIGHT + 100; p_AP2->y = WINDOW_HEIGHT + 100; if (boss1hp >14) { putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1S, NOTSRCERASE); putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1, SRCINVERT); } else if(boss1hp >= 9 && boss1hp <=14) { if (boss1hp % 2 == 0) { setlinecolor(0x996666); setlinestyle(PS_DOT, 3); line(line1_x, line1_y, line1_x, WINDOW_HEIGHT); line(line2_x, line2_y, line2_x, WINDOW_HEIGHT); putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2S, NOTSRCERASE); putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2, SRCINVERT); } else { setlinecolor(0xCC6666); setlinestyle(PS_DOT, 3); line(line1_x, line1_y, line1_x, WINDOW_HEIGHT); line(line2_x, line2_y, line2_x, WINDOW_HEIGHT); putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1S, NOTSRCERASE); putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1, SRCINVERT); } } else { if (test == 1) { PlaySound(L"Beam.wav", NULL, SND_FILENAME | SND_ASYNC); test++; } setlinecolor(0xFF6666); setlinestyle(PS_DASH, 5); line(line1_x, line1_y, line1_x, WINDOW_HEIGHT); line(line2_x, line2_y, line2_x, WINDOW_HEIGHT); line(WINDOW_WIDTH / 2 - boss1w / 2, boss1h -90, 482, boss1h + 50); line(WINDOW_WIDTH / 2 + boss1w / 2, boss1h - 90, 542, boss1h + 50); putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2S, NOTSRCERASE); putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2, SRCINVERT); if ((boss1hp!=8)&&(p_MP->x - line1_x) > -pw && (p_MP->x - line2_x)<0&& (p_MP->y - line1_y)>-ph) MP_HP = 0; } if(boss1image<=boss1h ) boss1image+=2; } void AddNode(int flag) { //后插法,更新第二个位置 if (flag == 0) { NODE* p_new = (NODE*)malloc(sizeof(NODE)); p_new->x = p_MP->x + 35; p_new->y = p_MP->y - 45; p_new->pnext = p_bullet->pnext; p_bullet->pnext = p_new; } } int main() { //create a window initgraph(WINDOW_WIDTH, WINDOW_HEIGHT); setfillcolor(0xFF9999); GameBackInit(); char key; CreateList(); //批量绘图 BeginBatchDraw(); while (1) { //清画板,要不然就成重叠的残影了 cleardevice(); putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0, WIDTH, WINDOW_HEIGHT, &i_backxing, left, 0, SRCCOPY); putimage(0, 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 0, 100, SRCCOPY); putimage((WINDOW_WIDTH / 2 + WIDTH / 2), 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 1200 - (WINDOW_WIDTH / 2 - WIDTH / 2), 100, SRCCOPY); putimage(p_MP->x, p_MP->y, &i_MPS, NOTSRCERASE); putimage(p_MP->x, p_MP->y, &i_MP, SRCINVERT); putimage(p_AP->x, p_AP->y, &i_APS, NOTSRCERASE); putimage(p_AP->x, p_AP->y, &i_AP, SRCINVERT); putimage(p_AP2->x, p_AP2->y, &i_APS, NOTSRCERASE); putimage(p_AP2->x, p_AP2->y, &i_AP, SRCINVERT); //MP单位时间发射子弹的数量 b2 = GetTickCount(); //不能等于,有偏差 if (b2 - b1 >= 600) { AddNode(0); b1 = b2; } //我方战机子弹递增 NODE* P = p_bullet->pnext; while (P != NULL) { if (boss1show == 0) { //确定敌机重生位置不是在原位置 int mid; //10是子弹宽度,但半个子弹打中也算,要不然太难了,就右边是-3,左边是-7 if ((P->y - p_AP->y) < ah && (P->y - p_AP->y) >= 0 && (P->x - p_AP->x) < aw -3 && (P->x - p_AP->x) >= -7) { P->y = APStart -100; P = P->pnext; p_AP->y = APStart; kill++; PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC); while (1) { mid = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2); if (abs(mid - p_AP->x) > aw) { p_AP->x = mid; break; } } } else if((P->y - p_AP2->y) < ah && (P->y - p_AP2->y) >= 0 && (P->x - p_AP2->x) < aw - 3 && (P->x - p_AP2->x) >= -7) { P->y = APStart -100; P = P->pnext; p_AP2->y = APStart; kill++; while (1) { mid = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2); if (abs(mid - p_AP2->x) > aw) { p_AP2->x = mid; break; } } PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC); } else { fillroundrect(P->x, P->y, P->x + 10, P->y + 35, 10, 30); P->y -= 5; P = P->pnext; } } else if (boss1show == 1) { if (boss1image > boss1h) { if ((P->y) < boss1h && (P->y) >= 0 && (P->x - (WINDOW_WIDTH / 2 - boss1w / 2)) < boss1w - 3 && (P->x - (WINDOW_WIDTH / 2 - boss1w / 2)) >= -7) { P->y = APStart -100; P = P->pnext; boss1hp--; if (boss1hp>9||boss1hp<7) PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC); } else { fillroundrect(P->x, P->y, P->x + 10, P->y - 35, 10, 30); P->y -= 10; P = P->pnext; } TCHAR s_boss1hp[100]; _stprintf(s_boss1hp, _T("【Boss】HP:%d"), boss1hp); outtextxy((WINDOW_WIDTH / 2 + WIDTH / 2) + 45, 200, s_boss1hp); if (boss1hp <= 0) { boss1show = 0; kill += 50; } } else { fillroundrect(P->x, P->y, P->x + 10, P->y + 35, 10, 30); P->y -= 5; P = P->pnext; } } } //AP飞行的速度 b4 = GetTickCount(); //不能等于,有偏差 if (b4- b3 >= 50) { if (p_AP->y < WINDOW_HEIGHT) { p_AP->y += 3; } else { p_AP->y = 0; p_AP->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2); } b3 = b4; } //AP2飞行的速度 b6 = GetTickCount(); //不能等于,有偏差 if (b6 - b5 >= 50) { if (p_AP2->y < WINDOW_HEIGHT) { p_AP2->y += 3; } else { p_AP2->y = 0; p_AP2->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2); } b5 = b6; } if (kill==10&& boss1hp > 0) boss1show = 1; if (boss1show==1) { Boss1show(); } if ((p_MP->x - p_AP->x) > -pw && (p_MP->x - p_AP->x)<pw && (p_MP->y - p_AP->y)>-ph && (p_MP->y - p_AP->y)<ph ) MP_HP = 0; else if ((p_MP->x - p_AP2->x) > -pw && (p_MP->x - p_AP2->x)<pw && (p_MP->y - p_AP2->y)>-ph && (p_MP->y - p_AP2->y)<ph) MP_HP = 0; else if (boss1show==1&&boss1image>boss1h&&(p_MP->x-(WINDOW_WIDTH / 2 - boss1w / 2)) >-pw && (p_MP->x-(WINDOW_WIDTH / 2 + boss1w / 2))<pw && p_MP->y<boss1h) MP_HP = 0; if (MP_HP == 0) { mciSendString(L"close bg", NULL, 0, NULL); mciSendString(L"open bggo.mp3 alias bg", NULL, 0, NULL); mciSendString(L"play bg repeat", NULL, 0, NULL); putimage(0, 0, &i_backgo, SRCCOPY); outtextxy(430, 540, L"3秒后自动退出"); EndBatchDraw(); Sleep(3000); closegraph(); return 0; } TCHAR s_score[100]; _stprintf(s_score, _T("你的分数:%d"), kill); outtextxy((WINDOW_WIDTH / 2 + WIDTH / 2) + 50, WINDOW_HEIGHT/2, s_score); FlushBatchDraw(); //子弹飞行速度以及按键延迟等 Sleep(15); if (kbhit()) { key = getch(); switch (key) { case 72://上 p_MP->y -= 5; break; case 80://下 p_MP->y += 5; break; case 75://左 p_MP->x -= 5; left -= 5; break; case 77://右 p_MP->x += 5; left += 5; break; } } if (p_MP->x<(WINDOW_WIDTH / 2 - WIDTH / 2)) p_MP->x = (WINDOW_WIDTH / 2 - WIDTH / 2); if (p_MP->x>(WINDOW_WIDTH / 2 + WIDTH / 2 - pw)) p_MP->x = (WINDOW_WIDTH / 2 + WIDTH / 2 - pw); if (p_MP->y<0 ) p_MP->y = 0; if (p_MP->y>WINDOW_HEIGHT - ph) p_MP->y = WINDOW_HEIGHT - ph; if (left < 0) left = 0; if (left>1280 - WIDTH) left = 1280 - WIDTH; } EndBatchDraw(); closegraph(); return 0; }
三、五子棋经典游戏源代码
#define _CRT_SECURE_NO_WARNINGS #define MAX_ROW 3 #define MAX_COL 3 #include <stdio.h> #include <stdlib.h> #include <time.h> void init(char chessBoard[MAX_ROW][MAX_COL]) { for (int row = 0; row < MAX_ROW; row++) { for (int col = 0; col < MAX_COL; col++) { chessBoard[row][col] = ' '; } } } void print_chessBoard(char chessBoard[MAX_ROW][MAX_COL]) { printf("+---+---+---+\n"); for (int row = 0; row < MAX_ROW; row++) { printf("| %c | %c | %c |\n", chessBoard[row][0], chessBoard[row][1], chessBoard[row][2]); printf("+---+---+---+\n"); } } void playerMove(char chessBoard[MAX_ROW][MAX_COL]) { while (1) { int row = 0; int col = 0; printf("请输入坐标(row col):"); scanf("%d %d", &row, &col); if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) { printf("您的坐标不在合法范围内 [0, 2],请重新输入:\n"); continue; } if (chessBoard[row][col] != ' ') { printf("您的坐标位置已经有子了!\n"); continue; } chessBoard[row][col] = 'x'; break; } } void computerMove(char chessBoard[MAX_ROW][MAX_COL]) { while (1) { int row = rand() % MAX_ROW; int col = rand() % MAX_COL; if (chessBoard[row][col] != ' ') { continue; } chessBoard[row][col] = 'o'; break; } } int isFull(char chessBoard[MAX_ROW][MAX_COL]) { for (int row = 0; row < MAX_ROW; row++) { for (int col = 0; col < MAX_COL; col++) { if (chessBoard[row][col] == ' ') { return 0; } } } return 1; } char isWin(char chessBoard[MAX_ROW][MAX_COL]) { for (int row = 0; row < MAX_ROW; row++) { if (chessBoard[row][0] != ' ' && chessBoard[row][0] == chessBoard[row][1] && chessBoard[row][0] == chessBoard[row][2]) { return chessBoard[row][0]; } } for (int col = 0; col < MAX_COL; col++) { if (chessBoard[0][col] != ' ' && chessBoard[0][col] == chessBoard[1][col] && chessBoard[0][col] == chessBoard[2][col]) { return chessBoard[0][col]; } } if (chessBoard[0][0] != ' ' && chessBoard[0][0] == chessBoard[1][1] && chessBoard[0][0] == chessBoard[2][2]) { return chessBoard[0][0]; } if (chessBoard[2][0] != ' ' && chessBoard[2][0] == chessBoard[1][1] && chessBoard[2][0] == chessBoard[0][2]) { return chessBoard[2][0]; } if (isFull(chessBoard)) { return 'q'; } return ' '; } void game() { char chessBoard[MAX_ROW][MAX_COL] = { 0 }; init(chessBoard); char winner = ' '; while (1) { system("cls"); print_chessBoard(chessBoard); playerMove(chessBoard); winner = isWin(chessBoard); if (winner != ' ') { break; } computerMove(chessBoard); winner = isWin(chessBoard); if (winner != ' ') { break; } } print_chessBoard(chessBoard); if (winner == 'x') { printf("恭喜您, 您赢了!\n"); } else if (winner == 'o') { printf("哈哈,您连人工智障都下不过!\n"); } else { printf("您只能和人工智障打平手!!\n"); } } int menu() { printf("--------------------------\n"); printf("--------1.开始游戏--------\n"); printf("--------0.退出游戏--------\n"); printf("--------------------------\n"); int choice = 0; printf("请输入你的选择:"); scanf("%d", &choice); return choice; } int main() { srand((unsigned int)time(0)); while (1) { int choice = menu(); if (choice == 1) { game(); } else if (choice == 0) { printf("退出游戏,GOODBYE!!!!!\n"); break; } else { printf("输入错误!请重新输入!\n"); continue; } } system("pause"); return 0; }
四、贪吃蛇完整版EN
// 必要的头文件 #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <time.h> #include <windows.h> #include <string.h> // 定义标记上下左右的明示常量 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define ESC 5 #define FOOD 10 // 定义表示位置的结构体类型 typedef struct snake{ int x; int y; struct snake *next; }snake; // 定义全局变量 int score = 0; // 当前得分 int speed = 200; // 存储当前速度 int status; snake *tail, *head; // 存储蛇头蛇尾 snake *food, *q;// q用于遍历链表 HANDLE hOUT; void gotoxy(int x, int y); // 设置光标位置 int choice(void); // 载入游戏界面 int color(int c); // 设置字体颜色 void printGame(void); // 打印游戏界面 void printSnake(void); // 打印蛇身 void printFood(void); // 打印食物 void printTips(void); // 打印提示 void snakeMove(void); // 主操作函数 int biteSelf(void); // 判断是否咬到了自己 int encounterWall(void); // 判断是否撞墙 void keyboardControl(void); // 获取击键 void speedUp(void); // 加速 void speedDown(void); // 减速 int endGame(void); // 结束函数; char *s_gets(char *st, int n); // 读取字符 void frees(snake *); // 释放内存 int main(int argc, char *argv[]){ while (1) { if (choice() == 1) keyboardControl(); else { gotoxy(5, 15); printf("按任意键返回"); getchar(); // 去除前一个前导换行 while (1) { if (getchar()) { system("cls"); break; } } } } frees(head); return 0; } void gotoxy(int x, int y) { COORD c; c.X = x; c.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); } int choice(void) { int yourchoice; // 画出界面 gotoxy(35, 5); color(11); printf("\t贪吃蛇大作战\n"); printf("\n\n"); color(13); printf("\t\t★★★★★★★★ Snake!"); printf("\t\t★★★★★★★★ Snake!"); gotoxy(25, 15); color(12); printf("1.进入游戏\t2.查看说明\t3.退出游戏\n"); color(11); printf("请选择:"); scanf("%d", &yourchoice); switch (yourchoice) { case 1: system("cls"); // 初始化 printGame(); printSnake(); printFood(); break; case 2: system("cls"); printTips(); break; case 3: system("cls"); gotoxy(30, 10); color(11); printf("Bye!"); exit(0); default: system("cls"); printf("没有此序号,请输入1,2或3\n"); Sleep(2000); system("cls"); } return yourchoice; } int color(int c) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改文字颜色 return 0; } void printGame() { int i, j; gotoxy(5, 5); printf("游戏载入中...请稍后"); Sleep(2000); system("cls"); // 打印上下界面 for (i = 0; i <= 50; i += 2) { gotoxy(i, 0); printf("□"); gotoxy(i, 25); printf("□"); } // 打印左右界面 for (i = 0; i <= 25; i += 1) { gotoxy(0, i); printf("□"); gotoxy(50, i); printf("□"); } // 打印中间网格 for (i = 1; i <= 24; i += 1) { for (j = 2; j <= 48; j += 2) { gotoxy(j, i); color(11); printf("■"); } } // 打印右侧的规则和计分栏 gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); gotoxy(60, 15); printf("用↑ ↓ ← →分别控制蛇的移动\n"); gotoxy(60, 18); printf("每次获取食物加10分 按下F1加速,F2减速,空格暂停\n"); gotoxy(60, 20); printf("不能撞墙和咬到自己!"); gotoxy(60, 22); printf("速度不低于100,不高于300"); } void printSnake(void) { int i; // 设定蛇尾(16,13),头插入,初始向右 tail = (snake*)malloc(sizeof(snake)); tail->x = 16; tail->y = 13; tail->next = NULL; // 设定初始蛇长是4 for (i = 1; i <= 4; i++) { head = (snake*)malloc(sizeof(snake)); head->next = tail; head->x = 16 + 2 * i; head->y = 13; tail = head; // 头成为尾 } // 输出蛇身 while (tail->next) { gotoxy(tail->x, tail->y); color(14); printf("★"); tail = tail->next; } } void printFood(void) { srand((unsigned)time(NULL)); // 利用时钟修改种子 food = (snake*)malloc(sizeof(snake)); food->x = 1; // 初始化x坐标 while (food->x % 2 && food->x) { food->x = rand() % 46 + 2;// 2-48 } food->y = rand() % 23 + 1; // 1-24 q = head; // 不改变头遍历链表 while (q->next) { if (q->x == food->x && q->y == food->y) { free(food); printFood(); } else { gotoxy(food->x, food->y); color(12); printf("●"); break; } } } void printTips(void) { color(11); printf("***********Tips************\n"); printf("1.采用合理的速度可以获得更高的分数哦!\n"); printf("2.一定不要撞到自己或者两边的墙!\n"); printf("3.游戏过程中按ESC退出游戏!\n"); } void snakeMove(void) { snake *snakenext; snakenext = (snake*)malloc(sizeof(snake)); if (biteSelf()) { gotoxy(60, 11); printf("咬到自己啦!"); free(snakenext); Sleep(1500); system("cls"); exit(0); } else if (encounterWall()) { gotoxy(60, 11); printf("撞到墙啦!"); free(snakenext); Sleep(1500); system("cls"); exit(0); } else { // 前两个条件判断完成才开始移动 Sleep(350 - speed); if (status == UP) { snakenext->x = head->x; snakenext->y = head->y - 1; snakenext->next = head; head = snakenext; q = head; if (snakenext->x == food->x && snakenext->y == food->y) { while (q) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } score += FOOD; gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); printFood(); } else { while (q->next->next) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } gotoxy(q->next->x, q->next->y); color(11); printf("■"); free(q->next); q->next = NULL; } } else if (status == DOWN) { snakenext->x = head->x; snakenext->y = head->y + 1; snakenext->next = head; head = snakenext; q = head; if (snakenext->x == food->x && snakenext->y == food->y) { while (q) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } score += FOOD; gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); printFood(); } else { while (q->next->next) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } gotoxy(q->next->x, q->next->y); color(11); printf("■"); free(q->next); q->next = NULL; } } else if (status == LEFT) { snakenext->x = head->x - 2; snakenext->y = head->y; snakenext->next = head; head = snakenext; q = head; if (snakenext->x == food->x && snakenext->y == food->y) { while (q) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } score += FOOD; gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); printFood(); } else { while (q->next->next) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } gotoxy(q->next->x, q->next->y); color(11); printf("■"); free(q->next); q->next = NULL; } } else if (status == RIGHT) { snakenext->x = head->x + 2; snakenext->y = head->y; snakenext->next = head; head = snakenext; q = head; if (snakenext->x == food->x && snakenext->y == food->y) { while (q) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } score += FOOD; gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); printFood(); } else { while (q->next->next) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } gotoxy(q->next->x, q->next->y); color(11); printf("■"); free(q->next); q->next = NULL; } } } } int biteSelf(void) { int x = 0; // 默认未咬到自己 q = head->next; // 遍历蛇身 while (q->next) { if (q->x == head->x && q->y == head->y) { x = 1; } q = q->next; } return x; } int encounterWall(void) { int x = 0; // 默认未撞到墙 if (head->x == 0 || head->x == 50 || head->y == 0 || head->y == 25) x = 1; return x; } void keyboardControl(void) { status = RIGHT; // 初始蛇向右移动 while (1) { if (GetAsyncKeyState(VK_UP) && status != DOWN) // GetAsyncKeyState函数用来判断函数调用时指定虚拟键的状态 { status = UP; //如果蛇不是向下前进的时候,按上键,执行向上前进操作 } else if (GetAsyncKeyState(VK_DOWN) && status != UP) // 如果蛇不是向上前进的时候,按下键,执行向下前进操作 { status = DOWN; } else if (GetAsyncKeyState(VK_LEFT) && status != RIGHT) // 如果蛇不是向右前进的时候,按左键,执行向左前进 { status = LEFT; } else if (GetAsyncKeyState(VK_RIGHT) && status != LEFT) // 如果蛇不是向左前进的时候,按右键,执行向右前进 { status = RIGHT; } if (GetAsyncKeyState(VK_SPACE))// 空格暂停 { while (1) { Sleep(300); if (GetAsyncKeyState(VK_SPACE)) // 再次按空格改变状态 { break; } } } else if (GetAsyncKeyState(VK_ESCAPE)) { status = ESC; // 按esc键,直接到结束界面 if (endGame()) { Sleep(500); system("cls"); break; } } else if (GetAsyncKeyState(VK_F1)) // 按F1键,加速 { speedUp(); gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); } else if (GetAsyncKeyState(VK_F2)) // 按F2键,减速 { speedDown(); gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); } snakeMove(); } } void speedUp(void) { if (speed <= 280) speed += 20; } void speedDown(void) { if (speed >= 120) speed -= 20; } int endGame(void) { char x = 0; char judge[5]; getchar(); gotoxy(60, 9); printf("确定退出吗?(Yes/No)"); gotoxy(60, 11); s_gets(judge, 5); if (strcmp(judge, "Yes") == 0) { Sleep(250); system("cls"); gotoxy(40, 11); printf("\tBye!"); x = 1; } else x = 0; return x; } char *s_gets(char *st, int n) { char *ret_val; char *find; gotoxy(60, 11); ret_val = fgets(st, n, stdin); if (ret_val) { find = strchr(st, '\n'); if (find) *find = '\0'; else while (getchar() != '\n') continue; } return ret_val; } void frees(snake *s) { snake *current = s; while (current) { current = s; s = current->next; free(current); } }
END
源代码比较长只能先放上去这么多,还有更多的小项目 加一下我的c/c++编程资料交流Q群:214574728