900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > C语言小游戏快速入门--推箱子

C语言小游戏快速入门--推箱子

时间:2019-08-08 11:11:33

相关推荐

C语言小游戏快速入门--推箱子

目录

一、前言二、游戏运行环境三、代码实现逻辑1. game.h2. game.c3. test.c四、总结

一、前言

这是最简单的推箱子了,非常适合初学者。只需要学会一点数组和函数的知识就可以实现。代码的逻辑也不是很难理,就是交换位置。博主实现的推箱子增加了一些花样关卡和颜色,相信很多朋友看完都会受益匪浅。这里我们还是沿用弹跳小球的框架(至于为什么总是沿用这个框架,因为弹跳小球是博主写的第一个小项目,直接搬代码比全部手写快多了),并在原来的框架上增加推箱子所需要的玩法描述。之后加上关卡地图和游戏逻辑就可以实现推箱子啦!先看一下代码的运行效果吧。

二、游戏运行环境

这里就是需要更改一下字符集,否则编译器会报错的。先说报错显示,然后再说更改步骤。这里只讲一种方法。

编译器报错显示:

第一步找到解决方案资源管理器选中你所创建的项目:

第二步:

最后结果:

三、代码实现逻辑

代码逻辑这里是先解释一些难点,然后在附上源码

1. game.h

头文件这里是放一些函数的声明和宏定义。

#pragma once//防止头文件重复包含#include<stdio.h>#include<windows.h>#include<conio.h>#define row 10#define col 10HANDLE hStdin;//控制台句柄void HideCursor();//隐藏光标函数int color(int c);//设置颜色void gotoxy(int x, int y);//设置光标的位置void prompt();//提示框void initMap();//加载当前关卡地图void people_move();//void IsWin();//胜利判断函数void draw_map(int arr[row][col],int x,int y);//打印地图void play_game();//开始游戏void game_help();//游戏帮助void update();//更新日志void showmenu();//游戏菜单

2. game.c

这里放的是代码的实现逻辑,这里需要讲的就是人物推箱子的逻辑。其他的包括地图设计和胜负判断看代码应该都不难理解。人物推箱子逻辑就是让这两个位置交换嘛,下面用图来帮助理解。

实现的代码:

void people_move()//判断人物移动代码{int x1 = 0;int y1 = 0;for (int i=0;i<row;i++){for (int j=0;j<col;j++){if (2==map[i][j]||6==map[i][j]){x1 = j;y1 = i;}}}switch (_getch()){case 'w':case 'W'://上case 72:if (0==map[y1-1][x1]||4==map[y1-1][x1]){map[y1][x1] -= 2;map[y1 - 1][x1] += 2;}else if (3==map[y1-1][x1]||7== map[y1 - 1][x1]){if (0==map[y1 - 2][x1]||4==map[y1-2][x1]){map[y1][x1] -= 2;map[y1 - 1][x1] -= 1;map[y1 - 2][x1] += 3;}}break;case 's':case 'S'://下case 80:if (0 == map[y1 + 1][x1] || 4 == map[y1 + 1][x1]){map[y1][x1] -= 2;map[y1 + 1][x1] += 2;}else if (3 == map[y1 + 1][x1] || 7 == map[y1 + 1][x1]){if (0 == map[y1 +2][x1] || 4 == map[y1 + 2][x1]){map[y1][x1] -= 2;map[y1 + 1][x1] -= 1;map[y1 +2][x1] += 3;}}break;case 'a'://左case 'A':case 75:if (0==map[y1][x1-1]||4==map[y1][x1-1]){map[y1][x1] -= 2;map[y1][x1 - 1] += 2;}else if (3 == map[y1][x1 - 1] || 7 == map[y1][x1 - 1]){if (0 == map[y1][x1 - 2] || 4 == map[y1][x1 - 2]){map[y1][x1] -= 2;map[y1][x1 - 1] -= 1;map[y1][x1 - 2] += 3;}}break;case 'd':case 'D'://右case 77:if (0 == map[y1][x1 + 1] || 4 == map[y1][x1 + 1]){map[y1][x1] -= 2;map[y1][x1 + 1] += 2;}else if (3 == map[y1][x1 + 1] || 7 == map[y1][x1 + 1]){if (0 == map[y1][x1 + 2] || 4 == map[y1][x1 + 2]){map[y1][x1] -= 2;map[y1][x1 + 1] -= 1;map[y1][x1 + 2] += 3;}}break;case 27://ESCsystem("cls");exit(0);break;}}

这里为了实现关卡地图,用到了三维数组来储存地图。这里好像并没有啥好讲的,就是每次开始游戏的时候需要在主函数调用一次加载关卡函数就完了。level是我定义的全局变量,用来表示当前到了第几关。我这里只实现了三关。想要实现更多关卡的话可以自己实现。

//加载当前关卡地图void initMap(){for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){map[i][j] = Map3[level-1][i][j];}}}

