ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

飞翔的年兽

2022-02-03 12:33:07  阅读:141  来源: 互联网

标签:柱子 int void move 飞翔 Pipe printf


创建常量

#define UP_DOWN_DISTANCE 5  //上下柱子之间的距离
#define LEFT_RIGHT_DISTANCE 20 //左右柱子之间的距离
#define LENGTH 6 //储存随机数

创建结构体

  • 年兽

    struct bird {
        //年兽的形象
        char ch[10];
    	//年兽的初始位置
    	int x;
    	int y;
    	int speed;//年兽的速度
    }={"○",15,13,2};
    
  • 柱子

    struct pillar
    {
    	//柱子的起始坐标
    	int x;
    	int y;
    	int hight;//柱子的高度
    
    };
    

设置光标

  • 还是抄就行

    void gotoxy(int x, int y)
    {
    	COORD pos = { x,y };
    	HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    	SetConsoleCursorPosition(hout, pos);
    }
    

创建界面

  • 界面大小

    system("mode con cols=120 lines=30");//cols是列,lines是行
    
  • 开始界面

    void startMap()
    {
    	printf("\n\n\n");
    	printf("\t\t\t----------------------------------------------------------------------\n");
    	printf("\t\t\t-                                                                    -\n");
    	printf("\t\t\t-                                                                    -\n");
    	printf("\t\t\t-                             开始游戏                               -\n");
    	printf("\t\t\t-                                                                    -\n");
    	printf("\t\t\t-                                                                    -\n");
    	printf("\t\t\t----------------------------------------------------------------------\n\n\n");
    	gotoxy(51, 15);
    	system("pause");
    }
    
  • 结束界面

    void endMap()
    {
    
    	system("cls");
    	printf("\n\n\n");
    	printf("\t\t\t----------------------------------------------------------------------\n");
    	printf("\t\t\t-                                                                    -\n");
    	printf("\t\t\t-                                                                    -\n");
    	printf("\t\t\t-                             开始结束                               -\n");
    	printf("\t\t\t-                           你的得分为:%d                           -\n",score);
    	printf("\t\t\t-                                                                    -\n");
    	printf("\t\t\t----------------------------------------------------------------------\n\n\n");
    	gotoxy(51, 15);
    	system("pause");
    }
    

设置年兽

  • 画年兽

    void drawBird(int y)
    {
    	gotoxy(flyBird.x, y);
    	printf("%s", flyBird.ch);
    }
    
    
  • 覆盖掉年兽

    void deleteBird(int y)
    {
    	gotoxy(flyBird.x, y);
    	printf("  ");
    }
    
  • 年兽向上升,别看现在只有一行代码,后面用来判断是否会和柱子碰撞有用

    void birdJump(int y)
    {
    	deleteBird(y);
    	flyBird.y -= flyBird.speed;
    }
    

判断是否会撞墙

  • 撞到墙会返回1,否则就返回0

    int isHitFloor(int y)
    {
    	if (flyBird.y < 0 || flyBird.y > 28)
    	{
    		return 1;
    	}
    	else {
    		return 0;
    	}
    }
    

    当返回1时,就退出循环

    		if (isHitFloor(flyBird.y))
    		{
    			break;
    		}
    

