【C++】几个有意思的小游戏

编程入门 行业动态 更新时间:2024-10-13 10:23:56

【C++】<a href=https://www.elefans.com/category/jswz/34/1769605.html style=几个有意思的小游戏"/>

【C++】几个有意思的小游戏

文章目录

    • 黑客帝国
    • 满天星
    • 贪吃蛇

黑客帝国

黑客帝国C++代码包含链表等知识,在娱乐的同时学习知识。

效果如下:

代码如下:

#include <windows.h> #define ID_TIMER 1 
#define STRMAXLEN 25 //一个显示列的最大长度
#define STRMINLEN 8 //一个显示列的最小长度 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	//函数声明typedef struct tagCharChain //整个当作屏幕的一个显示列,这是个双向列表 
{struct tagCharChain *prev; //链表的前一个元素 TCHAR ch; //一个显示列中的一个字符 struct tagCharChain *next; //链表的后一个元素 
}CharChain, *pCharChain;typedef struct tagCharColumn	//字符列
{CharChain *head, *current, *point;int x, y, iStrLen; //显示列的开始显示的x,y坐标,iStrLen是这个列的长度 int iStopTimes, iMustStopTimes; //已经停滞的次数和必须停滞的次数,必须停滞的次数是随机的 
}CharColumn, *pCharColumn;//main入口
int main(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{static TCHAR szAppName[] = TEXT("matrix");HWND hwnd;MSG msg;WNDCLASS wndclass;wndclass.style = CS_HREDRAW | CS_VREDRAW;wndclass.lpfnWndProc = WndProc;wndclass.cbClsExtra = 0;wndclass.cbWndExtra = 0;wndclass.hInstance = hInstance;wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);wndclass.lpszMenuName = NULL;wndclass.lpszClassName = szAppName;if (!RegisterClass(&wndclass)){MessageBox(NULL, TEXT("此程序必须运行在Windows下!"), szAppName, MB_ICONERROR);return 0;}hwnd = CreateWindow(szAppName, NULL,WS_DLGFRAME | WS_THICKFRAME | WS_POPUP,0, 0,GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),NULL, NULL, hInstance,NULL);ShowWindow(hwnd, SW_SHOWMAXIMIZED); //最大化显示 UpdateWindow(hwnd);ShowCursor(FALSE); //隐藏鼠标光标 srand((int)GetCurrentTime()); //初始化随机数发生器 while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}ShowCursor(TRUE); //显示鼠标光标 return msg.wParam;
}//随机字符产生函数 
TCHAR randomChar() 
{return (TCHAR)(rand() % (126 - 33) + 33); //33到126之间 
}//初始化 
int init(CharColumn *cc, int cyScreen, int x) 
{int j;cc->iStrLen = rand() % (STRMAXLEN - STRMINLEN) + STRMINLEN; //显示列的长度 cc->x = x + 3; //显示列的开始显示的x坐标 cc->y = rand() % 3 ? rand() % cyScreen : 0; //显示列的开始显示的y坐标 cc->iMustStopTimes = rand() % 6;cc->iStopTimes = 0;cc->head = cc->current =(pCharChain)calloc(cc->iStrLen, sizeof(CharChain)); //生成显示列 for (j = 0; j < cc->iStrLen - 1; j++){cc->current->prev = cc->point; //cc->point一个显示列的前个元素 cc->current->ch = '\0';cc->current->next = cc->current + 1; //cc->current+1一个显示列的后个元素 cc->point = cc->current++; //cc->point = cc->current; cc->current++; }cc->current->prev = cc->point; //最后一个节点 cc->current->ch = '\0';cc->current->next = cc->head;cc->head->prev = cc->current; //头节点的前一个为此链的最后一个元素 cc->current = cc->point = cc->head; //free掉申请的内存要用current当参数 cc->head->ch = randomChar(); // 对链表头的 元素填充 return 0;
}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{HDC hdc;//ctn 用来确定一个显示链是否 向下前进,如果等待次数超过必须等待的次数,ctn就代表要向下前进 int i, j, temp, ctn; //j为一个显示链中除链表头外的在屏幕上显示的y坐标,temp绿色过度到黑色之用 static HDC hdcMem;HFONT hFont;static HBITMAP hBitmap;static int cxScreen, cyScreen; //屏幕的宽度 高度. static int iFontWidth = 10, iFontHeight = 15, iColumnCount; //字体的宽度 高度, 列数 static CharColumn *ccChain;switch (message){case WM_CREATE:cxScreen = GetSystemMetrics(SM_CXSCREEN); //屏幕宽度 cyScreen = GetSystemMetrics(SM_CYSCREEN);	//屏幕高度SetTimer(hwnd, ID_TIMER, 10, NULL);hdc = GetDC(hwnd);hdcMem = CreateCompatibleDC(hdc);hBitmap = CreateCompatibleBitmap(hdc, cxScreen, cyScreen);SelectObject(hdcMem, hBitmap);ReleaseDC(hwnd, hdc);//创建字体 hFont = CreateFont(iFontHeight, iFontWidth - 5, 0, 0, FW_BOLD, 0, 0, 0,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DRAFT_QUALITY, FIXED_PITCH | FF_SWISS, TEXT("Fixedsys"));SelectObject(hdcMem, hFont);DeleteObject(hFont);SetBkMode(hdcMem, TRANSPARENT); //设置背景模式为 透明 iColumnCount = cxScreen / (iFontWidth * 3 / 2); //屏幕所显示字母雨的列数 ccChain = (pCharColumn)calloc(iColumnCount, sizeof(CharColumn));for (i = 0; i < iColumnCount; i++){init(ccChain + i, cyScreen, (iFontWidth * 3 / 2)*i);}return 0;case WM_TIMER:hdc = GetDC(hwnd);PatBlt(hdcMem, 0, 0, cxScreen, cyScreen, BLACKNESS); //将内存设备映像刷成黑色 for (i = 0; i < iColumnCount; i++){ctn = (ccChain + i)->iStopTimes++ > (ccChain + i)->iMustStopTimes;// (ccChain + i)->point = (ccChain + i)->head; //point用于遍历整个显示列 //第一个字符显示为 白色 SetTextColor(hdcMem, RGB(255, 255, 255));TextOut(hdcMem, (ccChain + i)->x, (ccChain + i)->y, &((ccChain + i)->point->ch), 1);j = (ccChain + i)->y;(ccChain + i)->point = (ccChain + i)->point->next;//遍历整个显示列,将这个显示列里的字符从下往上显示 temp = 0; //temp绿色过度到黑色之用 while ((ccChain + i)->point != (ccChain + i)->head && (ccChain + i)->point->ch){SetTextColor(hdcMem, RGB(0, 255 - (255 * (temp++) / (ccChain + i)->iStrLen), 0));TextOut(hdcMem, (ccChain + i)->x, j -= iFontHeight, &((ccChain + i)->point->ch), 1);(ccChain + i)->point = (ccChain + i)->point->next;}if (ctn)(ccChain + i)->iStopTimes = 0;else continue;(ccChain + i)->y += iFontHeight; //下次开始显示的y坐标 为当前的y坐标加上 一个字符的高度 //如果开始显示的y坐标减去 整个显示列的长度超过了屏幕的高度 if ((ccChain + i)->y - (ccChain + i)->iStrLen*iFontHeight > cyScreen){free((ccChain + i)->current);init(ccChain + i, cyScreen, (iFontWidth * 3 / 2)*i);}//链表的头 为此链表的前个元素,因为下次开始显示的时候 就相当与在整个显示列的开头添加个元素,然后在开始往上显示 (ccChain + i)->head = (ccChain + i)->head->prev;(ccChain + i)->head->ch = randomChar();}BitBlt(hdc, 0, 0, cxScreen, cyScreen, hdcMem, 0, 0, SRCCOPY);ReleaseDC(hwnd, hdc);return 0;case WM_RBUTTONDOWN:KillTimer(hwnd, ID_TIMER);return 0;case WM_RBUTTONUP:SetTimer(hwnd, ID_TIMER, 10, NULL);return 0;//处理善后工作 case WM_KEYDOWN:case WM_LBUTTONDOWN:case WM_DESTROY:KillTimer(hwnd, ID_TIMER);DeleteObject(hBitmap);DeleteDC(hdcMem);for (i = 0; i < iColumnCount; i++){free((ccChain + i)->current);}free(ccChain);PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, message, wParam, lParam);
}

