Serpent gourmand en langage C (version simple avec code complet)

Ce serpent gourmand a été fait après avoir terminé la partie de base du langage C et suivi le cours Mooc de programmation en langage C de Harbin Institute of Technology. Parce que j'étais confus après avoir appris le langage C et que je ne savais pas quoi apprendre. La question la banque de l'école avait envie de le brosser et pas pratique. Ce que je peux voir Je pense que dans le processus d'apprentissage par étapes, je devrais trouver les résultats que je peux voir afin de me stimuler à avancer et continuer à apprendre, sinon c'est très ennuyeux, personne ne peut persister à apprendre

Ceci est également tapé étape par étape après avoir visionné le didacticiel vidéo. En fait, il est recommandé de l'implémenter vous-même après avoir compris le code, car n'ayez pas peur de ne pas oublier que ce n'est pas le code qui est tapé par des connaissances théoriques, mais c'est votre propre amélioration étape par étape. qwq

Voici le fichier d'en-tête head.h car il peut rendre le fichier principal plus net et plus clair
car j'utilise code: blocks. Le fichier d'en-tête est créé dans File-> New-> Class et cliquez sur Create. N'oubliez pas si vous voulez voir Let's jetez un œil à l'effet de mise en œuvre de ce code. Créez vous-même le fichier d'en-tête. Le nom est head. Sinon, le nom du fichier d'en-tête ne correspondra pas à hhhh. Vous pouvez également copier le code dans le programme principal. Vous pouvez également qwq N'oubliez pas d'annuler le cpp.

#ifndef HEAD_H
#define HEAD_H
#define SnakeMaxLength 20
typedef int bool;
#define true 1
#define false -1

//背景布置
//这里解释一下 一个特殊字符实线格子在横列是占两格
//所以空白格子在圈中要以两倍的间隔空格隔开

char MyBackGround[22][80]={
    
      "■■■■■■■■■■■■■■■■■■■■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\t\t\t欢乐时光就要开始了\n",
							 "■                                    ■\n",
							 "■                                    ■\t\t\tW A S D控制操作\n",
							 "■                                    ■\n",
							 "■                                    ■\t\t\t碰到墙壁死亡\n",
							 "■                                    ■\n",
							 "■                                    ■\t\t\t祝好运\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■■■■■■■■■■■■■■■■■■■■\n"};
//这里使用了枚举 为什么这里go_ease = -2 因为这里特殊字符在横向占两格 
//数列只占一个格子

enum Direction{
    
    go_east = -2,go_west = 2,go_north = -1,go_south = 1};
int ArrSnake[SnakeMaxLength][3]={
    
    {
    
    0,0,0}};

//判断蛇默认开始方向
int SnakeDirection = go_east;

//判断食物是否还存在
bool OptionFoodAlive = false;
int x,y;

Voici l'implémentation de la fonction principale main.h. Il y a
une fonction de lecture de musique dedans, mais vous ne pouvez utiliser que le format de fichier WAV et
les fichiers de musique au format wav
et les jeter à côté de votre fichier exe car vous utilisez un chemin relatif et changez le nom de la chanson en 1.wav. Ce n'est pas grave. Si vous ne voulez pas changer le fichier de musique, changez simplement le 1.wav de MyMusic dans le programme par le nom de votre musique.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>//使用strncpy函数
#include <conio.h>//_getch()要用
#include <windows.h>//这个是有些函数要用
#include "head.h"//包含头文件
#include <time.h>//随机值懂得奥
#define true 1
#define false -1
typedef int bool;

//首页
void FirstPage();
//播放音乐
void MyMusic();
//按回车键进入游戏
void EnterGame();
//停止音乐
void StopMusic();
//清空页面
void CleanScreen();
//背景基础函数
void BackGround();
//蛇爹的初始位置
void SetSnakePos();
//画蛇的位置
void GiveSnake();
//给蛇的位置赋值
void MoveSnake();
//删除蛇
void DeleteSnake();
//控制蛇
void ControlSnake();
//判断蛇是否死亡
bool IsSnakeAlive();
//制造食物
void ProduceFood();
//蛇变长
void LengthenSnake();