设置柱子

  • 利用随机数,设置上下柱子的长度

    void arrayRand()
    {
    	for (int i = 0; i < LENGTH; i++)
    	{
    		Pipe[i].hight = rand() % 10 + 10;
    	}
    }
    
  • 创建柱子

    void creatPipe(int move)
    {
    	int i = 0;
    	int y = 0;
    	int x = 0;
    	for (x = 31-move ; x < 120; x += LEFT_RIGHT_DISTANCE)//循环五次,在指定位置生成五个柱子
    	{
    		
    		//生成上半部分的柱子
    		for (y = 0; y < Pipe[i].hight; y++) {
    			gotoxy(x, y);
    			printf("*");
    		}
    		
    		//实时记录柱子的位置
    		Pipe[i].x = x;
    		Pipe[i].y_up = Pipe[i].hight;
    		Pipe[i].y_down = y + UP_DOWN_DISTANCE;
    		//生成下半部分的柱子
    		for (y = y + UP_DOWN_DISTANCE; y < 30; y++)
    		{
    			gotoxy(x, y);
    			printf("*");
    		}
    		i++;
    	}
    }
    
    • 为了检测柱子的信息是否正确,写了一个打印函数来确认

      void printPipe()
      {
      	for (int i = 0; i < LENGTH; i++)
      	{
      		gotoxy(0, i);
      		printf("%d %d %d\n", Pipe[0].x, Pipe[0].y_up, Pipe[0].y_down);
      	}
      }
      
  • 覆盖柱子

    void deletePipe(int move)
    {
    	int i = 0;
    	int y = 0;
    	int x = 0;
    	for (x = 31-move; x < 120; x += LEFT_RIGHT_DISTANCE)//循环五次,覆盖掉指定位置的柱子
    	{
    
    		//覆盖掉上半部分的柱子
    		for (y = 0; y < Pipe[i].hight; y++) {
    			gotoxy(x, y);
    			printf(" ");
    		}
    
    		//覆盖掉下半部分的柱子
    		for (y = y + UP_DOWN_DISTANCE; y < 30; y++)
    		{
    			gotoxy(x, y);
    			printf(" ");
    		}
    
    		i++;
    	}
    }
    
  • 柱子的移动

    void movePipe()
    {
    	move = 0;
    	arrayRand();
    	while (1)
    	{
    		creatPipe(move);
    		Sleep(200);
    		deletePipe(move);
    		move++;
    
    		//简单的来说,就是将第一个柱子接到第六条柱子后面,但第一条柱子再次出场时,数值发生了改变
    		if (move == 20)
    		{
    			//当第一条柱子移动了20个单位时(此刻此刻的年兽以及穿过柱子了),将偏移量move归零
    			move = 0;
    			//此刻将第二个随机数以后的数都向前移动一位,将第一个随机数覆盖掉,空出最后一个位置
    			for (int i = 0; i < LENGTH - 1; i++)
    			{
    				Pipe[i].hight = Pipe[i + 1].hight;
    			}
    			//重新生成一个随机数放到最后一位
    			Pipe[LENGTH - 1].hight = rand() % 10 + 10;
    
    		}
    	}
    }
    
  • 接下来就是将年兽的移动和柱子的移动进行结合了

运行

  • 年兽的上下运动,柱子的移动,分数的计算都在这里完成

    void run()
    {
    	startMap();//开始界面
    	move = 0;
    	arrayRand();//生成随机数
    	while (1)
    	{
    		drawBird(flyBird.y);//初始化年兽
    		creatPipe(move);//柱子初始化(在界面生成5条柱子) 
    		for (int i = 0; i < 10; i++)//该循环可当作时间延迟
    		{
    			if (_kbhit())
    			{
    				//该出判断用来打断下降的时间循环,即刚按下按键就可让年兽向上升,不用等到每一次下降的时间结束在再上升
    				//可让年兽的上升操作更顺畅
    				char ch = _getch();
    				if (ch == 32)//空格的ascil码为32
    				{
    					birdJump(flyBird.y);//让年兽上升
    					break;
    				}
    
    			}
    			Sleep(1);//睡眠1毫秒,20次循环共20毫秒,但是可能里面的函数运行时会有时间延迟,所以总时间不止20毫秒
    		}
    		if (isHitFloor(flyBird.y) || isHitPipe())//判断是否会撞到边界或柱子
    		{
    			Sleep(1000);//死亡后,睡眠1秒
    			break;
    		}
    
    		getScore();//得分
    
    		deleteBird(flyBird.y);//覆盖掉上一个年兽的痕迹
    		deletePipe(move);//覆盖掉上一个柱子的痕迹
    		move++;//偏移量加1,即柱子向左移动
    
    		if (move == 20)
    		{
    			//当第一条柱子移动了20个单位时(此刻此刻的年兽以及穿过柱子了),将偏移量move归零
    			move = 0;
    			//此刻将第二个随机数以后的数都向前移动一位,将第一个随机数覆盖掉,空出最后一个位置
    			for (int i = 0; i < LENGTH - 1; i++)
    			{
    				Pipe[i].hight = Pipe[i + 1].hight;
    			}
    			//重新生成一个随机数放到最后一位
    			Pipe[LENGTH - 1].hight = rand() % 10 + 10;
    
    		}
    
    		
    		flyBird.y += 1;//下降1的单位
    	}
    	endMap();//结束界面
    }
    
    