满天星

学习模板类等操作。效果如下:

代码如下:

/*/\/_/\_\/_/_/\_\_\/_/_/_/\_\_\_\/_/\_\/_/_/\_\_\/_/_/_/\_\_\_\/_/_/_/_/\_\_\_\_\/_/_/_/_/_/\_\_\_\_\_\/_/_/\_\_\/_/_/_/\_\_\_\/_/_/_/_/\_\_\_\_\/_/_/_/_/_/\_\_\_\_\_\/_/_/_/_/_/_/\_\_\_\_\_\_\
/_/_/_/_/_/_/_/\_\_\_\_\_\_\_\[__]
*/
//满天星测试程序
#include<iostream>
#include<time.h>
#include<Windows.h>	//windows api
using namespace std;template <typename T>	//STL//输入
void input(T &t)
{char c;cin.get(c);if (c != '\n')	//回车即默认{cin.putback(c);cin >> t;while (cin.get() != '\n');}
}//树状
void tree(char photo[], int kd, int h, int l, int n)
{photo[h * kd + 2 + l] = '/';photo[h * kd + 3 + l] = '\\';for (int i = 0; i < n; i++){photo[h * kd + l + 1 - 2 * i] = '_';photo[h * kd + l + 0 - 2 * i] = '/';}for (int i = 0; i < n; i++){photo[h * kd + l + 4 + 2 * i] = '_';photo[h * kd + l + 5 + 2 * i] = '\\';}}//main入口
int main()
{//初始化值int sl = 1000, de = 8, pl = 50, ph = 24, treeco = 10, kd = 100, gd = 30;srand(time(NULL));CONSOLE_SCREEN_BUFFER_INFO csbi;int ret;HANDLE stdouthwnd = GetStdHandle(STD_OUTPUT_HANDLE);ret = GetConsoleScreenBufferInfo(stdouthwnd, &csbi);if (ret){kd = csbi.dwSize.X - 1;//gd = csbi.dwSize.Y;}pl = kd / 2;ph = gd - 16;cout << "in put print width(default " << kd << "):";input<int>(kd);cout << "in put print height(default " << gd << "):";input<int>(gd);cout << "in put tree color(30-37,default " << treeco << "):";input<int>(treeco);if (treeco > 15 || treeco < 0){cout << "tree color in put error,default is 10(green)" << endl;treeco = 10;}cout << "in put refresh cycke(1000 = 1second,default " << sl << "):";input<int>(sl);cout << "in put tree left blank(default " << pl << "):";input<int>(pl);cout << "in put tree above blank(default " << ph << "):";input<int>(ph);cout << "in put star density(default " << de << "):";input<int>(de);char *photo = new char[kd * gd];const char * EscOut = "Press ESC key to push out";COORD pos;pos.X = 0;pos.Y = 0;while (1){SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);//cout << "\033[0;0H";//rand *for (int i = 0; i < kd * gd; i++){if (i < 25){photo[i] = EscOut[i];}else{if (rand() % de == 0)photo[i] = '*';elsephoto[i] = ' ';}}//treefor (int i = 0; i < 15; i++){int temp = i;if (i > 3)temp -= 2;if (i > 8)temp -= 3;tree(photo, kd, i + ph, pl, temp);}photo[(ph + 15) * kd + pl + 1] = '[';photo[(ph + 15) * kd + pl + 2] = '_';photo[(ph + 15) * kd + pl + 3] = '_';photo[(ph + 15) * kd + pl + 4] = ']';//out for (int i = 0; i < gd; i++){for (int j = 0; j < kd; j++){if (photo[i * kd + j] == '*'){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), rand() % 16);cout << photo[i * kd + j];//cout << "\033[" << rand() % 8 + 30 << "m" << photo[i * kd + j];}else{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), treeco);cout << photo[i * kd + j];//cout << "\033[" << treeco << "m" << photo[i * kd + j];}}if (i < gd - 1)cout << endl;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);if (GetAsyncKeyState(VK_ESCAPE))break;Sleep(sl);if (GetAsyncKeyState(VK_ESCAPE))break;}delete[] photo;return 0;
}

