zoukankan      html  css  js  c++  java
  • 当你闲得无聊去编 C++「贪吃蛇」小游戏

    前言

    昨天下午在机房闲得无聊,然后就萌生了写一个简单的小游戏的想法。
    贪吃蛇算是很多小游戏之间比较简单易懂的一个。码起来也相对简单。所以就选择了贪吃蛇来编。
    编完之后发现代买超级无敌短,只有128行,随便敲一个平衡树或树剖就不止130行了。


    代码主体

    首先我们需要维护贪吃蛇的一下操作:

    1. 下一秒的贪食蛇的位置在哪里
    2. 获取按键并且让贪吃蛇转弯
    3. 打印贪吃蛇的位置

    - 操作1 下一秒的贪食蛇的位置在哪里color{blue} exttt{- 操作1 下一秒的贪食蛇的位置在哪里}
    其实这个就是编贪吃蛇的核心操作了。虽然这个实在来说也不是很难。
    我们只要记录num[i][j]num[i][j]表示位置(i,j)(i,j)还有多少秒蛇就会离开。也就是说,如果num[i][j]>0num[i][j]>0,那么此时贪吃蛇的一部分就位于位置(i,j)(i,j)上,且移动num[i][j]num[i][j]步之后贪吃蛇就不会再位于(i,j)(i,j)上了。
    所以对于每一次移动,我们就把贪吃蛇即将到达的位置numnum赋值为贪吃蛇的长度lenlen,然后就把所有大于0的numnum全部减一。
    如果即将到达的位置为食物所在的位置,我们就把所有的大于0的numnum加一,然后把lenlen也加一,相当于增加了一格的长度。

    bool move()
    {
    	int xx=sx+dx[f],yy=sy+dy[f];  //即将到达的位置
    	if (xx<1 || xx>n || yy<1 || yy>m) return 0;  //超界直接退出
    	if (a[xx][yy]>1) return 0;  //访问过这个点 也就是撞到自己
    	if (xx==tx && yy==ty)  //吃到食物
    	{
    		for (int i=1;i<=n;i++)
    			for (int j=1;j<=m;j++)
    				if (a[i][j]) a[i][j]++;
    		len++;
    		tx=rand()%n+1; ty=rand()%m+1;  //随机下一个食物的位置
    		while (a[tx][ty]) tx=rand()%n+1,ty=rand()%m+1;
    	}
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			if (a[i][j]) a[i][j]--;
    	a[xx][yy]=len;  //往前一格
    	sx=xx; sy=yy;
    	return 1;
    }
    

    - 操作2 获取按键并且让贪吃蛇转弯color{blue} exttt{- 操作2 获取按键并且让贪吃蛇转弯}
    这里我们需要用到两个函数

    #include <conio.h>
    kbhit();  //检测现在输入框内是否有字符
    ch=getch();  //直接读取输入框内的字符,不需要回车
    

    这样的话,我们就可以用一个变量ff记录贪吃蛇的方向。每次移动前判断输入框内是否有字符,如果有,那么久读取该字符并更新方向。

    void press()
    {
    	if (kbhit()) ch=getch();  //读取字符
    	if (ch=='w' || ch=='W') f=1;
    	if (ch=='s' || ch=='S') f=2;
    	if (ch=='a' || ch=='A') f=3;
    	if (ch=='d' || ch=='D') f=4; 
    }
    

    - 操作3 打印贪吃蛇的位置color{blue} exttt{- 操作3 打印贪吃蛇的位置}
    这个是最无脑的了。。。
    我们之前记录了数组numnum,那么打印时如果num[i][j]&gt;0num[i][j]&gt;0,那么这个位置就有贪吃蛇。如果这个位置是食物所在的位置,那么就打印食物即可。
    注意为了界面美观,每两列之间最好用空格隔开,因为C++每两行之间是有一个间距的。
    例如下列两图分别为有空格//无空格的贪吃蛇。两图大小均为15×1515 imes 15,差距是很明显的。
    在这里插入图片描述
    在这里插入图片描述

    然后大部分内容就搞定了。


    注意事项

    • 请务必使用英文输入法游玩本小游戏。因为中文输入法的字母C++经常无法读入
    • 建议C++窗口背景调成淡黄色(编号EE),文字依然是黑色(编号00),这样可能看着比较好看?(雾
    system("color E0"); 
    
    //影藏光标
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO CursorInfo;
    GetConsoleCursorInfo(handle, &CursorInfo);
    CursorInfo.bVisible = false;
    SetConsoleCursorInfo(handle, &CursorInfo);
    

    代码

    // ===================
    //     from stoorz
    //      2019.8.24
    // ===================
    #include <bits/stdc++.h>
    #include <windows.h>
    #include <conio.h>
    using namespace std;
    
    const int N=110;
    const int dx[]={0,-1,1,0,0};
    const int dy[]={0,0,0,-1,1};
    int n,m,v,f,len,sx,sy,tx,ty,a[N][N];
    char ch;
    
    void press()
    {
    	if (_kbhit()) ch=getch();
    	if (ch=='w' || ch=='W') f=1;
    	if (ch=='s' || ch=='S') f=2;
    	if (ch=='a' || ch=='A') f=3;
    	if (ch=='d' || ch=='D') f=4; 
    }
    
    bool move()
    {
    	int xx=sx+dx[f],yy=sy+dy[f];
    	if (xx<1 || xx>n || yy<1 || yy>m) return 0;
    	if (a[xx][yy]>1) return 0;
    	if (xx==tx && yy==ty)
    	{
    		for (int i=1;i<=n;i++)
    			for (int j=1;j<=m;j++)
    				if (a[i][j]) a[i][j]++;
    		len++;
    		tx=rand()%n+1; ty=rand()%m+1;
    		while (a[tx][ty]) tx=rand()%n+1,ty=rand()%m+1;
    	}
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			if (a[i][j]) a[i][j]--;
    	a[xx][yy]=len;
    	sx=xx; sy=yy;
    	return 1;
    }
    
    void output()
    {
    	putchar('+');
    	for (int i=1;i<m*2;i++) putchar('-'); 
    	putchar('+'); putchar(10);
    	for (int i=1;i<=n;i++)
    	{
    		putchar('|');
    		for (int j=1;j<=m;j++)
    		{
    			if (a[i][j]>0) putchar('o');
    			else if (i==tx && j==ty) putchar('*');
    			else putchar(' '); 
    			if (j!=m) putchar(' ');
    		}
    		putchar('|'); putchar(10);
    	}
    	putchar('+');
    	for (int i=1;i<m*2;i++) putchar('-'); 
    	putchar('+'); putchar(10); putchar(10);
    	printf("> len = %d 
    ",len);
    }
    
    int main()
    {
    	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    	CONSOLE_CURSOR_INFO CursorInfo;
    	GetConsoleCursorInfo(handle, &CursorInfo);
    	CursorInfo.bVisible = false;
    	SetConsoleCursorInfo(handle, &CursorInfo);
    
    	
    	system("color E0"); 
    	printf("> 请输入行数以及列数:
    ");
    	scanf("%d%d",&n,&m);
    	while (n<5 || m<5 || n>40 || m>40)
    	{
    		printf("> 行数以及列数的范围必须在5-40之间qwq
    ");
    		printf("> 请输入行数以及列数:
    ");
    		scanf("%d%d",&n,&m);
    	}
    	system("cls");
    	
    	printf("> 请输入速度(1~3):
    ");
    	scanf("%d",&v);
    	while (v<1 || v>3)
    	{
    		printf("> 速度必须在1至3之间!
    ");
    		printf("> 请输入速度:
    ");
    		scanf("%d",&v);
    	}
    	if (v==3) v=300;
    	if (v==2) v=200;
    	if (v==1) v=100;
    	
    	printf("> 游戏将在3秒后开始
    "); Sleep(1000);
    	printf("> 游戏将在2秒后开始
    "); Sleep(1000);
    	printf("> 游戏将在1秒后开始
    "); Sleep(1000);
    	printf("> 游戏开始!
    "); Sleep(500);
    	system("cls"); 
    	
    	// 1上 2下 3左 4右 
    	sx=n-1; sy=m/2; f=1; len=2;
    	a[sx][sy]=2; a[sx+1][sy]=1;
    	tx=rand()%n+1; ty=rand()%m+1;
    		while (a[tx][ty]) tx=rand()%n+1,ty=rand()%m+1;
    	while (1)
    	{
    		press();
    		if (!move()) break;
    		output();
    		Sleep(v);
    		if (len==n*m)
    		{
    			printf("
    > 你赢了!!!");
    			break; 
    		}
    		system("cls");
    	}
    	output();
    	Sleep(500);
    	printf("
    > 你死了!
    ");
    	Sleep(500);
    	printf("> 最终长度为 %d",len);
    	return 0;
    }
    
  • 相关阅读:
    南昌大学2021年数学分析考研试卷
    南昌大学2021年高等代数考研试卷
    吉林大学2021年数学分析考研试卷
    吉林大学2021年高等代数与解析几何考研试卷
    华中师范大学2021年高等代数考研试卷
    华中农业大学2021年数学分析考研试卷
    2021年清华大学丘成桐数学领军计划综合测试数学试题参考解析
    华中科技大学2021年数学分析考研试卷
    华中科技大学2021年高等代数考研试卷
    华东师范大学2021年数学分析考研试卷
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11997970.html
Copyright © 2011-2022 走看看