得分

  • 需要注意的一个点是getScore()函数要放在判断是否会撞到墙的if语句之后,因为两者都对(Pipe[0].x==flyBird.x)成立。如果getScore()放在判断是否会撞到墙的if语句之前,就算年兽撞到了墙,还是会加1 分后在死亡

    void getScore()
    {
    	gotoxy(0, 0);
    	printf("得分:%d", score);
    	if (Pipe[0].x == flyBird.x)
    	{
    		score++;
    	}
    }
    

选择角色

  • 为了增加游戏的趣味性,这一功能是特别加入的

  • 箭头图标(需要将界面调大)

    void selectMap()
    {
    	system("cls");
    	printf("\n\n\n\n\n");
    	printf("\t\t\t\t\t\t      请选择角色\n");
    	printf("\n\n\n\n\n");
    	
    	printf("\t\t\t\t      *                                         *                     \n");
    	printf("\t\t\t\t    * *                                         * *                      \n");
    	printf("\t\t\t\t  * * *                                         * * *             \n");
    	printf("\t\t\t\t    * *                                         * *              \n");
    	printf("\t\t\t\t      *                                         *                     \n");
    	
    
    }
    
  • 选择功能

    void selectRole()
    {
    	char role[10][5] = { "★","○","□" ,"=","@" };//“年兽”
    	int flag = 0;
    	while (1)
    	{
    		for (int i = 12; i < 15; i++)
    		{
    			gotoxy(59, i);
    			printf("%s", role[flag]);
    			for (int j = 0; j < 15; j++)
    			{
    				if (_kbhit())
    				{
    					//回车,ASCII码13;“键盘上下左右 方向键的键码(keyCode)是38、40、37和39,或者称虚拟ASCII值是38、40、37和39。”
    					char ch = _getch();
    					if (ch == 77 && flag < 4)//空格的ascil码为32
    					{
    						flag++;
    					}
    					else if (ch == 75 && flag > 0)
    					{
    						flag--;
    					}
    					else if (ch == 32)
    					{
    						system("cls");
    						return;
    					}
    				}
    				strcpy_s(flyBird.ch, role[flag]);
    				Sleep(1);
    			}
    			gotoxy(59, i);
    			printf("  ");
    			
    			
    		}
    		
    		
    	}
    
    }
    

新年祝福

  • 好吧,由于界面的原因,现在显示出来的东西很乱
void printNewYear()
{
	system("cls");
	printf("\n\n\n\n\n");


	printf("\t      *                                  *                  *               *                      *    \n");
	printf("\t       *                 *             *                    *               *                    *      \n");
	printf("\t  * * * * * * *        *             * * * * * * * * *      *        * * * * * * *            *         \n");
	printf("\t    *      *        *              *        *               * *             *    *         *               \n");
	printf("\t      *  *        * * * * * *   *           *               *  *           *     *         *      *       \n");
	printf("\t * * * * * * * *  *     *           * * * * * * * * *     * *   *         *      *         *      *       \n");
	printf("\t       *          *     *           *       *            *  *      * * * * * * * * * *     * * * * * * * *  \n");
	printf("\t   * * * * *      *     *           *       *           *   *           *   *                  *  *  *    \n");
	printf("\t     * * *        *     *       * * * * * * * * * * * *     *         *       *               *   *    *  \n");
	printf("\t    *  *  *       *     *                   *               *       *           *           *     *      * \n");
	printf("\t   *   *   *      *     *                   *               *     *               *       *       *        *   \n");
	printf("\t  *    *    *     *     *                   *               *   *                   *   *         *          *  \n");
	printf("\t       *          *     *                   *               *                                     *       \n");
	 


}

