汕头网站建设推广,河南旅游网站建设,pytson做网站安全吗,北京专业网站开发环境要求#xff1a;
1、VS2015以上
2、成功安装并配置图形库
项目注意事项#xff1a;代码复制好以后#xff0c;把下面的字符集改为多字节字符集 第 1 节 项目需求 实现一款推箱子游戏#xff0c;效果如下图所示 , 具体规则#xff1a; 1. 箱子只能推动而不能拉动…环境要求
1、VS2015以上
2、成功安装并配置图形库
项目注意事项代码复制好以后把下面的字符集改为多字节字符集 第 1 节 项目需求 实现一款推箱子游戏效果如下图所示 , 具体规则 1. 箱子只能推动而不能拉动 2. 如果箱子前一格是地板或箱子目的地则可以推动一个箱子往前走一格如果箱子已经在 箱子目的地则不能再推动 3. 推箱子的小人不能从箱子目的地上直接穿过 4. 注意不要把箱子推到死角上不然就无法再推动它了 5. 所有箱子都成功推到箱子目的地游戏结束过关成功 第 2 节 项目实现
2.1 模块划分 作用 1. 化繁为简 2. 适合团队协作 3. 高质量代码 2.1.1 地图初始化
搭台唱戏 戏台坐标系 (650 x 650) 地图表示: 使用二维数组 1、游戏道具显示墙、箱子、箱子目的地、小人、地板 2、便于程序在游戏过程中进行逻辑判断和控制小人向前一步的动作控制 3、 判断游戏结果 道具表示: 墙 : 0 地板 : 1 箱子目的地 : 2, 小人 : 3, 箱子 : 4, 箱子命中目标 : 5 编码实现
#include graphics.h
#include iostream
#include stdlib.h
#include string
using namespace std;
#define RATIO 61
#define SCREEN_WIDTH 960
#define SCREEN_HEIGHT 768
#define LINE 9
#define COLUMN 12
#define START_X 100
#define START_Y 150
IMAGE images[6];
/*游戏地图*/
int map[LINE][COLUMN] {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },{ 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },
{ 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
{ 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },
{ 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
int main(void) {IMAGE bg_img;//搭台唱戏initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);loadimage(bg_img, _T(blackground.bmp), SCREEN_WIDTH,SCREEN_HEIGHT, true);putimage(0, 0, bg_img);//加载道具图标loadimage(images[0], _T(wall.bmp), RATIO, RATIO, true);loadimage(images[1], _T(floor.bmp), RATIO, RATIO, true);loadimage(images[2], _T(des.bmp), RATIO, RATIO, true);loadimage(images[3], _T(man.bmp), RATIO, RATIO, true);loadimage(images[4], _T(box.bmp), RATIO, RATIO, true);loadimage(images[5], _T(box.bmp), RATIO, RATIO, true);for (int i 0; i LINE; i) {for (int j 0; j COLUMN; j) {putimage(START_X j * RATIO, START_Y i * RATIO,images[map[i][j]]);}}system(pause);return 0;
}
2.1.2 热键控制
热键定义 左 a 下 s 上 w 右 d 退出 q #include conio.h
//控制键 上、下、左、右 控制方向q 退出
#define KEY_UP w //char a
#define KEY_LEFT a
#define KEY_RIGHT d
#define KEY_DOWN s
#define KEY_QUIT q
//游戏环节
bool quit false;
do {if (_kbhit()) { //玩家按键char ch _getch();if (ch KEY_UP) {gameControl(UP);}else if (ch KEY_DOWN) {gameControl(DOWN);}else if (ch KEY_LEFT) {gameControl(LEFT);}else if (ch KEY_RIGHT) {gameControl(RIGHT);}else if (ch KEY_QUIT) {quit true;}}Sleep(100);
} while (quit false); //!quit
2.1.3 推箱子控制
/**********************************************
*实现游戏四个方向上、下、左、右的控制
* 输入
* direct - 人前进方向
* 输出 无
**********************************************/
void gameControl(enum _DIRECTION direct) {struct _POS next_pos man;struct _POS next_next_pos man;switch (direct) {case UP:next_pos.x--;next_next_pos.x - 2;break;case DOWN:next_pos.x;next_next_pos.x 2;break;case LEFT:next_pos.y--;next_next_pos.y - 2;break;case RIGHT:next_pos.y;next_next_pos.y 2;break;}//宏展开 next_pos.x0 next_pos.xLINE next_pos.y0 next_pos.y COLUMNif (isValid(next_pos) map[next_pos.x][next_pos.y] FLOOR) {//人的前方是地板changeMap(next_pos, MAN); //小人前进一格changeMap(man, FLOOR);man next_pos;}else if (isValid(next_next_pos) map[next_pos.x][next_pos.y] BOX) {//人的前方是箱子//两种情况箱子前面是地板或者是箱子目的地if (map[next_next_pos.x][next_next_pos.y] FLOOR) {changeMap(next_next_pos, BOX);changeMap(next_pos, MAN); //小人前进一格changeMap(man, FLOOR);man next_pos;}else if (map[next_next_pos.x][next_next_pos.y] BOX_DES) {changeMap(next_next_pos, HIT);changeMap(next_pos, MAN); //小人前进一格changeMap(man, FLOOR);man next_pos;}}
}
2.1.4 游戏结束
/**********************************************
*判断游戏是否结束如果不存在任何一个箱子目的地就代表游戏结束
*输入 无
*返回值
* true - 游戏结束 false - 游戏继续
**********************************************/
bool isGameOver() {for (int i 0; i LINE; i) {for (int j 0; j COLUMN; j) {if (map[i][j] BOX_DES) return false;}}return true;
}
/**********************************************
*游戏结束场景在玩家通关后显示
*输入
* bg - 背景图片变量的指针
*返回值 无
**********************************************/
void gameOverScene(IMAGE* bg) {putimage(0, 0, bg);settextcolor(WHITE);RECT rec { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };settextstyle(20, 0, _T(宋体));drawtext(_T(恭喜您~ \n 您终于成为了一个合格的搬箱子老司机),rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
//main 函数中
if (isGameOver()) {gameOverScene(bg_img);quit true;
} 3、完整代码实现
box_main.cpp
#pragma once#includebox_man.hint main() {initgraph(WEIGHT, HEIGHT);IMAGE bg_img;//参数分别表示图片变量的地址图片的路径图片的高度宽度是否要拉伸//用_T()是为了进行编码转换也可以更改项目属性——高级——多字符集loadimage(bg_img, _T(blackground.bmp), WEIGHT, HEIGHT, true);//加载图片到内存putimage(0, 0, bg_img);//把图片显示到窗口参数分别表示坐标x坐标y从左上角开始计算图片变量地址//加载道具loadimage(images[WALL], _T(wall_right.bmp), RATIO, RATIO, true);//墙loadimage(images[FLOOR], _T(floor.bmp), RATIO, RATIO, true);//地板loadimage(images[BOX_DES], _T(des.bmp), RATIO, RATIO, true);//目的地loadimage(images[MAN], _T(man.jpg), RATIO, RATIO, true);//小人loadimage(images[BOX], _T(box.jpg), RATIO, RATIO, true);//箱子loadimage(images[HIT], _T(des.jpg), RATIO, RATIO, true);//目标命中地图刚开始时没有数字5的因此这个到后面判断游戏才发挥作用//加载到地图上for (int i 0; i LINE; i) {for (int j 0; j COLUMN; j) {if (map1[i][j] MAN) {//找到小人的位置man.x i;man.y j;}putimage(WEIGHT_BIAS j * RATIO, HEIGHT_BIAS i * RATIO, images[map1[i][j]]);//核心代码段这个代码非常漂亮利用行列坐标直接求出图片的位置}}//进入游戏环节bool quit false;do{if (_kbhit()) //玩家有敲击键盘的操作{char ch _getch(); //获取敲击的热键switch (ch){case w:gameControl(UP);break;case a:gameControl(LEFT);break;case s:gameControl(DOWN);break;case d:gameControl(RIGHT);break;case q:quit true;break;default:break;}Sleep(100); //因为一直在循环一直在消耗CPU休眠可以节约CPU资源if (isGameOver()) { //游戏结束GameOverField(bg_img);quit true;}} } while (quit false);//游戏结束system(pause);closegraph();return 0;
}
function.cpp
#includeiostream
#includeiostream
#includeWindows.h
#includegraphics.h
#includestdlib.h
#includestring
#includeconio.h //获取键盘的热键
#includemmsystem.h//音乐头文件
#pragma comment(lib,winmm.lib)//支持音乐播放的库文件
using namespace std;#define WEIGHT 1190 //游戏窗口的宽度
#define HEIGHT 800 //游戏窗口的高度#define LINE 9 //地图的行数
#define COLUMN 12 //地图的列数#define KEY_UP w //上键
#define KEY_LEFT a //左键
#define KEY_DOWN s //下键
#define KEY_RIGHT d //右键
#define KEY_QUIT q //退出#define WEIGHT_BIAS 300 //地图离整个画布的横向偏移
#define HEIGHT_BIAS 150 //地图离整个画布的纵向偏移
#define RATIO 61 //小人物、强、箱子等元素的长和宽//把判断条件用宏来替换
#define isValid(pos) pos.x 0 pos.x LINE pos.y 0 pos.y COLUMN map1[pos.x][pos.y]//小人所在二维数组的位置行数和列数
struct _POS {//很多开源项目结构体名用下划线开头int x;int y;
};
struct _POS man;typedef enum _DIRECTION {UP,DOWN,LEFT,RIGHT
}DIRECTION;//用枚举定义道具
enum _PROPS {WALL, //墙FLOOR, //地板BOX_DES, //目的地MAN, //小人BOX, //箱子HIT, //命中目标ALL //为什么最后还要定义一个ALL为了定义下面images数组的长度这是顶尖项目的经验
};IMAGE images[ALL]; //存放各类道具图片变量//地图1假设后面还要做几个关卡那么map1表示第一关
int map1[LINE][COLUMN] {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
{ 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },
{ 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
{ 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },
{ 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};/*
小人发生移动时改变地图中游戏的道具line 地图的行下标colum 地图的列下标pros 道具的类型
*/void changeMap(struct _POS* pos, enum _PROPS pros) {map1[pos-x][pos-y] pros; //更改地图的状态putimage(WEIGHT_BIAS pos-y * RATIO, HEIGHT_BIAS pos-x * RATIO, images[pros]);}/*
实现游戏四个方向的移动
这里有很大的优化空间
*/
//版本1
//void gameControl(DIRECTION direct) {
// if (direct UP) {//先处理前进方向是地板的情况
// if (man.x - 1 0 map1[man.x - 1][man.y] FLOOR) {//防御式编程判断坐标的合法性
// changeMap(man.x-1, man.y, MAN); //小人的往上走一格
// changeMap(man.x, man.y, FLOOR);//小人原来的位置设置为地板
// man.x man.x - 1;//调整小人的坐标
// }
// }
// else if (direct DOWN) {
// if (man.x 1 LINE map1[man.x 1][man.y] FLOOR) {
// changeMap(man.x 1, man.y, MAN); //小人的往下走一格
// changeMap(man.x, man.y, FLOOR);//小人原来的位置设置为地板
// man.x man.x 1;//调整小人的坐标
// }
// }
// else if (direct LEFT) {
// if (man.y - 1 0 map1[man.x][man.y - 1] FLOOR) {
// changeMap(man.x, man.y-1, MAN); //小人的往左走一格
// changeMap(man.x, man.y, FLOOR);//小人原来的位置设置为地板
// man.y man.y - 1;//调整小人的坐标
// }
// }
// else if (direct RIGHT) {
// if (man.y 1 COLUMN map1[man.x][man.y 1] FLOOR) {
// changeMap(man.x, man.y 1, MAN); //小人的往右走一格
// changeMap(man.x, man.y, FLOOR);//小人原来的位置设置为地板
// man.y man.y 1;//调整小人的坐标
// }
// }
//}//版本2,简化代码提高代码重用率
void gameControl(DIRECTION direct) {struct _POS next_man man;struct _POS next_box man;switch (direct) {case UP:next_man.x--;next_box.x - 2;break;case DOWN:next_man.x;next_box.x 2;break;case LEFT:next_man.y--;next_box.y - 2;break;case RIGHT:next_man.y;next_box.y 2;break;}/*判断条件太长用宏定义替换来优化*///if (next_man.x 0 next_man.x LINE // next_man.y 0 next_man.y COLUMN // map1[next_man.x][next_man.y] FLOOR) {//防御式编程判断坐标的合法性// changeMap(next_man.x, next_man.y, MAN); //小人的往上走一格// changeMap(man.x, man.y, FLOOR);//小人原来的位置设置为地板// man next_man;//调整小人的坐标//}if (isValid(next_man) map1[next_man.x][next_man.y] FLOOR) {//防御式编程判断坐标的合法性//changeMap(next_man.x, next_man.y, MAN); //小人的往上走一格//changeMap(man.x, man.y, FLOOR);//小人原来的位置设置为地板//结构体传递用指针传递提高效率进一步优化changeMap(next_man, MAN);changeMap(man, FLOOR);man next_man;//调整小人的坐标}else if (isValid(next_man) map1[next_man.x][next_man.y] BOX) {//第一种情况箱子前面是地板if (isValid(next_box) map1[next_box.x][next_box.y] FLOOR) {changeMap(next_box, BOX);changeMap(next_man, MAN);changeMap(man, FLOOR);man next_man;}//第二种情况前面是箱子else if (isValid(next_box) map1[next_box.x][next_box.y] BOX_DES) {changeMap(next_box, HIT);changeMap(next_man, MAN);changeMap(man, FLOOR);man next_man;}//第二种情况箱子前面是目的地}
}/*
判断游戏是否结束如果地图中没有箱子目的地说明说有箱子已经全部移动到指定位置
游戏结束反之没有结束
*/
bool isGameOver() {for (int i 0; i LINE; i) {for (int j 0; j COLUMN; j) {if (map1[i][j] BOX_DES) {return false;}}}return true;
}/*
游戏结束场景
*/
void GameOverField(IMAGE* bg) {putimage(0, 0, bg);settextcolor(WHITE);RECT rec { 0,0,WEIGHT,HEIGHT };settextstyle(100, 0, _T(宋体));loadimage(NULL, _T(游戏结束背景.jpg));//加载胜利图片//音乐播放mciSendString(_T(play 游戏结束.mp3), 0, 0, 0);outtextxy(WEIGHT_BIAS, HEIGHT / 2, _T(恭喜你通关啦));}
box_man.h
#pragma once //头文件文件只包含一次#ifndef TEST_H
#define TEST_H
#includegraphics.h
#includeconio.h //获取键盘的热键#define WEIGHT 1190 //游戏窗口的宽度
#define HEIGHT 800 //游戏窗口的高度#define LINE 9 //地图的行数
#define COLUMN 12 //地图的列数#define RATIO 61 //小人物、强、箱子等元素的长和宽#define WEIGHT_BIAS 300 //地图离整个画布的横向偏移
#define HEIGHT_BIAS 150 //地图离整个画布的纵向偏移enum _PROPS {WALL, //墙FLOOR, //地板BOX_DES, //目的地MAN, //小人BOX, //箱子HIT, //命中目标ALL //为什么最后还要定义一个ALL为了定义下面images数组的长度这是顶尖项目的经验
};extern IMAGE images[ALL]; //存放各类道具图片变量typedef enum _DIRECTION {UP,DOWN,LEFT,RIGHT
}DIRECTION;struct _POS {//很多开源项目结构体名用下划线开头int x;int y;
};
extern struct _POS man;extern int map1[LINE][COLUMN];//函数声明一定要放在最后void changeMap(struct _POS* pos, enum _PROPS pros);
void gameControl(DIRECTION direct);
bool isGameOver();
void GameOverField(IMAGE* bg);#endif
如果图形库正常安装项目属性字符集改为多字节字符集就可以运行了。 运行我这里用的其他图片元素做的 胜利后 可能大家代码写好但是没有图像资源文件 大家可以私聊我一件三连免费送。没有图像资源光有代码运行不起来。