//首页
void FirstPage()
{
    
    
    printf("\n\n\n\n\n\n");
    printf("\t\t\t\t\t  《欢迎来到贪吃蛇的世界》\n\n\n");
    printf("\t\t\t\t\t 《W A S D 控制蛇前进后退》\n\n\n");
    printf("\t\t\t\t\t 《按下ENTER键开始新游戏》\n\n\n\n");
    printf("\t\t\t\t\t  《再次感谢游玩此游戏》\n");
}

//播放音乐
//这里可以删除功能 不想添加因为删掉就ok了
void MyMusic()
{
    
    
    PlaySound("1.wav",NULL,SND_FILENAME | SND_ASYNC );
}

//按回车键进入游戏
void EnterGame()
{
    
    
    while('\r'!=_getch());
}

//停止音乐
void StopMusic()
{
    
    
    PlaySound(NULL, 0, 0);
}

//清空页面
void CleanScreen()
{
    
    
    system("cls");
}

//背景基础函数
//布置背景嗷 头文件里面的背景
void BackGround()
{
    
    
    int i;
    for(i=0; i<20; i++)
    {
    
    
        printf("%s",MyBackGround[i]);
    }
}

//蛇爹的初始位置
void SetSnakePos()
{
    
    
	//其实这里的x , y我在后面加备注的时候我觉得会错意了
	//这里的x 我想表示的是他的行数
	//这里的y 我想表示的是他的列数 就是第几列
	//如果大家想改程序可以改成
	//x是rows y是lines即可 我懒我就懒得改了 大家懂的就ok了
	
    int x=-1;
    int y=-1;
    srand(time(NULL));
    y = rand()%16+1;//给蛇的位置赋值 默认蛇初始有三个格子
    x = rand()%16+1;
        ArrSnake[0][0] = x;
        ArrSnake[0][1] = y*2;//为什么乘以二呢 因为特殊格子在横向是占两格
        ArrSnake[0][2] = go_east;

        ArrSnake[1][0] = x;
        ArrSnake[1][1] = y*2 + 2;//加二是因为一个字符两个格子
        ArrSnake[1][2] = go_east;

        ArrSnake[2][0] = x;
        ArrSnake[2][1] = y*2 + 4;
        ArrSnake[2][2] = go_east;
}

//画蛇的位置
void GiveSnake()
{
    
    
    int i;
    for(i=0; ArrSnake[i][0] != 0;i++)
    {
    
    
    	//为什么使用strncpy呢 因为更安全hhhh 可以限制格子数
        strncpy(&MyBackGround[ArrSnake[i][0]][ArrSnake[i][1]],"■",2);
    }

}

//删除蛇
//为什么要删除蛇呢 因为这个蛇的移动就是一个 赋值 删除 赋值 删除的过程
//删除掉原来的蛇 然后再把现在的蛇表示出来 不然的话
//原来的蛇和现在的蛇就一直重复 导致原来的蛇一直在屏幕上
void DeleteSnake()
{
    
    
    int i;
    for(i=0; ArrSnake[i][0] != 0;i++)
    {
    
    
        strncpy(&MyBackGround[ArrSnake[i][0]][ArrSnake[i][1]],"  ",2);
    }
}

//蛇的坐标赋值
void MoveSnake()
{
    
    
    int i=SnakeMaxLength-1;
    ArrSnake[0][2]=SnakeDirection;
    for(;i>=1;i--)
    {
    
    
        //过滤坐标为0
        if(0 == ArrSnake[i][0])
        {
    
    
            continue;
        }
        //将上一个物块的值赋值给下一个物块(除蛇头)
        ArrSnake[i][0]=ArrSnake[i-1][0];
        ArrSnake[i][1]=ArrSnake[i-1][1];
        ArrSnake[i][2]=ArrSnake[i-1][2];
    }
    //处理蛇头
        if( go_east == ArrSnake[0][2] || go_west == ArrSnake[0][2])
        {
    
    
            ArrSnake[0][1]+=ArrSnake[0][2];
        }
        else
        {
    
    
            ArrSnake[0][0]+=ArrSnake[0][2];
        }
}