完整代码

  • 到现在总算是成功了,也没什么要总结的,就先祝大家新年快乐
 
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<conio.h> 
#include<time.h>
#include<string.h>

#define UP_DOWN_DISTANCE 7  //上下柱子之间的距离
#define LEFT_RIGHT_DISTANCE 20 //左右柱子之间的距离
#define LENGTH 6 //储存随机数


//柱子的结构体
struct pipe
{
	//柱子的起始坐标
	int x;
	int y_up;
	int y_down;
	int hight;//柱子的高度

};

struct bird {
	//年兽的形象
	char ch[10];
	//年兽的初始位置
	int x;
	int y;
	int speed;//年兽的速度
}flyBird = { "○",15,13,3 };

int score = 0;//得分
int random[LENGTH];
int move = 0;//偏移量

struct pipe Pipe[LENGTH];


void gotoxy(int x, int y);//设置光标
void startMap();//设置游戏开始界面
void endMap();//设置游戏结束界面
void run();//运行
void drawBird(int y);//画年兽
void deleteBird(int y);//覆盖掉年兽
void birdJump(int y);//年兽上升
int isHitFloor(int y);//判断年兽是否会撞到边界
void creatPipe(int move);//创建柱子
void arrayRand();//创建随机数
void deletePipe(int move);//覆盖柱子
void movePipe();//移动柱子
int isHitPipe();//判断是否会撞到柱子
void printPipe();//打印柱子的信息
void getScore();//得分
void selectMap();//打印选择图标
void selectRole();//选择角色
void printNewYear();//打印新年快乐


int main()
{
	srand((unsigned int)time(NULL));//随机数种子
	system("mode con cols=130 lines=30");//cols是列,lines是行
	//movePipe();
	//run();
	run();
	//printNewYear();
	return 0;
}

//设置鼠标
void gotoxy(int x, int y)
{
	COORD pos = { x,y };
	HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hout, pos);
}

void startMap()
{
	printf("\n\n\n");
	printf("\t\t\t----------------------------------------------------------------------\n");
	printf("\t\t\t-                                                                    -\n");
	printf("\t\t\t-                                                                    -\n");
	printf("\t\t\t-                             开始游戏                               -\n");
	printf("\t\t\t-                                                                    -\n");
	printf("\t\t\t-                                                                    -\n");
	printf("\t\t\t----------------------------------------------------------------------\n\n\n");
	gotoxy(51, 15);
	system("pause");
	system("cls");
}

void endMap()
{

	system("cls");
	printf("\n\n\n");
	printf("\t\t\t----------------------------------------------------------------------\n");
	printf("\t\t\t-                                                                    -\n");
	printf("\t\t\t-                                                                    -\n");
	printf("\t\t\t-                             游戏结束                               -\n");
	printf("\t\t\t-                           你的得分为:%d                           -\n",score);
	printf("\t\t\t-                                                                    -\n");
	printf("\t\t\t----------------------------------------------------------------------\n\n\n");
	gotoxy(51, 15);
	system("pause");
	system("cls");
}

