C++实习
来源:互联网 发布:中国荒漠化 知乎 编辑:程序博客网 时间:2024/06/05 20:01
C++暑假实习的前三天的任务就是用C语言做一个贪吃蛇的小游戏,然后开始跟着老师一起做核心功能板块,最后由我们自己去改善和美化我们的程序。下面就介绍一下这个简单的贪吃蛇游戏的实现过程。虽然是个小程序,但是其代码也有一定长度,并且其逻辑性很强,要实现程序的逻辑,必须要模块化地进行编写。以下叙述一下鄙人的思想
1、如何产生一条蛇?
首先用一个符号来作为我们的蛇身,并确定我们蛇的起始位置,规定我们蛇的起始长度,即可,蛇的身体可以用一个数组来存储,而蛇的初始位置可由我们的系统函数确定:
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOut,temp);
2、蛇如何进行运动?
蛇的移动即是我们数组的移动,而根据蛇的运动规律,点的移动新坐标即是前面一个点的旧坐标,因此,点的移动很简单。
3、运动的方向我们如何去控制?
方向的控制和我们蛇的移动息息相关,我们通过得到键盘的输入来控制相应的蛇的移动方向,这里用到了一个按键响应函数:
kbhit();
4、运动的范围该如何设置?
所谓运动的范围,不过是我们给蛇画的一个牢笼,任意在屏幕上用光标设置函数即可确定,就像打印蛇身一样来打印我们的地图。
5、蛇要吃的食物如何产生?
蛇的食物肯定是由随机数产生,然后我们要控制这个随机数在我们画的地图里面产生。
6、蛇如何吃食物?以及设置吃食物后的效果?
吃食物,即是蛇头和食物的坐标一致,然后食物的位置由蛇身代替,我们将蛇走过的轨迹置空,即可屏蔽蛇身的路径。然后当蛇头与食物相遇,我们即可将蛇的长度加1或其他效果
7、蛇要死亡,怎么个死法?
蛇的死法千种万种,可以吃毒食物而死,可以撞到我们的地图框而死,也可以吃到自己而死………………………….
如果能把上面的思路理清,那么写一个贪吃蛇的小游戏也就不难了,下面是我的具体实现代码:
// myproject.cpp : Defines the entry point for the console application.//#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <conio.h >#include <time.h>#define InitLEN 10 //蛇初始长度#define MAXLEN 100 //蛇最大长度#define HIGH 20 //地图高#define WIDTH 40 //地图宽int SnakeLEN=0; //蛇的长度int score=0; //得分int barrier_num =0; //所有障碍物组成点的个数int half; //#define HPRIZON 1//#define VERTICAL 2COORD arr[MAXLEN];COORD tmp_arr[50];COORD food_pos;COORD map_pos;COORD tmp_wall;COORD tmp_barrier;#define RIGHT 39#define LEFT 37#define UP 38#define DOWN 40HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE); //坐标void clearSnake(); //蛇路径清除函数void showSnake(); //蛇的显示函数void creatFood(); //产生食物void creatMap(); //产生地图void die(); //蛇的死亡方式void barrier_save(); void creatBarrier(COORD pos,int dir,int len); //void crossWall();struct wall{ int dir; int len; COORD bPos;};struct wall wall_arr[50];void draw_frame(int W,int H,int initX,int initY) //顺时针画框函数W、H为长度高度;initX ,initY为其实坐标 { COORD pos1={initX,initY}; int i; for(i= 0; i< W;i++) { pos1.X++; SetConsoleCursorPosition(hOut,pos1); printf("."); } for(i= 0; i< H;i++) { pos1.Y++; SetConsoleCursorPosition(hOut,pos1); printf("."); } for(i= 0; i< W;i++) { pos1.X--; SetConsoleCursorPosition(hOut,pos1); printf("."); } for(i= 0; i< H;i++) { pos1.Y--; SetConsoleCursorPosition(hOut,pos1); printf("."); }}void InitSnake(COORD SnakeHead){ int i; COORD temp = SnakeHead; for( i=0 ; i< InitLEN ; i++ ) { arr[i]=temp; HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOut,temp); //API中定位光标位置的函数 printf("@"); temp.X--; } SnakeLEN = InitLEN;}void move(int dir){ int i; Sleep(100); clearSnake(); //将蛇头状态给蛇身 for( i=0;i<SnakeLEN-1;i++) { arr[SnakeLEN-1-i] = arr[SnakeLEN-2-i]; } switch(dir){ case RIGHT: { arr[0].X++; //蛇头运动 break; } case LEFT: { arr[0].X--; break; } case UP: { arr[0].Y--; break; } case DOWN: { arr[0].Y++; break; } default: break; } die(); if(food_pos.X == arr[0].X && food_pos.Y == arr[0].Y ) //头的坐标和食物坐标相同(吃食物变长) { creatFood(); SnakeLEN++; COORD pos2={WIDTH+12,2}; //写计分位置的初始坐标,因为之前方框的起始坐标为(10,1),所以这里都加1。 SetConsoleCursorPosition(hOut,pos2); score++; printf("%d",score); printf(" "); //打印空白用于覆盖上一次计分 }void showSnake(){ int i; for( i=0; i < SnakeLEN;i++) { SetConsoleCursorPosition(hOut,arr[i]); if(i == 0) { printf("@"); } else { printf("*"); } }}void clearSnake() { int i; for( i=0; i < SnakeLEN;i++) { SetConsoleCursorPosition(hOut,arr[i]); printf(" "); }}void barrier_save() //保存所有生成的障碍物的点(所有障碍物由点组成){ tmp_arr[barrier_num]=tmp_barrier; barrier_num++; //全局变量}void creatBarrier(COORD pos,int dir,int len){ int i =0; tmp_barrier=pos; for(;i < len; i++) { static int j=0; SetConsoleCursorPosition(hOut,tmp_barrier); printf("+"); if(dir == 1 ) { tmp_barrier.X++; barrier_save(); //每次改变都会获得一个新的点,需要把这个点记录下来。 } else { tmp_barrier.Y++; barrier_save(); } barrier_save(); }}void kbctrl(){ char ch = 'd'; int dir=RIGHT; while(1) { if(kbhit()) //加入键盘控制,判断是否有按键 { ch=getch(); } switch(ch) //判断是否是 'a' 's' { case 'd': { dir = RIGHT; move(dir); break; } case 's': { dir = DOWN; move(dir); break; } case 'a': { dir = LEFT; move(dir); break; } case 'w': { dir = UP; move(dir); break; } default: { move(dir); break; } } }}void creatFood(){ srand((unsigned)time(NULL)); int x = (rand()%(WIDTH-1)+1); //-1为了产生随机数小于WIDTH,+1为了使产生随机数大于0 int y = (rand()%(HIGH-1)+1); food_pos.X =x; food_pos.Y =y; SetConsoleCursorPosition(hOut,food_pos); printf("o");}void myexit(){ COORD exit_pos={WIDTH+2,HIGH+2}; SetConsoleCursorPosition(hOut,exit_pos); printf("GAME OVER!"); exit(0);}//死亡的方式:void die(){ int i; for(i = 1;i < SnakeLEN-1;i++ ) //吃到自己,就会死掉。 { if(arr[0].X == arr[i].X && arr[0].Y == arr[i].Y) { myexit(); } } if(arr[0].X >= WIDTH || arr[0].X <= 0 || arr[0].Y >= HIGH || arr[0].Y <= 0 ) //撞墙就死掉 { myexit(); } for(i = 0;i < 50;i++ ) //撞到障碍物,死掉 { if(arr[0].X == tmp_arr[i].X && arr[0].Y == tmp_arr[i].Y) { myexit(); } }}/*计分板*/void score_frame(){ //计分方框 draw_frame(10,5,WIDTH+10,0); COORD pos1={WIDTH+11,1}; SetConsoleCursorPosition(hOut,pos1); printf("得分:"); //计分 COORD pos2={WIDTH+12,2}; //写计分位置的初始坐标,因为之前方框的起始坐标为(10,1),所以这里都加1。 SetConsoleCursorPosition(hOut,pos2); printf("%d",score);}int main(int argc, char* argv[]){ system("title 贪吃蛇"); COORD pos={5,3}; crossWall(); draw_frame(WIDTH,HIGH,0,0); score_frame(); InitSnake(pos); creatFood();/* while(1) { move(RIGHT); if(kbhit()) { ch=getch(); break; } }*/ kbctrl(); printf("\n"); return 0;}/////////////////*穿墙超级蛇*/void crossWall(){ srand((unsigned)time(NULL)); int i =0; for ( ; i < 5 ; i++) { tmp_wall.X=(rand()%(WIDTH-3)+3); tmp_wall.Y=(rand()%(HIGH-3)+3); // tmp_arr[i] = tmp_wall; half = (rand()%2+1); //随机获得 1 或者 2 ,两者概率都为二分之一 creatBarrier(tmp_wall,half,3); }}
代码还存在很多缺陷,需要大家一起晚上以及发散思维添加功能。
阅读全文
1 0
- C语言实习
- C语言相关 实习笔记
- 实习
- 实习~!
- 实习
- 实习
- 实习
- 实习
- 实习
- 实习
- 实习
- 实习
- 实习
- 实习
- 实习
- 实习。。。
- 实习
- 实习
- UVA 11988 Broken Keyboard (链表)
- CSS预编译与PostCSS以及Webpack构建CSS综合方案
- NOR Flash擦写和原理分析
- Activiti工作流学习(二)
- 使用SurfaceView实现简单的红包雨动画
- C++实习
- delphi热键设定的方法
- <div><div>的结果
- N
- ubuntu文档保存出现的一些错误
- 不要重新定义继承而来的缺省参数值
- linux命令---sort
- hdu 1272 判断是否为一棵无向树
- android studio导入第三方库和demo