//控制蛇的方向
//这里是控制蛇的方向
//具体为什么用这个函数 大家可以自急查询一下
//这个Asyn的意思就是 异步的意思 表示你在操作的时候同时读入你键盘的值
//如果是同步的话 大家可以想象一下 需要你敲下回车 蛇才移动 不是嘛hhhh
void ControlSnake()
{
    
    
    if(GetAsyncKeyState('W'))
    {
    
    
        if(SnakeDirection != go_south)
        SnakeDirection=go_north;
    }
    else if(GetAsyncKeyState('S'))
    {
    
    
        if(SnakeDirection != go_north)
        SnakeDirection=go_south;
    }
    else if(GetAsyncKeyState('A'))
    {
    
    
        if(SnakeDirection != go_west)
        SnakeDirection=go_east;
    }
    else if(GetAsyncKeyState('D'))
    {
    
    
        if(SnakeDirection != go_east)
        SnakeDirection=go_west;
    }
}

//判断蛇是否死亡
bool IsSnakeAlive()
{
    
    
    if(0 == strncmp(&MyBackGround[ArrSnake[0][0]][ArrSnake[0][1]],"■",2))
    {
    
    
        return false;
    }
    else
    {
    
    
        return true;
    }
}

//制造食物
void ProduceFood()
{
    
    
    //蛇的坐标
    int i;
    srand(time(NULL));
    //蛇的坐标给予
    if(true == OptionFoodAlive)
    {
    
    
        return;
    }
    while(1)
    {
    
    
        bool tempbool = true;
        x=rand()%18 + 1;
        y=rand()%18 + 1;
        for(i=0 ; i<ArrSnake[i][0] ; i++)
        {
    
    
            if(x == ArrSnake[i][0] && 2*y == ArrSnake[i][1])
            {
    
    
                tempbool = false;
                break;
            }
        }
        if(true == tempbool)
        {
    
    

            break;
        }
    }
        strncpy(&MyBackGround[x][y*2],"★",2);
        OptionFoodAlive = true;
}

//这里就是加长蛇的长度了
void LengthenSnake()
{
    
    
    int i=0;
    if(x == ArrSnake[0][0] && 2*y == ArrSnake[0][1])
    {
    
    
        OptionFoodAlive = false;
        for(; ;i++)
        {
    
    
            if(ArrSnake[i][0] == 0)
            {
    
    
                if(ArrSnake[i][2] == go_north || ArrSnake[i][2] == go_south)
                {
    
    
                    ArrSnake[i][0]=ArrSnake[i-1][0]-ArrSnake[i-1][2];
                    ArrSnake[i][1]=ArrSnake[i-1][1];
                    ArrSnake[i][2]=ArrSnake[i-1][2];
                }
                else
                {
    
    
                    ArrSnake[i][0]=ArrSnake[i-1][0];
                    ArrSnake[i][1]=ArrSnake[i][1]-ArrSnake[i][2];
                    ArrSnake[i][2]=ArrSnake[i][2];
                }
                break;
            }
        }
    }
}


//这里就是主函数具体怎么实现的了
//这个贪吃蛇还包含了重启功能
//这个注释还是挺详细的了 希望能对大家有所帮助 大家一起加油
int main()
{
    
    
    FirstPage();//首页显示
    MyMusic();//音乐播放
    EnterGame();//按回车键进入游戏
    StopMusic();//停止音乐
    CleanScreen();//清空屏幕(为正式游戏做铺垫)
    SetSnakePos();//设置蛇的初始坐标
    while(1)
    {
    
    
        ProduceFood();//制造食物
        DeleteSnake();//删除蛇
        ControlSnake();//控制蛇的移动
        MoveSnake();//蛇移动图案
        if(false == IsSnakeAlive())
        {
    
    
            printf("snake died\n");
            break;
        }
        LengthenSnake();
        GiveSnake();//给予蛇在背景中图案
        BackGround();//布置背景
        Sleep(1000);
        system("cls");
    }
    system("pause");
    return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_37500516/article/details/110262664
conseillé
Classement