void selectMap()
{
	system("cls");
	printf("\n\n\n\n\n");
	printf("\t\t\t\t\t\t      请选择角色\n");
	printf("\n\n\n\n\n");
	
	printf("\t\t\t\t      *                                         *                     \n");
	printf("\t\t\t\t    * *                                         * *                      \n");
	printf("\t\t\t\t  * * *                                         * * *             \n");
	printf("\t\t\t\t    * *                                         * *              \n");
	printf("\t\t\t\t      *                                         *                     \n");
	
}
void printNewYear()
{
	system("cls");
	printf("\n\n\n\n\n");


	printf("\t         *                                  *                  *              *                          *    \n");
	printf("\t          *                 *             *                    *              *                       *      \n");
	printf("\t     * * * * * * *        *             * * * * * * * * *      *        * * * * * * *             *         \n");
	printf("\t       *      *        *              *        *               * *            *     *         *               \n");
	printf("\t         *  *        * * * * * *   *           *               *  *           *     *         *      *       \n");
	printf("\t    * * * * * * * *  *     *           * * * * * * * * *     * *   *         *      *         *      *       \n");
	printf("\t          *          *     *           *       *            *  *      * * * * * * * * * *     * * * * * * * *  \n");
	printf("\t      * * * * *      *     *           *       *           *   *           *   *                  *  *  *    \n");
	printf("\t        * * *        *     *       * * * * * * * * * * * *     *         *       *               *   *    *  \n");
	printf("\t       *  *  *       *     *                   *               *       *           *           *     *      * \n");
	printf("\t      *   *   *      *     *                   *               *     *               *       *       *        *   \n");
	printf("\t     *    *    *     *     *                   *               *   *                   *          *  *             \n");
	printf("\t          *          *     *                   *               *                                     *       \n");
	 
}
void selectRole()
{
	char role[10][5] = { "★","○","□" ,"=","@" };//“年兽”
	char name[10][10] = { "年兽星星","年兽圆圆","年兽方方","年兽等等","年兽艾特" };
	int flag = 0;
	while (1)
	{
		for (int i = 12; i < 15; i++)
		{
			gotoxy(59, i);
			printf("%s", role[flag]);
			for (int j = 0; j < 15; j++)
			{
				if (_kbhit())
				{
					//回车,ASCII码13;“键盘上下左右 方向键的键码(keyCode)是38、40、37和39,或者称虚拟ASCII值是38、40、37和39。”
					char ch = _getch();
					if (ch == 77 && flag < 4)//空格的ascil码为32
					{
						flag++;
					}
					else if (ch == 75 && flag > 0)
					{
						flag--;
					}
					else if (ch == 32)
					{
						system("cls");
						return;
					}
				}
				strcpy_s(flyBird.ch, role[flag]);
				Sleep(1);
			}
			gotoxy(59, i);
			printf("  ");
			gotoxy(56, 17);
			printf("%s", name[flag]);
			
			
		}
		
		
	}

}
void run()
{
	startMap();//开始界面 
	selectMap();
	selectRole();
	
	
	move = 0;
	arrayRand();//生成随机数
	while (1)
	{
		drawBird(flyBird.y);//初始化年兽
		creatPipe(move);//柱子初始化(在界面生成5条柱子) 
		for (int i = 0; i < 10; i++)//该循环可当作时间延迟
		{
			if (_kbhit())
			{
				//该出判断用来打断下降的时间循环,即刚按下按键就可让年兽向上升,不用等到每一次下降的时间结束在再上升
				//可让年兽的上升操作更顺畅
				char ch = _getch();
				if (ch == 32)//空格的ascil码为32
				{
					birdJump(flyBird.y);//让年兽上升
					break;
				}
				 
			}
			Sleep(1);//睡眠1毫秒,20次循环共20毫秒,但是可能里面的函数运行时会有时间延迟,所以总时间不止20毫秒
		}
		if (isHitFloor(flyBird.y) || isHitPipe())//判断是否会撞到边界或柱子
		{
			//printPipe();
			Sleep(1000);//死亡后,睡眠1秒
			break;
		}

		getScore();//得分

		deleteBird(flyBird.y);//覆盖掉上一个年兽的痕迹
		deletePipe(move);//覆盖掉上一个柱子的痕迹
		move++;//偏移量加1,即柱子向左移动

		if (move == 20)
		{
			//当第一条柱子移动了20个单位时(此刻此刻的年兽以及穿过柱子了),将偏移量move归零
			move = 0;
			//此刻将第二个随机数以后的数都向前移动一位,将第一个随机数覆盖掉,空出最后一个位置
			for (int i = 0; i < LENGTH - 1; i++)
			{
				Pipe[i].hight = Pipe[i + 1].hight;
			}
			//重新生成一个随机数放到最后一位
			Pipe[LENGTH - 1].hight = rand() % 10 + 10;

		}

		
		flyBird.y += 1;//下降1的单位
	}
	endMap();//结束界面
}