这里的胜负判断比较简单,就是判断当前地图上没有箱子就是胜利!并加载下一关。

//胜利判断函数void IsWin(){//如果整个地图中没有箱子则通过此关卡for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){if (map[i][j] == 3){//如果在地图中发现一个箱子则判断为此关卡为不通过return;}}}color(15);printf("游戏胜利!\n");system("pause"); //暂停窗口if (level<3){level++; //通过当前关卡后,进入下一关initMap(); //并加载下一关的地图system("cls");}else{color(12);system("cls");exit(0); //退出程序}}

游戏源码:

#include"game.h"/********************************************* @数字0表示空地* @数字1表示墙* @数字2表示人物* @数字3表示箱子* @数字4表示终点* @数字6表示人物到达终点* @数字7表示箱子到达终点*********************************************/int Map3[3][row][col] ={{//第一关0, 0, 0, 1, 1, 1, 1, 1, 1, 1,1, 1, 1, 1, 0, 0, 0, 0, 0, 1,1, 0, 0, 0, 0, 4, 0, 2, 0, 1,1, 0, 0, 0, 3, 3, 3, 0, 0, 1,1, 0, 4, 1, 1, 4, 1, 1, 4, 1,1, 0, 0, 0, 0, 0, 0, 0, 0, 1,1, 0, 0, 0, 0, 3, 0, 0, 0, 1,1, 0, 0, 3, 0, 4, 0, 0, 0, 1,1, 1, 1, 1, 0, 0, 0, 0, 1, 0,0, 0, 0, 1, 1, 1, 1, 1, 1, 0,},{//第二关0, 1, 1, 1, 1, 1, 1, 1, 1, 0,0, 1, 4, 0, 0, 0, 4, 4, 1, 0,0, 1, 4, 0, 0, 0, 3, 4, 1, 0,1, 1, 1, 0, 0, 0, 0, 3, 1, 1,1, 0, 0, 0, 0, 0, 0, 0, 0, 1,1, 0, 3, 0, 0, 0, 0, 3, 0, 1,1, 0, 1, 1, 3, 1, 1, 1, 0, 1,1, 0, 0, 0, 0, 0, 0, 0, 0, 1,1, 0, 0, 0, 0, 2, 0, 0, 0, 1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},{//第三关1, 1, 1, 1, 1, 1, 1, 1, 1, 0,1, 0, 4, 4, 1, 0, 0, 0, 1, 1,1, 0, 0, 0, 1, 0, 0, 0, 0, 1,1, 0, 0, 0, 3, 0, 3, 0, 0, 1,1, 0, 0, 0, 1, 0, 0, 0, 0, 1,1, 1, 3, 0, 1, 0, 0, 0, 0, 1,1, 1, 4, 0, 4, 0, 1, 4, 0, 1,1, 1, 1, 1, 3, 3, 1, 1, 1, 1,0, 0, 0, 1, 0, 2, 1, 0, 0, 0,0, 0, 0, 1, 1, 1, 1, 0, 0, 0,}};int map[row][col] = {0 };int level = 1; //记录当前关卡,默认为第1关void HideCursor()//隐藏光标函数{CONSOLE_CURSOR_INFO cursor;cursor.bVisible = FALSE;cursor.dwSize = sizeof(cursor);HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorInfo(handle, &cursor);}void gotoxy(int x, int y) //设置光标的位置{COORD c; c.X=x-1; c.Y=y-1;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);} int color(int c)//设置颜色{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);return 0;//改变颜色的函数}void prompt(){gotoxy(21, 1);color(15);printf("||------------------||\n");gotoxy(21, 2);printf("|| 提 示 ||\n");gotoxy(21, 3);printf("|| ||\n");gotoxy(21, 4);printf("||①按wasd或↑←↓→||\n");gotoxy(21, 5);printf("|| 可以移动人物方向 ||\n");gotoxy(21, 6);printf("|| ||\n");gotoxy(21, 7);printf("||②退出请按ESC||\n");gotoxy(21, 8);printf("|| ||\n");gotoxy(21, 9);printf("||③当前关卡为第 关||\n");gotoxy(21, 10);printf("|| ||\n");gotoxy(21, 11); printf("||④祝您游戏愉快! ||\n");gotoxy(21, 12);printf("|| ||\n");gotoxy(21, 13);printf("||------------------||\n");color(12);gotoxy(38, 9);printf("%d", level);gotoxy(21, 13);printf("\n");}//加载当前关卡地图void initMap(){for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){map[i][j] = Map3[level-1][i][j];}}}void people_move(){int x1 = 0;int y1 = 0;for (int i=0;i<row;i++){for (int j=0;j<col;j++){if (2==map[i][j]||6==map[i][j]){x1 = j;y1 = i;}}}switch (_getch()){case 'w':case 'W':case 72:if (0==map[y1-1][x1]||4==map[y1-1][x1]){map[y1][x1] -= 2;map[y1 - 1][x1] += 2;}else if (3==map[y1-1][x1]||7== map[y1 - 1][x1]){if (0==map[y1 - 2][x1]||4==map[y1-2][x1]){map[y1][x1] -= 2;map[y1 - 1][x1] -= 1;map[y1 - 2][x1] += 3;}}break;case 's':case 'S':case 80:if (0 == map[y1 + 1][x1] || 4 == map[y1 + 1][x1]){map[y1][x1] -= 2;map[y1 + 1][x1] += 2;}else if (3 == map[y1 + 1][x1] || 7 == map[y1 + 1][x1]){if (0 == map[y1 +2][x1] || 4 == map[y1 + 2][x1]){map[y1][x1] -= 2;map[y1 + 1][x1] -= 1;map[y1 +2][x1] += 3;}}break;case 'a':case 'A':case 75:if (0==map[y1][x1-1]||4==map[y1][x1-1]){map[y1][x1] -= 2;map[y1][x1 - 1] += 2;}else if (3 == map[y1][x1 - 1] || 7 == map[y1][x1 - 1]){if (0 == map[y1][x1 - 2] || 4 == map[y1][x1 - 2]){map[y1][x1] -= 2;map[y1][x1 - 1] -= 1;map[y1][x1 - 2] += 3;}}break;case 'd':case 'D':case 77:if (0 == map[y1][x1 + 1] || 4 == map[y1][x1 + 1]){map[y1][x1] -= 2;map[y1][x1 + 1] += 2;}else if (3 == map[y1][x1 + 1] || 7 == map[y1][x1 + 1]){if (0 == map[y1][x1 + 2] || 4 == map[y1][x1 + 2]){map[y1][x1] -= 2;map[y1][x1 + 1] -= 1;map[y1][x1 + 2] += 3;}}break;case 27:system("cls");exit(0);break;}}void draw_map(int arr[row][col], int x, int y)//打印地图{for (int i=0;i<x;i++){for (int j=0;j<y;j++){if (1 == arr[i][j]){color(9);printf("■");}else if (2 == arr[i][j]){color(10);printf("♀");}else if (3 == arr[i][j]){color(14);printf("■");}else if (4 == arr[i][j]){color(13);printf("★");}else if (6 == arr[i][j]){color(10);printf("♀");}else if (7 == arr[i][j]){color(12);printf("●");}else{printf(" ");}}printf("\n");}}//胜利判断函数void IsWin(){//如果整个地图中没有箱子则通过此关卡for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){if (map[i][j] == 3){//如果在地图中发现一个箱子则判断为此关卡为不通过return;}}}color(15);printf("游戏胜利!\n");system("pause"); //暂停窗口if (level<3){level++; //通过当前关卡后,进入下一关initMap(); //并加载下一关的地图system("cls");}else{color(12);system("cls");exit(0); //退出程序}}void play_game(){HideCursor();while (1){gotoxy(1, 1);draw_map(map,row,col);prompt();people_move(map, row, col);gotoxy(1, 1);draw_map(map, row, col);prompt();IsWin(); }}static void game_help_menu()//游戏帮助菜单{printf("\n");printf("游戏操作:\n");printf("\n");printf("①:按w a s d 或 ↑ ←↓ →\n");printf("\n");printf(" 可以上下左右控制箱子\n");printf("\n");printf("\n");printf("\n");printf("(按1返回,按任意键退出)\n");printf("请选择:>");}void game_help()//游戏帮助{game_help_menu();switch (_getch()){case '1':break;default:exit(0);break;}}static void update_menu()//更新日志菜单{printf("(暂无)\n");printf("\n");printf("\n");printf("\n");printf("(按1返回,按任意键退出)\n");printf("请选择:>");}void update()//更新日志{update_menu();switch (_getch()){case '1':break;default:exit(0);break;}}void showmenu()//游戏菜单{printf("|----------------------|\n");printf("|1.开始游戏|\n");printf("|----------------------|\n");printf("|2.游戏帮助|\n");printf("|----------------------|\n");printf("|3.更新日志|\n");printf("|----------------------|\n");printf("|0.退出游戏|\n");printf("|----------------------|\n");printf("\n");printf("(温馨提醒:请按照菜单相应的选项选择)");printf("\n");printf("请输入你的选择:>");}

3. test.c

这里主要实现一些函数的调用。

#include"game.h"int main(){SetConsoleTitle("推箱子游戏");//控制台窗口菜单栏上的字system("mode con cols=42 lines=16");//控制台的大小,这里可以按需要自己设置initMap();do{system("cls");showmenu();switch (_getch()){case'1':system("cls");play_game();//开始游戏break;case'2':system("cls");game_help();//游戏帮助break;case'3':system("cls");update();//更新日志break;case'0':exit(0);//退出游戏break;}} while ('0');return 0;}

四、总结

推箱子实现还是很简单。也能知道前面学好框架有多重要。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。