贪吃蛇

学习制作贪吃蛇这样的小游戏,效果如下:

代码如下:

/*
**C++实现简单贪吃snake**
实现贪吃snake的步骤:
1.绘制地图
2.画snake
3.移动
*/
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#include<iostream>
#include<conio.h>
#define random(x) (rand()%x)
using namespace std;int **map;
char c = 0;
int sign = 0;char check_snake(char c);struct snake {int i;int j;struct snake *next;
};struct snake *generateSnake() {struct snake *s;s = (struct snake*)malloc(sizeof(struct snake));struct snake *p = s;int x[6] = { 2, 3, 4, 5, 5, 5 };int y[6] = { 2, 2, 2, 2, 3, 4 };for (int i = 0; i < 6; i++) {struct snake *node; //节点node = (struct snake*)malloc(sizeof(struct snake));p->next = node;p = p->next;p->i = x[i];p->j = y[i];}p->next = NULL;return s;
}  // 设置snake的长度和初始位置void gotoxy(int x, int y)
{COORD Position;Position.X = x;Position.Y = y;//调用API改变字体位置SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Position);
}// 绘制地图
void draw_map(int **map, int height, int weight) {for (int i = 0; i < height; ++i) {for (int j = 0; j < weight; ++j) {if (i == 0 || i == height - 1) {  // 表示在第一层和最后一层  map[i][j] = 1;  // 四边形的四边作为墙,强我们用1表示,表示位置已占}else if (j == 0 || j == weight - 1) { // 表示在最左层和最右层map[i][j] = 1;}else {map[i][j] = 0; // 除墙以外其他位置为0 表示该位置为空}}cout << "\n";}return;
}
// 图形形状
void draw(int **map, int *star, int height, int weight) {system("cls");//清空屏幕gotoxy(0, 0);for (int i = 0; i < height; ++i) {for (int j = 0; j < weight; ++j) {if (map[i][j] == 1) {cout << "■";}else if (map[i][j] == 2){cout << "●";}else if (i == star[0] && j == star[1]){cout << "★";}else {cout << "□";}}cout << '\n';}return;
}// 画snake
void drawSnake(int **map, struct snake *s) {struct snake *p = s->next;map[p->i][p->j] = 2;	// snake头p = p->next;while (p) {map[p->i][p->j] = 1;p = p->next;}return;
}//画star
void draw_star(int **map, int *star, int height, int weight) {int sum = 0; // 空格子的个数int index = 0; // 剩下的格子// 算出空格子的个数for (int i = 0; i < height; ++i) {for (int j = 0; j < weight; ++j) {if (map[i][j] == 0){sum += 1;}}}index = random(sum) + 1; // 在1到sum 中随机的位置生成星星//生成星星for (int i = 0; i < height; ++i) {for (int j = 0; j < weight; ++j) {if (map[i][j] == 0) {index -= 1;}if (index == 0) {star[0] = i;star[1] = j;return;}}}return;
}//状态更新
void update_snake(char c, struct snake *s, int *star) {snake *newsnake;newsnake = (snake*)malloc(sizeof(snake));if (c == 'w') {// 相当于在s 头插一个新节点newsnake->i = s->next->i - 1;newsnake->j = s->next->j;if (map[newsnake->i][newsnake->j] == 1) {// 头插的节点的位置 原本 map[i][j] == 1 表示该位置是墙或者是snake身了sign = 3;}else if (newsnake->i == star[0] && newsnake->j == star[1]) {newsnake->next = s->next;s->next = newsnake;struct  snake *q = s;while (q->next->next != NULL) {gotoxy(q->i, q->j);printf("■");  // 恢复snake身q = q->next;}sign = 2;}else {newsnake->next = s->next;s->next = newsnake;struct  snake *q = s;while (q->next->next != NULL) {gotoxy(q->i, q->j);printf("■");q = q->next;}gotoxy(q->i, q->j);printf("■");map[q->next->i][q->next->j] = 0;free(q->next);q->next = NULL;}}else if (c == 's') {newsnake->i = s->next->i + 1;newsnake->j = s->next->j;if (map[newsnake->i][newsnake->j] == 1) {sign = 3;}if (newsnake->i == star[0] && newsnake->j == star[1]) {newsnake->next = s->next;s->next = newsnake;struct  snake *q = s;while (q->next->next != NULL) {gotoxy(q->i, q->j);printf("■");q = q->next;}sign = 2;}else {newsnake->next = s->next;s->next = newsnake;struct  snake *q = s;while (q->next->next != NULL) {gotoxy(q->i, q->j);printf("■");q = q->next;}gotoxy(q->i, q->j);printf("■");map[q->next->i][q->next->j] = 0;free(q->next);q->next = NULL;}}else if (c == 'a') {newsnake->i = s->next->i;newsnake->j = s->next->j - 1;if (map[newsnake->i][newsnake->j] == 1) {sign = 3;}if (newsnake->i == star[0] && newsnake->j == star[1]) {newsnake->next = s->next;s->next = newsnake;struct  snake *q = s;while (q->next->next != NULL) {gotoxy(q->i, q->j);printf("■");q = q->next;}sign = 2;}else {newsnake->next = s->next;s->next = newsnake;struct  snake *q = s;while (q->next->next != NULL) {gotoxy(q->i, q->j);printf("■");q = q->next;}gotoxy(q->i, q->j);printf("■");map[q->next->i][q->next->j] = 0;free(q->next);q->next = NULL;}}else {newsnake->i = s->next->i;newsnake->j = s->next->j + 1;if (map[newsnake->i][newsnake->j] == 1) {sign = 3;}if (newsnake->i == star[0] && newsnake->j == star[1]) {newsnake->next = s->next;s->next = newsnake;struct  snake *q = s;while (q->next->next != NULL) {gotoxy(q->i, q->j);printf("■");q = q->next;}sign = 2;}else {newsnake->next = s->next;s->next = newsnake;struct  snake *q = s;while (q->next->next != NULL) {gotoxy(q->i, q->j);printf("■");q = q->next;}gotoxy(q->i, q->j);printf("■");map[q->next->i][q->next->j] = 0;free(q->next);q->next = NULL;}}
}// snake 移动方向
// 上 119 wd
// 下 115 s
// 左 97  a
// 右 100 d
void action_snake(struct snake *s, int *star) {switch (c){//向上case 'w':update_snake(c, s, star);break;//向下case 's':update_snake(c, s, star);break;//向左case 'a':update_snake(c, s, star);break;//向右case 'd':update_snake(c, s, star);break;}
}//检查snake状态
void check_snake() {DWORD time = 500; // 1表示一毫秒 1000表示一秒  要改变速度可以修改time的时间DWORD time_start = GetTickCount();  // 获取当前时间char t;while (true) {if (_kbhit()) {char ch = _getch(); // 当前键位if (ch == 97 || ch == 100 || ch == 115 || ch == 119) {t = ch;if (t == 97 && c == 'd'){c = 'd';}else if (t == 100 && c == 'a') {c = 'a';}else if (t == 115 && c == 'w') {c = 'w';}else if (t == 119 && c == 's') {c = 's';}else {c = ch;}}}DWORD time_end = GetTickCount(); // 获取键位后的时间if (time_end - time_start > time) {time_start = time_end;break;}}return;
}int main() {//地图参数int height = 40; // 地图高度  map.height = 20int weight = 40; // 地图宽度  map.weight = 20struct snake *s = generateSnake();map = (int **)malloc(sizeof(int*)*height);for (int i = 0; i < height; ++i) {map[i] = (int *)malloc(sizeof(int)*weight);}draw_map(map, height, weight);	//画地图drawSnake(map, s);	//画snakeint star[2] = { 0,0 };draw_star(map, star, height, weight);	//画stardraw(map, star, height, weight);//进入死循环while (1) {if (sign == 3) {break;}check_snake();action_snake(s, star);draw_map(map, height, weight);drawSnake(map, s);if (sign == 2) {draw_star(map, star, height, weight);sign = 0;}draw(map, star, height, weight);gotoxy(0, 0);}system("cls");gotoxy(height / 2, weight / 2);cout << "游戏结束 ";system("pause");return 0;
}

以上。

更多推荐

【C++】几个有意思的小游戏

本文发布于:2024-02-06 14:28:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1749269.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:几个   小游戏   有意思

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!