//这三个函数的使用要特别注意调用顺序
//画年兽
void drawBird(int y)
{
	gotoxy(flyBird.x, y);
	printf("%s", flyBird.ch);
}

//覆盖年兽
void deleteBird(int y)
{
	gotoxy(flyBird.x, y);
	printf("  ");
}
//年兽上升
void birdJump(int y)
{
	deleteBird(y);
	flyBird.y -= flyBird.speed;
}

//判断是否会撞到墙,撞到时返回1
int isHitFloor(int y)
{
	if (flyBird.y < 0 || flyBird.y > 28)
	{
		return 1;
	}
	else {
		return 0;
	}
}

//生成随机数,设置为并将上柱子的长度,生成的随机数放到数组中
void arrayRand()
{
	for (int i = 0; i < LENGTH; i++)
	{
		Pipe[i].hight = rand() % 10 + 10;
	}
}

void creatPipe(int move)
{
	int i = 0;
	int y = 0;
	int x = 0;
	for (x = 31-move ; x < 120; x += LEFT_RIGHT_DISTANCE)//循环五次,在指定位置生成五个柱子
	{
		
		//生成上半部分的柱子
		for (y = 0; y < Pipe[i].hight; y++) {
			gotoxy(x, y);
			printf("*");
		}
		
		//实时记录柱子的位置
		Pipe[i].x = x;
		Pipe[i].y_up = Pipe[i].hight;
		Pipe[i].y_down = y + UP_DOWN_DISTANCE;
		//生成下半部分的柱子
		for (y = y + UP_DOWN_DISTANCE; y < 30; y++)
		{
			gotoxy(x, y);
			printf("*");
		}
		i++;
	}
}
void printPipe()
{
	

	gotoxy(0, 2);
	printf("%d %d %d\n", Pipe[0].x, Pipe[0].y_up, Pipe[0].y_down);
	gotoxy(0, 3);
	printf("%d %d", flyBird.x, flyBird.y);
}
void deletePipe(int move)
{
	int i = 0;
	int y = 0;
	int x = 0;
	for (x = 31-move; x < 120; x += LEFT_RIGHT_DISTANCE)//循环五次,覆盖掉指定位置的柱子
	{

		//覆盖掉上半部分的柱子
		for (y = 0; y < Pipe[i].hight; y++) {
			gotoxy(x, y);
			printf(" ");
		}

		//覆盖掉下半部分的柱子
		for (y = y + UP_DOWN_DISTANCE; y < 30; y++)
		{
			gotoxy(x, y);
			printf(" ");
		}

		i++;
	}
}

void movePipe()
{
	move = 0;
	arrayRand();
	while (1)
	{
		creatPipe(move);
		Sleep(200);
		deletePipe(move);
		move++;

		//简单的来说,就是将第一个柱子接到第六条柱子后面,但第一条柱子再次出场时,数值发生了改变
		if (move == 20)
		{
			//当第一条柱子移动了20个单位时(此刻此刻的年兽以及穿过柱子了),将偏移量move归零
			move = 0;
			//此刻将第二个随机数以后的数都向前移动一位,将第一个随机数覆盖掉,空出最后一个位置
			for (int i = 0; i < LENGTH - 1; i++)
			{
				Pipe[i].hight = Pipe[i + 1].hight;
			}
			//重新生成一个随机数放到最后一位
			Pipe[LENGTH - 1].hight = rand() % 10 + 10;

		}
	}
}

int isHitPipe()
{
	if (flyBird.x+1 == Pipe[0].x || flyBird.x == Pipe[0].x)
	{
		if (flyBird.y >= Pipe[0].y_up&&flyBird.y <Pipe[0].y_down+1 )
		{
			return 0;
		}
		else
		{
			return 1;
		}
	}
	else {
		return 0;
	}
}

void getScore()
{
	gotoxy(0, 0);
	printf("得分:%d", score);
	if (Pipe[0].x == flyBird.x)
	{
		score++;
	}
}

标签:柱子,int,void,move,飞翔,Pipe,printf
来源: https://blog.csdn.net/xiaoiao_____/article/details/122775074

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有